From: Jiho Chu Date: Wed, 14 Dec 2022 05:57:36 +0000 (+0900) Subject: [SWAP] extract CacheElem class to new file X-Git-Tag: accepted/tizen/unified/20230425.130129~80 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d972a1d1d6749bfad922e96ff2aef2aa65df793e;p=platform%2Fcore%2Fml%2Fnntrainer.git [SWAP] extract CacheElem class to new file Signed-off-by: Jiho Chu --- diff --git a/nntrainer/tensor/cache_elem.cpp b/nntrainer/tensor/cache_elem.cpp new file mode 100644 index 0000000..b037db2 --- /dev/null +++ b/nntrainer/tensor/cache_elem.cpp @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * Copyright (C) 2022 Jiho Chu + * + * @file cache_elem.cpp + * @date 28 Nov 2022 + * @see https://github.com/nnstreamer/nntrainer + * @author Jiho Chu + * @bug No known bugs except for NYI items + * @brief Cache elem class + * + */ + +#include "cache_elem.h" + +#include +#include + +#include + +namespace nntrainer { + +namespace { + +std::map policyToStr = { + {WRITE_BACK, "WRITE_BACK"}, {NO_WRITE_BACK, "NO_WRITE_BACK"}, + {READ_CONSIST, "READ_CONSIST"}, {NO_READ_CONSIST, "NO_READ_CONSIST"}, + {ALWAYS_SYNCED, "ALWAYS_SYNCED"}, {TEMPORAL, "TEMPORAL"}, + {FIRST_LAST_SKIP, "FIRST_LAST_SKIP"}, {ITERATION_CONSIST, "ITER_CONSIST"}}; + +inline bool checkAllocOnly(CachePolicy policy, CacheElem::Options opt) { + return ((policy & CachePolicy::NO_READ_CONSIST) || + ((opt & CacheElem::Options::FIRST_ACCESS) && + (policy & CachePolicy::FIRST_LAST_SKIP))); +} + +inline bool checkDeallocOnly(CachePolicy policy, CacheElem::Options opt) { + return ((policy & CachePolicy::NO_READ_CONSIST) || + ((opt & CacheElem::Options::LAST_ACCESS) && + (policy & CachePolicy::FIRST_LAST_SKIP))); +} + +} // namespace + +void CacheElem::swapIn(Options opt) { + std::lock_guard lock(device_mutex); + + opt = static_cast(opt | initial_opt); + bool alloc_only = checkAllocOnly(policy, opt); + void *buf = device->getBuffer(offset, length, alloc_only); + + initial_opt = Options::NONE; + mem_data->setAddr((float *)buf); + mem_data->setValid(true); + active = true; + +#ifdef PROFILE + std::string msg("CacheElem("); + msg += device->getDevicePath() + ") #" + std::to_string(id); + PROFILE_CACHE_ALLOC(buf, length, msg, policyToStr[policy], !alloc_only); +#endif +} + +void CacheElem::swapOut(Options opt) { + std::lock_guard lock(device_mutex); + bool dealloc_only = checkDeallocOnly(policy, opt); + void *buf = (void *)mem_data->getAddr(); + device->putBuffer(buf, dealloc_only); + mem_data->setAddr(nullptr); + mem_data->setValid(false); + active = false; + +#ifdef PROFILE + PROFILE_CACHE_DEALLOC(buf, policyToStr[policy], !dealloc_only); +#endif +} + +} // namespace nntrainer diff --git a/nntrainer/tensor/cache_elem.h b/nntrainer/tensor/cache_elem.h new file mode 100644 index 0000000..e62d30b --- /dev/null +++ b/nntrainer/tensor/cache_elem.h @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: Apache-2.0 +/** + * Copyright (C) 2022 Jiho Chu + * + * @file cache_elem.h + * @date 28 Nov 2022 + * @see https://github.com/nnstreamer/nntrainer + * @author Jiho Chu + * @bug No known bugs except for NYI items + * @brief Cache elem class + * + */ + +#ifndef __CACHE_ELEM_H__ +#define __CACHE_ELEM_H__ + +#include +#include + +#include +#include + +namespace nntrainer { + +enum CachePolicy { + WRITE_BACK = 0b0001, /**< invalidate will write to device */ + NO_WRITE_BACK = 0b0010, /**< invalidate will not write to device */ + READ_CONSIST = 0b0100, /**< validate will read from device */ + NO_READ_CONSIST = 0b1000, /**< validate will not read from device */ + ALWAYS_SYNCED = + (READ_CONSIST | WRITE_BACK), /**< Always synchronized with device */ + TEMPORAL = (NO_READ_CONSIST | + NO_WRITE_BACK), /**< Will not be synchronized with device */ + FIRST_LAST_SKIP = 0b10000, + /**< Will skip first read and last write */ + ITERATION_CONSIST = (FIRST_LAST_SKIP | ALWAYS_SYNCED), + /**< Will skip first read and last write. other behaviors will be same as + ALWAYS_SYNCED */ +}; + +/** + * @class CacheElem + * @brief Cache element containing swap address + */ +class CacheElem { +public: + enum Options { + NONE = 0b0000, /**< No option */ + FIRST_ACCESS = 0x0001, /**< First Access */ + LAST_ACCESS = 0x0010, /**< Last Access */ + }; + + /** + * @brief CacheElem default constructor + * + */ + explicit CacheElem(std::shared_ptr dev, unsigned int mem_id, + size_t off, size_t len, + std::shared_ptr> data, + CachePolicy pol = CachePolicy::ALWAYS_SYNCED) : + initial_opt(Options::FIRST_ACCESS), + device(dev), + active(false), + id(mem_id), + offset(off), + length(len), + policy(pol), + mem_data(data) {} + + /** + * @brief CacheElem destructor + * + */ + virtual ~CacheElem() {} + + /** + * @brief load data from swap device + * + * @param alloc_only only allocate buffer without reading data + */ + void swapIn(Options opt = Options::NONE); + + /** + * @brief unload data to swap device + * + * @param dealloc_only only deallocate buffer without writing data + */ + void swapOut(Options opt = Options::NONE); + + /** + * @brief unload data to swap device + * + * @return active status + */ + bool isActive() const { return active; } + + /** + * @brief get length of cache element + * + * @return length of cache element in byte + */ + size_t getLength() const { return length; } + + /** + * @brief get id of cache element + * + * @return cache element id + */ + unsigned int getId() const { return id; } + + /** + * @brief reset access count + * + */ + void reset() { initial_opt = Options::FIRST_ACCESS; } + +private: + Options initial_opt; /**< accessed */ + std::mutex device_mutex; /**< protect device */ + std::shared_ptr device; /**< swap device */ + bool active; /**< element is loaded */ + unsigned int id; /**< memory id */ + size_t offset; /**< element offset from swap device */ + size_t length; /**< element size */ + CachePolicy policy; /**< cache policy */ + std::shared_ptr> mem_data; /**< allocated memory data */ +}; + +} // namespace nntrainer + +#endif /** __CACHE_ELEM_H__ */ diff --git a/nntrainer/tensor/memory_data.h b/nntrainer/tensor/memory_data.h index a3a6095..ca32d4e 100644 --- a/nntrainer/tensor/memory_data.h +++ b/nntrainer/tensor/memory_data.h @@ -14,6 +14,8 @@ #ifndef __MEMORY_DATA_H__ #define __MEMORY_DATA_H__ +#include + namespace nntrainer { using MemoryDataValidateCallback = std::function; diff --git a/nntrainer/tensor/meson.build b/nntrainer/tensor/meson.build index aef4231..cdd210d 100644 --- a/nntrainer/tensor/meson.build +++ b/nntrainer/tensor/meson.build @@ -1,5 +1,6 @@ tensor_sources = [ 'blas_interface.cpp', + 'cache_elem.cpp', 'cache_pool.cpp', 'lazy_tensor.cpp', 'manager.cpp',