已合并
[feat] Add operator scale_and_translate #693
FengHaozhan创建于 4月9日
[feat] Add operator scale_and_translate #693
已合并
共 17 个文件变更+2611-0
| @@ -395,6 +395,7 @@ function(gen_aicpu_kernel_symbol enable_built_in) | |||
| 395 | -o ${ARM_SO_OUTPUT} | 395 | -o ${ARM_SO_OUTPUT} |
| 396 | DEPENDS ${AICPU_CUST_OBJ_TARGETS} | 396 | DEPENDS ${AICPU_CUST_OBJ_TARGETS} |
| 397 | COMMENT "Linking aicpu_kernels.so using ARM toolchain" | 397 | COMMENT "Linking aicpu_kernels.so using ARM toolchain" |
| 398 | + COMMAND_EXPAND_LISTS | ||
| 398 | ) | 399 | ) |
| 399 | 400 | ||
| 400 | add_custom_target(aicpu_kernels ALL DEPENDS ${ARM_SO_OUTPUT}) | 401 | add_custom_target(aicpu_kernels ALL DEPENDS ${ARM_SO_OUTPUT}) |
| @@ -0,0 +1,27 @@ | |||
| 1 | +# --------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# --------------------------------------------------------------------------------------------------------- | ||
| 10 | +set(ASCEND_OP_NAME "" CACHE STRING "Ascend op names to compile") | ||
| 11 | +set(OP_TYPE "scale_and_translate") | ||
| 12 | + | ||
| 13 | +skip_aicpu_kernel("${OP_TYPE}" "${ASCEND_OP_NAME}") | ||
| 14 | + | ||
| 15 | +if(SKIP_FLAG) | ||
| 16 | + return() | ||
| 17 | +endif() | ||
| 18 | + | ||
| 19 | +file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 20 | +list(REMOVE_ITEM CURRENT_DIRS tests) | ||
| 21 | +foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 22 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 23 | + add_subdirectory(${SUB_DIR}) | ||
| 24 | + endif() | ||
| 25 | +endforeach() | ||
| 26 | + | ||
| 27 | +add_all_modules_sources(OPTYPE scale_and_translate ACLNNTYPE aclnn_exclude) | ||
| @@ -0,0 +1,307 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 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 | +using namespace ge; | ||
| 35 | +using std::map; | ||
| 36 | +using std::string; | ||
| 37 | +using std::vector; | ||
| 38 | + | ||
| 39 | + vector<int64_t> placeholder##inputIndex##_shape = inputShape; \ | ||
| 40 | + auto placeholder##inputIndex = op::Data("placeholder" + inputIndex).set_attr_index(0); \ | ||
| 41 | + TensorDesc placeholder##inputIndex##_desc = \ | ||
| 42 | + TensorDesc(ge::Shape(placeholder##inputIndex##_shape), FORMAT_NHWC, inputDtype); \ | ||
| 43 | + placeholder##inputIndex##_desc.SetPlacement(ge::kPlacementHost); \ | ||
| 44 | + placeholder##inputIndex##_desc.SetFormat(FORMAT_NHWC); \ | ||
| 45 | + Tensor tensor_placeholder##inputIndex; \ | ||
| 46 | + ret = GenOnesDataFloat32( \ | ||
| 47 | + placeholder##inputIndex##_shape, tensor_placeholder##inputIndex, placeholder##inputIndex##_desc, value); \ | ||
| 48 | + if (ret != SUCCESS) { \ | ||
| 49 | + printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \ | ||
| 50 | + return FAILED; \ | ||
| 51 | + } \ | ||
| 52 | + input.push_back(tensor_placeholder##inputIndex); \ | ||
| 53 | + graph.AddOp(placeholder##inputIndex); \ | ||
| 54 | + add1.set_input_##inputName(placeholder##inputIndex); \ | ||
| 55 | + add1.update_input_desc_##inputName(placeholder##inputIndex##_desc); \ | ||
| 56 | + inputs.push_back(placeholder##inputIndex); | ||
| 57 | + | ||
| 58 | + | ||
| 59 | + vector<int64_t> placeholder##inputIndex##_shape = inputShape; \ | ||
| 60 | + auto placeholder##inputIndex = op::Data("placeholder" + inputIndex).set_attr_index(0); \ | ||
| 61 | + TensorDesc placeholder##inputIndex##_desc = \ | ||
| 62 | + TensorDesc(ge::Shape(placeholder##inputIndex##_shape), FORMAT_NHWC, inputDtype); \ | ||
| 63 | + placeholder##inputIndex##_desc.SetPlacement(ge::kPlacementHost); \ | ||
| 64 | + placeholder##inputIndex##_desc.SetFormat(FORMAT_NHWC); \ | ||
| 65 | + Tensor tensor_placeholder##inputIndex; \ | ||
| 66 | + ret = GenOnesData(placeholder##inputIndex##_shape, \ | ||
| 67 | + tensor_placeholder##inputIndex, \ | ||
| 68 | + placeholder##inputIndex##_desc, \ | ||
| 69 | + inputDtype, \ | ||
| 70 | + 1); \ | ||
| 71 | + if (ret != SUCCESS) { \ | ||
| 72 | + printf("%s - ERROR - [XIR]: Generate input data failed\n", GetTime().c_str()); \ | ||
| 73 | + return FAILED; \ | ||
| 74 | + } \ | ||
| 75 | + input.push_back(tensor_placeholder##inputIndex); \ | ||
| 76 | + graph.AddOp(placeholder##inputIndex); \ | ||
| 77 | + add1.set_input_##inputName(placeholder##inputIndex); \ | ||
| 78 | + add1.update_input_desc_##inputName(placeholder##inputIndex##_desc); \ | ||
| 79 | + inputs.push_back(placeholder##inputIndex); | ||
| 80 | + | ||
| 81 | + | ||
| 82 | + TensorDesc outputName##outputIndex##_desc = TensorDesc(ge::Shape(outputShape), FORMAT_NHWC, outputDtype); \ | ||
| 83 | + add1.update_output_desc_##outputName(outputName##outputIndex##_desc); | ||
| 84 | + | ||
| 85 | + | ||
| 86 | + do { \ | ||
| 87 | + printf(message, ##__VA_ARGS__); \ | ||
| 88 | + } while (0) | ||
| 89 | + | ||
| 90 | +string GetTime() | ||
| 91 | +{ | ||
| 92 | + time_t timep; | ||
| 93 | + time(&timep); | ||
| 94 | + char tmp[64]; | ||
| 95 | + strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S,000", localtime(&timep)); | ||
| 96 | + return tmp; | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +uint32_t GetDataTypeSize(DataType dt) | ||
| 100 | +{ | ||
| 101 | + uint32_t dilation = 1; | ||
| 102 | + uint32_t oneByte = 1; | ||
| 103 | + uint32_t twoByte = 2; | ||
| 104 | + uint32_t fourByte = 4; | ||
| 105 | + uint32_t eightByte = 8; | ||
| 106 | + | ||
| 107 | + if (dt == ge::DT_FLOAT) { | ||
| 108 | + dilation = fourByte; | ||
| 109 | + } else if (dt == ge::DT_FLOAT16) { | ||
| 110 | + dilation = twoByte; | ||
| 111 | + } else if (dt == ge::DT_BF16) { | ||
| 112 | + dilation = twoByte; | ||
| 113 | + } else if (dt == ge::DT_INT16) { | ||
| 114 | + dilation = twoByte; | ||
| 115 | + } else if (dt == ge::DT_UINT16) { | ||
| 116 | + dilation = twoByte; | ||
| 117 | + } else if (dt == ge::DT_INT32) { | ||
| 118 | + dilation = fourByte; | ||
| 119 | + } else if (dt == ge::DT_UINT32) { | ||
| 120 | + dilation = fourByte; | ||
| 121 | + } else if (dt == ge::DT_INT64) { | ||
| 122 | + dilation = eightByte; | ||
| 123 | + } else if (dt == ge::DT_UINT64) { | ||
| 124 | + dilation = eightByte; | ||
| 125 | + } else if (dt == ge::DT_INT8) { | ||
| 126 | + dilation = oneByte; | ||
| 127 | + } | ||
| 128 | + return dilation; | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +int32_t GenOnesDataFloat32(vector<int64_t> shapes, Tensor &input_tensor, TensorDesc &input_tensor_desc, float value) | ||
| 132 | +{ | ||
| 133 | + input_tensor_desc.SetRealDimCnt(shapes.size()); | ||
| 134 | + size_t size = 1; | ||
| 135 | + for (uint32_t i = 0; i < shapes.size(); i++) { | ||
| 136 | + size *= shapes[i]; | ||
| 137 | + } | ||
| 138 | + uint32_t byteSizeFloat32 = 4; | ||
| 139 | + uint32_t data_len = size * byteSizeFloat32; | ||
| 140 | + float *pData = new (std::nothrow) float[size]; | ||
| 141 | + | ||
| 142 | + for (size_t i = 0; i < size; ++i) { | ||
| 143 | + *(pData + i) = value; | ||
| 144 | + } | ||
| 145 | + input_tensor = Tensor(input_tensor_desc, (uint8_t *)pData, data_len); | ||
| 146 | + return SUCCESS; | ||
| 147 | +} | ||
| 148 | + | ||
| 149 | +int32_t GenOnesData( | ||
| 150 | + vector<int64_t> shapes, Tensor &input_tensor, TensorDesc &input_tensor_desc, DataType data_type, int value) | ||
| 151 | +{ | ||
| 152 | + input_tensor_desc.SetRealDimCnt(shapes.size()); | ||
| 153 | + size_t size = 1; | ||
| 154 | + for (uint32_t i = 0; i < shapes.size(); i++) { | ||
| 155 | + size *= shapes[i]; | ||
| 156 | + } | ||
| 157 | + uint32_t data_len = size * GetDataTypeSize(data_type); | ||
| 158 | + int32_t *pData = new (std::nothrow) int32_t[data_len]; | ||
| 159 | + for (uint32_t i = 0; i < size; ++i) { | ||
| 160 | + *(pData + i) = value; | ||
| 161 | + } | ||
| 162 | + input_tensor = Tensor(input_tensor_desc, reinterpret_cast<uint8_t *>(pData), data_len); | ||
| 163 | + return SUCCESS; | ||
| 164 | +} | ||
| 165 | + | ||
| 166 | +int32_t WriteDataToFile(string bin_file, uint64_t data_size, uint8_t *inputData) | ||
| 167 | +{ | ||
| 168 | + FILE *fp; | ||
| 169 | + fp = fopen(bin_file.c_str(), "w"); | ||
| 170 | + fwrite(inputData, sizeof(uint8_t), data_size, fp); | ||
| 171 | + fclose(fp); | ||
| 172 | + return SUCCESS; | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +int CreateOppInGraph(DataType inDtype, std::vector<ge::Tensor> &input, std::vector<Operator> &inputs, | ||
| 176 | + std::vector<Operator> &outputs, Graph &graph) | ||
| 177 | +{ | ||
| 178 | + Status ret = SUCCESS; | ||
| 179 | + // 自定义代码:添加单算子定义到图中 | ||
| 180 | + auto add1 = op::ScaleAndTranslate("scale_and_translate"); | ||
| 181 | + std::vector<int64_t> imagesShape = {1, 4, 4, 3}; | ||
| 182 | + std::vector<int64_t> sizeShape = {2}; | ||
| 183 | + std::vector<int64_t> scaleShape = {2}; | ||
| 184 | + std::vector<int64_t> translationShape = {2}; | ||
| 185 | + | ||
| 186 | + ADD_INPUT(1, images, DT_FLOAT, imagesShape, 1.0); | ||
| 187 | + ADD_INPUT_INT(2, size, DT_INT32, sizeShape); | ||
| 188 | + ADD_INPUT(3, scale, DT_FLOAT, scaleShape, 1.0); | ||
| 189 | + ADD_INPUT(4, translation, DT_FLOAT, translationShape, 0.0); | ||
| 190 | + | ||
| 191 | + add1.set_attr_kernel_type("lanczos3"); | ||
| 192 | + add1.set_attr_antialias(true); | ||
| 193 | + | ||
| 194 | + outputs.push_back(add1); | ||
| 195 | + // 添加完毕 | ||
| 196 | + return SUCCESS; | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +int main(int argc, char *argv[]) | ||
| 200 | +{ | ||
| 201 | + const char *graph_name = "tc_ge_irrun_test"; | ||
| 202 | + Graph graph(graph_name); | ||
| 203 | + std::vector<ge::Tensor> input; | ||
| 204 | + | ||
| 205 | + printf("%s - INFO - [XIR]: Start to initialize ge using ge global options\n", GetTime().c_str()); | ||
| 206 | + std::map<AscendString, AscendString> global_options = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}}; | ||
| 207 | + Status ret = ge::GEInitialize(global_options); | ||
| 208 | + if (ret != SUCCESS) { | ||
| 209 | + printf("%s - INFO - [XIR]: Initialize ge using ge global options failed\n", GetTime().c_str()); | ||
| 210 | + return FAILED; | ||
| 211 | + } | ||
| 212 | + printf("%s - INFO - [XIR]: Initialize ge using ge global options success\n", GetTime().c_str()); | ||
| 213 | + | ||
| 214 | + std::vector<Operator> inputs{}; | ||
| 215 | + std::vector<Operator> outputs{}; | ||
| 216 | + | ||
| 217 | + std::cout << argv[1] << std::endl; | ||
| 218 | + char *endptr; | ||
| 219 | + | ||
| 220 | + DataType inDtype = DT_FLOAT; | ||
| 221 | + std::cout << inDtype << std::endl; | ||
| 222 | + | ||
| 223 | + ret = CreateOppInGraph(inDtype, input, inputs, outputs, graph); | ||
| 224 | + if (ret != SUCCESS) { | ||
| 225 | + printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str()); | ||
| 226 | + return FAILED; | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + if (!inputs.empty() && !outputs.empty()) { | ||
| 230 | + graph.SetInputs(inputs).SetOutputs(outputs); | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + std::map<AscendString, AscendString> build_options = { | ||
| 234 | + | ||
| 235 | + }; | ||
| 236 | + printf("%s - INFO - [XIR]: Start to create ir session using build options\n", GetTime().c_str()); | ||
| 237 | + ge::Session *session = new Session(build_options); | ||
| 238 | + | ||
| 239 | + if (session == nullptr) { | ||
| 240 | + printf("%s - ERROR - [XIR]: Create ir session using build options failed\n", GetTime().c_str()); | ||
| 241 | + return FAILED; | ||
| 242 | + } | ||
| 243 | + printf("%s - INFO - [XIR]: Create ir session using build options success\n", GetTime().c_str()); | ||
| 244 | + printf("%s - INFO - [XIR]: Start to add compute graph to ir session\n", GetTime().c_str()); | ||
| 245 | + | ||
| 246 | + std::map<AscendString, AscendString> graph_options = { | ||
| 247 | + | ||
| 248 | + }; | ||
| 249 | + uint32_t graph_id = 0; | ||
| 250 | + ret = session->AddGraph(graph_id, graph, graph_options); | ||
| 251 | + | ||
| 252 | + printf("%s - INFO - [XIR]: Session add ir compute graph to ir session success\n", GetTime().c_str()); | ||
| 253 | + printf("%s - INFO - [XIR]: dump graph to txt\n", GetTime().c_str()); | ||
| 254 | + std::string file_path = "./dump"; | ||
| 255 | + aclgrphDumpGraph(graph, file_path.c_str(), file_path.length()); | ||
| 256 | + printf("%s - INFO - [XIR]: Start to run ir compute graph\n", GetTime().c_str()); | ||
| 257 | + std::vector<ge::Tensor> output; | ||
| 258 | + ret = session->RunGraph(graph_id, input, output); | ||
| 259 | + if (ret != SUCCESS) { | ||
| 260 | + printf("%s - INFO - [XIR]: Run graph failed\n", GetTime().c_str()); | ||
| 261 | + delete session; | ||
| 262 | + GEFinalize(); | ||
| 263 | + return FAILED; | ||
| 264 | + } | ||
| 265 | + printf("%s - INFO - [XIR]: Session run ir compute graph success\n", GetTime().c_str()); | ||
| 266 | + | ||
| 267 | + int input_num = input.size(); | ||
| 268 | + for (int i = 0; i < input_num; i++) { | ||
| 269 | + std::cout << "input " << i << " dtype : " << input[i].GetTensorDesc().GetDataType() << std::endl; | ||
| 270 | + string input_file = "./tc_ge_irrun_test_0008_npu_input_" + std::to_string(i) + ".bin"; | ||
| 271 | + uint8_t *input_data_i = input[i].GetData(); | ||
| 272 | + int64_t input_shape = input[i].GetTensorDesc().GetShape().GetShapeSize(); | ||
| 273 | + std::cout << "this is " << i << "th input, input shape size =" << input_shape << std::endl; | ||
| 274 | + uint32_t data_size = input_shape * GetDataTypeSize(input[i].GetTensorDesc().GetDataType()); | ||
| 275 | + WriteDataToFile((const char *)input_file.c_str(), data_size, input_data_i); | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + int output_num = output.size(); | ||
| 279 | + for (int i = 0; i < output_num; i++) { | ||
| 280 | + std::cout << "output " << i << " dtype : " << output[i].GetTensorDesc().GetDataType() << std::endl; | ||
| 281 | + string output_file = "./tc_ge_irrun_test_0008_npu_output_" + std::to_string(i) + ".bin"; | ||
| 282 | + uint8_t *output_data_i = output[i].GetData(); | ||
| 283 | + int64_t output_shape = output[i].GetTensorDesc().GetShape().GetShapeSize(); | ||
| 284 | + std::cout << "this is " << i << "th output, output shape size =" << output_shape << std::endl; | ||
| 285 | + uint32_t data_size = output_shape * GetDataTypeSize(output[i].GetTensorDesc().GetDataType()); | ||
| 286 | + WriteDataToFile((const char *)output_file.c_str(), data_size, output_data_i); | ||
| 287 | + uint8_t *resultData = (uint8_t*)output_data_i; | ||
| 288 | + for (int64_t j = 0; j < output_shape; j++) { | ||
| 289 | + LOG_PRINT("result[%ld] is: %u\n", j, resultData[j]); | ||
| 290 | + } | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + ge::AscendString error_msg = ge::GEGetErrorMsgV2(); | ||
| 294 | + std::string error_str(error_msg.GetString()); | ||
| 295 | + std::cout << "Error message: " << error_str << std::endl; | ||
| 296 | + ge::AscendString warning_msg = ge::GEGetWarningMsgV2(); | ||
| 297 | + std::string warning_str(warning_msg.GetString()); | ||
| 298 | + std::cout << "Warning message: " << warning_str << std::endl; | ||
| 299 | + printf("%s - INFO - [XIR]: Start to finalize ir graph session\n", GetTime().c_str()); | ||
| 300 | + ret = ge::GEFinalize(); | ||
| 301 | + if (ret != SUCCESS) { | ||
| 302 | + printf("%s - INFO - [XIR]: Finalize ir graph session failed\n", GetTime().c_str()); | ||
| 303 | + return FAILED; | ||
| 304 | + } | ||
| 305 | + printf("%s - INFO - [XIR]: Finalize ir graph session success\n", GetTime().c_str()); | ||
| 306 | + return SUCCESS; | ||
| 307 | +} | ||
| @@ -0,0 +1,58 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + * | ||
| 10 | + * The code snippet comes from Huawei's open-source Mindspore project. | ||
| 11 | + * Copyright 2019-2020 Huawei Technologies Co., Ltd | ||
| 12 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 13 | + * You may obtain a copy of the License at | ||
| 14 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 15 | + * | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace ge { | ||
| 25 | +/** | ||
| 26 | + * @brief Resizes "images" to "size" by scale and translate . \n | ||
| 27 | + * | ||
| 28 | + * @par Inputs: | ||
| 29 | + * @li images: A `Tensor`. Must be one of the following types: `int8`, `uint8`, | ||
| 30 | + * `int16`, `uint16`, `int32`, `int64`, `float16`, `float32`, `float64`. | ||
| 31 | + * @li size: A `Tensor` of type `int32`. | ||
| 32 | + * @li scale: A `Tensor` of type `float32`. | ||
| 33 | + * @li translation: A `Tensor` of type `float32` . \n | ||
| 34 | + * | ||
| 35 | + * @par Attributes: | ||
| 36 | + * @li kernel_type: type is string, default is lanczos3. | ||
| 37 | + * @li antialias: type is bool, default is true. \n | ||
| 38 | + * | ||
| 39 | + * @par Outputs: | ||
| 40 | + * y: A Tensor with type float32 . \n | ||
| 41 | + * | ||
| 42 | + * @par Third-party framework compatibility | ||
| 43 | + * Compatible with TensorFlow ScaleAndTranslate operator. | ||
| 44 | +*/ | ||
| 45 | + | ||
| 46 | +REG_OP(ScaleAndTranslate) | ||
| 47 | + .INPUT(images, TensorType({DT_INT8, DT_UINT8, DT_INT16, DT_UINT16, | ||
| 48 | + DT_INT32, DT_INT64, DT_FLOAT16, DT_FLOAT, DT_DOUBLE})) | ||
| 49 | + .INPUT(size, TensorType({DT_INT32})) | ||
| 50 | + .INPUT(scale, TensorType({DT_FLOAT})) | ||
| 51 | + .INPUT(translation, TensorType({DT_FLOAT})) | ||
| 52 | + .OUTPUT(y, TensorType({DT_FLOAT})) | ||
| 53 | + .ATTR(kernel_type, String, "lanczos3") | ||
| 54 | + .ATTR(antialias, Bool, true) | ||
| 55 | + .OP_END_FACTORY_REG(ScaleAndTranslate) | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | + | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file scale_and_translate_infershape.cpp | ||
| 13 | + * \brief scale_and_translate infershape | ||
| 14 | + */ | ||
| @@ -0,0 +1,37 @@ | |||
| 1 | +# --------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# --------------------------------------------------------------------------------------------------------- | ||
| 10 | + | ||
| 11 | +if (BUILD_WITH_INSTALLED_DEPENDENCY_CANN_PKG) | ||
| 12 | + if (NOT (UT_TEST_ALL OR OP_KERNEL_AICPU_UT)) | ||
| 13 | + add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) | ||
| 14 | + set(CMAKE_CXX_COMPILER ${ASCEND_DIR}/toolkit/toolchain/hcc/bin/aarch64-target-linux-gnu-g++) | ||
| 15 | + endif() | ||
| 16 | + | ||
| 17 | + # aicpu op_def | ||
| 18 | + file(GLOB_RECURSE OP_DEF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu_def.cpp) | ||
| 19 | + set_property(GLOBAL APPEND PROPERTY AICPU_OP_DEF_FILES ${OP_DEF_FILE}) | ||
| 20 | + | ||
| 21 | + # aicpu cust kernel | ||
| 22 | + file(GLOB AICPU_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*_aicpu.cpp) | ||
| 23 | + file(GLOB AICPU_EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sampling_kernels.cpp) | ||
| 24 | + list(APPEND AICPU_SRC ${AICPU_EXTRA_SRC}) | ||
| 25 | + message(STATUS "[scale_and_translate] Found aicpu sources: ${AICPU_SRC}, ascend dir: ${ASCEND_DIR}, ophsot name: ${OPHOST_NAME}") | ||
| 26 | + | ||
| 27 | + set(OBJ_NAME scale_and_translate_cust_obj) | ||
| 28 | + add_aicpu_cust_kernel_modules(${OBJ_NAME}) | ||
| 29 | + target_sources(${OBJ_NAME} PRIVATE ${AICPU_SRC}) | ||
| 30 | +endif() | ||
| 31 | + | ||
| 32 | +if(UT_TEST_ALL OR OP_KERNEL_AICPU_UT) | ||
| 33 | + AddAicpuOpTestCase(scale_and_translate) | ||
| 34 | + target_sources(scale_and_translate_cases_obj PRIVATE | ||
| 35 | + ${CMAKE_CURRENT_SOURCE_DIR}/sampling_kernels.cpp | ||
| 36 | + ) | ||
| 37 | +endif() | ||
| @@ -0,0 +1,36 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | +namespace aicpu { | ||
| 15 | +SamplingKernelType SamplingKernelTypeFromString(const std::string &str) | ||
| 16 | +{ | ||
| 17 | + // Define map for different types of sampling kernels | ||
| 18 | + static const std::map<std::string, SamplingKernelType> SamplingTypesInfo { | ||
| 19 | + {"lanczos1", LANCZOS1_KERNEL}, | ||
| 20 | + {"lanczos3", LANCZOS3_KERNEL}, | ||
| 21 | + {"lanczos5", LANCZOS5_KERNEL}, | ||
| 22 | + {"gaussian", GAUSSIAN_KERNEL}, | ||
| 23 | + {"box", BOX_KERNEL}, | ||
| 24 | + {"triangle", TRIANGLE_KERNEL}, | ||
| 25 | + {"keyscubic", KEYS_CUBIC_KERNEL}, | ||
| 26 | + {"mitchellcubic", MITCHELL_CUBIC_KERNEL}, | ||
| 27 | + }; | ||
| 28 | + | ||
| 29 | + std::map<std::string, SamplingKernelType>::const_iterator iter = SamplingTypesInfo.find(str); | ||
| 30 | + if (iter != SamplingTypesInfo.end()) { | ||
| 31 | + return iter->second; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + return SAMPLING_KERNEL_TYPE_END; | ||
| 35 | +} | ||
| 36 | +} // namespace aicpu | ||
| @@ -0,0 +1,256 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +namespace aicpu { | ||
| 21 | +// Defines functions for different types of sampling kernels. | ||
| 22 | +enum SamplingKernelType { | ||
| 23 | + // Lanczos kernel with radius 1. Aliases but does not ring. | ||
| 24 | + LANCZOS1_KERNEL, | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * Lanczos kernel with radius 3. High-quality practical filter but may have | ||
| 28 | + * some ringing especially on synthetic images. | ||
| 29 | + */ | ||
| 30 | + LANCZOS3_KERNEL, | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * Lanczos kernel with radius 5. Very-high-quality filter but may have | ||
| 34 | + * stronger ringing. | ||
| 35 | + */ | ||
| 36 | + LANCZOS5_KERNEL, | ||
| 37 | + | ||
| 38 | + // Gaussian kernel with radius 3, sigma = 1.5 / 3. Less commonly used. | ||
| 39 | + GAUSSIAN_KERNEL, | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * Rectangle function. Equivalent to "nearest" sampling when upscaling. | ||
| 43 | + * Has value 1 in interval (-0.5, 0.5), value 0.5 on edge, and 0 elsewhere. | ||
| 44 | + */ | ||
| 45 | + BOX_KERNEL, | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * Hat/tent function with radius 1. Equivalent to "bilinear" reconstruction | ||
| 49 | + * when upsampling. | ||
| 50 | + * Has value zero at -1.0 and 1.0. | ||
| 51 | + */ | ||
| 52 | + TRIANGLE_KERNEL, | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * Cubic interpolant of Keys. Equivalent to Catmull-Rom kernel. Reasonably | ||
| 56 | + * good quality and faster than LANCZOS3_KERNEL. | ||
| 57 | + */ | ||
| 58 | + KEYS_CUBIC_KERNEL, | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * Cubic non-interpolating scheme. For synthetic images (especially those | ||
| 62 | + * lacking proper prefiltering), less ringing than Keys cubic kernel but less | ||
| 63 | + * sharp. | ||
| 64 | + */ | ||
| 65 | + MITCHELL_CUBIC_KERNEL, | ||
| 66 | + | ||
| 67 | + // Always insert new kernel types before this. | ||
| 68 | + SAMPLING_KERNEL_TYPE_END | ||
| 69 | +}; | ||
| 70 | + | ||
| 71 | +/** | ||
| 72 | + * Converts a string into the corresponding kernel type. | ||
| 73 | + * Returns SAMPLING_KERNEL_TYPE_END if the string couldn't be converted. | ||
| 74 | + */ | ||
| 75 | +SamplingKernelType SamplingKernelTypeFromString(const std::string &str); | ||
| 76 | + | ||
| 77 | +// A function object for a Lanczos kernel. | ||
| 78 | +struct LanczosKernelFunc { | ||
| 79 | + // Pass 1 for Lanczos1 kernel, 3 for Lanczos3 etc. | ||
| 80 | + explicit LanczosKernelFunc(float _radius) : radius(_radius) {} | ||
| 81 | + float operator()(float x) const | ||
| 82 | + { | ||
| 83 | + constexpr float kPI = 3.14159265359f; | ||
| 84 | + x = std::abs(x); | ||
| 85 | + if (x > radius) { | ||
| 86 | + return 0.0; | ||
| 87 | + } | ||
| 88 | + // Need to special case the limit case of sin(x) / x when x is zero. | ||
| 89 | + if (x <= 1e-3) { | ||
| 90 | + return 1.0; | ||
| 91 | + } | ||
| 92 | + return radius * std::sin(kPI * x) * std::sin(kPI * x / radius) / | ||
| 93 | + (kPI * kPI * x * x); | ||
| 94 | + } | ||
| 95 | + float Radius() const | ||
| 96 | + { | ||
| 97 | + return radius; | ||
| 98 | + } | ||
| 99 | + const float radius; | ||
| 100 | +}; | ||
| 101 | + | ||
| 102 | +struct GaussianKernelFunc { | ||
| 103 | + static constexpr float kRadiusMultiplier = 3.0f; | ||
| 104 | + /** | ||
| 105 | + * https://en.wikipedia.org/wiki/Gaussian_function | ||
| 106 | + * We use sigma = 0.5, as suggested on p. 4 of Ken Turkowski's "Filters | ||
| 107 | + * for Common Resampling Tasks" for kernels with a support of 3 pixels: | ||
| 108 | + * www.realitypixels.com/turk/computergraphics/ResamplingFilters.pdf | ||
| 109 | + * This implies a radius of 1.5, | ||
| 110 | + */ | ||
| 111 | + explicit GaussianKernelFunc(float _radius = 1.5f) | ||
| 112 | + : radius(_radius), sigma(_radius / kRadiusMultiplier) {} | ||
| 113 | + float operator()(float x) const | ||
| 114 | + { | ||
| 115 | + x = std::abs(x); | ||
| 116 | + if (x >= radius) { | ||
| 117 | + return 0.0; | ||
| 118 | + } | ||
| 119 | + return static_cast<float>(std::exp(-x * x / (2.0 * sigma * sigma))); | ||
| 120 | + } | ||
| 121 | + float Radius() const | ||
| 122 | + { | ||
| 123 | + return radius; | ||
| 124 | + } | ||
| 125 | + const float radius; | ||
| 126 | + // Gaussian standard deviation | ||
| 127 | + const float sigma; | ||
| 128 | +}; | ||
| 129 | + | ||
| 130 | +struct BoxKernelFunc { | ||
| 131 | + float operator()(float x) const | ||
| 132 | + { | ||
| 133 | + x = std::abs(x); | ||
| 134 | + constexpr float pointFive = 0.5f; | ||
| 135 | + constexpr float onePoint = 1.0f; | ||
| 136 | + return x < pointFive ? onePoint : IsValueEqual<float>(x, pointFive) ? pointFive : 0.0f; | ||
| 137 | + } | ||
| 138 | + float Radius() const | ||
| 139 | + { | ||
| 140 | + return 1.f; | ||
| 141 | + } | ||
| 142 | +}; | ||
| 143 | + | ||
| 144 | +struct TriangleKernelFunc { | ||
| 145 | + // https://en.wikipedia.org/wiki/Triangle_function | ||
| 146 | + float operator()(float x) const | ||
| 147 | + { | ||
| 148 | + x = std::abs(x); | ||
| 149 | + return x < 1.0f ? 1.0f - x : 0.0f; | ||
| 150 | + } | ||
| 151 | + float Radius() const | ||
| 152 | + { | ||
| 153 | + return 1.f; | ||
| 154 | + } | ||
| 155 | +}; | ||
| 156 | + | ||
| 157 | +struct KeysCubicKernelFunc { | ||
| 158 | + /** | ||
| 159 | + * http://ieeexplore.ieee.org/document/1163711/ | ||
| 160 | + * R. G. Keys. Cubic convolution interpolation for digital image | ||
| 161 | + * processing. IEEE Transactions on Acoustics, Speech, and Signal | ||
| 162 | + * Processing, 29(6):1153-1160, 1981. | ||
| 163 | + */ | ||
| 164 | + float operator()(float i) const | ||
| 165 | + { | ||
| 166 | + i = std::abs(i); | ||
| 167 | + if (i >= 2.0f) { | ||
| 168 | + return 0.0f; | ||
| 169 | + } else if (i >= 1.0f) { | ||
| 170 | + return ((-0.5f * i + 2.5f) * i - 4.0f) * i + 2.0f; | ||
| 171 | + } else { | ||
| 172 | + return ((1.5f * i - 2.5f) * i) * i + 1.0f; | ||
| 173 | + } | ||
| 174 | + } | ||
| 175 | + float Radius() const | ||
| 176 | + { | ||
| 177 | + return 2.f; | ||
| 178 | + } | ||
| 179 | +}; | ||
| 180 | + | ||
| 181 | +struct MitchellCubicKernelFunc { | ||
| 182 | + /** | ||
| 183 | + * https://doi.org/10.1145/378456.378514 | ||
| 184 | + * D. P. Mitchell and A. N. Netravali. Reconstruction filters in computer | ||
| 185 | + * graphics. Computer Graphics (Proceedings of ACM SIGGRAPH 1988), | ||
| 186 | + * 22(4):221-228, 1988. | ||
| 187 | + */ | ||
| 188 | + float operator()(float i) const | ||
| 189 | + { | ||
| 190 | + i = std::abs(i); | ||
| 191 | + if (i >= 2.0f) { | ||
| 192 | + return 0.0f; | ||
| 193 | + } else if (i >= 1.0f) { | ||
| 194 | + return (((-7.0f / 18.0f) * i + 2.0f) * i - 10.0f / 3.0f) * i + | ||
| 195 | + 16.0f / 9.0f; | ||
| 196 | + } else { | ||
| 197 | + return (((7.0f / 6.0f) * i - 2.0f) * i) * i + 8.0f / 9.0f; | ||
| 198 | + } | ||
| 199 | + } | ||
| 200 | + float Radius() const | ||
| 201 | + { | ||
| 202 | + return 2.f; | ||
| 203 | + } | ||
| 204 | +}; | ||
| 205 | + | ||
| 206 | +inline LanczosKernelFunc CreateLanczos1Kernel() | ||
| 207 | +{ | ||
| 208 | + float i = 1.0; | ||
| 209 | + return LanczosKernelFunc(i); | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +inline LanczosKernelFunc CreateLanczos3Kernel() | ||
| 213 | +{ | ||
| 214 | + float i = 3.0; | ||
| 215 | + return LanczosKernelFunc(i); | ||
| 216 | +} | ||
| 217 | + | ||
| 218 | +inline LanczosKernelFunc CreateLanczos5Kernel() | ||
| 219 | +{ | ||
| 220 | + float i = 5.0; | ||
| 221 | + return LanczosKernelFunc(i); | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +inline GaussianKernelFunc CreateGaussianKernel() | ||
| 225 | +{ | ||
| 226 | + float i = 1.5; | ||
| 227 | + return GaussianKernelFunc(i); | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | +inline BoxKernelFunc CreateBoxKernel() | ||
| 231 | +{ | ||
| 232 | + BoxKernelFunc retfunc = BoxKernelFunc(); | ||
| 233 | + return retfunc; | ||
| 234 | +} | ||
| 235 | + | ||
| 236 | +inline TriangleKernelFunc CreateTriangleKernel() | ||
| 237 | +{ | ||
| 238 | + TriangleKernelFunc retfunc = TriangleKernelFunc(); | ||
| 239 | + return retfunc; | ||
| 240 | +} | ||
| 241 | + | ||
| 242 | +inline KeysCubicKernelFunc CreateKeysCubicKernel() | ||
| 243 | +{ | ||
| 244 | + KeysCubicKernelFunc retfunc = KeysCubicKernelFunc(); | ||
| 245 | + return retfunc; | ||
| 246 | +} | ||
| 247 | + | ||
| 248 | +inline MitchellCubicKernelFunc CreateMitchellCubicKernel() | ||
| 249 | +{ | ||
| 250 | + MitchellCubicKernelFunc retfunc = MitchellCubicKernelFunc(); | ||
| 251 | + return retfunc; | ||
| 252 | +} | ||
| 253 | + | ||
| 254 | +} // namespace aicpu | ||
| 255 | + | ||
| 256 | + | ||
| @@ -0,0 +1,515 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +namespace { | ||
| 23 | +const uint32_t kOutputNum = 1; | ||
| 24 | +const uint32_t kInputNum = 4; | ||
| 25 | +constexpr int64_t kParallelDataNums = 1024; | ||
| 26 | +const char *kScaleAndTranslate = "ScaleAndTranslate"; | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + case (DTYPE): { \ | ||
| 30 | + uint32_t result = ScaleAndTranslateCompute<TYPE>(CTX); \ | ||
| 31 | + if (result != KERNEL_STATUS_OK) { \ | ||
| 32 | + KERNEL_LOG_ERROR("ScaleAndTranslate kernel compute failed."); \ | ||
| 33 | + return result; \ | ||
| 34 | + } \ | ||
| 35 | + break; \ | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + if ((end_num) <= kParallelDataNums) { \ | ||
| 40 | + for (size_t i = 0; i < size_t(end_num); i++) { \ | ||
| 41 | + SHARD(i, i + 1); \ | ||
| 42 | + } \ | ||
| 43 | + } else { \ | ||
| 44 | + KERNEL_HANDLE_ERROR(CpuKernelUtils::ParallelFor(ctx, end_num, 1, SHARD), \ | ||
| 45 | + "ScaleAndTranslate #SHARD Compute failed.") \ | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | +} // namespace | ||
| 49 | + | ||
| 50 | +namespace aicpu { | ||
| 51 | +uint32_t ScaleAndTranslateCpuKernel::Compute(CpuKernelContext &ctx) | ||
| 52 | +{ | ||
| 53 | + // check params | ||
| 54 | + KERNEL_HANDLE_ERROR( | ||
| 55 | + NormalCheck(ctx, kInputNum, kOutputNum), | ||
| 56 | + "ScaleAndTranslate check input and output number failed."); | ||
| 57 | + KERNEL_HANDLE_ERROR(ScaleAndTranslateCheck(ctx), | ||
| 58 | + "ScaleAndTranslate check params failed."); | ||
| 59 | + auto data_type = ctx.Input(0)->GetDataType(); | ||
| 60 | + switch (data_type) { | ||
| 61 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_INT8, int8_t, ctx) | ||
| 62 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_UINT8, uint8_t, ctx) | ||
| 63 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_INT16, int16_t, ctx) | ||
| 64 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_UINT16, uint16_t, ctx) | ||
| 65 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_INT32, int32_t, ctx) | ||
| 66 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_INT64, int64_t, ctx) | ||
| 67 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_FLOAT16, Eigen::half, ctx) | ||
| 68 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_FLOAT, float, ctx) | ||
| 69 | + SCALEANDTRANSLATE_COMPUTE_CASE(DT_DOUBLE, double, ctx) | ||
| 70 | + default: | ||
| 71 | + KERNEL_LOG_ERROR("ScaleAndTranslate kernel data type [%s] not support.", | ||
| 72 | + DTypeStr(data_type).c_str()); | ||
| 73 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 74 | + } | ||
| 75 | + return KERNEL_STATUS_OK; | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +uint32_t ScaleAndTranslateCpuKernel::ScaleAndTranslateCheck( | ||
| 79 | + CpuKernelContext &ctx) | ||
| 80 | +{ | ||
| 81 | + auto input0_shape = ctx.Input(0)->GetTensorShape(); | ||
| 82 | + auto input1_shape = ctx.Input(1)->GetTensorShape(); | ||
| 83 | + auto input2_shape = ctx.Input(2)->GetTensorShape(); | ||
| 84 | + auto input3_shape = ctx.Input(3)->GetTensorShape(); | ||
| 85 | + // dims check | ||
| 86 | + KERNEL_CHECK_FALSE( | ||
| 87 | + (input0_shape->GetDims() == 4), KERNEL_STATUS_PARAM_INVALID, | ||
| 88 | + "The input0's dims=[%d] must be 4-dimensional", input0_shape->GetDims()) | ||
| 89 | + KERNEL_CHECK_FALSE( | ||
| 90 | + (input1_shape->GetDims() == 1), KERNEL_STATUS_PARAM_INVALID, | ||
| 91 | + "The input1's dims=[%d] must be 1-dimensional", input1_shape->GetDims()) | ||
| 92 | + KERNEL_CHECK_FALSE((input1_shape->NumElements() == 2), | ||
| 93 | + KERNEL_STATUS_PARAM_INVALID, | ||
| 94 | + "The input1's numelements=[%d] must have two elements", | ||
| 95 | + input1_shape->NumElements()) | ||
| 96 | + | ||
| 97 | + DataType input1_type = ctx.Input(1)->GetDataType(); | ||
| 98 | + DataType input2_type = ctx.Input(2)->GetDataType(); | ||
| 99 | + DataType input3_type = ctx.Input(3)->GetDataType(); | ||
| 100 | + | ||
| 101 | + // dtypes check | ||
| 102 | + KERNEL_CHECK_FALSE((input1_type == DT_INT32), KERNEL_STATUS_PARAM_INVALID, | ||
| 103 | + "The input1's dtype=[%d] must be DT_INT32", | ||
| 104 | + DTypeStr(input1_type).c_str()) | ||
| 105 | + KERNEL_CHECK_FALSE((input2_type == DT_FLOAT), KERNEL_STATUS_PARAM_INVALID, | ||
| 106 | + "The input2's dtype=[%d] must be DT_FLOAT", | ||
| 107 | + DTypeStr(input2_type).c_str()) | ||
| 108 | + KERNEL_CHECK_FALSE((input3_type == DT_FLOAT), KERNEL_STATUS_PARAM_INVALID, | ||
| 109 | + "The input3's dtype=[%d] must be DT_FLOAT", | ||
| 110 | + DTypeStr(input3_type).c_str()) | ||
| 111 | + | ||
| 112 | + KERNEL_LOG_INFO( | ||
| 113 | + "ScaleAndTranslateCpuKernel[%s], input0: size[%llu], input1: size[%llu];" | ||
| 114 | + "input2: size[%llu], input3: size[%llu], output: size[%llu].", | ||
| 115 | + ctx.GetOpType().c_str(), ctx.Input(0)->GetDataSize(), | ||
| 116 | + ctx.Input(1)->GetDataSize(), ctx.Input(2)->GetDataSize(), | ||
| 117 | + ctx.Input(3)->GetDataSize(), ctx.Output(0)->GetDataSize()); | ||
| 118 | + return KERNEL_STATUS_OK; | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +template <typename T> | ||
| 122 | +inline const T &Clamp(const T &lower, const T &higher, const T &value) | ||
| 123 | +{ | ||
| 124 | + if (higher < value) { | ||
| 125 | + return higher; | ||
| 126 | + } | ||
| 127 | + if (value < lower) { | ||
| 128 | + return lower; | ||
| 129 | + } | ||
| 130 | + return value; | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +static void NormalizeSpanWeights(const std::vector<float> &temp_weights, | ||
| 134 | + float total_weight, int span_size, int x, | ||
| 135 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> &weights_vec) | ||
| 136 | +{ | ||
| 137 | + if (std::abs(total_weight) >= | ||
| 138 | + 1000.0f * std::numeric_limits<float>::min()) { | ||
| 139 | + float one_over_total_weight = 1.0f / total_weight; | ||
| 140 | + int out_index = span_size * x; | ||
| 141 | + for (float weight : temp_weights) { | ||
| 142 | + weights_vec(out_index) = weight * one_over_total_weight; | ||
| 143 | + ++out_index; | ||
| 144 | + } | ||
| 145 | + } | ||
| 146 | +} | ||
| 147 | + | ||
| 148 | +template <typename Kernel> | ||
| 149 | +uint32_t InitSpans(const Kernel &kernel, int64_t output_size, | ||
| 150 | + int64_t input_size, bool antialias, float inv_scale, | ||
| 151 | + Spans *spans, float &kernel_scale) | ||
| 152 | +{ | ||
| 153 | + kernel_scale = antialias ? std::max(inv_scale, 1.0f) : 1.0f; | ||
| 154 | + spans->span_size = std::min( | ||
| 155 | + 2 * static_cast<int>(std::ceil(kernel.Radius() * kernel_scale)) + 1, | ||
| 156 | + static_cast<int>(input_size)); | ||
| 157 | + | ||
| 158 | + spans->starts = new (std::nothrow) Eigen::Tensor<int32_t, 1>(output_size); | ||
| 159 | + KERNEL_CHECK_NULLPTR(spans->starts, KERNEL_STATUS_PARAM_INVALID, | ||
| 160 | + "New spans starts failed.") | ||
| 161 | + spans->weights = new (std::nothrow) Eigen::Tensor<float, 1>(spans->span_size * output_size); | ||
| 162 | + KERNEL_CHECK_NULLPTR(spans->weights, KERNEL_STATUS_PARAM_INVALID, | ||
| 163 | + "New spans weights failed.") | ||
| 164 | + return KERNEL_STATUS_OK; | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +template <typename Kernel> | ||
| 168 | +uint32_t ComputeSpansCore(CpuKernelContext &context, const Kernel &kernel, const int64_t output_size, | ||
| 169 | + const int64_t input_size, const float scale, const float translate, | ||
| 170 | + const bool antialias, Spans *spans) | ||
| 171 | +{ | ||
| 172 | + const float inv_scale = 1.0 / scale; | ||
| 173 | + const float inv_translate = -inv_scale * translate; | ||
| 174 | + float kernel_scale = 0.0f; | ||
| 175 | + KERNEL_HANDLE_ERROR(InitSpans(kernel, output_size, input_size, antialias, | ||
| 176 | + inv_scale, spans, kernel_scale), "InitSpans failed."); | ||
| 177 | + Eigen::TensorMap<Eigen::Tensor<int32_t, 1>> starts_vec( spans->starts->data(), spans->starts->dimensions()); | ||
| 178 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> weights_vec(spans->weights->data(), spans->weights->dimensions()); | ||
| 179 | + weights_vec.setZero(); | ||
| 180 | + const float one_over_kernel_scale = 1.0f / kernel_scale; | ||
| 181 | + int max_span_size = 0; | ||
| 182 | + std::vector<float> temp_weights; | ||
| 183 | + uint32_t shard_ret = KERNEL_STATUS_OK; | ||
| 184 | + auto shard_x = [&](int start, int end) { | ||
| 185 | + for (auto x = start; x < end; ++x) { | ||
| 186 | + const float col_f = x + 0.5f; | ||
| 187 | + const float sample_f = col_f * inv_scale + inv_translate; | ||
| 188 | + // Don't sample when the sampling location is outside the source image. | ||
| 189 | + if (sample_f < 0 || sample_f > input_size) { | ||
| 190 | + // Add an empty span. | ||
| 191 | + starts_vec(x) = 0; | ||
| 192 | + continue; | ||
| 193 | + } | ||
| 194 | + int64_t span_start = std::ceil(sample_f - kernel.Radius() * kernel_scale - 0.5f); | ||
| 195 | + int64_t span_end = std::floor(sample_f + kernel.Radius() * kernel_scale - 0.5f); | ||
| 196 | + span_start = Clamp(static_cast<int64_t>(0), input_size - 1, span_start); | ||
| 197 | + span_end = Clamp(static_cast<int64_t>(0), input_size - 1, span_end) + 1; | ||
| 198 | + const int this_span_size = span_end - span_start; | ||
| 199 | + if (this_span_size > spans->span_size) { | ||
| 200 | + KERNEL_LOG_ERROR("Span is too large: [%d] vs [%d].", this_span_size, spans->span_size); | ||
| 201 | + shard_ret = KERNEL_STATUS_PARAM_INVALID; | ||
| 202 | + return; | ||
| 203 | + } | ||
| 204 | + float total_weight = 0.0f; | ||
| 205 | + temp_weights.clear(); | ||
| 206 | + for (int source = span_start; source < span_end; ++source) { | ||
| 207 | + float kernel_pos = static_cast<float>(source) + 0.5f - sample_f; | ||
| 208 | + float weight = kernel(std::abs(kernel_pos * one_over_kernel_scale)); | ||
| 209 | + total_weight += weight; | ||
| 210 | + temp_weights.push_back(weight); | ||
| 211 | + } | ||
| 212 | + max_span_size = std::max(max_span_size, this_span_size); | ||
| 213 | + NormalizeSpanWeights(temp_weights, total_weight, spans->span_size, x, weights_vec); | ||
| 214 | + starts_vec(x) = span_start; | ||
| 215 | + } | ||
| 216 | + }; | ||
| 217 | + SWITCH_PARALLEL(shard_x, output_size, context); | ||
| 218 | + if (shard_ret != KERNEL_STATUS_OK) { | ||
| 219 | + return shard_ret; | ||
| 220 | + } | ||
| 221 | + return KERNEL_STATUS_OK; | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +uint32_t ComputeSpans(CpuKernelContext &context, | ||
| 225 | + const SamplingKernelType kernel_type, | ||
| 226 | + const int64_t output_size, const int64_t input_size, | ||
| 227 | + const float scale, const float translate, | ||
| 228 | + const bool antialias, Spans *spans) | ||
| 229 | +{ | ||
| 230 | + switch (kernel_type) { | ||
| 231 | + case LANCZOS1_KERNEL: { | ||
| 232 | + return ComputeSpansCore(context, CreateLanczos1Kernel(), output_size, | ||
| 233 | + input_size, scale, translate, antialias, spans); | ||
| 234 | + } | ||
| 235 | + case LANCZOS3_KERNEL: { | ||
| 236 | + return ComputeSpansCore(context, CreateLanczos3Kernel(), output_size, | ||
| 237 | + input_size, scale, translate, antialias, spans); | ||
| 238 | + } | ||
| 239 | + case LANCZOS5_KERNEL: { | ||
| 240 | + return ComputeSpansCore(context, CreateLanczos5Kernel(), output_size, | ||
| 241 | + input_size, scale, translate, antialias, spans); | ||
| 242 | + } | ||
| 243 | + case GAUSSIAN_KERNEL: { | ||
| 244 | + return ComputeSpansCore(context, CreateGaussianKernel(), output_size, | ||
| 245 | + input_size, scale, translate, antialias, spans); | ||
| 246 | + } | ||
| 247 | + case BOX_KERNEL: { | ||
| 248 | + return ComputeSpansCore(context, CreateBoxKernel(), output_size, | ||
| 249 | + input_size, scale, translate, antialias, spans); | ||
| 250 | + } | ||
| 251 | + case TRIANGLE_KERNEL: { | ||
| 252 | + return ComputeSpansCore(context, CreateTriangleKernel(), output_size, | ||
| 253 | + input_size, scale, translate, antialias, spans); | ||
| 254 | + } | ||
| 255 | + case KEYS_CUBIC_KERNEL: { | ||
| 256 | + return ComputeSpansCore(context, CreateKeysCubicKernel(), output_size, | ||
| 257 | + input_size, scale, translate, antialias, spans); | ||
| 258 | + } | ||
| 259 | + case MITCHELL_CUBIC_KERNEL: { | ||
| 260 | + return ComputeSpansCore(context, CreateMitchellCubicKernel(), output_size, | ||
| 261 | + input_size, scale, translate, antialias, spans); | ||
| 262 | + } | ||
| 263 | + default: | ||
| 264 | + KERNEL_LOG_ERROR("kernel_type kernel data type [%u] not support.", | ||
| 265 | + kernel_type); | ||
| 266 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 267 | + } | ||
| 268 | + return KERNEL_STATUS_OK; | ||
| 269 | +} | ||
| 270 | + | ||
| 271 | +struct ScaleAndTranslateParams { | ||
| 272 | + SamplingKernelType kernel_type; | ||
| 273 | + bool antialias; | ||
| 274 | + int64_t batch_size; | ||
| 275 | + int64_t input_height; | ||
| 276 | + int64_t input_width; | ||
| 277 | + int64_t channels; | ||
| 278 | + int64_t output_height; | ||
| 279 | + int64_t output_width; | ||
| 280 | + float row_scale; | ||
| 281 | + float col_scale; | ||
| 282 | + float row_translation; | ||
| 283 | + float col_translation; | ||
| 284 | +}; | ||
| 285 | + | ||
| 286 | +static uint32_t ParseScaleAndTranslateParams(CpuKernelContext &ctx, | ||
| 287 | + ScaleAndTranslateParams &p) | ||
| 288 | +{ | ||
| 289 | + auto input_size = reinterpret_cast<int32_t *>(ctx.Input(1)->GetData()); | ||
| 290 | + auto input_scale = reinterpret_cast<float *>(ctx.Input(2)->GetData()); | ||
| 291 | + auto input_translation = reinterpret_cast<float *>(ctx.Input(3)->GetData()); | ||
| 292 | + KERNEL_CHECK_NULLPTR(ctx.GetAttr("kernel_type"), KERNEL_STATUS_PARAM_INVALID, "Get attr [kernel_type] failed."); | ||
| 293 | + std::string kernel_type_str = ctx.GetAttr("kernel_type")->GetString(); | ||
| 294 | + KERNEL_CHECK_NULLPTR(ctx.GetAttr("antialias"), KERNEL_STATUS_PARAM_INVALID, "Get attr [antialias] failed."); | ||
| 295 | + p.antialias = ctx.GetAttr("antialias")->GetBool(); | ||
| 296 | + p.kernel_type = SamplingKernelTypeFromString(kernel_type_str); | ||
| 297 | + | ||
| 298 | + auto input0_shape = ctx.Input(0)->GetTensorShape(); | ||
| 299 | + | ||
| 300 | + p.output_height = input_size[0]; | ||
| 301 | + p.output_width = input_size[1]; | ||
| 302 | + | ||
| 303 | + p.batch_size = input0_shape->GetDimSize(0); | ||
| 304 | + p.input_height = input0_shape->GetDimSize(1); | ||
| 305 | + p.input_width = input0_shape->GetDimSize(2); | ||
| 306 | + p.channels = input0_shape->GetDimSize(3); | ||
| 307 | + | ||
| 308 | + KERNEL_CHECK_FALSE( | ||
| 309 | + (p.output_height > 0 && p.output_width > 0), KERNEL_STATUS_PARAM_INVALID, | ||
| 310 | + "output_height = [%d] and output_width = [%d] must be positive", | ||
| 311 | + p.output_height, p.output_width) | ||
| 312 | + KERNEL_CHECK_FALSE((p.channels > 0), KERNEL_STATUS_PARAM_INVALID, | ||
| 313 | + "image_channel = [%d] must have at least one", p.channels) | ||
| 314 | + KERNEL_CHECK_FALSE( | ||
| 315 | + (p.input_height > 0 && p.input_width > 0), KERNEL_STATUS_PARAM_INVALID, | ||
| 316 | + "input_height = [%d] and input_width = [%d] must be of non-zero size", | ||
| 317 | + p.input_height, p.input_width) | ||
| 318 | + | ||
| 319 | + p.row_scale = input_scale[0]; | ||
| 320 | + p.col_scale = input_scale[1]; | ||
| 321 | + | ||
| 322 | + KERNEL_CHECK_FALSE( | ||
| 323 | + (p.row_scale > 0 && p.col_scale > 0), KERNEL_STATUS_PARAM_INVALID, | ||
| 324 | + "row_scale = [%d] and col_scale = [%d] must be greater than zero.", | ||
| 325 | + p.row_scale, p.col_scale) | ||
| 326 | + | ||
| 327 | + p.row_translation = input_translation[0]; | ||
| 328 | + p.col_translation = input_translation[1]; | ||
| 329 | + return KERNEL_STATUS_OK; | ||
| 330 | +} | ||
| 331 | + | ||
| 332 | +template <typename T> | ||
| 333 | +uint32_t ScaleAndTranslateCpuKernel::ScaleAndTranslateCompute( | ||
| 334 | + CpuKernelContext &ctx) | ||
| 335 | +{ | ||
| 336 | + ScaleAndTranslateParams p; | ||
| 337 | + KERNEL_HANDLE_ERROR(ParseScaleAndTranslateParams(ctx, p), | ||
| 338 | + "ScaleAndTranslate parse params failed."); | ||
| 339 | + | ||
| 340 | + Tensor *input = ctx.Input(0); | ||
| 341 | + Tensor *output = ctx.Output(0); | ||
| 342 | + | ||
| 343 | + EigenTensor inputTensor(input, input->GetData()); | ||
| 344 | + EigenTensor outputTensor(output, output->GetData()); | ||
| 345 | + | ||
| 346 | + typename TTypes<T, 4>::Tensor image_data(inputTensor.tensor<T, 4>()); | ||
| 347 | + | ||
| 348 | + typename TTypes<float, 4>::Tensor output_data( | ||
| 349 | + outputTensor.tensor<float, 4>()); | ||
| 350 | + | ||
| 351 | + Spans col_spans; | ||
| 352 | + ComputeSpans(ctx, p.kernel_type, p.output_width, p.input_width, p.col_scale, | ||
| 353 | + p.col_translation, p.antialias, &col_spans); | ||
| 354 | + | ||
| 355 | + Spans row_spans; | ||
| 356 | + ComputeSpans(ctx, p.kernel_type, p.output_height, p.input_height, p.row_scale, | ||
| 357 | + p.row_translation, p.antialias, &row_spans); | ||
| 358 | + | ||
| 359 | + Eigen::Tensor<float, 4> intermediate_tensor_middle(p.batch_size, p.output_height, | ||
| 360 | + p.input_width, p.channels); | ||
| 361 | + Eigen::TensorMap<Eigen::Tensor<float, 4>> intermediate_data( | ||
| 362 | + intermediate_tensor_middle.data(), | ||
| 363 | + intermediate_tensor_middle.dimensions()); | ||
| 364 | + Eigen::TensorMap<Eigen::Tensor<int32_t, 1>> row_starts( | ||
| 365 | + row_spans.starts->data(), row_spans.starts->dimensions()); | ||
| 366 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> row_weights( | ||
| 367 | + row_spans.weights->data(), row_spans.weights->dimensions()); | ||
| 368 | + Eigen::TensorMap<Eigen::Tensor<int32_t, 1>> col_starts( | ||
| 369 | + col_spans.starts->data(), col_spans.starts->dimensions()); | ||
| 370 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> col_weights( | ||
| 371 | + col_spans.weights->data(), col_spans.weights->dimensions()); | ||
| 372 | + | ||
| 373 | + GatherSpans<T>()(ctx, row_spans.span_size, row_starts, row_weights, | ||
| 374 | + col_spans.span_size, col_starts, col_weights, image_data, | ||
| 375 | + intermediate_data, output_data); | ||
| 376 | + | ||
| 377 | + delete col_spans.starts; | ||
| 378 | + delete col_spans.weights; | ||
| 379 | + delete row_spans.starts; | ||
| 380 | + delete row_spans.weights; | ||
| 381 | + | ||
| 382 | + return KERNEL_STATUS_OK; | ||
| 383 | +} | ||
| 384 | + | ||
| 385 | +template <typename T> | ||
| 386 | +inline void GatherColumnPixel(const T *input_row_start, const int32_t *starts, | ||
| 387 | + const float *weights, int x, int span_size, | ||
| 388 | + int64_t input_width, int channels, float *out_pixel) | ||
| 389 | +{ | ||
| 390 | + const T *in_pixel = input_row_start + starts[x] * channels; | ||
| 391 | + const float *weights_start = weights + x * span_size; | ||
| 392 | + const int real_span_size = | ||
| 393 | + std::min(starts[x] + span_size, static_cast<int>(input_width)) - starts[x]; | ||
| 394 | + const float *weights_end = weights_start + real_span_size; | ||
| 395 | + for (int c = 0; c < channels; ++c) { | ||
| 396 | + out_pixel[c] = 0.0f; | ||
| 397 | + } | ||
| 398 | + for (const float *weight_ptr = weights_start; weight_ptr != weights_end; ++weight_ptr) { | ||
| 399 | + float weight = *weight_ptr; | ||
| 400 | + for (int c = 0; c < channels; ++c) { | ||
| 401 | + out_pixel[c] += weight * static_cast<float>(in_pixel[c]); | ||
| 402 | + } | ||
| 403 | + in_pixel += channels; | ||
| 404 | + } | ||
| 405 | +} | ||
| 406 | + | ||
| 407 | +template <typename T> | ||
| 408 | +uint32_t GatherColumns(CpuKernelContext &context, int span_size, | ||
| 409 | + const int32_t *starts, const float *weights, | ||
| 410 | + const T *image, const int64_t input_height, | ||
| 411 | + const int64_t input_width, const int64_t output_height, | ||
| 412 | + const int64_t output_width, const int channels, | ||
| 413 | + float *output) | ||
| 414 | +{ | ||
| 415 | + const int64_t in_row_size = input_width * channels; | ||
| 416 | + const int64_t out_row_size = output_width * channels; | ||
| 417 | + auto shard_column = [&](int start, int end) { | ||
| 418 | + for (int y = start; y < end; ++y) { | ||
| 419 | + const T *input_row_start = image + in_row_size * y; | ||
| 420 | + float *out_pixel = output + out_row_size * y; | ||
| 421 | + for (int x = 0; x < output_width; ++x, out_pixel += channels) { | ||
| 422 | + GatherColumnPixel(input_row_start, starts, weights, x, span_size, | ||
| 423 | + input_width, channels, out_pixel); | ||
| 424 | + } | ||
| 425 | + } | ||
| 426 | + }; | ||
| 427 | + SWITCH_PARALLEL(shard_column, output_height, context); | ||
| 428 | + return KERNEL_STATUS_OK; | ||
| 429 | +} | ||
| 430 | + | ||
| 431 | +template <typename T> | ||
| 432 | +inline void AddScaledVector(const T *in_vec, int vec_length, float weight, | ||
| 433 | + float *out_vec) | ||
| 434 | +{ | ||
| 435 | + float *out_vec_end = out_vec + vec_length; | ||
| 436 | + for (; out_vec != out_vec_end; ++out_vec, ++in_vec) { | ||
| 437 | + *out_vec += weight * static_cast<float>(*in_vec); | ||
| 438 | + } | ||
| 439 | +} | ||
| 440 | + | ||
| 441 | +template <typename T> | ||
| 442 | +uint32_t GatherRows(CpuKernelContext &context, int span_size, | ||
| 443 | + const int32_t *starts, const float *weights, const T *image, | ||
| 444 | + const int64_t input_height, const int64_t input_width, | ||
| 445 | + const int64_t output_height, const int64_t output_width, | ||
| 446 | + const int channels, float *output) | ||
| 447 | +{ | ||
| 448 | + const int64_t in_row_size = input_width * channels; | ||
| 449 | + const int64_t out_row_size = output_width * channels; | ||
| 450 | + auto shard_rows = [&](int start, int end) { | ||
| 451 | + for (int y = start; y < end; ++y) { | ||
| 452 | + float *output_row_data = output + out_row_size * y; | ||
| 453 | + std::fill(output_row_data, output_row_data + out_row_size, 0.0f); | ||
| 454 | + int in_row = starts[y]; | ||
| 455 | + const T *input_row_data = image + in_row_size * in_row; | ||
| 456 | + const float *weights_start = weights + y * span_size; | ||
| 457 | + const int real_span_size = | ||
| 458 | + std::min(starts[y] + span_size, static_cast<int>(input_height)) - starts[y]; | ||
| 459 | + const float *const weights_end = weights_start + real_span_size; | ||
| 460 | + | ||
| 461 | + for (const float *weight_it = weights_start; weight_it != weights_end; ++weight_it) { | ||
| 462 | + AddScaledVector(input_row_data, in_row_size, *weight_it, output_row_data); | ||
| 463 | + input_row_data += in_row_size; | ||
| 464 | + } | ||
| 465 | + } | ||
| 466 | + }; | ||
| 467 | + SWITCH_PARALLEL(shard_rows, output_height, context); | ||
| 468 | + return KERNEL_STATUS_OK; | ||
| 469 | +} | ||
| 470 | + | ||
| 471 | +template <typename T> | ||
| 472 | +uint32_t GatherSpans<T>::operator()( | ||
| 473 | + aicpu::CpuKernelContext &context, int row_span_size, | ||
| 474 | + Eigen::TensorMap<Eigen::Tensor<int32_t, 1>> row_starts, | ||
| 475 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> row_weights, int col_span_size, | ||
| 476 | + Eigen::TensorMap<Eigen::Tensor<int32_t, 1>> col_starts, | ||
| 477 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> col_weights, | ||
| 478 | + typename TTypes<T, 4>::Tensor images, | ||
| 479 | + Eigen::TensorMap<Eigen::Tensor<float, 4>> intermediate_buffer, | ||
| 480 | + typename TTypes<float, 4>::Tensor resized_images) | ||
| 481 | +{ | ||
| 482 | + const int batch_size = images.dimension(0); | ||
| 483 | + const int64_t input_height = images.dimension(1); | ||
| 484 | + const int64_t input_width = images.dimension(2); | ||
| 485 | + const int channels = images.dimension(3); | ||
| 486 | + | ||
| 487 | + const int64_t output_height = resized_images.dimension(1); | ||
| 488 | + const int64_t output_width = resized_images.dimension(2); | ||
| 489 | + | ||
| 490 | + const int64_t input_pix_per_batch = input_width * input_height * channels; | ||
| 491 | + const int64_t intermediate_pix_per_batch = | ||
| 492 | + input_width * output_height * channels; | ||
| 493 | + const int64_t output_pix_per_batch = output_width * output_height * channels; | ||
| 494 | + float *intermediate_ptr = intermediate_buffer.data(); | ||
| 495 | + | ||
| 496 | + const T *image_ptr = images.data(); | ||
| 497 | + float *out_ptr = resized_images.data(); | ||
| 498 | + | ||
| 499 | + auto row_start_data = row_starts.data(); | ||
| 500 | + auto row_weights_data = row_weights.data(); | ||
| 501 | + for (int b = 0; b < batch_size; ++b, image_ptr += input_pix_per_batch, | ||
| 502 | + intermediate_ptr += intermediate_pix_per_batch, | ||
| 503 | + out_ptr += output_pix_per_batch) { | ||
| 504 | + GatherRows(context, row_span_size, row_start_data, row_weights_data, | ||
| 505 | + image_ptr, input_height, input_width, output_height, input_width, | ||
| 506 | + channels, intermediate_ptr); | ||
| 507 | + GatherColumns(context, col_span_size, col_starts.data(), col_weights.data(), | ||
| 508 | + intermediate_ptr, output_height, input_width, output_height, | ||
| 509 | + output_width, channels, out_ptr); | ||
| 510 | + } | ||
| 511 | + return KERNEL_STATUS_OK; | ||
| 512 | +} | ||
| 513 | + | ||
| 514 | +REGISTER_CPU_KERNEL(kScaleAndTranslate, ScaleAndTranslateCpuKernel); | ||
| 515 | +} // namespace aicpu | ||
| @@ -0,0 +1,63 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace aicpu { | ||
| 25 | + | ||
| 26 | +class ScaleAndTranslateCpuKernel : public CpuKernel { | ||
| 27 | +public: | ||
| 28 | + ScaleAndTranslateCpuKernel() = default; | ||
| 29 | + ~ScaleAndTranslateCpuKernel() override = default; | ||
| 30 | + | ||
| 31 | +protected: | ||
| 32 | + uint32_t Compute(CpuKernelContext &ctx) override; | ||
| 33 | + | ||
| 34 | +private: | ||
| 35 | + static uint32_t ScaleAndTranslateCheck(CpuKernelContext &ctx); | ||
| 36 | + | ||
| 37 | + template <typename T> | ||
| 38 | + static uint32_t ScaleAndTranslateCompute(CpuKernelContext &ctx); | ||
| 39 | +}; | ||
| 40 | + | ||
| 41 | +struct Spans { | ||
| 42 | + // The maximum span size of any output pixel. | ||
| 43 | + int span_size; | ||
| 44 | + // int32 tensor of size [output_dim]. | ||
| 45 | + Eigen::Tensor<int32_t, 1> *starts; | ||
| 46 | + // float tensor of size [output_dim, span_size]. | ||
| 47 | + Eigen::Tensor<float, 1> *weights; | ||
| 48 | +}; | ||
| 49 | + | ||
| 50 | +template <typename T> | ||
| 51 | +struct GatherSpans { | ||
| 52 | + uint32_t operator()(aicpu::CpuKernelContext &context, int row_span_size, | ||
| 53 | + Eigen::TensorMap<Eigen::Tensor<int32_t, 1>> row_starts, | ||
| 54 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> row_weights, | ||
| 55 | + int col_span_size, | ||
| 56 | + Eigen::TensorMap<Eigen::Tensor<int32_t, 1>> col_starts, | ||
| 57 | + Eigen::TensorMap<Eigen::Tensor<float, 1>> col_weights, | ||
| 58 | + typename TTypes<T, 4>::Tensor input_images, | ||
| 59 | + Eigen::TensorMap<Eigen::Tensor<float, 4>> intermediate_buffer, | ||
| 60 | + typename TTypes<float, 4>::Tensor output_images); | ||
| 61 | +}; | ||
| 62 | +} // namespace aicpu | ||
| 63 | + | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file scale_and_translate_aicpu_def.cpp | ||
| 13 | + * \brief scale_and_translate def | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | +namespace ops { | ||
| 20 | +class ScaleAndTranslate : public OpDef { | ||
| 21 | +public: | ||
| 22 | + explicit ScaleAndTranslate(const char* name) : OpDef(name) | ||
| 23 | + { | ||
| 24 | + ApplyCvAicpuDefaultCfg(*this); | ||
| 25 | + this->Input("images").DataType( | ||
| 26 | + {ge::DT_INT8, ge::DT_UINT8, ge::DT_INT16, ge::DT_UINT16, | ||
| 27 | + ge::DT_INT32, ge::DT_INT64, ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_DOUBLE}); | ||
| 28 | + this->Input("size").DataType({ge::DT_INT32}); | ||
| 29 | + this->Input("scale").DataType({ge::DT_FLOAT}); | ||
| 30 | + this->Input("translation").DataType({ge::DT_FLOAT}); | ||
| 31 | + this->Output("y").DataType({ge::DT_FLOAT}); | ||
| 32 | + this->Attr("kernel_type").AttrType(OPTIONAL).String("lanczos3"); | ||
| 33 | + this->Attr("antialias").AttrType(OPTIONAL).Bool(true); | ||
| 34 | + this->AICPU().ExtendCfgInfo(OP_INFO_OPS_FLAG.c_str(), OPEN_OPS_FLAG.c_str()); | ||
| 35 | + } | ||
| 36 | +}; | ||
| 37 | + | ||
| 38 | +OP_ADD(ScaleAndTranslate); | ||
| 39 | +} // namespace ops | ||
| @@ -0,0 +1,16 @@ | |||
| 1 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 10 | + | ||
| 11 | +file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | +foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | + add_subdirectory(${SUB_DIR}) | ||
| 15 | + endif() | ||
| 16 | +endforeach() | ||
| @@ -0,0 +1,15 @@ | |||
| 1 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 10 | +file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 11 | +foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 12 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 13 | + add_subdirectory(${SUB_DIR}) | ||
| 14 | + endif() | ||
| 15 | +endforeach() | ||
| @@ -0,0 +1,21 @@ | |||
| 1 | +# --------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# --------------------------------------------------------------------------------------------------------- | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 13 | +foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 14 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | + add_subdirectory(${SUB_DIR}) | ||
| 16 | + endif() | ||
| 17 | +endforeach() | ||
| 18 | + | ||
| 19 | +if(TILING_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY)) | ||
| 20 | + target_sources(ops_cpp_proto_utest PRIVATE test_scale_and_translate_infershape.cpp) | ||
| 21 | +endif() | ||
| @@ -0,0 +1,11 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +// Placeholder for ScaleAndTranslate infershape test | ||
| @@ -0,0 +1,16 @@ | |||
| 1 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 10 | + | ||
| 11 | +file(GLOB CURRENT_SOURCE_DIRS LIST_DIRECTORIES true ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | +foreach(SUB_DIR ${CURRENT_SOURCE_DIRS}) | ||
| 13 | + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | + add_subdirectory(${SUB_DIR}) | ||
| 15 | + endif() | ||
| 16 | +endforeach() | ||
| @@ -0,0 +1,1179 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +using namespace std; | ||
| 24 | +using namespace aicpu; | ||
| 25 | + | ||
| 26 | +class TEST_SCALEANDTRANSLATE_UT : public testing::Test {}; | ||
| 27 | + | ||
| 28 | +template<typename T> | ||
| 29 | +void SetCheckerboardImageInput(int64_t batch_size, int64_t num_row_squares, | ||
| 30 | + int64_t num_col_squares, int64_t square_size, | ||
| 31 | + int64_t num_channels, std::vector<T>& data) { | ||
| 32 | + const int64_t row_size = num_col_squares * square_size * num_channels; | ||
| 33 | + const int64_t image_size = num_row_squares * square_size * row_size; | ||
| 34 | + data.resize(batch_size * image_size); | ||
| 35 | + typedef std::mt19937 RNG_Engine; | ||
| 36 | + RNG_Engine rng; | ||
| 37 | + rng.seed(0); | ||
| 38 | + std::uniform_real_distribution<float> Unifrom_01(0, 1); | ||
| 39 | + std::vector<float> col(num_channels); | ||
| 40 | + for (int b = 0; b < batch_size; ++b) { | ||
| 41 | + for (int y = 0; y < num_row_squares; ++y) { | ||
| 42 | + for (int x = 0; x < num_col_squares; ++x) { | ||
| 43 | + for (int n = 0; n < num_channels; ++n) { | ||
| 44 | + col[n] = Unifrom_01(rng); | ||
| 45 | + } | ||
| 46 | + for (int r = y * square_size; r < (y + 1) * square_size; ++r) { | ||
| 47 | + auto it = data.begin() + b * image_size + r * row_size + | ||
| 48 | + x * square_size * num_channels; | ||
| 49 | + for (int n = 0; n < square_size; ++n) { | ||
| 50 | + for (int chan = 0; chan < num_channels; ++chan, ++it) { | ||
| 51 | + *it = static_cast<T>(col[chan] * 255.0f); | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | + | ||
| 62 | + auto node_def = CpuKernelUtils::CpuKernelUtils::CreateNodeDef(); \ | ||
| 63 | + NodeDefBuilder(node_def.get(), "ScaleAndTranslate", "ScaleAndTranslate") \ | ||
| 64 | + .Input({"images", (data_types)[0], (shapes)[0], (datas)[0]}) \ | ||
| 65 | + .Input({"size", (data_types)[1], (shapes)[1], (datas)[1]}) \ | ||
| 66 | + .Input({"scale", (data_types)[2], (shapes)[2], (datas)[2]}) \ | ||
| 67 | + .Input({"translation", (data_types)[3], (shapes)[3], (datas)[3]}) \ | ||
| 68 | + .Output({"y", (data_types)[4], (shapes)[4], (datas)[4]}) \ | ||
| 69 | + .Attr("kernel_type", std::string(kernel_type_str)) \ | ||
| 70 | + .Attr("antialias", (bool)(antialias)); | ||
| 71 | + | ||
| 72 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_BOX_SUCC) { | ||
| 73 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 74 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 75 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 76 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 77 | + | ||
| 78 | + float image_data[6] = {138.568253f, 70.984192f, 108.251984f, 215.417908f, 1.203308f, 31.000126f}; | ||
| 79 | + int32_t size_data[2] = {4, 6}; | ||
| 80 | + float scale_data[2] = {1.000000f, 1.000000f}; | ||
| 81 | + float translate_data[2] = {0.000000f, 0.000000f}; | ||
| 82 | + | ||
| 83 | + float output[24] = {0}; | ||
| 84 | + float output_exp[24] = { | ||
| 85 | + 138.568253f, 70.984192f, 108.251984f, 0.000000f, 0.000000f, 0.000000f, | ||
| 86 | + 215.417908f, 1.203308f, 31.000126f, 0.000000f, 0.000000f, 0.000000f, | ||
| 87 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 88 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 89 | + | ||
| 90 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 91 | + CREATE_NODEDEF(shapes, data_types, datas, "box", true); | ||
| 92 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 93 | + | ||
| 94 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 95 | + EXPECT_EQ(compare, true); | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_KEYSCUBIC_SUCC) { | ||
| 99 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 100 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 101 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 102 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 103 | + | ||
| 104 | + float image_data[6] = {131.681656f, 145.520233f, 7.260928f, 43.738022f, 174.745636f, 212.643707f}; | ||
| 105 | + int32_t size_data[2] = {4, 6}; | ||
| 106 | + float scale_data[2] = {1.200000f, 1.500000f}; | ||
| 107 | + float translate_data[2] = {0.100000f, 0.200000f}; | ||
| 108 | + | ||
| 109 | + float output[24] = {0}; | ||
| 110 | + float output_exp[24] = { | ||
| 111 | + 136.860214f, 145.327011f, 140.872299f, 29.942684f, -22.839226f, 0.000000f, | ||
| 112 | + 60.625866f, 100.689201f, 167.188705f, 157.434418f, 149.374008f, 0.000000f, | ||
| 113 | + 18.317068f, 75.915985f, 181.793854f, 228.190155f, 244.949417f, 0.000000f, | ||
| 114 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 115 | + | ||
| 116 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 117 | + CREATE_NODEDEF(shapes, data_types, datas, "keyscubic", true); | ||
| 118 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 119 | + | ||
| 120 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 121 | + EXPECT_EQ(compare, true); | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_MITCHELLCUBIC_SUCC) { | ||
| 125 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 126 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 127 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 128 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 129 | + | ||
| 130 | + float image_data[6] = {152.408798f, 172.376663f, 76.316841f, 186.338776f, 147.578552f, 206.299500f}; | ||
| 131 | + int32_t size_data[2] = {4, 6}; | ||
| 132 | + float scale_data[2] = {1.000000f, 1.000000f}; | ||
| 133 | + float translate_data[2] = {0.300000f, 0.100000f}; | ||
| 134 | + | ||
| 135 | + float output[24] = {0}; | ||
| 136 | + float output_exp[24] = { | ||
| 137 | + 151.321594f, 169.369431f, 83.013969f, 0.000000f, 0.000000f, 0.000000f, | ||
| 138 | + 176.018616f, 157.613495f, 166.405380f, 0.000000f, 0.000000f, 0.000000f, | ||
| 139 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 140 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 141 | + | ||
| 142 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 143 | + CREATE_NODEDEF(shapes, data_types, datas, "mitchellcubic", true); | ||
| 144 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 145 | + | ||
| 146 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 147 | + EXPECT_EQ(compare, true); | ||
| 148 | +} | ||
| 149 | + | ||
| 150 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_GAUSSIAN_SUCC) { | ||
| 151 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 152 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 153 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 154 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 155 | + | ||
| 156 | + float image_data[6] = {110.188354f, 44.424892f, 43.590641f, 211.046219f, 149.728668f, 117.135208f}; | ||
| 157 | + int32_t size_data[2] = {4, 6}; | ||
| 158 | + float scale_data[2] = {1.500000f, 1.000000f}; | ||
| 159 | + float translate_data[2] = {0.000000f, 0.300000f}; | ||
| 160 | + | ||
| 161 | + float output[24] = {0}; | ||
| 162 | + float output_exp[24] = { | ||
| 163 | + 114.176651f, 70.930641f, 49.267105f, 0.000000f, 0.000000f, 0.000000f, | ||
| 164 | + 158.128662f, 115.779861f, 85.544647f, 0.000000f, 0.000000f, 0.000000f, | ||
| 165 | + 202.080704f, 160.629074f, 121.822182f, 0.000000f, 0.000000f, 0.000000f, | ||
| 166 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 167 | + | ||
| 168 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 169 | + CREATE_NODEDEF(shapes, data_types, datas, "gaussian", true); | ||
| 170 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 171 | + | ||
| 172 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 173 | + EXPECT_EQ(compare, true); | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT32_BOX_SUCC) { | ||
| 177 | + vector<DataType> data_types = {DT_INT32, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 178 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 179 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 180 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 181 | + | ||
| 182 | + int32_t image_data[6] = {26, 105, 16, 68, 42, 183}; | ||
| 183 | + int32_t size_data[2] = {4, 6}; | ||
| 184 | + float scale_data[2] = {1.000000f, 1.000000f}; | ||
| 185 | + float translate_data[2] = {0.000000f, 0.000000f}; | ||
| 186 | + | ||
| 187 | + float output[24] = {0}; | ||
| 188 | + float output_exp[24] = { | ||
| 189 | + 26.000000f, 105.000000f, 16.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 190 | + 68.000000f, 42.000000f, 183.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 191 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 192 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 193 | + | ||
| 194 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 195 | + CREATE_NODEDEF(shapes, data_types, datas, "box", false); | ||
| 196 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 197 | + | ||
| 198 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 199 | + EXPECT_EQ(compare, true); | ||
| 200 | +} | ||
| 201 | + | ||
| 202 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT32_KEYSCUBIC_SUCC) { | ||
| 203 | + vector<DataType> data_types = {DT_INT32, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 204 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 205 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 206 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 207 | + | ||
| 208 | + int32_t image_data[6] = {0, 41, 0, 97, 100, 245}; | ||
| 209 | + int32_t size_data[2] = {4, 6}; | ||
| 210 | + float scale_data[2] = {1.300000f, 1.200000f}; | ||
| 211 | + float translate_data[2] = {0.200000f, 0.100000f}; | ||
| 212 | + | ||
| 213 | + float output[24] = {0}; | ||
| 214 | + float output_exp[24] = { | ||
| 215 | + -11.912914f, 25.384739f, 7.328219f, -28.820704f, 0.000000f, 0.000000f, | ||
| 216 | + 47.052631f, 59.714275f, 99.323532f, 127.973701f, 0.000000f, 0.000000f, | ||
| 217 | + 106.018173f, 94.043808f, 191.318848f, 284.768097f, 0.000000f, 0.000000f, | ||
| 218 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 219 | + | ||
| 220 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 221 | + CREATE_NODEDEF(shapes, data_types, datas, "keyscubic", false); | ||
| 222 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 223 | + | ||
| 224 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 225 | + EXPECT_EQ(compare, true); | ||
| 226 | +} | ||
| 227 | + | ||
| 228 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT32_MITCHELLCUBIC_SUCC) { | ||
| 229 | + vector<DataType> data_types = {DT_INT32, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 230 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 231 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 232 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 233 | + | ||
| 234 | + int32_t image_data[6] = {147, 151, 60, 204, 40, 169}; | ||
| 235 | + int32_t size_data[2] = {4, 6}; | ||
| 236 | + float scale_data[2] = {1.000000f, 1.500000f}; | ||
| 237 | + float translate_data[2] = {0.100000f, 0.000000f}; | ||
| 238 | + | ||
| 239 | + float output[24] = {0}; | ||
| 240 | + float output_exp[24] = { | ||
| 241 | + 147.859848f, 151.504288f, 134.076508f, 76.278763f, 55.579456f, 0.000000f, | ||
| 242 | + 198.232605f, 124.231392f, 70.288658f, 137.711273f, 162.962631f, 0.000000f, | ||
| 243 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 244 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 245 | + | ||
| 246 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 247 | + CREATE_NODEDEF(shapes, data_types, datas, "mitchellcubic", false); | ||
| 248 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 249 | + | ||
| 250 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 251 | + EXPECT_EQ(compare, true); | ||
| 252 | +} | ||
| 253 | + | ||
| 254 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT32_GAUSSIAN_SUCC) { | ||
| 255 | + vector<DataType> data_types = {DT_INT32, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 256 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 257 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 258 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 259 | + | ||
| 260 | + int32_t image_data[6] = {108, 133, 220, 146, 8, 81}; | ||
| 261 | + int32_t size_data[2] = {4, 6}; | ||
| 262 | + float scale_data[2] = {1.500000f, 1.300000f}; | ||
| 263 | + float translate_data[2] = {0.000000f, 0.200000f}; | ||
| 264 | + | ||
| 265 | + float output[24] = {0}; | ||
| 266 | + float output_exp[24] = { | ||
| 267 | + 111.103859f, 117.673843f, 148.115021f, 202.018265f, 0.000000f, 0.000000f, | ||
| 268 | + 124.510078f, 98.750000f, 94.324577f, 142.182220f, 0.000000f, 0.000000f, | ||
| 269 | + 137.916306f, 79.826157f, 40.534134f, 82.346161f, 0.000000f, 0.000000f, | ||
| 270 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 271 | + | ||
| 272 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 273 | + CREATE_NODEDEF(shapes, data_types, datas, "gaussian", false); | ||
| 274 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 275 | + | ||
| 276 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 277 | + EXPECT_EQ(compare, true); | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT32_LANCZOS1_SUCC) { | ||
| 281 | + vector<DataType> data_types = {DT_INT32, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 282 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 283 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 284 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 285 | + | ||
| 286 | + int32_t image_data[6] = {65, 252, 245, 13, 229, 26}; | ||
| 287 | + int32_t size_data[2] = {4, 6}; | ||
| 288 | + float scale_data[2] = {1.000000f, 1.000000f}; | ||
| 289 | + float translate_data[2] = {0.000000f, 0.000000f}; | ||
| 290 | + | ||
| 291 | + float output[24] = {0}; | ||
| 292 | + float output_exp[24] = { | ||
| 293 | + 65.000000f, 252.000000f, 245.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 294 | + 13.000000f, 229.000000f, 26.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 295 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 296 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 297 | + | ||
| 298 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 299 | + CREATE_NODEDEF(shapes, data_types, datas, "lanczos1", true); | ||
| 300 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 301 | + | ||
| 302 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 303 | + EXPECT_EQ(compare, true); | ||
| 304 | +} | ||
| 305 | + | ||
| 306 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT64_LANCZOS1_SUCC) { | ||
| 307 | + vector<DataType> data_types = {DT_INT64, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 308 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 309 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 310 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 311 | + | ||
| 312 | + int64_t image_data[6] = {66, 36, 238, 184, 221, 148}; | ||
| 313 | + int32_t size_data[2] = {4, 6}; | ||
| 314 | + float scale_data[2] = {1.200000f, 1.000000f}; | ||
| 315 | + float translate_data[2] = {0.100000f, 0.100000f}; | ||
| 316 | + | ||
| 317 | + float output[24] = {0}; | ||
| 318 | + float output_exp[24] = { | ||
| 319 | + 66.000000f, 36.365852f, 235.536621f, 0.000000f, 0.000000f, 0.000000f, | ||
| 320 | + 160.399994f, 183.712189f, 166.219543f, 0.000000f, 0.000000f, 0.000000f, | ||
| 321 | + 184.000000f, 220.548782f, 148.890259f, 0.000000f, 0.000000f, 0.000000f, | ||
| 322 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 323 | + | ||
| 324 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 325 | + CREATE_NODEDEF(shapes, data_types, datas, "lanczos1", false); | ||
| 326 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 327 | + | ||
| 328 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 329 | + EXPECT_EQ(compare, true); | ||
| 330 | +} | ||
| 331 | + | ||
| 332 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT16_LANCZOS3_SUCC) { | ||
| 333 | + vector<DataType> data_types = {DT_INT16, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 334 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 335 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 336 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 337 | + | ||
| 338 | + int16_t image_data[6] = {21, 210, 200, 164, 62, 202}; | ||
| 339 | + int32_t size_data[2] = {4, 6}; | ||
| 340 | + float scale_data[2] = {1.000000f, 1.200000f}; | ||
| 341 | + float translate_data[2] = {0.000000f, 0.100000f}; | ||
| 342 | + | ||
| 343 | + float output[24] = {0}; | ||
| 344 | + float output_exp[24] = { | ||
| 345 | + 3.307576f, 142.551056f, 228.000000f, 189.905411f, 0.000000f, 0.000000f, | ||
| 346 | + 177.385513f, 79.621498f, 128.000000f, 229.652969f, 0.000000f, 0.000000f, | ||
| 347 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 348 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 349 | + | ||
| 350 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 351 | + CREATE_NODEDEF(shapes, data_types, datas, "lanczos3", false); | ||
| 352 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 353 | + | ||
| 354 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 355 | + EXPECT_EQ(compare, true); | ||
| 356 | +} | ||
| 357 | + | ||
| 358 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_UINT16_LANCZOS3_SUCC) { | ||
| 359 | + vector<DataType> data_types = {DT_UINT16, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 360 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 361 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 362 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 363 | + | ||
| 364 | + uint16_t image_data[6] = {6, 50, 181, 160, 78, 1}; | ||
| 365 | + int32_t size_data[2] = {4, 6}; | ||
| 366 | + float scale_data[2] = {1.000000f, 1.000000f}; | ||
| 367 | + float translate_data[2] = {0.200000f, 0.000000f}; | ||
| 368 | + | ||
| 369 | + float output[24] = {0}; | ||
| 370 | + float output_exp[24] = { | ||
| 371 | + -16.416292f, 45.924309f, 207.200882f, 0.000000f, 0.000000f, 0.000000f, | ||
| 372 | + 131.879150f, 72.887115f, 33.868526f, 0.000000f, 0.000000f, 0.000000f, | ||
| 373 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 374 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 375 | + | ||
| 376 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 377 | + CREATE_NODEDEF(shapes, data_types, datas, "lanczos3", false); | ||
| 378 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 379 | + | ||
| 380 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 381 | + EXPECT_EQ(compare, true); | ||
| 382 | +} | ||
| 383 | + | ||
| 384 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_LANCZOS3_SUCC) { | ||
| 385 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 386 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 387 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 388 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 389 | + | ||
| 390 | + float image_data[6] = {28.281147f, 206.032852f, 17.464172f, 244.885483f, 249.871445f, 92.243668f}; | ||
| 391 | + int32_t size_data[2] = {4, 6}; | ||
| 392 | + float scale_data[2] = {1.500000f, 1.500000f}; | ||
| 393 | + float translate_data[2] = {0.000000f, 0.000000f}; | ||
| 394 | + | ||
| 395 | + float output[24] = {0}; | ||
| 396 | + float output_exp[24] = { | ||
| 397 | + -22.442028f, 112.591362f, 189.377502f, 38.449009f, -44.437092f, 0.000000f, | ||
| 398 | + 123.233429f, 198.194443f, 208.764771f, 78.613449f, 11.813992f, 0.000000f, | ||
| 399 | + 268.908905f, 283.797546f, 228.152069f, 118.777908f, 68.065079f, 0.000000f, | ||
| 400 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 401 | + | ||
| 402 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 403 | + CREATE_NODEDEF(shapes, data_types, datas, "lanczos3", true); | ||
| 404 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 405 | + | ||
| 406 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 407 | + EXPECT_EQ(compare, true); | ||
| 408 | +} | ||
| 409 | + | ||
| 410 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT8_LANCZOS5_SUCC) { | ||
| 411 | + vector<DataType> data_types = {DT_INT8, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 412 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 413 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 414 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 415 | + | ||
| 416 | + int8_t image_data[6] = {-34, 125, -16, -95, 71, -22}; | ||
| 417 | + int32_t size_data[2] = {4, 6}; | ||
| 418 | + float scale_data[2] = {1.000000f, 1.000000f}; | ||
| 419 | + float translate_data[2] = {0.100000f, 0.200000f}; | ||
| 420 | + | ||
| 421 | + float output[24] = {0}; | ||
| 422 | + float output_exp[24] = { | ||
| 423 | + -53.807579f, 115.260719f, 15.897320f, 0.000000f, 0.000000f, 0.000000f, | ||
| 424 | + -111.851692f, 53.257767f, 4.182123f, 0.000000f, 0.000000f, 0.000000f, | ||
| 425 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 426 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 427 | + | ||
| 428 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 429 | + CREATE_NODEDEF(shapes, data_types, datas, "lanczos5", true); | ||
| 430 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 431 | + | ||
| 432 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 433 | + EXPECT_EQ(compare, true); | ||
| 434 | +} | ||
| 435 | + | ||
| 436 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_UINT8_LANCZOS5_SUCC) { | ||
| 437 | + vector<DataType> data_types = {DT_UINT8, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 438 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 439 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 440 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 441 | + | ||
| 442 | + uint8_t image_data[6] = {10, 103, 236, 133, 134, 100}; | ||
| 443 | + int32_t size_data[2] = {4, 6}; | ||
| 444 | + float scale_data[2] = {1.300000f, 1.000000f}; | ||
| 445 | + float translate_data[2] = {0.000000f, 0.100000f}; | ||
| 446 | + | ||
| 447 | + float output[24] = {0}; | ||
| 448 | + float output_exp[24] = { | ||
| 449 | + -2.695577f, 76.776100f, 245.176254f, 0.000000f, 0.000000f, 0.000000f, | ||
| 450 | + 90.168655f, 118.175423f, 146.308121f, 0.000000f, 0.000000f, 0.000000f, | ||
| 451 | + 174.934570f, 155.964462f, 56.061882f, 0.000000f, 0.000000f, 0.000000f, | ||
| 452 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 453 | + | ||
| 454 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 455 | + CREATE_NODEDEF(shapes, data_types, datas, "lanczos5", true); | ||
| 456 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 457 | + | ||
| 458 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 459 | + EXPECT_EQ(compare, true); | ||
| 460 | +} | ||
| 461 | + | ||
| 462 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_DOUBLE_TRIANGLE_SUCC) { | ||
| 463 | + vector<DataType> data_types = {DT_DOUBLE, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 464 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 465 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 466 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 467 | + | ||
| 468 | + double image_data[6] = {199.2488598334, 176.6713594530, 247.2630374143, 8.2623258913, 249.9158586850, 76.1476041631}; | ||
| 469 | + int32_t size_data[2] = {4, 6}; | ||
| 470 | + float scale_data[2] = {1.000000f, 1.000000f}; | ||
| 471 | + float translate_data[2] = {0.000000f, 0.000000f}; | ||
| 472 | + | ||
| 473 | + float output[24] = {0}; | ||
| 474 | + float output_exp[24] = { | ||
| 475 | + 199.248856f, 176.671356f, 247.263031f, 0.000000f, 0.000000f, 0.000000f, | ||
| 476 | + 8.262326f, 249.915863f, 76.147606f, 0.000000f, 0.000000f, 0.000000f, | ||
| 477 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, | ||
| 478 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 479 | + | ||
| 480 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 481 | + CREATE_NODEDEF(shapes, data_types, datas, "triangle", false); | ||
| 482 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 483 | + | ||
| 484 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 485 | + EXPECT_EQ(compare, true); | ||
| 486 | +} | ||
| 487 | + | ||
| 488 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT16_TRIANGLE_SUCC) { | ||
| 489 | + vector<DataType> data_types = {DT_FLOAT16, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 490 | + vector<int64_t> in_shape = {1, 2, 3, 1}; | ||
| 491 | + vector<int64_t> out_shape = {1, 4, 6, 1}; | ||
| 492 | + vector<vector<int64_t>> shapes = {in_shape, {2}, {2}, {2}, out_shape}; | ||
| 493 | + | ||
| 494 | + Eigen::half image_data[6] = {Eigen::half(59.3750f), Eigen::half(232.5000f), Eigen::half(13.0156f), Eigen::half(2.5527f), Eigen::half(79.8750f), Eigen::half(77.2500f)}; | ||
| 495 | + int32_t size_data[2] = {4, 6}; | ||
| 496 | + float scale_data[2] = {1.200000f, 1.200000f}; | ||
| 497 | + float translate_data[2] = {0.100000f, 0.100000f}; | ||
| 498 | + | ||
| 499 | + float output[24] = {0}; | ||
| 500 | + float output_exp[24] = { | ||
| 501 | + 59.375000f, 174.791656f, 122.757812f, 13.015625f, 0.000000f, 0.000000f, | ||
| 502 | + 21.493492f, 94.331161f, 93.294266f, 55.838539f, 0.000000f, 0.000000f, | ||
| 503 | + 2.552734f, 54.100910f, 78.562500f, 77.250000f, 0.000000f, 0.000000f, | ||
| 504 | + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; | ||
| 505 | + | ||
| 506 | + vector<void*> datas = {(void*)image_data, (void*)size_data, (void*)scale_data, (void*)translate_data, (void*)output}; | ||
| 507 | + CREATE_NODEDEF(shapes, data_types, datas, "triangle", false); | ||
| 508 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 509 | + | ||
| 510 | + bool compare = CompareResult(output, output_exp, 24); | ||
| 511 | + EXPECT_EQ(compare, true); | ||
| 512 | +} | ||
| 513 | + | ||
| 514 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_BOX_SUCC) { | ||
| 515 | + std::vector<float> data; | ||
| 516 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 517 | + int64_t kBatchSize_exp = 2; | ||
| 518 | + int64_t kNumRowSquares_exp = 16; | ||
| 519 | + int64_t kNumColSquares_exp = 13; | ||
| 520 | + int64_t kSquareSize_exp = 12; | ||
| 521 | + int64_t kNumChannels_exp = 3; | ||
| 522 | + | ||
| 523 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 524 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 525 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 526 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 527 | + | ||
| 528 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 529 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 530 | + | ||
| 531 | + float scale_data[2] = {0.5, 0.5}; | ||
| 532 | + | ||
| 533 | + float translate_data[2] = {0.5, 0.5}; | ||
| 534 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 535 | + vector<int64_t> sizeshape ={2}; | ||
| 536 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 537 | + float* output = new float[outputshape]; | ||
| 538 | + | ||
| 539 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 540 | + | ||
| 541 | + float* data_arr = new float[data.size()]; | ||
| 542 | + | ||
| 543 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 544 | + | ||
| 545 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 546 | + std::string kernel_type_str = "box"; | ||
| 547 | + bool antialias = false; | ||
| 548 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 549 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 550 | + delete [] data_arr; | ||
| 551 | + delete [] output; | ||
| 552 | +} | ||
| 553 | + | ||
| 554 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_LANCZOS1_SUCC) { | ||
| 555 | + std::vector<float> data; | ||
| 556 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 557 | + int64_t kBatchSize_exp = 4; | ||
| 558 | + int64_t kNumRowSquares_exp = 20; | ||
| 559 | + int64_t kNumColSquares_exp = 15; | ||
| 560 | + int64_t kSquareSize_exp = 13; | ||
| 561 | + int64_t kNumChannels_exp = 3; | ||
| 562 | + | ||
| 563 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 564 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 565 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 566 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 567 | + | ||
| 568 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 569 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 570 | + | ||
| 571 | + float scale_data[2] = {0.5, 0.5}; | ||
| 572 | + | ||
| 573 | + float translate_data[2] = {0.5, 0.5}; | ||
| 574 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 575 | + vector<int64_t> sizeshape ={2}; | ||
| 576 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 577 | + float* output = new float[outputshape]; | ||
| 578 | + | ||
| 579 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 580 | + | ||
| 581 | + float* data_arr = new float[data.size()]; | ||
| 582 | + | ||
| 583 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 584 | + | ||
| 585 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 586 | + std::string kernel_type_str = "lanczos1"; | ||
| 587 | + bool antialias = false; | ||
| 588 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 589 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 590 | + delete [] data_arr; | ||
| 591 | + delete [] output; | ||
| 592 | +} | ||
| 593 | + | ||
| 594 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_LANCZOS3_SUCC) { | ||
| 595 | + std::vector<float> data; | ||
| 596 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 597 | + int64_t kBatchSize_exp = 4; | ||
| 598 | + int64_t kNumRowSquares_exp = 20; | ||
| 599 | + int64_t kNumColSquares_exp = 15; | ||
| 600 | + int64_t kSquareSize_exp = 13; | ||
| 601 | + int64_t kNumChannels_exp = 3; | ||
| 602 | + | ||
| 603 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 604 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 605 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 606 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 607 | + | ||
| 608 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 609 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 610 | + | ||
| 611 | + float scale_data[2] = {0.5, 0.5}; | ||
| 612 | + | ||
| 613 | + float translate_data[2] = {0.5, 0.5}; | ||
| 614 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 615 | + vector<int64_t> sizeshape ={2}; | ||
| 616 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 617 | + float* output = new float[outputshape]; | ||
| 618 | + | ||
| 619 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 620 | + | ||
| 621 | + float* data_arr = new float[data.size()]; | ||
| 622 | + | ||
| 623 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 624 | + | ||
| 625 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 626 | + std::string kernel_type_str = "lanczos3"; | ||
| 627 | + bool antialias = false; | ||
| 628 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 629 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 630 | + delete [] data_arr; | ||
| 631 | + delete [] output; | ||
| 632 | +} | ||
| 633 | + | ||
| 634 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_LANCZOS5_SUCC) { | ||
| 635 | + std::vector<float> data; | ||
| 636 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 637 | + int64_t kBatchSize_exp = 4; | ||
| 638 | + int64_t kNumRowSquares_exp = 20; | ||
| 639 | + int64_t kNumColSquares_exp = 15; | ||
| 640 | + int64_t kSquareSize_exp = 13; | ||
| 641 | + int64_t kNumChannels_exp = 3; | ||
| 642 | + | ||
| 643 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 644 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 645 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 646 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 647 | + | ||
| 648 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 649 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 650 | + | ||
| 651 | + float scale_data[2] = {0.5, 0.5}; | ||
| 652 | + | ||
| 653 | + float translate_data[2] = {0.5, 0.5}; | ||
| 654 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 655 | + vector<int64_t> sizeshape ={2}; | ||
| 656 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 657 | + float* output = new float[outputshape]; | ||
| 658 | + | ||
| 659 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 660 | + | ||
| 661 | + float* data_arr = new float[data.size()]; | ||
| 662 | + | ||
| 663 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 664 | + | ||
| 665 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 666 | + std::string kernel_type_str = "lanczos5"; | ||
| 667 | + bool antialias = false; | ||
| 668 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 669 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 670 | + delete [] data_arr; | ||
| 671 | + delete [] output; | ||
| 672 | +} | ||
| 673 | + | ||
| 674 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_GAUSSIAN_SUCC) { | ||
| 675 | + std::vector<float> data; | ||
| 676 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 677 | + int64_t kBatchSize_exp = 4; | ||
| 678 | + int64_t kNumRowSquares_exp = 20; | ||
| 679 | + int64_t kNumColSquares_exp = 15; | ||
| 680 | + int64_t kSquareSize_exp = 13; | ||
| 681 | + int64_t kNumChannels_exp = 3; | ||
| 682 | + | ||
| 683 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 684 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 685 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 686 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 687 | + | ||
| 688 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 689 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 690 | + | ||
| 691 | + float scale_data[2] = {0.5, 0.5}; | ||
| 692 | + | ||
| 693 | + float translate_data[2] = {0.5, 0.5}; | ||
| 694 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 695 | + vector<int64_t> sizeshape ={2}; | ||
| 696 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 697 | + float* output = new float[outputshape]; | ||
| 698 | + | ||
| 699 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 700 | + | ||
| 701 | + float* data_arr = new float[data.size()]; | ||
| 702 | + | ||
| 703 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 704 | + | ||
| 705 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 706 | + std::string kernel_type_str = "gaussian"; | ||
| 707 | + bool antialias = false; | ||
| 708 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 709 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 710 | + delete [] data_arr; | ||
| 711 | + delete [] output; | ||
| 712 | +} | ||
| 713 | + | ||
| 714 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_TRIANGLE_SUCC) { | ||
| 715 | + std::vector<float> data; | ||
| 716 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 717 | + int64_t kBatchSize_exp = 4; | ||
| 718 | + int64_t kNumRowSquares_exp = 20; | ||
| 719 | + int64_t kNumColSquares_exp = 15; | ||
| 720 | + int64_t kSquareSize_exp = 13; | ||
| 721 | + int64_t kNumChannels_exp = 3; | ||
| 722 | + | ||
| 723 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 724 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 725 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 726 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 727 | + | ||
| 728 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 729 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 730 | + | ||
| 731 | + float scale_data[2] = {0.5, 0.5}; | ||
| 732 | + | ||
| 733 | + float translate_data[2] = {0.5, 0.5}; | ||
| 734 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 735 | + vector<int64_t> sizeshape ={2}; | ||
| 736 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 737 | + float* output = new float[outputshape]; | ||
| 738 | + | ||
| 739 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 740 | + | ||
| 741 | + float* data_arr = new float[data.size()]; | ||
| 742 | + | ||
| 743 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 744 | + | ||
| 745 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 746 | + std::string kernel_type_str = "triangle"; | ||
| 747 | + bool antialias = false; | ||
| 748 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 749 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 750 | + delete [] data_arr; | ||
| 751 | + delete [] output; | ||
| 752 | +} | ||
| 753 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_KEYSCUBIC_SUCC) { | ||
| 754 | + std::vector<float> data; | ||
| 755 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 756 | + int64_t kBatchSize_exp = 4; | ||
| 757 | + int64_t kNumRowSquares_exp = 20; | ||
| 758 | + int64_t kNumColSquares_exp = 15; | ||
| 759 | + int64_t kSquareSize_exp = 13; | ||
| 760 | + int64_t kNumChannels_exp = 3; | ||
| 761 | + | ||
| 762 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 763 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 764 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 765 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 766 | + | ||
| 767 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 768 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 769 | + | ||
| 770 | + float scale_data[2] = {0.5, 0.5}; | ||
| 771 | + | ||
| 772 | + float translate_data[2] = {0.5, 0.5}; | ||
| 773 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 774 | + vector<int64_t> sizeshape ={2}; | ||
| 775 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 776 | + float* output = new float[outputshape]; | ||
| 777 | + | ||
| 778 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 779 | + | ||
| 780 | + float* data_arr = new float[data.size()]; | ||
| 781 | + | ||
| 782 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 783 | + | ||
| 784 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 785 | + std::string kernel_type_str = "keyscubic"; | ||
| 786 | + bool antialias = false; | ||
| 787 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 788 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 789 | + delete [] data_arr; | ||
| 790 | + delete [] output; | ||
| 791 | +} | ||
| 792 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT_METHOD_MITCHELLCUBIC_SUCC) { | ||
| 793 | + std::vector<float> data; | ||
| 794 | + vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 795 | + int64_t kBatchSize_exp = 4; | ||
| 796 | + int64_t kNumRowSquares_exp = 20; | ||
| 797 | + int64_t kNumColSquares_exp = 15; | ||
| 798 | + int64_t kSquareSize_exp = 13; | ||
| 799 | + int64_t kNumChannels_exp = 3; | ||
| 800 | + | ||
| 801 | + SetCheckerboardImageInput<float> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 802 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 803 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 804 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 805 | + | ||
| 806 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 807 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 808 | + | ||
| 809 | + float scale_data[2] = {0.5, 0.5}; | ||
| 810 | + | ||
| 811 | + float translate_data[2] = {0.5, 0.5}; | ||
| 812 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 813 | + vector<int64_t> sizeshape ={2}; | ||
| 814 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 815 | + float* output = new float[outputshape]; | ||
| 816 | + | ||
| 817 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 818 | + | ||
| 819 | + float* data_arr = new float[data.size()]; | ||
| 820 | + | ||
| 821 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 822 | + | ||
| 823 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 824 | + std::string kernel_type_str = "mitchellcubic"; | ||
| 825 | + bool antialias = false; | ||
| 826 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 827 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 828 | + delete [] data_arr; | ||
| 829 | + delete [] output; | ||
| 830 | +} | ||
| 831 | + | ||
| 832 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT8_METHOD_BOX_SUCC) { | ||
| 833 | + std::vector<int8_t> data; | ||
| 834 | + vector<DataType> data_types = {DT_INT8, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 835 | + int64_t kBatchSize_exp = 2; | ||
| 836 | + int64_t kNumRowSquares_exp = 16; | ||
| 837 | + int64_t kNumColSquares_exp = 13; | ||
| 838 | + int64_t kSquareSize_exp = 12; | ||
| 839 | + int64_t kNumChannels_exp = 3; | ||
| 840 | + | ||
| 841 | + SetCheckerboardImageInput<int8_t> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 842 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 843 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 844 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 845 | + | ||
| 846 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 847 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 848 | + | ||
| 849 | + float scale_data[2] = {0.5, 0.5}; | ||
| 850 | + | ||
| 851 | + float translate_data[2] = {0.5, 0.5}; | ||
| 852 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 853 | + vector<int64_t> sizeshape ={2}; | ||
| 854 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 855 | + float* output = new float[outputshape]; | ||
| 856 | + | ||
| 857 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 858 | + | ||
| 859 | + int8_t* data_arr = new int8_t[data.size()]; | ||
| 860 | + | ||
| 861 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 862 | + | ||
| 863 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 864 | + std::string kernel_type_str = "box"; | ||
| 865 | + bool antialias = false; | ||
| 866 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 867 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 868 | + delete [] data_arr; | ||
| 869 | + delete [] output; | ||
| 870 | +} | ||
| 871 | + | ||
| 872 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT16_METHOD_BOX_SUCC) { | ||
| 873 | + std::vector<int16_t> data; | ||
| 874 | + vector<DataType> data_types = {DT_INT16, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 875 | + int64_t kBatchSize_exp = 2; | ||
| 876 | + int64_t kNumRowSquares_exp = 16; | ||
| 877 | + int64_t kNumColSquares_exp = 13; | ||
| 878 | + int64_t kSquareSize_exp = 12; | ||
| 879 | + int64_t kNumChannels_exp = 3; | ||
| 880 | + | ||
| 881 | + SetCheckerboardImageInput<int16_t> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 882 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 883 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 884 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 885 | + | ||
| 886 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 887 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 888 | + | ||
| 889 | + float scale_data[2] = {0.5, 0.5}; | ||
| 890 | + | ||
| 891 | + float translate_data[2] = {0.5, 0.5}; | ||
| 892 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 893 | + vector<int64_t> sizeshape ={2}; | ||
| 894 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 895 | + float* output = new float[outputshape]; | ||
| 896 | + | ||
| 897 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 898 | + | ||
| 899 | + int16_t* data_arr = new int16_t[data.size()]; | ||
| 900 | + | ||
| 901 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 902 | + | ||
| 903 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 904 | + std::string kernel_type_str = "box"; | ||
| 905 | + bool antialias = false; | ||
| 906 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 907 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 908 | + delete [] data_arr; | ||
| 909 | + delete [] output; | ||
| 910 | +} | ||
| 911 | + | ||
| 912 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT32_METHOD_BOX_SUCC) { | ||
| 913 | + std::vector<int32_t> data; | ||
| 914 | + vector<DataType> data_types = {DT_INT32, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 915 | + int64_t kBatchSize_exp = 2; | ||
| 916 | + int64_t kNumRowSquares_exp = 16; | ||
| 917 | + int64_t kNumColSquares_exp = 13; | ||
| 918 | + int64_t kSquareSize_exp = 12; | ||
| 919 | + int64_t kNumChannels_exp = 3; | ||
| 920 | + | ||
| 921 | + SetCheckerboardImageInput<int32_t> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 922 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 923 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 924 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 925 | + | ||
| 926 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 927 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 928 | + | ||
| 929 | + float scale_data[2] = {0.5, 0.5}; | ||
| 930 | + | ||
| 931 | + float translate_data[2] = {0.5, 0.5}; | ||
| 932 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 933 | + vector<int64_t> sizeshape ={2}; | ||
| 934 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 935 | + float* output = new float[outputshape]; | ||
| 936 | + | ||
| 937 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 938 | + | ||
| 939 | + int32_t* data_arr = new int32_t[data.size()]; | ||
| 940 | + | ||
| 941 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 942 | + | ||
| 943 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 944 | + std::string kernel_type_str = "box"; | ||
| 945 | + bool antialias = false; | ||
| 946 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 947 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 948 | + delete [] data_arr; | ||
| 949 | + delete [] output; | ||
| 950 | + | ||
| 951 | +} | ||
| 952 | + | ||
| 953 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_UINT8_METHOD_BOX_SUCC) { | ||
| 954 | + std::vector<uint8_t> data; | ||
| 955 | + vector<DataType> data_types = {DT_UINT8, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 956 | + int64_t kBatchSize_exp = 2; | ||
| 957 | + int64_t kNumRowSquares_exp = 16; | ||
| 958 | + int64_t kNumColSquares_exp = 13; | ||
| 959 | + int64_t kSquareSize_exp = 12; | ||
| 960 | + int64_t kNumChannels_exp = 3; | ||
| 961 | + | ||
| 962 | + SetCheckerboardImageInput<uint8_t> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 963 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 964 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 965 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 966 | + | ||
| 967 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 968 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 969 | + | ||
| 970 | + float scale_data[2] = {0.5, 0.5}; | ||
| 971 | + | ||
| 972 | + float translate_data[2] = {0.5, 0.5}; | ||
| 973 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 974 | + vector<int64_t> sizeshape ={2}; | ||
| 975 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 976 | + float* output = new float[outputshape]; | ||
| 977 | + | ||
| 978 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 979 | + | ||
| 980 | + uint8_t* data_arr = new uint8_t[data.size()]; | ||
| 981 | + | ||
| 982 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 983 | + | ||
| 984 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 985 | + std::string kernel_type_str = "box"; | ||
| 986 | + bool antialias = false; | ||
| 987 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 988 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 989 | + delete [] data_arr; | ||
| 990 | + delete [] output; | ||
| 991 | +} | ||
| 992 | + | ||
| 993 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_UINT16_METHOD_BOX_SUCC) { | ||
| 994 | + std::vector<uint16_t> data; | ||
| 995 | + vector<DataType> data_types = {DT_UINT16, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 996 | + int64_t kBatchSize_exp = 2; | ||
| 997 | + int64_t kNumRowSquares_exp = 16; | ||
| 998 | + int64_t kNumColSquares_exp = 13; | ||
| 999 | + int64_t kSquareSize_exp = 12; | ||
| 1000 | + int64_t kNumChannels_exp = 3; | ||
| 1001 | + | ||
| 1002 | + SetCheckerboardImageInput<uint16_t> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 1003 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 1004 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 1005 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 1006 | + | ||
| 1007 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 1008 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 1009 | + | ||
| 1010 | + float scale_data[2] = {0.5, 0.5}; | ||
| 1011 | + | ||
| 1012 | + float translate_data[2] = {0.5, 0.5}; | ||
| 1013 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 1014 | + vector<int64_t> sizeshape ={2}; | ||
| 1015 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 1016 | + float* output = new float[outputshape]; | ||
| 1017 | + | ||
| 1018 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 1019 | + | ||
| 1020 | + uint16_t* data_arr = new uint16_t[data.size()]; | ||
| 1021 | + | ||
| 1022 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 1023 | + | ||
| 1024 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 1025 | + std::string kernel_type_str = "box"; | ||
| 1026 | + bool antialias = false; | ||
| 1027 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 1028 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 1029 | + delete [] data_arr; | ||
| 1030 | + delete [] output; | ||
| 1031 | +} | ||
| 1032 | + | ||
| 1033 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_INT64_METHOD_BOX_SUCC) { | ||
| 1034 | + std::vector<int64_t> data; | ||
| 1035 | + vector<DataType> data_types = {DT_INT64, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 1036 | + int64_t kBatchSize_exp = 2; | ||
| 1037 | + int64_t kNumRowSquares_exp = 16; | ||
| 1038 | + int64_t kNumColSquares_exp = 13; | ||
| 1039 | + int64_t kSquareSize_exp = 12; | ||
| 1040 | + int64_t kNumChannels_exp = 3; | ||
| 1041 | + | ||
| 1042 | + SetCheckerboardImageInput<int64_t> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 1043 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 1044 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 1045 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 1046 | + | ||
| 1047 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 1048 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 1049 | + | ||
| 1050 | + float scale_data[2] = {0.5, 0.5}; | ||
| 1051 | + | ||
| 1052 | + float translate_data[2] = {0.5, 0.5}; | ||
| 1053 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 1054 | + vector<int64_t> sizeshape ={2}; | ||
| 1055 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 1056 | + float* output = new float[outputshape]; | ||
| 1057 | + | ||
| 1058 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 1059 | + | ||
| 1060 | + int64_t* data_arr = new int64_t[data.size()]; | ||
| 1061 | + | ||
| 1062 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 1063 | + | ||
| 1064 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 1065 | + std::string kernel_type_str = "box"; | ||
| 1066 | + bool antialias = false; | ||
| 1067 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 1068 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 1069 | + delete [] data_arr; | ||
| 1070 | + delete [] output; | ||
| 1071 | + | ||
| 1072 | +} | ||
| 1073 | + | ||
| 1074 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_FLOAT16_METHOD_BOX_SUCC) { | ||
| 1075 | + std::vector<Eigen::half> data; | ||
| 1076 | + vector<DataType> data_types = {DT_FLOAT16, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 1077 | + int64_t kBatchSize_exp = 2; | ||
| 1078 | + int64_t kNumRowSquares_exp = 16; | ||
| 1079 | + int64_t kNumColSquares_exp = 13; | ||
| 1080 | + int64_t kSquareSize_exp = 12; | ||
| 1081 | + int64_t kNumChannels_exp = 3; | ||
| 1082 | + | ||
| 1083 | + SetCheckerboardImageInput<Eigen::half> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 1084 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 1085 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 1086 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 1087 | + | ||
| 1088 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 1089 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 1090 | + | ||
| 1091 | + float scale_data[2] = {0.5, 0.5}; | ||
| 1092 | + | ||
| 1093 | + float translate_data[2] = {0.5, 0.5}; | ||
| 1094 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 1095 | + vector<int64_t> sizeshape ={2}; | ||
| 1096 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 1097 | + float* output = new float[outputshape]; | ||
| 1098 | + | ||
| 1099 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 1100 | + | ||
| 1101 | + Eigen::half* data_arr = new Eigen::half[data.size()]; | ||
| 1102 | + | ||
| 1103 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 1104 | + | ||
| 1105 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 1106 | + std::string kernel_type_str = "box"; | ||
| 1107 | + bool antialias = false; | ||
| 1108 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 1109 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 1110 | + delete [] data_arr; | ||
| 1111 | + delete [] output; | ||
| 1112 | + | ||
| 1113 | +} | ||
| 1114 | + | ||
| 1115 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, DATA_TYPE_DOUBLE_METHOD_BOX_SUCC) { | ||
| 1116 | + std::vector<double> data; | ||
| 1117 | + vector<DataType> data_types = {DT_DOUBLE, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 1118 | + int64_t kBatchSize_exp = 2; | ||
| 1119 | + int64_t kNumRowSquares_exp = 16; | ||
| 1120 | + int64_t kNumColSquares_exp = 13; | ||
| 1121 | + int64_t kSquareSize_exp = 12; | ||
| 1122 | + int64_t kNumChannels_exp = 3; | ||
| 1123 | + | ||
| 1124 | + SetCheckerboardImageInput<double> (kBatchSize_exp, kNumRowSquares_exp, kNumColSquares_exp, | ||
| 1125 | + kSquareSize_exp, kNumChannels_exp, data); | ||
| 1126 | + vector<int64_t> datashape = {kBatchSize_exp, kNumRowSquares_exp * kSquareSize_exp, | ||
| 1127 | + kNumColSquares_exp * kSquareSize_exp, kNumChannels_exp}; | ||
| 1128 | + | ||
| 1129 | + const int kOutputImageHeight_exp = kNumRowSquares_exp * kSquareSize_exp; | ||
| 1130 | + const int kOutputImageWidth_exp = kNumColSquares_exp * kSquareSize_exp; | ||
| 1131 | + | ||
| 1132 | + float scale_data[2] = {0.5, 0.5}; | ||
| 1133 | + | ||
| 1134 | + float translate_data[2] = {0.5, 0.5}; | ||
| 1135 | + int size_data[2] = {kOutputImageHeight_exp, kOutputImageWidth_exp}; | ||
| 1136 | + vector<int64_t> sizeshape ={2}; | ||
| 1137 | + const int outputshape= kBatchSize_exp* kOutputImageHeight_exp * kOutputImageWidth_exp * kNumChannels_exp; | ||
| 1138 | + float* output = new float[outputshape]; | ||
| 1139 | + | ||
| 1140 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {kBatchSize_exp, kOutputImageHeight_exp, kOutputImageWidth_exp, kNumChannels_exp}}; | ||
| 1141 | + | ||
| 1142 | + double* data_arr = new double[data.size()]; | ||
| 1143 | + | ||
| 1144 | + std::copy(data.begin(), data.end(), data_arr); | ||
| 1145 | + | ||
| 1146 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 1147 | + std::string kernel_type_str = "box"; | ||
| 1148 | + bool antialias = false; | ||
| 1149 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 1150 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK); | ||
| 1151 | + delete [] data_arr; | ||
| 1152 | + delete [] output; | ||
| 1153 | + | ||
| 1154 | +} | ||
| 1155 | + | ||
| 1156 | +// exception instance | ||
| 1157 | +TEST_F(TEST_SCALEANDTRANSLATE_UT, INPUT_DATA_TYPE_EXCEPTION) { | ||
| 1158 | + std::vector<uint64_t> data; | ||
| 1159 | + vector<DataType> data_types = {DT_UINT64, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT}; | ||
| 1160 | + | ||
| 1161 | + uint64_t data_arr[4] = {(uint64_t)1}; | ||
| 1162 | + vector<int64_t> datashape = {1, 2 , 2 ,1}; | ||
| 1163 | + float scale_data[2] = {0.5, 0.5}; | ||
| 1164 | + | ||
| 1165 | + float translate_data[2] = {0.5, 0.5}; | ||
| 1166 | + int size_data[2] = {4, 4}; | ||
| 1167 | + vector<int64_t> sizeshape ={2}; | ||
| 1168 | + const int outputshape= 16; | ||
| 1169 | + float* output = new float[outputshape]; | ||
| 1170 | + | ||
| 1171 | + vector<vector<int64_t>> shapes = {datashape, sizeshape, {2}, {2}, {1, 4, 4, 1}}; | ||
| 1172 | + | ||
| 1173 | + vector<void *> datas = {(void *)data_arr, (void *)size_data, (void *)scale_data, (void *)translate_data, (void *)output}; | ||
| 1174 | + std::string kernel_type_str = "box"; | ||
| 1175 | + bool antialias = false; | ||
| 1176 | + CREATE_NODEDEF(shapes, data_types, datas, kernel_type_str, antialias); | ||
| 1177 | + RUN_KERNEL(node_def, HOST, KERNEL_STATUS_PARAM_INVALID); | ||
| 1178 | + delete [] output; | ||
| 1179 | +} | ||
image/scale_and_translate/op_host/scale_and_translate_infershape.cpp此评论由代码审查工具自动生成