[SWAP] extract CacheElem class to new file
authorJiho Chu <jiho.chu@samsung.com>
Wed, 14 Dec 2022 05:57:36 +0000 (14:57 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Tue, 31 Jan 2023 11:27:17 +0000 (20:27 +0900)
Signed-off-by: Jiho Chu <jiho.chu@samsung.com>
nntrainer/tensor/cache_elem.cpp [new file with mode: 0644]
nntrainer/tensor/cache_elem.h [new file with mode: 0644]
nntrainer/tensor/memory_data.h
nntrainer/tensor/meson.build

diff --git a/nntrainer/tensor/cache_elem.cpp b/nntrainer/tensor/cache_elem.cpp
new file mode 100644 (file)
index 0000000..b037db2
--- /dev/null
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copyright (C) 2022 Jiho Chu <jiho.chu@samsung.com>
+ *
+ * @file   cache_elem.cpp
+ * @date   28 Nov 2022
+ * @see    https://github.com/nnstreamer/nntrainer
+ * @author Jiho Chu <jiho.chu@samsung.com>
+ * @bug    No known bugs except for NYI items
+ * @brief  Cache elem class
+ *
+ */
+
+#include "cache_elem.h"
+
+#include <stdexcept>
+#include <vector>
+
+#include <profiler.h>
+
+namespace nntrainer {
+
+namespace {
+
+std::map<CachePolicy, std::string> 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<std::mutex> lock(device_mutex);
+
+  opt = static_cast<Options>(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<std::mutex> 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 (file)
index 0000000..e62d30b
--- /dev/null
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copyright (C) 2022 Jiho Chu <jiho.chu@samsung.com>
+ *
+ * @file   cache_elem.h
+ * @date   28 Nov 2022
+ * @see    https://github.com/nnstreamer/nntrainer
+ * @author Jiho Chu <jiho.chu@samsung.com>
+ * @bug    No known bugs except for NYI items
+ * @brief  Cache elem class
+ *
+ */
+
+#ifndef __CACHE_ELEM_H__
+#define __CACHE_ELEM_H__
+
+#include <list>
+#include <mutex>
+
+#include <memory_data.h>
+#include <swap_device.h>
+
+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<SwapDevice> dev, unsigned int mem_id,
+                     size_t off, size_t len,
+                     std::shared_ptr<MemoryData<float>> 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<SwapDevice> 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<MemoryData<float>> mem_data; /**< allocated memory data */
+};
+
+} // namespace nntrainer
+
+#endif /** __CACHE_ELEM_H__ */
index a3a6095..ca32d4e 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef __MEMORY_DATA_H__
 #define __MEMORY_DATA_H__
 
+#include <functional>
+
 namespace nntrainer {
 
 using MemoryDataValidateCallback = std::function<void(unsigned int)>;
index aef4231..cdd210d 100644 (file)
@@ -1,5 +1,6 @@
 tensor_sources = [
   'blas_interface.cpp',
+  'cache_elem.cpp',
   'cache_pool.cpp',
   'lazy_tensor.cpp',
   'manager.cpp',