void sizeCheckedReadTensor(nntrainer::Tensor &t, std::ifstream &file,
const std::string &error_msg = "");
+template <typename Ta = float, typename Tb = float>
+double cosine_similarity(Ta *A /*Predict*/, Tb *B /*Reference */,
+ uint32_t size) {
+ double dot = 0.0, denom_a = 0.0, denom_b = 0.0;
+ for (uint32_t i = 0u; i < size; ++i) {
+ Ta pred = A[i];
+ Tb ref = B[i];
+ dot += pred * ref;
+ denom_a += pred * pred;
+ denom_b += ref * ref;
+ }
+
+ double cosine_sim = dot / (sqrt(denom_a) * sqrt(denom_b));
+ return cosine_sim;
+}
+
+template <typename Ta = float, typename Tb = float>
+float mse(Ta *A /* Predicted */, Tb *B /* Reference */, uint32_t size) {
+ Ta pred;
+ Tb ref;
+ float mse_error = 0;
+ for (int i = 0; i < size; i++) {
+ pred = A[i];
+ ref = B[i];
+ float diff = pred - ref;
+ mse_error += pow(diff, 2);
+ }
+ float mse = mse_error / size;
+ return mse;
+}
+
#endif /* __cplusplus */
#endif /* __NNTRAINER_TEST_UTIL_H__ */
endif
ifndef NNTRAINER_ROOT
-NNTRAINER_ROOT := $(LOCAL_PATH)/../../..
+NNTRAINER_ROOT := $(LOCAL_PATH)/../..
endif
ML_API_COMMON_INCLUDES := ${NNTRAINER_ROOT}/ml_api_common/include
include $(BUILD_EXECUTABLE)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := unittest_nntrainer_tensor_neon_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 -DENABLE_FP16=1
+LOCAL_CXXFLAGS += -std=c++17 -frtti -fexceptions
+LOCAL_LDLIBS := -llog -landroid -fopenmp -static-openmp
+
+LOCAL_SRC_FILES := \
+ ../unittest/unittest_nntrainer_tensor_neon_fp16.cpp
+
+LOCAL_C_INCLUDES += $(NNTRAINER_INCLUDES)
+
+LOCAL_SHARED_LIBRARIES := nntrainer ccapi-nntrainer
+LOCAL_STATIC_LIBRARIES := googletest_main test_util
+include $(BUILD_EXECUTABLE)
+
+
# include $(CLEAR_VARS)
# LOCAL_MODULE := unittest_ccapi
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0
+/**
+ * Copyright (C) 2023 Debadri Samaddar <s.debadri@samsung.com>
+ *
+ * @file unittest_nntrainer_tensor_neon_fp16.cpp
+ * @date 03 August 2023
+ * @brief Unit test utility for tensor with NEON __fp16 support for ARM.
+ * @see https://github.com/nnstreamer/nntrainer
+ * @author Debadri Samaddar <s.debadri@samsung.com>
+ * @bug No known bugs
+ */
+#include <gtest/gtest.h>
+
+#include "nntrainer_test_util.h"
+#include "util_func.h"
+#include <cmath>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <nntrainer_error.h>
+#include <tensor.h>
+#include <tensor_dim.h>
+
+#define EXPECT_IN_RANGE(VAL, MIN, MAX) \
+ EXPECT_GE((VAL), (MIN)); \
+ EXPECT_LE((VAL), (MAX))
+
+TEST(nntrainer_Tensor, add_i) {
+ int batch = 1;
+ int channel = 1;
+ int height = 2;
+ int width = 11;
+
+ nntrainer::TensorDim::TensorType t_type_nchw_fp16 = {
+ nntrainer::Tformat::NCHW, nntrainer::Tdatatype::FP16};
+
+ nntrainer::TensorDim::TensorType t_type_nchw_fp32 = {
+ nntrainer::Tformat::NCHW, nntrainer::Tdatatype::FP32};
+
+ nntrainer::Tensor input(batch, channel, height, width, t_type_nchw_fp16);
+ nntrainer::Tensor input_copy(batch, channel, height, width, t_type_nchw_fp16);
+ nntrainer::Tensor input_fp32(batch, channel, height, width, t_type_nchw_fp32);
+
+ const float alpha = 1e-5;
+ const float epsilon = 1e-4;
+
+ GEN_TEST_INPUT(input, i * (batch * height * channel) * alpha +
+ j * (batch * height) * alpha + k * (width)*alpha + l +
+ 1);
+ GEN_TEST_INPUT(input_copy, i * (batch * height * channel) * alpha +
+ j * (batch * height) * alpha +
+ k * (width)*alpha + l + 1);
+ GEN_TEST_INPUT(input_fp32, i * (batch * height * channel) * alpha +
+ j * (batch * height) * alpha +
+ k * (width)*alpha + l + 1);
+
+ // NEON fp16
+ int result = input.add_i(input_copy);
+
+ // fp32
+ result = input_fp32.add_i(input_fp32);
+
+ float mseErrorNeon = mse<__fp16>(input.getData<__fp16>(),
+ input_fp32.getData<float>(), input.size());
+
+ double cosSimNeon = cosine_similarity<__fp16>(
+ input.getData<__fp16>(), input_fp32.getData<float>(), input.size());
+
+ EXPECT_IN_RANGE(mseErrorNeon, 0, epsilon);
+ EXPECT_IN_RANGE(cosSimNeon, 0.99, 1);
+}
+
+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;
+}