diff options
author | Zhi An Ng <zhin@google.com> | 2022-06-13 22:46:13 -0700 |
---|---|---|
committer | XNNPACK Team <xnnpack-github-robot@google.com> | 2022-06-13 22:46:59 -0700 |
commit | d70915f2cee469e87809f055dd3b2ff3d7ba0983 (patch) | |
tree | 2f78f75ec0c1dc0bfc70c32f640fa3bc2753b498 | |
parent | 53af456dd04979fc78d232fb2a86f7538f2b946e (diff) | |
download | XNNPACK-d70915f2cee469e87809f055dd3b2ff3d7ba0983.tar.gz |
Add tests for subgraph level API to create Square
Test that an xnn_node's field is set correctly, and that calling the subgraph API produces the same results as calling the operator API.
PiperOrigin-RevId: 454775216
-rw-r--r-- | BUILD.bazel | 14 | ||||
-rwxr-xr-x | CMakeLists.txt | 5 | ||||
-rw-r--r-- | test/square.cc | 115 |
3 files changed, 134 insertions, 0 deletions
diff --git a/BUILD.bazel b/BUILD.bazel index 452bc36fe..0a5c31444 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -14650,6 +14650,20 @@ xnnpack_unit_test( ) xnnpack_unit_test( + name = "square_test", + srcs = [ + "test/square.cc", + ], + deps = [ + ":XNNPACK_test_mode", + ":node_type", + ":operators_test_mode", + ":subgraph_test_mode", + ":subgraph_unary_tester", + ], +) + +xnnpack_unit_test( name = "static_reshape_test", srcs = [ "test/static-reshape.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bb8293f4..2848adaf2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7482,6 +7482,11 @@ IF(XNNPACK_BUILD_TESTS) TARGET_LINK_LIBRARIES(softmax-test PRIVATE XNNPACK fp16 gtest gtest_main subgraph) ADD_TEST(softmax-test softmax-test) + ADD_EXECUTABLE(square-test test/square.cc) + TARGET_INCLUDE_DIRECTORIES(square-test PRIVATE src test) + TARGET_LINK_LIBRARIES(square-test PRIVATE XNNPACK fp16 gtest gtest_main subgraph) + ADD_TEST(square-test square-test) + ADD_EXECUTABLE(static-reshape-test test/static-reshape.cc) TARGET_INCLUDE_DIRECTORIES(static-reshape-test PRIVATE src test) TARGET_LINK_LIBRARIES(static-reshape-test PRIVATE XNNPACK fp16 gtest gtest_main subgraph) diff --git a/test/square.cc b/test/square.cc new file mode 100644 index 000000000..6347681f5 --- /dev/null +++ b/test/square.cc @@ -0,0 +1,115 @@ +// Copyright 2022 Google LLC +// +// This source code is licensed under the BSD-style license found in the +// LICENSE file in the root directory of this source tree. + +#include <algorithm> +#include <array> +#include <cstdint> +#include <cstddef> +#include <limits> +#include <memory> +#include <random> + +#include <xnnpack.h> +#include <xnnpack/node-type.h> +#include <xnnpack/operator.h> +#include <xnnpack/subgraph.h> + +#include "subgraph-unary-tester.h" +#include <gtest/gtest.h> + +using SquareTestF32 = UnaryTest<float>; + +TEST_F(SquareTestF32, define) +{ + ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr)); + + xnn_subgraph_t subgraph = nullptr; + ASSERT_EQ(xnn_status_success, xnn_create_subgraph(/*external_value_ids=*/2, /*flags=*/0, &subgraph)); + std::unique_ptr<xnn_subgraph, decltype(&xnn_delete_subgraph)> auto_subgraph(subgraph, xnn_delete_subgraph); + + input_id = XNN_INVALID_NODE_ID; + ASSERT_EQ( + xnn_status_success, xnn_define_tensor_value( + subgraph, xnn_datatype_fp32, dims.size(), dims.data(), nullptr, 0, + /*flags=*/XNN_VALUE_FLAG_EXTERNAL_INPUT, &input_id)); + ASSERT_NE(input_id, XNN_INVALID_NODE_ID); + + output_id = XNN_INVALID_NODE_ID; + ASSERT_EQ( + xnn_status_success, xnn_define_tensor_value( + subgraph, xnn_datatype_fp32, dims.size(), dims.data(), nullptr, 1, + /*flags=*/XNN_VALUE_FLAG_EXTERNAL_OUTPUT, &output_id)); + ASSERT_NE(output_id, XNN_INVALID_NODE_ID); + + ASSERT_EQ(xnn_status_success, xnn_define_square(subgraph, input_id, output_id, /*flags=*/0)); + + ASSERT_EQ(subgraph->num_nodes, 1); + const struct xnn_node* node = &subgraph->nodes[0]; + ASSERT_EQ(node->type, xnn_node_type_square); + ASSERT_EQ(node->compute_type, xnn_compute_type_fp32); + ASSERT_EQ(node->num_inputs, 1); + ASSERT_EQ(node->inputs[0], input_id); + ASSERT_EQ(node->num_outputs, 1); + ASSERT_EQ(node->outputs[0], output_id); + ASSERT_EQ(node->flags, 0); +} + +TEST_F(SquareTestF32, matches_operator_api) +{ + std::uniform_real_distribution<float> f32dist(-255.0f, 255.0f); + std::generate(input.begin(), input.end(), [&]() { return f32dist(rng); }); + std::fill(operator_output.begin(), operator_output.end(), nanf("")); + std::fill(subgraph_output.begin(), subgraph_output.end(), nanf("")); + + ASSERT_EQ(xnn_status_success, xnn_initialize(/*allocator=*/nullptr)); + + // Call operator API. + xnn_operator_t op = nullptr; + const xnn_status status = + xnn_create_square_nc_f32(channels, channels, channels, /*flags=*/0, &op); + if (status == xnn_status_unsupported_hardware) { + GTEST_SKIP(); + } + + ASSERT_EQ(xnn_status_success, status); + ASSERT_NE(nullptr, op); + std::unique_ptr<xnn_operator, decltype(&xnn_delete_operator)> auto_op(op, xnn_delete_operator); + + ASSERT_EQ( + xnn_status_success, + xnn_setup_square_nc_f32(op, batch_size, input.data(), operator_output.data(), /*threadpool=*/nullptr)); + + ASSERT_EQ(xnn_status_success, xnn_run_operator(op, /*threadpool=*/nullptr)); + + // Call subgraph API. + xnn_subgraph_t subgraph = nullptr; + ASSERT_EQ(xnn_status_success, xnn_create_subgraph(/*external_value_ids=*/2, /*flags=*/0, &subgraph)); + std::unique_ptr<xnn_subgraph, decltype(&xnn_delete_subgraph)> auto_subgraph(subgraph, xnn_delete_subgraph); + input_id = XNN_INVALID_NODE_ID; + ASSERT_EQ( + xnn_status_success, xnn_define_tensor_value( + subgraph, xnn_datatype_fp32, dims.size(), dims.data(), nullptr, /*external_id=*/0, + /*flags=*/XNN_VALUE_FLAG_EXTERNAL_INPUT, &input_id)); + ASSERT_NE(input_id, XNN_INVALID_NODE_ID); + + output_id = XNN_INVALID_NODE_ID; + ASSERT_EQ( + xnn_status_success, xnn_define_tensor_value( + subgraph, xnn_datatype_fp32, dims.size(), dims.data(), nullptr, /*external_id=*/1, + /*flags=*/XNN_VALUE_FLAG_EXTERNAL_OUTPUT, &output_id)); + ASSERT_NE(output_id, XNN_INVALID_NODE_ID); + + xnn_runtime_t runtime = nullptr; + ASSERT_EQ(xnn_status_success, xnn_define_square(subgraph, input_id, output_id, /*flags=*/0)); + ASSERT_EQ(xnn_status_success, xnn_create_runtime_v3(subgraph, nullptr, nullptr, /*flags=*/0, &runtime)); + ASSERT_NE(nullptr, runtime); + std::unique_ptr<xnn_runtime, decltype(&xnn_delete_runtime)> auto_runtime(runtime, xnn_delete_runtime); + std::array<xnn_external_value, 2> external = { + xnn_external_value{input_id, input.data()}, xnn_external_value{output_id, subgraph_output.data()}}; + ASSERT_EQ(xnn_status_success, xnn_setup_runtime(runtime, external.size(), external.data())); + ASSERT_EQ(xnn_status_success, xnn_invoke_runtime(runtime)); + + ASSERT_EQ(subgraph_output, operator_output); +} |