[ WIP ] Mixed Tensor Data Type
authorjijoong.moon <jijoong.moon@samsung.com>
Fri, 14 Jul 2023 12:27:53 +0000 (21:27 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Mon, 21 Aug 2023 06:29:23 +0000 (15:29 +0900)
Modification for Mixed Tensor Data Type

**Self evaluation:**
1. Build test:  [X]Passed [ ]Failed [ ]Skipped
2. Run test:  [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: jijoong.moon <jijoong.moon@samsung.com>
21 files changed:
Applications/meson.build
api/ccapi/include/tensor_dim.h
meson.build
meson_options.txt
nntrainer/layers/fc_layer.cpp
nntrainer/tensor/blas_interface.cpp
nntrainer/tensor/blas_interface.h
nntrainer/tensor/memory_data.h
nntrainer/tensor/tensor.cpp
nntrainer/tensor/tensor.h
nntrainer/tensor/tensor_dim.cpp
test/input_gen/genModelExeOrder.cpp
test/unittest/compiler/meson.build
test/unittest/compiler/unittest_compiler.cpp
test/unittest/memory/unittest_cache_loader.cpp
test/unittest/memory/unittest_cache_pool.cpp
test/unittest/memory/unittest_memory_planner.cpp
test/unittest/memory/unittest_memory_pool.cpp
test/unittest/meson.build
test/unittest/unittest_nntrainer_tensor.cpp
test/unittest/unittest_util_func.cpp

index cbfff7f..63f124e 100644 (file)
@@ -2,23 +2,23 @@ nntr_app_resdir = nntrainer_resdir / 'app'
 run_command('mkdir', '-p', nntr_app_resdir)
 
 subdir('utils')
-subdir('KNN/jni')
-subdir('LogisticRegression/jni')
+#subdir('KNN/jni')
+#subdir('LogisticRegression/jni')
 if enable_ccapi
   subdir('MNIST/jni')
 endif
 subdir('VGG/jni')
 subdir('Resnet/jni')
 subdir('YOLO/jni')
-subdir('ReinforcementLearning/DeepQ/jni')
-subdir('TransferLearning/CIFAR_Classification/jni')
-if enable_capi
-  subdir('TransferLearning/Draw_Classification/jni')
-endif
+#subdir('ReinforcementLearning/DeepQ/jni')
+#subdir('TransferLearning/CIFAR_Classification/jni')
+#if enable_capi
+#  subdir('TransferLearning/Draw_Classification/jni')
+#endif
 subdir('Custom')
 subdir('ProductRatings/jni')
 subdir('AlexNet/jni')
 subdir('Layers/jni')
-if get_option('enable-tflite-backbone')
-  subdir('SimpleShot')
-endif
+#if get_option('enable-tflite-backbone')
+#  subdir('SimpleShot')
+#endif
index dc2bc33..e6cf582 100644 (file)
@@ -33,11 +33,25 @@ class TensorDim {
 public:
   static constexpr const size_t MAXDIM = 4;
 
-  /**
-   * @brief     Tensor Formant : Default is NCHW
-   */
   enum class Format { NCHW, NHWC };
 
+  enum class DataType {
+    FP16, /** half precion */
+    FP32  /** single precision */
+  };
+
+  struct TensorType {
+    /**
+     * @brief     Tensor Formant : Default is NCHW
+     */
+    Format format;
+    DataType data_type;
+
+    TensorType() : format(Format::NCHW), data_type(DataType::FP32) {};
+
+    TensorType(Format fm, DataType d_type) : format(fm), data_type(d_type) {};
+  };
+
   /**
    * @brief Get the Num Dim object
    *
@@ -45,6 +59,10 @@ public:
    */
   static unsigned int getNumDim();
 
+  TensorDim(TensorDim::Format fm, TensorDim::DataType d_type,
+                     const std::bitset<MAXDIM> &eff_dim_flag_ = 0b1111,
+                     const std::bitset<MAXDIM> &dyn_dim_flag_ = 0b0000);
+
   /**
    * @brief Construct a new Tensor Dim object
    *
@@ -52,7 +70,7 @@ public:
    * @param eff_dim_flag_ effective dimension flag (1 means it's effective)
    * @param dyn_dim_flag_ dynamic dimension flag (1 means it's unspecified)
    */
-  explicit TensorDim(Format fm = Format::NCHW,
+  explicit TensorDim(TensorType t_type_=TensorType(),
                      const std::bitset<MAXDIM> &eff_dim_flag_ = 0b1111,
                      const std::bitset<MAXDIM> &dyn_dim_flag_ = 0b0000);
 
@@ -65,7 +83,11 @@ public:
    * formats of {w}, {h, w}, {c, h, w}, {b, c, h, w} for the NCHW & NHWC are
    * accepted
    */
-  TensorDim(std::initializer_list<size_t> dims, Format fm = Format::NCHW);
+  TensorDim(std::initializer_list<size_t> dims,
+            TensorType t_type_ = TensorType());
+
+  // TensorDim(std::initializer_list<size_t> dims, TensorDim::Format fm=Format::NCHW,
+  //           TensorDim::DataType d_type=DataType::FP32);
 
   /**
    * @brief Construct a new Tensor Dim object without batch dimension
@@ -73,7 +95,10 @@ public:
    * @param shapes shapes without batch dimension
    * @param fm format NCHW | HNWC
    */
-  TensorDim(const std::array<size_t, 3> &shapes, Format fm = Format::NCHW);
+  TensorDim(const std::array<size_t, 3> &shapes, TensorType t_type_ = TensorType());
+
+  // TensorDim(const std::array<size_t, 3> &shapes, TensorDim::Format fm = Format::NCHW,
+  //           TensorDim::DataType d_type=DataType::FP32);
 
   /**
    * @brief Construct a new Tensor Dim object
@@ -86,7 +111,13 @@ public:
    * @param eff_dim_flag_ dimension bit flag to calculate the dynamic
    * dimension, rightmost is width
    */
-  TensorDim(size_t b, size_t c, size_t h, size_t w, Format fm = Format::NCHW,
+  TensorDim(size_t b, size_t c, size_t h, size_t w,
+            TensorType t_type_ = TensorType(),
+            const std::bitset<MAXDIM> &eff_dim_flag_ = 0b1111,
+            const std::bitset<MAXDIM> &dyn_dim_flag_ = 0b0000);
+
+  TensorDim(size_t d0, size_t d1, size_t d2, size_t d3, TensorDim::Format fm,
+            TensorDim::DataType d_type,
             const std::bitset<MAXDIM> &eff_dim_flag_ = 0b1111,
             const std::bitset<MAXDIM> &dyn_dim_flag_ = 0b0000);
 
@@ -103,7 +134,11 @@ public:
    * @param shape shape of format
    * @param fm format NCHW | HNWC
    */
-  TensorDim(const std::string &shape, Format fm = Format::NCHW);
+  TensorDim(const std::string &shape, TensorType t_type_ = TensorType());
+
+  TensorDim(const std::string &shape,
+            TensorDim::Format fm,
+            TensorDim::DataType d_type = TensorDim::DataType::FP32);
 
   /**
    * @brief Destroy the Tensor Dim object
@@ -124,6 +159,11 @@ public:
   TensorDim &operator=(TensorDim &&rhs) noexcept;
 
   /**
+   * @brief  get data type size
+   */
+  uint getDataTypeSize() const ;
+
+  /**
    * @brief Set the Dim Flag to retrieve effective dimension
    * @note eg) if dimension 4:1:10:1 should be squeezed to 4:10,
    *       set this to 0b1010, rightmost is width
@@ -291,7 +331,10 @@ public:
    * @param fm NCHW | NHWC
    * @return int ML_ERROR_NONE if successs
    */
-  int setTensorDim(const std::string &input_shape, Format fm = Format::NCHW);
+  int setTensorDim(const std::string &input_shape, TensorType t_type_=TensorType());
+
+  // int setTensorDim(const std::string &input_shape, TensorDim::Format fm,
+  //                  TensorDim::DataType d_type);
 
   /**
    * @brief copy assign a dimension
@@ -383,13 +426,37 @@ public:
    * @brief getFormat
    *
    */
-  TensorDim::Format getFormat() const { return format; };
+  TensorDim::Format getFormat() const { return t_type.format; };
+
+  /**
+   * @brief getType
+   *
+   */
+ TensorDim::DataType getDataType() const { return t_type.data_type; };
 
   /**
    * @brief setFormat
    *
    */
-  void setFormat(TensorDim::Format fm) { format = fm; };
+  void setFormat(TensorDim::Format fm) { t_type.format = fm; };
+
+  /**
+   * @brief setDataType
+   *
+   */
+  void setDataType(TensorDim::DataType ty) { t_type.data_type = ty; };
+
+  /**
+   * @brief getFormat
+   *
+   */
+  TensorType getTensorType() const { return t_type; };
+
+  /**
+   * @brief setTensorType
+   *
+   */
+  void setTensorType(TensorType tt) { t_type = tt; };
 
 private:
   /**
@@ -398,7 +465,7 @@ private:
    */
   void resetLen();
 
-  Format format;
+  TensorType t_type;
 
   std::bitset<MAXDIM> eff_dim_flag; /**< dimension bit flag to define effective
           dimension size */
index d2f0063..0f43512 100644 (file)
@@ -55,6 +55,23 @@ warning_c_flags = [
 ]
 
 
+# arm_fp16_flags = [
+#     '-mfp16-format=alternative',
+#     '-mfpu=neon-fp16,
+#     '-mfloat-abi=softfp'
+# ]
+
+# if get_option('enable-fp16')
+#    foreach extra_arg : arm_fp16_flags
+#      if cc.has_argument (extra_arg)
+#        add_project_arguments([extra_arg], language: 'c')
+#      endif
+#      if cxx.has_argument (extra_arg)
+#        add_project_arguments([extra_arg], language: 'cpp')
+#      endif
+#    endforeach
+# enfif
+
 foreach extra_arg : warning_flags
   if cc.has_argument (extra_arg)
     add_project_arguments([extra_arg], language: 'c')
@@ -329,6 +346,10 @@ if get_option('platform') != 'android'
   extra_defines += '-DNNTRAINER_CONF_PATH="@0@"'.format(nntrainer_conf_abs_path)
 endif
 
+# if get_option('enable-fp16')
+#    extra_defines += '-march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp'
+# endif
+
 message('extra defines are:' + ' '.join(extra_defines))
 foreach defs: extra_defines
   add_project_arguments(defs, language: ['c', 'cpp'])
@@ -359,22 +380,22 @@ if get_option('enable-app')
     warning('android app is not supported for now, building app skipped')
   else
     # this is needed for reinforcement application. We can move this to reinforecement app dependency
-    jsoncpp_dep = dependency('jsoncpp') # jsoncpp
-    libcurl_dep = dependency('libcurl')
-    if not tflite_dep.found()
-      error('Tensorflow-Lite dependency not found')
-    endif
+    jsoncpp_dep = dependency('jsoncpp') # jsoncpp
+    libcurl_dep = dependency('libcurl')
+    if not tflite_dep.found()
+      error('Tensorflow-Lite dependency not found')
+    endif
     subdir('Applications')
   endif
 endif
 
-if get_option('platform') != 'android'
-  nnstreamer_dep = dependency('nnstreamer')
-  message('building nnstreamer')
-  subdir('nnstreamer')
-else
-  warning('android nnstreamer-filter and nnstreamer-trainer are not yet supported, building them is skipped')
-endif
+if get_option('platform') != 'android'
+  nnstreamer_dep = dependency('nnstreamer')
+  message('building nnstreamer')
+  subdir('nnstreamer')
+else
+  warning('android nnstreamer-filter and nnstreamer-trainer are not yet supported, building them is skipped')
+endif
 
 if get_option('platform') == 'android'
   subdir('jni')
index 61e659a..360a291 100644 (file)
@@ -8,11 +8,11 @@ option('enable-test', type: 'boolean', value: true)
 option('enable-logging', type: 'boolean', value: true)
 option('enable-tizen-feature-check', type: 'boolean', value: true)
 option('enable-nnstreamer-backbone', type: 'boolean', value: false)
-option('enable-tflite-backbone', type: 'boolean', value: true)
+option('enable-tflite-backbone', type: 'boolean', value: false)
 option('enable-profile', type: 'boolean', value: false)
 option('enable-trace', type: 'boolean', value: false)
 option('enable-debug', type: 'boolean', value: false)
-option('enable-tflite-interpreter', type: 'boolean', value: true)
+option('enable-tflite-interpreter', type: 'boolean', value: false)
 option('enable-memory-swap', type: 'boolean', value: false)
 option('memory-swap-path', type: 'string', value: '')
 option('test-timeout', type: 'integer', value: 60)
index ca5c70b..a10bddf 100644 (file)
@@ -76,12 +76,8 @@ void FullyConnectedLayer::finalize(InitLayerContext &context) {
   /** set weight specifications */
   // @todo : This NCHW format setting is just temporal, it needs to be set by
   // global configuration
-
-  TensorDim bias_dim(1, is_nchw ? 1 : unit, 1, is_nchw ? unit : 1,
-                     getTensorType(), is_nchw ? 0b0001 : 0b0100);
-  TensorDim weight_dim(1, is_nchw ? 1 : unit, is_nchw ? in_dim.width() : 1,
-                       is_nchw ? unit : in_dim.channel(), getTensorType(),
-                       is_nchw ? 0b0011 : 0b0101);
+  TensorDim bias_dim(1, 1, 1, unit, TensorDim::TensorType(getTensorType(), TensorDim::DataType::FP32) , 0b0001);
+  TensorDim weight_dim(1, 1, in_dim.width(), unit, TensorDim::TensorType(getTensorType(), TensorDim::DataType::FP32), 0b0011);
 
   weight_idx[FCParams::weight] = context.requestWeight(
     weight_dim, weight_initializer, weight_regularizer,
index 92b2720..5335db3 100644 (file)
@@ -102,17 +102,17 @@ void sscal(const unsigned int N, const float alpha, __fp16 *X, const int incX) {
 }
 
 void sscal(const unsigned int N, const float alpha, void *X, const int incX,
-           DataType d_type) {
+           ml::train::TensorDim::DataType d_type) {
 #ifdef USE_BLAS
 #ifdef BLAS_NUM_THREADS
   openblas_set_num_threads(BLAS_NUM_THREADS);
 #endif
-  if (d_type == DataType::FP32)
+  if (d_type == ml::train::TensorDim::DataType::FP32)
     cblas_sscal(N, alpha, (float *)X, incX);
 #else
-  if (d_type == DataType::FP32) {
+  if (d_type == ml::train::TensorDim::DataType::FP32) {
     sscal_raw(N, alpha, (float *)X, incX);
-  } else if (d_type == DataType::FP16) {
+  } else if (d_type == ml::train::TensorDim::DataType::FP16) {
     sscal(N, alpha, (__fp16 *)X, incX);
   }
 #endif
@@ -240,18 +240,18 @@ void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB,
 }
 
 void scopy(const unsigned int N, const void *X, const int incX, void *Y,
-           const int incY, DataType d_type) {
+           const int incY, ml::train::TensorDim::DataType d_type) {
 #ifdef USE_BLAS
 #ifdef BLAS_NUM_THREADS
   openblas_set_num_threads(BLAS_NUM_THREADS);
 #endif
-  if (d_type == DataType::FP32) {
+  if (d_type == ml::train::TensorDim::DataType::FP32) {
     cblas_scopy(N, (float *)X, incX, (float *)Y, incY);
   }
 #else
-  if (d_type == DataType::FP32) {
+  if (d_type == ml::train::TensorDim::DataType::FP32) {
     scopy_raw(N, (float *)X, incX, (float *)Y, incY);
-  } else if (d_type == DataType::FP16) {
+  } else if (d_type == ml::train::TensorDim::DataType::FP16) {
     scopy_FP16(N, (__fp16 *)X, incX, (__fp16 *)Y, incY);
   }
 #endif
index 8bab311..b560c28 100644 (file)
@@ -35,15 +35,12 @@ enum CBLAS_TRANSPOSE {
 #include <helper_functions.h>
 #endif
 
-namespace nntrainer {
+#include <tensor_dim.h>
 
-enum class DataType {
-  FP16, /** half precion */
-  FP32  /** single precision */
-};
+namespace nntrainer {
 
 void sscal(const unsigned int N, const float alpha, void *X, const int incX,
-           DataType d_type);
+           ml::train::TensorDim::DataType d_type);
 
 void sscal(const unsigned int N, const float alpha, float *X, const int incX);
 
@@ -52,7 +49,7 @@ void sscal(const unsigned int N, const float alpha, __fp16 *X, const int incX);
 float snrm2(const int N, const float *X, const int incX);
 
 void scopy(const unsigned int N, const void *X, const int incX, void *Y,
-           const int incY, DataType d_type);
+           const int incY, ml::train::TensorDim::DataType d_type);
 
 void scopy(const unsigned int N, const float *X, const int incX, float *Y,
            const int intY);
index 1494333..47bc9be 100644 (file)
@@ -79,7 +79,7 @@ public:
   /**
    * @brief  Get address
    */
-  void *getAddr() const { return address; }
+  template <typename T = float> T *getAddr() const { return (T *)address; }
 
   /**
    * @brief  Validate memory data
index f6feef2..028a32d 100644 (file)
@@ -84,23 +84,20 @@ struct Tensor::BroadcastInfo {
 };
 
 Tensor::Tensor(const TensorDim &d, bool alloc_now, Tensor::Initializer init,
-               std::string name_, nntrainer::DataType d_type) :
+               std::string name_) :
   Tensor(name_) {
   if (d.getDataLen() != 0) {
     dim = d;
     strides = d.computeStrides();
     initializer = init;
-    setDataType(d_type);
     if (alloc_now)
       allocate();
   }
 }
 
-Tensor::Tensor(const TensorDim &d, const void *buf,
-               nntrainer::DataType d_type) :
+Tensor::Tensor(const TensorDim &d, const void *buf) :
   Tensor(d, true) {
   if (d.getDataLen() != 0) {
-    setDataType(d_type);
     if (buf != nullptr)
       copy(buf);
   }
@@ -155,14 +152,14 @@ void Tensor::allocate() {
     /// allocate new memory for the tensor data
     MemoryData *mem_data;
 
-    if (getDataType() == DataType::FP32) {
+    if (getDataType() == ml::train::TensorDim::DataType::FP32) {
       mem_data = new MemoryData((void *)(new float[dim.getDataLen()]()));
       data = std::shared_ptr<MemoryData>(mem_data, [](auto *mem_data) {
         delete[](float *) mem_data->getAddr();
         delete mem_data;
       });
 
-    } else if (getDataType() == DataType::FP16) {
+    } else if (getDataType() == ml::train::TensorDim::DataType::FP16) {
       mem_data = new MemoryData((void *)(new __fp16[dim.getDataLen()]()));
       data = std::shared_ptr<MemoryData>(mem_data, [](auto *mem_data) {
         delete[](__fp16 *) mem_data->getAddr();
@@ -189,7 +186,7 @@ bool Tensor::operator==(const Tensor &rhs) const {
   if (strides != rhs.strides)
     return false;
 
-  if (data_type == nntrainer::DataType::FP32) {
+  if (dim.getDataType() == ml::train::TensorDim::DataType::FP32) {
     const float *_data = getData<float>();
     const float *_rdata = rhs.getData<float>();
     for (size_t i = 0; i < len; ++i) {
@@ -200,7 +197,7 @@ bool Tensor::operator==(const Tensor &rhs) const {
           std::fabs(_data[i] - _rdata[i]) > epsilon)
         return false;
     }
-  } else if (data_type == nntrainer::DataType::FP16) {
+  } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) {
     const __fp16 *_data = getData<__fp16>();
     const __fp16 *_rdata = rhs.getData<__fp16>();
     for (size_t i = 0; i < len; ++i) {
@@ -306,12 +303,12 @@ Tensor Tensor::multiply_strided(Tensor const &m, const float beta) const {
 Tensor &Tensor::multiply_strided(Tensor const &m, Tensor &output,
                                  const float beta) const {
   /** TODO: throw than create new dimenions */
-  CREATE_IF_EMPTY_DIMS(output, dim, nullptr, data_type);
+  CREATE_IF_EMPTY_DIMS(output, dim, nullptr);
 
   if (size() != m.size() || size() != output.size())
     throw std::invalid_argument(
       "Strided multiplication does not support broadcasting");
-  if (data_type == DataType::FP32) {
+  if (dim.getDataType() == ml::train::TensorDim::DataType::FP32) {
     if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 ||
         beta != 0.0) {
       for (unsigned int b = 0; b < batch(); ++b) {
@@ -340,7 +337,7 @@ Tensor &Tensor::multiply_strided(Tensor const &m, Tensor &output,
         }
       }
     }
-  } else if (data_type == DataType::FP16) {
+  } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) {
     if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 ||
         beta != 0.0) {
       for (unsigned int b = 0; b < batch(); ++b) {
@@ -393,12 +390,12 @@ Tensor Tensor::add_strided(Tensor const &m, const float beta) const {
 Tensor &Tensor::add_strided(Tensor const &m, Tensor &output,
                             const float beta) const {
   /** TODO: throw than create new dimenions */
-  CREATE_IF_EMPTY_DIMS(output, dim, nullptr, data_type);
+  CREATE_IF_EMPTY_DIMS(output, dim, nullptr);
 
   if (size() != m.size() || size() != output.size())
     throw std::invalid_argument(
       "Strided addition does not support broadcasting");
-  if (data_type == DataType::FP32) {
+  if (dim.getDataType() == ml::train::TensorDim::DataType::FP32) {
     if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 ||
         beta != 0.0) {
       for (unsigned int b = 0; b < batch(); ++b) {
@@ -426,7 +423,7 @@ Tensor &Tensor::add_strided(Tensor const &m, Tensor &output,
         }
       }
     }
-  } else if (data_type == DataType::FP16) {
+  } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) {
     if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 ||
         beta != 0.0) {
       for (unsigned int b = 0; b < batch(); ++b) {
@@ -464,12 +461,12 @@ int Tensor::multiply_i(float const &value) {
 
   /// @note this is not depending on multiply_i as there is an optimized
   /// version for multiply_i
-  if (data_type == DataType::FP32) {
+  if (dim.getDataType() == ml::train::TensorDim::DataType::FP32) {
     float *data = getData<float>();
     unsigned int len = size();
 
     sscal(len, value, data, 1);
-  } else if (data_type == DataType::FP16) {
+  } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) {
     __fp16 *data = getData<__fp16>();
     unsigned int len = size();
     sscal(len, value, data, 1);
@@ -484,13 +481,14 @@ Tensor Tensor::multiply(float const &value) const {
 
 Tensor &Tensor::multiply(float const &value, Tensor &out) const {
   /// @todo add unittest
-  if (data_type == DataType::FP32) {
+  if (dim.getDataType() == ml::train::TensorDim::DataType::FP32) {
     auto f = std::bind(std::multiplies<float>(), std::placeholders::_1, value);
     return apply(f, out);
-  } else if (data_type == DataType::FP16) {
+  } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) {
     auto f = std::bind(std::multiplies<__fp16>(), std::placeholders::_1, value);
     return apply(f, out);
   }
+  return out;
 }
 
 int Tensor::multiply_i(Tensor const &m, const float beta) {
@@ -515,7 +513,7 @@ Tensor &Tensor::multiply(Tensor const &m, Tensor &output,
    * @note this does not work correctly with differently strided inputs.
    * Use multiply_strided alternatively
    */
-  if (data_type == DataType::FP32) {
+  if (dim.getDataType() == ml::train::TensorDim::DataType::FP32) {
     auto f = [&](const BroadcastInfo &e, const float *buf, const float *m_buf,
                  float *out_buf) {
       if (e.strides[3] == 1 && output.strides[3] == 1 && strides[3] == 1 &&
@@ -538,7 +536,7 @@ Tensor &Tensor::multiply(Tensor const &m, Tensor &output,
 
     apply_broadcast(m, f, output);
     return output;
-  } else if (data_type == DataType::FP16) {
+  } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) {
     auto f = [&](const BroadcastInfo &e, const __fp16 *buf, const __fp16 *m_buf,
                  __fp16 *out_buf) {
       if (e.strides[3] == 1 && output.strides[3] == 1 && strides[3] == 1 &&
@@ -562,6 +560,7 @@ Tensor &Tensor::multiply(Tensor const &m, Tensor &output,
     apply_broadcast(m, f, output);
     return output;
   }
+  return output;
 }
 
 int Tensor::divide_i(float const &value) {
@@ -1060,7 +1059,7 @@ void Tensor::apply_broadcast(
                      __fp16 *)>
     v_func,
   Tensor &output) const {
-  CREATE_IF_EMPTY_DIMS(output, dim, nullptr, data_type);
+  CREATE_IF_EMPTY_DIMS(output, dim, nullptr);
 
   NNTR_THROW_IF(getData<__fp16>() == nullptr, std::invalid_argument)
     << getName() << " is not allocated";
@@ -1189,8 +1188,7 @@ Tensor &Tensor::sum(unsigned int axis, Tensor &ret, float alpha,
 
   switch (axis) {
   case 0: {
-    CREATE_IF_EMPTY_DIMS(ret, 1, dim[1], dim[2], dim[3], this->getFormat());
-
+    CREATE_IF_EMPTY_DIMS(ret, 1, dim.channel(), dim.height(), dim.width(),getTensorType());
     size_t feat_len = dim.getFeatureLen();
     size_t batch = dim.batch();
     Tensor ones(1, 1, 1, batch, this->getFormat());
@@ -1199,7 +1197,7 @@ Tensor &Tensor::sum(unsigned int axis, Tensor &ret, float alpha,
           ones.getData(), 1, beta, ret.getData(), 1);
   } break;
   case 1: {
-    CREATE_IF_EMPTY_DIMS(ret, dim.batch(), 1, dim.height(), dim.width());
+    CREATE_IF_EMPTY_DIMS(ret, dim.batch(), 1, dim.height(), dim.width(),getTensorType());
     unsigned int feat_len = dim.height() * dim.width();
     unsigned int channel = dim.channel();
     Tensor ones(1, 1, 1, channel);
@@ -1212,7 +1210,7 @@ Tensor &Tensor::sum(unsigned int axis, Tensor &ret, float alpha,
     }
   } break;
   case 2: {
-    CREATE_IF_EMPTY_DIMS(ret, dim.batch(), dim.channel(), 1, dim.width());
+    CREATE_IF_EMPTY_DIMS(ret, dim.batch(), dim.channel(), 1, dim.width(),getTensorType());
     unsigned int width = dim.width();
     unsigned int height = dim.height();
     Tensor ones(1, 1, 1, height);
@@ -1229,8 +1227,7 @@ Tensor &Tensor::sum(unsigned int axis, Tensor &ret, float alpha,
     }
   } break;
   case 3: {
-    CREATE_IF_EMPTY_DIMS(ret, dim.batch(), dim.channel(), dim.height(), 1,
-                         Tformat::NCHW, DataType::FP32);
+    CREATE_IF_EMPTY_DIMS(ret, dim.batch(), dim.channel(), dim.height(), 1, getTensorType());
     unsigned int m = ret.dim.getDataLen();
     unsigned int n = dim.width();
     Tensor ones(1, 1, 1, n);
@@ -1425,12 +1422,7 @@ Tensor &Tensor::dot(Tensor const &m, Tensor &result, bool trans, bool trans_m,
     K = mdim1; /** == dim2 */
     N = mdim2;
     M = dim1;
-    if (getFormat() == Tformat::NHWC) {
-      CREATE_IF_EMPTY_DIMS(result, batch(), N, height(), width(),
-                           Tformat::NHWC); //  NHWC Result Tensor
-    } else {
-      CREATE_IF_EMPTY_DIMS(result, batch(), channel(), height(), N);
-    }
+    CREATE_IF_EMPTY_DIMS(result, batch(), channel(), height(), N, getTensorType());
 
     // We are not set zero the result because of performnace reason.
     // However, result is not initialized properly. There might include
@@ -1444,14 +1436,7 @@ Tensor &Tensor::dot(Tensor const &m, Tensor &result, bool trans, bool trans_m,
     K = mdim2; /** == dim2 */
     N = mdim1;
     M = dim1;
-    if (getFormat() == Tformat::NHWC) {
-      CREATE_IF_EMPTY_DIMS(result, batch(), N, height(), width(),
-                           Tformat::NHWC);
-    } else {
-      CREATE_IF_EMPTY_DIMS(result, batch(), channel(), height(), N);
-      CREATE_IF_EMPTY_DIMS(result, batch(), channel(), height(), N);
-      CREATE_IF_EMPTY_DIMS(result, batch(), channel(), height(), N);
-    }
+    CREATE_IF_EMPTY_DIMS(result, batch(), channel(), height(), N, getTensorType());
   } else if (trans && !trans_m) {
     if (dim1 != mdim1)
       throw std::runtime_error(
@@ -1459,12 +1444,7 @@ Tensor &Tensor::dot(Tensor const &m, Tensor &result, bool trans, bool trans_m,
     K = mdim1; /** == dim1 */
     N = mdim2;
     M = dim2;
-
-    if (getFormat() == Tformat::NHWC) {
-      CREATE_IF_EMPTY_DIMS(result, 1, N, M, 1, Tformat::NHWC);
-    } else {
-      CREATE_IF_EMPTY_DIMS(result, 1, 1, M, N);
-    }
+    CREATE_IF_EMPTY_DIMS(result, 1, 1, M, N, getTensorType());
   } else {
     if (dim1 != mdim2)
       throw std::runtime_error(
@@ -1472,11 +1452,7 @@ Tensor &Tensor::dot(Tensor const &m, Tensor &result, bool trans, bool trans_m,
     K = mdim2; /** == dim1 */
     N = mdim1;
     M = dim2;
-    if (getFormat() == Tformat::NHWC) {
-      CREATE_IF_EMPTY_DIMS(result, 1, N, M, 1, Tformat::NHWC);
-    } else {
-      CREATE_IF_EMPTY_DIMS(result, 1, 1, M, N);
-    }
+    CREATE_IF_EMPTY_DIMS(result, 1, 1, M, N,getTensorType());
   }
   lda = dim2;
   ldb = mdim2;
@@ -1727,8 +1703,8 @@ Tensor &Tensor::apply(std::function<Tensor &(Tensor, Tensor &)> f,
 
 void Tensor::print(std::ostream &out) const {
   printInstance(out, this);
-  const float *data = getData();
-
+  if (getDataType() == ml::train::TensorDim::DataType::FP32){
+    const __fp16 *data = getData<__fp16>();
   unsigned int len = size();
   out << "data addr: " << data << '\n';
   out << dim;
@@ -1798,6 +1774,36 @@ void Tensor::print(std::ostream &out) const {
     }
   }
   out.copyfmt(init);
+  } else if (getDataType() == ml::train::TensorDim::DataType::FP16) {
+    const __fp16 *data = getData<__fp16>();
+    unsigned int len = size();
+    out << "data addr: " << data << '\n';
+    out << dim;
+
+    if (len > 100) {
+      out << '[' << data[0] << ' ' << data[1] << ' ' << data[2] << " ... "
+          << data[len - 3] << ' ' << data[len - 2] << ' ' << data[len - 1]
+          << ']' << std::endl;
+      return;
+    }
+
+    std::ios init(NULL);
+    init.copyfmt(out);
+    for (unsigned int k = 0; k < dim.batch(); k++) {
+      for (unsigned int l = 0; l < dim.channel(); l++) {
+        for (unsigned int i = 0; i < dim.height(); i++) {
+          for (unsigned int j = 0; j < dim.width(); j++) {
+            out << std::setw(10) << std::setprecision(10)
+                << this->getValue<__fp16>(k, l, i, j) << " ";
+          }
+          out << std::endl;
+        }
+        out << std::endl;
+      }
+      out << "-------" << std::endl;
+    }
+    out.copyfmt(init);
+  }
 }
 
 std::ostream &operator<<(std::ostream &out, Tensor const &m) {
@@ -1812,8 +1818,15 @@ void Tensor::copy(const void *buf) {
   if (buf == getData()) {
     return;
   }
+  // std::string type_ =
+  //   (getDataType() == ml::train::TensorDim::DataType::FP16) ? "FP16" : "NO";
+  // std::cout << type_ << std::endl;
 
-  scopy(size(), buf, 1, getData(), 1, getDataType());
+  if(getDataType() == ml::train::TensorDim::DataType::FP16){
+    scopy(size(), (__fp16*)buf, 1, getData<__fp16>(), 1);
+  }else if(getDataType() == ml::train::TensorDim::DataType::FP32){
+    scopy(size(), (float*)buf, 1, getData<float>(), 1);
+  }
 }
 
 void Tensor::copy_with_stride(const Tensor &from) {
@@ -1849,7 +1862,8 @@ void Tensor::copy(const Tensor &from) {
     throw std::runtime_error("Cannot copy non-contiguous tensor");
   }
 
-  if (from.size() != 0 && size() == from.size()) {
+  if (from.size() != 0 && size() == from.size() &&
+      getDataType() == from.getDataType()) {
     reshape(from.getDim());
     copy(from.getData());
   } else {
@@ -2022,12 +2036,12 @@ void Tensor::setValue(float val) {
 }
 
 void Tensor::setZero() {
-  if (data_type == nntrainer::DataType::FP32) {
+  if (dim.getDataType() == ml::train::TensorDim::DataType::FP32) {
     if (contiguous)
       sscal(size(), 0, getData<float>(), 1);
     else
       apply_i([](float val) -> float { return 0; });
-  } else if (data_type == nntrainer::DataType::FP16) {
+  } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) {
     if (contiguous)
       sscal(size(), 0, getData<__fp16>(), 1);
     else
index 9307e94..0a4613f 100644 (file)
@@ -57,6 +57,7 @@ namespace nntrainer {
 
 using TensorDim = ml::train::TensorDim;
 using Tformat = ml::train::TensorDim::Format;
+using Tdatatype = ml::train::TensorDim::DataType;
 
 class LazyTensor;
 class SrcSharedTensor;
@@ -83,35 +84,19 @@ public:
     NONE            /** No initialization */
   };
 
-  void setSizeOf(nntrainer::DataType d_type) {
-    switch (d_type) {
-    case nntrainer::DataType::FP16:
-      sizeof_d = sizeof(__fp16);
-      return;
-    case nntrainer::DataType::FP32:
-      sizeof_d = sizeof(float);
-      return;
-    default:
-      return;
-    }
-  }
-
   /**
    * @brief     Basic Constructor of Tensor
    */
   Tensor(std::string name_ = "", Tformat fm = Tformat::NCHW,
-         nntrainer::DataType d_type = nntrainer::DataType::FP32) :
-    dim(TensorDim(fm)),
+         Tdatatype d_type = Tdatatype::FP32) :
+    dim(TensorDim(fm, d_type)),
     strides(dim.computeStrides()),
     contiguous(true),
     initializer(Initializer::NONE),
     name(name_),
-    data_type(d_type),
     data(nullptr),
     offset(0),
-    src_tensor() {
-    setSizeOf(d_type);
-  }
+    src_tensor() {}
 
   /**
    * @brief     Constructor of Tensor with dimension, possibly lazily
@@ -121,8 +106,7 @@ public:
    * @param name Name of the tensor
    */
   Tensor(const TensorDim &d, bool alloc_now,
-         Initializer init = Initializer::NONE, std::string name = "",
-         nntrainer::DataType d_type = nntrainer::DataType::FP32);
+         Initializer init = Initializer::NONE, std::string name = "");
 
   /**
    * @brief     Constructor of Tensor with dimension/buf
@@ -130,8 +114,7 @@ public:
    * @param buf buffer
    * @note Memory for this tensor is instantaneously allocated
    */
-  Tensor(const TensorDim &d, const void *buf = nullptr,
-         nntrainer::DataType d_type = nntrainer::DataType::FP32);
+  Tensor(const TensorDim &d, const void *buf = nullptr);
 
   /**
    * @brief     Constructor of Tensor
@@ -141,8 +124,9 @@ public:
    * @param[in] d3 Width
    */
   Tensor(size_t d0, size_t d1, size_t d2, size_t d3, Tformat fm = Tformat::NCHW,
-         nntrainer::DataType d_type = nntrainer::DataType::FP32) :
-    Tensor(TensorDim(d0, d1, d2, d3, fm), nullptr, d_type){};
+         Tdatatype d_type = Tdatatype::FP32) :
+    Tensor(TensorDim(d0, d1, d2, d3, fm, d_type), nullptr){
+  };
 
   /**
    * @brief     Constructor of Tensor
@@ -151,7 +135,7 @@ public:
    * @param[in] d3 Width
    */
   Tensor(size_t d1, size_t d2, size_t d3, Tformat fm = Tformat::NCHW,
-         nntrainer::DataType d_type = nntrainer::DataType::FP32) :
+         Tdatatype d_type = Tdatatype::FP32) :
     Tensor(1, d1, d2, d3, fm, d_type){};
 
   /**
@@ -160,7 +144,7 @@ public:
    * @param[in] d3 Width (NCHW) or Channel (NHWC)
    */
   Tensor(size_t d2, size_t d3, Tformat fm = Tformat::NCHW,
-         nntrainer::DataType d_type = nntrainer::DataType::FP32) :
+         Tdatatype d_type = Tdatatype::FP32) :
     Tensor(1, 1, d2, d3, fm, d_type){};
 
   /**
@@ -168,9 +152,46 @@ public:
    * @param[in] d3 Width (NCHW) or Channel (NHWC)
    */
   explicit Tensor(size_t d3, Tformat fm = Tformat::NCHW,
-                  nntrainer::DataType d_type = nntrainer::DataType::FP32) :
+                  Tdatatype d_type = Tdatatype::FP32) :
     Tensor(1, 1, 1, d3, fm, d_type){};
 
+
+  /**
+   * @brief     Constructor of Tensor
+   * @param[in] d0 Batch of Tensor
+   * @param[in] d1 Channel (NCHW) or Height (NHWC)
+   * @param[in] d2 Height (NCHW) or Width (NHWC)
+   * @param[in] d3 Width (NCHW) or Channel (NHWC)
+   */
+  Tensor(size_t d0, size_t d1, size_t d2, size_t d3, ml::train::TensorDim::TensorType t_type) :
+    Tensor(TensorDim(d0, d1, d2, d3, t_type), nullptr){
+  };
+
+  /**
+   * @brief     Constructor of Tensor
+   * @param[in] d1 Channel (NCHW) or Height (NHWC)
+   * @param[in] d2 Height (NCHW) or Width (NHWC)
+   * @param[in] d3 Width (NCHW) or Channel (NHWC)
+   */
+  Tensor(size_t d1, size_t d2, size_t d3, ml::train::TensorDim::TensorType t_type) :
+    Tensor(1, d1, d2, d3, t_type){};
+
+  /**
+   * @brief     Constructor of Tensor with batch size one and d1 size one
+   * @param[in] d2 Height (NCHW) or Width (NHWC)
+   * @param[in] d3 Width (NCHW) or Channel (NHWC)
+   */
+  Tensor(size_t d2, size_t d3,ml::train::TensorDim::TensorType t_type) :
+    Tensor(1, 1, d2, d3, t_type){};
+
+  /**
+   * @brief     Constructor of Tensor with just Width or Channel
+   * @param[in] d3 Width (NCHW) or Channel (NHWC)
+   */
+  explicit Tensor(size_t d3, ml::train::TensorDim::TensorType t_type) :
+    Tensor(1, 1, 1, d3, t_type){};
+  
+
   /**
    * @brief     Constructor of Tensor
    * @param[in] d data for the Tensor. It needs to set format properly.
@@ -188,14 +209,15 @@ public:
     dim.width(d[0][0][0].size());
     strides = dim.computeStrides();
 
-    auto mem_data = new MemoryData((void *)(new float[dim.getDataLen()]()));
-    data = std::shared_ptr<MemoryData>(
-      mem_data, [](auto *mem_data) { delete[](float *) mem_data->getAddr(); });
+    MemoryData* mem_data = new MemoryData((void *)(new float[dim.getDataLen()]()));
+    data = std::shared_ptr<MemoryData>(mem_data, [](MemoryData *mem_data) {
+      delete[] mem_data->getAddr<float>();
+    });
     offset = 0;
     contiguous = true;
     initializer = Initializer::NONE;
 
-    setDataType(DataType::FP32);
+    setDataType(Tdatatype::FP32);
 
     for (unsigned int i = 0; i < dim.batch(); ++i)
       for (unsigned int j = 0; j < dim.channel(); ++j)
@@ -235,14 +257,15 @@ public:
     dim.width(d[0][0][0].size());
     strides = dim.computeStrides();
 
-    auto mem_data = new MemoryData((void *)(new __fp16[dim.getDataLen()]()));
-    data = std::shared_ptr<MemoryData>(
-      mem_data, [](auto *mem_data) { delete[](__fp16 *) mem_data->getAddr(); });
+    MemoryData* mem_data = new MemoryData((void *)(new __fp16[dim.getDataLen()]()));
+    data = std::shared_ptr<MemoryData>(mem_data, [](MemoryData *mem_data) {
+      delete[] mem_data->getAddr<__fp16>();
+    });
     offset = 0;
     contiguous = true;
     initializer = Initializer::NONE;
 
-    setDataType(DataType::FP16);
+    setDataType(Tdatatype::FP16);
 
     for (unsigned int i = 0; i < dim.batch(); ++i)
       for (unsigned int j = 0; j < dim.channel(); ++j)
@@ -752,7 +775,7 @@ public:
    */
   Tensor &erf(Tensor &out) const;
 
-  unsigned int sizeofData() { return sizeof_d; }
+  unsigned int sizeofData() { return dim.getDataTypeSize(); }
 
   /**
    * @brief     Dot Product of Tensor ( equal MxM )
@@ -1095,7 +1118,7 @@ public:
    * @retval    Tensor
    */
   Tensor &apply(std::function<float(float)> f, Tensor &output) const {
-    CREATE_IF_EMPTY_DIMS(output, dim, nullptr, data_type);
+    CREATE_IF_EMPTY_DIMS(output, dim, nullptr);
 
     if (dim != output.dim) {
       /// @todo add unittest
@@ -1103,7 +1126,7 @@ public:
         "[Tensor::apply] output dimension does not match");
     }
 
-    if (data_type == nntrainer::DataType::FP32) {
+    if (dim.getDataType() == Tdatatype::FP32) {
       if (contiguous && output.contiguous) {
         const float *data = (getData<float>());
         float *rdata = (output.getData<float>());
@@ -1131,7 +1154,7 @@ public:
           }
         }
       }
-    } else if (data_type == nntrainer::DataType::FP16) {
+    } else if (dim.getDataType() == Tdatatype::FP16) {
       if (contiguous && output.contiguous) {
         const __fp16 *data = (getData<__fp16>());
         __fp16 *rdata = (output.getData<__fp16>());
@@ -1213,7 +1236,7 @@ public:
    * @brief     Get size of the data in bytes
    * @retval    size_t Size in bytes
    */
-  size_t bytes() const { return size() * sizeof_d; }
+  size_t bytes() const { return size() * dim.getDataTypeSize(); }
 
   /**
    * @brief     Set the element value
@@ -1225,9 +1248,9 @@ public:
    */
   void setValue(unsigned int batch, unsigned int c, unsigned int h,
                 unsigned int w, float value) noexcept {
-    if (data_type == nntrainer::DataType::FP32) {
+    if (dim.getDataType() == Tdatatype::FP32) {
       getData<float>()[getIndex(batch, c, h, w)] = value;
-    } else if (data_type == nntrainer::DataType::FP16) {
+    } else if (dim.getDataType() == Tdatatype::FP16) {
       getData<__fp16>()[getIndex(batch, c, h, w)] = value;
     }
   }
@@ -1244,9 +1267,9 @@ public:
   void addValue(unsigned int batch, unsigned int c, unsigned int h,
                 unsigned int w, float value, float beta) noexcept {
     auto const &idx = getIndex(batch, c, h, w);
-    if (data_type == nntrainer::DataType::FP32) {
+    if (dim.getDataType() == Tdatatype::FP32) {
       *(float *)(getData(idx)) = value + *(float *)(getData(idx)) * beta;
-    } else if (data_type == nntrainer::DataType::FP16) {
+    } else if (dim.getDataType() == Tdatatype::FP16) {
       *(__fp16 *)(getData(idx)) = value + *(__fp16 *)(getData(idx)) * beta;
     }
   }
@@ -1466,6 +1489,9 @@ public:
    */
   size_t getTensorDim(unsigned int axis);
 
+
+  ml::train::TensorDim::TensorType getTensorType() const {return dim.getTensorType();}
+
   /**
    * @brief     return Tensor batch size
    * @retval    batch size
@@ -1491,6 +1517,13 @@ public:
   size_t width() const { return dim.width(); }
 
   /**
+   * @brief     return Tensor Data Type Size
+   * @retval    data type size
+   */
+  uint getDataTypeSize() const { return dim.getDataTypeSize(); }
+  
+
+  /**
    * @brief     update batch size for this tensor
    * @param     batch size
    * @note      The batchsize of src_tensor need not be related with this
@@ -1530,7 +1563,7 @@ public:
       return nullptr;
 
     data->validate();
-    return (T *)((T *)(data->getAddr()) + offset);
+    return (T *)((data->getAddr<T>()) + offset);
   }
 
   /**
@@ -1542,7 +1575,7 @@ public:
       return nullptr;
 
     data->validate();
-    return (T *)((T *)data->getAddr() + offset);
+    return (T *)(data->getAddr<T>() + offset);
   }
 
   /**
@@ -1553,16 +1586,13 @@ public:
     if (!data)
       return nullptr;
 
-    size_t index = idx * sizeof_d;
+    size_t index = idx * sizeof(T);
 
     data->validate();
-    return (T *)((T *)data->getAddr() + offset + index);
+    return (T *)(data->getAddr<T>() + offset + index);
   }
 
-  void setDataType(nntrainer::DataType d_type) {
-    data_type = d_type;
-    setSizeOf(data_type);
-  }
+  void setDataType(Tdatatype d_type) { dim.setDataType(d_type); }
 
   /**
    * @brief     put data of Tensor
@@ -1697,7 +1727,7 @@ public:
    *
    * @return data type of the tensor
    */
-  nntrainer::DataType getDataType() const { return data_type; }
+  Tdatatype getDataType() const { return dim.getDataType(); }
 
   static constexpr float epsilon = 1e-5;
 
@@ -1708,10 +1738,8 @@ private:
   bool contiguous;
   Tensor::Initializer initializer;
   std::string name; /**< name of the tensor */
-  nntrainer::DataType data_type;
   std::shared_ptr<MemoryData> data;
   unsigned int offset;
-  unsigned int sizeof_d;
 
   /**<
    * When using shared_data with tensor, this stores the ptr of the source
index 95d0481..eb954e3 100644 (file)
 #include <nntrainer_log.h>
 #include <tensor_dim.h>
 #include <util_func.h>
+#include <iostream>
 
 namespace ml {
 namespace train {
 
-TensorDim::TensorDim(Format fm, const std::bitset<MAXDIM> &eff_dim_flag_,
+TensorDim::TensorDim(TensorDim::Format fm, TensorDim::DataType d_type,
+                     const std::bitset<MAXDIM> &eff_dim_flag_,
+                     const std::bitset<MAXDIM> &dyn_dim_flag_) :
+  TensorDim(TensorDim::TensorType(fm, d_type), eff_dim_flag_, dyn_dim_flag_) {}
+
+TensorDim::TensorDim(TensorType t_type_,
+                     const std::bitset<MAXDIM> &eff_dim_flag_,
                      const std::bitset<MAXDIM> &dyn_dim_flag_) :
-  format(fm),
+  t_type(t_type_),
   eff_dim_flag(eff_dim_flag_),
   dyn_dim_flag(dyn_dim_flag_) {
   for (size_t i = 0; i < MAXDIM; ++i) {
@@ -37,8 +44,8 @@ TensorDim::TensorDim(Format fm, const std::bitset<MAXDIM> &eff_dim_flag_,
   feature_len = 0;
 }
 
-TensorDim::TensorDim(std::initializer_list<size_t> dims, Format fm) :
-  TensorDim(fm) {
+TensorDim::TensorDim(std::initializer_list<size_t> dims, TensorType t_type_) :
+  TensorDim(t_type_) {
   int shift_size = MAXDIM - dims.size();
 
   if (shift_size < 0) {
@@ -53,13 +60,22 @@ TensorDim::TensorDim(std::initializer_list<size_t> dims, Format fm) :
   }
 }
 
-TensorDim::TensorDim(const std::array<size_t, 3> &shapes, Format fm) :
-  TensorDim({shapes[0], shapes[1], shapes[2]}, fm) {}
+// TensorDim::TensorDim(std::initializer_list<size_t> dims, TensorDim::Format fm,
+//                      TensorDim::DataType d_type) :
+//   TensorDim(dims, TensorType{fm, d_type}) {}
+
+TensorDim::TensorDim(const std::array<size_t, 3> &shapes, TensorType t_type_) :
+  TensorDim({shapes[0], shapes[1], shapes[2]}, t_type_) {}
+
+// TensorDim::TensorDim(const std::array<size_t, 3> &shapes, TensorDim::Format fm,
+//                      TensorDim::DataType d_type) :
+  // TensorDim({shapes[0], shapes[1], shapes[2]}, TensorType{fm, d_type}) {}
 
-TensorDim::TensorDim(size_t d0, size_t d1, size_t d2, size_t d3, Format fm,
+TensorDim::TensorDim(size_t d0, size_t d1, size_t d2, size_t d3,
+                     TensorType t_type_,
                      const std::bitset<MAXDIM> &eff_dim_flag_,
                      const std::bitset<MAXDIM> &dyn_dim_flag_) :
-  TensorDim(fm, eff_dim_flag_, dyn_dim_flag_) {
+  TensorDim(t_type_, eff_dim_flag_, dyn_dim_flag_) {
 
   setTensorDim(0, d0);
   setTensorDim(1, d1);
@@ -69,8 +85,24 @@ TensorDim::TensorDim(size_t d0, size_t d1, size_t d2, size_t d3, Format fm,
   len = d0 * feature_len;
 }
 
-TensorDim::TensorDim(const std::string &shape, Format fm) : TensorDim() {
-  if (setTensorDim(shape, fm) != ML_ERROR_NONE) {
+TensorDim::TensorDim(size_t d0, size_t d1, size_t d2, size_t d3,
+                     TensorDim::Format fm, TensorDim::DataType d_type,
+                     const std::bitset<MAXDIM> &eff_dim_flag_,
+                     const std::bitset<MAXDIM> &dyn_dim_flag_) :
+  TensorDim(d0, d1, d2, d3, TensorType(fm, d_type), eff_dim_flag_,
+            dyn_dim_flag_) {}
+
+TensorDim::TensorDim(const std::string &shape, TensorType t_type_) :
+  TensorDim() {
+  if (setTensorDim(shape, t_type_) != ML_ERROR_NONE) {
+    throw std::invalid_argument("[TensorDim] Setting TensorDim failed");
+  }
+}
+
+TensorDim::TensorDim(const std::string &shape, TensorDim::Format fm,
+                     TensorDim::DataType d_type) :
+  TensorDim() {
+  if (setTensorDim(shape, TensorType(fm, d_type)) != ML_ERROR_NONE) {
     throw std::invalid_argument("[TensorDim] Setting TensorDim failed");
   }
 }
@@ -90,6 +122,17 @@ TensorDim &TensorDim::operator=(TensorDim &&rhs) noexcept {
   return *this;
 }
 
+uint TensorDim::getDataTypeSize()const {
+  switch (t_type.data_type) {
+  case TensorDim::DataType::FP16:
+    return sizeof(__fp16);
+  case TensorDim::DataType::FP32:
+    return sizeof(float);
+  default:
+    return sizeof(float);
+  }
+}
+
 void TensorDim::resetLen() {
   feature_len = dim[1] * dim[2] * dim[3];
   len = dim[0] * feature_len;
@@ -122,7 +165,8 @@ void TensorDim::setTensorDim(unsigned int idx, size_t value) {
   resetLen();
 }
 
-int TensorDim::setTensorDim(const std::string &input_shape, Format fm) {
+int TensorDim::setTensorDim(const std::string &input_shape,
+                            TensorType t_type_) {
   int status = ML_ERROR_NONE;
   static const std::regex words_regex("[^\\s.,:;!?]+");
   auto words_begin =
@@ -137,10 +181,15 @@ int TensorDim::setTensorDim(const std::string &input_shape, Format fm) {
   for (std::sregex_iterator i = words_begin; i != words_end; ++i, ++cn) {
     setTensorDim(MAXDIM - cur_dim + cn, std::stoul((*i).str()));
   }
-  format = fm;
+  t_type = t_type_;
   return status;
 }
 
+// int TensorDim::setTensorDim(const std::string &input_shape,
+//                             TensorDim::Format fm, TensorDim::DataType d_type) {
+//   return setTensorDim(input_shape, TensorType{fm, d_type});
+// }
+
 void TensorDim::setEffDimFlag(const std::bitset<MAXDIM> &dim_flag_) {
   eff_dim_flag = dim_flag_;
 }
@@ -164,16 +213,22 @@ void swap(TensorDim &lhs, TensorDim &rhs) noexcept {
   std::swap(lhs.feature_len, rhs.feature_len);
   std::swap(lhs.eff_dim_flag, rhs.eff_dim_flag);
   std::swap(lhs.dyn_dim_flag, rhs.dyn_dim_flag);
-  std::swap(lhs.format, rhs.format);
+  std::swap(lhs.t_type, rhs.t_type);
 }
 
 size_t TensorDim::batch() const { return dim[0]; };
 
-size_t TensorDim::channel() const { return dim[1]; };
+size_t TensorDim::channel() const {
+  return t_type.format == Format::NCHW ? dim[1] : dim[3];
+};
 
-size_t TensorDim::height() const { return dim[2]; };
+size_t TensorDim::height() const {
+  return t_type.format == Format::NCHW ? dim[2] : dim[1];
+};
 
-size_t TensorDim::width() const { return dim[3]; };
+size_t TensorDim::width() const {
+  return t_type.format == Format::NCHW ? dim[3] : dim[2];
+};
 
 size_t TensorDim::getDataLen() const { return len; };
 
@@ -181,11 +236,20 @@ size_t TensorDim::getFeatureLen() const { return feature_len; };
 
 void TensorDim::batch(size_t b) { setTensorDim(0, b); }
 
-void TensorDim::channel(size_t c) { setTensorDim(1, c); }
+void TensorDim::channel(size_t c) {
+  uint i = (t_type.format == Format::NCHW) ? 1 : 3;
+  setTensorDim(i, c);
+}
 
-void TensorDim::height(size_t h) { setTensorDim(2, h); }
+void TensorDim::height(size_t h) {
+  uint i = (t_type.format == Format::NCHW) ? 2 : 1;
+  setTensorDim(i, h);
+}
 
-void TensorDim::width(size_t w) { setTensorDim(3, w); }
+void TensorDim::width(size_t w) {
+  uint i = (t_type.format == Format::NCHW) ? 3 : 2;
+  setTensorDim(i, w);
+}
 
 const size_t *TensorDim::getDim() const { return dim; }
 
@@ -215,7 +279,10 @@ TensorDim TensorDim::transpose(const std::array<size_t, MAXDIM> &axes) const {
 }
 
 bool TensorDim::operator==(const TensorDim &rhs) const {
-  if (this->format != rhs.format)
+  if (this->t_type.format != rhs.t_type.format)
+    return false;
+
+  if (this->t_type.data_type != rhs.t_type.data_type)
     return false;
 
   for (size_t i = 0; i < MAXDIM; ++i) {
@@ -291,7 +358,12 @@ std::vector<int> TensorDim::getEffectiveDimension(bool dynamic) const {
 bool TensorDim::is_dynamic() const { return dyn_dim_flag.any(); }
 
 std::ostream &operator<<(std::ostream &out, TensorDim const &d) {
-  out << "Shape: " << d[0] << ":" << d[1] << ":" << d[2] << ":" << d[3]
+  std::string type_ =
+    (d.getDataType() == ml::train::TensorDim::DataType::FP16) ? "FP16" : "FP32";
+  std::string format_ =
+    (d.getFormat() == ml::train::TensorDim::Format::NCHW) ? "NCHW" : "NHWC";
+  out << "Shape: " << d.batch() << ":" << d.channel() << ":" << d.height()
+      << ":" << d.width() << " [ " << type_ << " : " << format_ << " ]"
       << std::endl;
   return out;
 }
index 5f78624..9b129b5 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "neuralnet.h"
 #include "nntrainer_test_util.h"
+#include <set>
 
 nntrainer::NeuralNetwork
 genModel(const std::vector<LayerRepresentation> &layers) {
index 6857a7f..f48d0ed 100644 (file)
@@ -3,7 +3,7 @@ test_name = 'unittest_compiler'
 test_target = [
   'compiler_test_util.cpp',
   'unittest_compiler.cpp',
-  'unittest_interpreter.cpp',
+#  'unittest_interpreter.cpp',
   'unittest_realizer.cpp'
 ]
 
index cddaa03..5c092c5 100644 (file)
 #include <gtest/gtest.h>
 
 #include <compiler.h>
+
+#ifdef NDK_BUILD
+
+int main(int argc, char **argv) {
+  int result = -1;
+
+  try {
+    testing::InitGoogleTest(&argc, argv);
+  } catch (...) {
+    std::cerr << "Error duing InitGoogleTest" << std::endl;
+    return 0;
+  }
+
+  try {
+    result = RUN_ALL_TESTS();
+  } catch (...) {
+    std::cerr << "Error duing RUN_ALL_TESTS()" << std::endl;
+  }
+
+  return result;
+}
+#endif
index e42b514..4ff3ec2 100644 (file)
@@ -46,7 +46,7 @@ public:
  * @brief load synchronously
  */
 TEST_F(CacheLoaderTest, load_01_p) {
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   EXPECT_NO_THROW(pool->planLayout(nntrainer::OptimizedV1Planner()));
   EXPECT_NO_THROW(pool->allocate());
@@ -85,7 +85,7 @@ TEST_F(CacheLoaderTest, load_01_p) {
  * @brief load synchronously multiple
  */
 TEST_F(CacheLoaderTest, load_02_p) {
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   auto idx2 = pool->requestMemory(4, 3, 8, {3, 4, 5, 6, 7, 8});
   auto idx3 = pool->requestMemory(4, 2, 4, {2, 3, 4});
@@ -162,7 +162,7 @@ TEST_F(CacheLoaderTest, load_02_p) {
  * @brief load asynchronously
  */
 TEST_F(CacheLoaderTest, load_async_01_p) {
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   EXPECT_NO_THROW(pool->planLayout(nntrainer::OptimizedV1Planner()));
   EXPECT_NO_THROW(pool->allocate());
@@ -192,7 +192,7 @@ TEST_F(CacheLoaderTest, load_async_01_p) {
  * @brief load asynchronously
  */
 TEST_F(CacheLoaderTest, load_async_02_p) {
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   auto idx2 = pool->requestMemory(4, 3, 8, {3, 4, 5, 6, 7, 8});
   auto idx3 = pool->requestMemory(4, 2, 4, {2, 3, 4});
@@ -411,7 +411,7 @@ TEST_F(CacheLoaderTest, load_async_02_p) {
  * @brief load asynchronously (discontinous order)
  */
 TEST_F(CacheLoaderTest, load_async_03_p) {
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5, {1, 2, 5});
   auto idx2 = pool->requestMemory(4, 3, 8, {3, 4, 7, 8});
   auto idx3 = pool->requestMemory(4, 2, 4, {2, 3, 4});
index 6161647..6f12e05 100644 (file)
@@ -79,7 +79,7 @@ TEST_F(CachePoolTest, get_memory_01_p) {
   EXPECT_CALL(*pool, validate).Times(0);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(1));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(1, 4, 5);
   EXPECT_NO_THROW(pool->planLayout(nntrainer::BasicPlanner()));
   EXPECT_NO_THROW(pool->allocate());
@@ -88,8 +88,8 @@ TEST_F(CachePoolTest, get_memory_01_p) {
   EXPECT_NE(mem, nullptr);
 
   /* cache addr is invalid until validate() called */
-  EXPECT_EQ(mem->getAddr(), nullptr);
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -101,18 +101,18 @@ TEST_F(CachePoolTest, validate_01_p) {
   EXPECT_CALL(*pool, validate).Times(1);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(1));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(1, 4, 5);
   EXPECT_NO_THROW(pool->planLayout(nntrainer::BasicPlanner()));
   EXPECT_NO_THROW(pool->allocate());
   EXPECT_NO_THROW(mem = pool->getMemory(idx));
   EXPECT_NE(mem, nullptr);
   /* cache addr is invalid until validate() called */
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   /* cache addr is valid after validate() called */
   mem->validate();
-  EXPECT_NE(mem->getAddr(), nullptr);
+  EXPECT_NE(mem->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -124,22 +124,22 @@ TEST_F(CachePoolTest, validate_02_p) {
   EXPECT_CALL(*pool, validate).Times(1);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(1));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(1, 4, 5);
   EXPECT_NO_THROW(pool->planLayout(nntrainer::BasicPlanner()));
   EXPECT_NO_THROW(pool->allocate());
   EXPECT_NO_THROW(mem = pool->getMemory(idx));
   EXPECT_NE(mem, nullptr);
   /* cache addr is invalid until validate() called */
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   /* cache addr is valid after validate() called */
   mem->validate();
-  EXPECT_NE(mem->getAddr(), nullptr);
+  EXPECT_NE(mem->getAddr<float>(), nullptr);
 
   /* double call for validate() has no effect for cache pool validate */
   mem->validate();
-  EXPECT_NE(mem->getAddr(), nullptr);
+  EXPECT_NE(mem->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -151,21 +151,21 @@ TEST_F(CachePoolTest, invalidate_01_p) {
   EXPECT_CALL(*pool, validate).Times(1);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(2));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(1, 4, 5);
   EXPECT_NO_THROW(pool->planLayout(nntrainer::BasicPlanner()));
   EXPECT_NO_THROW(pool->allocate());
   EXPECT_NO_THROW(mem = pool->getMemory(idx));
   EXPECT_NE(mem, nullptr);
   /* cache addr is invalid until validate() called */
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   /* cache addr is valid after validate() called */
   mem->validate();
-  EXPECT_NE(mem->getAddr(), nullptr);
+  EXPECT_NE(mem->getAddr<float>(), nullptr);
   /* invalidate() call makes cache addr invalid */
   mem->invalidate();
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -177,24 +177,24 @@ TEST_F(CachePoolTest, invalidate_02_p) {
   EXPECT_CALL(*pool, validate).Times(1);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(2));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(1, 4, 5);
   EXPECT_NO_THROW(pool->planLayout(nntrainer::BasicPlanner()));
   EXPECT_NO_THROW(pool->allocate());
   EXPECT_NO_THROW(mem = pool->getMemory(idx));
   EXPECT_NE(mem, nullptr);
   /* cache addr is invalid until validate() called */
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   /* cache addr is valid after validate() called */
   mem->validate();
-  EXPECT_NE(mem->getAddr(), nullptr);
+  EXPECT_NE(mem->getAddr<float>(), nullptr);
   /* cache addr is invalid after invalidate() called */
   mem->invalidate();
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
   /* double call for invalidate() has no effect for cache pool invalidate */
   mem->invalidate();
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -206,29 +206,29 @@ TEST_F(CachePoolTest, validate_invalidate_01_p) {
   EXPECT_CALL(*pool, validate).Times(2);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(2));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
   auto idx = pool->requestMemory(4, 4, 5);
   EXPECT_NO_THROW(pool->planLayout(nntrainer::BasicPlanner()));
   EXPECT_NO_THROW(pool->allocate());
   EXPECT_NO_THROW(mem = pool->getMemory(idx));
   EXPECT_NE(mem, nullptr);
   /* cache addr is invalid until validate() called */
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   /**
    * The data wrote on valid addr is equal to the data after
    * swap out(invalidate) and in(validate).
    */
   mem->validate();
-  EXPECT_NE(mem->getAddr(), nullptr);
-  *(mem->getAddr()) = TEMP_DATA1;
+  EXPECT_NE(mem->getAddr<float>(), nullptr);
+  *(mem->getAddr<float>()) = TEMP_DATA1;
 
   mem->invalidate();
-  EXPECT_EQ(mem->getAddr(), nullptr);
+  EXPECT_EQ(mem->getAddr<float>(), nullptr);
 
   mem->validate();
-  EXPECT_NE(mem->getAddr(), nullptr);
-  EXPECT_EQ(*(mem->getAddr()), TEMP_DATA1);
+  EXPECT_NE(mem->getAddr<float>(), nullptr);
+  EXPECT_EQ(*(mem->getAddr<float>()), TEMP_DATA1);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -241,7 +241,7 @@ TEST_F(CachePoolTest, validate_invalidate_02_n) {
   EXPECT_CALL(*pool, validate).Times(6);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(6));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 2);
   auto idx2 = pool->requestMemory(4, 3, 4);
   auto idx3 = pool->requestMemory(4, 5, 6);
@@ -252,11 +252,11 @@ TEST_F(CachePoolTest, validate_invalidate_02_n) {
   EXPECT_NO_THROW(mem2 = pool->getMemory(idx2));
   EXPECT_NO_THROW(mem3 = pool->getMemory(idx3));
   EXPECT_NE(mem1, nullptr);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   EXPECT_NE(mem2, nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   EXPECT_NE(mem3, nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   /**
    * The data wrote on valid addr is equal to the data after
@@ -266,33 +266,33 @@ TEST_F(CachePoolTest, validate_invalidate_02_n) {
    * memory can be used for all.
    */
   mem1->validate();
-  EXPECT_NE(mem1->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
   mem2->validate();
-  EXPECT_NE(mem2->getAddr(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
   mem3->validate();
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
-  *(mem1->getAddr()) = TEMP_DATA1;
-  *(mem2->getAddr()) = TEMP_DATA2;
-  *(mem3->getAddr()) = TEMP_DATA3;
+  *(mem1->getAddr<float>()) = TEMP_DATA1;
+  *(mem2->getAddr<float>()) = TEMP_DATA2;
+  *(mem3->getAddr<float>()) = TEMP_DATA3;
 
   mem1->invalidate();
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   mem2->invalidate();
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   mem3->invalidate();
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
-  EXPECT_NE(mem1->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
   mem2->validate();
-  EXPECT_NE(mem2->getAddr(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
   mem3->validate();
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
-  EXPECT_EQ(*(mem1->getAddr()), TEMP_DATA3);
-  EXPECT_EQ(*(mem2->getAddr()), TEMP_DATA3);
-  EXPECT_EQ(*(mem3->getAddr()), TEMP_DATA3);
+  EXPECT_EQ(*(mem1->getAddr<float>()), TEMP_DATA3);
+  EXPECT_EQ(*(mem2->getAddr<float>()), TEMP_DATA3);
+  EXPECT_EQ(*(mem3->getAddr<float>()), TEMP_DATA3);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -305,7 +305,7 @@ TEST_F(CachePoolTest, validate_invalidate_03_p) {
   EXPECT_CALL(*pool, validate).Times(6);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(6));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5);
   auto idx2 = pool->requestMemory(4, 3, 8);
   auto idx3 = pool->requestMemory(4, 2, 4);
@@ -316,11 +316,11 @@ TEST_F(CachePoolTest, validate_invalidate_03_p) {
   EXPECT_NO_THROW(mem2 = pool->getMemory(idx2));
   EXPECT_NO_THROW(mem3 = pool->getMemory(idx3));
   EXPECT_NE(mem1, nullptr);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   EXPECT_NE(mem2, nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   EXPECT_NE(mem3, nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   /**
    * The data wrote on valid addr is equal to the data after
@@ -330,33 +330,33 @@ TEST_F(CachePoolTest, validate_invalidate_03_p) {
    * addr are different.
    */
   mem1->validate();
-  EXPECT_NE(mem1->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
   mem2->validate();
-  EXPECT_NE(mem2->getAddr(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
   mem3->validate();
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
-  *(mem1->getAddr()) = TEMP_DATA1;
-  *(mem2->getAddr()) = TEMP_DATA2;
-  *(mem3->getAddr()) = TEMP_DATA3;
+  *(mem1->getAddr<float>()) = TEMP_DATA1;
+  *(mem2->getAddr<float>()) = TEMP_DATA2;
+  *(mem3->getAddr<float>()) = TEMP_DATA3;
 
   mem1->invalidate();
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   mem2->invalidate();
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   mem3->invalidate();
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
-  EXPECT_NE(mem1->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
   mem2->validate();
-  EXPECT_NE(mem2->getAddr(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
   mem3->validate();
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
-  EXPECT_EQ(*(mem1->getAddr()), TEMP_DATA1);
-  EXPECT_EQ(*(mem2->getAddr()), TEMP_DATA2);
-  EXPECT_EQ(*(mem3->getAddr()), TEMP_DATA3);
+  EXPECT_EQ(*(mem1->getAddr<float>()), TEMP_DATA1);
+  EXPECT_EQ(*(mem2->getAddr<float>()), TEMP_DATA2);
+  EXPECT_EQ(*(mem3->getAddr<float>()), TEMP_DATA3);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -368,7 +368,7 @@ TEST_F(CachePoolTest, flush_01_p) {
   EXPECT_CALL(*pool, validate).Times(3);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(3));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   auto idx2 = pool->requestMemory(4, 3, 8, {3, 4, 5, 6, 7, 8});
   auto idx3 = pool->requestMemory(4, 2, 4, {2, 3, 4});
@@ -379,11 +379,11 @@ TEST_F(CachePoolTest, flush_01_p) {
   EXPECT_NO_THROW(mem2 = pool->getMemory(idx2));
   EXPECT_NO_THROW(mem3 = pool->getMemory(idx3));
   EXPECT_NE(mem1, nullptr);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   EXPECT_NE(mem2, nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   EXPECT_NE(mem3, nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   /**
    * Check loaded data are invalid after flush()
@@ -391,14 +391,14 @@ TEST_F(CachePoolTest, flush_01_p) {
   mem1->validate();
   mem2->validate();
   mem3->validate();
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   pool->flush();
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -410,7 +410,7 @@ TEST_F(CachePoolTest, loadExec_01_p) {
   EXPECT_CALL(*pool, validate).Times(14);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(3));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   auto idx2 = pool->requestMemory(4, 3, 8, {3, 4, 5, 6, 7, 8});
   auto idx3 = pool->requestMemory(4, 2, 4, {2, 3, 4});
@@ -421,61 +421,61 @@ TEST_F(CachePoolTest, loadExec_01_p) {
   EXPECT_NO_THROW(mem2 = pool->getMemory(idx2));
   EXPECT_NO_THROW(mem3 = pool->getMemory(idx3));
   EXPECT_NE(mem1, nullptr);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   EXPECT_NE(mem2, nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   EXPECT_NE(mem3, nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   /**
    * Check loaded data for each execution order
    */
   pool->loadExec(1);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   pool->loadExec(2);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   pool->loadExec(3);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   pool->loadExec(4);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   pool->loadExec(5);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   pool->loadExec(6);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   pool->loadExec(7);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   pool->loadExec(8);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
   pool->flush();
 
   EXPECT_NO_THROW(pool->deallocate());
@@ -488,7 +488,7 @@ TEST_F(CachePoolTest, unloadExec_01_p) {
   EXPECT_CALL(*pool, validate).Times(16);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(16));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   auto idx2 = pool->requestMemory(4, 3, 8, {3, 4, 5, 6, 7, 8});
   auto idx3 = pool->requestMemory(4, 2, 4, {2, 3, 4});
@@ -499,11 +499,11 @@ TEST_F(CachePoolTest, unloadExec_01_p) {
   EXPECT_NO_THROW(mem2 = pool->getMemory(idx2));
   EXPECT_NO_THROW(mem3 = pool->getMemory(idx3));
   EXPECT_NE(mem1, nullptr);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   EXPECT_NE(mem2, nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   EXPECT_NE(mem3, nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   /**
    * Check unloaded data for each execution order
@@ -513,72 +513,72 @@ TEST_F(CachePoolTest, unloadExec_01_p) {
   mem3->validate();
 
   pool->unloadExec(1);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
   mem2->validate();
   mem3->validate();
 
   pool->unloadExec(2);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
   mem2->validate();
   mem3->validate();
 
   pool->unloadExec(3);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
   mem2->validate();
   mem3->validate();
 
   pool->unloadExec(4);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
   mem2->validate();
   mem3->validate();
 
   pool->unloadExec(5);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
   mem2->validate();
   mem3->validate();
 
   pool->unloadExec(6);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
   mem2->validate();
   mem3->validate();
 
   pool->unloadExec(7);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   mem1->validate();
   mem2->validate();
   mem3->validate();
 
   pool->unloadExec(8);
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
@@ -590,7 +590,7 @@ TEST_F(CachePoolTest, load_unload_actives_01_p) {
   EXPECT_CALL(*pool, validate).Times(3);
   EXPECT_CALL(*pool, invalidate).Times(testing::AtLeast(3));
 
-  std::shared_ptr<nntrainer::MemoryData<float>> mem1, mem2, mem3;
+  std::shared_ptr<nntrainer::MemoryData> mem1, mem2, mem3;
   auto idx1 = pool->requestMemory(4, 1, 5, {1, 2, 3, 4, 5});
   auto idx2 = pool->requestMemory(4, 3, 8, {3, 4, 5, 6, 7, 8});
   auto idx3 = pool->requestMemory(4, 2, 4, {2, 3, 4});
@@ -601,11 +601,11 @@ TEST_F(CachePoolTest, load_unload_actives_01_p) {
   EXPECT_NO_THROW(mem2 = pool->getMemory(idx2));
   EXPECT_NO_THROW(mem3 = pool->getMemory(idx3));
   EXPECT_NE(mem1, nullptr);
-  EXPECT_EQ(mem1->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
   EXPECT_NE(mem2, nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
   EXPECT_NE(mem3, nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   /**
    * Check load and unload acives
@@ -615,29 +615,29 @@ TEST_F(CachePoolTest, load_unload_actives_01_p) {
   mem2->validate();
   mem3->validate();
 
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   pool->unloadActives();
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   pool->loadActives();
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   pool->unloadActives();
-  EXPECT_EQ(mem1->getAddr(), nullptr);
-  EXPECT_EQ(mem2->getAddr(), nullptr);
-  EXPECT_EQ(mem3->getAddr(), nullptr);
+  EXPECT_EQ(mem1->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem2->getAddr<float>(), nullptr);
+  EXPECT_EQ(mem3->getAddr<float>(), nullptr);
 
   pool->loadActives();
-  EXPECT_NE(mem1->getAddr(), nullptr);
-  EXPECT_NE(mem2->getAddr(), nullptr);
-  EXPECT_NE(mem3->getAddr(), nullptr);
+  EXPECT_NE(mem1->getAddr<float>(), nullptr);
+  EXPECT_NE(mem2->getAddr<float>(), nullptr);
+  EXPECT_NE(mem3->getAddr<float>(), nullptr);
 
   EXPECT_NO_THROW(pool->deallocate());
 }
index 69391a7..885ac1e 100644 (file)
@@ -260,7 +260,7 @@ TEST_P(MemoryPlannerValidate, validate_memory_full_overlap) {
 
   std::vector<unsigned int> tokens(MEM_QUANT);
   std::vector<size_t> memory_size(MEM_QUANT);
-  std::vector<std::shared_ptr<nntrainer::MemoryData<float>>> ptrs(MEM_QUANT);
+  std::vector<std::shared_ptr<nntrainer::MemoryData>> ptrs(MEM_QUANT);
 
   for (unsigned int idx = 0; idx < MEM_QUANT; idx++) {
     memory_size[idx] = dist(rng);
@@ -302,7 +302,7 @@ TEST_P(MemoryPlannerValidate, validate_memory_no_overlap) {
 
   std::vector<unsigned int> tokens(MEM_QUANT);
   std::vector<size_t> memory_size(MEM_QUANT);
-  std::vector<std::shared_ptr<nntrainer::MemoryData<float>>> ptrs(MEM_QUANT);
+  std::vector<std::shared_ptr<nntrainer::MemoryData>> ptrs(MEM_QUANT);
 
   unsigned int prev_idx = 0;
   for (unsigned int idx = 0; idx < MEM_QUANT; idx++) {
@@ -352,7 +352,7 @@ TEST_P(MemoryPlannerValidate, validate_memory_partial_overlap) {
 
   std::vector<unsigned int> tokens(MEM_QUANT);
   std::vector<size_t> memory_size(MEM_QUANT);
-  std::vector<std::shared_ptr<nntrainer::MemoryData<float>>> ptrs(MEM_QUANT);
+  std::vector<std::shared_ptr<nntrainer::MemoryData>> ptrs(MEM_QUANT);
 
   for (unsigned int idx = 0; idx < MEM_QUANT; idx++) {
     memory_size[idx] = dist(rng);
index ae175fd..4ce43c9 100644 (file)
@@ -424,7 +424,7 @@ TEST_P(MemoryPoolTest, get_memory_03_n) {
  */
 TEST_P(MemoryPoolTest, get_memory_04_p) {
   nntrainer::MemoryPool pool;
-  std::shared_ptr<nntrainer::MemoryData<float>> mem;
+  std::shared_ptr<nntrainer::MemoryData> mem;
 
   auto idx = pool.requestMemory(1, 4, 5);
   EXPECT_NO_THROW(pool.planLayout(nntrainer::BasicPlanner()));
index 71a7f47..9efde0f 100644 (file)
@@ -37,7 +37,7 @@ test_target = [
   ['unittest_nntrainer_internal', []],
   ['unittest_nntrainer_lazy_tensor', []],
   ['unittest_nntrainer_tensor', []],
-  ['unittest_nntrainer_tensor_nhwc', []],
+  ['unittest_nntrainer_tensor_fp16', []],
   ['unittest_util_func', []],
   ['unittest_nntrainer_modelfile', []],
   ['unittest_nntrainer_models', [
index ddaa0bd..4e2b173 100644 (file)
@@ -38,7 +38,35 @@ TEST(nntrainer_TensorDim, ctor_initializer_p) {
 }
 
 TEST(nntrianer_TensorDim, effective_dimension_p) {
-  nntrainer::TensorDim t(3, 2, 4, 5, nntrainer::Tformat::NCHW);
+  nntrainer::TensorDim t(3, 2, 4, 5, nntrainer::Tformat::NCHW, nntrainer::Tdatatype::FP32);
+  EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 4, 5}));
+
+  t.setEffDimFlag(0b1101);
+  EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 5}));
+
+  t.setEffDimFlag(0b0011);
+  EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({4, 5}));
+
+  t.setEffDimFlag(0b1111);
+  EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 4, 5}));
+
+  t.setEffDimFlag(0b1100);
+  EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2}));
+
+  t.setDynDimFlag(0b1100);
+  EXPECT_EQ(t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
+
+  auto copied_t = t;
+  EXPECT_EQ(copied_t.getEffectiveDimension(), std::vector<int>({3, 2}));
+  EXPECT_EQ(copied_t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
+
+  auto moved_t = std::move(copied_t);
+  EXPECT_EQ(moved_t.getEffectiveDimension(), std::vector<int>({3, 2}));
+  EXPECT_EQ(moved_t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
+}
+
+TEST(nntrianer_TensorDim, effective_dimension_nhwc_p) {
+  nntrainer::TensorDim t(3, 2, 4, 5, nntrainer::Tformat::NHWC, nntrainer::Tdatatype::FP32);
   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 4, 5}));
 
   t.setEffDimFlag(0b1101);
@@ -69,6 +97,12 @@ TEST(nntrainer_TensorDim, ctor_initializer_n) {
   EXPECT_THROW(nntrainer::TensorDim t({1, 2, 3, 4, 5}), std::invalid_argument);
 }
 
+TEST(nntrainer_TensorDim, ctor_initializer_nhwc_n) {
+  EXPECT_THROW(
+    nntrainer::TensorDim t({1, 2, 3, 4, 5}, nntrainer::Tformat::NHWC, nntrainer::Tdatatype::FP32),
+    std::invalid_argument);
+}
+
 TEST(nntrainer_TensorDim, setTensorDim_01_p) {
   int status = ML_ERROR_NONE;
 
@@ -77,6 +111,14 @@ TEST(nntrainer_TensorDim, setTensorDim_01_p) {
   EXPECT_EQ(status, ML_ERROR_NONE);
 }
 
+TEST(nntrainer_TensorDim, setTensorDim_01_nhwc_p) {
+  int status = ML_ERROR_NONE;
+
+  nntrainer::TensorDim tensor_dim;
+  status = tensor_dim.setTensorDim("1:2:3:4", {nntrainer::Tformat::NHWC, nntrainer::Tdatatype::FP32});
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
+
 TEST(nntrainer_TensorDim, setTensorDim_02_n) {
   int status = ML_ERROR_NONE;
 
@@ -85,6 +127,14 @@ TEST(nntrainer_TensorDim, setTensorDim_02_n) {
   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
 }
 
+TEST(nntrainer_TensorDim, setTensorDim_02__nhwc_n) {
+  int status = ML_ERROR_NONE;
+
+  nntrainer::TensorDim tensor_dim;
+  status = tensor_dim.setTensorDim("1:2:3:4:5", {nntrainer::Tformat::NHWC, nntrainer::Tdatatype::FP32});
+  EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
+}
+
 TEST(nntrainer_TensorDim, setTensorDim_03_n) {
   nntrainer::TensorDim d;
 
@@ -94,6 +144,15 @@ TEST(nntrainer_TensorDim, setTensorDim_03_n) {
   EXPECT_THROW(d.setTensorDim(3, 0), std::invalid_argument);
 }
 
+TEST(nntrainer_TensorDim, setTensorDim_03_nhwc_n) {
+  nntrainer::TensorDim d(nntrainer::Tformat::NHWC, nntrainer::Tdatatype::FP32);
+
+  EXPECT_THROW(d.setTensorDim(0, 0), std::invalid_argument);
+  EXPECT_THROW(d.setTensorDim(1, 0), std::invalid_argument);
+  EXPECT_THROW(d.setTensorDim(2, 0), std::invalid_argument);
+  EXPECT_THROW(d.setTensorDim(3, 0), std::invalid_argument);
+}
+
 TEST(nntrainer_TensorDim, setTensorDim_04_p) {
   nntrainer::TensorDim d;
 
@@ -108,6 +167,20 @@ TEST(nntrainer_TensorDim, setTensorDim_04_p) {
   EXPECT_EQ(d.width(), 7u);
 }
 
+TEST(nntrainer_TensorDim, setTensorDim_04_nhwc_p) {
+  nntrainer::TensorDim d(nntrainer::Tformat::NHWC, nntrainer::Tdatatype::FP32);
+
+  d.setTensorDim(0, 4);
+  d.setTensorDim(1, 5);
+  d.setTensorDim(2, 6);
+  d.setTensorDim(3, 7);
+
+  EXPECT_EQ(d.batch(), 4u);
+  EXPECT_EQ(d.height(), 5u);
+  EXPECT_EQ(d.width(), 6u);
+  EXPECT_EQ(d.channel(), 7u);
+}
+
 TEST(nntrainer_Tensor, Tensor_01_p) {
   int status = ML_ERROR_NONE;
   nntrainer::Tensor tensor = nntrainer::Tensor(1, 2, 3);
@@ -118,26 +191,32 @@ TEST(nntrainer_Tensor, Tensor_01_p) {
   EXPECT_EQ(status, ML_ERROR_NONE);
 }
 
-// TEST(nntrainer_Tensor, Tensor_02_p) {
-//   int status = ML_ERROR_NONE;
-//   int height = 3;
-//   int width = 10;
-//   std::vector<std::vector<float>> in;
-//   for (int i = 0; i < height; ++i) {
-//     std::vector<float> tv;
-//     for (int j = 0; j < width; ++j) {
-//       tv.push_back(i * 2.0 + j);
-//     }
-//     in.push_back(tv);
-//   }
+TEST(nntrainer_Tensor, Tensor_01_nhwc_p) {
+  int status = ML_ERROR_NONE;
+  nntrainer::Tensor tensor =
+    nntrainer::Tensor(1, 2, 3, nntrainer::Tformat::NHWC, nntrainer::Tdatatype::FP32);
+  tensor.setZero();
+  ASSERT_NE(nullptr, tensor.getData());
+  if (tensor.getValue(0, 0, 0, 0) != 0.0)
+    status = ML_ERROR_INVALID_PARAMETER;
+  EXPECT_EQ(status, ML_ERROR_NONE);
+}
 
-//   nntrainer::Tensor tensor = nntrainer::Tensor(in);
-//   ASSERT_NE(nullptr, tensor.getData());
+TEST(nntrainer_Tensor, Tensor_02_p) {
+  int status = ML_ERROR_NONE;
+  int height = 3;
+  int width = 10;
+  std::vector<std::vector<float>> in;
+  for (int i = 0; i < height; ++i) {
+    std::vector<float> tv;
+    for (int j = 0; j < width; ++j) {
+      tv.push_back(i * 2.0 + j);
+    }
+    in.push_back(tv);
+  }
 
-//   if (tensor.getValue(0, 0, 0, 1) != 1.0)
-//     status = ML_ERROR_INVALID_PARAMETER;
-//   EXPECT_EQ(status, ML_ERROR_NONE);
-// }
+  nntrainer::Tensor tensor = nntrainer::Tensor(in);
+  ASSERT_NE(nullptr, tensor.getData());
 
 // TEST(nntrainer_Tensor, Tensor_02_nhwc_p) {
 //   int status = ML_ERROR_NONE;
@@ -158,7 +237,7 @@ TEST(nntrainer_Tensor, Tensor_01_p) {
 //   if (tensor.getValue(0, 0, 0, 1) != 1.0)
 //     status = ML_ERROR_INVALID_PARAMETER;
 //   EXPECT_EQ(status, ML_ERROR_NONE);
-// }
+}
 
 TEST(nntrainer_Tensor, Tensor_03_p) {
   int status = ML_ERROR_NONE;
@@ -196,8 +275,11 @@ TEST(nntrainer_Tensor, multiply_i_01_p) {
   nntrainer::Tensor input(batch, channel, height, width);
   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
 
+  input.print(std::cout);
+
   nntrainer::Tensor original;
   original.copy(input);
+  original.print(std::cout);  
 
   status = input.multiply_i(2.0);
   EXPECT_EQ(status, ML_ERROR_NONE);
@@ -3080,7 +3162,7 @@ TEST(nntrainer_Tensor, print_small_size) {
 
   expected << '<' << typeid(target).name() << " at " << &target << ">\n"
            << "data addr: " << target.getData() << '\n'
-           << "Shape: 3:1:2:3\n"
+           << "Shape: 3:1:2:3 [ FP32 : NCHW ]\n"
            << "         1          1          1 \n"
            << "         1          1          1 \n"
            << "\n"
index 59fee51..9291fca 100644 (file)
@@ -56,21 +56,21 @@ TEST(nntrainer_util_func, logFloat_01_p) {
   }
 }
 
-TEST(nntrainer_util_func, rotate_180_p) {
-  nntrainer::TensorDim dim(1, 1, 2, 3);
+// TEST(nntrainer_util_func, rotate_180_p) {
+//   nntrainer::TensorDim dim(1, 1, 2, 3);
 
-  float data[6] = {1, 2, 3, 4, 5, 6};
-  float rotated_data[6] = {6, 5, 4, 3, 2, 1};
+//   float data[6] = {1, 2, 3, 4, 5, 6};
+//   float rotated_data[6] = {6, 5, 4, 3, 2, 1};
 
-  nntrainer::Tensor tensor1(dim, data);
-  nntrainer::Tensor tensor2 = nntrainer::rotate_180(tensor1);
+//   nntrainer::Tensor tensor1(dim, data);
+//   nntrainer::Tensor tensor2 = nntrainer::rotate_180(tensor1);
 
-  for (unsigned int i = 0, cnt = 0; i < dim.batch(); ++i)
-    for (unsigned int j = 0; j < dim.channel(); ++j)
-      for (unsigned int k = 0; k < dim.height(); ++k)
-        for (unsigned int l = 0; l < dim.width(); ++l)
-          EXPECT_EQ(tensor2.getValue(i, j, k, l), rotated_data[cnt++]);
-}
+//   for (unsigned int i = 0, cnt = 0; i < dim.batch(); ++i)
+//     for (unsigned int j = 0; j < dim.channel(); ++j)
+//       for (unsigned int k = 0; k < dim.height(); ++k)
+//         for (unsigned int l = 0; l < dim.width(); ++l)
+//           EXPECT_EQ(tensor2.getValue(i, j, k, l), rotated_data[cnt++]);
+// }
 
 TEST(nntrainer_util_func, checkedRead_n) {
   std::ifstream file("not existing file");