91 lines
2.8 KiB
C++
91 lines
2.8 KiB
C++
// 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 <array>
|
|
|
|
#include <xnnpack.h>
|
|
#include <xnnpack/node-type.h>
|
|
|
|
#include "subgraph-tester.h"
|
|
#include <gtest/gtest.h>
|
|
|
|
namespace xnnpack {
|
|
|
|
TEST(SUBGRAPH_FP16, value_both_external_output_and_input) {
|
|
auto tester = SubgraphTester(4);
|
|
std::array<size_t, 4> pre_paddings = {0,1,0,0};
|
|
std::array<size_t, 4> post_paddings = {0,1,0,0};
|
|
// external input[0]
|
|
// /
|
|
// [constant pad]
|
|
// /
|
|
// external dynamic[1]
|
|
// output[2] /
|
|
// \ /
|
|
// [add]
|
|
// |
|
|
// external
|
|
// output[3]
|
|
tester
|
|
.AddInputTensorF32({1, 2, 2, 3}, 0)
|
|
.AddDynamicTensorF32({1, 1, 1, 3}, 1)
|
|
.AddOutputTensorF32({1, 4, 2, 3}, 2)
|
|
.AddOutputTensorF32({1, 4, 2, 3}, 3)
|
|
.AddConstantPad(pre_paddings.data(), post_paddings.data(), 0.0f, 0, 2)
|
|
.AddAddition(2, 1, 3)
|
|
.Optimize()
|
|
.RewriteForFp16();
|
|
|
|
// After rewriting for FP16, the graph should look like this, with * indicating new operators and values created:
|
|
//
|
|
// external input[0]
|
|
// |
|
|
// [convert]*
|
|
// |
|
|
// input[4]*
|
|
// /
|
|
// [constant pad]
|
|
// /
|
|
// fp16 value[5]*
|
|
// | \
|
|
// [convert]* \
|
|
// | \
|
|
// external \ dynamic[1] converted in-place
|
|
// output[2] \ /
|
|
// \ /
|
|
// [add]
|
|
// |
|
|
// fp16 value[6]*
|
|
// |
|
|
// [convert]*
|
|
// |
|
|
// external
|
|
// output[3]
|
|
|
|
// We should have 3 convert nodes, one for external input, 2 for external
|
|
// outputs, so 5 in total, including the pad and add in the original graph.
|
|
ASSERT_EQ(tester.NumNodes(), 5);
|
|
|
|
const xnn_node* output_convert_node = tester.Node(4);
|
|
ASSERT_EQ(output_convert_node->type, xnn_node_type_convert);
|
|
ASSERT_EQ(output_convert_node->compute_type, xnn_compute_type_fp16_to_fp32);
|
|
|
|
// Check that Addition node refers to the FP16 value before conversion.
|
|
const xnn_node* addition_node = tester.Node(3);
|
|
ASSERT_EQ(addition_node->type, xnn_node_type_add2);
|
|
ASSERT_EQ(addition_node->inputs[0], 5);
|
|
ASSERT_EQ(addition_node->inputs[1], 1);
|
|
ASSERT_EQ(tester.Value(5)->datatype, xnn_datatype_fp16);
|
|
ASSERT_EQ(tester.Value(1)->datatype, xnn_datatype_fp16);
|
|
|
|
ASSERT_EQ(tester.Node(2)->type, xnn_node_type_convert);
|
|
ASSERT_EQ(tester.Node(2)->compute_type, xnn_compute_type_fp16_to_fp32);
|
|
ASSERT_EQ(tester.Node(1)->type, xnn_node_type_static_constant_pad);
|
|
ASSERT_EQ(tester.Node(0)->type, xnn_node_type_convert);
|
|
ASSERT_EQ(tester.Node(0)->compute_type, xnn_compute_type_fp32_to_fp16);
|
|
}
|
|
|
|
} // namespace xnnpack
|