From 11669e49af771ec9325d2ea894f32306c92a48d0 Mon Sep 17 00:00:00 2001 From: Donghyeon Jeong Date: Wed, 16 Oct 2024 16:37:29 +0900 Subject: [PATCH] [Test] Add unit tests for newly added tensor type This PR adds unit tests for the recently implemented tensor data types. The purpose is to ensure their functionality and correctness by performing various test cases. **Changes proposed in this PR:** - Added unit tests to test functions for CharTensor and ShortTensor - Check if both tensor data are contiguous before copy() **Self-evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: Donghyeon Jeong --- nntrainer/tensor/tensor.cpp | 2 +- test/unittest/unittest_nntrainer_tensor.cpp | 588 ++++++++++++++++++-- 2 files changed, 546 insertions(+), 44 deletions(-) diff --git a/nntrainer/tensor/tensor.cpp b/nntrainer/tensor/tensor.cpp index 5c38fcf093..00d7ee0ebd 100644 --- a/nntrainer/tensor/tensor.cpp +++ b/nntrainer/tensor/tensor.cpp @@ -898,7 +898,7 @@ size_t Tensor::getOffset() const { return itensor->getOffset(); } void Tensor::copy(const Tensor &from) { /// @todo enable copy to non-contiguous tensor - if (!itensor->getContiguous()) { + if (!itensor->getContiguous() || !from.getContiguous()) { throw std::runtime_error("Cannot copy non-contiguous tensor"); } diff --git a/test/unittest/unittest_nntrainer_tensor.cpp b/test/unittest/unittest_nntrainer_tensor.cpp index 0d6d47be37..cdfe0a659f 100644 --- a/test/unittest/unittest_nntrainer_tensor.cpp +++ b/test/unittest/unittest_nntrainer_tensor.cpp @@ -130,46 +130,27 @@ TEST(nntrainer_Tensor, Tensor_01_p) { EXPECT_EQ(status, ML_ERROR_NONE); } -// TEST(nntrainer_Tensor, Tensor_02_p) { -// int status = ML_ERROR_NONE; -// int height = 3; -// int width = 10; -// std::vector> 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_02_nhwc_p) { -// int status = ML_ERROR_NONE; -// int width = 10; -// int channel = 3; -// std::vector> in; -// for (int i = 0; i < width; ++i) { -// std::vector tv; -// for (int j = 0; j < channel; ++j) { -// tv.push_back(i * 2.0 + j); -// } -// in.push_back(tv); -// } +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, NHWC_); -// ASSERT_NE(nullptr, tensor.getData()); + nntrainer::Tensor tensor = nntrainer::Tensor( + in, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::FP32}); + 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); + 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; @@ -220,7 +201,7 @@ TEST(nntrainer_Tensor, Tensor_04_p) { nntrainer::Tensor tensor = nntrainer::Tensor( in, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}); - ASSERT_NE(nullptr, tensor.getData()); + ASSERT_NE(nullptr, tensor.getData(0)); if (tensor.getValue(0, 0, 0, 1) != 1) status = ML_ERROR_INVALID_PARAMETER; @@ -236,7 +217,7 @@ TEST(nntrainer_Tensor, Tensor_05_p) { nntrainer::Tensor tensor = nntrainer::Tensor( in, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}); - ASSERT_NE(nullptr, tensor.getData()); + ASSERT_NE(nullptr, tensor.getData(0)); for (size_t b = 0; b < tensor.batch(); ++b) { for (size_t c = 0; c < tensor.channel(); ++c) { @@ -270,6 +251,316 @@ TEST(nntrainer_Tensor, Tensor_05_p) { // } // } +TEST(nntrainer_Tensor, Tensor_07_n) { + 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; + ttv.push_back(tv); + } + in.push_back(ttv); + } + + EXPECT_THROW(nntrainer::Tensor( + in, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::FP32}), + std::out_of_range); +} + +TEST(nntrainer_Tensor, Tensor_08_n) { + 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; + ttv.push_back(tv); + } + in.push_back(ttv); + } + + EXPECT_THROW(nntrainer::Tensor( + in, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}), + std::out_of_range); +} + +TEST(nntrainer_Tensor, Tensor_09_n) { + 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; + ttv.push_back(tv); + } + in.push_back(ttv); + } + + EXPECT_THROW(nntrainer::Tensor( + in, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}), + std::out_of_range); +} + +TEST(nntrainer_Tensor, copy_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); + + nntrainer::Tensor output(batch, channel, height, width); + + // use copy() to copy non-contiguous tensor + EXPECT_THROW(output.copy(input.getSharedDataTensor({3, 1, 3, 5}, 0, false)), + std::runtime_error); +} + +TEST(nntrainer_Tensor, copy_02_n) { + int batch = 3; + int channel = 1; + int height = 3; + int width = 10; + + nntrainer::Tensor input( + batch, channel, height, width, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output( + batch, channel, height, width, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}); + + // use copy() to copy non-contiguous tensor + EXPECT_THROW(output.copy(input.getSharedDataTensor({3, 1, 3, 5}, 0, false)), + std::runtime_error); +} + +TEST(nntrainer_Tensor, copy_03_n) { + int batch = 3; + int channel = 1; + int height = 3; + int width = 10; + + nntrainer::Tensor input( + batch, channel, height, width, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output( + batch, channel, height, width, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}); + + // use copy() to copy non-contiguous tensor + EXPECT_THROW(output.copy(input.getSharedDataTensor({3, 1, 3, 5}, 0, false)), + std::runtime_error); +} + +TEST(nntrainer_Tensor, copy_04_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); + + nntrainer::Tensor output(batch, channel, width, height); + output.copy(input); + + EXPECT_EQ(input, output); +} + +TEST(nntrainer_Tensor, copy_05_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::Tdatatype::QINT8}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output( + batch, channel, height, width, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}); + + output.copy(input); + + ASSERT_EQ(input, output); +} + +TEST(nntrainer_Tensor, copy_06_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::Tdatatype::UINT16}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output( + batch, channel, height, width, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}); + + output.copy(input); + + ASSERT_EQ(input, output); +} + +TEST(nntrainer_Tensor, copy_07_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 output( + batch, channel, height, width, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}); + + input.copyData(output); + + ASSERT_NE(input, output); + + for (unsigned int idx = 0; idx < input.size(); ++idx) { + if ((int)input.getValue(idx) != output.getValue(idx)) + status = ML_ERROR_RESULT_OUT_OF_RANGE; + } + + EXPECT_EQ(status, ML_ERROR_NONE); +} + +TEST(nntrainer_Tensor, copy_08_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::Tdatatype::QINT8}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output(batch, channel, height, width); + + // Currently, CharTensor does not support copyData of a different data type + EXPECT_THROW(input.copyData(output), std::invalid_argument); +} + +TEST(nntrainer_Tensor, copy_09_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::Tdatatype::UINT16}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output(batch, channel, height, width); + + // Currently, UINT Tensor does not support copyData of a different data type + EXPECT_THROW(input.copyData(output), std::invalid_argument); +} + +TEST(nntrainer_Tensor, copy_10_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::Tdatatype::QINT8}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output( + batch, channel, height, width / 2, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}); + + EXPECT_NO_THROW(output.copy_with_stride(input.getSharedDataTensor( + {3, 1, 3, 5, nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}, 0, + false))); + + for (unsigned int b = 0; b < output.batch(); ++b) { + for (unsigned int c = 0; c < output.channel(); ++c) { + for (unsigned int h = 0; h < output.height(); ++h) { + for (unsigned int w = 0; w < output.width(); ++w) { + if (input.getValue(b, c, h, w) != + output.getValue(b, c, h, w)) { + status = ML_ERROR_RESULT_OUT_OF_RANGE; + } + } + } + } + } + + EXPECT_EQ(status, ML_ERROR_NONE); +} + +TEST(nntrainer_Tensor, copy_11_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::Tdatatype::UINT16}); + GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k); + + nntrainer::Tensor output( + batch, channel, height, width / 2, + {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}); + + EXPECT_NO_THROW(output.copy_with_stride(input.getSharedDataTensor( + {3, 1, 3, 5, nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}, 0, + false))); + + for (unsigned int b = 0; b < output.batch(); ++b) { + for (unsigned int c = 0; c < output.channel(); ++c) { + for (unsigned int h = 0; h < output.height(); ++h) { + for (unsigned int w = 0; w < output.width(); ++w) { + if (input.getValue(b, c, h, w) != + output.getValue(b, c, h, w)) { + status = ML_ERROR_RESULT_OUT_OF_RANGE; + } + } + } + } + } + + EXPECT_EQ(status, ML_ERROR_NONE); +} + TEST(nntrainer_Tensor, multiply_i_01_p) { int status = ML_ERROR_NONE; int batch = 3; @@ -1642,7 +1933,6 @@ TEST(nntrainer_Tensor, add_08_n) { } TEST(nntrainer_Tensor, pow_01_p) { - nntrainer::Tensor input = constant(4.0, 3, 2, 4, 5); nntrainer::Tensor actual, expected; @@ -3131,6 +3421,96 @@ TEST(nntrainer_Tensor, save_read_01_n) { ASSERT_EQ(status, 0); } +TEST(nntrainer_Tensor, max_element_01_p) { + int batch = 3; + int channel = 1; + int height = 5; + int width = 6; + nntrainer::Tensor target(3, 1, 5, 6, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::QINT8); + + GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 - k * i); + + EXPECT_EQ(target.argmax(), std::vector({24, 0, 0})); +} + +TEST(nntrainer_Tensor, max_element_02_p) { + int batch = 3; + int channel = 1; + int height = 5; + int width = 6; + nntrainer::Tensor target(3, 1, 5, 6, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::UINT16); + + GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 - k * i); + + EXPECT_EQ(target.argmax(), std::vector({24, 0, 0})); +} + +TEST(nntrainer_Tensor, max_element_03_p) { + int batch = 3; + int channel = 1; + int height = 5; + int width = 6; + nntrainer::Tensor target(3, 1, 5, 6, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::QINT8); + + GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 - k * i); + + EXPECT_EQ(target.max_abs(), 31); +} + +TEST(nntrainer_Tensor, max_element_04_p) { + int batch = 3; + int channel = 1; + int height = 5; + int width = 6; + nntrainer::Tensor target(3, 1, 5, 6, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::UINT16); + + GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 - k * i); + + EXPECT_EQ(target.max_abs(), 31); +} + +TEST(nntrainer_Tensor, min_element_01_p) { + int batch = 3; + int channel = 1; + int height = 5; + int width = 1; + nntrainer::Tensor target(3, 1, 5, 1, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::QINT8); + + GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 - k * i); + + EXPECT_EQ(target.minValue(), 1); + + for (int idx = 0; idx < height; ++idx) { + target.addValue(0, 0, idx, 0, 15.5f, 1.0f); + } + + EXPECT_EQ(target.minValue(), 16); +} + +TEST(nntrainer_Tensor, min_element_02_p) { + int batch = 3; + int channel = 1; + int height = 5; + int width = 1; + nntrainer::Tensor target(3, 1, 5, 1, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::UINT16); + + GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1); + + EXPECT_EQ(target.minValue(), 1); + + for (int idx = 0; idx < height; ++idx) { + target.addValue(0, 0, idx, 0, 15.5f, 1.0f); + } + + EXPECT_EQ(target.minValue(), 16); +} + TEST(nntrainer_Tensor, copy_and_shares_variable_01_p) { nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6); nntrainer::Tensor B = A.clone(); @@ -3147,6 +3527,23 @@ TEST(nntrainer_Tensor, copy_and_shares_variable_01_p) { } TEST(nntrainer_Tensor, copy_and_shares_variable_02_p) { + nntrainer::Tensor A = constant(10, 3, 4, 5, 6, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::QINT8); + nntrainer::Tensor B = A.clone(); + nntrainer::Tensor C = A; + + C.setValue(1, 1, 1, 1, 9); + + EXPECT_EQ(A, C); + EXPECT_NE(B, C); + + C.reshape(nntrainer::TensorDim(3, 4, 6, 5, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::QINT8)); + EXPECT_EQ(A.getDim(), B.getDim()); + EXPECT_NE(A.getDim(), C.getDim()); +} + +TEST(nntrainer_Tensor, copy_and_shares_variable_03_p) { nntrainer::Tensor A = constant(10, 3, 4, 5, 6, nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16); nntrainer::Tensor B = A.clone(); @@ -3209,7 +3606,7 @@ TEST(nntrainer_Tensor, constructor_from_shared_const_ptr_shares_variable_n) { EXPECT_NE(A->getDim(), C.getDim()); } -TEST(nntrainer_Tensor, print_small_size) { +TEST(nntrainer_Tensor, print_small_size_01) { nntrainer::Tensor target = constant(1.0, 3, 1, 2, 3); std::stringstream ss, expected; @@ -3234,7 +3631,65 @@ TEST(nntrainer_Tensor, print_small_size) { EXPECT_EQ(ss.str(), expected.str()); } -TEST(nntrainer_Tensor, print_large_size) { +TEST(nntrainer_Tensor, print_small_size_02) { + nntrainer::Tensor target = constant(1.0, 4, 1, 3, 2, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::QINT8); + + std::stringstream ss, expected; + ss << target; + + expected << '<' << typeid(target).name() << " at " << &target << ">\n" + << "data addr: " << target.getData() << '\n' + << "Shape: 4:1:3:2 [ QINT8 : NCHW ]\n" + << " 1 1 \n" + << " 1 1 \n" + << " 1 1 \n" + << "\n" + << "-------\n" + << " 1 1 \n" + << " 1 1 \n" + << " 1 1 \n" + << "\n" + << "-------\n" + << " 1 1 \n" + << " 1 1 \n" + << " 1 1 \n" + << "\n" + << "-------\n" + << " 1 1 \n" + << " 1 1 \n" + << " 1 1 \n" + << "\n" + << "-------\n"; + + EXPECT_EQ(ss.str(), expected.str()); +} + +TEST(nntrainer_Tensor, print_small_size_03) { + nntrainer::Tensor target = constant(1.0, 2, 1, 3, 3, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::UINT16); + + std::stringstream ss, expected; + ss << target; + + expected << '<' << typeid(target).name() << " at " << &target << ">\n" + << "data addr: " << target.getData() << '\n' + << "Shape: 2:1:3:3 [ UINT16 : NCHW ]\n" + << " 1 1 1 \n" + << " 1 1 1 \n" + << " 1 1 1 \n" + << "\n" + << "-------\n" + << " 1 1 1 \n" + << " 1 1 1 \n" + << " 1 1 1 \n" + << "\n" + << "-------\n"; + + EXPECT_EQ(ss.str(), expected.str()); +} + +TEST(nntrainer_Tensor, print_large_size_01) { nntrainer::Tensor target = constant(1.2, 3, 10, 10, 10); std::stringstream ss, expected; @@ -3248,6 +3703,37 @@ TEST(nntrainer_Tensor, print_large_size) { EXPECT_EQ(ss.str(), expected.str()); } +TEST(nntrainer_Tensor, print_large_size_02) { + nntrainer::Tensor target = constant( + 7, 3, 3, 256, 256, nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8); + + std::stringstream ss, expected; + + expected << '<' << typeid(target).name() << " at " << &target << ">\n" + << "data addr: " << target.getData() << '\n' + << "Shape: 3:3:256:256 [ QINT8 : NCHW ]\n" + << "[7 7 7 ... 7 7 7]\n"; + ss << target; + + EXPECT_EQ(ss.str(), expected.str()); +} + +TEST(nntrainer_Tensor, print_large_size_03) { + nntrainer::Tensor target = + constant(165, 1, 3, 128, 512, nntrainer::Tformat::NCHW, + nntrainer::Tdatatype::UINT16); + + std::stringstream ss, expected; + + expected << '<' << typeid(target).name() << " at " << &target << ">\n" + << "data addr: " << target.getData() << '\n' + << "Shape: 1:3:128:512 [ UINT16 : NCHW ]\n" + << "[165 165 165 ... 165 165 165]\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; @@ -3367,6 +3853,9 @@ TEST(nntrainer_Tensor, allocate_04_p) { t.allocate(); EXPECT_TRUE(t.isAllocated()); + + t.deallocate(); + EXPECT_FALSE(t.isAllocated()); } TEST(nntrainer_Tensor, allocate_05_p) { @@ -3377,6 +3866,9 @@ TEST(nntrainer_Tensor, allocate_05_p) { t.allocate(); EXPECT_TRUE(t.isAllocated()); + + t.deallocate(); + EXPECT_FALSE(t.isAllocated()); } TEST(nntrainer_Tensor, initialize_01_p) { @@ -3509,6 +4001,16 @@ TEST(nntrainer_Tensor, initialize_10_p) { } TEST(nntrainer_Tensor, initialize_11_n) { + nntrainer::Tensor t( + {1, 2, 3, 4, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::QINT8}}, + true); + + /// @note CharTensor does not support HE_NORMAL initialization + EXPECT_THROW(t.initialize(nntrainer::Initializer::HE_NORMAL), + std::invalid_argument); +} + +TEST(nntrainer_Tensor, initialize_12_n) { nntrainer::Tensor t( {1, 2, 3, 4, {nntrainer::Tformat::NCHW, nntrainer::Tdatatype::UINT16}}, true);