From cd1eaf74aa06e4f5026a5037ddfe44c90edb072a Mon Sep 17 00:00:00 2001 From: "jing.tang" Date: Mon, 1 Apr 2024 08:15:02 +0000 Subject: [PATCH] add some nbg graph tests Type: Unit Test Signed-off-by: Tang Jing --- src/tim/vx/graph_test.cc | 2436 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 2436 insertions(+) diff --git a/src/tim/vx/graph_test.cc b/src/tim/vx/graph_test.cc index bc964ff52..30bba0079 100644 --- a/src/tim/vx/graph_test.cc +++ b/src/tim/vx/graph_test.cc @@ -28,6 +28,9 @@ #include "gtest/gtest.h" #include +#include +#include +#include TEST(graph, gen_binary_graph_with_empty_graph) { auto ctx = tim::vx::Context::Create(); @@ -90,6 +93,2439 @@ TEST(graph, gen_binary_graph_with_simple_add) { EXPECT_EQ(output, expected_out); } +TEST(graph, gen_binary_graph_with_self_elementwise) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType io_shape({1, 1, 1, 1}); + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec input_1_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto input_t0 = graph->CreateTensor(input_spec); + auto op = graph->CreateOperation(io_shape); + auto input_t1 = graph->CreateTensor(input_1_spec); + (*op).BindInputs({input_t0}).BindOutputs({input_t1}); + + auto output_t = graph->CreateTensor(output_spec); + auto add = graph->CreateOperation(); + (*add).BindInputs({input_t1, input_t1}).BindOutputs({output_t}); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + std::cout << "CompileToBinary 1." << std::endl; + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + std::cout << "CompileToBinary 2." << std::endl; + + // binary graph compilation doesn't impact current graph's execution + float in = 1.0f; + float expected_out = 2.0f; + EXPECT_TRUE(input_t0->CopyDataToTensor(&in, sizeof(in))); + // EXPECT_TRUE(input_t1->CopyDataToTensor(&in, sizeof(in))); + + EXPECT_TRUE(graph->Run()); + float output = 0.0f; + EXPECT_TRUE(output_t->CopyDataFromTensor(&output)); + EXPECT_EQ(output, expected_out); + std::cout << "graph->Run." << output << std::endl; + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_in0 = nbg_graph->CreateTensor(input_spec); + auto nbg_out = nbg_graph->CreateTensor(output_spec); + + EXPECT_TRUE(nbg_in0->CopyDataToTensor(&in, sizeof(in))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_in0}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + output = 0.0f; + EXPECT_TRUE(nbg_out->CopyDataFromTensor(&output)); + EXPECT_EQ(output, expected_out); +} + +TEST(graph, gen_binary_graph_with_all_const_input) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType io_shape({1, 1, 1, 1}); + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::CONSTANT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::OUTPUT); + + float const_in = 6.0f; + auto input_t0 = graph->CreateTensor(input_spec, &const_in); + auto input_t1 = graph->CreateTensor(input_spec, &const_in); + + auto output_t = graph->CreateTensor(output_spec); + auto add = graph->CreateOperation(); + (*add).BindInputs({input_t0, input_t1}).BindOutputs({output_t}); + + // size_t bin_size = -1; + // EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + // std::cout << "CompileToBinary 1." << std::endl; + // EXPECT_NE(bin_size, -1); + // std::vector nbg_buf(bin_size); + + // // generate binary graph does't require input data + // EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + // std::cout << "CompileToBinary 2." << std::endl; + + EXPECT_TRUE(graph->Run()); + float output = 0.0f; + float expected_out = 12.0f; + EXPECT_TRUE(output_t->CopyDataFromTensor(&output)); + EXPECT_EQ(output, expected_out); + std::cout << "graph->Run. " << output << std::endl; + + // auto nbg_graph = ctx->CreateGraph(); + // auto nbg_out = nbg_graph->CreateTensor(output_spec); + + // auto nbg_node = nbg_graph->CreateOperation( + // (nbg_buf.data()), /*num_of_input*/ 0, + // /*num_of_output*/ 1); + // (*nbg_node).BindInputs({}).BindOutputs({nbg_out}); + // EXPECT_TRUE(nbg_graph->Compile()); + // EXPECT_TRUE(nbg_graph->Run()); + + // output = 0.0f; + // EXPECT_TRUE(nbg_out->CopyDataFromTensor(&output)); + // EXPECT_EQ(output, expected_out); +} + +TEST(graph, sqrt13) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType io_shape({13, 1}); + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec input_1_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto input_t0 = graph->CreateTensor(input_spec); + auto op = graph->CreateOperation(io_shape); + auto input_t1 = graph->CreateTensor(input_1_spec); + (*op).BindInputs({input_t0}).BindOutputs({input_t1}); + + auto output_t = graph->CreateTensor(output_spec); + auto add = graph->CreateOperation(); + (*add).BindInputs({input_t1}).BindOutputs({output_t}); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + std::cout << "CompileToBinary 1." << std::endl; + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + std::cout << "CompileToBinary 2." << std::endl; + + // binary graph compilation doesn't impact current graph's execution + std::vector in(13, 1.21f); + std::vector expected_out(13, 1.1f); + EXPECT_TRUE(input_t0->CopyDataToTensor(in.data(), in.size() * sizeof(float))); + // EXPECT_TRUE(input_t1->CopyDataToTensor(&in, sizeof(in))); + + EXPECT_TRUE(graph->Run()); + std::vector output(in.size()); + EXPECT_TRUE(output_t->CopyDataFromTensor(output.data())); + EXPECT_EQ(output, expected_out); + // std::cout << "graph->Run." << output << std::endl; + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_in0 = nbg_graph->CreateTensor(input_spec); + auto nbg_out = nbg_graph->CreateTensor(output_spec); + + EXPECT_TRUE(nbg_in0->CopyDataToTensor(in.data(), in.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_in0}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + // output = 0.0f; + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output.data())); + EXPECT_EQ(output, expected_out); +} + +TEST(graph, gen_binary_graph_with_self_elementwise_mul) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType io_shape({13, 1}); + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec input_1_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, io_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto input_t0 = graph->CreateTensor(input_spec); + auto op = graph->CreateOperation(io_shape); + auto input_t1 = graph->CreateTensor(input_1_spec); + (*op).BindInputs({input_t0}).BindOutputs({input_t1}); + + auto output_t0 = graph->CreateTensor(input_1_spec); + auto add = graph->CreateOperation(); + (*add).BindInputs({input_t1, input_t1}).BindOutputs({output_t0}); + + auto output_t = graph->CreateTensor(output_spec); + auto reshape1 = graph->CreateOperation(io_shape); + (*reshape1).BindInputs({output_t0}).BindOutputs({output_t}); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + std::cout << "CompileToBinary 1." << std::endl; + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + std::cout << "CompileToBinary 2." << std::endl; + + // binary graph compilation doesn't impact current graph's execution + std::vector in(13, 2.0f); + std::vector expected_out(13, 4.0f); + EXPECT_TRUE(input_t0->CopyDataToTensor(in.data(), in.size() * sizeof(float))); + // EXPECT_TRUE(input_t1->CopyDataToTensor(&in, sizeof(in))); + + EXPECT_TRUE(graph->Run()); + std::vector output(in.size()); + EXPECT_TRUE(output_t->CopyDataFromTensor(output.data())); + EXPECT_EQ(output, expected_out); + // std::cout << "graph->Run." << output << std::endl; + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_in0 = nbg_graph->CreateTensor(input_spec); + auto nbg_out = nbg_graph->CreateTensor(output_spec); + + EXPECT_TRUE(nbg_in0->CopyDataToTensor(in.data(), in.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_in0}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + // output = 0.0f; + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output.data())); + EXPECT_EQ(output, expected_out); +} + +TEST(graph, gen_binary_graph_with_big_batch) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType input_shape({7, 7, 1, 2048}); + tim::vx::ShapeType kernel_shape({7, 7, 1, 512}); + tim::vx::ShapeType output_shape({1, 1, 512, 2048}); + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, input_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec kernel_spec(tim::vx::DataType::FLOAT32, kernel_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, output_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto input_t = graph->CreateTensor(input_spec); + auto kernel_t = graph->CreateTensor(kernel_spec); + auto output_t = graph->CreateTensor(output_spec); + + auto padding = tim::vx::PadType::VALID; + std::array stride({1, 1}); + std::array dilation({0, 0}); + + auto op = + graph->CreateOperation(padding, stride, dilation); + (*op).BindInputs({input_t, kernel_t}).BindOutputs({output_t}); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + std::cout << "CompileToBinary 1." << std::endl; + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + std::cout << "CompileToBinary 2." << std::endl; +} + +// single channel single batch, without permute +TEST(graph, MPG6411) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({6, 4, 1, 1}); + tim::vx::ShapeType upd_shape({2, 2, 1, 1}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec upd_spec(tim::vx::DataType::FLOAT32, upd_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto inp_tensor = graph->CreateTensor(inp_spec); + auto upd_tensor = graph->CreateTensor(upd_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::array ksize = {3, 2}; + std::array stride = {3, 2}; + auto op = graph->CreateOperation( + tim::vx::PadType::VALID, ksize, stride); + (*op).BindInputs({inp_tensor, upd_tensor}).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = {7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, + 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8}; + std::vector upd_data = {2, 6, 3, 1}; + std::vector golden = {0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(upd_tensor->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_upd = nbg_graph->CreateTensor(upd_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(nbg_upd->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 2, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp, nbg_upd}).BindOutputs({nbg_out}); + /* all cmodel execution failed here */ + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +// multi channel single batch, without permute +TEST(graph, MPG6421) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({6, 4, 2, 1}); + tim::vx::ShapeType upd_shape({2, 2, 2, 1}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec upd_spec(tim::vx::DataType::FLOAT32, upd_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto inp_tensor = graph->CreateTensor(inp_spec); + auto upd_tensor = graph->CreateTensor(upd_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::array ksize = {3, 2}; + std::array stride = {3, 2}; + auto op = graph->CreateOperation( + tim::vx::PadType::VALID, ksize, stride); + (*op).BindInputs({inp_tensor, upd_tensor}).BindOutputs({out_tensor}); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = { + 7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8, + 7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8}; + std::vector upd_data = {2, 6, 3, 1, 2, 6, 3, 1}; + std::vector golden = {0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(upd_tensor->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_upd = nbg_graph->CreateTensor(upd_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(nbg_upd->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 2, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp, nbg_upd}).BindOutputs({nbg_out}); + /* all cmodel execution failed here */ + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +// single channel single batch, with permute +TEST(graph, MPG1641T) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({1, 6, 4, 1}); // CWHN + tim::vx::ShapeType upd_shape({1, 2, 2, 1}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec upd_spec(tim::vx::DataType::FLOAT32, upd_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto inp_tensor = graph->CreateTensor(inp_spec); + auto upd_tensor = graph->CreateTensor(upd_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; // CWHN -> WHCN + std::vector inp_shape_t(inp_perm.size()); + std::vector upd_shape_t(inp_perm.size()); + for (uint32_t i = 0; i < inp_perm.size(); i++) { + inp_shape_t[i] = inp_shape[inp_perm[i]]; + upd_shape_t[i] = upd_shape[inp_perm[i]]; + } + tim::vx::TensorSpec inp_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec upd_spec_t(tim::vx::DataType::FLOAT32, upd_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + + auto inp_tensor_t = graph->CreateTensor(inp_spec_t); + auto upd_tensor_t = graph->CreateTensor(upd_spec_t); + auto out_tensor_t = graph->CreateTensor(out_spec_t); + + auto inp_permute = graph->CreateOperation(inp_perm); + inp_permute->BindInput(inp_tensor).BindOutput(inp_tensor_t); + auto upd_permute = graph->CreateOperation(inp_perm); + upd_permute->BindInput(upd_tensor).BindOutput(upd_tensor_t); + + std::array ksize = {3, 2}; + std::array stride = {3, 2}; + auto op = graph->CreateOperation( + tim::vx::PadType::VALID, ksize, stride); + (*op).BindInputs({inp_tensor_t, upd_tensor_t}).BindOutputs({out_tensor_t}); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(out_tensor_t).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = {7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, + 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8}; + std::vector upd_data = {2, 6, 3, 1}; + std::vector golden = {0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(upd_tensor->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_upd = nbg_graph->CreateTensor(upd_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(nbg_upd->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 2, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp, nbg_upd}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +// multi channel single batch, with permute +TEST(graph, MPG2641T) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({2, 6, 4, 1}); // CWHN + tim::vx::ShapeType upd_shape({2, 2, 2, 1}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec upd_spec(tim::vx::DataType::FLOAT32, upd_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto inp_tensor = graph->CreateTensor(inp_spec); + auto upd_tensor = graph->CreateTensor(upd_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; // CWHN -> WHCN + + std::vector inp_shape_t(inp_perm.size()); + std::vector upd_shape_t(inp_perm.size()); + for (uint32_t i = 0; i < inp_perm.size(); i++) { + inp_shape_t[i] = inp_shape[inp_perm[i]]; + upd_shape_t[i] = upd_shape[inp_perm[i]]; + } + tim::vx::TensorSpec inp_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec upd_spec_t(tim::vx::DataType::FLOAT32, upd_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + + auto inp_tensor_t = graph->CreateTensor(inp_spec_t); + auto upd_tensor_t = graph->CreateTensor(upd_spec_t); + auto out_tensor_t = graph->CreateTensor(out_spec_t); + + auto inp_permute = graph->CreateOperation(inp_perm); + inp_permute->BindInput(inp_tensor).BindOutput(inp_tensor_t); + auto upd_permute = graph->CreateOperation(inp_perm); + upd_permute->BindInput(upd_tensor).BindOutput(upd_tensor_t); + + std::array ksize = {3, 2}; + std::array stride = {3, 2}; + auto op = graph->CreateOperation( + tim::vx::PadType::VALID, ksize, stride); + (*op).BindInputs({inp_tensor_t, upd_tensor_t}).BindOutputs({out_tensor_t}); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(out_tensor_t).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data_ = {7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, + 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8}; + std::vector inp_data; + for (uint32_t i = 0; i < 2 * inp_data_.size(); i++) { + inp_data.push_back(inp_data_[i / 2]); + } + + std::vector upd_data_ = {2, 6, 3, 1}; + std::vector upd_data; + for (uint32_t i = 0; i < 2 * upd_data_.size(); i++) { + upd_data.push_back(upd_data_[i / 2]); + } + + std::vector golden_ = {0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + std::vector golden; + for (uint32_t i = 0; i < 2 * golden_.size(); i++) { + golden.push_back(golden_[i / 2]); + } + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(upd_tensor->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_upd = nbg_graph->CreateTensor(upd_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(nbg_upd->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 2, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp, nbg_upd}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +// single channel multi batch, with permute +TEST(graph, MPG1642T) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({1, 6, 4, 2}); // CWHN + tim::vx::ShapeType upd_shape({1, 2, 2, 2}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec upd_spec(tim::vx::DataType::FLOAT32, upd_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto inp_tensor = graph->CreateTensor(inp_spec); + auto upd_tensor = graph->CreateTensor(upd_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; // CWHN -> WHCN + std::vector inp_shape_t(inp_perm.size()); + std::vector upd_shape_t(inp_perm.size()); + for (uint32_t i = 0; i < inp_perm.size(); i++) { + inp_shape_t[i] = inp_shape[inp_perm[i]]; + upd_shape_t[i] = upd_shape[inp_perm[i]]; + } + tim::vx::TensorSpec inp_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec upd_spec_t(tim::vx::DataType::FLOAT32, upd_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + + auto inp_tensor_t = graph->CreateTensor(inp_spec_t); + auto upd_tensor_t = graph->CreateTensor(upd_spec_t); + auto out_tensor_t = graph->CreateTensor(out_spec_t); + + auto inp_permute = graph->CreateOperation(inp_perm); + inp_permute->BindInput(inp_tensor).BindOutput(inp_tensor_t); + auto upd_permute = graph->CreateOperation(inp_perm); + upd_permute->BindInput(upd_tensor).BindOutput(upd_tensor_t); + + std::array ksize = {3, 2}; + std::array stride = {3, 2}; + auto op = graph->CreateOperation( + tim::vx::PadType::VALID, ksize, stride); + (*op).BindInputs({inp_tensor_t, upd_tensor_t}).BindOutputs({out_tensor_t}); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(out_tensor_t).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = { + 7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8, + 7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8}; + std::vector upd_data = {2, 6, 3, 1, 2, 6, 3, 1}; + std::vector golden = {0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(upd_tensor->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_upd = nbg_graph->CreateTensor(upd_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(nbg_upd->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 2, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp, nbg_upd}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +// multi channel multi batch, with permute +TEST(graph, MPG2642T) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({2, 6, 4, 2}); // CWHN + tim::vx::ShapeType upd_shape({2, 2, 2, 2}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec upd_spec(tim::vx::DataType::FLOAT32, upd_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto inp_tensor = graph->CreateTensor(inp_spec); + auto upd_tensor = graph->CreateTensor(upd_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; // CWHN -> WHCN + std::vector inp_shape_t(inp_perm.size()); + std::vector upd_shape_t(inp_perm.size()); + for (uint32_t i = 0; i < inp_perm.size(); i++) { + inp_shape_t[i] = inp_shape[inp_perm[i]]; + upd_shape_t[i] = upd_shape[inp_perm[i]]; + } + tim::vx::TensorSpec inp_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec upd_spec_t(tim::vx::DataType::FLOAT32, upd_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec_t(tim::vx::DataType::FLOAT32, inp_shape_t, + tim::vx::TensorAttribute::TRANSIENT); + + auto inp_tensor_t = graph->CreateTensor(inp_spec_t); + auto upd_tensor_t = graph->CreateTensor(upd_spec_t); + auto out_tensor_t = graph->CreateTensor(out_spec_t); + + auto inp_permute = graph->CreateOperation(inp_perm); + inp_permute->BindInput(inp_tensor).BindOutput(inp_tensor_t); + auto upd_permute = graph->CreateOperation(inp_perm); + upd_permute->BindInput(upd_tensor).BindOutput(upd_tensor_t); + + std::array ksize = {3, 2}; + std::array stride = {3, 2}; + auto op = graph->CreateOperation( + tim::vx::PadType::VALID, ksize, stride); + (*op).BindInputs({inp_tensor_t, upd_tensor_t}).BindOutputs({out_tensor_t}); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(out_tensor_t).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data_ = { + 7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8, + 7, 2, 5, 3, 10, 2, 3, 8, 9, 3, 4, 2, 1, 5, 7, 5, 6, 1, 0, 6, 2, 7, 2, 8}; + std::vector inp_data; + for (uint32_t i = 0; i < 2 * inp_data_.size(); i++) { + inp_data.push_back(inp_data_[i / 2]); + } + + std::vector upd_data_ = {2, 6, 3, 1, 2, 6, 3, 1}; + std::vector upd_data; + for (uint32_t i = 0; i < 2 * upd_data_.size(); i++) { + upd_data.push_back(upd_data_[i / 2]); + } + + std::vector golden_ = {0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + std::vector golden; + for (uint32_t i = 0; i < 2 * golden_.size(); i++) { + golden.push_back(golden_[i / 2]); + } + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(upd_tensor->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_upd = nbg_graph->CreateTensor(upd_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + EXPECT_TRUE(nbg_upd->CopyDataToTensor(upd_data.data(), + upd_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 2, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp, nbg_upd}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +TEST(graph, PermuteTwice2641) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({2, 6, 4, 1}); // CWHN + tim::vx::ShapeType mid_shape({6, 4, 2, 1}); + tim::vx::ShapeType out_shape({2, 6, 4, 1}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec mid_spec(tim::vx::DataType::FLOAT32, mid_shape, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, out_shape, + tim::vx::TensorAttribute::OUTPUT); + auto inp_tensor = graph->CreateTensor(inp_spec); + auto mid_tensor = graph->CreateTensor(mid_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; + auto in_permute = graph->CreateOperation(inp_perm); + in_permute->BindInput(inp_tensor).BindOutput(mid_tensor); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(mid_tensor).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = { + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + + std::vector golden = inp_data; + + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +TEST(graph, PermuteTwice1642) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({1, 6, 4, 2}); // CWHN + tim::vx::ShapeType mid_shape({6, 4, 1, 2}); + tim::vx::ShapeType out_shape({1, 6, 4, 2}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec mid_spec(tim::vx::DataType::FLOAT32, mid_shape, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, out_shape, + tim::vx::TensorAttribute::OUTPUT); + auto inp_tensor = graph->CreateTensor(inp_spec); + auto mid_tensor = graph->CreateTensor(mid_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; + auto in_permute = graph->CreateOperation(inp_perm); + in_permute->BindInput(inp_tensor).BindOutput(mid_tensor); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(mid_tensor).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = { + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + + std::vector golden = inp_data; + + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +TEST(graph, PermuteTwice1641) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({1, 6, 4, 1}); // CWHN + tim::vx::ShapeType mid_shape({6, 4, 1, 1}); + tim::vx::ShapeType out_shape({1, 6, 4, 1}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec mid_spec(tim::vx::DataType::FLOAT32, mid_shape, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, out_shape, + tim::vx::TensorAttribute::OUTPUT); + auto inp_tensor = graph->CreateTensor(inp_spec); + auto mid_tensor = graph->CreateTensor(mid_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; + auto in_permute = graph->CreateOperation(inp_perm); + in_permute->BindInput(inp_tensor).BindOutput(mid_tensor); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(mid_tensor).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = {0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + + std::vector golden = inp_data; + + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +TEST(graph, PermuteTwice2642) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType inp_shape({2, 6, 4, 2}); // CWHN + tim::vx::ShapeType mid_shape({6, 4, 2, 2}); + tim::vx::ShapeType out_shape({2, 6, 4, 2}); + tim::vx::TensorSpec inp_spec(tim::vx::DataType::FLOAT32, inp_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec mid_spec(tim::vx::DataType::FLOAT32, mid_shape, + tim::vx::TensorAttribute::TRANSIENT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, out_shape, + tim::vx::TensorAttribute::OUTPUT); + auto inp_tensor = graph->CreateTensor(inp_spec); + auto mid_tensor = graph->CreateTensor(mid_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector inp_perm = {1, 2, 0, 3}; + auto in_permute = graph->CreateOperation(inp_perm); + in_permute->BindInput(inp_tensor).BindOutput(mid_tensor); + + std::vector out_perm = {2, 0, 1, 3}; + auto out_permute = graph->CreateOperation(out_perm); + out_permute->BindInput(mid_tensor).BindOutput(out_tensor); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + // binary graph compilation doesn't impact current graph's execution + std::vector inp_data = { + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + + std::vector golden = inp_data; + + EXPECT_TRUE(inp_tensor->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + EXPECT_TRUE(graph->Run()); + std::vector output_values(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(inp_spec); + auto nbg_out = nbg_graph->CreateTensor(out_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(inp_data.data(), + inp_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +TEST(Broadcast, 3To32) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType input_shape({3}); + tim::vx::ShapeType output_shape({3, 2}); + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, input_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, output_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto input_tensor = graph->CreateTensor(input_spec); + auto output_tensor = graph->CreateTensor(output_spec); + + std::vector shape = {3, 2}; + auto op = graph->CreateOperation(shape); + (*op).BindInputs({input_tensor}).BindOutputs({output_tensor}); + + size_t bin_size = -1; + EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size)); + EXPECT_NE(bin_size, -1); + std::vector nbg_buf(bin_size); + + // generate binary graph does't require input data + EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + char file_name[256]; + sprintf(file_name, "bcast_gen_by_soc_exe_succ.nb"); + FILE* fp; + fp = fopen(file_name, "wb"); + fwrite(nbg_buf.data(), bin_size, 1, fp); + fclose(fp); + printf("Save NBG in %s, nbg_bin_size = %d \n", file_name, (int)bin_size); + + std::vector in_data = { + 1.f, + 2.f, + 3.f, + }; + std::vector golden = {1.f, 2.f, 3.f, 1.f, 2.f, 3.f}; + EXPECT_TRUE(input_tensor->CopyDataToTensor(in_data.data(), + in_data.size() * sizeof(float))); + EXPECT_TRUE(graph->Run()); + + std::vector output_values(golden.size()); + EXPECT_TRUE(output_tensor->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); + + auto nbg_graph = ctx->CreateGraph(); + auto nbg_inp = nbg_graph->CreateTensor(input_spec); + auto nbg_out = nbg_graph->CreateTensor(output_spec); + + EXPECT_TRUE(nbg_inp->CopyDataToTensor(in_data.data(), + in_data.size() * sizeof(float))); + + auto nbg_node = nbg_graph->CreateOperation( + (nbg_buf.data()), /*num_of_input*/ 1, + /*num_of_output*/ 1); + (*nbg_node).BindInputs({nbg_inp}).BindOutputs({nbg_out}); + EXPECT_TRUE(nbg_graph->Compile()); + EXPECT_TRUE(nbg_graph->Run()); + + EXPECT_TRUE(nbg_out->CopyDataFromTensor(output_values.data())); + EXPECT_EQ(golden, output_values); +} + +TEST(graph, G_SIM_DEFORM_DETR_R50_ONNX_SOC) { + auto vx_context = tim::vx::Context::Create(); + auto vx_graph = vx_context->CreateGraph(); + tim::vx::TensorSpec vx_output_tspec; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({2, 4, 600, 8}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + auto dumpTensor_0 = vx_graph->CreateTensor(vx_output_tspec); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({2, 4, 600, 8, 1}), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + auto dumpTensor_1 = vx_graph->CreateTensor(vx_output_tspec); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({2, 4, 8, 600, 1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + auto dumpTensor_2 = vx_graph->CreateTensor(vx_output_tspec); + + std::vector perm = {0, 1, 3, 2, 4}; + vx_graph->CreateOperation(perm) + ->BindInputs({dumpTensor_2}) + .BindOutputs({dumpTensor_1}); + + std::vector shape = {2, 4, 600, 8}; + vx_graph->CreateOperation(shape) + ->BindInputs({dumpTensor_1}) + .BindOutputs({dumpTensor_0}); + + size_t bin_size = 0; + std::vector nbg_buf(bin_size); + EXPECT_TRUE(vx_graph->CompileToBinary(nullptr, &bin_size)); + + std::vector tmp(bin_size); + nbg_buf.swap(tmp); + EXPECT_TRUE(vx_graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + std::vector input_specs_; + std::vector output_specs_; + + auto vx_nbg_graph = vx_context->CreateGraph(); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({2, 4, 8, 600, 1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + input_specs_.push_back(vx_output_tspec); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({2, 4, 600, 8}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + output_specs_.push_back(vx_output_tspec); + + auto nbg_node = vx_nbg_graph->CreateOperation( + nbg_buf.data(), input_specs_.size(), output_specs_.size()); + std::vector in_data(2 * 4 * 8 * 600, 1.5f); + std::vector out_data(2 * 4 * 8 * 600); + std::vector> input_tensors, output_tensors; + std::transform(input_specs_.begin(), input_specs_.end(), + std::back_inserter(input_tensors), + [vx_nbg_graph, &in_data](const tim::vx::TensorSpec& spec) { + auto input_tensor = vx_nbg_graph->CreateTensor(spec); + input_tensor->CopyDataToTensor( + in_data.data(), in_data.size() * sizeof(float)); + return input_tensor; + }); + std::transform(output_specs_.begin(), output_specs_.end(), + std::back_inserter(output_tensors), + [vx_nbg_graph](const tim::vx::TensorSpec& spec) { + return vx_nbg_graph->CreateTensor(spec); + }); + + nbg_node->BindInputs(input_tensors).BindOutputs(output_tensors); + + EXPECT_TRUE(vx_nbg_graph->Compile()); + EXPECT_TRUE(vx_nbg_graph->Run()); + EXPECT_TRUE(output_tensors[0]->CopyDataFromTensor(out_data.data())); +} + +TEST(graph, G_YOLO3_10_ONNX_SOC) { + std::shared_ptr dumpTensor; + std::unordered_map> dumpTensorMap; + + auto vx_context = tim::vx::Context::Create(); + auto vx_graph = vx_context->CreateGraph(); + tim::vx::TensorSpec vx_output_tspec; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[0] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[1] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[2] = dumpTensor; + + std::vector weights_3 = {1}; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_3.data()); + dumpTensorMap[3] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[4] = dumpTensor; + /* Node[0] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[2], dumpTensorMap[3]}) + .BindOutputs({dumpTensorMap[1]}); + /* Node[1] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[1], dumpTensorMap[4]}) + .BindOutputs({dumpTensorMap[0]}); + + size_t bin_size = 0; + std::vector nbg_buf(bin_size); + EXPECT_TRUE(vx_graph->CompileToBinary(nullptr, &bin_size)); + + std::vector tmp(bin_size); + nbg_buf.swap(tmp); + EXPECT_TRUE(vx_graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + std::vector input_specs_; + std::vector output_specs_; + auto vx_nbg_graph = vx_context->CreateGraph(); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + input_specs_.push_back(vx_output_tspec); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + input_specs_.push_back(vx_output_tspec); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + output_specs_.push_back(vx_output_tspec); + + auto nbg_node = vx_nbg_graph->CreateOperation( + nbg_buf.data(), input_specs_.size(), output_specs_.size()); + + std::vector in_data = {0}; + std::vector> input_tensors, output_tensors; + std::transform(input_specs_.begin(), input_specs_.end(), + std::back_inserter(input_tensors), + [vx_nbg_graph, &in_data](const tim::vx::TensorSpec& spec) { + auto input_tensor = vx_nbg_graph->CreateTensor(spec); + input_tensor->CopyDataToTensor( + in_data.data(), in_data.size() * sizeof(char)); + return input_tensor; + }); + std::transform(output_specs_.begin(), output_specs_.end(), + std::back_inserter(output_tensors), + [vx_nbg_graph](const tim::vx::TensorSpec& spec) { + return vx_nbg_graph->CreateTensor(spec); + }); + nbg_node->BindInputs(input_tensors).BindOutputs(output_tensors); + EXPECT_TRUE(vx_nbg_graph->Compile()); + EXPECT_TRUE(vx_nbg_graph->Run()); +} + +TEST(graph, G_VOXELNET_ONNX_SOC) { + std::shared_ptr dumpTensor; + std::unordered_map> dumpTensorMap; + auto vx_context = tim::vx::Context::Create(); + auto vx_graph = vx_context->CreateGraph(); + tim::vx::TensorSpec vx_output_tspec; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1, 35, 1}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[0] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({35, 1}), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[1] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({35, 1}), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[2] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({35, 1}), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[3] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({7, 35, 1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[4] = dumpTensor; + + std::vector weights_5(4, 1); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({1}), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_5.data()); + dumpTensorMap[5] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1, 35, 1}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[6] = dumpTensor; + + /* Node[0] */ + std::vector axis = {0}; + vx_graph->CreateOperation(axis, 0) + ->BindInputs({dumpTensorMap[4]}) + .BindOutputs({dumpTensorMap[3]}); + /* Node[1] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[3], dumpTensorMap[5]}) + .BindOutputs({dumpTensorMap[2]}); + /* Node[2] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[2]}) + .BindOutputs({dumpTensorMap[1]}); + /* Node[3] */ + std::vector shape = {1, 35, 1}; + vx_graph->CreateOperation(shape) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[0]}); + /* Node[4] */ + vx_graph->CreateOperation(shape) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[6]}); + + size_t bin_size = 0; + std::vector nbg_buf(bin_size); + EXPECT_TRUE(vx_graph->CompileToBinary(nullptr, &bin_size)); + + std::vector tmp(bin_size); + nbg_buf.swap(tmp); + EXPECT_TRUE(vx_graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + std::vector input_specs_; + std::vector output_specs_; + auto vx_nbg_graph = vx_context->CreateGraph(); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, tim::vx::ShapeType({7, 35, 1}), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + + input_specs_.push_back(vx_output_tspec); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1, 35, 1}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + + output_specs_.push_back(vx_output_tspec); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, tim::vx::ShapeType({1, 35, 1}), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, {}, {})); + + output_specs_.push_back(vx_output_tspec); + auto nbg_node = vx_nbg_graph->CreateOperation( + nbg_buf.data(), input_specs_.size(), output_specs_.size()); + + std::vector> input_tensors, output_tensors; + + std::vector in_data(7 * 5 * 1, 1.5f); + std::transform(input_specs_.begin(), input_specs_.end(), + std::back_inserter(input_tensors), + [vx_nbg_graph, &in_data](const tim::vx::TensorSpec& spec) { + auto input_tensor = vx_nbg_graph->CreateTensor(spec); + input_tensor->CopyDataToTensor( + in_data.data(), in_data.size() * sizeof(float)); + return input_tensor; + }); + std::transform(output_specs_.begin(), output_specs_.end(), + std::back_inserter(output_tensors), + [vx_nbg_graph](const tim::vx::TensorSpec& spec) { + return vx_nbg_graph->CreateTensor(spec); + }); + nbg_node->BindInputs(input_tensors).BindOutputs(output_tensors); + EXPECT_TRUE(vx_nbg_graph->Compile()); + EXPECT_TRUE(vx_nbg_graph->Run()); +} + +TEST(graph, G_DETR3D_0913_NO_DCN_SIM_ONNX_SOC) { + std::shared_ptr dumpTensor; + std::unordered_map> dumpTensorMap; + auto vx_context = tim::vx::Context::Create(); + auto vx_graph = vx_context->CreateGraph(); + tim::vx::TensorSpec vx_output_tspec; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[0] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[1] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[2] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 900, 6, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[3] = dumpTensor; + std::vector weights_4(4, 1); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>({1})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_4.data()); + dumpTensorMap[4] = dumpTensor; + std::vector weights_5(4, 2); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>({1})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_5.data()); + dumpTensorMap[5] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[6] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[7] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[8] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {4, 1, 6, 900, 1, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[9] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {4, 1, 6, 900, 1, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[10] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 6, 900, 1, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[11] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 1, 6, 900, 1, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[12] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 1, 900, 1, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[13] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[14] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[15] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[16] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[17] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[18] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[19] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[20] = dumpTensor; + std::vector weights_21(4, 3); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>({1})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_21.data()); + dumpTensorMap[21] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[22] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[23] = dumpTensor; + std::vector weights_24(4, 4); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>({1})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_24.data()); + dumpTensorMap[24] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[25] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[26] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[27] = dumpTensor; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[28] = dumpTensor; + /* Node[0] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[3], dumpTensorMap[4]}) + .BindOutputs({dumpTensorMap[2]}); + /* Node[1] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[2], dumpTensorMap[5]}) + .BindOutputs({dumpTensorMap[1]}); + /* Node[2] */ + vx_graph + ->CreateOperation( + std::vector>( + {2, 1, 900, 6})) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[0]}); + /* Node[3] */ + vx_graph + ->CreateOperation( + std::vector>( + {2, 1, 900, 6})) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[6]}); + /* Node[4] */ + vx_graph + ->CreateOperation( + std::vector>( + {2, 1, 900, 6})) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[7]}); + /* Node[5] */ + vx_graph + ->CreateOperation( + std::vector>( + {2, 1, 900, 6})) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[8]}); + /* Node[6] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[10], dumpTensorMap[11]}) + .BindOutputs({dumpTensorMap[9]}); + /* Node[7] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[18], dumpTensorMap[19]}) + .BindOutputs({dumpTensorMap[17]}); + /* Node[8] */ + vx_graph + ->CreateOperation( + std::vector>({0, 0, 0, 0}), + std::vector>({1, 900, 6, 1}), + std::vector>({1, 1, 1, 1}), 0, 0, 0) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[20]}); + /* Node[9] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[20], dumpTensorMap[21]}) + .BindOutputs({dumpTensorMap[19]}); + /* Node[10] */ + vx_graph + ->CreateOperation( + std::vector>({0, 0, 0, 0}), + std::vector>({1, 900, 6, 1}), + std::vector>({1, 1, 1, 1}), 0, 0, 0) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[23]}); + /* Node[11] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[23], dumpTensorMap[24]}) + .BindOutputs({dumpTensorMap[22]}); + /* Node[12] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[17], dumpTensorMap[22]}) + .BindOutputs({dumpTensorMap[16]}); + /* Node[13] */ + vx_graph + ->CreateOperation( + std::vector>({1, 0, 0, 0}), + std::vector>({2, 900, 6, 1}), + std::vector>({1, 1, 1, 1}), 0, 0, 0) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[26]}); + /* Node[14] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[26], dumpTensorMap[21]}) + .BindOutputs({dumpTensorMap[25]}); + /* Node[15] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[16], dumpTensorMap[25]}) + .BindOutputs({dumpTensorMap[15]}); + /* Node[16] */ + vx_graph + ->CreateOperation( + std::vector>({1, 0, 0, 0}), + std::vector>({2, 900, 6, 1}), + std::vector>({1, 1, 1, 1}), 0, 0, 0) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[28]}); + /* Node[17] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[28], dumpTensorMap[24]}) + .BindOutputs({dumpTensorMap[27]}); + /* Node[18] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[15], dumpTensorMap[27]}) + .BindOutputs({dumpTensorMap[14]}); + /* Node[19] */ + vx_graph + ->CreateOperation( + std::vector>( + {1, 1, 900, 1, 6, 1})) + ->BindInputs({dumpTensorMap[14]}) + .BindOutputs({dumpTensorMap[13]}); + /* Node[20] */ + vx_graph + ->CreateOperation( + std::vector>( + {0, 1, 4, 2, 3, 5})) + ->BindInputs({dumpTensorMap[13]}) + .BindOutputs({dumpTensorMap[12]}); + /* Node[21] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[12]}) + .BindOutputs({dumpTensorMap[11]}); + + size_t bin_size = 0; + std::vector nbg_buf(bin_size); + EXPECT_TRUE(vx_graph->CompileToBinary(nullptr, &bin_size)); + + std::vector tmp(bin_size); + nbg_buf.swap(tmp); + EXPECT_TRUE(vx_graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + std::vector>> input_specs_; + std::vector output_specs_; + auto vx_nbg_graph = vx_context->CreateGraph(); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 900, 6, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + std::vector in_data_0(2 * 900 * 6, 1.5f); + input_specs_.push_back(std::make_pair(vx_output_tspec, in_data_0)); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {4, 1, 6, 900, 1, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + std::vector in_data_1(4 * 6 * 900 * 6, 1.5f); + input_specs_.push_back(std::make_pair(vx_output_tspec, in_data_1)); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::BOOL8, + tim::vx::ShapeType( + std::vector>( + {1, 900, 6, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + std::vector in_data_2(900 * 6, 1.5f); + input_specs_.push_back(std::make_pair(vx_output_tspec, in_data_2)); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + output_specs_.push_back(vx_output_tspec); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + output_specs_.push_back(vx_output_tspec); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + output_specs_.push_back(vx_output_tspec); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {2, 1, 900, 6})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + output_specs_.push_back(vx_output_tspec); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {4, 1, 6, 900, 1, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + output_specs_.push_back(vx_output_tspec); + auto nbg_node = vx_nbg_graph->CreateOperation( + nbg_buf.data(), input_specs_.size(), output_specs_.size()); + + std::vector> input_tensors, output_tensors; + std::transform( + input_specs_.begin(), input_specs_.end(), + std::back_inserter(input_tensors), + [vx_nbg_graph]( + const std::pair>& pair) { + auto input_tensor = vx_nbg_graph->CreateTensor(pair.first); + input_tensor->CopyDataToTensor(pair.second.data(), + pair.second.size() * sizeof(float)); + return input_tensor; + }); + std::transform(output_specs_.begin(), output_specs_.end(), + std::back_inserter(output_tensors), + [vx_nbg_graph](const tim::vx::TensorSpec& spec) { + return vx_nbg_graph->CreateTensor(spec); + }); + nbg_node->BindInputs(input_tensors).BindOutputs(output_tensors); + EXPECT_TRUE(vx_nbg_graph->Compile()); + EXPECT_TRUE(vx_nbg_graph->Run()); +} + +TEST(graph, G_3DUNET_ONNX_SOC) { + std::shared_ptr dumpTensor; + std::unordered_map> dumpTensorMap; + auto vx_context = tim::vx::Context::Create(); + auto vx_graph = vx_context->CreateGraph(); + tim::vx::TensorSpec vx_output_tspec; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {5, 7, 7, 64, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[0] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {5, 7, 7, 64, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[1] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {5, 7, 7, 64, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[2] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {10, 14, 14, 32, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[3] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {10, 14, 14, 32, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[4] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {10, 14, 14, 32, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[5] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {10, 14, 14, 32, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[6] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {10, 14, 14, 32, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[7] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 32, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[8] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 32, 1})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[9] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 32, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[10] = dumpTensor; + + std::vector weights_11(4, 1); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>({1})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_11.data()); + dumpTensorMap[11] = dumpTensor; + + std::vector weights_12(128, 2); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 32})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_12.data()); + dumpTensorMap[12] = dumpTensor; + + std::vector weights_13(128, 3); + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 32})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_13.data()); + dumpTensorMap[13] = dumpTensor; + + std::vector weights_14(221184, 3); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {3, 3, 3, 32, 64})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_14.data()); + dumpTensorMap[14] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 64})), + tim::vx::TensorAttribute::TRANSIENT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[15] = dumpTensor; + + std::vector weights_16(256, 5); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>({64})), + tim::vx::TensorAttribute::CONSTANT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec, weights_16.data()); + dumpTensorMap[16] = dumpTensor; + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 64, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + dumpTensor = vx_graph->CreateTensor(vx_output_tspec); + dumpTensorMap[17] = dumpTensor; + + /* Node[0] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[7], dumpTensorMap[8]}) + .BindOutputs({dumpTensorMap[6]}); + /* Node[1] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[10], dumpTensorMap[11]}) + .BindOutputs({dumpTensorMap[9]}); + /* Node[2] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[9]}) + .BindOutputs({dumpTensorMap[8]}); + /* Node[3] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[6], dumpTensorMap[12]}) + .BindOutputs({dumpTensorMap[5]}); + /* Node[4] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[5], dumpTensorMap[13]}) + .BindOutputs({dumpTensorMap[4]}); + /* Node[5] */ + vx_graph->CreateOperation(0.010000) + ->BindInputs({dumpTensorMap[4]}) + .BindOutputs({dumpTensorMap[3]}); + /* Node[6] */ + vx_graph + ->CreateOperation( + 64, tim::vx::PadType::AUTO, std::array({3, 3, 3}), + std::array({2, 2, 2}), std::array({1, 1, 1}), + std::array({1, 1, 1, 1, 1, 1}), 0, + tim::vx::DataLayout::WHDCN, tim::vx::DataLayout::WHDIcOc) + ->BindInputs({dumpTensorMap[3], dumpTensorMap[14]}) + .BindOutputs({dumpTensorMap[2]}); + /* Node[7] */ + vx_graph + ->CreateOperation( + std::vector>( + {1, 1, 1, 64})) + ->BindInputs({dumpTensorMap[16]}) + .BindOutputs({dumpTensorMap[15]}); + /* Node[8] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[2], dumpTensorMap[15]}) + .BindOutputs({dumpTensorMap[1]}); + /* Node[9] */ + vx_graph + ->CreateOperation( + std::vector>({0, 1, 2}), 1) + ->BindInputs({dumpTensorMap[1]}) + .BindOutputs({dumpTensorMap[17]}); + /* Node[10] */ + vx_graph->CreateOperation() + ->BindInputs({dumpTensorMap[1], dumpTensorMap[17]}) + .BindOutputs({dumpTensorMap[0]}); + + size_t bin_size = 0; + std::vector nbg_buf(bin_size); + + EXPECT_TRUE(vx_graph->CompileToBinary(nullptr, &bin_size)); + + std::vector tmp(bin_size); + nbg_buf.swap(tmp); + EXPECT_TRUE(vx_graph->CompileToBinary(nbg_buf.data(), &bin_size)); + + auto vx_nbg_graph = vx_context->CreateGraph(); + std::vector> input_tensors, output_tensors; + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {10, 14, 14, 32, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + std::vector in_data_0(10 * 14 * 14 * 32 * 1, 1.5f); + auto input_tensor_0 = + vx_nbg_graph->CreateTensor(vx_output_tspec, in_data_0.data()); + input_tensors.push_back(input_tensor_0); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 32, 1})), + tim::vx::TensorAttribute::INPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + std::vector in_data_1(32, 2.5f); + auto input_tensor_1 = + vx_nbg_graph->CreateTensor(vx_output_tspec, in_data_1.data()); + input_tensors.push_back(input_tensor_1); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {5, 7, 7, 64, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + auto output_tensor_0 = vx_nbg_graph->CreateTensor(vx_output_tspec); + output_tensors.push_back(output_tensor_0); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {5, 7, 7, 64, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + + auto output_tensor_1 = vx_nbg_graph->CreateTensor(vx_output_tspec); + output_tensors.push_back(output_tensor_1); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {10, 14, 14, 32, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + auto output_tensor_3 = vx_nbg_graph->CreateTensor(vx_output_tspec); + output_tensors.push_back(output_tensor_3); + + vx_output_tspec = tim::vx::TensorSpec( + tim::vx::DataType::FLOAT32, + tim::vx::ShapeType( + std::vector>( + {1, 1, 1, 64, 1})), + tim::vx::TensorAttribute::OUTPUT, + tim::vx::Quantization(tim::vx::QuantType::NONE, -1, + std::vector>({}), + std::vector>({}))); + auto output_tensor_2 = vx_nbg_graph->CreateTensor(vx_output_tspec); + output_tensors.push_back(output_tensor_2); + + auto nbg_node = vx_nbg_graph->CreateOperation( + nbg_buf.data(), input_tensors.size(), output_tensors.size()); + + nbg_node->BindInputs(input_tensors).BindOutputs(output_tensors); + EXPECT_TRUE(vx_nbg_graph->Compile()); + EXPECT_TRUE(vx_nbg_graph->Run()); +} // You can disable compile trace_test if only need replay // #undef ENABLE_API_TRACE #ifdef ENABLE_API_TRACE