diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/FloatCastKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/FloatCastKernel.h new file mode 100644 index 00000000000..e1d4085455a --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/FloatCastKernel.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef LUCI_INTERPRETER_TEST_MODELS_FLOAT_CAST_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_FLOAT_CAST_KERNEL_H + +#include "TestDataCastBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace cast_float +{ +/* + * Cast Kernel: + * + * Input(1, 3, 3, 2) - Float + * | + * Cast + * | + * Output(1, 3, 3, 2) - Int + */ +const unsigned char test_kernel_model_circle[] = { + 0x18, 0x00, 0x00, 0x00, 0x43, 0x49, 0x52, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, + 0xfc, 0xff, 0xff, 0xff, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x35, 0x11, 0x00, 0x00, 0x00, 0x4f, 0x4e, 0x45, 0x2d, 0x74, 0x66, 0x6c, 0x69, + 0x74, 0x65, 0x32, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00}; + +const std::vector input_data = {-17.791723, -85.53769, 37.783722, -90.81935, 17.43155, + 44.95357, 51.40224, 90.3479, 23.142117, -31.959887, + -1.5401196, -64.85761, 53.559418, -52.90431, 25.37937, + -71.28326, -63.8249, -5.807645}; + +const std::vector reference_output_data = {-17, -85, 37, -90, 17, 44, 51, 90, 23, + -31, -1, -64, 53, -52, 25, -71, -63, -5}; + +} // namespace cast_float + +class TestDataFloatCast : public TestDataCastBase +{ +public: + TestDataFloatCast() + { + _input_data = cast_float::input_data; + _reference_output_data = cast_float::reference_output_data; + _test_kernel_model_circle = cast_float::test_kernel_model_circle; + } + + ~TestDataFloatCast() override = default; +}; + +} // namespace test_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_FLOAT_CAST_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/NegCastKernel.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/NegCastKernel.h new file mode 100644 index 00000000000..b45f0860bfe --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/NegCastKernel.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef LUCI_INTERPRETER_TEST_MODELS_NEG_CAST_KERNEL_H +#define LUCI_INTERPRETER_TEST_MODELS_NEG_CAST_KERNEL_H + +#include "luci_interpreter/test_models/TestDataBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ +namespace neg_input_output_shape_mismatch_cast_kernel +{ +/* + * Cast Kernel with input output shape mismatch: + * + * Input(1, 1, 3, 3, 2) - Float32 + * | + * Cast + * | + * Output(1, 3, 3, 2) - Int32 + */ +const unsigned char test_kernel_model_circle[] = { + 0x18, 0x00, 0x00, 0x00, 0x43, 0x49, 0x52, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, + 0xfc, 0xff, 0xff, 0xff, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0c, 0x00, + 0x08, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x14, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x6f, 0x66, 0x6d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x10, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x66, 0x6d, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x11, 0x00, 0x00, 0x00, 0x4f, 0x4e, 0x45, 0x2d, + 0x74, 0x66, 0x6c, 0x69, 0x74, 0x65, 0x32, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x00, 0x00, 0x00}; + +} // namespace neg_input_output_shape_mismatch_cast_kernel + +class NegTestDataInputOutputShapeMismatchCeilKernel : public NegTestDataBase +{ +public: + NegTestDataInputOutputShapeMismatchCeilKernel() + { + _test_kernel_model_circle = + neg_input_output_shape_mismatch_cast_kernel::test_kernel_model_circle; + } + + ~NegTestDataInputOutputShapeMismatchCeilKernel() override = default; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + +protected: + const unsigned char *_test_kernel_model_circle; +}; + +} // namespace test_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_NEG_CAST_KERNEL_H diff --git a/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/TestDataCastBase.h b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/TestDataCastBase.h new file mode 100644 index 00000000000..42e2a9eba9f --- /dev/null +++ b/onert-micro/luci-interpreter/include/luci_interpreter/test_models/cast/TestDataCastBase.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef LUCI_INTERPRETER_TEST_MODELS_CAST_KERNEL_BASE_H +#define LUCI_INTERPRETER_TEST_MODELS_CAST_KERNEL_BASE_H + +#include "luci_interpreter/test_models/TestDataBase.h" + +namespace luci_interpreter +{ +namespace test_kernel +{ + +template class TestDataCastBase : public TestDataBase +{ +public: + TestDataCastBase() = default; + + const unsigned char *get_model_ptr() override final { return _test_kernel_model_circle; } + + const std::vector &get_input_data_by_index(int i) override final + { + switch (i) + { + case 0: + return _input_data; + default: + assert(false && "Wrong input index"); + } + } + + const std::vector &get_output_data_by_index(int i) override final + { + assert(i == 0); + return _reference_output_data; + } + +protected: + std::vector _input_data; + std::vector _reference_output_data; + const unsigned char *_test_kernel_model_circle; +}; + +} // namespace test_kernel +} // namespace luci_interpreter + +#endif // LUCI_INTERPRETER_TEST_MODELS_CAST_KERNEL_BASE_H diff --git a/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst b/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst index 6a303ac7eda..04825abf679 100644 --- a/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst +++ b/onert-micro/luci-interpreter/pal/cmsisnn/KernelsToBuild.lst @@ -5,6 +5,7 @@ REGISTER_KERNEL(ARG_MAX, ArgMax) REGISTER_KERNEL(ARG_MIN, ArgMin) REGISTER_KERNEL(BATCH_TO_SPACE_ND, BatchToSpaceND) REGISTER_KERNEL(CEIL, Ceil) +REGISTER_KERNEL(CAST, Cast) REGISTER_KERNEL(DIV, Div) REGISTER_KERNEL(DEPTH_TO_SPACE, DepthToSpace) REGISTER_KERNEL(DEQUANTIZE, Dequantize) diff --git a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst index d346de45f1f..e67897239f5 100644 --- a/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst +++ b/onert-micro/luci-interpreter/pal/mcu/KernelsToBuild.lst @@ -5,6 +5,7 @@ REGISTER_KERNEL(ARG_MAX, ArgMax) REGISTER_KERNEL(ARG_MIN, ArgMin) REGISTER_KERNEL(BATCH_TO_SPACE_ND, BatchToSpaceND) REGISTER_KERNEL(CEIL, Ceil) +REGISTER_KERNEL(CAST, Cast) REGISTER_KERNEL(DIV, Div) REGISTER_KERNEL(DEPTHWISE_CONV_2D, DepthwiseConv2D) REGISTER_KERNEL(DEPTH_TO_SPACE, DepthToSpace) diff --git a/onert-micro/luci-interpreter/src/kernels/Cast.cpp b/onert-micro/luci-interpreter/src/kernels/Cast.cpp index 82b187a1d14..c336c792aba 100644 --- a/onert-micro/luci-interpreter/src/kernels/Cast.cpp +++ b/onert-micro/luci-interpreter/src/kernels/Cast.cpp @@ -15,130 +15,69 @@ * limitations under the License. */ -#include "kernels/Cast.h" +#include "Builders.h" #include "kernels/Utils.h" +#include "SISOKernel.h" +namespace luci_interpreter +{ namespace { -using namespace luci_interpreter; -using namespace luci_interpreter::kernels; - -template -void cast_data(const InT *in_data, OutT *out_data, uint32_t elements_count) +template void copyCast(const FromT *in, ToT *out, int num_elements) { - std::transform(in_data, in_data + elements_count, out_data, - [](InT a) { return static_cast(a); }); + std::transform(in, in + num_elements, out, [](FromT a) { return static_cast(a); }); } -template void cast_from_pointer_to_tensor(const InT *in_data, Tensor *out_tensor) -{ - auto const out_type = out_tensor->element_type(); - auto const elements_count = out_tensor->shape().num_elements(); - - switch (out_type) - { - case DataType::U8: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::U16: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::U32: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::U64: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::S8: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::S16: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::S32: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::S64: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::FLOAT32: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - case DataType::BOOL: - cast_data(in_data, getTensorData(out_tensor), elements_count); - break; - default: - assert(false && "Unsupported output type."); - } -} +} // namespace -void cast_from_tensor_to_tensor(const Tensor *in_tensor, Tensor *out_tensor) +void configure_kernel_CircleCast(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph) { - auto in_type = in_tensor->element_type(); + kernels::SISOKernel kernel(cur_op, runtime_graph); - switch (in_type) - { - case DataType::U8: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::U16: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::U32: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::U64: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::S8: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::S16: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::S32: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::S64: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::FLOAT32: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - case DataType::BOOL: - cast_from_pointer_to_tensor(getTensorData(in_tensor), out_tensor); - break; - default: - assert(false && "Unsupported input type."); - } + LUCI_INTERPRETER_CHECK(Tensor::num_elements(kernel.input()) == + Tensor::num_elements(kernel.output())); + LUCI_INTERPRETER_CHECK(Tensor::num_dims(kernel.input()) == Tensor::num_dims(kernel.output())); } -} // namespace - -namespace luci_interpreter -{ -namespace kernels +void execute_kernel_CircleCast(const circle::Operator *cur_op, BaseRuntimeGraph *runtime_graph) { + kernels::SISOKernel kernel(cur_op, runtime_graph); -Cast::Cast(const Tensor *input, Tensor *output) : Kernel({input}, {output}) {} + const auto *input_data = runtime_graph->getDataByTensor(kernel.input()); + assert(input_data); -void Cast::configure() -{ - LUCI_INTERPRETER_CHECK(input()->element_type() != DataType::Unknown); - LUCI_INTERPRETER_CHECK(output()->element_type() != DataType::Unknown); - - const Shape &shape = input()->shape(); - // TODO: enable it only if kernel with dynamic shapes - output()->resize(shape); -} + auto *output_data = runtime_graph->getDataByTensor(kernel.output()); + assert(output_data); -void Cast::execute() const -{ - assert(input()->shape().num_elements() == output()->shape().num_elements()); + const int flat_size = kernels::getTensorRuntimeShape(kernel.input(), runtime_graph).flatSize(); - cast_from_tensor_to_tensor(input(), output()); + switch (Tensor::element_type(kernel.input())) + { +#ifndef DIS_FLOAT + case DataType::FLOAT32: + { + const float *input_data_float = kernels::getTensorData(input_data); + + switch (Tensor::element_type(kernel.output())) + { + case DataType::S8: + copyCast(input_data_float, kernels::getTensorData(output_data), flat_size); + break; + case DataType::S16: + copyCast(input_data_float, kernels::getTensorData(output_data), flat_size); + break; + case DataType::S32: + copyCast(input_data_float, kernels::getTensorData(output_data), flat_size); + break; + default: + assert(false && "Not supported type"); + } + break; + } +#endif // DIS_FLOAT + default: + assert(false && "Unsupported type"); + } } - -} // namespace kernels } // namespace luci_interpreter diff --git a/onert-micro/luci-interpreter/src/kernels/Cast.h b/onert-micro/luci-interpreter/src/kernels/Cast.h deleted file mode 100644 index f0bd020378a..00000000000 --- a/onert-micro/luci-interpreter/src/kernels/Cast.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef LUCI_INTERPRETER_KERNELS_CAST_H -#define LUCI_INTERPRETER_KERNELS_CAST_H - -#include "core/Kernel.h" -#include "core/KernelParams.h" - -namespace luci_interpreter -{ -namespace kernels -{ - -class Cast : public Kernel -{ -public: - Cast(const Tensor *input, Tensor *output); - - const Tensor *input() const { return _inputs[0]; } - Tensor *output() const { return _outputs[0]; } - - void configure() override; - void execute() const override; -}; - -} // namespace kernels -} // namespace luci_interpreter - -#endif // LUCI_INTERPRETER_KERNELS_CAST_H diff --git a/onert-micro/luci-interpreter/src/kernels/Cast.test.cpp b/onert-micro/luci-interpreter/src/kernels/Cast.test.cpp index 4713ad34c95..c352654f14a 100644 --- a/onert-micro/luci-interpreter/src/kernels/Cast.test.cpp +++ b/onert-micro/luci-interpreter/src/kernels/Cast.test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. All Rights Reserved + * Copyright (c) 2023 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. @@ -14,228 +14,73 @@ * limitations under the License. */ -#include "kernels/Cast.h" #include "kernels/TestUtils.h" -#include "luci_interpreter/TestMemoryManager.h" +#include "luci_interpreter/test_models/cast/FloatCastKernel.h" +#include "luci_interpreter/test_models/cast/NegCastKernel.h" + +#include "loader/ModuleLoader.h" namespace luci_interpreter { -namespace kernels -{ namespace { using namespace testing; -template -void Check(std::initializer_list shape, std::initializer_list input_data, - std::initializer_list output_data) -{ - std::unique_ptr memory_manager = std::make_unique(); - constexpr DataType input_type = getElementType(); - constexpr DataType output_type = getElementType(); - - Tensor input_tensor = makeInputTensor(shape, input_data, memory_manager.get()); - Tensor output_tensor = makeOutputTensor(output_type); - - Cast kernel(&input_tensor, &output_tensor); - kernel.configure(); - memory_manager->allocate_memory(output_tensor); - kernel.execute(); - - EXPECT_THAT(extractTensorData(output_tensor), ::testing::ElementsAreArray(output_data)); - EXPECT_THAT(extractTensorShape(output_tensor), shape); -} - -template -void CheckBoolTo(std::initializer_list shape, std::initializer_list input_data, - std::initializer_list output_data) -{ - std::unique_ptr memory_manager = std::make_unique(); - constexpr DataType input_type = loco::DataType::BOOL; - constexpr DataType output_type = getElementType(); - std::vector::Type> input_data_converted; - for (auto elem : input_data) - { - input_data_converted.push_back(elem); - } - - Tensor input_tensor = - makeInputTensor(shape, input_data_converted, memory_manager.get()); - Tensor output_tensor = makeOutputTensor(output_type); - - Cast kernel(&input_tensor, &output_tensor); - kernel.configure(); - memory_manager->allocate_memory(output_tensor); - kernel.execute(); - - EXPECT_THAT(extractTensorData(output_tensor), ::testing::ElementsAreArray(output_data)); - EXPECT_THAT(extractTensorShape(output_tensor), shape); -} - -template class CastTest : public ::testing::Test +class CastTest : public ::testing::Test { + // Do nothing }; -using IntDataTypes = - ::testing::Types; -TYPED_TEST_SUITE(CastTest, IntDataTypes); - -TYPED_TEST(CastTest, FloatToInt) -{ - Check(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - 1.0f, 9.0f, 7.0f, 3.0f, // - }, - /*output_data=*/ - { - 1, 9, 7, 3, // - }); - SUCCEED(); -} - -TYPED_TEST(CastTest, IntToFloat) +template +std::vector checkCastKernel(test_kernel::TestDataBase *test_data_base) { - Check(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - 1, 9, 7, 3, // - }, - /*output_data=*/ - { - 1.0f, 9.0f, 7.0f, 3.0f, // - }); - SUCCEED(); -} - -template void check_int() -{ - Check(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - 1, 9, 7, 3, // - }, - /*output_data=*/ - { - 1, 9, 7, 3, // - }); - SUCCEED(); -} + MemoryManager memory_manager{}; + RuntimeModule runtime_module{}; + bool dealloc_input = true; -TYPED_TEST(CastTest, IntToInt) -{ - check_int(); - check_int(); - check_int(); - check_int(); - check_int(); - check_int(); - check_int(); - check_int(); - SUCCEED(); -} + // Load model with single op + auto *model_data_raw = reinterpret_cast(test_data_base->get_model_ptr()); + ModuleLoader::load(&runtime_module, &memory_manager, model_data_raw, dealloc_input); -TYPED_TEST(CastTest, IntToBool) -{ - Check(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - 1, 0, 7, 0, // - }, - /*output_data=*/ - { - true, false, true, false, // - }); - SUCCEED(); -} + auto *main_runtime_graph = runtime_module.getMainGraph(); + assert(main_runtime_graph->getNumOfInputTensors() == 1); -TYPED_TEST(CastTest, BoolToInt) -{ - CheckBoolTo(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - true, false, false, true, // - }, - /*output_data=*/ - { - 1, 0, 0, 1, // - }); - SUCCEED(); -} + // Set input data + { + auto *input_tensor_data = reinterpret_cast(main_runtime_graph->configureGraphInput(0)); + std::copy(test_data_base->get_input_data_by_index(0).begin(), + test_data_base->get_input_data_by_index(0).end(), input_tensor_data); + } -TEST(CastTest, FloatToBool) -{ - Check(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - 1.0f, 0.0f, 7.0f, 0.0f, // - }, - /*output_data=*/ - { - true, false, true, false, // - }); - SUCCEED(); -} + runtime_module.execute(); -TEST(CastTest, BoolToFloat) -{ - CheckBoolTo(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - true, false, false, true, // - }, - /*output_data=*/ - { - 1.0f, 0.0f, 0.0f, 1.0f, // - }); - SUCCEED(); -} + assert(main_runtime_graph->getNumOfOutputTensors() == 1); -TEST(CastTest, FloatToFloat) -{ - Check(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - 1.0f, 0.0f, 7.0f, 0.0f, // - }, - /*output_data=*/ - { - 1.0f, 0.0f, 7.0f, 0.0f, // - }); - SUCCEED(); + U *output_data = reinterpret_cast(main_runtime_graph->getOutputDataByIndex(0)); + const size_t num_elements = (main_runtime_graph->getOutputDataSizeByIndex(0) / sizeof(U)); + std::vector output_data_vector(output_data, output_data + num_elements); + return output_data_vector; } -TEST(CastTest, BoolToBool) +TEST_F(CastTest, Float_P) { - CheckBoolTo(/*shape=*/{1, 1, 1, 4}, - /*input_data=*/ - { - true, true, false, false, // - }, - /*output_data=*/ - { - true, true, false, false, // - }); - SUCCEED(); + test_kernel::TestDataFloatCast test_data_kernel; + std::vector output_data_vector = checkCastKernel(&test_data_kernel); + EXPECT_THAT(output_data_vector, test_data_kernel.get_output_data_by_index(0)); } -TEST(CastTest, UnsupportedType_NEG) +TEST_F(CastTest, Input_output_type_mismatch_NEG) { - std::unique_ptr memory_manager = std::make_unique(); - Tensor input_tensor = makeInputTensor({1, 1, 2, 4}, - { - 1, 2, 7, 8, // - 1, 9, 7, 3, // - }, - memory_manager.get()); - Tensor output_tensor = makeOutputTensor(DataType::Unknown); - - Cast kernel(&input_tensor, &output_tensor); - EXPECT_ANY_THROW(kernel.configure()); - SUCCEED(); + test_kernel::NegTestDataInputOutputShapeMismatchCeilKernel test_data_kernel; + MemoryManager memory_manager{}; + RuntimeModule runtime_module{}; + bool dealloc_input = true; + // Load model with single op + auto *model_data_raw = reinterpret_cast(test_data_kernel.get_model_ptr()); + EXPECT_DEATH(ModuleLoader::load(&runtime_module, &memory_manager, model_data_raw, dealloc_input), + ""); } } // namespace -} // namespace kernels } // namespace luci_interpreter