From e21e209ce0de9c6eaf2013b09ae652db0130512e Mon Sep 17 00:00:00 2001 From: "jijoong.moon" Date: Tue, 25 Jul 2023 07:47:33 +0900 Subject: [PATCH] [ Mixed Tensor ] Enable FP32 unittest cases This PR enables the FP32 unittest cases. It includes various fixes and adding compiler preprocessor pragmas. **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: jijoong.moon --- meson.build | 4 + nntrainer/graph/network_graph.h | 2 +- nntrainer/layers/loss/loss_layer.h | 22 + nntrainer/models/model_loader.cpp | 8 +- nntrainer/tensor/blas_interface.cpp | 398 +- nntrainer/tensor/blas_interface.h | 49 +- nntrainer/tensor/memory_data.h | 4 +- nntrainer/tensor/tensor.cpp | 277 +- nntrainer/tensor/tensor.h | 49 +- nntrainer/tensor/tensor_dim.cpp | 4 + nntrainer/tensor/tensor_pool.cpp | 2 +- nntrainer/tensor/tensor_pool.h | 2 +- nntrainer/utils/base_properties.h | 8 +- test/jni/Android.mk | 30 +- test/unittest/jni/tests/nntrainer_test_util.cpp | 268 -- test/unittest/jni/tests/nntrainer_test_util.h | 244 -- .../jni/tests/unittest_nntrainer_tensor.cpp | 4067 -------------------- .../jni/tests/unittest_nntrainer_tensor_fp16.cpp | 3893 ------------------- test/unittest/meson.build | 5 +- test/unittest/unittest_nntrainer_tensor_pool.cpp | 30 +- 20 files changed, 566 insertions(+), 8800 deletions(-) delete mode 100644 test/unittest/jni/tests/nntrainer_test_util.cpp delete mode 100644 test/unittest/jni/tests/nntrainer_test_util.h delete mode 100644 test/unittest/jni/tests/unittest_nntrainer_tensor.cpp delete mode 100644 test/unittest/jni/tests/unittest_nntrainer_tensor_fp16.cpp diff --git a/meson.build b/meson.build index 0f43512..8559247 100644 --- a/meson.build +++ b/meson.build @@ -72,6 +72,10 @@ warning_c_flags = [ # endforeach # enfif +if get_option('enable-fp16') + extra_defines += '-DENABLE_FP16=1' +endif + foreach extra_arg : warning_flags if cc.has_argument (extra_arg) add_project_arguments([extra_arg], language: 'c') diff --git a/nntrainer/graph/network_graph.h b/nntrainer/graph/network_graph.h index d3a3459..34292e5 100644 --- a/nntrainer/graph/network_graph.h +++ b/nntrainer/graph/network_graph.h @@ -377,7 +377,7 @@ public: * @return TensorDim::Format NCHW or NHWC */ std::array getTensorType() { - return {std::move(tensor_format), std::move(tensor_dtype)}; + return {tensor_format, tensor_dtype}; }; /** diff --git a/nntrainer/layers/loss/loss_layer.h b/nntrainer/layers/loss/loss_layer.h index 00b520f..0307f5c 100644 --- a/nntrainer/layers/loss/loss_layer.h +++ b/nntrainer/layers/loss/loss_layer.h @@ -52,6 +52,28 @@ public: */ bool requireLabel() const override { return true; } + /** + * @brief set the Tensor Type for the layer + * @param Tensor Type : NCHW or NHWC + */ + void setTensorType(std::array t_type) { + if (t_type[0].compare("NCHW") == 0 || t_type[0].compare("nchw") == 0) { + tensor_format = ml::train::TensorDim::Format::NCHW; + } else { + tensor_format = ml::train::TensorDim::Format::NHWC; + } + + nntrainer::props::TensorDataType type_; + + from_string(t_type[1], type_); + + tensor_dtype = type_; + } + +private: + ml::train::TensorDim::Format tensor_format; + ml::train::TensorDim::DataType tensor_dtype; + protected: /** * @brief update loss diff --git a/nntrainer/models/model_loader.cpp b/nntrainer/models/model_loader.cpp index 6d438f4..286ed17 100644 --- a/nntrainer/models/model_loader.cpp +++ b/nntrainer/models/model_loader.cpp @@ -121,10 +121,10 @@ int ModelLoader::loadModelConfigIni(dictionary *ini, NeuralNetwork &model) { return ML_ERROR_INVALID_PARAMETER; } - std::vector properties = - parseProperties(ini, "Model", - {"optimizer", "learning_rate", "decay_steps", "decay_rate", - "beta1", "beta2", "epsilon", "type", "save_path"}); + std::vector properties = parseProperties( + ini, "Model", + {"optimizer", "learning_rate", "decay_steps", "decay_rate", "beta1", + "beta2", "epsilon", "type", "save_path", "tensor_type", "tensor_format"}); try { model.setProperty(properties); } catch (std::exception &e) { diff --git a/nntrainer/tensor/blas_interface.cpp b/nntrainer/tensor/blas_interface.cpp index e88b8ce..764eaea 100644 --- a/nntrainer/tensor/blas_interface.cpp +++ b/nntrainer/tensor/blas_interface.cpp @@ -29,31 +29,9 @@ } \ } while (0); -// #define sgemv_loop_fp16(ci, cj, cM, cN) \ -// do { \ -// __fp16 y0; \ -// unsigned int i, j; \ -// for (ci = 0; ci != cM; ci++) { \ -// y0 = Y[ci * incy] * beta; \ -// for (cj = 0; cj != cN; cj++) \ -// y0 += A[i + j * lda] * X[cj * incx]; \ -// Y[ci * incy] = y0; \ -// } \ -// } while (0); - namespace nntrainer { -#ifndef USE_BLAS - -static void saxpy_raw(const unsigned int N, const float alpha, const float *X, - const int incX, float *Y, const int incY) { - if (incX < 0 or incY < 0) - throw std::invalid_argument( - "Error: negative inc not supported without cblas"); - for (unsigned int i = 0; i < N; ++i) - Y[i * incY] = Y[i * incY] + X[i * incX] * alpha; -} - +#ifdef ENABLE_FP16 static void saxpy_FP16(const unsigned int N, const float alpha, const __fp16 *X, const int incX, __fp16 *Y, const int incY) { if (incX < 0 or incY < 0) @@ -63,22 +41,6 @@ static void saxpy_FP16(const unsigned int N, const float alpha, const __fp16 *X, Y[i * incY] = Y[i * incY] + alpha * X[i * incX]; } -static void sgemv_raw(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, - const unsigned int M, const unsigned int N, - const float alpha, const float *A, const unsigned int lda, - const float *X, const int incX, const float beta, - float *Y, const int incY) { - - unsigned int incy = abs(incY); - unsigned int incx = abs(incX); - - if (TransA == CblasTrans) { - sgemv_loop(i, j, N, M); - } else { - sgemv_loop(j, i, M, N); - } -} - static void sgemv_FP16(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, const unsigned int N, const float alpha, const __fp16 *A, @@ -95,16 +57,6 @@ static void sgemv_FP16(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, } } -static float sdot_raw(const unsigned int N, const float *X, - const unsigned int incX, const float *Y, - const unsigned int incY) { - float ret = 0; - for (unsigned int i = 0; i < N; ++i) { - ret += X[i * incX] * Y[i * incY]; - } - return ret; -} - static __fp16 sdot_FP16(const unsigned int N, const __fp16 *X, const unsigned int incX, const __fp16 *Y, const unsigned int incY) { @@ -115,15 +67,6 @@ static __fp16 sdot_FP16(const unsigned int N, const __fp16 *X, return ret; } -static void scopy_raw(const unsigned int N, const float *X, const int incX, - float *Y, const int incY) { - unsigned int incy = abs(incY); - unsigned int incx = abs(incX); - - for (unsigned int i = 0; i < N; ++i) - Y[i * incy] = X[i * incx]; -} - static void scopy_FP16(const unsigned int N, const __fp16 *X, const int incX, __fp16 *Y, const int incY) { unsigned int incy = abs(incY); @@ -133,65 +76,165 @@ static void scopy_FP16(const unsigned int N, const __fp16 *X, const int incX, Y[i * incy] = X[i * incx]; } -static void sscal_raw(const unsigned int N, const float alpha, float *X, - const int incX) { +void sscal(const unsigned int N, const float alpha, __fp16 *X, const int incX) { unsigned int incx = abs(incX); for (unsigned int i = 0; i < N; ++i) X[i * incx] = alpha * X[i * incx]; } -void sscal(const unsigned int N, const float alpha, __fp16 *X, const int incX) { +static float snrm2_FP16(const unsigned int N, const __fp16 *X, const int incX) { unsigned int incx = abs(incX); + __fp16 sum = 0.0f; + __fp16 tmp; +#pragma omp parallel for private(tmp) reduction(+ : sum) + for (unsigned int i = 0; i < N; i++) { + tmp = X[i * incx]; + sum += tmp * tmp; + } + return sqrt(sum); +} +static void sgemm_FP16(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, + CBLAS_TRANSPOSE TransB, const unsigned int M, + const unsigned int N, const unsigned int K, + const float alpha, const __fp16 *A, + const unsigned int lda, const __fp16 *B, + const unsigned int ldb, const float beta, __fp16 *C, + const unsigned int ldc) { - for (unsigned int i = 0; i < N; ++i) - X[i * incx] = alpha * X[i * incx]; + for (unsigned int m = 0; m < M; ++m) { + for (unsigned int n = 0; n < N; ++n) { + __fp16 c = 0.0; + __fp16 c_old = C[m * ldc + n]; + for (unsigned int k = 0; k < K; ++k) { + __fp16 a, b; + a = ((TransA == CblasTrans) ? A[k * lda + m] : A[m * lda + k]); + b = ((TransB == CblasTrans) ? B[n * ldb + k] : B[k * ldb + n]); + c += a * b; + } + C[m * ldc + n] = alpha * c; + if (beta != 0.0) + C[m * ldc + n] += beta * c_old; + } + } } -void sscal(const unsigned int N, const float alpha, void *X, const int incX, - ml::train::TensorDim::DataType d_type) { -#ifdef USE_BLAS -#ifdef BLAS_NUM_THREADS - openblas_set_num_threads(BLAS_NUM_THREADS); -#endif - if (d_type == ml::train::TensorDim::DataType::FP32) - cblas_sscal(N, alpha, (float *)X, incX); -#else - if (d_type == ml::train::TensorDim::DataType::FP32) { - sscal_raw(N, alpha, (float *)X, incX); - } else if (d_type == ml::train::TensorDim::DataType::FP16) { - sscal(N, alpha, (__fp16 *)X, incX); +static unsigned int isamax_FP16(const unsigned int N, const __fp16 *X, + const int incX) { + + unsigned int max_idx = 0; + __fp16 max_val = X[0]; + for (unsigned int n = 1; n < N; n += incX) { + __fp16 cur_val = abs(X[n]); + if (cur_val > max_val) { + max_val = cur_val; + max_idx = n; + } } -#endif + + return max_idx; +} + +void saxpy(const unsigned int N, const float alpha, const __fp16 *X, + const int incX, __fp16 *Y, const int incY) { + saxpy_FP16(N, alpha, X, incX, Y, incY); +} + +void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, + const unsigned int M, const unsigned int N, const unsigned int K, + const float alpha, const __fp16 *A, const unsigned int lda, + const __fp16 *B, const unsigned int ldb, const float beta, __fp16 *C, + const unsigned int ldc) { + sgemm_FP16(order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, + ldc); +} + +void scopy(const unsigned int N, const __fp16 *X, const int incX, __fp16 *Y, + const int incY) { + scopy_FP16(N, X, incX, Y, incY); + +} // namespace nntrainer + +__fp16 snrm2(const int N, const __fp16 *X, const int incX) { + return snrm2_FP16(N, X, incX); +} + +__fp16 sdot(const unsigned int N, const __fp16 *X, const unsigned int incX, + const __fp16 *Y, const unsigned int incY) { + return sdot_FP16(N, X, incX, Y, incY); +} + +void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, + const unsigned int N, const float alpha, const __fp16 *A, + const unsigned int lda, const __fp16 *X, const int incX, + const float beta, __fp16 *Y, const int incY) { + sgemv_FP16(order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); +} + +unsigned int isamax(const unsigned int N, const __fp16 *X, const int incX) { + /// @todo isamax_FP16 for BLAS_NUM_THREADS + return isamax_FP16(N, X, incX); } -void sscal(const unsigned int N, const float alpha, float *X, const int incX) { -#ifdef USE_BLAS -#ifdef BLAS_NUM_THREADS - openblas_set_num_threads(BLAS_NUM_THREADS); -#endif - cblas_sscal(N, alpha, (float *)X, incX); -#else - sscal_raw(N, alpha, (float *)X, incX); #endif + +#ifndef USE_BLAS +static void saxpy_raw(const unsigned int N, const float alpha, const float *X, + const int incX, float *Y, const int incY) { + if (incX < 0 or incY < 0) + throw std::invalid_argument( + "Error: negative inc not supported without cblas"); + for (unsigned int i = 0; i < N; ++i) + Y[i * incY] = Y[i * incY] + X[i * incX] * alpha; } -static float snrm2_raw(const unsigned int N, const float *X, const int incX) { +static void sgemv_raw(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, + const unsigned int M, const unsigned int N, + const float alpha, const float *A, const unsigned int lda, + const float *X, const int incX, const float beta, + float *Y, const int incY) { + + unsigned int incy = abs(incY); unsigned int incx = abs(incX); - float sum = 0.0f; - float tmp; -#pragma omp parallel for private(tmp) reduction(+ : sum) - for (unsigned int i = 0; i < N; i++) { - tmp = X[i * incx]; - sum += tmp * tmp; + + if (TransA == CblasTrans) { + sgemv_loop(i, j, N, M); + } else { + sgemv_loop(j, i, M, N); } - return sqrt(sum); } -static float snrm2_FP16(const unsigned int N, const __fp16 *X, const int incX) { +static float sdot_raw(const unsigned int N, const float *X, + const unsigned int incX, const float *Y, + const unsigned int incY) { + float ret = 0; + for (unsigned int i = 0; i < N; ++i) { + ret += X[i * incX] * Y[i * incY]; + } + return ret; +} + +static void scopy_raw(const unsigned int N, const float *X, const int incX, + float *Y, const int incY) { + unsigned int incy = abs(incY); unsigned int incx = abs(incX); - __fp16 sum = 0.0f; - __fp16 tmp; + + for (unsigned int i = 0; i < N; ++i) + Y[i * incy] = X[i * incx]; +} + +static void sscal_raw(const unsigned int N, const float alpha, float *X, + const int incX) { + unsigned int incx = abs(incX); + + for (unsigned int i = 0; i < N; ++i) + X[i * incx] = alpha * X[i * incx]; +} + +static float snrm2_raw(const unsigned int N, const float *X, const int incX) { + unsigned int incx = abs(incX); + float sum = 0.0f; + float tmp; #pragma omp parallel for private(tmp) reduction(+ : sum) for (unsigned int i = 0; i < N; i++) { tmp = X[i * incx]; @@ -224,31 +267,6 @@ static void sgemm_raw(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, } } -static void sgemm_FP16(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, - CBLAS_TRANSPOSE TransB, const unsigned int M, - const unsigned int N, const unsigned int K, - const float alpha, const __fp16 *A, - const unsigned int lda, const __fp16 *B, - const unsigned int ldb, const float beta, __fp16 *C, - const unsigned int ldc) { - - for (unsigned int m = 0; m < M; ++m) { - for (unsigned int n = 0; n < N; ++n) { - __fp16 c = 0.0; - __fp16 c_old = C[m * ldc + n]; - for (unsigned int k = 0; k < K; ++k) { - __fp16 a, b; - a = ((TransA == CblasTrans) ? A[k * lda + m] : A[m * lda + k]); - b = ((TransB == CblasTrans) ? B[n * ldb + k] : B[k * ldb + n]); - c += a * b; - } - C[m * ldc + n] = alpha * c; - if (beta != 0.0) - C[m * ldc + n] += beta * c_old; - } - } -} - static unsigned int isamax_raw(const unsigned int N, const float *X, const int incX) { @@ -265,23 +283,39 @@ static unsigned int isamax_raw(const unsigned int N, const float *X, return max_idx; } -static unsigned int isamax_FP16(const unsigned int N, const __fp16 *X, - const int incX) { +#endif - unsigned int max_idx = 0; - __fp16 max_val = X[0]; - for (unsigned int n = 1; n < N; n += incX) { - __fp16 cur_val = abs(X[n]); - if (cur_val > max_val) { - max_val = cur_val; - max_idx = n; - } +void sscal(const unsigned int N, const float alpha, void *X, const int incX, + ml::train::TensorDim::DataType d_type) { +#ifdef USE_BLAS +#ifdef BLAS_NUM_THREADS + openblas_set_num_threads(BLAS_NUM_THREADS); +#endif + if (d_type == ml::train::TensorDim::DataType::FP32) + cblas_sscal(N, alpha, (float *)X, incX); +#else + if (d_type == ml::train::TensorDim::DataType::FP32) { + sscal_raw(N, alpha, (float *)X, incX); + } else if (d_type == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 + sscal(N, alpha, (__fp16 *)X, incX); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } - - return max_idx; +#endif } +void sscal(const unsigned int N, const float alpha, float *X, const int incX) { +#ifdef USE_BLAS +#ifdef BLAS_NUM_THREADS + openblas_set_num_threads(BLAS_NUM_THREADS); #endif + cblas_sscal(N, alpha, X, incX); +#else + sscal_raw(N, alpha, X, incX); +#endif +} void saxpy(const unsigned int N, const float alpha, const void *X, const int incX, void *Y, const int incY, @@ -290,12 +324,19 @@ void saxpy(const unsigned int N, const float alpha, const void *X, #ifdef BLAS_NUM_THREADS openblas_set_num_threads(BLAS_NUM_THREADS); #endif - cblas_saxpy(N, alpha, X, incX, Y, incY); + cblas_saxpy(N, alpha, static_cast(X), incX, + static_cast(Y), incY); #else if (d_type == ml::train::TensorDim::DataType::FP32) { - saxpy_raw(N, alpha, (float *)X, incX, (float *)Y, incY); + saxpy_raw(N, alpha, static_cast(X), incX, + static_cast(Y), incY); } else if (d_type == ml::train::TensorDim::DataType::FP16) { - saxpy_FP16(N, alpha, (__fp16 *)X, incX, (__fp16 *)Y, incY); +#ifdef ENABLE_FP16 + saxpy_FP16(N, alpha, static_cast(X), incX, + static_cast<__fp16 *>(Y), incY); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } #endif } @@ -312,11 +353,6 @@ void saxpy(const unsigned int N, const float alpha, const float *X, #endif } -void saxpy(const unsigned int N, const float alpha, const __fp16 *X, - const int incX, __fp16 *Y, const int incY) { - saxpy_FP16(N, alpha, X, incX, Y, incY); -} - void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const unsigned int M, const unsigned int N, const unsigned int K, const float alpha, const void *A, const unsigned int lda, @@ -352,15 +388,23 @@ void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, #ifdef BLAS_NUM_THREADS openblas_set_num_threads(BLAS_NUM_THREADS); #endif - cblas_sgemm(order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, - ldc); + cblas_sgemm(order, TransA, TransB, M, N, K, alpha, + static_cast(A), lda, static_cast(B), + ldb, beta, static_cast(C), ldc); #else if (d_type == ml::train::TensorDim::DataType::FP32) { - sgemm_raw(order, TransA, TransB, M, N, K, alpha, (float *)A, lda, - (float *)B, ldb, beta, (float *)C, ldc); + sgemm_raw(order, TransA, TransB, M, N, K, alpha, + static_cast(A), lda, static_cast(B), + ldb, beta, static_cast(C), ldc); } else if (d_type == ml::train::TensorDim::DataType::FP16) { - sgemm_FP16(order, TransA, TransB, M, N, K, alpha, (__fp16 *)A, lda, - (__fp16 *)B, ldb, beta, (__fp16 *)C, ldc); +#ifdef ENABLE_FP16 + sgemm_FP16(order, TransA, TransB, M, N, K, alpha, + static_cast(A), lda, + static_cast(B), ldb, beta, + static_cast<__fp16 *>(C), ldc); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } #endif } @@ -409,15 +453,6 @@ void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, #endif } -void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, - const unsigned int M, const unsigned int N, const unsigned int K, - const float alpha, const __fp16 *A, const unsigned int lda, - const __fp16 *B, const unsigned int ldb, const float beta, __fp16 *C, - const unsigned int ldc) { - sgemm_FP16(order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, - ldc); -} - void scopy(const unsigned int N, const void *X, const int incX, void *Y, const int incY, ml::train::TensorDim::DataType d_type) { #ifdef USE_BLAS @@ -431,7 +466,11 @@ void scopy(const unsigned int N, const void *X, const int incX, void *Y, if (d_type == ml::train::TensorDim::DataType::FP32) { scopy_raw(N, (float *)X, incX, (float *)Y, incY); } else if (d_type == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 scopy_FP16(N, (__fp16 *)X, incX, (__fp16 *)Y, incY); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } #endif } // namespace nntrainer @@ -448,12 +487,6 @@ void scopy(const unsigned int N, const float *X, const int incX, float *Y, #endif } // namespace nntrainer -void scopy(const unsigned int N, const __fp16 *X, const int incX, __fp16 *Y, - const int incY) { - scopy_FP16(N, X, incX, Y, incY); - -} // namespace nntrainer - float snrm2(const int N, const float *X, const int incX) { #ifdef USE_BLAS #ifdef BLAS_NUM_THREADS @@ -465,10 +498,6 @@ float snrm2(const int N, const float *X, const int incX) { #endif } -__fp16 snrm2(const int N, const __fp16 *X, const int incX) { - return snrm2_FP16(N, X, incX); -} - float sdot(const unsigned int N, const float *X, const unsigned int incX, const float *Y, const unsigned int incY) { #ifdef USE_BLAS @@ -481,11 +510,6 @@ float sdot(const unsigned int N, const float *X, const unsigned int incX, #endif } -__fp16 sdot(const unsigned int N, const __fp16 *X, const unsigned int incX, - const __fp16 *Y, const unsigned int incY) { - return sdot_FP16(N, X, incX, Y, incY); -} - void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, const unsigned int N, const float alpha, const void *A, const unsigned int lda, const void *X, const int incX, @@ -495,15 +519,23 @@ void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, #ifdef BLAS_NUM_THREADS openblas_set_num_threads(BLAS_NUM_THREADS); #endif - return cblas_sgemv(order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, - incY); + return cblas_sgemv(order, TransA, M, N, alpha, static_cast(A), + lda, static_cast(X), incX, beta, + static_cast(Y), incY); #else if (d_type == ml::train::TensorDim::DataType::FP32) { - return sgemv_raw(order, TransA, M, N, alpha, (float *)A, lda, (float *)X, - incX, beta, (float *)Y, incY); + return sgemv_raw(order, TransA, M, N, alpha, static_cast(A), + lda, static_cast(X), incX, beta, + static_cast(Y), incY); } else if (d_type == ml::train::TensorDim::DataType::FP16) { - return sgemv_FP16(order, TransA, M, N, alpha, (__fp16 *)A, lda, (__fp16 *)X, - incX, beta, (__fp16 *)Y, incY); +#ifdef ENABLE_FP16 + return sgemv_FP16(order, TransA, M, N, alpha, + static_cast(A), lda, + static_cast(X), incX, beta, + static_cast<__fp16 *>(Y), incY); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } #endif } @@ -523,13 +555,6 @@ void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, #endif } -void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, - const unsigned int N, const float alpha, const __fp16 *A, - const unsigned int lda, const __fp16 *X, const int incX, - const float beta, __fp16 *Y, const int incY) { - sgemv_FP16(order, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY); -} - unsigned int isamax(const unsigned int N, const float *X, const int incX) { #ifdef USE_BLAS #ifdef BLAS_NUM_THREADS @@ -541,9 +566,4 @@ unsigned int isamax(const unsigned int N, const float *X, const int incX) { #endif } -unsigned int isamax(const unsigned int N, const __fp16 *X, const int incX) { - /// @todo isamax_FP16 for BLAS_NUM_THREADS - return isamax_FP16(N, X, incX); -} - } // namespace nntrainer diff --git a/nntrainer/tensor/blas_interface.h b/nntrainer/tensor/blas_interface.h index 63274a9..1aff5b5 100644 --- a/nntrainer/tensor/blas_interface.h +++ b/nntrainer/tensor/blas_interface.h @@ -39,42 +39,48 @@ enum CBLAS_TRANSPOSE { namespace nntrainer { +#ifdef ENABLE_FP16 +void sscal(const unsigned int N, const float alpha, __fp16 *X, const int incX); +__fp16 snrm2(const int N, const __fp16 *X, const int incX); +void scopy(const unsigned int N, const __fp16 *X, const int incX, __fp16 *Y, + const int intY); +__fp16 sdot(const unsigned int N, const __fp16 *X, const unsigned int incX, + const __fp16 *Y, const unsigned int incY); +void saxpy(const unsigned int N, const float alpha, const __fp16 *X, + const int incX, __fp16 *Y, const int incY); +void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, + const unsigned int M, const unsigned int N, const unsigned int K, + const float alpha, const __fp16 *A, const unsigned int lda, + const __fp16 *B, const unsigned int ldb, const float beta, __fp16 *C, + const unsigned int ldc); +void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, + const unsigned int N, const float alpha, const __fp16 *A, + const unsigned int lda, const __fp16 *X, const int incX, + const float beta, __fp16 *Y, const int incY); +unsigned int isamax(const unsigned int N, const __fp16 *X, const int incX); +#endif + void sscal(const unsigned int N, const float alpha, void *X, const int incX, ml::train::TensorDim::DataType d_type); void sscal(const unsigned int N, const float alpha, float *X, const int incX); -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); -__fp16 snrm2(const int N, const __fp16 *X, const int incX); - void scopy(const unsigned int N, const void *X, const int incX, void *Y, 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); -void scopy(const unsigned int N, const __fp16 *X, const int incX, __fp16 *Y, - const int intY); - float sdot(const unsigned int N, const float *X, const unsigned int incX, const float *Y, const unsigned int incY); -__fp16 sdot(const unsigned int N, const __fp16 *X, const unsigned int incX, - const __fp16 *Y, const unsigned int incY); - void saxpy(const unsigned int N, const float alpha, const void *X, const int incX, void *Y, const int incY, ml::train::TensorDim::DataType d_type); - void saxpy(const unsigned int N, const float alpha, const float *X, const int incX, float *Y, const int incY); -void saxpy(const unsigned int N, const float alpha, const __fp16 *X, - const int incX, __fp16 *Y, const int incY); - void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const unsigned int M, const unsigned int N, const unsigned int K, const float alpha, const void *A, const unsigned int lda, @@ -87,12 +93,6 @@ void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const float *B, const unsigned int ldb, const float beta, float *C, const unsigned int ldc); -void sgemm(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, - const unsigned int M, const unsigned int N, const unsigned int K, - const float alpha, const __fp16 *A, const unsigned int lda, - const __fp16 *B, const unsigned int ldb, const float beta, __fp16 *C, - const unsigned int ldc); - void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, const unsigned int N, const float alpha, const void *A, const unsigned int lda, const void *X, const int incX, @@ -104,15 +104,8 @@ void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, const unsigned int lda, const float *X, const int incX, const float beta, float *Y, const int incY); -void sgemv(CBLAS_ORDER order, CBLAS_TRANSPOSE TransA, const unsigned int M, - const unsigned int N, const float alpha, const __fp16 *A, - const unsigned int lda, const __fp16 *X, const int incX, - const float beta, __fp16 *Y, const int incY); - unsigned int isamax(const unsigned int N, const float *X, const int incX); -unsigned int isamax(const unsigned int N, const __fp16 *X, const int incX); - } /* namespace nntrainer */ #endif /* __cplusplus */ #endif /* __BLAS_INTERFACE_H__ */ diff --git a/nntrainer/tensor/memory_data.h b/nntrainer/tensor/memory_data.h index 47bc9be..834d351 100644 --- a/nntrainer/tensor/memory_data.h +++ b/nntrainer/tensor/memory_data.h @@ -79,7 +79,9 @@ public: /** * @brief Get address */ - template T *getAddr() const { return (T *)address; } + template T *getAddr() const { + return static_cast(address); + } /** * @brief Validate memory data diff --git a/nntrainer/tensor/tensor.cpp b/nntrainer/tensor/tensor.cpp index 0bf5290..86a81d3 100644 --- a/nntrainer/tensor/tensor.cpp +++ b/nntrainer/tensor/tensor.cpp @@ -36,7 +36,6 @@ #include #include -#include #include #include @@ -93,7 +92,7 @@ struct Tensor::BroadcastInfo { int buffer_axis; /**< the smallest axis that should be looped. -1 means no loop needed*/ std::array - strides; /**< modified strides for the loop */ + strides; /**< modified strides for the loop */ nntrainer::TensorDim::TensorType tensor_type; }; @@ -128,7 +127,8 @@ public: SrcSharedTensor() : src(nullptr), off(0) {} SrcSharedTensor(const Tensor *tensor, size_t offset) : - src(tensor), off(offset) {} + src(tensor), + off(offset) {} /** * @brief Get the allocated src tensor @@ -168,16 +168,20 @@ void Tensor::allocate() { if (getDataType() == ml::train::TensorDim::DataType::FP32) { mem_data = new MemoryData((void *)(new float[dim.getDataLen()]())); data = std::shared_ptr(mem_data, [](auto *mem_data) { - delete[] (float *)mem_data->getAddr(); + delete[](float *) mem_data->getAddr(); delete mem_data; }); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 mem_data = new MemoryData((void *)(new __fp16[dim.getDataLen()]())); data = std::shared_ptr(mem_data, [](auto *mem_data) { - delete[] (__fp16 *)mem_data->getAddr(); + delete[](__fp16 *) mem_data->getAddr(); delete mem_data; }); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } offset = 0; initialize(); @@ -211,6 +215,7 @@ bool Tensor::operator==(const Tensor &rhs) const { return false; } } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *_data = getData<__fp16>(); const __fp16 *_rdata = rhs.getData<__fp16>(); for (size_t i = 0; i < len; ++i) { @@ -219,6 +224,9 @@ bool Tensor::operator==(const Tensor &rhs) const { std::fabs(_data[i] - _rdata[i]) > epsilon) return false; } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return true; @@ -249,8 +257,12 @@ void Tensor::setRandBernoulli(float probability) { setDist( std::bernoulli_distribution(probability)); } else if (this->getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 setDist<__fp16, std::bernoulli_distribution>( std::bernoulli_distribution((__fp16)probability)); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -345,12 +357,16 @@ Tensor &Tensor::multiply_strided(Tensor const &m, Tensor &output, NNTR_THROW_IF(output.getData() == nullptr, std::invalid_argument) << output.getName() << " is not allocated"; } else if (getDataType() == Tdatatype::FP16) { +#ifdef ENABLE_FP16 NNTR_THROW_IF(getData<__fp16>() == nullptr, std::invalid_argument) << getName() << " is not allocated"; NNTR_THROW_IF(m.getData<__fp16>() == nullptr, std::invalid_argument) << m.getName() << " is not allocated"; NNTR_THROW_IF(output.getData<__fp16>() == nullptr, std::invalid_argument) << output.getName() << " is not allocated"; +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } // Format NCHW Case @@ -386,6 +402,7 @@ Tensor &Tensor::multiply_strided(Tensor const &m, Tensor &output, } } } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 || beta != 0.0) { for (unsigned int b = 0; b < batch(); ++b) { @@ -413,6 +430,9 @@ Tensor &Tensor::multiply_strided(Tensor const &m, Tensor &output, } } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } else { // Format NHWC Case if (getDataType() == Tdatatype::FP32) { @@ -446,6 +466,7 @@ Tensor &Tensor::multiply_strided(Tensor const &m, Tensor &output, } } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 || beta != 0.0) { for (unsigned int b = 0; b < batch(); ++b) { @@ -475,6 +496,9 @@ Tensor &Tensor::multiply_strided(Tensor const &m, Tensor &output, } } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -514,12 +538,16 @@ Tensor &Tensor::add_strided(Tensor const &m, Tensor &output, NNTR_THROW_IF(output.getData() == nullptr, std::invalid_argument) << output.getName() << " is not allocated"; } else if (getDataType() == Tdatatype::FP16) { +#ifdef ENABLE_FP16 NNTR_THROW_IF(getData<__fp16>() == nullptr, std::invalid_argument) << getName() << " is not allocated"; NNTR_THROW_IF(m.getData<__fp16>() == nullptr, std::invalid_argument) << m.getName() << " is not allocated"; NNTR_THROW_IF(output.getData<__fp16>() == nullptr, std::invalid_argument) << output.getName() << " is not allocated"; +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } // Format NCHW Case @@ -553,6 +581,7 @@ Tensor &Tensor::add_strided(Tensor const &m, Tensor &output, } } } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 || beta != 0.0) { for (unsigned int b = 0; b < batch(); ++b) { @@ -579,6 +608,9 @@ Tensor &Tensor::add_strided(Tensor const &m, Tensor &output, } } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } else { // Format NHWC Case if (getDataType() == Tdatatype::FP32) { @@ -611,6 +643,7 @@ Tensor &Tensor::add_strided(Tensor const &m, Tensor &output, } } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 if (strides[3] != 1 || m.strides[3] != 1 || output.strides[3] != 1 || beta != 0.0) { for (unsigned int b = 0; b < batch(); ++b) { @@ -639,6 +672,9 @@ Tensor &Tensor::add_strided(Tensor const &m, Tensor &output, } } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } return output; @@ -656,9 +692,13 @@ int Tensor::multiply_i(float const &value) { sscal(len, value, data, 1); } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 __fp16 *data = getData<__fp16>(); unsigned int len = size(); sscal(len, value, data, 1); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return ML_ERROR_NONE; } @@ -674,8 +714,12 @@ Tensor &Tensor::multiply(float const &value, Tensor &out) const { auto f = std::bind(std::multiplies(), std::placeholders::_1, value); return apply(f, out); } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto f = std::bind(std::multiplies<__fp16>(), std::placeholders::_1, value); return apply(f, out); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return out; } @@ -736,6 +780,7 @@ Tensor &Tensor::multiply(Tensor const &m, Tensor &output, return output; } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_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 && @@ -763,6 +808,9 @@ Tensor &Tensor::multiply(Tensor const &m, Tensor &output, apply_broadcast(m, f, output); return output; +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return output; } @@ -830,6 +878,7 @@ Tensor &Tensor::divide(Tensor const &m, Tensor &output) const { apply_broadcast(m, f, output); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_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) { @@ -850,6 +899,9 @@ Tensor &Tensor::divide(Tensor const &m, Tensor &output) const { << getName() << " is not contiguous, cannot divide"; apply_broadcast(m, f, output); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return output; } @@ -870,8 +922,12 @@ Tensor &Tensor::add(float const &value, Tensor &out) const { auto f = std::bind(std::plus(), std::placeholders::_1, value); return apply(f, out); } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto f = std::bind(std::plus<__fp16>(), std::placeholders::_1, value); return apply(f, out); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return out; } @@ -896,8 +952,8 @@ int Tensor::add_i(Tensor const &m, float const alpha) { return ML_ERROR_INVALID_PARAMETER; } - return ML_ERROR_NONE; } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto f = [&](const BroadcastInfo &e, const __fp16 *buf, const __fp16 *m_buf, __fp16 *out_buf) { saxpy(e.buffer_size, alpha, m_buf, e.strides[3], out_buf, strides[3]); @@ -915,8 +971,12 @@ int Tensor::add_i(Tensor const &m, float const alpha) { return ML_ERROR_INVALID_PARAMETER; } - return ML_ERROR_NONE; +#else + ml_loge("%s", "Error: enable-fp16 is not enabled"); + return ML_ERROR_INVALID_PARAMETER; +#endif } + return ML_ERROR_NONE; } Tensor Tensor::add(Tensor const &m, float const alpha) const { @@ -947,6 +1007,7 @@ Tensor &Tensor::add(Tensor const &m, Tensor &output, float const alpha) const { }; apply_broadcast(m, f, output); } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto f = [&](const BroadcastInfo &e, const __fp16 *buf, const __fp16 *m_buf, __fp16 *out_buf) { if (e.strides[3] == 1 && strides[3] == 1 && strides[3] == 1 && @@ -963,6 +1024,9 @@ Tensor &Tensor::add(Tensor const &m, Tensor &output, float const alpha) const { } }; apply_broadcast(m, f, output); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return output; } @@ -983,9 +1047,14 @@ Tensor &Tensor::subtract(float const &value, Tensor &out) const { auto f = std::bind(std::minus(), std::placeholders::_1, value); return apply(f, out); } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto f = std::bind(std::minus<__fp16>(), std::placeholders::_1, value); return apply(f, out); +#else + ml_loge("%s", "Error: enable-fp16 is not enabled"); +#endif } + return out; // shouldn't reach } int Tensor::subtract_i(Tensor const &m) { return add_i(m, -1); } @@ -1012,9 +1081,14 @@ Tensor &Tensor::pow(float exponent, Tensor &out) const { return apply(f, out); } if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto f = [exponent](__fp16 in) { return powf(in, exponent); }; return apply(f, out); +#else + ml_loge("%s", "Error: enable-fp16 is not enabled"); +#endif } + return out; } Tensor Tensor::getBatchSlice(size_t offset, unsigned int size) const { @@ -1135,7 +1209,8 @@ std::vector Tensor::split(std::vector sizes, int axis) { ret_dims[i].setTensorDim(axis, sizes[i]); } - bool is_format_nchw = (dim.getFormat() == Tformat::NCHW); + bool is_format_nchw = (dim.getFormat() == Tformat::NCHW) ? true : false; + std::vector ret; if (getDataType() == ml::train::TensorDim::DataType::FP32) { auto iter_value = [this, is_format_nchw]( @@ -1155,7 +1230,6 @@ std::vector Tensor::split(std::vector sizes, int axis) { return value; }; - std::vector ret; ret.reserve(num_size); unsigned int accumulated_size = 0; @@ -1214,10 +1288,9 @@ std::vector Tensor::split(std::vector sizes, int axis) { return iter_value(loc, end_loc, reset_dim_arr); }); } - - return ret; } if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto iter_value = [this, is_format_nchw]( std::array &loc, const std::array &end_loc, @@ -1236,7 +1309,6 @@ std::vector Tensor::split(std::vector sizes, int axis) { return value; }; - std::vector ret; ret.reserve(num_size); unsigned int accumulated_size = 0; @@ -1296,8 +1368,12 @@ std::vector Tensor::split(std::vector sizes, int axis) { }); } - return ret; +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } + + return ret; } Tensor Tensor::cat(const std::vector &tensors, int axis) { @@ -1312,6 +1388,7 @@ Tensor Tensor::cat(const std::vector &tensors, int axis) { NNTR_THROW_IF(tensors.empty(), std::invalid_argument) << "given tensor vector is empty"; + Tensor ret; auto ref_dim = tensors.front().getDim(); bool is_format_nchw = (ref_dim.getFormat() == Tformat::NCHW); ref_dim.setTensorDim(axis, 1); @@ -1352,7 +1429,7 @@ Tensor Tensor::cat(const std::vector &tensors, int axis) { auto ret_dim = ref_dim; ret_dim.setTensorDim(axis, axis_dim); - auto ret = Tensor(ret_dim); + ret = Tensor(ret_dim); std::array loc = {0, 0, 0, 0}; for (auto &t : tensors) { @@ -1387,8 +1464,9 @@ Tensor Tensor::cat(const std::vector &tensors, int axis) { } } - return ret; + // return ret; } else if (ref_dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 auto iter_value = [is_format_nchw](std::array &loc, const std::array &start_loc, Tensor &t, @@ -1411,7 +1489,7 @@ Tensor Tensor::cat(const std::vector &tensors, int axis) { auto ret_dim = ref_dim; ret_dim.setTensorDim(axis, axis_dim); - auto ret = Tensor(ret_dim); + ret = Tensor(ret_dim); std::array loc = {0, 0, 0, 0}; for (auto &t : tensors) { @@ -1446,8 +1524,11 @@ Tensor Tensor::cat(const std::vector &tensors, int axis) { } } - return ret; +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } + return ret; } void Tensor::makeSharedDataTensor(const Tensor &src, size_t offset) { @@ -1496,6 +1577,7 @@ void Tensor::apply_broadcast( return apply_broadcast_util(m, v_func, output, this->computeBroadcastInfo(m)); } +#ifdef ENABLE_FP16 void Tensor::apply_broadcast( Tensor const &m, std::function + std::function v_func, Tensor &output, const BroadcastInfo &e, int cur_axis, size_t offset, size_t m_offset) const { - const float *buf = this->getData(); - const float *m_buf = m.getData(); - float *out_buf = output.getData(); + const __fp16 *buf = this->getData<__fp16>(); + const __fp16 *m_buf = m.getData<__fp16>(); + __fp16 *out_buf = output.getData<__fp16>(); if (e.buffer_axis == cur_axis) { v_func(e, buf + offset, m_buf + m_offset, out_buf + offset); @@ -1543,13 +1625,7 @@ void Tensor::apply_broadcast_util( } cur_axis++; - uint continuity[4] = {0, 1, 2, 3}; - if (getFormat() == Tformat::NHWC) { - continuity[1] = 2; - continuity[2] = 3; - continuity[3] = 1; - } - for (unsigned int i = 0; i < dim.getTensorDim(continuity[cur_axis]); ++i) { + for (unsigned int i = 0; i < dim.getTensorDim(cur_axis); ++i) { size_t next_offset = offset + i * strides[cur_axis]; size_t next_m_offset = m_offset + i * e.strides[cur_axis]; apply_broadcast_util(m, v_func, output, e, cur_axis, next_offset, @@ -1557,17 +1633,19 @@ void Tensor::apply_broadcast_util( } } +#endif + void Tensor::apply_broadcast_util( Tensor const &m, - std::function + std::function v_func, Tensor &output, const BroadcastInfo &e, int cur_axis, size_t offset, size_t m_offset) const { - const __fp16 *buf = this->getData<__fp16>(); - const __fp16 *m_buf = m.getData<__fp16>(); - __fp16 *out_buf = output.getData<__fp16>(); + const float *buf = this->getData(); + const float *m_buf = m.getData(); + float *out_buf = output.getData(); if (e.buffer_axis == cur_axis) { v_func(e, buf + offset, m_buf + m_offset, out_buf + offset); @@ -1575,7 +1653,13 @@ void Tensor::apply_broadcast_util( } cur_axis++; - for (unsigned int i = 0; i < dim.getTensorDim(cur_axis); ++i) { + uint continuity[4] = {0, 1, 2, 3}; + if (getFormat() == Tformat::NHWC) { + continuity[1] = 2; + continuity[2] = 3; + continuity[3] = 1; + } + for (unsigned int i = 0; i < dim.getTensorDim(continuity[cur_axis]); ++i) { size_t next_offset = offset + i * strides[cur_axis]; size_t next_m_offset = m_offset + i * e.strides[cur_axis]; apply_broadcast_util(m, v_func, output, e, cur_axis, next_offset, @@ -1604,6 +1688,7 @@ Tensor Tensor::sum_by_batch() const { sgemv(CblasRowMajor, CblasNoTrans, batch, feat_len, 1, data, feat_len, ones.getData(), 1, 0.0, rdata, 1); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); __fp16 *rdata = ret.getData<__fp16>(); @@ -1611,6 +1696,9 @@ Tensor Tensor::sum_by_batch() const { ones.setValue((__fp16)1.0); sgemv(CblasRowMajor, CblasNoTrans, batch, feat_len, 1, data, feat_len, ones.getData<__fp16>(), 1, 0.0, rdata, 1); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return ret; @@ -1734,8 +1822,8 @@ Tensor &Tensor::sum(unsigned int axis, Tensor &ret, float alpha, default: throw std::out_of_range("Error: Dimension cannot exceed 3"); } - return ret; } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); NNTR_THROW_IF(!contiguous, std::invalid_argument) @@ -1841,8 +1929,11 @@ Tensor &Tensor::sum(unsigned int axis, Tensor &ret, float alpha, default: throw std::out_of_range("Error: Dimension cannot exceed 3"); } - return ret; +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } + return ret; } Tensor Tensor::sum(const std::vector &axes, float alpha) const { @@ -2123,6 +2214,7 @@ Tensor &Tensor::dot(Tensor const &m, Tensor &result, bool trans, bool trans_m, ldb, beta, rdata, ldc); } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); const __fp16 *mdata = m.getData<__fp16>(); __fp16 *rdata = result.getData<__fp16>(); @@ -2158,6 +2250,9 @@ Tensor &Tensor::dot(Tensor const &m, Tensor &result, bool trans, bool trans_m, sgemm(CblasRowMajor, transA, transB, M, N, K, alpha, data, lda, mdata, ldb, beta, rdata, ldc); } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return result; @@ -2233,7 +2328,8 @@ Tensor &Tensor::transpose(const std::string &direction, Tensor &out) const { } break; } - } else { + } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *inptr = getData<__fp16>(); __fp16 *outptr = out.getData<__fp16>(); switch (indexI) { @@ -2283,6 +2379,9 @@ Tensor &Tensor::transpose(const std::string &direction, Tensor &out) const { } break; } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return out; @@ -2312,6 +2411,7 @@ void Tensor::dropout_mask(float dropout) { data_[i] = 0.0; } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 __fp16 scale = 1.0 / (1 - dropout); __fp16 *data_ = getData<__fp16>(); for (unsigned int i = 0; i < size(); ++i) { @@ -2320,6 +2420,9 @@ void Tensor::dropout_mask(float dropout) { else data_[i] = 0.0; } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -2342,11 +2445,15 @@ void Tensor::filter_mask(const Tensor &mask_len, bool reverse) { std::fill(addr, addr + (*mask_len_val), en_mask_val); } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 for (unsigned int b = 0; b < batch(); b++) { __fp16 *addr = getAddress<__fp16>(b, 0, 0, 0); const uint *mask_len_val = mask_len.getAddress(b, 0, 0, 0); std::fill(addr, addr + (*mask_len_val), (__fp16)en_mask_val); } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -2376,6 +2483,7 @@ void Tensor::zoneout_mask(Tensor &opposite, float zoneout) { } } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 __fp16 zoneout_fp16 = (__fp16)zoneout; opposite.setRandBernoulli(zoneout_fp16); @@ -2389,6 +2497,9 @@ void Tensor::zoneout_mask(Tensor &opposite, float zoneout) { data[i] = (__fp16)1.0; } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -2498,6 +2609,7 @@ void Tensor::print(std::ostream &out) const { out.copyfmt(init); } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); unsigned int len = size(); out << "data addr: " << data << '\n'; @@ -2542,6 +2654,9 @@ void Tensor::print(std::ostream &out) const { } out.copyfmt(init); } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -2641,19 +2756,29 @@ void Tensor::copy(const void *buf) { NNTR_THROW_IF(!contiguous, std::invalid_argument) << getName() << "Tensor is not contiguous, cannot copy."; - if (getDataType() == ml::train::TensorDim::DataType::FP16 && - buf == getData<__fp16>()) { - return; - } else if (getDataType() == ml::train::TensorDim::DataType::FP32 && - buf == getData()) { - return; + if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 + if (buf == getData<__fp16>()) { + return; + } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif + } else if (getDataType() == ml::train::TensorDim::DataType::FP32) { + if (buf == getData()) { + return; + } } // std::string type_ = // (getDataType() == ml::train::TensorDim::DataType::FP16) ? "FP16" : "NO"; // std::cout << type_ << std::endl; if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 scopy(size(), (__fp16 *)buf, 1, getData<__fp16>(), 1); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } else if (getDataType() == ml::train::TensorDim::DataType::FP32) { scopy(size(), (float *)buf, 1, getData(), 1); } @@ -2672,7 +2797,8 @@ void Tensor::copy_with_stride(const Tensor &from) { } } } - } else { + } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 for (unsigned int b = 0; b < batch(); ++b) { for (unsigned int c = 0; c < channel(); ++c) { for (unsigned int h = 0; h < height(); ++h) { @@ -2682,6 +2808,9 @@ void Tensor::copy_with_stride(const Tensor &from) { } } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } else { Tensor t = Tensor(from.getDim(), true); @@ -2695,7 +2824,8 @@ void Tensor::copy_with_stride(const Tensor &from) { } } } - } else { + } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 for (unsigned int b = 0; b < batch(); ++b) { for (unsigned int c = 0; c < channel(); ++c) { for (unsigned int h = 0; h < height(); ++h) { @@ -2705,6 +2835,9 @@ void Tensor::copy_with_stride(const Tensor &from) { } } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } swap(t, *this); } @@ -2722,7 +2855,11 @@ void Tensor::copy(const Tensor &from) { if (getDataType() == ml::train::TensorDim::DataType::FP32) { copy(from.getData()); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 copy(from.getData<__fp16>()); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } else { @@ -2898,8 +3035,12 @@ void Tensor::setValue(float val) { float *data = getData(); std::fill(data, data + size(), val); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 __fp16 *data = getData<__fp16>(); std::fill(data, data + size(), (__fp16)val); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -2910,10 +3051,14 @@ void Tensor::setZero() { else apply_i([](float val) -> float { return 0; }); } else if (dim.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 if (contiguous) sscal(size(), 0, getData<__fp16>(), 1); else apply_i([](__fp16 val) -> __fp16 { return 0; }); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -2936,6 +3081,7 @@ std::vector Tensor::argmax() const { } } if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); size_t batch_size = batch(); size_t feature_len = dim.getFeatureLen(); @@ -2947,6 +3093,9 @@ std::vector Tensor::argmax() const { std::max_element(data + b * feature_len, data + (b + 1) * feature_len); result[b] = std::distance(data, max_iter) - (b * feature_len); } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } return result; @@ -2955,15 +3104,20 @@ std::vector Tensor::argmax() const { float Tensor::l2norm() const { NNTR_THROW_IF(!contiguous, std::invalid_argument) << getName() << " is not contiguous, cannot get l2norm."; - + float ret; unsigned int len = size(); if (getDataType() == ml::train::TensorDim::DataType::FP32) { const float *data = getData(); - return snrm2(len, data, 1); + ret = snrm2(len, data, 1); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); - return snrm2(len, data, 1); + ret = snrm2(len, data, 1); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } + return ret; } float Tensor::max_abs() const { @@ -2971,18 +3125,24 @@ float Tensor::max_abs() const { << getName() << " is not contiguous, cannot get max_abs."; unsigned int len = size(); + float ret; if (getDataType() == ml::train::TensorDim::DataType::FP32) { const float *data = getData(); unsigned int idx = isamax(len, data, 1); - return *(data + idx); + ret = *(data + idx); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); unsigned int idx = isamax(len, data, 1); - return *(data + idx); + ret = *(data + idx); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } + return ret; } Tensor &Tensor::normalization(Tensor &output) const { @@ -3014,6 +3174,7 @@ void Tensor::normalization_i() { this->divide_i(max - min); } } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 const __fp16 *data = getData<__fp16>(); auto bounds = std::minmax_element(data, data + size()); @@ -3027,6 +3188,9 @@ void Tensor::normalization_i() { this->subtract_i(min); this->divide_i(max - min); } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -3060,6 +3224,7 @@ void Tensor::standardization_i() { std_dev_by_batch.divide_i(dim.getFeatureLen()); this->divide_i(std_dev_by_batch); } else if (getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 Tensor std_dev_by_batch(dim.batch(), 1, 1, 1); std_dev_by_batch.setZero(); __fp16 *std_dev = std_dev_by_batch.getData<__fp16>(); @@ -3071,6 +3236,9 @@ void Tensor::standardization_i() { std_dev_by_batch.divide_i(dim.getFeatureLen()); this->divide_i(std_dev_by_batch); +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } } @@ -3166,8 +3334,8 @@ Tensor Tensor::rotate_180(Tensor in) { } } } - return output; } else if (in.getDataType() == ml::train::TensorDim::DataType::FP16) { +#ifdef ENABLE_FP16 output.setZero(); for (unsigned int i = 0; i < in.batch(); ++i) { for (unsigned int j = 0; j < in.channel(); ++j) { @@ -3180,8 +3348,11 @@ Tensor Tensor::rotate_180(Tensor in) { } } } - return output; +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } + return output; } } /* namespace nntrainer */ diff --git a/nntrainer/tensor/tensor.h b/nntrainer/tensor/tensor.h index eb1279f..887ea73 100644 --- a/nntrainer/tensor/tensor.h +++ b/nntrainer/tensor/tensor.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -267,6 +268,7 @@ public: ml::train::TensorDim::TensorType t_type) : Tensor(std::vector::type>{d}, t_type){}; +#ifdef ENABLE_FP16 Tensor(std::vector>>> const &d, ml::train::TensorDim::TensorType t_type) { @@ -337,6 +339,8 @@ public: ml::train::TensorDim::TensorType t_type) : Tensor(std::vector::type>{d}, t_type){}; +#endif + /** * @brief Copy constructor of Tensor. * @param[in] Tensor & @@ -1202,6 +1206,7 @@ public: } } } else if (dim.getDataType() == Tdatatype::FP16) { +#ifdef ENABLE_FP16 if (contiguous && output.contiguous) { const __fp16 *data = (getData<__fp16>()); __fp16 *rdata = (output.getData<__fp16>()); @@ -1230,8 +1235,10 @@ public: } } } +#else + throw std::invalid_argument("Error: enable-fp16 is not enabled"); +#endif } - return output; }; @@ -1298,7 +1305,11 @@ public: if (getDataType() == Tdatatype::FP32) { getData()[getIndex(batch, c, h, w)] = value; } else if (getDataType() == Tdatatype::FP16) { +#ifdef ENABLE_FP16 getData<__fp16>()[getIndex(batch, c, h, w)] = value; +#else + ml_loge("%s", "Error: enable-fp16 is not enabled"); +#endif } } @@ -1318,8 +1329,12 @@ public: getData()[idx] *= beta; getData()[idx] += value; } else if (dim.getDataType() == Tdatatype::FP16) { +#ifdef ENABLE_FP16 getData<__fp16>()[idx] *= beta; getData<__fp16>()[idx] += value; +#else + ml_loge("%s", "Error: enable-fp16 is not enabled"); +#endif } } @@ -1613,7 +1628,7 @@ public: return nullptr; data->validate(); - return (T *)((data->getAddr()) + offset); + return data->getAddr() + offset; } /** @@ -1625,7 +1640,7 @@ public: return nullptr; data->validate(); - return (T *)(data->getAddr() + offset); + return data->getAddr() + offset; } /** @@ -1636,10 +1651,10 @@ public: if (!data) return nullptr; - size_t index = idx * sizeof(T); + size_t index = idx; data->validate(); - return (T *)(data->getAddr() + offset + index); + return data->getAddr() + offset + index; } void setDataType(Tdatatype d_type) { dim.setDataType(d_type); } @@ -1669,7 +1684,7 @@ public: /** * @brief return offset */ - unsigned int getOffset() const { return offset; } + size_t getOffset() const { return offset; } /** * @brief i data index @@ -1750,7 +1765,7 @@ public: * @param buf the memory buffer * @param init intialize the buffer */ - void setData(const std::shared_ptr buf, unsigned int off = 0, + void setData(const std::shared_ptr buf, size_t off = 0, bool init = false) { if (buf) { data = buf; @@ -1794,7 +1809,7 @@ private: Tensor::Initializer initializer; std::string name; /**< name of the tensor */ std::shared_ptr data; - unsigned int offset; + size_t offset; /**< * When using shared_data with tensor, this stores the ptr of the source @@ -1826,14 +1841,6 @@ private: int cur_axis = -1, size_t offset = 0, size_t m_offset = 0) const; - void apply_broadcast_util( - Tensor const &m, - std::function - v_func, - Tensor &output, const BroadcastInfo &e, int cur_axis = -1, - size_t offset = 0, size_t m_offset = 0) const; - /** * @brief Applies the given operator to the tensor with the passed argument * @@ -1847,6 +1854,14 @@ private: const float *, float *)> v_func, Tensor &output) const; +#ifdef ENABLE_FP16 + void apply_broadcast_util( + Tensor const &m, + std::function + v_func, + Tensor &output, const BroadcastInfo &e, int cur_axis = -1, + size_t offset = 0, size_t m_offset = 0) const; void apply_broadcast(Tensor const &m, @@ -1854,7 +1869,7 @@ private: const __fp16 *, __fp16 *)> v_func, Tensor &output) const; - +#endif /** * @brief compute Loop info for broadcasting and vectorization * diff --git a/nntrainer/tensor/tensor_dim.cpp b/nntrainer/tensor/tensor_dim.cpp index 90825d5..eff8159 100644 --- a/nntrainer/tensor/tensor_dim.cpp +++ b/nntrainer/tensor/tensor_dim.cpp @@ -117,7 +117,11 @@ TensorDim &TensorDim::operator=(TensorDim &&rhs) noexcept { uint TensorDim::getDataTypeSize() const { switch (t_type.data_type) { case TensorDim::DataType::FP16: +#ifdef ENABLE_FP16 return sizeof(__fp16); +#else + return 2; +#endif case TensorDim::DataType::FP32: return sizeof(float); default: diff --git a/nntrainer/tensor/tensor_pool.cpp b/nntrainer/tensor/tensor_pool.cpp index a1ec348..ba1021c 100644 --- a/nntrainer/tensor/tensor_pool.cpp +++ b/nntrainer/tensor/tensor_pool.cpp @@ -60,7 +60,7 @@ Tensor *TensorPool::placeholder(const std::string &name, const TensorDim &dim) { Tensor *TensorPool::view(const std::string &name, const std::string &reference, const TensorDim &dim, const std::vector &exec_order, - TensorLifespan lifespan, const unsigned int offset) { + TensorLifespan lifespan, const size_t offset) { auto &spec = getSourceSpec(reference); unsigned adjusted_offset = std::visit( [](const auto &s) { diff --git a/nntrainer/tensor/tensor_pool.h b/nntrainer/tensor/tensor_pool.h index 25cb270..abd4a2f 100644 --- a/nntrainer/tensor/tensor_pool.h +++ b/nntrainer/tensor/tensor_pool.h @@ -197,7 +197,7 @@ public: Tensor *view(const std::string &name, const std::string &reference, const TensorDim &dim, const std::vector &exec_order, - TensorLifespan lifespan, const unsigned int offset = 0); + TensorLifespan lifespan, const size_t offset = 0); /** * @brief extend a tensor life as tensor is being shared. diff --git a/nntrainer/utils/base_properties.h b/nntrainer/utils/base_properties.h index 8f1905a..117b02b 100644 --- a/nntrainer/utils/base_properties.h +++ b/nntrainer/utils/base_properties.h @@ -650,7 +650,7 @@ struct TensorDataTypeInfo { static constexpr std::initializer_list EnumList = {Enum::FP16, Enum::FP32}; - static constexpr const char *EnumStr[] = {"fp16", "fp32"}; + static constexpr const char *EnumStr[] = {"FP16", "FP32"}; }; namespace props { @@ -663,6 +663,10 @@ class TensorDataType final : public EnumProperty { public: using prop_tag = enum_class_prop_tag; static constexpr const char *key = "tensor_type"; + TensorDataType( + TensorDataTypeInfo::Enum value = TensorDataTypeInfo::Enum::FP32) { + set(value); + }; }; /** @@ -682,7 +686,7 @@ public: */ TensorFormat(const std::string &value = "NCHW") { set(value); }; }; - } +} // namespace props } // namespace nntrainer diff --git a/test/jni/Android.mk b/test/jni/Android.mk index daeae45..a22202c 100644 --- a/test/jni/Android.mk +++ b/test/jni/Android.mk @@ -52,7 +52,7 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := test_util -LOCAL_CFLAGS := -Igoogletest/include -I../include -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti +LOCAL_CFLAGS := -Igoogletest/include -I../include -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti -DENABLE_FP16=1 LOCAL_CXXFLAGS += -std=c++17 -frtti -fexceptions LOCAL_LDLIBS := -llog -landroid -fopenmp -static-openmp @@ -66,7 +66,7 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := unittest_nntrainer_tensor -LOCAL_CFLAGS := -Igoogletest/include -I../include -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti +LOCAL_CFLAGS := -Igoogletest/include -I../include -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti -DENABLE_FP16=1 LOCAL_CXXFLAGS += -std=c++17 -frtti -fexceptions LOCAL_LDLIBS := -llog -landroid -fopenmp -static-openmp @@ -82,7 +82,7 @@ include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) LOCAL_MODULE := unittest_nntrainer_tensor_fp16 -LOCAL_CFLAGS := -Igoogletest/include -I../include -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti +LOCAL_CFLAGS := -Igoogletest/include -I../include -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti -DENABLE_FP16=1 LOCAL_CXXFLAGS += -std=c++17 -frtti -fexceptions LOCAL_LDLIBS := -llog -landroid -fopenmp -static-openmp @@ -114,19 +114,19 @@ include $(BUILD_EXECUTABLE) # include $(CLEAR_VARS) -# LOCAL_MODULE := unittest_compiler -# LOCAL_CFLAGS := -Igoogletest/include -I../include -I../unittest/compiler -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti -DNDK_BUILD=1 -# LOCAL_CXXFLAGS += -std=c++17 -frtti -fexceptions -# LOCAL_LDLIBS := -llog -landroid -fopenmp -static-openmp +LOCAL_MODULE := unittest_compiler +LOCAL_CFLAGS := -Igoogletest/include -I../include -I../unittest/compiler -pthread -fexceptions -fopenmp -static-openmp -DMIN_CPP_VERSION=201703L -DNNTR_NUM_THREADS=1 -D__LOGGING__=1 -DENABLE_TEST=1 -DREDUCE_TOLERANCE=1 -march=armv8.2-a+fp16 -mfpu=neon-fp16 -mfloat-abi=softfp -O3 -frtti -DNDK_BUILD=1 -DENABLE_FP16=1 +LOCAL_CXXFLAGS += -std=c++17 -frtti -fexceptions +LOCAL_LDLIBS := -llog -landroid -fopenmp -static-openmp -# LOCAL_SRC_FILES := \ -# ../unittest/compiler/compiler_test_util.cpp \ -# ../unittest/compiler/unittest_compiler.cpp \ -# ../unittest/compiler/unittest_realizer.cpp \ +LOCAL_SRC_FILES := \ + ../unittest/compiler/compiler_test_util.cpp \ + ../unittest/compiler/unittest_compiler.cpp \ + ../unittest/compiler/unittest_realizer.cpp \ -# LOCAL_C_INCLUDES += $(NNTRAINER_INCLUDES) +LOCAL_C_INCLUDES += $(NNTRAINER_INCLUDES) -# LOCAL_SHARED_LIBRARIES := nntrainer ccapi-nntrainer -# LOCAL_STATIC_LIBRARIES := googletest_main test_util -# include $(BUILD_EXECUTABLE) +LOCAL_SHARED_LIBRARIES := nntrainer ccapi-nntrainer +LOCAL_STATIC_LIBRARIES := googletest_main test_util +include $(BUILD_EXECUTABLE) diff --git a/test/unittest/jni/tests/nntrainer_test_util.cpp b/test/unittest/jni/tests/nntrainer_test_util.cpp deleted file mode 100644 index 790616e..0000000 --- a/test/unittest/jni/tests/nntrainer_test_util.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/** - * Copyright (C) 2019 Samsung Electronics Co., Ltd. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - * @file nntrainer_test_util.cpp - * @date 28 April 2020 - * @brief This is util functions for test - * @see https://github.com/nnstreamer/nntrainer - * @author Jijoong Moon - * @bug No known bugs except for NYI items - * - */ - -#include "nntrainer_test_util.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define num_class 10 -#define batch_size 16 -#define feature_size 62720 - -static std::mt19937 rng(0); - -/** - * @brief replace string and save it in file - * @param[in] from string to be replaced - * @param[in] to string to be replaced to - * @param[in] file file to perform the action on - * @param[in] init_config file contents to be initialized with if file not found - */ -void replaceString(const std::string &from, const std::string &to, - const std::string file, std::string init_config) { - size_t start_pos = 0; - std::string s; - std::ifstream file_stream(file.c_str(), std::ifstream::in); - if (file_stream.good()) { - s.assign((std::istreambuf_iterator(file_stream)), - std::istreambuf_iterator()); - file_stream.close(); - } else { - s = init_config; - } - while ((start_pos = s.find(from, start_pos)) != std::string::npos) { - s.replace(start_pos, from.size(), to); - start_pos += to.size(); - } - - std::ofstream data_file(file.c_str()); - data_file << s; - data_file.close(); -} - -/** - * @brief load data at specific position of file - * @param[in] F ifstream (input file) - * @param[out] outVec - * @param[out] outLabel - * @param[in] id th data to get - * @retval true/false false : end of data - */ -static bool getData(std::ifstream &F, float *outVec, float *outLabel, - unsigned int id) { - F.clear(); - F.seekg(0, std::ios_base::end); - uint64_t file_length = F.tellg(); - - uint64_t position = - (uint64_t)((feature_size + num_class) * (uint64_t)id * sizeof(float)); - - if (position > file_length) { - return false; - } - F.seekg(position, std::ios::beg); - F.read((char *)outVec, sizeof(float) * feature_size); - F.read((char *)outLabel, sizeof(float) * num_class); - - return true; -} - -DataInformation::DataInformation(unsigned int num_samples, - const std::string &filename) : - count(0), - num_samples(num_samples), - file(filename, std::ios::in | std::ios::binary), - idxes(num_samples) { - std::iota(idxes.begin(), idxes.end(), 0); - std::shuffle(idxes.begin(), idxes.end(), rng); - rng.seed(0); - if (!file.good()) { - throw std::invalid_argument("given file is not good, filename: " + - filename); - } -} - -static auto getDataSize = [](const std::string &file_name) { - std::ifstream f(file_name, std::ios::in | std::ios::binary); - NNTR_THROW_IF(!f.good(), std::invalid_argument) - << "cannot find " << file_name; - f.seekg(0, std::ios::end); - long file_size = f.tellg(); - return static_cast( - file_size / ((num_class + feature_size) * sizeof(float))); -}; - -std::string train_filename = getResPath("trainingSet.dat", {"test"}); -std::string valid_filename = getResPath("trainingSet.dat", {"test"}); - -DataInformation createTrainData() { - return DataInformation(getDataSize(train_filename), train_filename); -} - -DataInformation createValidData() { - return DataInformation(getDataSize(valid_filename), valid_filename); -} - -/** - * @brief get data which size is batch for train - * @param[out] outVec - * @param[out] outLabel - * @param[out] last if the data is finished - * @param[in] user_data private data for the callback - * @retval status for handling error - */ -int getSample(float **outVec, float **outLabel, bool *last, void *user_data) { - auto data = reinterpret_cast(user_data); - - getData(data->file, *outVec, *outLabel, data->idxes.at(data->count)); - data->count++; - if (data->count < data->num_samples) { - *last = false; - } else { - *last = true; - data->count = 0; - std::shuffle(data->idxes.begin(), data->idxes.end(), data->rng); - } - - return ML_ERROR_NONE; -} - -/** - * @brief return a tensor filled with contant value with dimension - */ -nntrainer::Tensor constant(float value, unsigned int batch, - unsigned int channel, unsigned int height, - unsigned int width) { - nntrainer::Tensor t(batch, channel, height, width); - t.setValue(value); - - return t; -} - -nntrainer::Tensor ranged(unsigned int batch, unsigned int channel, - unsigned int height, unsigned int width, - nntrainer::Tformat fm, nntrainer::DataType d_type) { - nntrainer::Tensor t(batch, channel, height, width, fm, d_type); - unsigned int i = 0; - if (d_type == nntrainer::DataType::FP32) - return t.apply([&](float in) { return i++; }); - else if (d_type == nntrainer::DataType::FP16) - return t.apply([&](__fp16 in) { return i++; }); -} - -nntrainer::Tensor randUniform(unsigned int batch, unsigned int channel, - unsigned int height, unsigned int width, - float min, float max) { - nntrainer::Tensor t(batch, channel, height, width); - t.setRandUniform(min, max); - return t; -} - -const std::string -getResPath(const std::string &filename, - const std::initializer_list fallback_base) { - static const char *prefix = std::getenv("NNTRAINER_RESOURCE_PATH"); - static const char *fallback_prefix = "./res"; - - std::stringstream ss; - if (prefix != nullptr) { - ss << prefix << '/' << filename; - return ss.str(); - } - - ss << fallback_prefix; - for (auto &folder : fallback_base) { - ss << '/' << folder; - } - - ss << '/' << filename; - - return ss.str(); -} - -nntrainer::GraphRepresentation -makeGraph(const std::vector &layer_reps) { - static auto &ac = nntrainer::AppContext::Global(); - nntrainer::GraphRepresentation graph_rep; - - for (const auto &layer_representation : layer_reps) { - /// @todo Use unique_ptr here - std::shared_ptr layer = nntrainer::createLayerNode( - ac.createObject(layer_representation.first), - layer_representation.second); - graph_rep.push_back(layer); - } - - return graph_rep; -} - -nntrainer::GraphRepresentation makeCompiledGraph( - const std::vector &layer_reps, - std::vector> &realizers, - const std::string &loss_layer) { - static auto &ac = nntrainer::AppContext::Global(); - - nntrainer::GraphRepresentation graph_rep; - auto model_graph = nntrainer::NetworkGraph(); - - for (auto &layer_representation : layer_reps) { - std::shared_ptr layer = nntrainer::createLayerNode( - ac.createObject(layer_representation.first), - layer_representation.second); - graph_rep.push_back(layer); - } - - for (auto &realizer : realizers) { - graph_rep = realizer->realize(graph_rep); - } - - for (auto &layer : graph_rep) { - model_graph.addLayer(layer); - } - - model_graph.compile(loss_layer); - - graph_rep.clear(); - for (auto &node : model_graph.getLayerNodes()) { - graph_rep.push_back(node); - } - - return graph_rep; -} - -void sizeCheckedReadTensor(nntrainer::Tensor &t, std::ifstream &file, - const std::string &error_msg) { - unsigned int sz = 0; - nntrainer::checkedRead(file, (char *)&sz, sizeof(unsigned)); - NNTR_THROW_IF(t.getDim().getDataLen() != sz, std::invalid_argument) - << "[ReadFail] dimension does not match at " << error_msg << " sz: " << sz - << " dimsize: " << t.getDim().getDataLen() << '\n'; - t.read(file); -} diff --git a/test/unittest/jni/tests/nntrainer_test_util.h b/test/unittest/jni/tests/nntrainer_test_util.h deleted file mode 100644 index 3a5767c..0000000 --- a/test/unittest/jni/tests/nntrainer_test_util.h +++ /dev/null @@ -1,244 +0,0 @@ -/** - * Copyright (C) 2019 Samsung Electronics Co., Ltd. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * - * @file nntrainer_test_util.h - * @date 28 April 2020 - * @brief This is util functions for test - * @see https://github.com/nnstreamer/nntrainer - * @author Jijoong Moon - * @bug No known bugs except for NYI items - * - */ - -#ifndef __NNTRAINER_TEST_UTIL_H__ -#define __NNTRAINER_TEST_UTIL_H__ -#ifdef __cplusplus - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/** tolerance is reduced for packaging, but CI runs at full tolerance */ -#ifdef REDUCE_TOLERANCE -#define tolerance 1.0e-4 -#else -#define tolerance 1.0e-5 -#endif - -/** Enum values to get model accuracy and loss. Sync with internal CAPI header - */ -#define ML_TRAIN_SUMMARY_MODEL_TRAIN_LOSS 101 -#define ML_TRAIN_SUMMARY_MODEL_VALID_LOSS 102 -#define ML_TRAIN_SUMMARY_MODEL_VALID_ACCURACY 103 - -/** Gtest compatibility for parameterize google test API */ -#ifdef GTEST_BACKPORT -#define GTEST_PARAMETER_TEST INSTANTIATE_TEST_CASE_P -#else -#define GTEST_PARAMETER_TEST INSTANTIATE_TEST_SUITE_P -#endif - -/** - * @brief This class wraps IniWrapper. This generates real ini file when - * construct, and remove real ini file when destroy - * - */ -class ScopedIni { -public: - /** - * @brief Construct a new Scoped Ini object - * - * @param ini_ ini wrapper - */ - ScopedIni(const nntrainer::IniWrapper &ini_) : ini(ini_) { ini.save_ini(); } - - /** - * @brief Construct a new Scoped Ini object - * - * @param name_ name - * @param sections_ sequenes of sections to save - */ - ScopedIni(const std::string &name_, - const nntrainer::IniWrapper::Sections §ions_) : - ini(name_, sections_) { - ini.save_ini(); - } - - /** - * @brief Get the Ini Name object - * - * @return std::string ini name - */ - std::string getIniName() { return ini.getIniName(); } - - /** - * @brief Destroy the Scoped Ini object - * - */ - ~ScopedIni() { ini.erase_ini(); } - -private: - nntrainer::IniWrapper ini; -}; - -#define GEN_TEST_INPUT(input, eqation_i_j_k_l) \ - do { \ - for (int i = 0; i < batch; ++i) { \ - for (int j = 0; j < channel; ++j) { \ - for (int k = 0; k < height; ++k) { \ - for (int l = 0; l < width; ++l) { \ - float val = eqation_i_j_k_l; \ - input.setValue(i, j, k, l, val); \ - } \ - } \ - } \ - } \ - } while (0) - -/** - * @brief return a tensor filled with contant value with dimension - */ -nntrainer::Tensor constant(float value, unsigned int batch, unsigned channel, - unsigned height, unsigned width); - -/** - * @brief return a tensor filled with ranged value with given dimension - */ -nntrainer::Tensor -ranged(unsigned int batch, unsigned channel, unsigned height, unsigned width, - nntrainer::Tformat fm = nntrainer::Tformat::NCHW, - nntrainer::DataType d_type = nntrainer::DataType::FP32); - -/** - * @brief return a tensor filled with random value with given dimension - */ -nntrainer::Tensor randUniform(unsigned int batch, unsigned channel, - unsigned height, unsigned width, float min = -1, - float max = 1); - -/** - * @brief replace string and save in file - * @param[in] from string to be replaced - * @param[in] to string to repalce with - * @param[in] n file name to save - * @retval void - */ -void replaceString(const std::string &from, const std::string &to, - const std::string n, std::string str); - -/** - * @brief UserData which stores information used to feed data from data callback - * - */ -class DataInformation { -public: - /** - * @brief Construct a new Data Information object - * - * @param num_samples number of data - * @param filename file name to read from - */ - DataInformation(unsigned int num_samples, const std::string &filename); - unsigned int count; - unsigned int num_samples; - std::ifstream file; - std::vector idxes; - std::mt19937 rng; -}; - -/** - * @brief Create a user data for training - * - * @return DataInformation - */ -DataInformation createTrainData(); - -/** - * @brief Create a user data for validataion - * - * @return DataInformation - */ -DataInformation createValidData(); - -/** - * @brief get data which size is batch - * @param[out] outVec - * @param[out] outLabel - * @param[out] last if the data is finished - * @param[in] user_data private data for the callback - * @retval status for handling error - */ -int getSample(float **outVec, float **outLabel, bool *last, void *user_data); - -/** - * @brief Get the Res Path object - * @note if NNTRAINER_RESOURCE_PATH environment variable is given, @a - * fallback_base is ignored and NNTRINAER_RESOURCE_PATH is directly used as a - * base - * - * @param filename filename if omitted, ${prefix}/${base} will be returned - * @param fallback_base list of base to attach when NNTRAINER_RESOURCE_PATH is - * not given - * @return const std::string path, - */ -const std::string -getResPath(const std::string &filename, - const std::initializer_list fallback_base = {}); - -using LayerRepresentation = std::pair>; - -/** - * @brief make graph of a representation - * - * @param layer_reps layer representation (pair of type, properties) - * @return nntrainer::GraphRepresentation synthesized graph representation - */ -nntrainer::GraphRepresentation -makeGraph(const std::vector &layer_reps); - -/** - * @brief make graph of a representation after compile - * - * @param layer_reps layer representation (pair of type, properties) - * @param realizers GraphRealizers to modify graph before compile - * @param loss_layer loss layer to compile with - * @return nntrainer::GraphRepresentation synthesized graph representation - */ -nntrainer::GraphRepresentation makeCompiledGraph( - const std::vector &layer_reps, - std::vector> &realizers, - const std::string &loss_layer = ""); - -/** - * @brief read tensor after reading tensor size - * - * @param t tensor to fill - * @param file file name - * @param error_msg error msg - */ -void sizeCheckedReadTensor(nntrainer::Tensor &t, std::ifstream &file, - const std::string &error_msg = ""); - -#endif /* __cplusplus */ -#endif /* __NNTRAINER_TEST_UTIL_H__ */ diff --git a/test/unittest/jni/tests/unittest_nntrainer_tensor.cpp b/test/unittest/jni/tests/unittest_nntrainer_tensor.cpp deleted file mode 100644 index 0773e30..0000000 --- a/test/unittest/jni/tests/unittest_nntrainer_tensor.cpp +++ /dev/null @@ -1,4067 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/** - * Copyright (C) 2020 Jijoong Moon - * - * @file unittest_nntrainer_tensor.cpp - * @date 03 June 2020 - * @brief Unit test utility for tensor. - * @see https://github.com/nnstreamer/nntrainer - * @author Jijoong Moon - * @bug No known bugs - */ -#include - -#include "nntrainer_test_util.h" -#include "util_func.h" -#include -#include -#include -#include -#include - -TEST(nntrainer_TensorDim, ctor_initializer_p) { - unsigned int b = 3; - unsigned int c = 2; - unsigned int h = 4; - unsigned int w = 5; - - nntrainer::TensorDim t = {w}; - EXPECT_EQ(nntrainer::TensorDim(1, 1, 1, w), t); - - t = {h, w}; - EXPECT_EQ(nntrainer::TensorDim(1, 1, h, w), t); - - t = {c, h, w}; - EXPECT_EQ(nntrainer::TensorDim(1, c, h, w), t); - - t = {b, c, h, w}; - EXPECT_EQ(nntrainer::TensorDim(b, c, h, w), t); -} - -TEST(nntrainer_TensorDim, ctor_initializer_nhwc_p) { - unsigned int b = 3; - unsigned int c = 2; - unsigned int h = 4; - unsigned int w = 5; - - nntrainer::TensorDim t = {c}; - EXPECT_EQ(nntrainer::TensorDim(1, 1, 1, c), t); - - t = {w, c}; - EXPECT_EQ(nntrainer::TensorDim(1, 1, w, c), t); - - t = {h, w, c}; - EXPECT_EQ(nntrainer::TensorDim(1, h, w, c), t); - - t = {b, h, w, c}; - EXPECT_EQ(nntrainer::TensorDim(b, h, w, c), t); -} - -TEST(nntrianer_TensorDim, effective_dimension_p) { - nntrainer::TensorDim t(3, 2, 4, 5, nntrainer::Tformat::NCHW); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2, 4, 5})); - - t.setEffDimFlag(0b1101); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2, 5})); - - t.setEffDimFlag(0b0011); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({4, 5})); - - t.setEffDimFlag(0b1111); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2, 4, 5})); - - t.setEffDimFlag(0b1100); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2})); - - t.setDynDimFlag(0b1100); - EXPECT_EQ(t.getEffectiveDimension(true), std::vector({-1, -1})); - - auto copied_t = t; - EXPECT_EQ(copied_t.getEffectiveDimension(), std::vector({3, 2})); - EXPECT_EQ(copied_t.getEffectiveDimension(true), std::vector({-1, -1})); - - auto moved_t = std::move(copied_t); - EXPECT_EQ(moved_t.getEffectiveDimension(), std::vector({3, 2})); - EXPECT_EQ(moved_t.getEffectiveDimension(true), std::vector({-1, -1})); -} - -TEST(nntrianer_TensorDim, effective_dimension_nhwc_p) { - nntrainer::TensorDim t(3, 2, 4, 5, nntrainer::Tformat::NHWC); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2, 4, 5})); - - t.setEffDimFlag(0b1101); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2, 5})); - - t.setEffDimFlag(0b0011); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({4, 5})); - - t.setEffDimFlag(0b1111); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2, 4, 5})); - - t.setEffDimFlag(0b1100); - EXPECT_EQ(t.getEffectiveDimension(), std::vector({3, 2})); - - t.setDynDimFlag(0b1100); - EXPECT_EQ(t.getEffectiveDimension(true), std::vector({-1, -1})); - - auto copied_t = t; - EXPECT_EQ(copied_t.getEffectiveDimension(), std::vector({3, 2})); - EXPECT_EQ(copied_t.getEffectiveDimension(true), std::vector({-1, -1})); - - auto moved_t = std::move(copied_t); - EXPECT_EQ(moved_t.getEffectiveDimension(), std::vector({3, 2})); - EXPECT_EQ(moved_t.getEffectiveDimension(true), std::vector({-1, -1})); -} - -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), - std::invalid_argument); -} - -TEST(nntrainer_TensorDim, setTensorDim_01_p) { - int status = ML_ERROR_NONE; - - nntrainer::TensorDim tensor_dim; - status = tensor_dim.setTensorDim("1:2:3:4"); - 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); - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_TensorDim, setTensorDim_02_n) { - int status = ML_ERROR_NONE; - - nntrainer::TensorDim tensor_dim; - status = tensor_dim.setTensorDim("1:2:3:4:5"); - 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); - EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_TensorDim, setTensorDim_03_n) { - nntrainer::TensorDim d; - - 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_03_nhwc_n) { - nntrainer::TensorDim d(nntrainer::Tformat::NHWC); - - 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; - - d.setTensorDim(0, 4); - d.setTensorDim(1, 5); - d.setTensorDim(2, 6); - d.setTensorDim(3, 7); - - EXPECT_EQ(d.batch(), 4u); - EXPECT_EQ(d.channel(), 5u); - EXPECT_EQ(d.height(), 6u); - EXPECT_EQ(d.width(), 7u); -} - -TEST(nntrainer_TensorDim, setTensorDim_04_nhwc_p) { - nntrainer::TensorDim d(nntrainer::Tformat::NHWC); - - 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); - 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); -} - -TEST(nntrainer_Tensor, Tensor_01_nhwc_p) { - int status = ML_ERROR_NONE; - nntrainer::Tensor tensor = - nntrainer::Tensor(1, 2, 3, nntrainer::Tformat::NHWC); - 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); -} - -TEST(nntrainer_Tensor, Tensor_02_p) { - int status = ML_ERROR_NONE; - int height = 3; - int width = 10; - std::vector> in; - for (int i = 0; i < height; ++i) { - std::vector tv; - for (int j = 0; j < width; ++j) { - tv.push_back(i * 2.0 + j); - } - in.push_back(tv); - } - - nntrainer::Tensor tensor = nntrainer::Tensor(in); - ASSERT_NE(nullptr, tensor.getData()); - - 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; - int batch = 3; - int height = 3; - int width = 10; - std::vector>> in; - for (int k = 0; k < batch; ++k) { - std::vector> ttv; - for (int i = 0; i < height; ++i) { - std::vector tv; - for (int j = 0; j < width; ++j) { - tv.push_back(k * height * width + i * width + j); - } - ttv.push_back(tv); - } - in.push_back(ttv); - } - - nntrainer::Tensor tensor = nntrainer::Tensor(in); - ASSERT_NE(nullptr, tensor.getData()); - - if (tensor.getValue(0, 0, 0, 1) != 1.0) - status = ML_ERROR_INVALID_PARAMETER; - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, multiply_i_01_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor original; - original.copy(input); - - status = input.multiply_i(2.0); - EXPECT_EQ(status, ML_ERROR_NONE); - - float *data = original.getData(); - ASSERT_NE(nullptr, data); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width * channel; ++i) { - EXPECT_FLOAT_EQ(data[i] + data[i], indata[i]); - } -} - -TEST(nntrainer_Tensor, multiply_i_02_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor original; - original.copy(input); - - status = input.multiply_i(input); - EXPECT_EQ(status, ML_ERROR_NONE); - - float *data = original.getData(); - ASSERT_NE(nullptr, data); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width * channel; ++i) { - EXPECT_FLOAT_EQ(data[i] * data[i], indata[i]); - } -} - -TEST(nntrainer_Tensor, multiply_i_03_n) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor target2(batch, channel, height - 2, width - 1); - status = input.multiply_i(target2); - - EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, multiply_i_broadcast_01_p) { - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 2, 4, 5); - float answer_data[] = { - 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, - 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, - 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, - 1296, 1369, 1444, 1521, 0, 41, 84, 129, 176, 225, 276, 329, - 384, 441, 500, 561, 624, 689, 756, 825, 896, 969, 1044, 1121, - 1200, 1281, 1364, 1449, 1536, 1625, 1716, 1809, 1904, 2001, 2100, 2201, - 2304, 2409, 2516, 2625, 2736, 2849, 2964, 3081, 0, 81, 164, 249, - 336, 425, 516, 609, 704, 801, 900, 1001, 1104, 1209, 1316, 1425, - 1536, 1649, 1764, 1881, 2000, 2121, 2244, 2369, 2496, 2625, 2756, 2889, - 3024, 3161, 3300, 3441, 3584, 3729, 3876, 4025, 4176, 4329, 4484, 4641}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 4, 5); - float answer_data[] = { - 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, - 144, 169, 196, 225, 256, 289, 324, 361, 0, 21, 44, 69, - 96, 125, 156, 189, 224, 261, 300, 341, 384, 429, 476, 525, - 576, 629, 684, 741, 800, 861, 924, 989, 1056, 1125, 1196, 1269, - 1344, 1421, 1500, 1581, 1664, 1749, 1836, 1925, 2016, 2109, 2204, 2301, - 1200, 1281, 1364, 1449, 1536, 1625, 1716, 1809, 1904, 2001, 2100, 2201, - 2304, 2409, 2516, 2625, 2736, 2849, 2964, 3081, 3200, 3321, 3444, 3569, - 3696, 3825, 3956, 4089, 4224, 4361, 4500, 4641, 4784, 4929, 5076, 5225, - 5376, 5529, 5684, 5841, 4000, 4141, 4284, 4429, 4576, 4725, 4876, 5029, - 5184, 5341, 5500, 5661, 5824, 5989, 6156, 6325, 6496, 6669, 6844, 7021}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 2, 4, 1); - float answer_data[] = { - 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 20, 22, - 24, 26, 28, 45, 48, 51, 54, 57, 80, 84, 88, 92, - 96, 125, 130, 135, 140, 145, 180, 186, 192, 198, 204, 245, - 252, 259, 266, 273, 320, 328, 336, 344, 352, 405, 414, 423, - 432, 441, 500, 510, 520, 530, 540, 605, 616, 627, 638, 649, - 720, 732, 744, 756, 768, 845, 858, 871, 884, 897, 980, 994, - 1008, 1022, 1036, 1125, 1140, 1155, 1170, 1185, 1280, 1296, 1312, 1328, - 1344, 1445, 1462, 1479, 1496, 1513, 1620, 1638, 1656, 1674, 1692, 1805, - 1824, 1843, 1862, 1881, 2000, 2020, 2040, 2060, 2080, 2205, 2226, 2247, - 2268, 2289, 2420, 2442, 2464, 2486, 2508, 2645, 2668, 2691, 2714, 2737}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 1, 5); - float answer_data[] = { - 0, 1, 4, 9, 16, 0, 6, 14, 24, 36, 0, 11, - 24, 39, 56, 0, 16, 34, 54, 76, 0, 21, 44, 69, - 96, 0, 26, 54, 84, 116, 0, 31, 64, 99, 136, 0, - 36, 74, 114, 156, 200, 246, 294, 344, 396, 225, 276, 329, - 384, 441, 250, 306, 364, 424, 486, 275, 336, 399, 464, 531, - 300, 366, 434, 504, 576, 325, 396, 469, 544, 621, 350, 426, - 504, 584, 666, 375, 456, 539, 624, 711, 800, 891, 984, 1079, - 1176, 850, 946, 1044, 1144, 1246, 900, 1001, 1104, 1209, 1316, 950, - 1056, 1164, 1274, 1386, 1000, 1111, 1224, 1339, 1456, 1050, 1166, 1284, - 1404, 1526, 1100, 1221, 1344, 1469, 1596, 1150, 1276, 1404, 1534, 1666}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 2, 1, 5); - float answer_data[] = { - 0, 1, 4, 9, 16, 0, 6, 14, 24, 36, 0, 11, 24, 39, - 56, 0, 16, 34, 54, 76, 100, 126, 154, 184, 216, 125, 156, 189, - 224, 261, 150, 186, 224, 264, 306, 175, 216, 259, 304, 351, 0, 41, - 84, 129, 176, 0, 46, 94, 144, 196, 0, 51, 104, 159, 216, 0, - 56, 114, 174, 236, 300, 366, 434, 504, 576, 325, 396, 469, 544, 621, - 350, 426, 504, 584, 666, 375, 456, 539, 624, 711, 0, 81, 164, 249, - 336, 0, 86, 174, 264, 356, 0, 91, 184, 279, 376, 0, 96, 194, - 294, 396, 500, 606, 714, 824, 936, 525, 636, 749, 864, 981, 550, 666, - 784, 904, 1026, 575, 696, 819, 944, 1071}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 4, 1); - float answer_data[] = { - 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 20, 22, - 24, 26, 28, 45, 48, 51, 54, 57, 0, 0, 0, 0, - 0, 25, 26, 27, 28, 29, 60, 62, 64, 66, 68, 105, - 108, 111, 114, 117, 160, 164, 168, 172, 176, 225, 230, 235, - 240, 245, 300, 306, 312, 318, 324, 385, 392, 399, 406, 413, - 240, 244, 248, 252, 256, 325, 330, 335, 340, 345, 420, 426, - 432, 438, 444, 525, 532, 539, 546, 553, 640, 648, 656, 664, - 672, 765, 774, 783, 792, 801, 900, 910, 920, 930, 940, 1045, - 1056, 1067, 1078, 1089, 800, 808, 816, 824, 832, 945, 954, 963, - 972, 981, 1100, 1110, 1120, 1130, 1140, 1265, 1276, 1287, 1298, 1309}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 1, 1, 5); - float answer_data[] = { - 0, 1, 4, 9, 16, 0, 6, 14, 24, 36, 0, 11, 24, 39, 56, - 0, 16, 34, 54, 76, 0, 21, 44, 69, 96, 0, 26, 54, 84, 116, - 0, 31, 64, 99, 136, 0, 36, 74, 114, 156, 0, 41, 84, 129, 176, - 0, 46, 94, 144, 196, 0, 51, 104, 159, 216, 0, 56, 114, 174, 236, - 0, 61, 124, 189, 256, 0, 66, 134, 204, 276, 0, 71, 144, 219, 296, - 0, 76, 154, 234, 316, 0, 81, 164, 249, 336, 0, 86, 174, 264, 356, - 0, 91, 184, 279, 376, 0, 96, 194, 294, 396, 0, 101, 204, 309, 416, - 0, 106, 214, 324, 436, 0, 111, 224, 339, 456, 0, 116, 234, 354, 476}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 2, 1, 1); - float answer_data[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 1, 1); - float answer_data[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 160, 162, 164, 166, - 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, - 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, - 224, 226, 228, 230, 232, 234, 236, 238}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 5, 1, 4); - nntrainer::Tensor t = ranged(3, 5, 1, 4); - nntrainer::Tensor m = ranged(3, 1, 1, 4); - float answer_data[] = {0, 1, 4, 9, 0, 5, 12, 21, 0, 9, - 20, 33, 0, 13, 28, 45, 0, 17, 36, 57, - 80, 105, 132, 161, 96, 125, 156, 189, 112, 145, - 180, 217, 128, 165, 204, 245, 144, 185, 228, 273, - 320, 369, 420, 473, 352, 405, 460, 517, 384, 441, - 500, 561, 416, 477, 540, 605, 448, 513, 580, 649}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.multiply_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } -} - -TEST(nntrainer_Tensor, multiply_i_broadcast_not_supported_01_n) { - nntrainer::Tensor target(3, 1, 3, 1); - nntrainer::Tensor target2(3, 1, 3, 3); - - EXPECT_EQ(target.multiply_i(target2), ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, multiply_i_broadcast_not_broadcastable_02_n) { - nntrainer::Tensor target(3, 2, 4, 5); - nntrainer::Tensor target2(3, 2, 3, 1); - - EXPECT_EQ(target.multiply_i(target2), ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, multiply_01_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor result = input.multiply(0.0); - if (result.getValue(0, 0, 1, 1) != 0.0) - status = ML_ERROR_RESULT_OUT_OF_RANGE; - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, multiply_02_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor result = input.multiply(input); - - float *data = result.getData(); - ASSERT_NE(nullptr, data); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width; ++i) { - if (data[i] != indata[i] * indata[i]) { - status = ML_ERROR_RESULT_OUT_OF_RANGE; - break; - } - } - - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, multiply_03_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor test(batch - 1, height - 1, width - 1); - - EXPECT_THROW({ input.multiply(test); }, std::invalid_argument); -} - -TEST(nntrainer_Tensor, multiply_04_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(batch, channel, height, 2 * width); - nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); - nntrainer::Tensor test(dim); - - EXPECT_THROW(shared_input.multiply(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, multiply_05_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - nntrainer::Tensor test(batch, channel, height, 2 * width); - nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - - EXPECT_THROW(input.multiply(shared_test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, multiply_06_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim, false); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - - EXPECT_THROW(input.multiply(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, multiply_07_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim, false); - - EXPECT_THROW(input.multiply(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, multiply_08_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); - nntrainer::Tensor output(dim, false); - - EXPECT_THROW(input.multiply(test, output), std::invalid_argument); -} - -TEST(nntrainer_Tensor, multiply_float_01_p) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor expected(batch, channel, height, width); - GEN_TEST_INPUT(expected, (i * (batch * height) + j * (width) + k + 1) * 2); - - nntrainer::Tensor result = input.multiply(2.0); - - EXPECT_EQ(result, expected); -} - -TEST(nntrainer_Tensor, divide_i_01_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor original; - original.copy(input); - - status = input.divide_i((float)2.0); - EXPECT_EQ(status, ML_ERROR_NONE); - - float *data = original.getData(); - ASSERT_NE(nullptr, data); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width * channel; ++i) { - EXPECT_FLOAT_EQ(data[i], indata[i] + indata[i]); - } -} - -TEST(nntrainer_Tensor, divide_i_02_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - status = input.divide_i(input); - EXPECT_EQ(status, ML_ERROR_NONE); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width * channel; ++i) { - EXPECT_FLOAT_EQ(indata[i], float(1.0)); - } -} - -TEST(nntrainer_Tensor, divide_i_01_n) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - status = input.divide_i((float)0); - EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, divide_i_02_n) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor original(batch, channel, height - 2, width - 1); - - status = input.divide_i(original); - EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, divide_01_p) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor result = input.divide(1.0); - - float *previous = input.getData(); - ASSERT_NE(nullptr, previous); - float *data = result.getData(); - ASSERT_NE(nullptr, data); - - for (int i = 0; i < batch * height * width * channel; ++i) { - EXPECT_FLOAT_EQ(data[i], previous[i]); - } -} - -TEST(nntrainer_Tensor, divide_02_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - EXPECT_THROW({ input.divide(0.0); }, std::invalid_argument); -} - -TEST(nntrainer_Tensor, divide_03_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1); - - EXPECT_THROW({ input.divide(test); }, std::invalid_argument); -} - -TEST(nntrainer_Tensor, divide_04_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(batch, channel, height, 2 * width); - nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); - nntrainer::Tensor test(dim); - - EXPECT_THROW(shared_input.divide(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, divide_05_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - nntrainer::Tensor test(batch, channel, height, 2 * width); - nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - - EXPECT_THROW(input.divide(shared_test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, divide_06_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim, false); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - - EXPECT_THROW(input.divide(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, divide_07_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim, false); - - EXPECT_THROW(input.divide(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, divide_08_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); - nntrainer::Tensor output(dim, false); - - EXPECT_THROW(input.divide(test, output), std::invalid_argument); -} - -TEST(nntrainer_Tensor, divide_i_broadcast_01_p) { - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(1, 2, 4, 5); - m.add_i(1); - float answer_data[] = { - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 41.0, 21.0, - 14.333333, 11.0, 9.0, 7.6666665, 6.714286, 6.0, - 5.4444447, 5.0, 4.6363635, 4.3333335, 4.076923, 3.857143, - 3.6666667, 3.5, 3.3529413, 3.2222223, 3.1052632, 3.0, - 2.9047618, 2.8181818, 2.7391305, 2.6666667, 2.6, 2.5384614, - 2.4814816, 2.4285715, 2.3793104, 2.3333333, 2.2903225, 2.25, - 2.2121212, 2.1764705, 2.142857, 2.1111112, 2.0810812, 2.0526316, - 2.025641, 2.0, 81.0, 41.0, 27.666666, 21.0, - 17.0, 14.333333, 12.428572, 11.0, 9.888889, 9.0, - 8.272727, 7.6666665, 7.1538463, 6.714286, 6.3333335, 6.0, - 5.7058825, 5.4444447, 5.2105265, 5.0, 4.8095236, 4.6363635, - 4.478261, 4.3333335, 4.2, 4.076923, 3.9629629, 3.857143, - 3.7586207, 3.6666667, 3.580645, 3.5, 3.4242425, 3.3529413, - 3.2857144, 3.2222223, 3.162162, 3.1052632, 3.0512822, 3.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(3, 1, 4, 5); - m.add_i(1); - float answer_data[] = { - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 21.0, 11.0, 7.6666665, 6.0, - 5.0, 4.3333335, 3.857143, 3.5, 3.2222223, 3.0, - 2.8181818, 2.6666667, 2.5384614, 2.4285715, 2.3333333, 2.25, - 2.1764705, 2.1111112, 2.0526316, 2.0, 1.9523809, 1.9090909, - 1.8695652, 1.8333334, 1.8, 1.7692307, 1.7407408, 1.7142857, - 1.6896552, 1.6666666, 1.6451613, 1.625, 1.6060606, 1.5882353, - 1.5714285, 1.5555556, 1.5405406, 1.5263158, 1.5128205, 1.5, - 2.9047618, 2.8181818, 2.7391305, 2.6666667, 2.6, 2.5384614, - 2.4814816, 2.4285715, 2.3793104, 2.3333333, 2.2903225, 2.25, - 2.2121212, 2.1764705, 2.142857, 2.1111112, 2.0810812, 2.0526316, - 2.025641, 2.0, 1.9756098, 1.9523809, 1.9302325, 1.9090909, - 1.8888888, 1.8695652, 1.8510638, 1.8333334, 1.8163265, 1.8, - 1.7843137, 1.7692307, 1.754717, 1.7407408, 1.7272727, 1.7142857, - 1.7017543, 1.6896552, 1.6779661, 1.6666666, 2.4634147, 2.4285715, - 2.3953488, 2.3636363, 2.3333333, 2.3043478, 2.2765958, 2.25, - 2.2244897, 2.2, 2.1764705, 2.1538463, 2.1320755, 2.1111112, - 2.090909, 2.0714285, 2.0526316, 2.0344827, 2.0169492, 2.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(3, 2, 4, 1); - m.add_i(1); - float answer_data[] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 3.0, - 3.5, 4.0, 4.5, 5.0, 3.6666667, 4.0, - 4.3333335, 4.6666665, 5.0, 4.0, 4.25, 4.5, - 4.75, 5.0, 4.2, 4.4, 4.6, 4.8, - 5.0, 4.3333335, 4.5, 4.6666665, 4.8333335, 5.0, - 4.428571, 4.571429, 4.714286, 4.857143, 5.0, 4.5, - 4.625, 4.75, 4.875, 5.0, 4.5555553, 4.6666665, - 4.7777777, 4.888889, 5.0, 4.6, 4.7, 4.8, - 4.9, 5.0, 4.6363635, 4.7272725, 4.818182, 4.909091, - 5.0, 4.6666665, 4.75, 4.8333335, 4.9166665, 5.0, - 4.6923075, 4.769231, 4.8461537, 4.923077, 5.0, 4.714286, - 4.785714, 4.857143, 4.928571, 5.0, 4.733333, 4.8, - 4.866667, 4.9333334, 5.0, 4.75, 4.8125, 4.875, - 4.9375, 5.0, 4.7647057, 4.8235292, 4.882353, 4.9411764, - 5.0, 4.7777777, 4.8333335, 4.888889, 4.9444447, 5.0, - 4.7894735, 4.8421054, 4.894737, 4.9473686, 5.0, 4.8, - 4.85, 4.9, 4.95, 5.0, 4.8095236, 4.857143, - 4.904762, 4.952381, 5.0, 4.818182, 4.8636365, 4.909091, - 4.9545455, 5.0, 4.826087, 4.869565, 4.9130435, 4.9565215, - 5.0, 4.8333335, 4.875, 4.9166665, 4.9583335, 5.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(3, 1, 1, 5); - m.add_i(1); - float answer_data[] = { - 1.0, 1.0, 1.0, 1.0, 1.0, 6.0, - 3.5, 2.6666667, 2.25, 2.0, 11.0, 6.0, - 4.3333335, 3.5, 3.0, 16.0, 8.5, 6.0, - 4.75, 4.0, 21.0, 11.0, 7.6666665, 6.0, - 5.0, 26.0, 13.5, 9.333333, 7.25, 6.0, - 31.0, 16.0, 11.0, 8.5, 7.0, 36.0, - 18.5, 12.666667, 9.75, 8.0, 6.8333335, 6.0, - 5.375, 4.888889, 4.5, 7.6666665, 6.714286, 6.0, - 5.4444447, 5.0, 8.5, 7.428571, 6.625, 6.0, - 5.5, 9.333333, 8.142858, 7.25, 6.5555553, 6.0, - 10.166667, 8.857142, 7.875, 7.111111, 6.5, 11.0, - 9.571428, 8.5, 7.6666665, 7.0, 11.833333, 10.285714, - 9.125, 8.222222, 7.5, 12.666667, 11.0, 9.75, - 8.777778, 8.0, 7.3636365, 6.8333335, 6.3846154, 6.0, - 5.6666665, 7.818182, 7.25, 6.769231, 6.357143, 6.0, - 8.272727, 7.6666665, 7.1538463, 6.714286, 6.3333335, 8.727273, - 8.083333, 7.5384617, 7.071429, 6.6666665, 9.181818, 8.5, - 7.923077, 7.428571, 7.0, 9.636364, 8.916667, 8.307693, - 7.785714, 7.3333335, 10.090909, 9.333333, 8.692307, 8.142858, - 7.6666665, 10.545455, 9.75, 9.076923, 8.5, 8.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(1, 2, 1, 5); - m.add_i(1); - float answer_data[] = { - 1.0, 1.0, 1.0, 1.0, 1.0, 6.0, - 3.5, 2.6666667, 2.25, 2.0, 11.0, 6.0, - 4.3333335, 3.5, 3.0, 16.0, 8.5, 6.0, - 4.75, 4.0, 3.5, 3.142857, 2.875, 2.6666667, - 2.5, 4.3333335, 3.857143, 3.5, 3.2222223, 3.0, - 5.1666665, 4.571429, 4.125, 3.7777777, 3.5, 6.0, - 5.285714, 4.75, 4.3333335, 4.0, 41.0, 21.0, - 14.333333, 11.0, 9.0, 46.0, 23.5, 16.0, - 12.25, 10.0, 51.0, 26.0, 17.666666, 13.5, - 11.0, 56.0, 28.5, 19.333334, 14.75, 12.0, - 10.166667, 8.857142, 7.875, 7.111111, 6.5, 11.0, - 9.571428, 8.5, 7.6666665, 7.0, 11.833333, 10.285714, - 9.125, 8.222222, 7.5, 12.666667, 11.0, 9.75, - 8.777778, 8.0, 81.0, 41.0, 27.666666, 21.0, - 17.0, 86.0, 43.5, 29.333334, 22.25, 18.0, - 91.0, 46.0, 31.0, 23.5, 19.0, 96.0, - 48.5, 32.666668, 24.75, 20.0, 16.833334, 14.571428, - 12.875, 11.555555, 10.5, 17.666666, 15.285714, 13.5, - 12.111111, 11.0, 18.5, 16.0, 14.125, 12.666667, - 11.5, 19.333334, 16.714285, 14.75, 13.222222, 12.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(3, 1, 4, 1); - m.add_i(1); - float answer_data[] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 3.0, - 3.5, 4.0, 4.5, 5.0, 3.6666667, 4.0, - 4.3333335, 4.6666665, 5.0, 4.0, 4.25, 4.5, - 4.75, 5.0, 21.0, 22.0, 23.0, 24.0, - 25.0, 13.0, 13.5, 14.0, 14.5, 15.0, - 10.333333, 10.666667, 11.0, 11.333333, 11.666667, 9.0, - 9.25, 9.5, 9.75, 10.0, 8.2, 8.4, - 8.6, 8.8, 9.0, 7.6666665, 7.8333335, 8.0, - 8.166667, 8.333333, 7.285714, 7.428571, 7.571429, 7.714286, - 7.857143, 7.0, 7.125, 7.25, 7.375, 7.5, - 12.2, 12.4, 12.6, 12.8, 13.0, 11.0, - 11.166667, 11.333333, 11.5, 11.666667, 10.142858, 10.285714, - 10.428572, 10.571428, 10.714286, 9.5, 9.625, 9.75, - 9.875, 10.0, 9.0, 9.111111, 9.222222, 9.333333, - 9.444445, 8.6, 8.7, 8.8, 8.9, 9.0, - 8.272727, 8.363636, 8.454545, 8.545455, 8.636364, 8.0, - 8.083333, 8.166667, 8.25, 8.333333, 11.222222, 11.333333, - 11.444445, 11.555555, 11.666667, 10.6, 10.7, 10.8, - 10.9, 11.0, 10.090909, 10.181818, 10.272727, 10.363636, - 10.454545, 9.666667, 9.75, 9.833333, 9.916667, 10.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(1, 1, 1, 5); - m.add_i(1); - float answer_data[] = { - 1.0, 1.0, 1.0, 1.0, 1.0, 6.0, 3.5, 2.6666667, 2.25, 2.0, - 11.0, 6.0, 4.3333335, 3.5, 3.0, 16.0, 8.5, 6.0, 4.75, 4.0, - 21.0, 11.0, 7.6666665, 6.0, 5.0, 26.0, 13.5, 9.333333, 7.25, 6.0, - 31.0, 16.0, 11.0, 8.5, 7.0, 36.0, 18.5, 12.666667, 9.75, 8.0, - 41.0, 21.0, 14.333333, 11.0, 9.0, 46.0, 23.5, 16.0, 12.25, 10.0, - 51.0, 26.0, 17.666666, 13.5, 11.0, 56.0, 28.5, 19.333334, 14.75, 12.0, - 61.0, 31.0, 21.0, 16.0, 13.0, 66.0, 33.5, 22.666666, 17.25, 14.0, - 71.0, 36.0, 24.333334, 18.5, 15.0, 76.0, 38.5, 26.0, 19.75, 16.0, - 81.0, 41.0, 27.666666, 21.0, 17.0, 86.0, 43.5, 29.333334, 22.25, 18.0, - 91.0, 46.0, 31.0, 23.5, 19.0, 96.0, 48.5, 32.666668, 24.75, 20.0, - 101.0, 51.0, 34.333332, 26.0, 21.0, 106.0, 53.5, 36.0, 27.25, 22.0, - 111.0, 56.0, 37.666668, 28.5, 23.0, 116.0, 58.5, 39.333332, 29.75, 24.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(1, 2, 1, 1); - m.add_i(1); - float answer_data[] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, - 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 10.5, 11.0, 11.5, 12.0, - 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0, - 18.5, 19.0, 19.5, 20.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, - 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, - 30.5, 31.0, 31.5, 32.0, 32.5, 33.0, 33.5, 34.0, 34.5, 35.0, 35.5, 36.0, - 36.5, 37.0, 37.5, 38.0, 38.5, 39.0, 39.5, 40.0, 81.0, 82.0, 83.0, 84.0, - 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, - 97.0, 98.0, 99.0, 100.0, 50.5, 51.0, 51.5, 52.0, 52.5, 53.0, 53.5, 54.0, - 54.5, 55.0, 55.5, 56.0, 56.5, 57.0, 57.5, 58.0, 58.5, 59.0, 59.5, 60.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - t.add_i(1); - nntrainer::Tensor m = ranged(3, 1, 1, 1); - m.add_i(1); - float answer_data[] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, - 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, - 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, - 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, - 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, - 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, - 37.0, 38.0, 39.0, 40.0, 20.5, 21.0, - 21.5, 22.0, 22.5, 23.0, 23.5, 24.0, - 24.5, 25.0, 25.5, 26.0, 26.5, 27.0, - 27.5, 28.0, 28.5, 29.0, 29.5, 30.0, - 30.5, 31.0, 31.5, 32.0, 32.5, 33.0, - 33.5, 34.0, 34.5, 35.0, 35.5, 36.0, - 36.5, 37.0, 37.5, 38.0, 38.5, 39.0, - 39.5, 40.0, 27.0, 27.333334, 27.666666, 28.0, - 28.333334, 28.666666, 29.0, 29.333334, 29.666666, 30.0, - 30.333334, 30.666666, 31.0, 31.333334, 31.666666, 32.0, - 32.333332, 32.666668, 33.0, 33.333332, 33.666668, 34.0, - 34.333332, 34.666668, 35.0, 35.333332, 35.666668, 36.0, - 36.333332, 36.666668, 37.0, 37.333332, 37.666668, 38.0, - 38.333332, 38.666668, 39.0, 39.333332, 39.666668, 40.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 5, 1, 4); - nntrainer::Tensor t = ranged(3, 5, 1, 4); - t.add_i(1); - nntrainer::Tensor m = ranged(3, 1, 1, 4); - m.add_i(1); - float answer_data[] = { - 1.0, 1.0, 1.0, 1.0, 5.0, 3.0, - 2.3333333, 2.0, 9.0, 5.0, 3.6666667, 3.0, - 13.0, 7.0, 5.0, 4.0, 17.0, 9.0, - 6.3333335, 5.0, 4.2, 3.6666667, 3.2857144, 3.0, - 5.0, 4.3333335, 3.857143, 3.5, 5.8, 5.0, - 4.428571, 4.0, 6.6, 5.6666665, 5.0, 4.5, - 7.4, 6.3333335, 5.571429, 5.0, 4.5555553, 4.2, - 3.909091, 3.6666667, 5.0, 4.6, 4.2727275, 4.0, - 5.4444447, 5.0, 4.6363635, 4.3333335, 5.888889, 5.4, - 5.0, 4.6666665, 6.3333335, 5.8, 5.3636365, 5.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.divide_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } -} - -TEST(nntrainer_Tensor, divide_i_broadcast_not_supported_01_n) { - nntrainer::Tensor target(3, 1, 3, 1); - nntrainer::Tensor target2(3, 1, 3, 3); - - EXPECT_EQ(target.divide_i(target2), ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, divide_i_broadcast_not_broadcastable_02_n) { - nntrainer::Tensor target(3, 2, 4, 5); - nntrainer::Tensor target2(3, 2, 3, 1); - - EXPECT_EQ(target.divide_i(target2), ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, add_i_01_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int height = 3; - int width = 10; - int channel = 1; - - nntrainer::Tensor target(batch, channel, height, width); - GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - - nntrainer::Tensor original(batch, channel, height, width); - original.copy(target); - - status = target.add_i(2.1); - EXPECT_EQ(status, ML_ERROR_NONE); - - float *previous = original.getData(); - ASSERT_NE(nullptr, previous); - float *data = target.getData(); - ASSERT_NE(nullptr, data); - - for (int i = 0; i < batch * height * width; ++i) { - EXPECT_FLOAT_EQ(data[i], previous[i] + (float)2.1); - } -} - -TEST(nntrainer_Tensor, add_i_02_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int height = 3; - int width = 10; - int channel = 1; - - nntrainer::Tensor target(batch, channel, height, width); - GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor original(batch, height, width); - original.copy(target); - - status = target.add_i(target, 3.0); - EXPECT_EQ(status, ML_ERROR_NONE); - - float *previous = original.getData(); - ASSERT_NE(nullptr, previous); - float *data = target.getData(); - ASSERT_NE(nullptr, data); - - for (int i = 0; i < batch * height * width; ++i) { - EXPECT_FLOAT_EQ(data[i], previous[i] * 4.0); - } -} - -/** - * @brief operand dimension is not right - */ -TEST(nntrainer_Tensor, add_i_01_n) { - int status = ML_ERROR_NONE; - int batch = 3; - int height = 3; - int width = 10; - int channel = 1; - - nntrainer::Tensor target(batch, channel, height, width); - GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor target2(batch, height - 2, width - 3); - - status = target.add_i(target2); - EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, add_i_broadcast_01_p) { - nntrainer::TensorDim ref_dim{3, 2, 4, 5}; - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 2, 4, 5); - float answer_data[] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, - 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, - 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 40, 42, - 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, - 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, - 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 80, 82, 84, 86, - 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, - 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, - 144, 146, 148, 150, 152, 154, 156, 158}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 4, 5); - float answer_data[] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, - 28, 30, 32, 34, 36, 38, 20, 22, 24, 26, 28, 30, 32, 34, - 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, - 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, - 92, 94, 96, 98, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, - 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, - 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, - 156, 158, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, - 164, 166, 168, 170, 172, 174, 176, 178}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 2, 4, 1); - float answer_data[] = { - 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, - 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 30, 31, 32, - 33, 34, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 48, 49, - 50, 51, 52, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 66, - 67, 68, 69, 70, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, - 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 96, 97, 98, 99, - 100, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 114, 115, 116, - 117, 118, 120, 121, 122, 123, 124, 126, 127, 128, 129, 130, 132, 133, - 134, 135, 136, 138, 139, 140, 141, 142}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 1, 5); - float answer_data[] = { - 0, 2, 4, 6, 8, 5, 7, 9, 11, 13, 10, 12, 14, 16, - 18, 15, 17, 19, 21, 23, 20, 22, 24, 26, 28, 25, 27, 29, - 31, 33, 30, 32, 34, 36, 38, 35, 37, 39, 41, 43, 45, 47, - 49, 51, 53, 50, 52, 54, 56, 58, 55, 57, 59, 61, 63, 60, - 62, 64, 66, 68, 65, 67, 69, 71, 73, 70, 72, 74, 76, 78, - 75, 77, 79, 81, 83, 80, 82, 84, 86, 88, 90, 92, 94, 96, - 98, 95, 97, 99, 101, 103, 100, 102, 104, 106, 108, 105, 107, 109, - 111, 113, 110, 112, 114, 116, 118, 115, 117, 119, 121, 123, 120, 122, - 124, 126, 128, 125, 127, 129, 131, 133}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 2, 1, 5); - float answer_data[] = { - 0, 2, 4, 6, 8, 5, 7, 9, 11, 13, 10, 12, 14, 16, - 18, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 30, 32, 34, - 36, 38, 35, 37, 39, 41, 43, 40, 42, 44, 46, 48, 40, 42, - 44, 46, 48, 45, 47, 49, 51, 53, 50, 52, 54, 56, 58, 55, - 57, 59, 61, 63, 65, 67, 69, 71, 73, 70, 72, 74, 76, 78, - 75, 77, 79, 81, 83, 80, 82, 84, 86, 88, 80, 82, 84, 86, - 88, 85, 87, 89, 91, 93, 90, 92, 94, 96, 98, 95, 97, 99, - 101, 103, 105, 107, 109, 111, 113, 110, 112, 114, 116, 118, 115, 117, - 119, 121, 123, 120, 122, 124, 126, 128}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 4, 1); - float answer_data[] = { - 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, - 16, 18, 19, 20, 21, 22, 20, 21, 22, 23, 24, 26, 27, 28, - 29, 30, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 44, 45, - 46, 47, 48, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 62, - 63, 64, 65, 66, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, - 76, 77, 78, 79, 80, 82, 83, 84, 85, 86, 88, 89, 90, 91, - 92, 94, 95, 96, 97, 98, 100, 101, 102, 103, 104, 106, 107, 108, - 109, 110, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 120, 121, - 122, 123, 124, 126, 127, 128, 129, 130}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 1, 1, 5); - float answer_data[] = { - 0, 2, 4, 6, 8, 5, 7, 9, 11, 13, 10, 12, 14, 16, - 18, 15, 17, 19, 21, 23, 20, 22, 24, 26, 28, 25, 27, 29, - 31, 33, 30, 32, 34, 36, 38, 35, 37, 39, 41, 43, 40, 42, - 44, 46, 48, 45, 47, 49, 51, 53, 50, 52, 54, 56, 58, 55, - 57, 59, 61, 63, 60, 62, 64, 66, 68, 65, 67, 69, 71, 73, - 70, 72, 74, 76, 78, 75, 77, 79, 81, 83, 80, 82, 84, 86, - 88, 85, 87, 89, 91, 93, 90, 92, 94, 96, 98, 95, 97, 99, - 101, 103, 100, 102, 104, 106, 108, 105, 107, 109, 111, 113, 110, 112, - 114, 116, 118, 115, 117, 119, 121, 123}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 2, 1, 1); - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 1, 1, 1); - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(1, 1, 1, 1); - m.add_i(1.0); - float answer_data[] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(3, 5, 1, 4); - nntrainer::Tensor t = ranged(3, 5, 1, 4); - nntrainer::Tensor m = ranged(3, 1, 1, 4); - float answer_data[] = {0, 2, 4, 6, 4, 6, 8, 10, 8, 10, 12, 14, - 12, 14, 16, 18, 16, 18, 20, 22, 24, 26, 28, 30, - 28, 30, 32, 34, 32, 34, 36, 38, 36, 38, 40, 42, - 40, 42, 44, 46, 48, 50, 52, 54, 52, 54, 56, 58, - 56, 58, 60, 62, 60, 62, 64, 66, 64, 66, 68, 70}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(1, 1, 2, 1); - nntrainer::Tensor t = ranged(1, 1, 2, 1); - nntrainer::Tensor m = ranged(1, 1, 2, 1); - float answer_data[] = {0.0, 2.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } - { - nntrainer::TensorDim ref_dim(16, 1, 1, 1); - nntrainer::Tensor t = ranged(16, 1, 1, 1); - nntrainer::Tensor m = ranged(1, 1, 1, 1); - float answer_data[] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, - 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0}; - nntrainer::Tensor answer(ref_dim, answer_data); - int status = t.add_i(m); - EXPECT_EQ(status, ML_ERROR_NONE); - EXPECT_EQ(t, answer); - } -} - -TEST(nntrainer_Tensor, add_i_broadcast_not_supported_01_n) { - nntrainer::Tensor target(3, 1, 3, 1); - nntrainer::Tensor target2(3, 1, 3, 3); - - EXPECT_EQ(target.add_i(target2), ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, add_i_broadcast_not_broadcastable_02_n) { - nntrainer::Tensor target(3, 2, 4, 5); - nntrainer::Tensor target2(3, 2, 3, 1); - - EXPECT_EQ(target.add_i(target2), ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, add_01_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor result = input.add(1.0); - - float *data = result.getData(); - ASSERT_NE(nullptr, data); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width; ++i) { - if (data[i] != indata[i] + (float)1.0) { - status = ML_ERROR_RESULT_OUT_OF_RANGE; - break; - } - } - - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, add_02_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor result = input.add(input); - - float *data = result.getData(); - ASSERT_NE(nullptr, data); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width; ++i) { - if (data[i] != indata[i] + indata[i]) { - status = ML_ERROR_RESULT_OUT_OF_RANGE; - break; - } - } - - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, add_03_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1); - - EXPECT_THROW({ input.add(test); }, std::invalid_argument); -} - -TEST(nntrainer_Tensor, add_04_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(batch, channel, height, 2 * width); - nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); - nntrainer::Tensor test(dim); - - EXPECT_THROW(shared_input.add(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, add_05_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - nntrainer::Tensor test(batch, channel, height, 2 * width); - nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - - EXPECT_THROW(input.add(shared_test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, add_06_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim, false); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - - EXPECT_THROW(input.add(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, add_07_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim, false); - - EXPECT_THROW(input.add(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, add_08_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); - nntrainer::Tensor output(dim, false); - - EXPECT_THROW(input.add(test, output), std::invalid_argument); -} - -TEST(nntrainer_Tensor, pow_01_p) { - - nntrainer::Tensor input = constant(4.0, 3, 2, 4, 5); - - nntrainer::Tensor actual, expected; - - actual = input.pow(0.5f); - expected = constant(2.0, 3, 2, 4, 5); - EXPECT_EQ(actual, expected); - - actual = input.pow(2.0f); - expected = constant(16.0, 3, 2, 4, 5); - EXPECT_EQ(actual, expected); - - actual = input.pow(-0.5f); - expected = constant(0.5, 3, 2, 4, 5); - EXPECT_EQ(actual, expected); -} - -TEST(nntrainer_Tensor, erf_01_p) { - int batch = 1; - int channel = 1; - int height = 2; - int width = 2; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, k + l * 0.5 + 0.5); - nntrainer::Tensor actual = input.erf(); - nntrainer::Tensor expected( - std::vector>>>( - {{{{0.5205, 0.8427}, {0.966105, 0.995322}}}})); - - EXPECT_EQ(actual, expected); -} - -TEST(nntrainer_Tensor, subtract_i_01_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int height = 3; - int width = 10; - int channel = 1; - - nntrainer::Tensor target(batch, channel, height, width); - GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - - nntrainer::Tensor original(batch, height, width); - original.copy(target); - - status = target.subtract_i(2.1); - EXPECT_EQ(status, ML_ERROR_NONE); - - float *previous = original.getData(); - ASSERT_NE(nullptr, previous); - float *data = target.getData(); - ASSERT_NE(nullptr, data); - - for (int i = 0; i < batch * height * width; ++i) { - EXPECT_FLOAT_EQ(data[i], previous[i] - (float)2.1); - } -} - -TEST(nntrainer_Tensor, subtract_i_02_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int height = 3; - int width = 10; - int channel = 1; - - nntrainer::Tensor target(batch, channel, height, width); - GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - - status = target.subtract_i(target); - EXPECT_EQ(status, ML_ERROR_NONE); - - float *data = target.getData(); - ASSERT_NE(nullptr, data); - - for (int i = 0; i < batch * height * width; ++i) { - EXPECT_FLOAT_EQ(data[i], 0); - } -} - -TEST(nntrainer_Tensor, subtract_i_03_n) { - int status = ML_ERROR_NONE; - int batch = 3; - int height = 3; - int width = 10; - int channel = 1; - - nntrainer::Tensor target(batch, channel, height, width); - GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - - nntrainer::Tensor target2(batch, channel, height - 1, width - 3); - - status = target.subtract_i(target2); - EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -} - -TEST(nntrainer_Tensor, subtract_01_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor result = input.subtract(1.0); - - float *data = result.getData(); - ASSERT_NE(nullptr, data); - float *indata = input.getData(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width; ++i) { - if (data[i] != indata[i] - 1.0) { - status = ML_ERROR_RESULT_OUT_OF_RANGE; - break; - } - } - - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, subtract_02_p) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor result = input.subtract(input); - - EXPECT_EQ(constant(0.0, batch, channel, height, width), result); -} - -TEST(nntrainer_Tensor, subtract_03_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1); - - EXPECT_THROW({ input.subtract(test); }, std::invalid_argument); -} - -TEST(nntrainer_Tensor, subtract_04_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(batch, channel, height, 2 * width); - nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); - nntrainer::Tensor test(dim); - - EXPECT_THROW(shared_input.subtract(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, subtract_05_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - nntrainer::Tensor test(batch, channel, height, 2 * width); - nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - - EXPECT_THROW(input.subtract(shared_test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, subtract_06_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim, false); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - - EXPECT_THROW(input.subtract(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, subtract_07_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim, false); - - EXPECT_THROW(input.subtract(test), std::invalid_argument); -} - -TEST(nntrainer_Tensor, subtract_08_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::TensorDim dim(batch, channel, height, width); - - nntrainer::Tensor input(dim); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - nntrainer::Tensor test(dim); - GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); - nntrainer::Tensor output(dim, false); - - EXPECT_THROW(input.subtract(test, output), std::invalid_argument); -} - -TEST(nntrainer_Tensor, subtract_float_01_p) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - - nntrainer::Tensor expected(batch, channel, height, width); - GEN_TEST_INPUT(expected, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor result = input.subtract(1.0); - - EXPECT_EQ(result, expected); -} - -TEST(nntrainer_Tensor, sum_01_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - EXPECT_THROW({ input.sum(4); }, std::out_of_range); -} - -TEST(nntrainer_Tensor, sum_02_n) { - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - EXPECT_THROW({ input.sum(-1); }, std::out_of_range); -} - -TEST(nntrainer_Tensor, sum_02_p) { - int batch = 3; - int channel = 2; - int height = 2; - int width = 10; - - nntrainer::Tensor ans0( - std::vector>>>( - {{{{39, 42, 45, 48, 51, 54, 57, 60, 63, 66}, - {69, 72, 75, 78, 81, 84, 87, 90, 93, 96}}, - {{57, 60, 63, 66, 69, 72, 75, 78, 81, 84}, - {87, 90, 93, 96, 99, 102, 105, 108, 111, 114}}}})); - - nntrainer::Tensor ans1( - std::vector>>>( - {{{{8, 10, 12, 14, 16, 18, 20, 22, 24, 26}, - {28, 30, 32, 34, 36, 38, 40, 42, 44, 46}}}, - {{{32, 34, 36, 38, 40, 42, 44, 46, 48, 50}, - {52, 54, 56, 58, 60, 62, 64, 66, 68, 70}}}, - {{{56, 58, 60, 62, 64, 66, 68, 70, 72, 74}, - {76, 78, 80, 82, 84, 86, 88, 90, 92, 94}}}})); - - nntrainer::Tensor ans2( - std::vector>>>( - {{{{12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}, - {{24, 26, 28, 30, 32, 34, 36, 38, 40, 42}}}, - {{{36, 38, 40, 42, 44, 46, 48, 50, 52, 54}}, - {{48, 50, 52, 54, 56, 58, 60, 62, 64, 66}}}, - {{{60, 62, 64, 66, 68, 70, 72, 74, 76, 78}}, - {{72, 74, 76, 78, 80, 82, 84, 86, 88, 90}}}})); - - nntrainer::Tensor ans3( - std::vector>>>( - {{{{55}, {155}}, {{115}, {215}}}, - {{{175}, {275}}, {{235}, {335}}}, - {{{295}, {395}}, {{355}, {455}}}})); - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height * channel) + j * (batch * height) + - k * (width) + l + 1); - - nntrainer::Tensor result0 = input.sum(0); - nntrainer::Tensor result1 = input.sum(1); - nntrainer::Tensor result2 = input.sum(2); - nntrainer::Tensor result3 = input.sum(3); - - EXPECT_EQ(ans0, result0); - EXPECT_EQ(ans1, result1); - EXPECT_EQ(ans2, result2); - EXPECT_EQ(ans3, result3); -} - -TEST(nntrainer_Tensor, sum_03_p) { - const int batch = 3; - const int channel = 2; - const int height = 1; - const int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (height * channel * width) + j * (height * width) + - k * (width) + l + 1); - // Test for alpha == 1 and beta == 0 and dimension of reduced axis == 1 - { - nntrainer::Tensor ans_0_1_0( - std::vector>>>( - {{{{63, 66, 69, 72, 75, 78, 81, 84, 87, 90}}, - {{93, 96, 99, 102, 105, 108, 111, 114, 117, 120}}}})); - - nntrainer::Tensor ans_1_1_0( - std::vector>>>( - {{{{12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}}, - {{{52, 54, 56, 58, 60, 62, 64, 66, 68, 70}}}, - {{{92, 94, 96, 98, 100, 102, 104, 106, 108, 110}}}})); - - nntrainer::Tensor ans_2_1_0( - std::vector>>>( - {{{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, - {{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}}}, - {{{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}}, - {{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}}}, - {{{41, 42, 43, 44, 45, 46, 47, 48, 49, 50}}, - {{51, 52, 53, 54, 55, 56, 57, 58, 59, 60}}}})); - - nntrainer::Tensor ans_3_1_0( - std::vector>>>( - {{{{55}}, {{155}}}, {{{255}}, {{355}}}, {{{455}}, {{555}}}})); - - nntrainer::Tensor result_0_1_0 = input.sum(0, 1); - nntrainer::Tensor result_1_1_0 = input.sum(1, 1); - nntrainer::Tensor result_2_1_0 = input.sum(2, 1); - nntrainer::Tensor result_3_1_0 = input.sum(3, 1); - - EXPECT_EQ(ans_0_1_0, result_0_1_0); - EXPECT_EQ(ans_1_1_0, result_1_1_0); - EXPECT_EQ(ans_2_1_0, result_2_1_0); - EXPECT_EQ(ans_3_1_0, result_3_1_0); - } - - // Test for alpha == 1 and beta == 2 and dimension of reduced axis == 1 - { - nntrainer::Tensor ans_0_1_2( - std::vector>>>( - {{{{65, 70, 75, 80, 85, 90, 95, 100, 105, 110}}, - {{115, 120, 125, 130, 135, 140, 145, 150, 155, 160}}}})); - - nntrainer::Tensor ans_1_1_2( - std::vector>>>( - {{{{14, 18, 22, 26, 30, 34, 38, 42, 46, 50}}}, - {{{74, 78, 82, 86, 90, 94, 98, 102, 106, 110}}}, - {{{134, 138, 142, 146, 150, 154, 158, 162, 166, 170}}}})); - - nntrainer::Tensor ans_2_1_2( - std::vector>>>( - {{{{3, 6, 9, 12, 15, 18, 21, 24, 27, 30}}, - {{33, 36, 39, 42, 45, 48, 51, 54, 57, 60}}}, - {{{63, 66, 69, 72, 75, 78, 81, 84, 87, 90}}, - {{93, 96, 99, 102, 105, 108, 111, 114, 117, 120}}}, - {{{123, 126, 129, 132, 135, 138, 141, 144, 147, 150}}, - {{153, 156, 159, 162, 165, 168, 171, 174, 177, 180}}}})); - - nntrainer::Tensor ans_3_1_2( - std::vector>>>( - {{{{57}}, {{159}}}, {{{261}}, {{363}}}, {{{465}}, {{567}}}})); - - nntrainer::Tensor output_0_1_2(1, channel, height, width); - { - const int batch = 1; - GEN_TEST_INPUT(output_0_1_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor output_1_1_2(batch, 1, height, width); - { - const int channel = 1; - GEN_TEST_INPUT(output_1_1_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor output_2_1_2(batch, channel, 1, width); - { - const int height = 1; - GEN_TEST_INPUT(output_2_1_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor output_3_1_2(batch, channel, height, 1); - { - const int width = 1; - GEN_TEST_INPUT(output_3_1_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor result_0_1_2 = input.sum(0, output_0_1_2, 1, 2); - nntrainer::Tensor result_1_1_2 = input.sum(1, output_1_1_2, 1, 2); - nntrainer::Tensor result_2_1_2 = input.sum(2, output_2_1_2, 1, 2); - nntrainer::Tensor result_3_1_2 = input.sum(3, output_3_1_2, 1, 2); - - EXPECT_EQ(ans_0_1_2, result_0_1_2); - EXPECT_EQ(ans_1_1_2, result_1_1_2); - EXPECT_EQ(ans_2_1_2, result_2_1_2); - EXPECT_EQ(ans_3_1_2, result_3_1_2); - } - - // Test for alpha == 2 and beta == 0 - { - nntrainer::Tensor ans_0_2_0( - std::vector>>>( - {{{{126, 132, 138, 144, 150, 156, 162, 168, 174, 180}}, - {{186, 192, 198, 204, 210, 216, 222, 228, 234, 240}}}})); - - nntrainer::Tensor ans_1_2_0( - std::vector>>>( - {{{{24, 28, 32, 36, 40, 44, 48, 52, 56, 60}}}, - {{{104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, - {{{184, 188, 192, 196, 200, 204, 208, 212, 216, 220}}}})); - - nntrainer::Tensor ans_2_2_0( - std::vector>>>( - {{{{2, 4, 6, 8, 10, 12, 14, 16, 18, 20}}, - {{22, 24, 26, 28, 30, 32, 34, 36, 38, 40}}}, - {{{42, 44, 46, 48, 50, 52, 54, 56, 58, 60}}, - {{62, 64, 66, 68, 70, 72, 74, 76, 78, 80}}}, - {{{82, 84, 86, 88, 90, 92, 94, 96, 98, 100}}, - {{102, 104, 106, 108, 110, 112, 114, 116, 118, 120}}}})); - - nntrainer::Tensor ans_3_2_0( - std::vector>>>( - {{{{110}}, {{310}}}, {{{510}}, {{710}}}, {{{910}}, {{1110}}}})); - - nntrainer::Tensor result_0_2_0 = input.sum(0, 2); - nntrainer::Tensor result_1_2_0 = input.sum(1, 2); - nntrainer::Tensor result_2_2_0 = input.sum(2, 2); - nntrainer::Tensor result_3_2_0 = input.sum(3, 2); - - EXPECT_EQ(ans_0_2_0, result_0_2_0); - EXPECT_EQ(ans_1_2_0, result_1_2_0); - EXPECT_EQ(ans_2_2_0, result_2_2_0); - EXPECT_EQ(ans_3_2_0, result_3_2_0); - } - - // Test for alpha == 2 and beta == 2 - { - nntrainer::Tensor ans_0_2_2( - std::vector>>>( - {{{{128, 136, 144, 152, 160, 168, 176, 184, 192, 200}}, - {{208, 216, 224, 232, 240, 248, 256, 264, 272, 280}}}})); - - nntrainer::Tensor ans_1_2_2( - std::vector>>>( - {{{{26, 32, 38, 44, 50, 56, 62, 68, 74, 80}}}, - {{{126, 132, 138, 144, 150, 156, 162, 168, 174, 180}}}, - {{{226, 232, 238, 244, 250, 256, 262, 268, 274, 280}}}})); - - nntrainer::Tensor ans_2_2_2( - std::vector>>>( - {{{{4, 8, 12, 16, 20, 24, 28, 32, 36, 40}}, - {{44, 48, 52, 56, 60, 64, 68, 72, 76, 80}}}, - {{{84, 88, 92, 96, 100, 104, 108, 112, 116, 120}}, - {{124, 128, 132, 136, 140, 144, 148, 152, 156, 160}}}, - {{{164, 168, 172, 176, 180, 184, 188, 192, 196, 200}}, - {{204, 208, 212, 216, 220, 224, 228, 232, 236, 240}}}})); - - nntrainer::Tensor ans_3_2_2( - std::vector>>>( - {{{{112}}, {{314}}}, {{{516}}, {{718}}}, {{{920}}, {{1122}}}})); - - nntrainer::Tensor output_0_2_2(1, channel, height, width); - { - const int batch = 1; - GEN_TEST_INPUT(output_0_2_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor output_1_2_2(batch, 1, height, width); - { - const int channel = 1; - GEN_TEST_INPUT(output_1_2_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor output_2_2_2(batch, channel, 1, width); - { - const int height = 1; - GEN_TEST_INPUT(output_2_2_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor output_3_2_2(batch, channel, height, 1); - { - const int width = 1; - GEN_TEST_INPUT(output_3_2_2, i * (channel * height * width) + - j * (height * width) + k * (width) + l + - 1); - } - nntrainer::Tensor result_0_2_2 = input.sum(0, output_0_2_2, 2, 2); - nntrainer::Tensor result_1_2_2 = input.sum(1, output_1_2_2, 2, 2); - nntrainer::Tensor result_2_2_2 = input.sum(2, output_2_2_2, 2, 2); - nntrainer::Tensor result_3_2_2 = input.sum(3, output_3_2_2, 2, 2); - - EXPECT_EQ(ans_0_2_2, result_0_2_2); - EXPECT_EQ(ans_1_2_2, result_1_2_2); - EXPECT_EQ(ans_2_2_2, result_2_2_2); - EXPECT_EQ(ans_3_2_2, result_3_2_2); - } -} - -TEST(nntrainer_Tensor, sum_04_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 2; - int height = 2; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (batch * height * channel) + j * (height * width) + - k * width + l + 1); - - nntrainer::Tensor result = input.sum_by_batch(); - if (result.getValue(0, 0, 0, 0) != 820 || - result.getValue(1, 0, 0, 0) != 1300 || - result.getValue(2, 0, 0, 0) != 1780) - status = ML_ERROR_RESULT_OUT_OF_RANGE; - - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, multiple_sum_invalid_args_01_n) { - nntrainer::Tensor t = constant(1.0, 1, 1, 1, 1); - EXPECT_THROW(t.sum(std::vector()), std::invalid_argument); -} - -TEST(nntrainer_Tensor, multiple_sum_out_of_range_n) { - nntrainer::Tensor t = constant(1.0, 1, 1, 1, 1); - EXPECT_THROW(t.sum({7}), std::out_of_range); -} - -TEST(nntrainer_Tensor, multiple_sum_p) { - nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); - nntrainer::Tensor actual, expected; - - actual = t.sum({0, 1}); - expected = constant(2 * 3, 1, 1, 5, 7); - EXPECT_EQ(actual, expected); - - actual = t.sum({1, 2, 3}); - expected = constant(3 * 5 * 7, 2, 1, 1, 1); - EXPECT_EQ(actual, expected); - - actual = t.sum({3, 1}); - expected = constant(7 * 3, 2, 1, 5, 1); - EXPECT_EQ(actual, expected); - - actual = t.sum({3, 1}, 0.5); - expected = constant(7 * 3 * 0.5, 2, 1, 5, 1); - EXPECT_EQ(actual, expected); -} - -TEST(nntrainer_Tensor, average_p) { - nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); - - nntrainer::Tensor actual, expected; - - actual = t.average(); - expected = constant(1.0, 1, 1, 1, 1); - EXPECT_EQ(actual, expected); - - int idx = 0; - t = t.apply([&](float in) { return idx++ % 2; }); - - actual = t.average(); - expected = constant(0.5, 1, 1, 1, 1); - EXPECT_EQ(actual, expected); -} - -TEST(nntrainer_Tensor, average_axis_p) { - nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2); - int idx = 0; - std::function f = [&](float in) { return idx++ % 2; }; - t = t.apply(f); - - nntrainer::Tensor actual, expected; - - actual = t.average(0); - expected = constant(0, 1, 2, 2, 2).apply(f); - EXPECT_EQ(actual, expected); - - actual = t.average(1); - expected = constant(0, 2, 1, 2, 2).apply(f); - EXPECT_EQ(actual, expected); - - actual = t.average(2); - expected = constant(0, 2, 2, 1, 2).apply(f); - EXPECT_EQ(actual, expected); - - actual = t.average(3); - expected = constant(0.5, 2, 2, 2, 1); - EXPECT_EQ(actual, expected); -} - -TEST(nntrainer_Tensor, average_axis_out_of_range_01_n) { - nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2); - EXPECT_THROW(t.average(-1), std::out_of_range); -} - -TEST(nntrainer_Tensor, average_axis_out_of_range_02_n) { - nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2); - EXPECT_THROW(t.average(7), std::out_of_range); -} - -TEST(nntrainer_Tensor, average_multiple_axes_p) { - nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); - nntrainer::Tensor actual, expected; - - actual = t.average({0, 1, 2}); - expected = constant(1.0, 1, 1, 1, 7); - EXPECT_EQ(actual, expected); - - actual = t.average({0, 1, 2, 3}); - expected = constant(1.0, 1, 1, 1, 1); - EXPECT_EQ(actual, expected); - - actual = t.average({3, 1}); - expected = constant(1.0, 2, 1, 5, 1); - EXPECT_EQ(actual, expected); - - actual = t.average({3, 1, 1, 1, 3}); - expected = constant(1.0, 2, 1, 5, 1); - EXPECT_EQ(actual, expected); -} - -TEST(nntrainer_Tensor, average_multiple_axes_01_n) { - nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); - EXPECT_THROW(t.average({5, 7}), std::out_of_range); -} - -TEST(nntrainer_Tensor, dot_01_n) { - nntrainer::Tensor input(2, 3, 4, 5); - nntrainer::Tensor m(1, 3, 4, 5); - EXPECT_THROW(nntrainer::Tensor result = input.dot(m), std::runtime_error); -} - -TEST(nntrainer_Tensor, dot_02_n) { - nntrainer::Tensor input(2, 3, 4, 5); - nntrainer::Tensor m(1, 3, 4, 5); - EXPECT_THROW(nntrainer::Tensor result = input.dot(m, true), - std::runtime_error); -} - -TEST(nntrainer_Tensor, dot_02_p) { - nntrainer::Tensor input(2, 3, 4, 5); - nntrainer::Tensor m(1, 3, 4, 5); - EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, false, true)); -} - -TEST(nntrainer_Tensor, dot_03_p) { - nntrainer::Tensor input(1, 3, 4, 5); - nntrainer::Tensor m(1, 3, 4, 5); - EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, true)); -} - -TEST(nntrainer_Tensor, dot_04_n) { - nntrainer::Tensor input(2, 3, 4, 5); - nntrainer::Tensor m(1, 1, 4, 5); - EXPECT_THROW(nntrainer::Tensor result = input.dot(m), std::runtime_error); - EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, false, true)); -} - -TEST(nntrainer_Tensor, dot_05_p) { - int status = ML_ERROR_NONE; - int batch = 2; - int channel = 3; - int height = 4; - int width = 5; - float ans[2][3][4][24] = {0}; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (channel * width * height) + j * (height * width) + - k * (width) + l + 1); - nntrainer::Tensor weight(batch, channel, height, width); - GEN_TEST_INPUT(weight, i * (channel * width * height) + j * (height * width) + - k * (width) + l + 1); - weight.reshape({1, 1, 24, 5}); - - nntrainer::Tensor result = input.dot(weight, false, true); - - for (int b = 0; b < batch; b++) { - for (int c = 0; c < channel; c++) { - for (int h = 0; h < height; h++) { - for (int k = 0; k < batch * channel * height; k++) { - ans[b][c][h][k] = 0; - for (int w = 0; w < width; w++) { - float val1 = input.getValue(b, c, h, w); - float val2 = weight.getValue(0, 0, k, w); - ans[b][c][h][k] += val1 * val2; - } - } - } - } - } - - for (unsigned int i = 0; i < result.batch(); ++i) { - for (unsigned int c = 0; c < result.channel(); ++c) { - for (unsigned int j = 0; j < result.height(); ++j) { - for (unsigned int k = 0; k < result.width(); ++k) { - float val1 = ans[i][c][j][k]; - float val2 = result.getValue(i, c, j, k); - if (val1 != val2) { - status = ML_ERROR_RESULT_OUT_OF_RANGE; - goto end_dot_01_p; - } - } - } - } - } -end_dot_01_p: - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, dot_06_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 1; - int width = 3; - float ans[3][1][1][3] = { - {{{30, 36, 42}}}, {{{66, 81, 96}}}, {{{102, 126, 150}}}}; - - nntrainer::Tensor input(batch, channel, height, width); - GEN_TEST_INPUT(input, i * (channel * width * height) + j * (height * width) + - k * (width) + l + 1); - - nntrainer::Tensor result = input.dot(input); - - for (unsigned int i = 0; i < result.batch(); ++i) { - for (unsigned int j = 0; j < result.height(); ++j) { - for (unsigned int k = 0; k < result.width(); ++k) { - if (ans[i][0][j][k] != result.getValue(i, 0, j, k)) { - status = ML_ERROR_RESULT_OUT_OF_RANGE; - goto end_dot_01_p; - } - } - } - } -end_dot_01_p: - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, dot_transpose_p) { - { - float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, - 92, 113, 134, 155, 128, 158, 188, 218}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, - 92, 113, 134, 155, 128, 158, 188, 218}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, - 92, 113, 134, 155, 128, 158, 188, 218}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, - 92, 113, 134, 155, 128, 158, 188, 218}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 1, 4, 2, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 1, 4, 2, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); - float b_data[] = {0, 2, 4, 1, 3, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); - float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); - float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); - float b_data[] = {0, 2, 4, 1, 3, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); - float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); - float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 1, 4, 2, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); - float b_data[] = {0, 2, 4, 1, 3, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); - float answer_data[] = {10, 13, 28, 40}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 1, 4, 2, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); - float answer_data[] = {10, 13, 28, 40}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); - float b_data[] = {0, 2, 4, 1, 3, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); - float answer_data[] = {10, 13, 28, 40}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); - float answer_data[] = {10, 13, 28, 40}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } -} - -TEST(nntrainer_Tensor, dot_shortcuts_p) { - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); - float answer_data[] = {5}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); - float answer_data[] = {5}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); - float answer_data[] = {5}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); - float answer_data[] = {5}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); - float answer_data[] = {5, 14}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 1, 4, 2, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); - float answer_data[] = {5, 14}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); - float answer_data[] = {5, 14}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 1, 4, 2, 5}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); - float answer_data[] = {5, 14}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); - float answer_data[] = {5, 14, 23, 32}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); - float answer_data[] = {5, 14, 23, 32}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); - float answer_data[] = {5, 14, 23, 32}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); - float b_data[] = {0, 1, 2}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); - float answer_data[] = {5, 14, 23, 32}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); - float answer_data[] = {20, 23, 26, 29}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); - float answer_data[] = {10, 13}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, false, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 1, 2, 3, 4, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); - float answer_data[] = {10, 13}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, true, false); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); - float b_data[] = {0, 2, 4, 1, 3, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); - float answer_data[] = {10, 13}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, false, true); - EXPECT_EQ(ret, answer); - } - { - float a_data[] = {0, 1, 2}; - nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); - float b_data[] = {0, 2, 4, 1, 3, 5}; - nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); - float answer_data[] = {10, 13}; - nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); - nntrainer::Tensor ret = a.dot(b, true, true); - EXPECT_EQ(ret, answer); - } -} - -TEST(nntrainer_Tensor, transpose_p) { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - - /// plain transpose - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119}; - nntrainer::Tensor answer({3, 2, 4, 5}, answer_data); - nntrainer::Tensor m = t.transpose("0:1:2"); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - float answer_data[] = { - 0, 5, 10, 15, 1, 6, 11, 16, 2, 7, 12, 17, 3, 8, - 13, 18, 4, 9, 14, 19, 20, 25, 30, 35, 21, 26, 31, 36, - 22, 27, 32, 37, 23, 28, 33, 38, 24, 29, 34, 39, 40, 45, - 50, 55, 41, 46, 51, 56, 42, 47, 52, 57, 43, 48, 53, 58, - 44, 49, 54, 59, 60, 65, 70, 75, 61, 66, 71, 76, 62, 67, - 72, 77, 63, 68, 73, 78, 64, 69, 74, 79, 80, 85, 90, 95, - 81, 86, 91, 96, 82, 87, 92, 97, 83, 88, 93, 98, 84, 89, - 94, 99, 100, 105, 110, 115, 101, 106, 111, 116, 102, 107, 112, 117, - 103, 108, 113, 118, 104, 109, 114, 119}; - nntrainer::Tensor answer({3, 2, 5, 4}, answer_data); - nntrainer::Tensor m = t.transpose("0:2:1"); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - float answer_data[] = { - 0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 5, 6, 7, 8, - 9, 25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 30, 31, 32, - 33, 34, 15, 16, 17, 18, 19, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 60, 61, 62, 63, 64, 45, 46, 47, 48, 49, 65, - 66, 67, 68, 69, 50, 51, 52, 53, 54, 70, 71, 72, 73, 74, - 55, 56, 57, 58, 59, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 100, 101, 102, 103, 104, 85, 86, 87, 88, 89, 105, 106, 107, - 108, 109, 90, 91, 92, 93, 94, 110, 111, 112, 113, 114, 95, 96, - 97, 98, 99, 115, 116, 117, 118, 119}; - nntrainer::Tensor answer({3, 4, 2, 5}, answer_data); - nntrainer::Tensor m = t.transpose("1:0:2"); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - float answer_data[] = { - 0, 20, 1, 21, 2, 22, 3, 23, 4, 24, 5, 25, 6, 26, 7, 27, - 8, 28, 9, 29, 10, 30, 11, 31, 12, 32, 13, 33, 14, 34, 15, 35, - 16, 36, 17, 37, 18, 38, 19, 39, 40, 60, 41, 61, 42, 62, 43, 63, - 44, 64, 45, 65, 46, 66, 47, 67, 48, 68, 49, 69, 50, 70, 51, 71, - 52, 72, 53, 73, 54, 74, 55, 75, 56, 76, 57, 77, 58, 78, 59, 79, - 80, 100, 81, 101, 82, 102, 83, 103, 84, 104, 85, 105, 86, 106, 87, 107, - 88, 108, 89, 109, 90, 110, 91, 111, 92, 112, 93, 113, 94, 114, 95, 115, - 96, 116, 97, 117, 98, 118, 99, 119}; - nntrainer::Tensor answer({3, 4, 5, 2}, answer_data); - nntrainer::Tensor m = t.transpose("1:2:0"); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - float answer_data[] = { - 0, 5, 10, 15, 20, 25, 30, 35, 1, 6, 11, 16, 21, 26, 31, - 36, 2, 7, 12, 17, 22, 27, 32, 37, 3, 8, 13, 18, 23, 28, - 33, 38, 4, 9, 14, 19, 24, 29, 34, 39, 40, 45, 50, 55, 60, - 65, 70, 75, 41, 46, 51, 56, 61, 66, 71, 76, 42, 47, 52, 57, - 62, 67, 72, 77, 43, 48, 53, 58, 63, 68, 73, 78, 44, 49, 54, - 59, 64, 69, 74, 79, 80, 85, 90, 95, 100, 105, 110, 115, 81, 86, - 91, 96, 101, 106, 111, 116, 82, 87, 92, 97, 102, 107, 112, 117, 83, - 88, 93, 98, 103, 108, 113, 118, 84, 89, 94, 99, 104, 109, 114, 119}; - nntrainer::Tensor answer({3, 5, 2, 4}, answer_data); - nntrainer::Tensor m = t.transpose("2:0:1"); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - float answer_data[] = { - 0, 20, 5, 25, 10, 30, 15, 35, 1, 21, 6, 26, 11, 31, 16, 36, - 2, 22, 7, 27, 12, 32, 17, 37, 3, 23, 8, 28, 13, 33, 18, 38, - 4, 24, 9, 29, 14, 34, 19, 39, 40, 60, 45, 65, 50, 70, 55, 75, - 41, 61, 46, 66, 51, 71, 56, 76, 42, 62, 47, 67, 52, 72, 57, 77, - 43, 63, 48, 68, 53, 73, 58, 78, 44, 64, 49, 69, 54, 74, 59, 79, - 80, 100, 85, 105, 90, 110, 95, 115, 81, 101, 86, 106, 91, 111, 96, 116, - 82, 102, 87, 107, 92, 112, 97, 117, 83, 103, 88, 108, 93, 113, 98, 118, - 84, 104, 89, 109, 94, 114, 99, 119}; - nntrainer::Tensor answer({3, 5, 4, 2}, answer_data); - nntrainer::Tensor m = t.transpose("2:1:0"); - EXPECT_EQ(answer, m); - } - - /// outplace transpose - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 2, 4, 5); - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119}; - nntrainer::Tensor answer({3, 2, 4, 5}, answer_data); - t.transpose("0:1:2", m); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 2, 5, 4); - float answer_data[] = { - 0, 5, 10, 15, 1, 6, 11, 16, 2, 7, 12, 17, 3, 8, - 13, 18, 4, 9, 14, 19, 20, 25, 30, 35, 21, 26, 31, 36, - 22, 27, 32, 37, 23, 28, 33, 38, 24, 29, 34, 39, 40, 45, - 50, 55, 41, 46, 51, 56, 42, 47, 52, 57, 43, 48, 53, 58, - 44, 49, 54, 59, 60, 65, 70, 75, 61, 66, 71, 76, 62, 67, - 72, 77, 63, 68, 73, 78, 64, 69, 74, 79, 80, 85, 90, 95, - 81, 86, 91, 96, 82, 87, 92, 97, 83, 88, 93, 98, 84, 89, - 94, 99, 100, 105, 110, 115, 101, 106, 111, 116, 102, 107, 112, 117, - 103, 108, 113, 118, 104, 109, 114, 119}; - nntrainer::Tensor answer({3, 2, 5, 4}, answer_data); - t.transpose("0:2:1", m); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 4, 2, 5); - float answer_data[] = { - 0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 5, 6, 7, 8, - 9, 25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 30, 31, 32, - 33, 34, 15, 16, 17, 18, 19, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 60, 61, 62, 63, 64, 45, 46, 47, 48, 49, 65, - 66, 67, 68, 69, 50, 51, 52, 53, 54, 70, 71, 72, 73, 74, - 55, 56, 57, 58, 59, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 100, 101, 102, 103, 104, 85, 86, 87, 88, 89, 105, 106, 107, - 108, 109, 90, 91, 92, 93, 94, 110, 111, 112, 113, 114, 95, 96, - 97, 98, 99, 115, 116, 117, 118, 119}; - nntrainer::Tensor answer({3, 4, 2, 5}, answer_data); - t.transpose("1:0:2", m); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 4, 5, 2); - float answer_data[] = { - 0, 20, 1, 21, 2, 22, 3, 23, 4, 24, 5, 25, 6, 26, 7, 27, - 8, 28, 9, 29, 10, 30, 11, 31, 12, 32, 13, 33, 14, 34, 15, 35, - 16, 36, 17, 37, 18, 38, 19, 39, 40, 60, 41, 61, 42, 62, 43, 63, - 44, 64, 45, 65, 46, 66, 47, 67, 48, 68, 49, 69, 50, 70, 51, 71, - 52, 72, 53, 73, 54, 74, 55, 75, 56, 76, 57, 77, 58, 78, 59, 79, - 80, 100, 81, 101, 82, 102, 83, 103, 84, 104, 85, 105, 86, 106, 87, 107, - 88, 108, 89, 109, 90, 110, 91, 111, 92, 112, 93, 113, 94, 114, 95, 115, - 96, 116, 97, 117, 98, 118, 99, 119}; - nntrainer::Tensor answer({3, 4, 5, 2}, answer_data); - t.transpose("1:2:0", m); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 5, 2, 4); - float answer_data[] = { - 0, 5, 10, 15, 20, 25, 30, 35, 1, 6, 11, 16, 21, 26, 31, - 36, 2, 7, 12, 17, 22, 27, 32, 37, 3, 8, 13, 18, 23, 28, - 33, 38, 4, 9, 14, 19, 24, 29, 34, 39, 40, 45, 50, 55, 60, - 65, 70, 75, 41, 46, 51, 56, 61, 66, 71, 76, 42, 47, 52, 57, - 62, 67, 72, 77, 43, 48, 53, 58, 63, 68, 73, 78, 44, 49, 54, - 59, 64, 69, 74, 79, 80, 85, 90, 95, 100, 105, 110, 115, 81, 86, - 91, 96, 101, 106, 111, 116, 82, 87, 92, 97, 102, 107, 112, 117, 83, - 88, 93, 98, 103, 108, 113, 118, 84, 89, 94, 99, 104, 109, 114, 119}; - nntrainer::Tensor answer({3, 5, 2, 4}, answer_data); - t.transpose("2:0:1", m); - EXPECT_EQ(answer, m); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - nntrainer::Tensor m = ranged(3, 5, 4, 2); - float answer_data[] = { - 0, 20, 5, 25, 10, 30, 15, 35, 1, 21, 6, 26, 11, 31, 16, 36, - 2, 22, 7, 27, 12, 32, 17, 37, 3, 23, 8, 28, 13, 33, 18, 38, - 4, 24, 9, 29, 14, 34, 19, 39, 40, 60, 45, 65, 50, 70, 55, 75, - 41, 61, 46, 66, 51, 71, 56, 76, 42, 62, 47, 67, 52, 72, 57, 77, - 43, 63, 48, 68, 53, 73, 58, 78, 44, 64, 49, 69, 54, 74, 59, 79, - 80, 100, 85, 105, 90, 110, 95, 115, 81, 101, 86, 106, 91, 111, 96, 116, - 82, 102, 87, 107, 92, 112, 97, 117, 83, 103, 88, 108, 93, 113, 98, 118, - 84, 104, 89, 109, 94, 114, 99, 119}; - nntrainer::Tensor answer({3, 5, 4, 2}, answer_data); - t.transpose("2:1:0", m); - EXPECT_EQ(answer, m); - } -} - -TEST(nntrainer_Tensor, tranpose_dimension_not_match_n) { - nntrainer::Tensor a(3, 2, 4, 5); - nntrainer::Tensor b(3, 1, 2, 3); - - EXPECT_THROW(a.transpose("0:1:2", b), std::invalid_argument); -} - -TEST(nntrainer_Tensor, set_01_p) { - nntrainer::Tensor tensor = nntrainer::Tensor(1, 1, 1, 1); - - tensor.setZero(); - EXPECT_EQ(tensor.getValue(0, 0, 0, 0), 0.0); - - tensor.setRandUniform(-0.5, 0); - float val = tensor.getValue(0, 0, 0, 0); - EXPECT_TRUE(val >= -0.5 && val < 0); -} - -TEST(nntrainer_Tensor, save_read_01_p) { - int batch = 3; - int channel = 4; - int height = 5; - int width = 6; - nntrainer::Tensor target(3, 4, 5, 6); - nntrainer::Tensor readed(3, 4, 5, 6); - - GEN_TEST_INPUT(target, i * (channel * width * height) + j * (height * width) + - k * (width) + l + 1); - - std::ofstream save_file("save.bin", std::ios::out | std::ios::binary); - target.save(save_file); - save_file.close(); - - std::ifstream read_file("save.bin"); - readed.read(read_file); - read_file.close(); - - EXPECT_EQ(target, readed); - - int status = std::remove("save.bin"); - - ASSERT_EQ(status, 0); -} - -TEST(nntrainer_Tensor, save_read_01_n) { - int batch = 3; - int channel = 4; - int height = 5; - int width = 6; - nntrainer::Tensor target(3, 4, 5, 6); - nntrainer::Tensor readed(3, 4, 1, 1); - - GEN_TEST_INPUT(target, i * (channel * width * height) + j * (height * width) + - k * (width) + l + 1); - - std::ofstream save_file("save.bin", std::ios::out | std::ios::binary); - target.save(save_file); - save_file.close(); - - std::ifstream read_file("save.bin"); - readed.read(read_file); - read_file.close(); - - EXPECT_NE(target, readed); - - int status = std::remove("save.bin"); - - ASSERT_EQ(status, 0); -} - -TEST(nntrainer_Tensor, copy_and_shares_variable_p) { - nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); - nntrainer::Tensor B = A.clone(); - nntrainer::Tensor C = A; - - C.setValue(1, 1, 1, 1, 2.0f); - - EXPECT_EQ(A, C); - EXPECT_NE(B, C); - - C.reshape(nntrainer::TensorDim(3, 4, 6, 5)); - EXPECT_EQ(A.getDim(), B.getDim()); - EXPECT_NE(A.getDim(), C.getDim()); -} - -TEST(nntrainer_Tensor, reshape_n_01) { - nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); - - EXPECT_THROW(A.reshape(nntrainer::TensorDim(9, 9, 9, 9)), - std::invalid_argument); -} - -TEST(nntrainer_Tensor, reshape_n_02) { - nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); - nntrainer::TensorDim A_dim = A.getDim(); - - /** Changing the dim of a tensor only affects local copy of the dim */ - A_dim.setTensorDim(1, 100); - EXPECT_EQ(A_dim.getTensorDim(1), 100u); - - nntrainer::TensorDim A_dim_2 = A.getDim(); - EXPECT_EQ(A_dim_2.getTensorDim(1), 4u); -} - -TEST(nntrainer_Tensor, copy_and_reshape_n) { - nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); - nntrainer::Tensor B = A; - nntrainer::Tensor C = A.clone(); - - EXPECT_THROW(B.reshape(nntrainer::TensorDim(9, 9, 9, 9)), - std::invalid_argument); -} - -/// @note this test case demonstrates it is dangerous to use sharedConstTensor -/// to const correct the inner data. -TEST(nntrainer_Tensor, constructor_from_shared_const_ptr_shares_variable_n) { - nntrainer::sharedConstTensor A = - MAKE_SHARED_TENSOR(constant(1.0f, 3, 4, 5, 6)); - - nntrainer::Tensor B = *A; - nntrainer::Tensor C = A->clone(); - - B.setValue(2, 3, 4, 5, 2.0f); - EXPECT_EQ(*A, B); - EXPECT_NE(*A, C); - - C.reshape(nntrainer::TensorDim(3, 4, 6, 5)); - EXPECT_EQ(A->getDim(), B.getDim()); - EXPECT_NE(A->getDim(), C.getDim()); -} - -TEST(nntrainer_Tensor, print_small_size) { - nntrainer::Tensor target = constant(1.0, 3, 1, 2, 3); - - std::stringstream ss, expected; - ss << target; - - expected << '<' << typeid(target).name() << " at " << &target << ">\n" - << "data addr: " << target.getData() << '\n' - << "Shape: 3:1:2:3\n" - << " 1 1 1 \n" - << " 1 1 1 \n" - << "\n" - << "-------\n" - << " 1 1 1 \n" - << " 1 1 1 \n" - << "\n" - << "-------\n" - << " 1 1 1 \n" - << " 1 1 1 \n" - << "\n" - << "-------\n"; - - EXPECT_EQ(ss.str(), expected.str()); -} - -// TEST(nntrainer_Tensor, print_large_size) { -// nntrainer::Tensor target = constant(1.2, 3, 10, 10, 10); - -// std::stringstream ss, expected; - -// expected << '<' << typeid(target).name() << " at " << &target << ">\n" -// << "data addr: " << target.getData() << '\n' -// << "Shape: 3:10:10:10\n" -// << "[1.2 1.2 1.2 ... 1.2 1.2 1.2]\n"; -// ss << target; - -// EXPECT_EQ(ss.str(), expected.str()); -// } - -TEST(nntrainer_Tensor, DISABLED_equation_test_01_p) { - nntrainer::Tensor a, b, c; - nntrainer::Tensor ret1, ret2; - - a = randUniform(4, 6, 7, 3, -100, 100); - b = randUniform(4, 6, 7, 3, -100, 100); - c = randUniform(4, 6, 7, 3, -100, 100); - - ret1 = a.subtract(b).multiply(c); - ret2 = a.multiply(c).subtract(b.multiply(c)); - - float *data1 = ret1.getData(); - float *data2 = ret2.getData(); - EXPECT_EQ(ret1, ret2); - - for (unsigned int i = 0; i < ret1.size(); ++i) { - EXPECT_FLOAT_EQ(data1[i], data2[i]); - } -} - -TEST(nntrainer_Tensor, fill_p) { - /// same dimension, buffer size - { - nntrainer::Tensor target(3, 2, 4, 5); - nntrainer::Tensor original = randUniform(3, 2, 4, 5, -1.0f, 1.0f); - target.fill(original, false); - - EXPECT_EQ(target, original); - } - - /// same dimension, buffer size is different (not tested) - { - /// there is no way to make non contiguous tensor publicily yet - EXPECT_TRUE(true); - } - - /// uninitialized with initialized flag is true - { - nntrainer::Tensor target; - nntrainer::Tensor original = randUniform(3, 2, 4, 5, -1.0f, 1.0f); - target.fill(original, true); - - EXPECT_EQ(target, original); - } -} - -TEST(nntrainer_Tensor, fill_uninitialized_n) { - nntrainer::Tensor target; - nntrainer::Tensor original = randUniform(3, 1, 2, 3, -1.0f, 1.0f); - EXPECT_THROW(target.fill(original, false), std::invalid_argument); -} - -TEST(nntrainer_Tensor, fill_different_dimension_n) { - nntrainer::Tensor target(3, 1, 3, 2); - nntrainer::Tensor original = randUniform(3, 1, 2, 3, -1.0f, 1.0f); - EXPECT_THROW(target.fill(original, false), std::invalid_argument); -} - -TEST(nntrainer_Tensor, DISABLED_fill_non_contiguous_n) { - /// there is no way to make non contiguous tensor publicily yet - EXPECT_TRUE(false); -} - -TEST(nntrainer_Tensor, DISABLED_fill_different_buffer_size_n) { - /// there is no way to make same dimension, diffrent buffersized tensor - /// publicily yet - EXPECT_TRUE(false); -} - -TEST(nntrainer_Tensor, empty_01) { - nntrainer::Tensor t; - - EXPECT_TRUE(t.empty()); -} - -TEST(nntrainer_Tensor, empty_02) { - nntrainer::Tensor t({1, 2, 3, 4}, false); - - EXPECT_FALSE(t.empty()); -} - -TEST(nntrainer_Tensor, empty_03) { - nntrainer::Tensor t({1, 2, 3, 4}, true); - - EXPECT_FALSE(t.empty()); -} - -TEST(nntrainer_Tensor, allocate_01_n) { - nntrainer::Tensor t; - EXPECT_FALSE(t.isAllocated()); - - t.allocate(); - EXPECT_FALSE(t.isAllocated()); -} - -TEST(nntrainer_Tensor, allocate_02_p) { - nntrainer::Tensor t({1, 2, 3, 4}, false); - EXPECT_FALSE(t.isAllocated()); - - t.allocate(); - EXPECT_TRUE(t.isAllocated()); -} - -TEST(nntrainer_Tensor, allocate_03_p) { - nntrainer::Tensor t({1, 2, 3, 4}, true); - EXPECT_TRUE(t.isAllocated()); - - t.allocate(); - EXPECT_TRUE(t.isAllocated()); -} - -TEST(nntrainer_Tensor, initialize_01_p) { - nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); - - nntrainer::Tensor golden(1, 2, 3, 4); - golden.setValue(1); - - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, initialize_02_p) { - nntrainer::Tensor t({1, 2, 3, 4}, true); - - nntrainer::Tensor golden(1, 2, 3, 4); - golden.setValue(1); - - EXPECT_NE(golden, t); - - t.initialize(nntrainer::Tensor::Initializer::ONES); - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, initialize_03_p) { - nntrainer::Tensor t({1, 2, 3, 4}, false, - nntrainer::Tensor::Initializer::ONES); - t.allocate(); - - nntrainer::Tensor golden(1, 2, 3, 4); - golden.setValue(1); - - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, initialize_04_p) { - nntrainer::Tensor t({1, 2, 3, 4}, false); - t.initialize(nntrainer::Tensor::Initializer::ONES); - t.allocate(); - - nntrainer::Tensor golden(1, 2, 3, 4); - golden.setValue(1); - - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, initialize_05_p) { - nntrainer::Tensor t({1, 2, 3, 4}, false); - t.allocate(); - - nntrainer::Tensor golden(1, 2, 3, 4); - golden.setValue(1.f); - - /** - * Ideally, it should be NE, but it can be equal due to no initialization - * EXPECT_NE(golden, t); - */ - - t.initialize(nntrainer::Tensor::Initializer::ONES); - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, initialize_06_n) { - nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); - nntrainer::Tensor golden({1, 2, 3, 4}, true, - nntrainer::Tensor::Initializer::ZEROS); - - EXPECT_NE(golden, t); - - golden.initialize(nntrainer::Tensor::Initializer::ONES); - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, initialize_07_p) { - nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); - - nntrainer::Tensor golden(1, 2, 3, 4); - golden.setValue(1); - - EXPECT_EQ(golden, t); - - t.setValue(0, 0, 0, 0, 0); - t.setValue(0, 0, 0, t.size() - 1, 0); - EXPECT_NE(golden, t); - - t.initialize(); - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, initialize_08_p) { - nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); - - nntrainer::Tensor golden(1, 2, 3, 4, nntrainer::Tformat::NCHW, nntrainer::DataType::FP32); - golden.setValue(1); - EXPECT_EQ(golden, t); - - t.initialize(nntrainer::Tensor::Initializer::HE_NORMAL); - EXPECT_NE(golden, t); - - - t.initialize(); - EXPECT_NE(golden, t); - - t.initialize(nntrainer::Tensor::Initializer::ONES); - EXPECT_EQ(golden, t); - - t.initialize(); - EXPECT_EQ(golden, t); -} - -TEST(nntrainer_Tensor, split_01_p) { - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(3); - { - float answer_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39}; - answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); - } - { - float answer_data[] = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}; - answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); - } - { - float answer_data[] = {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; - answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); - } - EXPECT_EQ(t.split(3, 0), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(2); - { - float answer_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; - answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); - } - { - float answer_data[] = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; - answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); - } - EXPECT_EQ(t.split(2, 1), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(2); - { - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109}; - answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); - } - { - float answer_data[] = { - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; - answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); - } - EXPECT_EQ(t.split(2, 2), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(5); - { - float answer_data[] = {0, 5, 10, 15, 20, 25, 30, 35, - 40, 45, 50, 55, 60, 65, 70, 75, - 80, 85, 90, 95, 100, 105, 110, 115}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - { - float answer_data[] = {1, 6, 11, 16, 21, 26, 31, 36, - 41, 46, 51, 56, 61, 66, 71, 76, - 81, 86, 91, 96, 101, 106, 111, 116}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - { - float answer_data[] = {2, 7, 12, 17, 22, 27, 32, 37, - 42, 47, 52, 57, 62, 67, 72, 77, - 82, 87, 92, 97, 102, 107, 112, 117}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - { - float answer_data[] = {3, 8, 13, 18, 23, 28, 33, 38, - 43, 48, 53, 58, 63, 68, 73, 78, - 83, 88, 93, 98, 103, 108, 113, 118}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - { - float answer_data[] = {4, 9, 14, 19, 24, 29, 34, 39, - 44, 49, 54, 59, 64, 69, 74, 79, - 84, 89, 94, 99, 104, 109, 114, 119}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - EXPECT_EQ(t.split(5, 3), answer); - } - { - nntrainer::TensorDim ref_dim(1, 1, 4, 6); - nntrainer::Tensor t = ranged(1, 1, 4, 6); - std::vector answer; - answer.reserve(2); - { - float answer_data[] = {0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20}; - answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data); - } - { - float answer_data[] = {3, 4, 5, 9, 10, 11, 15, 16, 17, 21, 22, 23}; - answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data); - } - EXPECT_EQ(t.split(2, 3), answer); - } -} - -TEST(nntrainer_Tensor, split_02_n) { - nntrainer::Tensor t(1, 1, 1, 1); - EXPECT_THROW(t.split(0, 0), std::invalid_argument); -} - -TEST(nntrainer_Tensor, split_03_n) { - nntrainer::Tensor t(3, 1, 1, 1); - EXPECT_THROW(t.split(2, 0), std::invalid_argument); -} - -TEST(nntrainer_Tensor, split_04_p) { - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(2); - { - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}; - answer.emplace_back(ml::train::TensorDim{2, 2, 4, 5}, answer_data); - } - { - float answer_data[] = {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; - answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); - } - EXPECT_EQ(t.split({2, 1}, 0), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(2); - { - float answer_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; - answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); - } - { - float answer_data[] = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; - answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); - } - EXPECT_EQ(t.split({1, 1}, 1), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(2); - { - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109}; - answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); - } - { - float answer_data[] = { - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; - answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); - } - EXPECT_EQ(t.split({2, 2}, 2), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(3); - { - float answer_data[] = {0, 5, 10, 15, 20, 25, 30, 35, - 40, 45, 50, 55, 60, 65, 70, 75, - 80, 85, 90, 95, 100, 105, 110, 115}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - { - float answer_data[] = { - 1, 2, 3, 6, 7, 8, 11, 12, 13, 16, 17, 18, 21, 22, 23, - 26, 27, 28, 31, 32, 33, 36, 37, 38, 41, 42, 43, 46, 47, 48, - 51, 52, 53, 56, 57, 58, 61, 62, 63, 66, 67, 68, 71, 72, 73, - 76, 77, 78, 81, 82, 83, 86, 87, 88, 91, 92, 93, 96, 97, 98, - 101, 102, 103, 106, 107, 108, 111, 112, 113, 116, 117, 118}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 3}, answer_data); - } - { - float answer_data[] = {4, 9, 14, 19, 24, 29, 34, 39, - 44, 49, 54, 59, 64, 69, 74, 79, - 84, 89, 94, 99, 104, 109, 114, 119}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - EXPECT_EQ(t.split({1, 3, 1}, 3), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(3); - { - float answer_data[] = { - 0, 1, 5, 6, 10, 11, 15, 16, 20, 21, 25, 26, 30, 31, 35, 36, - 40, 41, 45, 46, 50, 51, 55, 56, 60, 61, 65, 66, 70, 71, 75, 76, - 80, 81, 85, 86, 90, 91, 95, 96, 100, 101, 105, 106, 110, 111, 115, 116}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data); - } - { - float answer_data[] = { - 2, 3, 7, 8, 12, 13, 17, 18, 22, 23, 27, 28, 32, 33, 37, 38, - 42, 43, 47, 48, 52, 53, 57, 58, 62, 63, 67, 68, 72, 73, 77, 78, - 82, 83, 87, 88, 92, 93, 97, 98, 102, 103, 107, 108, 112, 113, 117, 118}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data); - } - { - float answer_data[] = {4, 9, 14, 19, 24, 29, 34, 39, - 44, 49, 54, 59, 64, 69, 74, 79, - 84, 89, 94, 99, 104, 109, 114, 119}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); - } - EXPECT_EQ(t.split({2, 2, 1}, 3), answer); - } - { - nntrainer::TensorDim ref_dim(3, 2, 4, 5); - nntrainer::Tensor t = ranged(3, 2, 4, 5); - std::vector answer; - answer.reserve(2); - { - float answer_data[] = { - 0, 1, 5, 6, 10, 11, 15, 16, 20, 21, 25, 26, 30, 31, 35, 36, - 40, 41, 45, 46, 50, 51, 55, 56, 60, 61, 65, 66, 70, 71, 75, 76, - 80, 81, 85, 86, 90, 91, 95, 96, 100, 101, 105, 106, 110, 111, 115, 116}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data); - } - { - float answer_data[] = { - 2, 3, 4, 7, 8, 9, 12, 13, 14, 17, 18, 19, 22, 23, 24, - 27, 28, 29, 32, 33, 34, 37, 38, 39, 42, 43, 44, 47, 48, 49, - 52, 53, 54, 57, 58, 59, 62, 63, 64, 67, 68, 69, 72, 73, 74, - 77, 78, 79, 82, 83, 84, 87, 88, 89, 92, 93, 94, 97, 98, 99, - 102, 103, 104, 107, 108, 109, 112, 113, 114, 117, 118, 119}; - answer.emplace_back(ml::train::TensorDim{3, 2, 4, 3}, answer_data); - } - EXPECT_EQ(t.split({2, 3}, 3), answer); - } - { - nntrainer::TensorDim ref_dim(1, 1, 4, 6); - nntrainer::Tensor t = ranged(1, 1, 4, 6); - std::vector answer; - answer.reserve(3); - { - float answer_data[] = {0, 6, 12, 18}; - answer.emplace_back(ml::train::TensorDim{1, 1, 4, 1}, answer_data); - } - { - float answer_data[] = {1, 2, 3, 7, 8, 9, 13, 14, 15, 19, 20, 21}; - answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data); - } - { - float answer_data[] = {4, 5, 10, 11, 16, 17, 22, 23}; - answer.emplace_back(ml::train::TensorDim{1, 1, 4, 2}, answer_data); - } - EXPECT_EQ(t.split({1, 3, 2}, 3), answer); - } -} - -TEST(nntrainer_Tensor, split_05_n) { - nntrainer::Tensor t(3, 1, 1, 1); - EXPECT_THROW(t.split({1, 1}, 0), std::invalid_argument); -} - -TEST(nntrainer_Tensor, split_06_n) { - nntrainer::Tensor t(3, 1, 1, 1); - EXPECT_THROW(t.split({2, 0, 1}, 0), std::invalid_argument); -} - -TEST(nntrainer_Tensor, split_07_n) { - nntrainer::Tensor t(3, 1, 1, 1); - EXPECT_THROW(t.split({}, 0), std::invalid_argument); -} - -TEST(nntrainer_Tensor, cat_01_p) { - { - std::vector inputs; - inputs.reserve(2); - inputs.emplace_back(ranged(2, 1, 1, 2)); - inputs.emplace_back(ranged(2, 2, 1, 2)); - float answer_data[] = {0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 6, 7}; - nntrainer::Tensor answer(ml::train::TensorDim{2, 3, 1, 2}, answer_data); - EXPECT_EQ(nntrainer::Tensor::cat(inputs, 1), answer); - } - { - std::vector inputs; - inputs.reserve(2); - inputs.emplace_back(ranged(3, 2, 4, 5)); - inputs.emplace_back(ranged(2, 2, 4, 5)); - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79}; - nntrainer::Tensor answer(ml::train::TensorDim{5, 2, 4, 5}, answer_data); - EXPECT_EQ(nntrainer::Tensor::cat(inputs, 0), answer); - } - { - std::vector inputs; - inputs.reserve(2); - inputs.emplace_back(ranged(3, 3, 4, 5)); - inputs.emplace_back(ranged(3, 2, 4, 5)); - float answer_data[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119}; - nntrainer::Tensor answer(ml::train::TensorDim{3, 5, 4, 5}, answer_data); - EXPECT_EQ(nntrainer::Tensor::cat(inputs, 1), answer); - } - { - std::vector inputs; - inputs.reserve(2); - inputs.emplace_back(ranged(3, 2, 1, 5)); - inputs.emplace_back(ranged(3, 2, 2, 5)); - float answer_data[] = { - 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 25, 26, 27, 28, 29, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}; - nntrainer::Tensor answer(ml::train::TensorDim{3, 2, 3, 5}, answer_data); - EXPECT_EQ(nntrainer::Tensor::cat(inputs, 2), answer); - } - { - std::vector inputs; - inputs.reserve(3); - inputs.emplace_back(ranged(3, 2, 4, 1)); - inputs.emplace_back(ranged(3, 2, 4, 3)); - inputs.emplace_back(ranged(3, 2, 4, 2)); - float answer_data[] = { - 0, 0, 1, 2, 0, 1, 1, 3, 4, 5, 2, 3, 2, 6, 7, 8, 4, 5, - 3, 9, 10, 11, 6, 7, 4, 12, 13, 14, 8, 9, 5, 15, 16, 17, 10, 11, - 6, 18, 19, 20, 12, 13, 7, 21, 22, 23, 14, 15, 8, 24, 25, 26, 16, 17, - 9, 27, 28, 29, 18, 19, 10, 30, 31, 32, 20, 21, 11, 33, 34, 35, 22, 23, - 12, 36, 37, 38, 24, 25, 13, 39, 40, 41, 26, 27, 14, 42, 43, 44, 28, 29, - 15, 45, 46, 47, 30, 31, 16, 48, 49, 50, 32, 33, 17, 51, 52, 53, 34, 35, - 18, 54, 55, 56, 36, 37, 19, 57, 58, 59, 38, 39, 20, 60, 61, 62, 40, 41, - 21, 63, 64, 65, 42, 43, 22, 66, 67, 68, 44, 45, 23, 69, 70, 71, 46, 47}; - nntrainer::Tensor answer(ml::train::TensorDim{3, 2, 4, 6}, answer_data); - EXPECT_EQ(nntrainer::Tensor::cat(inputs, 3), answer); - } -} - -TEST(nntrainer_Tensor, cat_02_n) { - { - std::vector inputs; - inputs.reserve(2); - inputs.emplace_back(nntrainer::Tensor(2, 1, 1, 2)); - inputs.emplace_back(nntrainer::Tensor(2, 2, 1, 2)); - EXPECT_THROW(nntrainer::Tensor::cat(inputs, 2), std::invalid_argument); - } -} - -TEST(nntrainer_Tensor, zoneout_mask_01_n) { - const float zoneout_rate = 0.3f; - nntrainer::Tensor t(10, 10, 10, 10); - nntrainer::Tensor opposite(20, 20, 20, 20); - EXPECT_THROW(t.zoneout_mask(opposite, zoneout_rate), std::invalid_argument); -} - -TEST(nntrainer_Tensor, zoneout_mask_02_p) { - const float zoneout_rate = 0.3f; - nntrainer::Tensor t(10, 10, 10, 10); - nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate); - constexpr float epsilon = 1e-3; - - EXPECT_EQ(t.size(), opposite.size()); - - auto is_near = [epsilon](float val1, float val2) { - return val2 - epsilon < val1 && val1 < val2 + epsilon; - }; - - for (unsigned int i = 0; i < opposite.size(); ++i) { - if (is_near(opposite.getValue(i), 0.0f)) { - EXPECT_NEAR(t.getValue(i), 1.0f, epsilon); - } else if (is_near(opposite.getValue(i), 1.0f)) { - EXPECT_NEAR(t.getValue(i), 0.0f, epsilon); - } else { - FAIL() << "This should not be happen"; - } - } -} - -TEST(nntrainer_Tensor, zoneout_mask_03_p) { - const float zoneout_rate = 0.3f; - nntrainer::Tensor t(10, 10, 100, 100); - nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate); - constexpr float epsilon = 1e-3; - - auto is_near = [epsilon](float val1, float val2) { - return val2 - epsilon < val1 && val1 < val2 + epsilon; - }; - auto percentage = [](unsigned int dividend, unsigned int divisor) { - return (float)dividend / (float)divisor; - }; - - { - unsigned int zeros = 0; - unsigned int ones = 0; - for (unsigned int i = 0; i < opposite.size(); ++i) { - if (is_near(opposite.getValue(i), 0.0f)) { - ++zeros; - } else if (is_near(opposite.getValue(i), 1.0f)) { - ++ones; - } else { - FAIL() << "This should not be happen"; - } - } - EXPECT_NEAR(percentage(zeros, opposite.size()), 1.0f - zoneout_rate, - epsilon); - - // main test - EXPECT_NEAR(percentage(ones, opposite.size()), zoneout_rate, epsilon); - } - - { - unsigned int zeros = 0; - unsigned int ones = 0; - for (unsigned int i = 0; i < t.size(); ++i) { - if (is_near(t.getValue(i), 0.0f)) { - ++zeros; - } else if (is_near(t.getValue(i), 1.0f)) { - ++ones; - } else { - FAIL() << "This should not be happen"; - } - } - EXPECT_NEAR(percentage(zeros, t.size()), zoneout_rate, epsilon); - - // main test - EXPECT_NEAR(percentage(ones, t.size()), 1.0f - zoneout_rate, epsilon); - } -} - -TEST(nntrainer_Tensor, zoneout_mask_04_n) { - const float zoneout_rate = 0.3f; - nntrainer::Tensor t(10, 10, 100, 100); - nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate); - constexpr float epsilon = 1e-3; - - auto is_near = [epsilon](float val1, float val2) { - return val2 - epsilon < val1 && val1 < val2 + epsilon; - }; - auto percentage = [](unsigned int dividend, unsigned int divisor) { - return (float)dividend / (float)divisor; - }; - - { - unsigned int zeros = 0; - unsigned int ones = 0; - for (unsigned int i = 0; i < opposite.size(); ++i) { - if (is_near(opposite.getValue(i), 0.0f)) { - ++zeros; - } else if (is_near(opposite.getValue(i), 1.0f)) { - ++ones; - } else { - FAIL() << "This should not be happen"; - } - } - EXPECT_FALSE( - is_near(percentage(ones, opposite.size()), 1.0f - zoneout_rate)); - } - - { - unsigned int zeros = 0; - unsigned int ones = 0; - for (unsigned int i = 0; i < t.size(); ++i) { - if (is_near(t.getValue(i), 0.0f)) { - ++zeros; - } else if (is_near(t.getValue(i), 1.0f)) { - ++ones; - } else { - FAIL() << "This should not be happen"; - } - } - EXPECT_FALSE(is_near(percentage(ones, t.size()), zoneout_rate)); - } -} - -TEST(nntrainer_Tensor, TensorMap_p) { - float dat[] = {1, 2, 3}; - - { - nntrainer::Tensor a = nntrainer::Tensor::Map(dat, 3 * sizeof(float), {3}); - /// check if a.getData() has same address with dat - EXPECT_EQ(dat, a.getData()); - { - /// check if b.getData() has same address with data - nntrainer::Tensor b = a; - EXPECT_EQ(dat, b.getData()); - } - } - /// check if dat is accessible after destruction of all the tensor - EXPECT_FLOAT_EQ(dat[2], 3); -} - -TEST(nntrainer_Tensor, TensorWrap_01_n) { - float dat[] = {1, 2, 3}; - EXPECT_THROW(nntrainer::Tensor::Map(dat, 3, nntrainer::TensorDim({})), - std::invalid_argument); -} - -TEST(nntrainer_Tensor, TensorWrap_02_n) { - float dat[] = {1, 2, 3}; - EXPECT_THROW(nntrainer::Tensor::Map(dat, 3, {4}), std::invalid_argument); -} - -TEST(nntrainer_Tensor, TensorPaddedValue_p) { - nntrainer::Tensor a = ranged(1, 1, 3, 3); - float default_padded = -1; - - for (int i = 0; i < 5; ++i) { - for (int j = 0; j < 5; ++j) { - float expected = default_padded; - if (1 <= i && i <= 3 && 1 <= j && j <= 3) { - expected = (i - 1) * 3 + (j - 1); - } - float actual = a.getValuePaddedVirtual(0, 0, i, j, 1, 1, default_padded); - EXPECT_FLOAT_EQ(actual, expected); - } - } -} - -GTEST_API_ 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; -} diff --git a/test/unittest/jni/tests/unittest_nntrainer_tensor_fp16.cpp b/test/unittest/jni/tests/unittest_nntrainer_tensor_fp16.cpp deleted file mode 100644 index 20e4723..0000000 --- a/test/unittest/jni/tests/unittest_nntrainer_tensor_fp16.cpp +++ /dev/null @@ -1,3893 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/** - * Copyright (C) 2020 Jijoong Moon - * - * @file unittest_nntrainer_tensor.cpp - * @date 03 June 2020 - * @brief Unit test utility for tensor. - * @see https://github.com/nnstreamer/nntrainer - * @author Jijoong Moon - * @bug No known bugs - */ -#include - -#include "nntrainer_test_util.h" -#include "util_func.h" -#include -#include -#include -#include -#include - -TEST(nntrainer_Tensor, Tensor_01_fp16_p) { - int status = ML_ERROR_NONE; - nntrainer::Tensor tensor = nntrainer::Tensor( - 1, 2, 3, nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); - tensor.setZero(); - ASSERT_NE(nullptr, tensor.getData<__fp16>()); - if (tensor.getValue(0, 0, 0, 0) != 0.0) - status = ML_ERROR_INVALID_PARAMETER; - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, Tensor_01_nhwc_fp16_p) { - int status = ML_ERROR_NONE; - nntrainer::Tensor tensor = nntrainer::Tensor( - 1, 2, 3, nntrainer::Tformat::NHWC, nntrainer::DataType::FP16); - tensor.setZero(); - ASSERT_NE(nullptr, tensor.getData<__fp16>()); - if (tensor.getValue<__fp16>(0, 0, 0, 0) != 0.0) - status = ML_ERROR_INVALID_PARAMETER; - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, Tensor_02_fp16_p) { - int status = ML_ERROR_NONE; - int height = 3; - int width = 10; - std::vector> in; - for (int i = 0; i < height; ++i) { - std::vector<__fp16> tv; - for (int j = 0; j < width; ++j) { - tv.push_back(i * 2.0 + j); - } - in.push_back(tv); - } - - nntrainer::Tensor tensor = nntrainer::Tensor(in); - ASSERT_NE(nullptr, tensor.getData<__fp16>()); - - if (tensor.getValue<__fp16>(0, 0, 0, 1) != 1.0) - status = ML_ERROR_INVALID_PARAMETER; - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, Tensor_03_fp16_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int height = 3; - int width = 10; - std::vector>> in; - for (int k = 0; k < batch; ++k) { - std::vector> ttv; - for (int i = 0; i < height; ++i) { - std::vector<__fp16> tv; - for (int j = 0; j < width; ++j) { - tv.push_back(k * height * width + i * width + j); - } - ttv.push_back(tv); - } - in.push_back(ttv); - } - - nntrainer::Tensor tensor = nntrainer::Tensor(in); - ASSERT_NE(nullptr, tensor.getData<__fp16>()); - - if (tensor.getValue<__fp16>(0, 0, 0, 1) != 1.0) - status = ML_ERROR_INVALID_PARAMETER; - EXPECT_EQ(status, ML_ERROR_NONE); -} - -TEST(nntrainer_Tensor, multiply_i_01_fp16_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width, - nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor original; - original.copy(input); - - status = input.multiply_i(2.0); - EXPECT_EQ(status, ML_ERROR_NONE); - - __fp16 *data = original.getData<__fp16>(); - ASSERT_NE(nullptr, data); - __fp16 *indata = input.getData<__fp16>(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width * channel; ++i) { - EXPECT_FLOAT_EQ(data[i] + data[i], indata[i]); - } -} - -TEST(nntrainer_Tensor, multiply_i_02_fp16_p) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width, - nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor original; - original.copy(input); - - status = input.multiply_i(input); - EXPECT_EQ(status, ML_ERROR_NONE); - - __fp16 *data = original.getData<__fp16>(); - ASSERT_NE(nullptr, data); - __fp16 *indata = input.getData<__fp16>(); - ASSERT_NE(nullptr, indata); - - for (int i = 0; i < batch * height * width * channel; ++i) { - EXPECT_FLOAT_EQ(data[i] * data[i], indata[i]); - } -} - -TEST(nntrainer_Tensor, multiply_i_03_fp16_n) { - int status = ML_ERROR_NONE; - int batch = 3; - int channel = 1; - int height = 3; - int width = 10; - - nntrainer::Tensor input(batch, channel, height, width, - nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); - GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - - nntrainer::Tensor target2(batch, channel, height - 2, width - 1, - nntrainer::Tformat::NCHW, - nntrainer::DataType::FP16); - status = input.multiply_i(target2); - - EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -} - -// TEST(nntrainer_Tensor, multiply_i_broadcast_01_fp16_p) { -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = -// ranged(3, 2, 4, 5, nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); -// nntrainer::Tensor m = -// ranged(1, 2, 4, 5, nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); -// __fp16 answer_data[] = { -// 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, -// 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, -// 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, -// 1296, 1369, 1444, 1521, 0, 41, 84, 129, 176, 225, 276, 329, -// 384, 441, 500, 561, 624, 689, 756, 825, 896, 969, 1044, 1121, -// 1200, 1281, 1364, 1449, 1536, 1625, 1716, 1809, 1904, 2001, 2100, 2201, -// 2304, 2409, 2516, 2625, 2736, 2849, 2964, 3081, 0, 81, 164, 249, -// 336, 425, 516, 609, 704, 801, 900, 1001, 1104, 1209, 1316, 1425, -// 1536, 1649, 1764, 1881, 2000, 2121, 2244, 2369, 2496, 2625, 2756, 2889, -// 3024, 3161, 3300, 3441, 3584, 3729, 3876, 4025, 4176, 4329, 4484, 4641}; -// nntrainer::Tensor answer(ref_dim, answer_data, nntrainer::DataType::FP16); -// int status = t.multiply_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5, nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); -// nntrainer::Tensor m = ranged(3, 1, 4, 5, nntrainer::Tformat::NCHW, nntrainer::DataType::FP16); -// __fp16 answer_data[] = { -// 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, -// 144, 169, 196, 225, 256, 289, 324, 361, 0, 21, 44, 69, -// 96, 125, 156, 189, 224, 261, 300, 341, 384, 429, 476, 525, -// 576, 629, 684, 741, 800, 861, 924, 989, 1056, 1125, 1196, 1269, -// 1344, 1421, 1500, 1581, 1664, 1749, 1836, 1925, 2016, 2109, 2204, 2301, -// 1200, 1281, 1364, 1449, 1536, 1625, 1716, 1809, 1904, 2001, 2100, 2201, -// 2304, 2409, 2516, 2625, 2736, 2849, 2964, 3081, 3200, 3321, 3444, 3569, -// 3696, 3825, 3956, 4089, 4224, 4361, 4500, 4641, 4784, 4929, 5076, 5225, -// 5376, 5529, 5684, 5841, 4000, 4141, 4284, 4429, 4576, 4725, 4876, 5029, -// 5184, 5341, 5500, 5661, 5824, 5989, 6156, 6325, 6496, 6669, 6844, 7021}; -// nntrainer::Tensor answer(ref_dim, answer_data, nntrainer::DataType::FP16); -// int status = t.multiply_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } - // { - // nntrainer::TensorDim ref_dim(3, 2, 4, 5); - // nntrainer::Tensor t = ranged(3, 2, 4, 5); - // nntrainer::Tensor m = ranged(3, 2, 4, 1); - // __fp16 answer_data[] = { - // 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 20, 22, - // 24, 26, 28, 45, 48, 51, 54, 57, 80, 84, 88, 92, - // 96, 125, 130, 135, 140, 145, 180, 186, 192, 198, 204, 245, - // 252, 259, 266, 273, 320, 328, 336, 344, 352, 405, 414, 423, - // 432, 441, 500, 510, 520, 530, 540, 605, 616, 627, 638, 649, - // 720, 732, 744, 756, 768, 845, 858, 871, 884, 897, 980, 994, - // 1008, 1022, 1036, 1125, 1140, 1155, 1170, 1185, 1280, 1296, 1312, 1328, - // 1344, 1445, 1462, 1479, 1496, 1513, 1620, 1638, 1656, 1674, 1692, 1805, - // 1824, 1843, 1862, 1881, 2000, 2020, 2040, 2060, 2080, 2205, 2226, 2247, - // 2268, 2289, 2420, 2442, 2464, 2486, 2508, 2645, 2668, 2691, 2714, 2737}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } - // { - // nntrainer::TensorDim ref_dim(3, 2, 4, 5); - // nntrainer::Tensor t = ranged(3, 2, 4, 5); - // nntrainer::Tensor m = ranged(3, 1, 1, 5); - // __fp16 answer_data[] = { - // 0, 1, 4, 9, 16, 0, 6, 14, 24, 36, 0, 11, - // 24, 39, 56, 0, 16, 34, 54, 76, 0, 21, 44, 69, - // 96, 0, 26, 54, 84, 116, 0, 31, 64, 99, 136, 0, - // 36, 74, 114, 156, 200, 246, 294, 344, 396, 225, 276, 329, - // 384, 441, 250, 306, 364, 424, 486, 275, 336, 399, 464, 531, - // 300, 366, 434, 504, 576, 325, 396, 469, 544, 621, 350, 426, - // 504, 584, 666, 375, 456, 539, 624, 711, 800, 891, 984, 1079, - // 1176, 850, 946, 1044, 1144, 1246, 900, 1001, 1104, 1209, 1316, 950, - // 1056, 1164, 1274, 1386, 1000, 1111, 1224, 1339, 1456, 1050, 1166, 1284, - // 1404, 1526, 1100, 1221, 1344, 1469, 1596, 1150, 1276, 1404, 1534, 1666}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } - // { - // nntrainer::TensorDim ref_dim(3, 2, 4, 5); - // nntrainer::Tensor t = ranged(3, 2, 4, 5); - // nntrainer::Tensor m = ranged(1, 2, 1, 5); - // __fp16 answer_data[] = { - // 0, 1, 4, 9, 16, 0, 6, 14, 24, 36, 0, 11, 24, 39, - // 56, 0, 16, 34, 54, 76, 100, 126, 154, 184, 216, 125, 156, 189, - // 224, 261, 150, 186, 224, 264, 306, 175, 216, 259, 304, 351, 0, 41, - // 84, 129, 176, 0, 46, 94, 144, 196, 0, 51, 104, 159, 216, 0, - // 56, 114, 174, 236, 300, 366, 434, 504, 576, 325, 396, 469, 544, 621, - // 350, 426, 504, 584, 666, 375, 456, 539, 624, 711, 0, 81, 164, 249, - // 336, 0, 86, 174, 264, 356, 0, 91, 184, 279, 376, 0, 96, 194, - // 294, 396, 500, 606, 714, 824, 936, 525, 636, 749, 864, 981, 550, 666, - // 784, 904, 1026, 575, 696, 819, 944, 1071}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } - // { - // nntrainer::TensorDim ref_dim(3, 2, 4, 5); - // nntrainer::Tensor t = ranged(3, 2, 4, 5); - // nntrainer::Tensor m = ranged(3, 1, 4, 1); - // __fp16 answer_data[] = { - // 0, 0, 0, 0, 0, 5, 6, 7, 8, 9, 20, 22, - // 24, 26, 28, 45, 48, 51, 54, 57, 0, 0, 0, 0, - // 0, 25, 26, 27, 28, 29, 60, 62, 64, 66, 68, 105, - // 108, 111, 114, 117, 160, 164, 168, 172, 176, 225, 230, 235, - // 240, 245, 300, 306, 312, 318, 324, 385, 392, 399, 406, 413, - // 240, 244, 248, 252, 256, 325, 330, 335, 340, 345, 420, 426, - // 432, 438, 444, 525, 532, 539, 546, 553, 640, 648, 656, 664, - // 672, 765, 774, 783, 792, 801, 900, 910, 920, 930, 940, 1045, - // 1056, 1067, 1078, 1089, 800, 808, 816, 824, 832, 945, 954, 963, - // 972, 981, 1100, 1110, 1120, 1130, 1140, 1265, 1276, 1287, 1298, 1309}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } - // { - // nntrainer::TensorDim ref_dim(3, 2, 4, 5); - // nntrainer::Tensor t = ranged(3, 2, 4, 5); - // nntrainer::Tensor m = ranged(1, 1, 1, 5); - // __fp16 answer_data[] = { - // 0, 1, 4, 9, 16, 0, 6, 14, 24, 36, 0, 11, 24, 39, 56, - // 0, 16, 34, 54, 76, 0, 21, 44, 69, 96, 0, 26, 54, 84, 116, - // 0, 31, 64, 99, 136, 0, 36, 74, 114, 156, 0, 41, 84, 129, 176, - // 0, 46, 94, 144, 196, 0, 51, 104, 159, 216, 0, 56, 114, 174, 236, - // 0, 61, 124, 189, 256, 0, 66, 134, 204, 276, 0, 71, 144, 219, 296, - // 0, 76, 154, 234, 316, 0, 81, 164, 249, 336, 0, 86, 174, 264, 356, - // 0, 91, 184, 279, 376, 0, 96, 194, 294, 396, 0, 101, 204, 309, 416, - // 0, 106, 214, 324, 436, 0, 111, 224, 339, 456, 0, 116, 234, 354, 476}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } - // { - // nntrainer::TensorDim ref_dim(3, 2, 4, 5); - // nntrainer::Tensor t = ranged(3, 2, 4, 5); - // nntrainer::Tensor m = ranged(1, 2, 1, 1); - // __fp16 answer_data[] = { - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, - // 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - // 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - // 112, 113, 114, 115, 116, 117, 118, 119}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } - // { - // nntrainer::TensorDim ref_dim(3, 2, 4, 5); - // nntrainer::Tensor t = ranged(3, 2, 4, 5); - // nntrainer::Tensor m = ranged(3, 1, 1, 1); - // __fp16 answer_data[] = { - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, - // 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - // 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - // 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 160, 162, 164, 166, - // 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, - // 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, - // 224, 226, 228, 230, 232, 234, 236, 238}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } - // { - // nntrainer::TensorDim ref_dim(3, 5, 1, 4); - // nntrainer::Tensor t = ranged(3, 5, 1, 4); - // nntrainer::Tensor m = ranged(3, 1, 1, 4); - // __fp16 answer_data[] = {0, 1, 4, 9, 0, 5, 12, 21, 0, 9, - // 20, 33, 0, 13, 28, 45, 0, 17, 36, 57, - // 80, 105, 132, 161, 96, 125, 156, 189, 112, 145, - // 180, 217, 128, 165, 204, 245, 144, 185, 228, 273, - // 320, 369, 420, 473, 352, 405, 460, 517, 384, 441, - // 500, 561, 416, 477, 540, 605, 448, 513, 580, 649}; - // nntrainer::Tensor answer(ref_dim, answer_data); - // int status = t.multiply_i(m); - // EXPECT_EQ(status, ML_ERROR_NONE); - // EXPECT_EQ(t, answer); - // } -// } - -// TEST(nntrainer_Tensor, multiply_i_broadcast_not_supported_01_n) { -// nntrainer::Tensor target(3, 1, 3, 1); -// nntrainer::Tensor target2(3, 1, 3, 3); - -// EXPECT_EQ(target.multiply_i(target2), ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, multiply_i_broadcast_not_broadcastable_02_n) { -// nntrainer::Tensor target(3, 2, 4, 5); -// nntrainer::Tensor target2(3, 2, 3, 1); - -// EXPECT_EQ(target.multiply_i(target2), ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, multiply_01_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - -// nntrainer::Tensor result = input.multiply(0.0); -// if (result.getValue(0, 0, 1, 1) != 0.0) -// status = ML_ERROR_RESULT_OUT_OF_RANGE; -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, multiply_02_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor result = input.multiply(input); - -// __fp16 *data = result.getData(); -// ASSERT_NE(nullptr, data); -// __fp16 *indata = input.getData(); -// ASSERT_NE(nullptr, indata); - -// for (int i = 0; i < batch * height * width; ++i) { -// if (data[i] != indata[i] * indata[i]) { -// status = ML_ERROR_RESULT_OUT_OF_RANGE; -// break; -// } -// } - -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, multiply_03_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor test(batch - 1, height - 1, width - 1); - -// EXPECT_THROW({ input.multiply(test); }, std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, multiply_04_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); -// nntrainer::Tensor test(dim); - -// EXPECT_THROW(shared_input.multiply(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, multiply_05_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// nntrainer::Tensor test(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - -// EXPECT_THROW(input.multiply(shared_test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, multiply_06_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim, false); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - -// EXPECT_THROW(input.multiply(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, multiply_07_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim, false); - -// EXPECT_THROW(input.multiply(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, multiply_08_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); -// nntrainer::Tensor output(dim, false); - -// EXPECT_THROW(input.multiply(test, output), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, multiply___fp16_01_p) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor expected(batch, channel, height, width); -// GEN_TEST_INPUT(expected, (i * (batch * height) + j * (width) + k + 1) * 2); - -// nntrainer::Tensor result = input.multiply(2.0); - -// EXPECT_EQ(result, expected); -// } - -// TEST(nntrainer_Tensor, divide_i_01_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - -// nntrainer::Tensor original; -// original.copy(input); - -// status = input.divide_i((__fp16)2.0); -// EXPECT_EQ(status, ML_ERROR_NONE); - -// __fp16 *data = original.getData(); -// ASSERT_NE(nullptr, data); -// __fp16 *indata = input.getData(); -// ASSERT_NE(nullptr, indata); - -// for (int i = 0; i < batch * height * width * channel; ++i) { -// EXPECT_FLOAT_EQ(data[i], indata[i] + indata[i]); -// } -// } - -// TEST(nntrainer_Tensor, divide_i_02_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// status = input.divide_i(input); -// EXPECT_EQ(status, ML_ERROR_NONE); -// __fp16 *indata = input.getData(); -// ASSERT_NE(nullptr, indata); - -// for (int i = 0; i < batch * height * width * channel; ++i) { -// EXPECT_FLOAT_EQ(indata[i], __fp16(1.0)); -// } -// } - -// TEST(nntrainer_Tensor, divide_i_01_n) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - -// status = input.divide_i((__fp16)0); -// EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, divide_i_02_n) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - -// nntrainer::Tensor original(batch, channel, height - 2, width - 1); - -// status = input.divide_i(original); -// EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, divide_01_p) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor result = input.divide(1.0); - -// __fp16 *previous = input.getData(); -// ASSERT_NE(nullptr, previous); -// __fp16 *data = result.getData(); -// ASSERT_NE(nullptr, data); - -// for (int i = 0; i < batch * height * width * channel; ++i) { -// EXPECT_FLOAT_EQ(data[i], previous[i]); -// } -// } - -// TEST(nntrainer_Tensor, divide_02_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// EXPECT_THROW({ input.divide(0.0); }, std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, divide_03_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1); - -// EXPECT_THROW({ input.divide(test); }, std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, divide_04_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); -// nntrainer::Tensor test(dim); - -// EXPECT_THROW(shared_input.divide(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, divide_05_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// nntrainer::Tensor test(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - -// EXPECT_THROW(input.divide(shared_test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, divide_06_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim, false); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - -// EXPECT_THROW(input.divide(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, divide_07_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim, false); - -// EXPECT_THROW(input.divide(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, divide_08_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); -// nntrainer::Tensor output(dim, false); - -// EXPECT_THROW(input.divide(test, output), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, divide_i_broadcast_01_p) { -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(1, 2, 4, 5); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 41.0, 21.0, -// 14.333333, 11.0, 9.0, 7.6666665, 6.714286, 6.0, -// 5.4444447, 5.0, 4.6363635, 4.3333335, 4.076923, 3.857143, -// 3.6666667, 3.5, 3.3529413, 3.2222223, 3.1052632, 3.0, -// 2.9047618, 2.8181818, 2.7391305, 2.6666667, 2.6, 2.5384614, -// 2.4814816, 2.4285715, 2.3793104, 2.3333333, 2.2903225, 2.25, -// 2.2121212, 2.1764705, 2.142857, 2.1111112, 2.0810812, 2.0526316, -// 2.025641, 2.0, 81.0, 41.0, 27.666666, 21.0, -// 17.0, 14.333333, 12.428572, 11.0, 9.888889, 9.0, -// 8.272727, 7.6666665, 7.1538463, 6.714286, 6.3333335, 6.0, -// 5.7058825, 5.4444447, 5.2105265, 5.0, 4.8095236, 4.6363635, -// 4.478261, 4.3333335, 4.2, 4.076923, 3.9629629, 3.857143, -// 3.7586207, 3.6666667, 3.580645, 3.5, 3.4242425, 3.3529413, -// 3.2857144, 3.2222223, 3.162162, 3.1052632, 3.0512822, 3.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(3, 1, 4, 5); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -// 1.0, 1.0, 21.0, 11.0, 7.6666665, 6.0, -// 5.0, 4.3333335, 3.857143, 3.5, 3.2222223, 3.0, -// 2.8181818, 2.6666667, 2.5384614, 2.4285715, 2.3333333, 2.25, -// 2.1764705, 2.1111112, 2.0526316, 2.0, 1.9523809, 1.9090909, -// 1.8695652, 1.8333334, 1.8, 1.7692307, 1.7407408, 1.7142857, -// 1.6896552, 1.6666666, 1.6451613, 1.625, 1.6060606, 1.5882353, -// 1.5714285, 1.5555556, 1.5405406, 1.5263158, 1.5128205, 1.5, -// 2.9047618, 2.8181818, 2.7391305, 2.6666667, 2.6, 2.5384614, -// 2.4814816, 2.4285715, 2.3793104, 2.3333333, 2.2903225, 2.25, -// 2.2121212, 2.1764705, 2.142857, 2.1111112, 2.0810812, 2.0526316, -// 2.025641, 2.0, 1.9756098, 1.9523809, 1.9302325, 1.9090909, -// 1.8888888, 1.8695652, 1.8510638, 1.8333334, 1.8163265, 1.8, -// 1.7843137, 1.7692307, 1.754717, 1.7407408, 1.7272727, 1.7142857, -// 1.7017543, 1.6896552, 1.6779661, 1.6666666, 2.4634147, 2.4285715, -// 2.3953488, 2.3636363, 2.3333333, 2.3043478, 2.2765958, 2.25, -// 2.2244897, 2.2, 2.1764705, 2.1538463, 2.1320755, 2.1111112, -// 2.090909, 2.0714285, 2.0526316, 2.0344827, 2.0169492, 2.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(3, 2, 4, 1); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 2.0, 3.0, 4.0, 5.0, 3.0, -// 3.5, 4.0, 4.5, 5.0, 3.6666667, 4.0, -// 4.3333335, 4.6666665, 5.0, 4.0, 4.25, 4.5, -// 4.75, 5.0, 4.2, 4.4, 4.6, 4.8, -// 5.0, 4.3333335, 4.5, 4.6666665, 4.8333335, 5.0, -// 4.428571, 4.571429, 4.714286, 4.857143, 5.0, 4.5, -// 4.625, 4.75, 4.875, 5.0, 4.5555553, 4.6666665, -// 4.7777777, 4.888889, 5.0, 4.6, 4.7, 4.8, -// 4.9, 5.0, 4.6363635, 4.7272725, 4.818182, 4.909091, -// 5.0, 4.6666665, 4.75, 4.8333335, 4.9166665, 5.0, -// 4.6923075, 4.769231, 4.8461537, 4.923077, 5.0, 4.714286, -// 4.785714, 4.857143, 4.928571, 5.0, 4.733333, 4.8, -// 4.866667, 4.9333334, 5.0, 4.75, 4.8125, 4.875, -// 4.9375, 5.0, 4.7647057, 4.8235292, 4.882353, 4.9411764, -// 5.0, 4.7777777, 4.8333335, 4.888889, 4.9444447, 5.0, -// 4.7894735, 4.8421054, 4.894737, 4.9473686, 5.0, 4.8, -// 4.85, 4.9, 4.95, 5.0, 4.8095236, 4.857143, -// 4.904762, 4.952381, 5.0, 4.818182, 4.8636365, 4.909091, -// 4.9545455, 5.0, 4.826087, 4.869565, 4.9130435, 4.9565215, -// 5.0, 4.8333335, 4.875, 4.9166665, 4.9583335, 5.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(3, 1, 1, 5); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 1.0, 1.0, 1.0, 1.0, 6.0, -// 3.5, 2.6666667, 2.25, 2.0, 11.0, 6.0, -// 4.3333335, 3.5, 3.0, 16.0, 8.5, 6.0, -// 4.75, 4.0, 21.0, 11.0, 7.6666665, 6.0, -// 5.0, 26.0, 13.5, 9.333333, 7.25, 6.0, -// 31.0, 16.0, 11.0, 8.5, 7.0, 36.0, -// 18.5, 12.666667, 9.75, 8.0, 6.8333335, 6.0, -// 5.375, 4.888889, 4.5, 7.6666665, 6.714286, 6.0, -// 5.4444447, 5.0, 8.5, 7.428571, 6.625, 6.0, -// 5.5, 9.333333, 8.142858, 7.25, 6.5555553, 6.0, -// 10.166667, 8.857142, 7.875, 7.111111, 6.5, 11.0, -// 9.571428, 8.5, 7.6666665, 7.0, 11.833333, 10.285714, -// 9.125, 8.222222, 7.5, 12.666667, 11.0, 9.75, -// 8.777778, 8.0, 7.3636365, 6.8333335, 6.3846154, 6.0, -// 5.6666665, 7.818182, 7.25, 6.769231, 6.357143, 6.0, -// 8.272727, 7.6666665, 7.1538463, 6.714286, 6.3333335, 8.727273, -// 8.083333, 7.5384617, 7.071429, 6.6666665, 9.181818, 8.5, -// 7.923077, 7.428571, 7.0, 9.636364, 8.916667, 8.307693, -// 7.785714, 7.3333335, 10.090909, 9.333333, 8.692307, 8.142858, -// 7.6666665, 10.545455, 9.75, 9.076923, 8.5, 8.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(1, 2, 1, 5); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 1.0, 1.0, 1.0, 1.0, 6.0, -// 3.5, 2.6666667, 2.25, 2.0, 11.0, 6.0, -// 4.3333335, 3.5, 3.0, 16.0, 8.5, 6.0, -// 4.75, 4.0, 3.5, 3.142857, 2.875, 2.6666667, -// 2.5, 4.3333335, 3.857143, 3.5, 3.2222223, 3.0, -// 5.1666665, 4.571429, 4.125, 3.7777777, 3.5, 6.0, -// 5.285714, 4.75, 4.3333335, 4.0, 41.0, 21.0, -// 14.333333, 11.0, 9.0, 46.0, 23.5, 16.0, -// 12.25, 10.0, 51.0, 26.0, 17.666666, 13.5, -// 11.0, 56.0, 28.5, 19.333334, 14.75, 12.0, -// 10.166667, 8.857142, 7.875, 7.111111, 6.5, 11.0, -// 9.571428, 8.5, 7.6666665, 7.0, 11.833333, 10.285714, -// 9.125, 8.222222, 7.5, 12.666667, 11.0, 9.75, -// 8.777778, 8.0, 81.0, 41.0, 27.666666, 21.0, -// 17.0, 86.0, 43.5, 29.333334, 22.25, 18.0, -// 91.0, 46.0, 31.0, 23.5, 19.0, 96.0, -// 48.5, 32.666668, 24.75, 20.0, 16.833334, 14.571428, -// 12.875, 11.555555, 10.5, 17.666666, 15.285714, 13.5, -// 12.111111, 11.0, 18.5, 16.0, 14.125, 12.666667, -// 11.5, 19.333334, 16.714285, 14.75, 13.222222, 12.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(3, 1, 4, 1); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 2.0, 3.0, 4.0, 5.0, 3.0, -// 3.5, 4.0, 4.5, 5.0, 3.6666667, 4.0, -// 4.3333335, 4.6666665, 5.0, 4.0, 4.25, 4.5, -// 4.75, 5.0, 21.0, 22.0, 23.0, 24.0, -// 25.0, 13.0, 13.5, 14.0, 14.5, 15.0, -// 10.333333, 10.666667, 11.0, 11.333333, 11.666667, 9.0, -// 9.25, 9.5, 9.75, 10.0, 8.2, 8.4, -// 8.6, 8.8, 9.0, 7.6666665, 7.8333335, 8.0, -// 8.166667, 8.333333, 7.285714, 7.428571, 7.571429, 7.714286, -// 7.857143, 7.0, 7.125, 7.25, 7.375, 7.5, -// 12.2, 12.4, 12.6, 12.8, 13.0, 11.0, -// 11.166667, 11.333333, 11.5, 11.666667, 10.142858, 10.285714, -// 10.428572, 10.571428, 10.714286, 9.5, 9.625, 9.75, -// 9.875, 10.0, 9.0, 9.111111, 9.222222, 9.333333, -// 9.444445, 8.6, 8.7, 8.8, 8.9, 9.0, -// 8.272727, 8.363636, 8.454545, 8.545455, 8.636364, 8.0, -// 8.083333, 8.166667, 8.25, 8.333333, 11.222222, 11.333333, -// 11.444445, 11.555555, 11.666667, 10.6, 10.7, 10.8, -// 10.9, 11.0, 10.090909, 10.181818, 10.272727, 10.363636, -// 10.454545, 9.666667, 9.75, 9.833333, 9.916667, 10.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(1, 1, 1, 5); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 1.0, 1.0, 1.0, 1.0, 6.0, 3.5, 2.6666667, 2.25, 2.0, -// 11.0, 6.0, 4.3333335, 3.5, 3.0, 16.0, 8.5, 6.0, 4.75, 4.0, -// 21.0, 11.0, 7.6666665, 6.0, 5.0, 26.0, 13.5, 9.333333, 7.25, 6.0, -// 31.0, 16.0, 11.0, 8.5, 7.0, 36.0, 18.5, 12.666667, 9.75, 8.0, -// 41.0, 21.0, 14.333333, 11.0, 9.0, 46.0, 23.5, 16.0, 12.25, 10.0, -// 51.0, 26.0, 17.666666, 13.5, 11.0, 56.0, 28.5, 19.333334, 14.75, 12.0, -// 61.0, 31.0, 21.0, 16.0, 13.0, 66.0, 33.5, 22.666666, 17.25, 14.0, -// 71.0, 36.0, 24.333334, 18.5, 15.0, 76.0, 38.5, 26.0, 19.75, 16.0, -// 81.0, 41.0, 27.666666, 21.0, 17.0, 86.0, 43.5, 29.333334, 22.25, 18.0, -// 91.0, 46.0, 31.0, 23.5, 19.0, 96.0, 48.5, 32.666668, 24.75, 20.0, -// 101.0, 51.0, 34.333332, 26.0, 21.0, 106.0, 53.5, 36.0, 27.25, 22.0, -// 111.0, 56.0, 37.666668, 28.5, 23.0, 116.0, 58.5, 39.333332, 29.75, 24.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(1, 2, 1, 1); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, -// 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 10.5, 11.0, 11.5, 12.0, -// 12.5, 13.0, 13.5, 14.0, 14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0, -// 18.5, 19.0, 19.5, 20.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, -// 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, -// 30.5, 31.0, 31.5, 32.0, 32.5, 33.0, 33.5, 34.0, 34.5, 35.0, 35.5, 36.0, -// 36.5, 37.0, 37.5, 38.0, 38.5, 39.0, 39.5, 40.0, 81.0, 82.0, 83.0, 84.0, -// 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, -// 97.0, 98.0, 99.0, 100.0, 50.5, 51.0, 51.5, 52.0, 52.5, 53.0, 53.5, 54.0, -// 54.5, 55.0, 55.5, 56.0, 56.5, 57.0, 57.5, 58.0, 58.5, 59.0, 59.5, 60.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// t.add_i(1); -// nntrainer::Tensor m = ranged(3, 1, 1, 1); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, -// 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, -// 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, -// 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, -// 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, -// 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, -// 37.0, 38.0, 39.0, 40.0, 20.5, 21.0, -// 21.5, 22.0, 22.5, 23.0, 23.5, 24.0, -// 24.5, 25.0, 25.5, 26.0, 26.5, 27.0, -// 27.5, 28.0, 28.5, 29.0, 29.5, 30.0, -// 30.5, 31.0, 31.5, 32.0, 32.5, 33.0, -// 33.5, 34.0, 34.5, 35.0, 35.5, 36.0, -// 36.5, 37.0, 37.5, 38.0, 38.5, 39.0, -// 39.5, 40.0, 27.0, 27.333334, 27.666666, 28.0, -// 28.333334, 28.666666, 29.0, 29.333334, 29.666666, 30.0, -// 30.333334, 30.666666, 31.0, 31.333334, 31.666666, 32.0, -// 32.333332, 32.666668, 33.0, 33.333332, 33.666668, 34.0, -// 34.333332, 34.666668, 35.0, 35.333332, 35.666668, 36.0, -// 36.333332, 36.666668, 37.0, 37.333332, 37.666668, 38.0, -// 38.333332, 38.666668, 39.0, 39.333332, 39.666668, 40.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 5, 1, 4); -// nntrainer::Tensor t = ranged(3, 5, 1, 4); -// t.add_i(1); -// nntrainer::Tensor m = ranged(3, 1, 1, 4); -// m.add_i(1); -// __fp16 answer_data[] = { -// 1.0, 1.0, 1.0, 1.0, 5.0, 3.0, -// 2.3333333, 2.0, 9.0, 5.0, 3.6666667, 3.0, -// 13.0, 7.0, 5.0, 4.0, 17.0, 9.0, -// 6.3333335, 5.0, 4.2, 3.6666667, 3.2857144, 3.0, -// 5.0, 4.3333335, 3.857143, 3.5, 5.8, 5.0, -// 4.428571, 4.0, 6.6, 5.6666665, 5.0, 4.5, -// 7.4, 6.3333335, 5.571429, 5.0, 4.5555553, 4.2, -// 3.909091, 3.6666667, 5.0, 4.6, 4.2727275, 4.0, -// 5.4444447, 5.0, 4.6363635, 4.3333335, 5.888889, 5.4, -// 5.0, 4.6666665, 6.3333335, 5.8, 5.3636365, 5.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.divide_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// } - -// TEST(nntrainer_Tensor, divide_i_broadcast_not_supported_01_n) { -// nntrainer::Tensor target(3, 1, 3, 1); -// nntrainer::Tensor target2(3, 1, 3, 3); - -// EXPECT_EQ(target.divide_i(target2), ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, divide_i_broadcast_not_broadcastable_02_n) { -// nntrainer::Tensor target(3, 2, 4, 5); -// nntrainer::Tensor target2(3, 2, 3, 1); - -// EXPECT_EQ(target.divide_i(target2), ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, add_i_01_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int height = 3; -// int width = 10; -// int channel = 1; - -// nntrainer::Tensor target(batch, channel, height, width); -// GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - -// nntrainer::Tensor original(batch, channel, height, width); -// original.copy(target); - -// status = target.add_i(2.1); -// EXPECT_EQ(status, ML_ERROR_NONE); - -// __fp16 *previous = original.getData(); -// ASSERT_NE(nullptr, previous); -// __fp16 *data = target.getData(); -// ASSERT_NE(nullptr, data); - -// for (int i = 0; i < batch * height * width; ++i) { -// EXPECT_FLOAT_EQ(data[i], previous[i] + (__fp16)2.1); -// } -// } - -// TEST(nntrainer_Tensor, add_i_02_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int height = 3; -// int width = 10; -// int channel = 1; - -// nntrainer::Tensor target(batch, channel, height, width); -// GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor original(batch, height, width); -// original.copy(target); - -// status = target.add_i(target, 3.0); -// EXPECT_EQ(status, ML_ERROR_NONE); - -// __fp16 *previous = original.getData(); -// ASSERT_NE(nullptr, previous); -// __fp16 *data = target.getData(); -// ASSERT_NE(nullptr, data); - -// for (int i = 0; i < batch * height * width; ++i) { -// EXPECT_FLOAT_EQ(data[i], previous[i] * 4.0); -// } -// } - -// /** -// * @brief operand dimension is not right -// */ -// TEST(nntrainer_Tensor, add_i_01_n) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int height = 3; -// int width = 10; -// int channel = 1; - -// nntrainer::Tensor target(batch, channel, height, width); -// GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor target2(batch, height - 2, width - 3); - -// status = target.add_i(target2); -// EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, add_i_broadcast_01_p) { -// nntrainer::TensorDim ref_dim{3, 2, 4, 5}; -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(1, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, -// 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, -// 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 40, 42, -// 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, -// 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, -// 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 80, 82, 84, 86, -// 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, -// 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, -// 144, 146, 148, 150, 152, 154, 156, 158}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 1, 4, 5); -// __fp16 answer_data[] = { -// 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, -// 28, 30, 32, 34, 36, 38, 20, 22, 24, 26, 28, 30, 32, 34, -// 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, -// 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, -// 92, 94, 96, 98, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, -// 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, -// 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, -// 156, 158, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, -// 164, 166, 168, 170, 172, 174, 176, 178}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 2, 4, 1); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, -// 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 30, 31, 32, -// 33, 34, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 48, 49, -// 50, 51, 52, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 66, -// 67, 68, 69, 70, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, -// 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 96, 97, 98, 99, -// 100, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 114, 115, 116, -// 117, 118, 120, 121, 122, 123, 124, 126, 127, 128, 129, 130, 132, 133, -// 134, 135, 136, 138, 139, 140, 141, 142}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 1, 1, 5); -// __fp16 answer_data[] = { -// 0, 2, 4, 6, 8, 5, 7, 9, 11, 13, 10, 12, 14, 16, -// 18, 15, 17, 19, 21, 23, 20, 22, 24, 26, 28, 25, 27, 29, -// 31, 33, 30, 32, 34, 36, 38, 35, 37, 39, 41, 43, 45, 47, -// 49, 51, 53, 50, 52, 54, 56, 58, 55, 57, 59, 61, 63, 60, -// 62, 64, 66, 68, 65, 67, 69, 71, 73, 70, 72, 74, 76, 78, -// 75, 77, 79, 81, 83, 80, 82, 84, 86, 88, 90, 92, 94, 96, -// 98, 95, 97, 99, 101, 103, 100, 102, 104, 106, 108, 105, 107, 109, -// 111, 113, 110, 112, 114, 116, 118, 115, 117, 119, 121, 123, 120, 122, -// 124, 126, 128, 125, 127, 129, 131, 133}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(1, 2, 1, 5); -// __fp16 answer_data[] = { -// 0, 2, 4, 6, 8, 5, 7, 9, 11, 13, 10, 12, 14, 16, -// 18, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 30, 32, 34, -// 36, 38, 35, 37, 39, 41, 43, 40, 42, 44, 46, 48, 40, 42, -// 44, 46, 48, 45, 47, 49, 51, 53, 50, 52, 54, 56, 58, 55, -// 57, 59, 61, 63, 65, 67, 69, 71, 73, 70, 72, 74, 76, 78, -// 75, 77, 79, 81, 83, 80, 82, 84, 86, 88, 80, 82, 84, 86, -// 88, 85, 87, 89, 91, 93, 90, 92, 94, 96, 98, 95, 97, 99, -// 101, 103, 105, 107, 109, 111, 113, 110, 112, 114, 116, 118, 115, 117, -// 119, 121, 123, 120, 122, 124, 126, 128}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 1, 4, 1); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, -// 16, 18, 19, 20, 21, 22, 20, 21, 22, 23, 24, 26, 27, 28, -// 29, 30, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 44, 45, -// 46, 47, 48, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 62, -// 63, 64, 65, 66, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, -// 76, 77, 78, 79, 80, 82, 83, 84, 85, 86, 88, 89, 90, 91, -// 92, 94, 95, 96, 97, 98, 100, 101, 102, 103, 104, 106, 107, 108, -// 109, 110, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 120, 121, -// 122, 123, 124, 126, 127, 128, 129, 130}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(1, 1, 1, 5); -// __fp16 answer_data[] = { -// 0, 2, 4, 6, 8, 5, 7, 9, 11, 13, 10, 12, 14, 16, -// 18, 15, 17, 19, 21, 23, 20, 22, 24, 26, 28, 25, 27, 29, -// 31, 33, 30, 32, 34, 36, 38, 35, 37, 39, 41, 43, 40, 42, -// 44, 46, 48, 45, 47, 49, 51, 53, 50, 52, 54, 56, 58, 55, -// 57, 59, 61, 63, 60, 62, 64, 66, 68, 65, 67, 69, 71, 73, -// 70, 72, 74, 76, 78, 75, 77, 79, 81, 83, 80, 82, 84, 86, -// 88, 85, 87, 89, 91, 93, 90, 92, 94, 96, 98, 95, 97, 99, -// 101, 103, 100, 102, 104, 106, 108, 105, 107, 109, 111, 113, 110, 112, -// 114, 116, 118, 115, 117, 119, 121, 123}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(1, 2, 1, 1); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -// 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, -// 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 40, 41, -// 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -// 56, 57, 58, 59, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -// 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 80, 81, 82, 83, -// 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, -// 98, 99, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, -// 113, 114, 115, 116, 117, 118, 119, 120}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 1, 1, 1); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -// 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -// 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, -// 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -// 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -// 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 83, 84, 85, -// 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, -// 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, -// 114, 115, 116, 117, 118, 119, 120, 121}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(1, 1, 1, 1); -// m.add_i(1.0); -// __fp16 answer_data[] = { -// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -// 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, -// 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, -// 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -// 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -// 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -// 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, -// 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, -// 113, 114, 115, 116, 117, 118, 119, 120}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 5, 1, 4); -// nntrainer::Tensor t = ranged(3, 5, 1, 4); -// nntrainer::Tensor m = ranged(3, 1, 1, 4); -// __fp16 answer_data[] = {0, 2, 4, 6, 4, 6, 8, 10, 8, 10, 12, 14, -// 12, 14, 16, 18, 16, 18, 20, 22, 24, 26, 28, 30, -// 28, 30, 32, 34, 32, 34, 36, 38, 36, 38, 40, 42, -// 40, 42, 44, 46, 48, 50, 52, 54, 52, 54, 56, 58, -// 56, 58, 60, 62, 60, 62, 64, 66, 64, 66, 68, 70}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(1, 1, 2, 1); -// nntrainer::Tensor t = ranged(1, 1, 2, 1); -// nntrainer::Tensor m = ranged(1, 1, 2, 1); -// __fp16 answer_data[] = {0.0, 2.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// { -// nntrainer::TensorDim ref_dim(16, 1, 1, 1); -// nntrainer::Tensor t = ranged(16, 1, 1, 1); -// nntrainer::Tensor m = ranged(1, 1, 1, 1); -// __fp16 answer_data[] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, -// 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0}; -// nntrainer::Tensor answer(ref_dim, answer_data); -// int status = t.add_i(m); -// EXPECT_EQ(status, ML_ERROR_NONE); -// EXPECT_EQ(t, answer); -// } -// } - -// TEST(nntrainer_Tensor, add_i_broadcast_not_supported_01_n) { -// nntrainer::Tensor target(3, 1, 3, 1); -// nntrainer::Tensor target2(3, 1, 3, 3); - -// EXPECT_EQ(target.add_i(target2), ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, add_i_broadcast_not_broadcastable_02_n) { -// nntrainer::Tensor target(3, 2, 4, 5); -// nntrainer::Tensor target2(3, 2, 3, 1); - -// EXPECT_EQ(target.add_i(target2), ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, add_01_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor result = input.add(1.0); - -// __fp16 *data = result.getData(); -// ASSERT_NE(nullptr, data); -// __fp16 *indata = input.getData(); -// ASSERT_NE(nullptr, indata); - -// for (int i = 0; i < batch * height * width; ++i) { -// if (data[i] != indata[i] + (__fp16)1.0) { -// status = ML_ERROR_RESULT_OUT_OF_RANGE; -// break; -// } -// } - -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, add_02_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor result = input.add(input); - -// __fp16 *data = result.getData(); -// ASSERT_NE(nullptr, data); -// __fp16 *indata = input.getData(); -// ASSERT_NE(nullptr, indata); - -// for (int i = 0; i < batch * height * width; ++i) { -// if (data[i] != indata[i] + indata[i]) { -// status = ML_ERROR_RESULT_OUT_OF_RANGE; -// break; -// } -// } - -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, add_03_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1); - -// EXPECT_THROW({ input.add(test); }, std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, add_04_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); -// nntrainer::Tensor test(dim); - -// EXPECT_THROW(shared_input.add(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, add_05_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// nntrainer::Tensor test(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - -// EXPECT_THROW(input.add(shared_test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, add_06_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim, false); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - -// EXPECT_THROW(input.add(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, add_07_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim, false); - -// EXPECT_THROW(input.add(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, add_08_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); -// nntrainer::Tensor output(dim, false); - -// EXPECT_THROW(input.add(test, output), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, pow_01_p) { - -// nntrainer::Tensor input = constant(4.0, 3, 2, 4, 5); - -// nntrainer::Tensor actual, expected; - -// actual = input.pow(0.5f); -// expected = constant(2.0, 3, 2, 4, 5); -// EXPECT_EQ(actual, expected); - -// actual = input.pow(2.0f); -// expected = constant(16.0, 3, 2, 4, 5); -// EXPECT_EQ(actual, expected); - -// actual = input.pow(-0.5f); -// expected = constant(0.5, 3, 2, 4, 5); -// EXPECT_EQ(actual, expected); -// } - -// TEST(nntrainer_Tensor, erf_01_p) { -// int batch = 1; -// int channel = 1; -// int height = 2; -// int width = 2; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, k + l * 0.5 + 0.5); -// nntrainer::Tensor actual = input.erf(); -// nntrainer::Tensor expected( -// std::vector>>>( -// {{{{0.5205, 0.8427}, {0.966105, 0.995322}}}})); - -// EXPECT_EQ(actual, expected); -// } - -// TEST(nntrainer_Tensor, subtract_i_01_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int height = 3; -// int width = 10; -// int channel = 1; - -// nntrainer::Tensor target(batch, channel, height, width); -// GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - -// nntrainer::Tensor original(batch, height, width); -// original.copy(target); - -// status = target.subtract_i(2.1); -// EXPECT_EQ(status, ML_ERROR_NONE); - -// __fp16 *previous = original.getData(); -// ASSERT_NE(nullptr, previous); -// __fp16 *data = target.getData(); -// ASSERT_NE(nullptr, data); - -// for (int i = 0; i < batch * height * width; ++i) { -// EXPECT_FLOAT_EQ(data[i], previous[i] - (__fp16)2.1); -// } -// } - -// TEST(nntrainer_Tensor, subtract_i_02_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int height = 3; -// int width = 10; -// int channel = 1; - -// nntrainer::Tensor target(batch, channel, height, width); -// GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - -// status = target.subtract_i(target); -// EXPECT_EQ(status, ML_ERROR_NONE); - -// __fp16 *data = target.getData(); -// ASSERT_NE(nullptr, data); - -// for (int i = 0; i < batch * height * width; ++i) { -// EXPECT_FLOAT_EQ(data[i], 0); -// } -// } - -// TEST(nntrainer_Tensor, subtract_i_03_n) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int height = 3; -// int width = 10; -// int channel = 1; - -// nntrainer::Tensor target(batch, channel, height, width); -// GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel); - -// nntrainer::Tensor target2(batch, channel, height - 1, width - 3); - -// status = target.subtract_i(target2); -// EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER); -// } - -// TEST(nntrainer_Tensor, subtract_01_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor result = input.subtract(1.0); - -// __fp16 *data = result.getData(); -// ASSERT_NE(nullptr, data); -// __fp16 *indata = input.getData(); -// ASSERT_NE(nullptr, indata); - -// for (int i = 0; i < batch * height * width; ++i) { -// if (data[i] != indata[i] - 1.0) { -// status = ML_ERROR_RESULT_OUT_OF_RANGE; -// break; -// } -// } - -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, subtract_02_p) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor result = input.subtract(input); - -// EXPECT_EQ(constant(0.0, batch, channel, height, width), result); -// } - -// TEST(nntrainer_Tensor, subtract_03_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1); - -// EXPECT_THROW({ input.subtract(test); }, std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, subtract_04_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false); -// nntrainer::Tensor test(dim); - -// EXPECT_THROW(shared_input.subtract(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, subtract_05_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// nntrainer::Tensor test(batch, channel, height, 2 * width); -// nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false); - -// EXPECT_THROW(input.subtract(shared_test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, subtract_06_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim, false); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1); - -// EXPECT_THROW(input.subtract(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, subtract_07_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim, false); - -// EXPECT_THROW(input.subtract(test), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, subtract_08_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::TensorDim dim(batch, channel, height, width); - -// nntrainer::Tensor input(dim); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); -// nntrainer::Tensor test(dim); -// GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2); -// nntrainer::Tensor output(dim, false); - -// EXPECT_THROW(input.subtract(test, output), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, subtract___fp16_01_p) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1); - -// nntrainer::Tensor expected(batch, channel, height, width); -// GEN_TEST_INPUT(expected, i * (batch * height) + j * (width) + k); - -// nntrainer::Tensor result = input.subtract(1.0); - -// EXPECT_EQ(result, expected); -// } - -// TEST(nntrainer_Tensor, sum_01_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - -// EXPECT_THROW({ input.sum(4); }, std::out_of_range); -// } - -// TEST(nntrainer_Tensor, sum_02_n) { -// int batch = 3; -// int channel = 1; -// int height = 3; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); - -// EXPECT_THROW({ input.sum(-1); }, std::out_of_range); -// } - -// TEST(nntrainer_Tensor, sum_02_p) { -// int batch = 3; -// int channel = 2; -// int height = 2; -// int width = 10; - -// nntrainer::Tensor ans0( -// std::vector>>>( -// {{{{39, 42, 45, 48, 51, 54, 57, 60, 63, 66}, -// {69, 72, 75, 78, 81, 84, 87, 90, 93, 96}}, -// {{57, 60, 63, 66, 69, 72, 75, 78, 81, 84}, -// {87, 90, 93, 96, 99, 102, 105, 108, 111, 114}}}})); - -// nntrainer::Tensor ans1( -// std::vector>>>( -// {{{{8, 10, 12, 14, 16, 18, 20, 22, 24, 26}, -// {28, 30, 32, 34, 36, 38, 40, 42, 44, 46}}}, -// {{{32, 34, 36, 38, 40, 42, 44, 46, 48, 50}, -// {52, 54, 56, 58, 60, 62, 64, 66, 68, 70}}}, -// {{{56, 58, 60, 62, 64, 66, 68, 70, 72, 74}, -// {76, 78, 80, 82, 84, 86, 88, 90, 92, 94}}}})); - -// nntrainer::Tensor ans2( -// std::vector>>>( -// {{{{12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}, -// {{24, 26, 28, 30, 32, 34, 36, 38, 40, 42}}}, -// {{{36, 38, 40, 42, 44, 46, 48, 50, 52, 54}}, -// {{48, 50, 52, 54, 56, 58, 60, 62, 64, 66}}}, -// {{{60, 62, 64, 66, 68, 70, 72, 74, 76, 78}}, -// {{72, 74, 76, 78, 80, 82, 84, 86, 88, 90}}}})); - -// nntrainer::Tensor ans3( -// std::vector>>>( -// {{{{55}, {155}}, {{115}, {215}}}, -// {{{175}, {275}}, {{235}, {335}}}, -// {{{295}, {395}}, {{355}, {455}}}})); - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height * channel) + j * (batch * height) + -// k * (width) + l + 1); - -// nntrainer::Tensor result0 = input.sum(0); -// nntrainer::Tensor result1 = input.sum(1); -// nntrainer::Tensor result2 = input.sum(2); -// nntrainer::Tensor result3 = input.sum(3); - -// EXPECT_EQ(ans0, result0); -// EXPECT_EQ(ans1, result1); -// EXPECT_EQ(ans2, result2); -// EXPECT_EQ(ans3, result3); -// } - -// TEST(nntrainer_Tensor, sum_03_p) { -// const int batch = 3; -// const int channel = 2; -// const int height = 1; -// const int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (height * channel * width) + j * (height * width) + -// k * (width) + l + 1); -// // Test for alpha == 1 and beta == 0 and dimension of reduced axis == 1 -// { -// nntrainer::Tensor ans_0_1_0( -// std::vector>>>( -// {{{{63, 66, 69, 72, 75, 78, 81, 84, 87, 90}}, -// {{93, 96, 99, 102, 105, 108, 111, 114, 117, 120}}}})); - -// nntrainer::Tensor ans_1_1_0( -// std::vector>>>( -// {{{{12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}}, -// {{{52, 54, 56, 58, 60, 62, 64, 66, 68, 70}}}, -// {{{92, 94, 96, 98, 100, 102, 104, 106, 108, 110}}}})); - -// nntrainer::Tensor ans_2_1_0( -// std::vector>>>( -// {{{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, -// {{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}}}, -// {{{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}}, -// {{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}}}, -// {{{41, 42, 43, 44, 45, 46, 47, 48, 49, 50}}, -// {{51, 52, 53, 54, 55, 56, 57, 58, 59, 60}}}})); - -// nntrainer::Tensor ans_3_1_0( -// std::vector>>>( -// {{{{55}}, {{155}}}, {{{255}}, {{355}}}, {{{455}}, {{555}}}})); - -// nntrainer::Tensor result_0_1_0 = input.sum(0, 1); -// nntrainer::Tensor result_1_1_0 = input.sum(1, 1); -// nntrainer::Tensor result_2_1_0 = input.sum(2, 1); -// nntrainer::Tensor result_3_1_0 = input.sum(3, 1); - -// EXPECT_EQ(ans_0_1_0, result_0_1_0); -// EXPECT_EQ(ans_1_1_0, result_1_1_0); -// EXPECT_EQ(ans_2_1_0, result_2_1_0); -// EXPECT_EQ(ans_3_1_0, result_3_1_0); -// } - -// // Test for alpha == 1 and beta == 2 and dimension of reduced axis == 1 -// { -// nntrainer::Tensor ans_0_1_2( -// std::vector>>>( -// {{{{65, 70, 75, 80, 85, 90, 95, 100, 105, 110}}, -// {{115, 120, 125, 130, 135, 140, 145, 150, 155, 160}}}})); - -// nntrainer::Tensor ans_1_1_2( -// std::vector>>>( -// {{{{14, 18, 22, 26, 30, 34, 38, 42, 46, 50}}}, -// {{{74, 78, 82, 86, 90, 94, 98, 102, 106, 110}}}, -// {{{134, 138, 142, 146, 150, 154, 158, 162, 166, 170}}}})); - -// nntrainer::Tensor ans_2_1_2( -// std::vector>>>( -// {{{{3, 6, 9, 12, 15, 18, 21, 24, 27, 30}}, -// {{33, 36, 39, 42, 45, 48, 51, 54, 57, 60}}}, -// {{{63, 66, 69, 72, 75, 78, 81, 84, 87, 90}}, -// {{93, 96, 99, 102, 105, 108, 111, 114, 117, 120}}}, -// {{{123, 126, 129, 132, 135, 138, 141, 144, 147, 150}}, -// {{153, 156, 159, 162, 165, 168, 171, 174, 177, 180}}}})); - -// nntrainer::Tensor ans_3_1_2( -// std::vector>>>( -// {{{{57}}, {{159}}}, {{{261}}, {{363}}}, {{{465}}, {{567}}}})); - -// nntrainer::Tensor output_0_1_2(1, channel, height, width); -// { -// const int batch = 1; -// GEN_TEST_INPUT(output_0_1_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor output_1_1_2(batch, 1, height, width); -// { -// const int channel = 1; -// GEN_TEST_INPUT(output_1_1_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor output_2_1_2(batch, channel, 1, width); -// { -// const int height = 1; -// GEN_TEST_INPUT(output_2_1_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor output_3_1_2(batch, channel, height, 1); -// { -// const int width = 1; -// GEN_TEST_INPUT(output_3_1_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor result_0_1_2 = input.sum(0, output_0_1_2, 1, 2); -// nntrainer::Tensor result_1_1_2 = input.sum(1, output_1_1_2, 1, 2); -// nntrainer::Tensor result_2_1_2 = input.sum(2, output_2_1_2, 1, 2); -// nntrainer::Tensor result_3_1_2 = input.sum(3, output_3_1_2, 1, 2); - -// EXPECT_EQ(ans_0_1_2, result_0_1_2); -// EXPECT_EQ(ans_1_1_2, result_1_1_2); -// EXPECT_EQ(ans_2_1_2, result_2_1_2); -// EXPECT_EQ(ans_3_1_2, result_3_1_2); -// } - -// // Test for alpha == 2 and beta == 0 -// { -// nntrainer::Tensor ans_0_2_0( -// std::vector>>>( -// {{{{126, 132, 138, 144, 150, 156, 162, 168, 174, 180}}, -// {{186, 192, 198, 204, 210, 216, 222, 228, 234, 240}}}})); - -// nntrainer::Tensor ans_1_2_0( -// std::vector>>>( -// {{{{24, 28, 32, 36, 40, 44, 48, 52, 56, 60}}}, -// {{{104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, -// {{{184, 188, 192, 196, 200, 204, 208, 212, 216, 220}}}})); - -// nntrainer::Tensor ans_2_2_0( -// std::vector>>>( -// {{{{2, 4, 6, 8, 10, 12, 14, 16, 18, 20}}, -// {{22, 24, 26, 28, 30, 32, 34, 36, 38, 40}}}, -// {{{42, 44, 46, 48, 50, 52, 54, 56, 58, 60}}, -// {{62, 64, 66, 68, 70, 72, 74, 76, 78, 80}}}, -// {{{82, 84, 86, 88, 90, 92, 94, 96, 98, 100}}, -// {{102, 104, 106, 108, 110, 112, 114, 116, 118, 120}}}})); - -// nntrainer::Tensor ans_3_2_0( -// std::vector>>>( -// {{{{110}}, {{310}}}, {{{510}}, {{710}}}, {{{910}}, {{1110}}}})); - -// nntrainer::Tensor result_0_2_0 = input.sum(0, 2); -// nntrainer::Tensor result_1_2_0 = input.sum(1, 2); -// nntrainer::Tensor result_2_2_0 = input.sum(2, 2); -// nntrainer::Tensor result_3_2_0 = input.sum(3, 2); - -// EXPECT_EQ(ans_0_2_0, result_0_2_0); -// EXPECT_EQ(ans_1_2_0, result_1_2_0); -// EXPECT_EQ(ans_2_2_0, result_2_2_0); -// EXPECT_EQ(ans_3_2_0, result_3_2_0); -// } - -// // Test for alpha == 2 and beta == 2 -// { -// nntrainer::Tensor ans_0_2_2( -// std::vector>>>( -// {{{{128, 136, 144, 152, 160, 168, 176, 184, 192, 200}}, -// {{208, 216, 224, 232, 240, 248, 256, 264, 272, 280}}}})); - -// nntrainer::Tensor ans_1_2_2( -// std::vector>>>( -// {{{{26, 32, 38, 44, 50, 56, 62, 68, 74, 80}}}, -// {{{126, 132, 138, 144, 150, 156, 162, 168, 174, 180}}}, -// {{{226, 232, 238, 244, 250, 256, 262, 268, 274, 280}}}})); - -// nntrainer::Tensor ans_2_2_2( -// std::vector>>>( -// {{{{4, 8, 12, 16, 20, 24, 28, 32, 36, 40}}, -// {{44, 48, 52, 56, 60, 64, 68, 72, 76, 80}}}, -// {{{84, 88, 92, 96, 100, 104, 108, 112, 116, 120}}, -// {{124, 128, 132, 136, 140, 144, 148, 152, 156, 160}}}, -// {{{164, 168, 172, 176, 180, 184, 188, 192, 196, 200}}, -// {{204, 208, 212, 216, 220, 224, 228, 232, 236, 240}}}})); - -// nntrainer::Tensor ans_3_2_2( -// std::vector>>>( -// {{{{112}}, {{314}}}, {{{516}}, {{718}}}, {{{920}}, {{1122}}}})); - -// nntrainer::Tensor output_0_2_2(1, channel, height, width); -// { -// const int batch = 1; -// GEN_TEST_INPUT(output_0_2_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor output_1_2_2(batch, 1, height, width); -// { -// const int channel = 1; -// GEN_TEST_INPUT(output_1_2_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor output_2_2_2(batch, channel, 1, width); -// { -// const int height = 1; -// GEN_TEST_INPUT(output_2_2_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor output_3_2_2(batch, channel, height, 1); -// { -// const int width = 1; -// GEN_TEST_INPUT(output_3_2_2, i * (channel * height * width) + -// j * (height * width) + k * (width) + l + -// 1); -// } -// nntrainer::Tensor result_0_2_2 = input.sum(0, output_0_2_2, 2, 2); -// nntrainer::Tensor result_1_2_2 = input.sum(1, output_1_2_2, 2, 2); -// nntrainer::Tensor result_2_2_2 = input.sum(2, output_2_2_2, 2, 2); -// nntrainer::Tensor result_3_2_2 = input.sum(3, output_3_2_2, 2, 2); - -// EXPECT_EQ(ans_0_2_2, result_0_2_2); -// EXPECT_EQ(ans_1_2_2, result_1_2_2); -// EXPECT_EQ(ans_2_2_2, result_2_2_2); -// EXPECT_EQ(ans_3_2_2, result_3_2_2); -// } -// } - -// TEST(nntrainer_Tensor, sum_04_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 2; -// int height = 2; -// int width = 10; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (batch * height * channel) + j * (height * width) + -// k * width + l + 1); - -// nntrainer::Tensor result = input.sum_by_batch(); -// if (result.getValue(0, 0, 0, 0) != 820 || -// result.getValue(1, 0, 0, 0) != 1300 || -// result.getValue(2, 0, 0, 0) != 1780) -// status = ML_ERROR_RESULT_OUT_OF_RANGE; - -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, multiple_sum_invalid_args_01_n) { -// nntrainer::Tensor t = constant(1.0, 1, 1, 1, 1); -// EXPECT_THROW(t.sum(std::vector()), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, multiple_sum_out_of_range_n) { -// nntrainer::Tensor t = constant(1.0, 1, 1, 1, 1); -// EXPECT_THROW(t.sum({7}), std::out_of_range); -// } - -// TEST(nntrainer_Tensor, multiple_sum_p) { -// nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); -// nntrainer::Tensor actual, expected; - -// actual = t.sum({0, 1}); -// expected = constant(2 * 3, 1, 1, 5, 7); -// EXPECT_EQ(actual, expected); - -// actual = t.sum({1, 2, 3}); -// expected = constant(3 * 5 * 7, 2, 1, 1, 1); -// EXPECT_EQ(actual, expected); - -// actual = t.sum({3, 1}); -// expected = constant(7 * 3, 2, 1, 5, 1); -// EXPECT_EQ(actual, expected); - -// actual = t.sum({3, 1}, 0.5); -// expected = constant(7 * 3 * 0.5, 2, 1, 5, 1); -// EXPECT_EQ(actual, expected); -// } - -// TEST(nntrainer_Tensor, average_p) { -// nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); - -// nntrainer::Tensor actual, expected; - -// actual = t.average(); -// expected = constant(1.0, 1, 1, 1, 1); -// EXPECT_EQ(actual, expected); - -// int idx = 0; -// t = t.apply([&](__fp16 in) { return idx++ % 2; }); - -// actual = t.average(); -// expected = constant(0.5, 1, 1, 1, 1); -// EXPECT_EQ(actual, expected); -// } - -// TEST(nntrainer_Tensor, average_axis_p) { -// nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2); -// int idx = 0; -// std::function<__fp16(__fp16)> f = [&](__fp16 in) { return idx++ % 2; }; -// t = t.apply(f); - -// nntrainer::Tensor actual, expected; - -// actual = t.average(0); -// expected = constant(0, 1, 2, 2, 2).apply(f); -// EXPECT_EQ(actual, expected); - -// actual = t.average(1); -// expected = constant(0, 2, 1, 2, 2).apply(f); -// EXPECT_EQ(actual, expected); - -// actual = t.average(2); -// expected = constant(0, 2, 2, 1, 2).apply(f); -// EXPECT_EQ(actual, expected); - -// actual = t.average(3); -// expected = constant(0.5, 2, 2, 2, 1); -// EXPECT_EQ(actual, expected); -// } - -// TEST(nntrainer_Tensor, average_axis_out_of_range_01_n) { -// nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2); -// EXPECT_THROW(t.average(-1), std::out_of_range); -// } - -// TEST(nntrainer_Tensor, average_axis_out_of_range_02_n) { -// nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2); -// EXPECT_THROW(t.average(7), std::out_of_range); -// } - -// TEST(nntrainer_Tensor, average_multiple_axes_p) { -// nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); -// nntrainer::Tensor actual, expected; - -// actual = t.average({0, 1, 2}); -// expected = constant(1.0, 1, 1, 1, 7); -// EXPECT_EQ(actual, expected); - -// actual = t.average({0, 1, 2, 3}); -// expected = constant(1.0, 1, 1, 1, 1); -// EXPECT_EQ(actual, expected); - -// actual = t.average({3, 1}); -// expected = constant(1.0, 2, 1, 5, 1); -// EXPECT_EQ(actual, expected); - -// actual = t.average({3, 1, 1, 1, 3}); -// expected = constant(1.0, 2, 1, 5, 1); -// EXPECT_EQ(actual, expected); -// } - -// TEST(nntrainer_Tensor, average_multiple_axes_01_n) { -// nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7); -// EXPECT_THROW(t.average({5, 7}), std::out_of_range); -// } - -// TEST(nntrainer_Tensor, dot_01_n) { -// nntrainer::Tensor input(2, 3, 4, 5); -// nntrainer::Tensor m(1, 3, 4, 5); -// EXPECT_THROW(nntrainer::Tensor result = input.dot(m), std::runtime_error); -// } - -// TEST(nntrainer_Tensor, dot_02_n) { -// nntrainer::Tensor input(2, 3, 4, 5); -// nntrainer::Tensor m(1, 3, 4, 5); -// EXPECT_THROW(nntrainer::Tensor result = input.dot(m, true), -// std::runtime_error); -// } - -// TEST(nntrainer_Tensor, dot_02_p) { -// nntrainer::Tensor input(2, 3, 4, 5); -// nntrainer::Tensor m(1, 3, 4, 5); -// EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, false, true)); -// } - -// TEST(nntrainer_Tensor, dot_03_p) { -// nntrainer::Tensor input(1, 3, 4, 5); -// nntrainer::Tensor m(1, 3, 4, 5); -// EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, true)); -// } - -// TEST(nntrainer_Tensor, dot_04_n) { -// nntrainer::Tensor input(2, 3, 4, 5); -// nntrainer::Tensor m(1, 1, 4, 5); -// EXPECT_THROW(nntrainer::Tensor result = input.dot(m), std::runtime_error); -// EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, false, true)); -// } - -// TEST(nntrainer_Tensor, dot_05_p) { -// int status = ML_ERROR_NONE; -// int batch = 2; -// int channel = 3; -// int height = 4; -// int width = 5; -// __fp16 ans[2][3][4][24] = {0}; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (channel * width * height) + j * (height * width) + -// k * (width) + l + 1); -// nntrainer::Tensor weight(batch, channel, height, width); -// GEN_TEST_INPUT(weight, i * (channel * width * height) + j * (height * width) + -// k * (width) + l + 1); -// weight.reshape({1, 1, 24, 5}); - -// nntrainer::Tensor result = input.dot(weight, false, true); - -// for (int b = 0; b < batch; b++) { -// for (int c = 0; c < channel; c++) { -// for (int h = 0; h < height; h++) { -// for (int k = 0; k < batch * channel * height; k++) { -// ans[b][c][h][k] = 0; -// for (int w = 0; w < width; w++) { -// __fp16 val1 = input.getValue(b, c, h, w); -// __fp16 val2 = weight.getValue(0, 0, k, w); -// ans[b][c][h][k] += val1 * val2; -// } -// } -// } -// } -// } - -// for (unsigned int i = 0; i < result.batch(); ++i) { -// for (unsigned int c = 0; c < result.channel(); ++c) { -// for (unsigned int j = 0; j < result.height(); ++j) { -// for (unsigned int k = 0; k < result.width(); ++k) { -// __fp16 val1 = ans[i][c][j][k]; -// __fp16 val2 = result.getValue(i, c, j, k); -// if (val1 != val2) { -// status = ML_ERROR_RESULT_OUT_OF_RANGE; -// goto end_dot_01_p; -// } -// } -// } -// } -// } -// end_dot_01_p: -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, dot_06_p) { -// int status = ML_ERROR_NONE; -// int batch = 3; -// int channel = 1; -// int height = 1; -// int width = 3; -// __fp16 ans[3][1][1][3] = { -// {{{30, 36, 42}}}, {{{66, 81, 96}}}, {{{102, 126, 150}}}}; - -// nntrainer::Tensor input(batch, channel, height, width); -// GEN_TEST_INPUT(input, i * (channel * width * height) + j * (height * width) + -// k * (width) + l + 1); - -// nntrainer::Tensor result = input.dot(input); - -// for (unsigned int i = 0; i < result.batch(); ++i) { -// for (unsigned int j = 0; j < result.height(); ++j) { -// for (unsigned int k = 0; k < result.width(); ++k) { -// if (ans[i][0][j][k] != result.getValue(i, 0, j, k)) { -// status = ML_ERROR_RESULT_OUT_OF_RANGE; -// goto end_dot_01_p; -// } -// } -// } -// } -// end_dot_01_p: -// EXPECT_EQ(status, ML_ERROR_NONE); -// } - -// TEST(nntrainer_Tensor, dot_transpose_p) { -// { -// __fp16 a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, -// 92, 113, 134, 155, 128, 158, 188, 218}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, -// 92, 113, 134, 155, 128, 158, 188, 218}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, -// 92, 113, 134, 155, 128, 158, 188, 218}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92, -// 92, 113, 134, 155, 128, 158, 188, 218}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 1, 4, 2, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 1, 4, 2, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); -// __fp16 b_data[] = {0, 2, 4, 1, 3, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); -// __fp16 b_data[] = {0, 2, 4, 1, 3, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 1, 4, 2, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); -// __fp16 b_data[] = {0, 2, 4, 1, 3, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 1, 4, 2, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); -// __fp16 b_data[] = {0, 2, 4, 1, 3, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); -// __fp16 answer_data[] = {10, 13, 28, 40}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// } - -// TEST(nntrainer_Tensor, dot_shortcuts_p) { -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); -// __fp16 answer_data[] = {5}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); -// __fp16 answer_data[] = {5}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); -// __fp16 answer_data[] = {5}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); -// __fp16 answer_data[] = {5}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); -// __fp16 answer_data[] = {5, 14}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 1, 4, 2, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); -// __fp16 answer_data[] = {5, 14}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); -// __fp16 answer_data[] = {5, 14}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 1, 4, 2, 5}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); -// __fp16 answer_data[] = {5, 14}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); -// __fp16 answer_data[] = {5, 14, 23, 32}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data); -// __fp16 answer_data[] = {5, 14, 23, 32}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); -// __fp16 answer_data[] = {5, 14, 23, 32}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data); -// __fp16 b_data[] = {0, 1, 2}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data); -// __fp16 answer_data[] = {5, 14, 23, 32}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data); -// __fp16 answer_data[] = {20, 23, 26, 29}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); -// __fp16 answer_data[] = {10, 13}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 1, 2, 3, 4, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data); -// __fp16 answer_data[] = {10, 13}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, false); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data); -// __fp16 b_data[] = {0, 2, 4, 1, 3, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); -// __fp16 answer_data[] = {10, 13}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, false, true); -// EXPECT_EQ(ret, answer); -// } -// { -// __fp16 a_data[] = {0, 1, 2}; -// nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data); -// __fp16 b_data[] = {0, 2, 4, 1, 3, 5}; -// nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data); -// __fp16 answer_data[] = {10, 13}; -// nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data); -// nntrainer::Tensor ret = a.dot(b, true, true); -// EXPECT_EQ(ret, answer); -// } -// } - -// TEST(nntrainer_Tensor, transpose_p) { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); - -// /// plain transpose -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -// 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -// 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, -// 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -// 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, -// 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, -// 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, -// 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, -// 112, 113, 114, 115, 116, 117, 118, 119}; -// nntrainer::Tensor answer({3, 2, 4, 5}, answer_data); -// nntrainer::Tensor m = t.transpose("0:1:2"); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 5, 10, 15, 1, 6, 11, 16, 2, 7, 12, 17, 3, 8, -// 13, 18, 4, 9, 14, 19, 20, 25, 30, 35, 21, 26, 31, 36, -// 22, 27, 32, 37, 23, 28, 33, 38, 24, 29, 34, 39, 40, 45, -// 50, 55, 41, 46, 51, 56, 42, 47, 52, 57, 43, 48, 53, 58, -// 44, 49, 54, 59, 60, 65, 70, 75, 61, 66, 71, 76, 62, 67, -// 72, 77, 63, 68, 73, 78, 64, 69, 74, 79, 80, 85, 90, 95, -// 81, 86, 91, 96, 82, 87, 92, 97, 83, 88, 93, 98, 84, 89, -// 94, 99, 100, 105, 110, 115, 101, 106, 111, 116, 102, 107, 112, 117, -// 103, 108, 113, 118, 104, 109, 114, 119}; -// nntrainer::Tensor answer({3, 2, 5, 4}, answer_data); -// nntrainer::Tensor m = t.transpose("0:2:1"); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 5, 6, 7, 8, -// 9, 25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 30, 31, 32, -// 33, 34, 15, 16, 17, 18, 19, 35, 36, 37, 38, 39, 40, 41, -// 42, 43, 44, 60, 61, 62, 63, 64, 45, 46, 47, 48, 49, 65, -// 66, 67, 68, 69, 50, 51, 52, 53, 54, 70, 71, 72, 73, 74, -// 55, 56, 57, 58, 59, 75, 76, 77, 78, 79, 80, 81, 82, 83, -// 84, 100, 101, 102, 103, 104, 85, 86, 87, 88, 89, 105, 106, 107, -// 108, 109, 90, 91, 92, 93, 94, 110, 111, 112, 113, 114, 95, 96, -// 97, 98, 99, 115, 116, 117, 118, 119}; -// nntrainer::Tensor answer({3, 4, 2, 5}, answer_data); -// nntrainer::Tensor m = t.transpose("1:0:2"); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 20, 1, 21, 2, 22, 3, 23, 4, 24, 5, 25, 6, 26, 7, 27, -// 8, 28, 9, 29, 10, 30, 11, 31, 12, 32, 13, 33, 14, 34, 15, 35, -// 16, 36, 17, 37, 18, 38, 19, 39, 40, 60, 41, 61, 42, 62, 43, 63, -// 44, 64, 45, 65, 46, 66, 47, 67, 48, 68, 49, 69, 50, 70, 51, 71, -// 52, 72, 53, 73, 54, 74, 55, 75, 56, 76, 57, 77, 58, 78, 59, 79, -// 80, 100, 81, 101, 82, 102, 83, 103, 84, 104, 85, 105, 86, 106, 87, 107, -// 88, 108, 89, 109, 90, 110, 91, 111, 92, 112, 93, 113, 94, 114, 95, 115, -// 96, 116, 97, 117, 98, 118, 99, 119}; -// nntrainer::Tensor answer({3, 4, 5, 2}, answer_data); -// nntrainer::Tensor m = t.transpose("1:2:0"); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 5, 10, 15, 20, 25, 30, 35, 1, 6, 11, 16, 21, 26, 31, -// 36, 2, 7, 12, 17, 22, 27, 32, 37, 3, 8, 13, 18, 23, 28, -// 33, 38, 4, 9, 14, 19, 24, 29, 34, 39, 40, 45, 50, 55, 60, -// 65, 70, 75, 41, 46, 51, 56, 61, 66, 71, 76, 42, 47, 52, 57, -// 62, 67, 72, 77, 43, 48, 53, 58, 63, 68, 73, 78, 44, 49, 54, -// 59, 64, 69, 74, 79, 80, 85, 90, 95, 100, 105, 110, 115, 81, 86, -// 91, 96, 101, 106, 111, 116, 82, 87, 92, 97, 102, 107, 112, 117, 83, -// 88, 93, 98, 103, 108, 113, 118, 84, 89, 94, 99, 104, 109, 114, 119}; -// nntrainer::Tensor answer({3, 5, 2, 4}, answer_data); -// nntrainer::Tensor m = t.transpose("2:0:1"); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 20, 5, 25, 10, 30, 15, 35, 1, 21, 6, 26, 11, 31, 16, 36, -// 2, 22, 7, 27, 12, 32, 17, 37, 3, 23, 8, 28, 13, 33, 18, 38, -// 4, 24, 9, 29, 14, 34, 19, 39, 40, 60, 45, 65, 50, 70, 55, 75, -// 41, 61, 46, 66, 51, 71, 56, 76, 42, 62, 47, 67, 52, 72, 57, 77, -// 43, 63, 48, 68, 53, 73, 58, 78, 44, 64, 49, 69, 54, 74, 59, 79, -// 80, 100, 85, 105, 90, 110, 95, 115, 81, 101, 86, 106, 91, 111, 96, 116, -// 82, 102, 87, 107, 92, 112, 97, 117, 83, 103, 88, 108, 93, 113, 98, 118, -// 84, 104, 89, 109, 94, 114, 99, 119}; -// nntrainer::Tensor answer({3, 5, 4, 2}, answer_data); -// nntrainer::Tensor m = t.transpose("2:1:0"); -// EXPECT_EQ(answer, m); -// } - -// /// outplace transpose -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 2, 4, 5); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -// 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -// 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, -// 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -// 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, -// 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, -// 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, -// 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, -// 112, 113, 114, 115, 116, 117, 118, 119}; -// nntrainer::Tensor answer({3, 2, 4, 5}, answer_data); -// t.transpose("0:1:2", m); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 2, 5, 4); -// __fp16 answer_data[] = { -// 0, 5, 10, 15, 1, 6, 11, 16, 2, 7, 12, 17, 3, 8, -// 13, 18, 4, 9, 14, 19, 20, 25, 30, 35, 21, 26, 31, 36, -// 22, 27, 32, 37, 23, 28, 33, 38, 24, 29, 34, 39, 40, 45, -// 50, 55, 41, 46, 51, 56, 42, 47, 52, 57, 43, 48, 53, 58, -// 44, 49, 54, 59, 60, 65, 70, 75, 61, 66, 71, 76, 62, 67, -// 72, 77, 63, 68, 73, 78, 64, 69, 74, 79, 80, 85, 90, 95, -// 81, 86, 91, 96, 82, 87, 92, 97, 83, 88, 93, 98, 84, 89, -// 94, 99, 100, 105, 110, 115, 101, 106, 111, 116, 102, 107, 112, 117, -// 103, 108, 113, 118, 104, 109, 114, 119}; -// nntrainer::Tensor answer({3, 2, 5, 4}, answer_data); -// t.transpose("0:2:1", m); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 4, 2, 5); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 20, 21, 22, 23, 24, 5, 6, 7, 8, -// 9, 25, 26, 27, 28, 29, 10, 11, 12, 13, 14, 30, 31, 32, -// 33, 34, 15, 16, 17, 18, 19, 35, 36, 37, 38, 39, 40, 41, -// 42, 43, 44, 60, 61, 62, 63, 64, 45, 46, 47, 48, 49, 65, -// 66, 67, 68, 69, 50, 51, 52, 53, 54, 70, 71, 72, 73, 74, -// 55, 56, 57, 58, 59, 75, 76, 77, 78, 79, 80, 81, 82, 83, -// 84, 100, 101, 102, 103, 104, 85, 86, 87, 88, 89, 105, 106, 107, -// 108, 109, 90, 91, 92, 93, 94, 110, 111, 112, 113, 114, 95, 96, -// 97, 98, 99, 115, 116, 117, 118, 119}; -// nntrainer::Tensor answer({3, 4, 2, 5}, answer_data); -// t.transpose("1:0:2", m); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 4, 5, 2); -// __fp16 answer_data[] = { -// 0, 20, 1, 21, 2, 22, 3, 23, 4, 24, 5, 25, 6, 26, 7, 27, -// 8, 28, 9, 29, 10, 30, 11, 31, 12, 32, 13, 33, 14, 34, 15, 35, -// 16, 36, 17, 37, 18, 38, 19, 39, 40, 60, 41, 61, 42, 62, 43, 63, -// 44, 64, 45, 65, 46, 66, 47, 67, 48, 68, 49, 69, 50, 70, 51, 71, -// 52, 72, 53, 73, 54, 74, 55, 75, 56, 76, 57, 77, 58, 78, 59, 79, -// 80, 100, 81, 101, 82, 102, 83, 103, 84, 104, 85, 105, 86, 106, 87, 107, -// 88, 108, 89, 109, 90, 110, 91, 111, 92, 112, 93, 113, 94, 114, 95, 115, -// 96, 116, 97, 117, 98, 118, 99, 119}; -// nntrainer::Tensor answer({3, 4, 5, 2}, answer_data); -// t.transpose("1:2:0", m); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 5, 2, 4); -// __fp16 answer_data[] = { -// 0, 5, 10, 15, 20, 25, 30, 35, 1, 6, 11, 16, 21, 26, 31, -// 36, 2, 7, 12, 17, 22, 27, 32, 37, 3, 8, 13, 18, 23, 28, -// 33, 38, 4, 9, 14, 19, 24, 29, 34, 39, 40, 45, 50, 55, 60, -// 65, 70, 75, 41, 46, 51, 56, 61, 66, 71, 76, 42, 47, 52, 57, -// 62, 67, 72, 77, 43, 48, 53, 58, 63, 68, 73, 78, 44, 49, 54, -// 59, 64, 69, 74, 79, 80, 85, 90, 95, 100, 105, 110, 115, 81, 86, -// 91, 96, 101, 106, 111, 116, 82, 87, 92, 97, 102, 107, 112, 117, 83, -// 88, 93, 98, 103, 108, 113, 118, 84, 89, 94, 99, 104, 109, 114, 119}; -// nntrainer::Tensor answer({3, 5, 2, 4}, answer_data); -// t.transpose("2:0:1", m); -// EXPECT_EQ(answer, m); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// nntrainer::Tensor m = ranged(3, 5, 4, 2); -// __fp16 answer_data[] = { -// 0, 20, 5, 25, 10, 30, 15, 35, 1, 21, 6, 26, 11, 31, 16, 36, -// 2, 22, 7, 27, 12, 32, 17, 37, 3, 23, 8, 28, 13, 33, 18, 38, -// 4, 24, 9, 29, 14, 34, 19, 39, 40, 60, 45, 65, 50, 70, 55, 75, -// 41, 61, 46, 66, 51, 71, 56, 76, 42, 62, 47, 67, 52, 72, 57, 77, -// 43, 63, 48, 68, 53, 73, 58, 78, 44, 64, 49, 69, 54, 74, 59, 79, -// 80, 100, 85, 105, 90, 110, 95, 115, 81, 101, 86, 106, 91, 111, 96, 116, -// 82, 102, 87, 107, 92, 112, 97, 117, 83, 103, 88, 108, 93, 113, 98, 118, -// 84, 104, 89, 109, 94, 114, 99, 119}; -// nntrainer::Tensor answer({3, 5, 4, 2}, answer_data); -// t.transpose("2:1:0", m); -// EXPECT_EQ(answer, m); -// } -// } - -// TEST(nntrainer_Tensor, tranpose_dimension_not_match_n) { -// nntrainer::Tensor a(3, 2, 4, 5); -// nntrainer::Tensor b(3, 1, 2, 3); - -// EXPECT_THROW(a.transpose("0:1:2", b), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, set_01_p) { -// nntrainer::Tensor tensor = nntrainer::Tensor(1, 1, 1, 1); - -// tensor.setZero(); -// EXPECT_EQ(tensor.getValue(0, 0, 0, 0), 0.0); - -// tensor.setRandUniform(-0.5, 0); -// __fp16 val = tensor.getValue(0, 0, 0, 0); -// EXPECT_TRUE(val >= -0.5 && val < 0); -// } - -// TEST(nntrainer_Tensor, save_read_01_p) { -// int batch = 3; -// int channel = 4; -// int height = 5; -// int width = 6; -// nntrainer::Tensor target(3, 4, 5, 6); -// nntrainer::Tensor readed(3, 4, 5, 6); - -// GEN_TEST_INPUT(target, i * (channel * width * height) + j * (height * width) + -// k * (width) + l + 1); - -// std::ofstream save_file("save.bin", std::ios::out | std::ios::binary); -// target.save(save_file); -// save_file.close(); - -// std::ifstream read_file("save.bin"); -// readed.read(read_file); -// read_file.close(); - -// EXPECT_EQ(target, readed); - -// int status = std::remove("save.bin"); - -// ASSERT_EQ(status, 0); -// } - -// TEST(nntrainer_Tensor, save_read_01_n) { -// int batch = 3; -// int channel = 4; -// int height = 5; -// int width = 6; -// nntrainer::Tensor target(3, 4, 5, 6); -// nntrainer::Tensor readed(3, 4, 1, 1); - -// GEN_TEST_INPUT(target, i * (channel * width * height) + j * (height * width) + -// k * (width) + l + 1); - -// std::ofstream save_file("save.bin", std::ios::out | std::ios::binary); -// target.save(save_file); -// save_file.close(); - -// std::ifstream read_file("save.bin"); -// readed.read(read_file); -// read_file.close(); - -// EXPECT_NE(target, readed); - -// int status = std::remove("save.bin"); - -// ASSERT_EQ(status, 0); -// } - -// TEST(nntrainer_Tensor, copy_and_shares_variable_p) { -// nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); -// nntrainer::Tensor B = A.clone(); -// nntrainer::Tensor C = A; - -// C.setValue(1, 1, 1, 1, 2.0f); - -// EXPECT_EQ(A, C); -// EXPECT_NE(B, C); - -// C.reshape(nntrainer::TensorDim(3, 4, 6, 5)); -// EXPECT_EQ(A.getDim(), B.getDim()); -// EXPECT_NE(A.getDim(), C.getDim()); -// } - -// TEST(nntrainer_Tensor, reshape_n_01) { -// nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); - -// EXPECT_THROW(A.reshape(nntrainer::TensorDim(9, 9, 9, 9)), -// std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, reshape_n_02) { -// nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); -// nntrainer::TensorDim A_dim = A.getDim(); - -// /** Changing the dim of a tensor only affects local copy of the dim */ -// A_dim.setTensorDim(1, 100); -// EXPECT_EQ(A_dim.getTensorDim(1), 100u); - -// nntrainer::TensorDim A_dim_2 = A.getDim(); -// EXPECT_EQ(A_dim_2.getTensorDim(1), 4u); -// } - -// TEST(nntrainer_Tensor, copy_and_reshape_n) { -// nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); -// nntrainer::Tensor B = A; -// nntrainer::Tensor C = A.clone(); - -// EXPECT_THROW(B.reshape(nntrainer::TensorDim(9, 9, 9, 9)), -// std::invalid_argument); -// } - -// /// @note this test case demonstrates it is dangerous to use sharedConstTensor -// /// to const correct the inner data. -// TEST(nntrainer_Tensor, constructor_from_shared_const_ptr_shares_variable_n) { -// nntrainer::sharedConstTensor A = -// MAKE_SHARED_TENSOR(constant(1.0f, 3, 4, 5, 6)); - -// nntrainer::Tensor B = *A; -// nntrainer::Tensor C = A->clone(); - -// B.setValue(2, 3, 4, 5, 2.0f); -// EXPECT_EQ(*A, B); -// EXPECT_NE(*A, C); - -// C.reshape(nntrainer::TensorDim(3, 4, 6, 5)); -// EXPECT_EQ(A->getDim(), B.getDim()); -// EXPECT_NE(A->getDim(), C.getDim()); -// } - -// TEST(nntrainer_Tensor, print_small_size) { -// nntrainer::Tensor target = constant(1.0, 3, 1, 2, 3); - -// std::stringstream ss, expected; -// ss << target; - -// expected << '<' << typeid(target).name() << " at " << &target << ">\n" -// << "data addr: " << target.getData() << '\n' -// << "Shape: 3:1:2:3\n" -// << " 1 1 1 \n" -// << " 1 1 1 \n" -// << "\n" -// << "-------\n" -// << " 1 1 1 \n" -// << " 1 1 1 \n" -// << "\n" -// << "-------\n" -// << " 1 1 1 \n" -// << " 1 1 1 \n" -// << "\n" -// << "-------\n"; - -// EXPECT_EQ(ss.str(), expected.str()); -// } - -// // TEST(nntrainer_Tensor, print_large_size) { -// // nntrainer::Tensor target = constant(1.2, 3, 10, 10, 10); - -// // std::stringstream ss, expected; - -// // expected << '<' << typeid(target).name() << " at " << &target << ">\n" -// // << "data addr: " << target.getData() << '\n' -// // << "Shape: 3:10:10:10\n" -// // << "[1.2 1.2 1.2 ... 1.2 1.2 1.2]\n"; -// // ss << target; - -// // EXPECT_EQ(ss.str(), expected.str()); -// // } - -// TEST(nntrainer_Tensor, DISABLED_equation_test_01_p) { -// nntrainer::Tensor a, b, c; -// nntrainer::Tensor ret1, ret2; - -// a = randUniform(4, 6, 7, 3, -100, 100); -// b = randUniform(4, 6, 7, 3, -100, 100); -// c = randUniform(4, 6, 7, 3, -100, 100); - -// ret1 = a.subtract(b).multiply(c); -// ret2 = a.multiply(c).subtract(b.multiply(c)); - -// __fp16 *data1 = ret1.getData(); -// __fp16 *data2 = ret2.getData(); -// EXPECT_EQ(ret1, ret2); - -// for (unsigned int i = 0; i < ret1.size(); ++i) { -// EXPECT_FLOAT_EQ(data1[i], data2[i]); -// } -// } - -// TEST(nntrainer_Tensor, fill_p) { -// /// same dimension, buffer size -// { -// nntrainer::Tensor target(3, 2, 4, 5); -// nntrainer::Tensor original = randUniform(3, 2, 4, 5, -1.0f, 1.0f); -// target.fill(original, false); - -// EXPECT_EQ(target, original); -// } - -// /// same dimension, buffer size is different (not tested) -// { -// /// there is no way to make non contiguous tensor publicily yet -// EXPECT_TRUE(true); -// } - -// /// uninitialized with initialized flag is true -// { -// nntrainer::Tensor target; -// nntrainer::Tensor original = randUniform(3, 2, 4, 5, -1.0f, 1.0f); -// target.fill(original, true); - -// EXPECT_EQ(target, original); -// } -// } - -// TEST(nntrainer_Tensor, fill_uninitialized_n) { -// nntrainer::Tensor target; -// nntrainer::Tensor original = randUniform(3, 1, 2, 3, -1.0f, 1.0f); -// EXPECT_THROW(target.fill(original, false), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, fill_different_dimension_n) { -// nntrainer::Tensor target(3, 1, 3, 2); -// nntrainer::Tensor original = randUniform(3, 1, 2, 3, -1.0f, 1.0f); -// EXPECT_THROW(target.fill(original, false), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, DISABLED_fill_non_contiguous_n) { -// /// there is no way to make non contiguous tensor publicily yet -// EXPECT_TRUE(false); -// } - -// TEST(nntrainer_Tensor, DISABLED_fill_different_buffer_size_n) { -// /// there is no way to make same dimension, diffrent buffersized tensor -// /// publicily yet -// EXPECT_TRUE(false); -// } - -// TEST(nntrainer_Tensor, empty_01) { -// nntrainer::Tensor t; - -// EXPECT_TRUE(t.empty()); -// } - -// TEST(nntrainer_Tensor, empty_02) { -// nntrainer::Tensor t({1, 2, 3, 4}, false); - -// EXPECT_FALSE(t.empty()); -// } - -// TEST(nntrainer_Tensor, empty_03) { -// nntrainer::Tensor t({1, 2, 3, 4}, true); - -// EXPECT_FALSE(t.empty()); -// } - -// TEST(nntrainer_Tensor, allocate_01_n) { -// nntrainer::Tensor t; -// EXPECT_FALSE(t.isAllocated()); - -// t.allocate(); -// EXPECT_FALSE(t.isAllocated()); -// } - -// TEST(nntrainer_Tensor, allocate_02_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, false); -// EXPECT_FALSE(t.isAllocated()); - -// t.allocate(); -// EXPECT_TRUE(t.isAllocated()); -// } - -// TEST(nntrainer_Tensor, allocate_03_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, true); -// EXPECT_TRUE(t.isAllocated()); - -// t.allocate(); -// EXPECT_TRUE(t.isAllocated()); -// } - -// TEST(nntrainer_Tensor, initialize_01_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); - -// nntrainer::Tensor golden(1, 2, 3, 4); -// golden.setValue(1); - -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, initialize_02_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, true); - -// nntrainer::Tensor golden(1, 2, 3, 4); -// golden.setValue(1); - -// EXPECT_NE(golden, t); - -// t.initialize(nntrainer::Tensor::Initializer::ONES); -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, initialize_03_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, false, -// nntrainer::Tensor::Initializer::ONES); -// t.allocate(); - -// nntrainer::Tensor golden(1, 2, 3, 4); -// golden.setValue(1); - -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, initialize_04_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, false); -// t.initialize(nntrainer::Tensor::Initializer::ONES); -// t.allocate(); - -// nntrainer::Tensor golden(1, 2, 3, 4); -// golden.setValue(1); - -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, initialize_05_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, false); -// t.allocate(); - -// nntrainer::Tensor golden(1, 2, 3, 4); -// golden.setValue(1.f); - -// /** -// * Ideally, it should be NE, but it can be equal due to no initialization -// * EXPECT_NE(golden, t); -// */ - -// t.initialize(nntrainer::Tensor::Initializer::ONES); -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, initialize_06_n) { -// nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); -// nntrainer::Tensor golden({1, 2, 3, 4}, true, -// nntrainer::Tensor::Initializer::ZEROS); - -// EXPECT_NE(golden, t); - -// golden.initialize(nntrainer::Tensor::Initializer::ONES); -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, initialize_07_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); - -// nntrainer::Tensor golden(1, 2, 3, 4); -// golden.setValue(1); - -// EXPECT_EQ(golden, t); - -// t.setValue(0, 0, 0, 0, 0); -// t.setValue(0, 0, 0, t.size() - 1, 0); -// EXPECT_NE(golden, t); - -// t.initialize(); -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, initialize_08_p) { -// nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES); - -// nntrainer::Tensor golden(1, 2, 3, 4, nntrainer::Tformat::NCHW, nntrainer::DataType::FP32); -// golden.setValue(1); -// EXPECT_EQ(golden, t); - -// t.initialize(nntrainer::Tensor::Initializer::HE_NORMAL); -// EXPECT_NE(golden, t); - - -// t.initialize(); -// EXPECT_NE(golden, t); - -// t.initialize(nntrainer::Tensor::Initializer::ONES); -// EXPECT_EQ(golden, t); - -// t.initialize(); -// EXPECT_EQ(golden, t); -// } - -// TEST(nntrainer_Tensor, split_01_p) { -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(3); -// { -// __fp16 answer_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -// 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -// 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -// 30, 31, 32, 33, 34, 35, 36, 37, 38, 39}; -// answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); -// } -// { -// __fp16 answer_data[] = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, -// 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, -// 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, -// 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}; -// answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); -// } -// { -// __fp16 answer_data[] = {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -// 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, -// 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -// 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; -// answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); -// } -// EXPECT_EQ(t.split(3, 0), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(2); -// { -// __fp16 answer_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -// 12, 13, 14, 15, 16, 17, 18, 19, 40, 41, 42, 43, -// 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -// 56, 57, 58, 59, 80, 81, 82, 83, 84, 85, 86, 87, -// 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; -// answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); -// } -// { -// __fp16 answer_data[] = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -// 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -// 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, -// 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, -// 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -// 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); -// } -// EXPECT_EQ(t.split(2, 1), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(2); -// { -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, -// 25, 26, 27, 28, 29, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, -// 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 80, 81, 82, 83, 84, -// 85, 86, 87, 88, 89, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); -// } -// { -// __fp16 answer_data[] = { -// 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, -// 35, 36, 37, 38, 39, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, -// 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 90, 91, 92, 93, 94, -// 95, 96, 97, 98, 99, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); -// } -// EXPECT_EQ(t.split(2, 2), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(5); -// { -// __fp16 answer_data[] = {0, 5, 10, 15, 20, 25, 30, 35, -// 40, 45, 50, 55, 60, 65, 70, 75, -// 80, 85, 90, 95, 100, 105, 110, 115}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// { -// __fp16 answer_data[] = {1, 6, 11, 16, 21, 26, 31, 36, -// 41, 46, 51, 56, 61, 66, 71, 76, -// 81, 86, 91, 96, 101, 106, 111, 116}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// { -// __fp16 answer_data[] = {2, 7, 12, 17, 22, 27, 32, 37, -// 42, 47, 52, 57, 62, 67, 72, 77, -// 82, 87, 92, 97, 102, 107, 112, 117}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// { -// __fp16 answer_data[] = {3, 8, 13, 18, 23, 28, 33, 38, -// 43, 48, 53, 58, 63, 68, 73, 78, -// 83, 88, 93, 98, 103, 108, 113, 118}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// { -// __fp16 answer_data[] = {4, 9, 14, 19, 24, 29, 34, 39, -// 44, 49, 54, 59, 64, 69, 74, 79, -// 84, 89, 94, 99, 104, 109, 114, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// EXPECT_EQ(t.split(5, 3), answer); -// } -// { -// nntrainer::TensorDim ref_dim(1, 1, 4, 6); -// nntrainer::Tensor t = ranged(1, 1, 4, 6); -// std::vector answer; -// answer.reserve(2); -// { -// __fp16 answer_data[] = {0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20}; -// answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data); -// } -// { -// __fp16 answer_data[] = {3, 4, 5, 9, 10, 11, 15, 16, 17, 21, 22, 23}; -// answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data); -// } -// EXPECT_EQ(t.split(2, 3), answer); -// } -// } - -// TEST(nntrainer_Tensor, split_02_n) { -// nntrainer::Tensor t(1, 1, 1, 1); -// EXPECT_THROW(t.split(0, 0), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, split_03_n) { -// nntrainer::Tensor t(3, 1, 1, 1); -// EXPECT_THROW(t.split(2, 0), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, split_04_p) { -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(2); -// { -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -// 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -// 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, -// 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -// 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79}; -// answer.emplace_back(ml::train::TensorDim{2, 2, 4, 5}, answer_data); -// } -// { -// __fp16 answer_data[] = {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -// 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, -// 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -// 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; -// answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data); -// } -// EXPECT_EQ(t.split({2, 1}, 0), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(2); -// { -// __fp16 answer_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -// 12, 13, 14, 15, 16, 17, 18, 19, 40, 41, 42, 43, -// 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -// 56, 57, 58, 59, 80, 81, 82, 83, 84, 85, 86, 87, -// 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}; -// answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); -// } -// { -// __fp16 answer_data[] = {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -// 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -// 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, -// 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, -// 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -// 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data); -// } -// EXPECT_EQ(t.split({1, 1}, 1), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(2); -// { -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, -// 25, 26, 27, 28, 29, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, -// 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 80, 81, 82, 83, 84, -// 85, 86, 87, 88, 89, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); -// } -// { -// __fp16 answer_data[] = { -// 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 30, 31, 32, 33, 34, -// 35, 36, 37, 38, 39, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, -// 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 90, 91, 92, 93, 94, -// 95, 96, 97, 98, 99, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data); -// } -// EXPECT_EQ(t.split({2, 2}, 2), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(3); -// { -// __fp16 answer_data[] = {0, 5, 10, 15, 20, 25, 30, 35, -// 40, 45, 50, 55, 60, 65, 70, 75, -// 80, 85, 90, 95, 100, 105, 110, 115}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// { -// __fp16 answer_data[] = { -// 1, 2, 3, 6, 7, 8, 11, 12, 13, 16, 17, 18, 21, 22, 23, -// 26, 27, 28, 31, 32, 33, 36, 37, 38, 41, 42, 43, 46, 47, 48, -// 51, 52, 53, 56, 57, 58, 61, 62, 63, 66, 67, 68, 71, 72, 73, -// 76, 77, 78, 81, 82, 83, 86, 87, 88, 91, 92, 93, 96, 97, 98, -// 101, 102, 103, 106, 107, 108, 111, 112, 113, 116, 117, 118}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 3}, answer_data); -// } -// { -// __fp16 answer_data[] = {4, 9, 14, 19, 24, 29, 34, 39, -// 44, 49, 54, 59, 64, 69, 74, 79, -// 84, 89, 94, 99, 104, 109, 114, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// EXPECT_EQ(t.split({1, 3, 1}, 3), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(3); -// { -// __fp16 answer_data[] = { -// 0, 1, 5, 6, 10, 11, 15, 16, 20, 21, 25, 26, 30, 31, 35, 36, -// 40, 41, 45, 46, 50, 51, 55, 56, 60, 61, 65, 66, 70, 71, 75, 76, -// 80, 81, 85, 86, 90, 91, 95, 96, 100, 101, 105, 106, 110, 111, 115, 116}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data); -// } -// { -// __fp16 answer_data[] = { -// 2, 3, 7, 8, 12, 13, 17, 18, 22, 23, 27, 28, 32, 33, 37, 38, -// 42, 43, 47, 48, 52, 53, 57, 58, 62, 63, 67, 68, 72, 73, 77, 78, -// 82, 83, 87, 88, 92, 93, 97, 98, 102, 103, 107, 108, 112, 113, 117, 118}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data); -// } -// { -// __fp16 answer_data[] = {4, 9, 14, 19, 24, 29, 34, 39, -// 44, 49, 54, 59, 64, 69, 74, 79, -// 84, 89, 94, 99, 104, 109, 114, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data); -// } -// EXPECT_EQ(t.split({2, 2, 1}, 3), answer); -// } -// { -// nntrainer::TensorDim ref_dim(3, 2, 4, 5); -// nntrainer::Tensor t = ranged(3, 2, 4, 5); -// std::vector answer; -// answer.reserve(2); -// { -// __fp16 answer_data[] = { -// 0, 1, 5, 6, 10, 11, 15, 16, 20, 21, 25, 26, 30, 31, 35, 36, -// 40, 41, 45, 46, 50, 51, 55, 56, 60, 61, 65, 66, 70, 71, 75, 76, -// 80, 81, 85, 86, 90, 91, 95, 96, 100, 101, 105, 106, 110, 111, 115, 116}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data); -// } -// { -// __fp16 answer_data[] = { -// 2, 3, 4, 7, 8, 9, 12, 13, 14, 17, 18, 19, 22, 23, 24, -// 27, 28, 29, 32, 33, 34, 37, 38, 39, 42, 43, 44, 47, 48, 49, -// 52, 53, 54, 57, 58, 59, 62, 63, 64, 67, 68, 69, 72, 73, 74, -// 77, 78, 79, 82, 83, 84, 87, 88, 89, 92, 93, 94, 97, 98, 99, -// 102, 103, 104, 107, 108, 109, 112, 113, 114, 117, 118, 119}; -// answer.emplace_back(ml::train::TensorDim{3, 2, 4, 3}, answer_data); -// } -// EXPECT_EQ(t.split({2, 3}, 3), answer); -// } -// { -// nntrainer::TensorDim ref_dim(1, 1, 4, 6); -// nntrainer::Tensor t = ranged(1, 1, 4, 6); -// std::vector answer; -// answer.reserve(3); -// { -// __fp16 answer_data[] = {0, 6, 12, 18}; -// answer.emplace_back(ml::train::TensorDim{1, 1, 4, 1}, answer_data); -// } -// { -// __fp16 answer_data[] = {1, 2, 3, 7, 8, 9, 13, 14, 15, 19, 20, 21}; -// answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data); -// } -// { -// __fp16 answer_data[] = {4, 5, 10, 11, 16, 17, 22, 23}; -// answer.emplace_back(ml::train::TensorDim{1, 1, 4, 2}, answer_data); -// } -// EXPECT_EQ(t.split({1, 3, 2}, 3), answer); -// } -// } - -// TEST(nntrainer_Tensor, split_05_n) { -// nntrainer::Tensor t(3, 1, 1, 1); -// EXPECT_THROW(t.split({1, 1}, 0), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, split_06_n) { -// nntrainer::Tensor t(3, 1, 1, 1); -// EXPECT_THROW(t.split({2, 0, 1}, 0), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, split_07_n) { -// nntrainer::Tensor t(3, 1, 1, 1); -// EXPECT_THROW(t.split({}, 0), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, cat_01_p) { -// { -// std::vector inputs; -// inputs.reserve(2); -// inputs.emplace_back(ranged(2, 1, 1, 2)); -// inputs.emplace_back(ranged(2, 2, 1, 2)); -// __fp16 answer_data[] = {0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 6, 7}; -// nntrainer::Tensor answer(ml::train::TensorDim{2, 3, 1, 2}, answer_data); -// EXPECT_EQ(nntrainer::Tensor::cat(inputs, 1), answer); -// } -// { -// std::vector inputs; -// inputs.reserve(2); -// inputs.emplace_back(ranged(3, 2, 4, 5)); -// inputs.emplace_back(ranged(2, 2, 4, 5)); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -// 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -// 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -// 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, -// 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, -// 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -// 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, -// 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -// 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -// 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, -// 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, -// 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, -// 75, 76, 77, 78, 79}; -// nntrainer::Tensor answer(ml::train::TensorDim{5, 2, 4, 5}, answer_data); -// EXPECT_EQ(nntrainer::Tensor::cat(inputs, 0), answer); -// } -// { -// std::vector inputs; -// inputs.reserve(2); -// inputs.emplace_back(ranged(3, 3, 4, 5)); -// inputs.emplace_back(ranged(3, 2, 4, 5)); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -// 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -// 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, -// 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -// 56, 57, 58, 59, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -// 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, -// 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, -// 38, 39, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, -// 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, -// 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, -// 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, -// 114, 115, 116, 117, 118, 119, 40, 41, 42, 43, 44, 45, 46, 47, -// 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -// 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, -// 76, 77, 78, 79, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, -// 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, -// 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, -// 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, -// 172, 173, 174, 175, 176, 177, 178, 179, 80, 81, 82, 83, 84, 85, -// 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, -// 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, -// 114, 115, 116, 117, 118, 119}; -// nntrainer::Tensor answer(ml::train::TensorDim{3, 5, 4, 5}, answer_data); -// EXPECT_EQ(nntrainer::Tensor::cat(inputs, 1), answer); -// } -// { -// std::vector inputs; -// inputs.reserve(2); -// inputs.emplace_back(ranged(3, 2, 1, 5)); -// inputs.emplace_back(ranged(3, 2, 2, 5)); -// __fp16 answer_data[] = { -// 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, -// 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 20, -// 21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 30, 31, 32, 33, -// 34, 35, 36, 37, 38, 39, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 45, 46, -// 47, 48, 49, 25, 26, 27, 28, 29, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}; -// nntrainer::Tensor answer(ml::train::TensorDim{3, 2, 3, 5}, answer_data); -// EXPECT_EQ(nntrainer::Tensor::cat(inputs, 2), answer); -// } -// { -// std::vector inputs; -// inputs.reserve(3); -// inputs.emplace_back(ranged(3, 2, 4, 1)); -// inputs.emplace_back(ranged(3, 2, 4, 3)); -// inputs.emplace_back(ranged(3, 2, 4, 2)); -// __fp16 answer_data[] = { -// 0, 0, 1, 2, 0, 1, 1, 3, 4, 5, 2, 3, 2, 6, 7, 8, 4, 5, -// 3, 9, 10, 11, 6, 7, 4, 12, 13, 14, 8, 9, 5, 15, 16, 17, 10, 11, -// 6, 18, 19, 20, 12, 13, 7, 21, 22, 23, 14, 15, 8, 24, 25, 26, 16, 17, -// 9, 27, 28, 29, 18, 19, 10, 30, 31, 32, 20, 21, 11, 33, 34, 35, 22, 23, -// 12, 36, 37, 38, 24, 25, 13, 39, 40, 41, 26, 27, 14, 42, 43, 44, 28, 29, -// 15, 45, 46, 47, 30, 31, 16, 48, 49, 50, 32, 33, 17, 51, 52, 53, 34, 35, -// 18, 54, 55, 56, 36, 37, 19, 57, 58, 59, 38, 39, 20, 60, 61, 62, 40, 41, -// 21, 63, 64, 65, 42, 43, 22, 66, 67, 68, 44, 45, 23, 69, 70, 71, 46, 47}; -// nntrainer::Tensor answer(ml::train::TensorDim{3, 2, 4, 6}, answer_data); -// EXPECT_EQ(nntrainer::Tensor::cat(inputs, 3), answer); -// } -// } - -// TEST(nntrainer_Tensor, cat_02_n) { -// { -// std::vector inputs; -// inputs.reserve(2); -// inputs.emplace_back(nntrainer::Tensor(2, 1, 1, 2)); -// inputs.emplace_back(nntrainer::Tensor(2, 2, 1, 2)); -// EXPECT_THROW(nntrainer::Tensor::cat(inputs, 2), std::invalid_argument); -// } -// } - -// TEST(nntrainer_Tensor, zoneout_mask_01_n) { -// const __fp16 zoneout_rate = 0.3f; -// nntrainer::Tensor t(10, 10, 10, 10); -// nntrainer::Tensor opposite(20, 20, 20, 20); -// EXPECT_THROW(t.zoneout_mask(opposite, zoneout_rate), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, zoneout_mask_02_p) { -// const __fp16 zoneout_rate = 0.3f; -// nntrainer::Tensor t(10, 10, 10, 10); -// nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate); -// constexpr __fp16 epsilon = 1e-3; - -// EXPECT_EQ(t.size(), opposite.size()); - -// auto is_near = [epsilon](__fp16 val1, __fp16 val2) { -// return val2 - epsilon < val1 && val1 < val2 + epsilon; -// }; - -// for (unsigned int i = 0; i < opposite.size(); ++i) { -// if (is_near(opposite.getValue(i), 0.0f)) { -// EXPECT_NEAR(t.getValue(i), 1.0f, epsilon); -// } else if (is_near(opposite.getValue(i), 1.0f)) { -// EXPECT_NEAR(t.getValue(i), 0.0f, epsilon); -// } else { -// FAIL() << "This should not be happen"; -// } -// } -// } - -// TEST(nntrainer_Tensor, zoneout_mask_03_p) { -// const __fp16 zoneout_rate = 0.3f; -// nntrainer::Tensor t(10, 10, 100, 100); -// nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate); -// constexpr __fp16 epsilon = 1e-3; - -// auto is_near = [epsilon](__fp16 val1, __fp16 val2) { -// return val2 - epsilon < val1 && val1 < val2 + epsilon; -// }; -// auto percentage = [](unsigned int dividend, unsigned int divisor) { -// return (__fp16)dividend / (__fp16)divisor; -// }; - -// { -// unsigned int zeros = 0; -// unsigned int ones = 0; -// for (unsigned int i = 0; i < opposite.size(); ++i) { -// if (is_near(opposite.getValue(i), 0.0f)) { -// ++zeros; -// } else if (is_near(opposite.getValue(i), 1.0f)) { -// ++ones; -// } else { -// FAIL() << "This should not be happen"; -// } -// } -// EXPECT_NEAR(percentage(zeros, opposite.size()), 1.0f - zoneout_rate, -// epsilon); - -// // main test -// EXPECT_NEAR(percentage(ones, opposite.size()), zoneout_rate, epsilon); -// } - -// { -// unsigned int zeros = 0; -// unsigned int ones = 0; -// for (unsigned int i = 0; i < t.size(); ++i) { -// if (is_near(t.getValue(i), 0.0f)) { -// ++zeros; -// } else if (is_near(t.getValue(i), 1.0f)) { -// ++ones; -// } else { -// FAIL() << "This should not be happen"; -// } -// } -// EXPECT_NEAR(percentage(zeros, t.size()), zoneout_rate, epsilon); - -// // main test -// EXPECT_NEAR(percentage(ones, t.size()), 1.0f - zoneout_rate, epsilon); -// } -// } - -// TEST(nntrainer_Tensor, zoneout_mask_04_n) { -// const __fp16 zoneout_rate = 0.3f; -// nntrainer::Tensor t(10, 10, 100, 100); -// nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate); -// constexpr __fp16 epsilon = 1e-3; - -// auto is_near = [epsilon](__fp16 val1, __fp16 val2) { -// return val2 - epsilon < val1 && val1 < val2 + epsilon; -// }; -// auto percentage = [](unsigned int dividend, unsigned int divisor) { -// return (__fp16)dividend / (__fp16)divisor; -// }; - -// { -// unsigned int zeros = 0; -// unsigned int ones = 0; -// for (unsigned int i = 0; i < opposite.size(); ++i) { -// if (is_near(opposite.getValue(i), 0.0f)) { -// ++zeros; -// } else if (is_near(opposite.getValue(i), 1.0f)) { -// ++ones; -// } else { -// FAIL() << "This should not be happen"; -// } -// } -// EXPECT_FALSE( -// is_near(percentage(ones, opposite.size()), 1.0f - zoneout_rate)); -// } - -// { -// unsigned int zeros = 0; -// unsigned int ones = 0; -// for (unsigned int i = 0; i < t.size(); ++i) { -// if (is_near(t.getValue(i), 0.0f)) { -// ++zeros; -// } else if (is_near(t.getValue(i), 1.0f)) { -// ++ones; -// } else { -// FAIL() << "This should not be happen"; -// } -// } -// EXPECT_FALSE(is_near(percentage(ones, t.size()), zoneout_rate)); -// } -// } - -// TEST(nntrainer_Tensor, TensorMap_p) { -// __fp16 dat[] = {1, 2, 3}; - -// { -// nntrainer::Tensor a = nntrainer::Tensor::Map(dat, 3 * sizeof(__fp16), {3}); -// /// check if a.getData() has same address with dat -// EXPECT_EQ(dat, a.getData()); -// { -// /// check if b.getData() has same address with data -// nntrainer::Tensor b = a; -// EXPECT_EQ(dat, b.getData()); -// } -// } -// /// check if dat is accessible after destruction of all the tensor -// EXPECT_FLOAT_EQ(dat[2], 3); -// } - -// TEST(nntrainer_Tensor, TensorWrap_01_n) { -// __fp16 dat[] = {1, 2, 3}; -// EXPECT_THROW(nntrainer::Tensor::Map(dat, 3, nntrainer::TensorDim({})), -// std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, TensorWrap_02_n) { -// __fp16 dat[] = {1, 2, 3}; -// EXPECT_THROW(nntrainer::Tensor::Map(dat, 3, {4}), std::invalid_argument); -// } - -// TEST(nntrainer_Tensor, TensorPaddedValue_p) { -// nntrainer::Tensor a = ranged(1, 1, 3, 3); -// __fp16 default_padded = -1; - -// for (int i = 0; i < 5; ++i) { -// for (int j = 0; j < 5; ++j) { -// __fp16 expected = default_padded; -// if (1 <= i && i <= 3 && 1 <= j && j <= 3) { -// expected = (i - 1) * 3 + (j - 1); -// } -// __fp16 actual = a.getValuePaddedVirtual<__fp16>(0, 0, i, j, 1, 1, default_padded); -// EXPECT_FLOAT_EQ(actual, expected); -// } -// } -// } - -// GTEST_API_ 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; -// } diff --git a/test/unittest/meson.build b/test/unittest/meson.build index 0846cc1..15d00d8 100644 --- a/test/unittest/meson.build +++ b/test/unittest/meson.build @@ -37,7 +37,6 @@ test_target = [ ['unittest_nntrainer_internal', []], ['unittest_nntrainer_lazy_tensor', []], ['unittest_nntrainer_tensor', []], - ['unittest_nntrainer_tensor_fp16', []], ['unittest_nntrainer_tensor_nhwc', []], ['unittest_util_func', []], ['unittest_nntrainer_modelfile', []], @@ -53,6 +52,10 @@ test_target = [ ['unittest_nntrainer_task', []], ] +if get_option('enable-fp16') + test_target += [['unittest_nntrainer_tensor_fp16', []]] +endif + if get_option('enable-profile') if gmock_dep.version().version_compare('>=1.10.0') test_target += [['unittest_nntrainer_profiler', []]] diff --git a/test/unittest/unittest_nntrainer_tensor_pool.cpp b/test/unittest/unittest_nntrainer_tensor_pool.cpp index f449ecc..20f8028 100644 --- a/test/unittest/unittest_nntrainer_tensor_pool.cpp +++ b/test/unittest/unittest_nntrainer_tensor_pool.cpp @@ -395,8 +395,8 @@ TEST(TensorPool, allocate_deallocate_03_p) { EXPECT_TRUE(t2->isAllocated()); EXPECT_TRUE(t3->isAllocated()); - EXPECT_EQ(t1->getData(), t2->getData()); - EXPECT_EQ(t1->getData(), t3->getData()); + EXPECT_EQ(t1->getData(), t2->getData()); + EXPECT_EQ(t1->getData(), t3->getData()); EXPECT_NO_THROW(pool.deallocate()); EXPECT_FALSE(t1->isAllocated()); @@ -441,11 +441,11 @@ TEST(TensorPool, validate_memory) { * @param t2 tensor2 */ static void testNoOverlap(nntrainer::Tensor *t1, nntrainer::Tensor *t2) { - char *t1_start = t1->getData(); - char *t1_end = t1_start + t1->bytes(); + float *t1_start = t1->getData(); + float *t1_end = t1_start + t1->size(); - char *t2_start = t2->getData(); - char *t2_end = t2_start + t2->bytes(); + float *t2_start = t2->getData(); + float *t2_end = t2_start + t2->size(); EXPECT_NE(t1_start, nullptr); EXPECT_NE(t2_start, nullptr); @@ -460,11 +460,11 @@ static void testNoOverlap(nntrainer::Tensor *t1, nntrainer::Tensor *t2) { * @param t2 t2 tensor 2 */ static void testSubset(nntrainer::Tensor *t1, nntrainer::Tensor *t2) { - char *t1_start = t1->getData(); - char *t1_end = t1_start + t1->bytes(); + float *t1_start = t1->getData(); + float *t1_end = t1_start + t1->size(); - char *t2_start = t2->getData(); - char *t2_end = t2_start + t2->bytes(); + float *t2_start = t2->getData(); + float *t2_end = t2_start + t2->size(); EXPECT_NE(t1_start, nullptr); EXPECT_NE(t2_start, nullptr); @@ -519,7 +519,7 @@ TEST(TensorPool, view_is_same_p) { EXPECT_NE(t1, t2); EXPECT_EQ(t1->getDim(), t2->getDim()); - EXPECT_EQ(t1->getData(), t2->getData()); + EXPECT_EQ(t1->getData(), t2->getData()); pool.deallocate(); } @@ -593,8 +593,8 @@ TEST(TensorPool, view_of_placeholder_p) { pool.allocate(); EXPECT_NE(t1, t2); - EXPECT_EQ(t1->getData(), nullptr); - EXPECT_EQ(t2->getData(), nullptr); + EXPECT_EQ(t1->getData(), nullptr); + EXPECT_EQ(t2->getData(), nullptr); /// t_original: 0 1 2 3 4 5 6 7 8 9 /// t1 : 0 1 2 3 4 5 6 7 8 9 @@ -609,8 +609,8 @@ TEST(TensorPool, view_of_placeholder_p) { testSubset(t1, t3); EXPECT_EQ(*t1, t_original); - EXPECT_FLOAT_EQ(*t2->getData(), 1.0f); - EXPECT_FLOAT_EQ(*t3->getData(), 3.0f); + EXPECT_FLOAT_EQ(t2->getData()[0], 1.0f); + EXPECT_FLOAT_EQ(t3->getData()[0], 3.0f); pool.deallocate(); } -- 2.7.4