From: Inki Dae Date: Thu, 14 May 2020 05:02:34 +0000 (+0900) Subject: rename inference engine profiler relevant files X-Git-Tag: submit/tizen/20200602.011936~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b42b81de268072a53a0f042e2d8f484803b67157;p=platform%2Fcore%2Fmultimedia%2Finference-engine-interface.git rename inference engine profiler relevant files This patch renames src/inference_engine_profiler.cpp -> src/inference_engine_common_profiler.cpp include/inference_engine_profiler.h -> include/inference_engine_common_profiler.h because the name is conflicted with the one of inference engine profiler test file. Change-Id: Ibce9ba539b02826601eac4f8eebe16cf32dabf2d Signed-off-by: Inki Dae --- diff --git a/include/inference_engine_common_impl.h b/include/inference_engine_common_impl.h index f823f9f..08ccf52 100755 --- a/include/inference_engine_common_impl.h +++ b/include/inference_engine_common_impl.h @@ -22,7 +22,7 @@ #include "inference_engine_common.h" #include "inference_engine_type.h" -#include "inference_engine_profiler.h" +#include "inference_engine_common_profiler.h" using namespace InferenceEngineInterface::Profiler; diff --git a/include/inference_engine_common_profiler.h b/include/inference_engine_common_profiler.h new file mode 100644 index 0000000..d17b5d5 --- /dev/null +++ b/include/inference_engine_common_profiler.h @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __INFERENCE_ENGINE_PROFILER_H__ +#define __INFERENCE_ENGINE_PROFILER_H__ + +#include +#include +#include +#include + +#include "inference_engine_type.h" + +namespace InferenceEngineInterface { +namespace Profiler { + +/** + * @brief Enumeration for how-to-dump to profile data. + * + * @since_tizen 6.0 + * + */ +enum { + IE_PROFILER_DUMP_MIN, + // Profile data will be printed out on console screen. + IE_PROFILER_DUMP_CONSOLE, + // Profile data will be stored on a given file. + IE_PROFILER_DUMP_FILE, + IE_PROFILER_DUMP_MAX +}; + +/** + * @brief Enumeration for profile types. + * + * @since_tizen 6.0 + * + */ +enum { + IE_PROFILER_MIN, + // Measure performance in millisecond. + IE_PROFILER_LATENCY, + // Measure physical memory usage. + IE_PROFILER_MEMORY, + IE_PROFILER_MAX +}; + +/** + * @brief Enumeration for dump format to profile data. + * + * @since_tizen 6.0 + * + */ +enum { + IE_PROFILER_DUMP_FORMAT_MIN, + // Store profiling data to a given file in Markdown syntax[1] + // [1] https://daringfireball.net/projects/markdown/syntax + IE_PROFILER_DUMP_FORMAT_MARKDOWN, + IE_PROFILER_DUMP_FORMAT_MAX +}; + +/** + * @brief A structure of containg inference env. + * @details This structure contains inference information which says what env. the inference is being performed on. + * + * @since_tizen 6.0 + */ +typedef struct _ProfileEnv { + std::string backend_name; /**< backend name such as armnn, tflite, opencv and dldt. */ + std::string model_name; /**< model name which contains full path of a given model file. */ + unsigned int target_devices; /**< Hardware type the inference will be performed on. */ +} ProfileEnv; + +/** + * @brief A structure of containg profiled elased time data. + * @details This structure contains profiling data while in inference. + * + * @since_tizen 6.0 + */ +typedef struct _ProileData { + unsigned int env_idx; /**< An index of v_mProfileEnv vector.*/ + std::string function_name; /**< A function name targetd to profile. */ + unsigned int elapsed_time; /**< A latency to how long time a given function is performed. */ +} ProfileData; + +/** + * @brief A structure of containg profiled memory usage data. + * @details This structure contains profiling data while in inference. + * + * @since_tizen 6.0 + */ +typedef struct _MemoryData { + long rss; /** A number of physical pages consumed by current process. */ + long gpu_memory; /** A number of physical pages consumed by GPU device. */ + // TODO. +} MemoryData; + +/** + * @brief A class of representing profiler. + * @details This class interfaces will be called by InferenceEngineCommon class properly. + * + * @since_tizen 6.0 + */ +class InferenceEngineProfiler { +public: + InferenceEngineProfiler(); + ~InferenceEngineProfiler(); + + /** + * @brief Set backend name. + * @details It will be set in BindBackend callback of InferenceEngineCommon object + * to indicate which backend - armnn, opencv, tflite or dldt - inference will be performed by. + * + * @since_tizen 6.0 + * @param[in] name A backend name. + */ + void AddBackendName(std::string &name) { mProfileEnv.backend_name = name; } + + /** + * @brief Set model name. + * @details It will be set in Load callback of InferenceEngineCommon object to indicate which pre-trained model + * the inference will be performed on. + * + * @since_tizen 6.0 + * @param[in] name A full path to model file. + */ + void AddModelName(std::string &name) { mProfileEnv.model_name = name; } + + /** + * @brief Set taget devices the inference runs on. + * @details It will be set in SetTargetDevices callback of InferenceEngineCommon object to indicate + * which Hardware - CPU or GPU - the inference will be performed on. + * + * @since_tizen 6.0 + * @param[in] name A target device type. Please refer to inference_target_type_e enumeration of inference_engine_type.h. + */ + void AddTargetDevices(unsigned int devices) { mProfileEnv.target_devices = devices; } + + /** + * @brief Add inference env. information to a vector member, v_mProfileEnv. + * @details It will be called in Load callback of InferenceEngineCommon object to add inference env. information + * updated already to the vector member, which will be used to get inference env. information + * when dumping profile data. + * + * @since_tizen 6.0 + */ + void PushEnv(void) { v_mProfileEnv.push_back(mProfileEnv); mEnvNum++; } + + /** + * @brief Start profiling with a given profile type. + * @details It will be called at top of a callback function of InferenceEngineCommon object to collect profile data. + * + * @since_tizen 6.0 + * @param[in] type Profile type which can be IR_PROFILER_LATENCY or IR_PROFILER_MEMORY for now. + */ + void Start(const unsigned int type); + + /** + * @brief Stop profiling to a given profile type. + * @details It will be called at bottom of a callback function of InferenceEngineCommon object to collect profile data. + * + * @since_tizen 6.0 + * @param[in] type Profile type which can be IR_PROFILER_LATENCY or IR_PROFILER_MEMORY for now. + * @param[in] env_idx A index to v_mProfileEnv vector object. + * @param[in] func_name A function name to be profiled. + */ + void Stop(const unsigned int type, const char *func_name = "Unknown"); + + /** + * @brief Dump profiled data to console or a given file. + * @details It will be called in deconstructor of InferenceEngineCommon object to dump all of collected profile data. + * + * @since_tizen 6.0 + * @param[in] dump_type A dump type which can be IR_PROFILER_DUMP_TEXT or IR_PROFILER_DUMP_FILE for now. + */ + void Dump(const unsigned int dump_type); + + /** + * @brief Set user-given dump file name. + * @details If a file name is set using this function then profiled data will be stored to the given file. + * + * @since_tizen 6.0 + * @param[in] filename A name to user-given dump file. + */ + void SetDumpFilename(const std::string filename) { mDumpFilename = filename; } + +private: + void PushData(ProfileData &data); + struct timespec GetTimeDiff(struct timespec &start, struct timespec &end); + unsigned long ConvertMillisec(const struct timespec &time); + void GetMemoryUsage(MemoryData &data); + void DumpToConsole(void); + void DumpToFile(const unsigned int dump_type, std::string filename); + + struct timespec mStartTime, mEndTime; + unsigned int mEnvNum; + ProfileEnv mProfileEnv; + std::vector v_mProfileEnv; + std::vector v_mProfileData; + std::map m_mDataTable; + std::string mDumpFilename; + MemoryData mStartMemoryData; + MemoryData mEndMemoryData; +}; +} /* Profiler */ +} /* InferenceEngineInterface */ + +#endif /* __INFERENCE_ENGINE_COMMON_H__ */ diff --git a/include/inference_engine_profiler.h b/include/inference_engine_profiler.h deleted file mode 100644 index d17b5d5..0000000 --- a/include/inference_engine_profiler.h +++ /dev/null @@ -1,220 +0,0 @@ -/** - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __INFERENCE_ENGINE_PROFILER_H__ -#define __INFERENCE_ENGINE_PROFILER_H__ - -#include -#include -#include -#include - -#include "inference_engine_type.h" - -namespace InferenceEngineInterface { -namespace Profiler { - -/** - * @brief Enumeration for how-to-dump to profile data. - * - * @since_tizen 6.0 - * - */ -enum { - IE_PROFILER_DUMP_MIN, - // Profile data will be printed out on console screen. - IE_PROFILER_DUMP_CONSOLE, - // Profile data will be stored on a given file. - IE_PROFILER_DUMP_FILE, - IE_PROFILER_DUMP_MAX -}; - -/** - * @brief Enumeration for profile types. - * - * @since_tizen 6.0 - * - */ -enum { - IE_PROFILER_MIN, - // Measure performance in millisecond. - IE_PROFILER_LATENCY, - // Measure physical memory usage. - IE_PROFILER_MEMORY, - IE_PROFILER_MAX -}; - -/** - * @brief Enumeration for dump format to profile data. - * - * @since_tizen 6.0 - * - */ -enum { - IE_PROFILER_DUMP_FORMAT_MIN, - // Store profiling data to a given file in Markdown syntax[1] - // [1] https://daringfireball.net/projects/markdown/syntax - IE_PROFILER_DUMP_FORMAT_MARKDOWN, - IE_PROFILER_DUMP_FORMAT_MAX -}; - -/** - * @brief A structure of containg inference env. - * @details This structure contains inference information which says what env. the inference is being performed on. - * - * @since_tizen 6.0 - */ -typedef struct _ProfileEnv { - std::string backend_name; /**< backend name such as armnn, tflite, opencv and dldt. */ - std::string model_name; /**< model name which contains full path of a given model file. */ - unsigned int target_devices; /**< Hardware type the inference will be performed on. */ -} ProfileEnv; - -/** - * @brief A structure of containg profiled elased time data. - * @details This structure contains profiling data while in inference. - * - * @since_tizen 6.0 - */ -typedef struct _ProileData { - unsigned int env_idx; /**< An index of v_mProfileEnv vector.*/ - std::string function_name; /**< A function name targetd to profile. */ - unsigned int elapsed_time; /**< A latency to how long time a given function is performed. */ -} ProfileData; - -/** - * @brief A structure of containg profiled memory usage data. - * @details This structure contains profiling data while in inference. - * - * @since_tizen 6.0 - */ -typedef struct _MemoryData { - long rss; /** A number of physical pages consumed by current process. */ - long gpu_memory; /** A number of physical pages consumed by GPU device. */ - // TODO. -} MemoryData; - -/** - * @brief A class of representing profiler. - * @details This class interfaces will be called by InferenceEngineCommon class properly. - * - * @since_tizen 6.0 - */ -class InferenceEngineProfiler { -public: - InferenceEngineProfiler(); - ~InferenceEngineProfiler(); - - /** - * @brief Set backend name. - * @details It will be set in BindBackend callback of InferenceEngineCommon object - * to indicate which backend - armnn, opencv, tflite or dldt - inference will be performed by. - * - * @since_tizen 6.0 - * @param[in] name A backend name. - */ - void AddBackendName(std::string &name) { mProfileEnv.backend_name = name; } - - /** - * @brief Set model name. - * @details It will be set in Load callback of InferenceEngineCommon object to indicate which pre-trained model - * the inference will be performed on. - * - * @since_tizen 6.0 - * @param[in] name A full path to model file. - */ - void AddModelName(std::string &name) { mProfileEnv.model_name = name; } - - /** - * @brief Set taget devices the inference runs on. - * @details It will be set in SetTargetDevices callback of InferenceEngineCommon object to indicate - * which Hardware - CPU or GPU - the inference will be performed on. - * - * @since_tizen 6.0 - * @param[in] name A target device type. Please refer to inference_target_type_e enumeration of inference_engine_type.h. - */ - void AddTargetDevices(unsigned int devices) { mProfileEnv.target_devices = devices; } - - /** - * @brief Add inference env. information to a vector member, v_mProfileEnv. - * @details It will be called in Load callback of InferenceEngineCommon object to add inference env. information - * updated already to the vector member, which will be used to get inference env. information - * when dumping profile data. - * - * @since_tizen 6.0 - */ - void PushEnv(void) { v_mProfileEnv.push_back(mProfileEnv); mEnvNum++; } - - /** - * @brief Start profiling with a given profile type. - * @details It will be called at top of a callback function of InferenceEngineCommon object to collect profile data. - * - * @since_tizen 6.0 - * @param[in] type Profile type which can be IR_PROFILER_LATENCY or IR_PROFILER_MEMORY for now. - */ - void Start(const unsigned int type); - - /** - * @brief Stop profiling to a given profile type. - * @details It will be called at bottom of a callback function of InferenceEngineCommon object to collect profile data. - * - * @since_tizen 6.0 - * @param[in] type Profile type which can be IR_PROFILER_LATENCY or IR_PROFILER_MEMORY for now. - * @param[in] env_idx A index to v_mProfileEnv vector object. - * @param[in] func_name A function name to be profiled. - */ - void Stop(const unsigned int type, const char *func_name = "Unknown"); - - /** - * @brief Dump profiled data to console or a given file. - * @details It will be called in deconstructor of InferenceEngineCommon object to dump all of collected profile data. - * - * @since_tizen 6.0 - * @param[in] dump_type A dump type which can be IR_PROFILER_DUMP_TEXT or IR_PROFILER_DUMP_FILE for now. - */ - void Dump(const unsigned int dump_type); - - /** - * @brief Set user-given dump file name. - * @details If a file name is set using this function then profiled data will be stored to the given file. - * - * @since_tizen 6.0 - * @param[in] filename A name to user-given dump file. - */ - void SetDumpFilename(const std::string filename) { mDumpFilename = filename; } - -private: - void PushData(ProfileData &data); - struct timespec GetTimeDiff(struct timespec &start, struct timespec &end); - unsigned long ConvertMillisec(const struct timespec &time); - void GetMemoryUsage(MemoryData &data); - void DumpToConsole(void); - void DumpToFile(const unsigned int dump_type, std::string filename); - - struct timespec mStartTime, mEndTime; - unsigned int mEnvNum; - ProfileEnv mProfileEnv; - std::vector v_mProfileEnv; - std::vector v_mProfileData; - std::map m_mDataTable; - std::string mDumpFilename; - MemoryData mStartMemoryData; - MemoryData mEndMemoryData; -}; -} /* Profiler */ -} /* InferenceEngineInterface */ - -#endif /* __INFERENCE_ENGINE_COMMON_H__ */ diff --git a/src/inference_engine_common_profiler.cpp b/src/inference_engine_common_profiler.cpp new file mode 100644 index 0000000..9786343 --- /dev/null +++ b/src/inference_engine_common_profiler.cpp @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "inference_engine_error.h" +#include "inference_engine_common_profiler.h" +#include +#include +#include +#include + +extern "C" { + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "INFERENCE_ENGINE_PROFILER" +} + +#define NANO_PER_SEC ((__clock_t) 1000000000) +#define NANO_PER_MILLI ((__clock_t) 1000000) +#define MILLI_PER_SEC ((__clock_t) 1000) + +namespace InferenceEngineInterface { +namespace Profiler { + +// In default, we will use Markdown syntax to print out profile data. +static const std::string sTitleMarkdown("backend|target devices|model name|Function name|Latency(ms)\n--|--|--|--|--\n"); + +InferenceEngineProfiler::InferenceEngineProfiler() +{ + mStartTime = { 0, }; + mEndTime = { 0, }; + mEnvNum = 0; + + // In default. we will store profile data to dump.txt file. + // If you want to use other file then use SetDumpFilename function to change the filename. + mDumpFilename = "dump.txt"; + + mStartMemoryData = {0, }; + mEndMemoryData = {0, }; +} + +InferenceEngineProfiler::~InferenceEngineProfiler() +{ + v_mProfileEnv.clear(); + v_mProfileData.clear(); + m_mDataTable.clear(); +} + +void InferenceEngineProfiler::PushData(ProfileData &data) +{ + std::string key = std::to_string(mEnvNum - 1) + data.function_name; + + // In case of multiple 'Run' per one 'Load', update just average value of measured ones instead of adding new one. + if (!m_mDataTable.empty()) { + std::map::iterator iter; + iter = m_mDataTable.find(key.c_str()); + if (iter != m_mDataTable.end()) { + ProfileData *item = (ProfileData *)iter->second; + item->elapsed_time = (item->elapsed_time + data.elapsed_time) >> 1; + return; + } + } + + v_mProfileData.push_back(data); + m_mDataTable.insert(std::make_pair(key.c_str(), &v_mProfileData.back())); +} + +struct timespec InferenceEngineProfiler::GetTimeDiff(struct timespec &start, + struct timespec &end) +{ + struct timespec temp; + + if ((end.tv_nsec - start.tv_nsec) < 0) { + temp.tv_sec = end.tv_sec - start.tv_sec - 1; + temp.tv_nsec = NANO_PER_SEC + end.tv_nsec - start.tv_nsec; + } + else { + temp.tv_sec = end.tv_sec - start.tv_sec; + temp.tv_nsec = end.tv_nsec - start.tv_nsec; + } + + return temp; +} + +unsigned long InferenceEngineProfiler::ConvertMillisec(const struct timespec &time) +{ + mStartTime.tv_nsec = 0; + mStartTime.tv_sec = 0; + mEndTime.tv_nsec = 0; + mEndTime.tv_sec = 0; + + return (unsigned long)(time.tv_sec * MILLI_PER_SEC + time.tv_nsec / NANO_PER_MILLI); +} + +void InferenceEngineProfiler::GetMemoryUsage(MemoryData &data) +{ + unsigned long resident_set = 0, rss = 0; + + std::string ignore; + std::ifstream ifs("/proc/self/stat", std::ios_base::in); + ifs >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore + >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore + >> ignore >> ignore >> ignore >> rss; + + resident_set = (rss * getpagesize()) / 1024; + data.rss = resident_set; + + // TODO. Collect GPU memory usage specific to board in case of GPU acceleration. + // + // If current Linux kernel used Linux DMA mapping framework which is a generic solution for GPU memory management + // then we can get all memory usage. + // On the other hands, GPU driver on some boards may use reserved memory which is hided + // from Linux kernel memory subsystem so the memory usage cannot be measured in generic way. + // In this case, board specific interface is required. +} + +void InferenceEngineProfiler::Start(const unsigned int type) +{ + if (IE_PROFILER_MIN >= type || IE_PROFILER_MAX <= type) { + LOGE("Invalid profiler type."); + return; + } + + switch (type) { + case IE_PROFILER_LATENCY: + clock_gettime(CLOCK_MONOTONIC, &mStartTime); + break; + case IE_PROFILER_MEMORY: + mStartMemoryData = { 0, }; + GetMemoryUsage(mStartMemoryData); + break; + /* TODO */ + } +} + +void InferenceEngineProfiler::Stop(const unsigned int type, const char *func_name) +{ + if (IE_PROFILER_MIN >= type || IE_PROFILER_MAX <= type) { + LOGE("Invalid profiler type."); + return; + } + + ProfileData data = { mEnvNum - 1, func_name, 0 }; + + switch (type) { + case IE_PROFILER_LATENCY: { + clock_gettime(CLOCK_MONOTONIC, &mEndTime); + data.elapsed_time = ConvertMillisec(GetTimeDiff(mStartTime, mEndTime)); + // TODO. + PushData(data); + break; + } + case IE_PROFILER_MEMORY: + mEndMemoryData = { 0, }; + GetMemoryUsage(mEndMemoryData); + break; + /* TODO */ + } +} + +void InferenceEngineProfiler::DumpToConsole(void) +{ + std::cout << sTitleMarkdown; + + std::vector::iterator iter; + for (iter = v_mProfileData.begin(); iter != v_mProfileData.end(); iter++) { + ProfileData data = *iter; + ProfileEnv env = v_mProfileEnv[data.env_idx]; + std::cout << env.backend_name << "|" << env.target_devices << "|" << env.model_name << "|"; + std::cout << data.function_name << "|" << data.elapsed_time << "\n"; + } + + std::cout << "***" << "\n"; + std::cout << "Memory Usage(kb) : " << mEndMemoryData.rss - mStartMemoryData.rss << "\n"; + std::cout << "***" << "\n"; +} + +void InferenceEngineProfiler::DumpToFile(const unsigned int dump_type, std::string filename) +{ + if (mDumpFilename.empty()) + mDumpFilename = filename; + + std::ofstream dump_file; + + dump_file.open(mDumpFilename, std::ios::binary | std::ios::app); + if (dump_file.is_open()) { + dump_file.write(sTitleMarkdown.c_str(), sTitleMarkdown.length()); + + std::vector::iterator iter; + for (iter = v_mProfileData.begin(); iter != v_mProfileData.end(); iter++) { + ProfileData data = *iter; + ProfileEnv env = v_mProfileEnv[data.env_idx]; + dump_file.write(env.backend_name.c_str(), env.backend_name.length()); + dump_file.write("|", 1); + if (env.target_devices & INFERENCE_TARGET_CPU) + dump_file.write("CPU", 3); + if (env.target_devices & INFERENCE_TARGET_GPU) + dump_file.write("GPU", 3); + dump_file.write("|", 1); + dump_file.write(env.model_name.c_str(), env.model_name.length()); + dump_file.write("|", 1); + dump_file.write(data.function_name.c_str(), data.function_name.length()); + dump_file.write("|", 1); + std::string sElapsedTime(std::to_string(data.elapsed_time)); + dump_file.write(sElapsedTime.c_str(), sElapsedTime.length()); + dump_file.write("\n", 1); + } + + dump_file.write("***\n", 4); + std::string sMemoryUsage = std::to_string(mEndMemoryData.rss - mStartMemoryData.rss) + "KB Memory used"; + dump_file.write(sMemoryUsage.c_str(), sMemoryUsage.length()); + dump_file.write("\n", 1); + dump_file.write("***\n", 4); + } + + dump_file.close(); +} + +void InferenceEngineProfiler::Dump(const unsigned int dump_type) +{ + if (IE_PROFILER_DUMP_MIN >= dump_type || IE_PROFILER_DUMP_MAX <= dump_type) { + LOGE("Invalid profiler dump type."); + return; + } + + if (dump_type == IE_PROFILER_DUMP_CONSOLE) { + DumpToConsole(); + } else { + DumpToFile(IE_PROFILER_DUMP_FORMAT_MARKDOWN, mDumpFilename); + } +} + +} /* Profiler */ +} /* InferenceEngineInterface */ diff --git a/src/inference_engine_profiler.cpp b/src/inference_engine_profiler.cpp deleted file mode 100644 index b4a9c2e..0000000 --- a/src/inference_engine_profiler.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/** - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "inference_engine_error.h" -#include "inference_engine_profiler.h" -#include -#include -#include -#include - -extern "C" { - -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "INFERENCE_ENGINE_PROFILER" -} - -#define NANO_PER_SEC ((__clock_t) 1000000000) -#define NANO_PER_MILLI ((__clock_t) 1000000) -#define MILLI_PER_SEC ((__clock_t) 1000) - -namespace InferenceEngineInterface { -namespace Profiler { - -// In default, we will use Markdown syntax to print out profile data. -static const std::string sTitleMarkdown("backend|target devices|model name|Function name|Latency(ms)\n--|--|--|--|--\n"); - -InferenceEngineProfiler::InferenceEngineProfiler() -{ - mStartTime = { 0, }; - mEndTime = { 0, }; - mEnvNum = 0; - - // In default. we will store profile data to dump.txt file. - // If you want to use other file then use SetDumpFilename function to change the filename. - mDumpFilename = "dump.txt"; - - mStartMemoryData = {0, }; - mEndMemoryData = {0, }; -} - -InferenceEngineProfiler::~InferenceEngineProfiler() -{ - v_mProfileEnv.clear(); - v_mProfileData.clear(); - m_mDataTable.clear(); -} - -void InferenceEngineProfiler::PushData(ProfileData &data) -{ - std::string key = std::to_string(mEnvNum - 1) + data.function_name; - - // In case of multiple 'Run' per one 'Load', update just average value of measured ones instead of adding new one. - if (!m_mDataTable.empty()) { - std::map::iterator iter; - iter = m_mDataTable.find(key.c_str()); - if (iter != m_mDataTable.end()) { - ProfileData *item = (ProfileData *)iter->second; - item->elapsed_time = (item->elapsed_time + data.elapsed_time) >> 1; - return; - } - } - - v_mProfileData.push_back(data); - m_mDataTable.insert(std::make_pair(key.c_str(), &v_mProfileData.back())); -} - -struct timespec InferenceEngineProfiler::GetTimeDiff(struct timespec &start, - struct timespec &end) -{ - struct timespec temp; - - if ((end.tv_nsec - start.tv_nsec) < 0) { - temp.tv_sec = end.tv_sec - start.tv_sec - 1; - temp.tv_nsec = NANO_PER_SEC + end.tv_nsec - start.tv_nsec; - } - else { - temp.tv_sec = end.tv_sec - start.tv_sec; - temp.tv_nsec = end.tv_nsec - start.tv_nsec; - } - - return temp; -} - -unsigned long InferenceEngineProfiler::ConvertMillisec(const struct timespec &time) -{ - mStartTime.tv_nsec = 0; - mStartTime.tv_sec = 0; - mEndTime.tv_nsec = 0; - mEndTime.tv_sec = 0; - - return (unsigned long)(time.tv_sec * MILLI_PER_SEC + time.tv_nsec / NANO_PER_MILLI); -} - -void InferenceEngineProfiler::GetMemoryUsage(MemoryData &data) -{ - unsigned long resident_set = 0, rss = 0; - - std::string ignore; - std::ifstream ifs("/proc/self/stat", std::ios_base::in); - ifs >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore - >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore - >> ignore >> ignore >> ignore >> rss; - - resident_set = (rss * getpagesize()) / 1024; - data.rss = resident_set; - - // TODO. Collect GPU memory usage specific to board in case of GPU acceleration. - // - // If current Linux kernel used Linux DMA mapping framework which is a generic solution for GPU memory management - // then we can get all memory usage. - // On the other hands, GPU driver on some boards may use reserved memory which is hided - // from Linux kernel memory subsystem so the memory usage cannot be measured in generic way. - // In this case, board specific interface is required. -} - -void InferenceEngineProfiler::Start(const unsigned int type) -{ - if (IE_PROFILER_MIN >= type || IE_PROFILER_MAX <= type) { - LOGE("Invalid profiler type."); - return; - } - - switch (type) { - case IE_PROFILER_LATENCY: - clock_gettime(CLOCK_MONOTONIC, &mStartTime); - break; - case IE_PROFILER_MEMORY: - mStartMemoryData = { 0, }; - GetMemoryUsage(mStartMemoryData); - break; - /* TODO */ - } -} - -void InferenceEngineProfiler::Stop(const unsigned int type, const char *func_name) -{ - if (IE_PROFILER_MIN >= type || IE_PROFILER_MAX <= type) { - LOGE("Invalid profiler type."); - return; - } - - ProfileData data = { mEnvNum - 1, func_name, 0 }; - - switch (type) { - case IE_PROFILER_LATENCY: { - clock_gettime(CLOCK_MONOTONIC, &mEndTime); - data.elapsed_time = ConvertMillisec(GetTimeDiff(mStartTime, mEndTime)); - // TODO. - PushData(data); - break; - } - case IE_PROFILER_MEMORY: - mEndMemoryData = { 0, }; - GetMemoryUsage(mEndMemoryData); - break; - /* TODO */ - } -} - -void InferenceEngineProfiler::DumpToConsole(void) -{ - std::cout << sTitleMarkdown; - - std::vector::iterator iter; - for (iter = v_mProfileData.begin(); iter != v_mProfileData.end(); iter++) { - ProfileData data = *iter; - ProfileEnv env = v_mProfileEnv[data.env_idx]; - std::cout << env.backend_name << "|" << env.target_devices << "|" << env.model_name << "|"; - std::cout << data.function_name << "|" << data.elapsed_time << "\n"; - } - - std::cout << "***" << "\n"; - std::cout << "Memory Usage(kb) : " << mEndMemoryData.rss - mStartMemoryData.rss << "\n"; - std::cout << "***" << "\n"; -} - -void InferenceEngineProfiler::DumpToFile(const unsigned int dump_type, std::string filename) -{ - if (mDumpFilename.empty()) - mDumpFilename = filename; - - std::ofstream dump_file; - - dump_file.open(mDumpFilename, std::ios::binary | std::ios::app); - if (dump_file.is_open()) { - dump_file.write(sTitleMarkdown.c_str(), sTitleMarkdown.length()); - - std::vector::iterator iter; - for (iter = v_mProfileData.begin(); iter != v_mProfileData.end(); iter++) { - ProfileData data = *iter; - ProfileEnv env = v_mProfileEnv[data.env_idx]; - dump_file.write(env.backend_name.c_str(), env.backend_name.length()); - dump_file.write("|", 1); - if (env.target_devices & INFERENCE_TARGET_CPU) - dump_file.write("CPU", 3); - if (env.target_devices & INFERENCE_TARGET_GPU) - dump_file.write("GPU", 3); - dump_file.write("|", 1); - dump_file.write(env.model_name.c_str(), env.model_name.length()); - dump_file.write("|", 1); - dump_file.write(data.function_name.c_str(), data.function_name.length()); - dump_file.write("|", 1); - std::string sElapsedTime(std::to_string(data.elapsed_time)); - dump_file.write(sElapsedTime.c_str(), sElapsedTime.length()); - dump_file.write("\n", 1); - } - - dump_file.write("***\n", 4); - std::string sMemoryUsage = std::to_string(mEndMemoryData.rss - mStartMemoryData.rss) + "KB Memory used"; - dump_file.write(sMemoryUsage.c_str(), sMemoryUsage.length()); - dump_file.write("\n", 1); - dump_file.write("***\n", 4); - } - - dump_file.close(); -} - -void InferenceEngineProfiler::Dump(const unsigned int dump_type) -{ - if (IE_PROFILER_DUMP_MIN >= dump_type || IE_PROFILER_DUMP_MAX <= dump_type) { - LOGE("Invalid profiler dump type."); - return; - } - - if (dump_type == IE_PROFILER_DUMP_CONSOLE) { - DumpToConsole(); - } else { - DumpToFile(IE_PROFILER_DUMP_FORMAT_MARKDOWN, mDumpFilename); - } -} - -} /* Profiler */ -} /* InferenceEngineInterface */