// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include "lite/api/paddle_use_kernels.h" #include "lite/api/paddle_use_ops.h" #include "lite/core/arena/framework.h" namespace paddle { namespace lite { class CtcAlignComputeTester : public arena::TestCase { protected: // common attributes for this op. std::string input_ = "input"; std::string input_length_ = "input_length"; std::string output_ = "output"; std::string output_length_ = "output_length"; std::vector input_data_; std::vector input_shape_; std::vector> input_lod_; std::vector input_length_data_; std::vector input_length_shape_; std::vector output_data_; std::vector output_shape_; std::vector> output_lod_; std::vector output_length_data_; std::vector output_length_shape_; int blank_; bool merge_repeated_; int padding_value_; public: CtcAlignComputeTester(const Place& place, const std::string& alias, const std::vector& input_data, const std::vector input_shape, const std::vector>& input_lod, const std::vector& input_length_data, const std::vector input_length_shape, const int blank, const bool merge_repeated, const int padding_value, const std::vector& output_data, const std::vector& output_shape, const std::vector>& output_lod, const std::vector& output_length_data, const std::vector& output_length_shape) : TestCase(place, alias) { input_data_ = input_data; input_shape_ = input_shape; input_lod_ = input_lod; input_length_data_ = input_length_data; input_length_shape_ = input_length_shape; blank_ = blank; merge_repeated_ = merge_repeated; padding_value_ = padding_value; output_data_ = output_data; output_shape_ = output_shape; output_lod_ = output_lod; output_length_data_ = output_length_data; output_length_shape_ = output_length_shape; } void RunBaseline(Scope* scope) override { auto* output_tensor = scope->NewTensor(output_); output_tensor->Resize(output_shape_); if (!output_lod_.empty()) { output_tensor->set_lod(output_lod_); } auto* output_data = output_tensor->mutable_data(); int64_t output_num = 1; for (auto e : output_shape_) { output_num *= e; } for (int i = 0; i < output_num; i++) { output_data[i] = output_data_[i]; } if (!input_length_data_.empty() && !output_length_data_.empty()) { auto* output_length_tensor = scope->NewTensor(output_length_); output_length_tensor->Resize(output_length_shape_); auto* output_length_data = output_length_tensor->mutable_data(); int64_t num = 1; for (auto e : output_length_shape_) { num *= e; } for (int i = 0; i < num; i++) { output_length_data[i] = output_length_data_[i]; } } } void PrepareOpDesc(cpp::OpDesc* op_desc) { op_desc->SetType("ctc_align"); op_desc->SetInput("Input", {input_}); op_desc->SetOutput("Output", {output_}); if (!input_length_data_.empty()) { op_desc->SetInput("InputLength", {input_length_}); op_desc->SetOutput("OutputLength", {output_length_}); } op_desc->SetAttr("blank", blank_); op_desc->SetAttr("merge_repeated", merge_repeated_); op_desc->SetAttr("padding_value", padding_value_); } void PrepareData() override { SetCommonTensor(input_, DDim(input_shape_), input_data_.data(), input_lod_); if (!input_length_data_.empty()) { SetCommonTensor( input_length_, DDim(input_length_shape_), input_length_data_.data()); } } }; TEST(CtcAlign1, precision) { LOG(INFO) << "test ctc_align op"; #ifdef LITE_WITH_ARM // Define variable const std::vector& input_data = { 0, 1, 2, 2, 0, 4, 0, 4, 5, 0, 6, 6, 0, 0, 7, 7, 7, 0}; const std::vector input_shape = {18, 1}; const std::vector> input_lod = {{11, 7}}; const std::vector input_length_data = {}; const std::vector input_length_shape = {}; const int blank = 0; const bool merge_repeated = false; const int padding_value = 0; const std::vector output_data = {1, 2, 2, 4, 4, 5, 6, 6, 7, 7, 7}; const std::vector output_shape = {11, 1}; const std::vector> output_lod = {{7, 4}}; const std::vector output_length_data = {}; const std::vector output_length_shape = {}; // Test Place place(TARGET(kHost), PRECISION(kInt32)); std::unique_ptr tester( new CtcAlignComputeTester(place, "def", input_data, input_shape, input_lod, input_length_data, input_length_shape, blank, merge_repeated, padding_value, output_data, output_shape, output_lod, output_length_data, output_length_shape)); arena::Arena arena(std::move(tester), place, 2e-5); arena.TestPrecision(); #endif } TEST(CtcAlign2, precision) { LOG(INFO) << "test ctc_align op"; #ifdef LITE_WITH_ARM // Define variable const std::vector& input_data = { 0, 1, 2, 2, 0, 4, 0, 4, 5, 0, 6, 0, 0, 7, 7, 7, 0, 0}; const std::vector input_shape = {3, 6}; const std::vector> input_lod = {}; const std::vector input_length_data = {6, 5, 4}; const std::vector input_length_shape = {3, 1}; const int blank = 0; const bool merge_repeated = true; const int padding_value = 0; const std::vector output_data = { 1, 2, 4, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0}; const std::vector output_shape = {3, 6}; const std::vector> output_lod = {}; const std::vector output_length_data = {3, 3, 1}; const std::vector output_length_shape = {3, 1}; // Test Place place(TARGET(kHost), PRECISION(kInt32)); std::unique_ptr tester( new CtcAlignComputeTester(place, "def", input_data, input_shape, input_lod, input_length_data, input_length_shape, blank, merge_repeated, padding_value, output_data, output_shape, output_lod, output_length_data, output_length_shape)); arena::Arena arena(std::move(tester), place, 2e-5); arena.TestPrecision(); #endif } TEST(CtcAlign3, precision) { LOG(INFO) << "test ctc_align op"; #ifdef LITE_WITH_ARM // Define variable const std::vector& input_data = { 0, 1, 2, 2, 0, 4, 0, 4, 5, 0, 6, 0, 0, 7, 7, 7, 0, 0}; const std::vector input_shape = {3, 6}; const std::vector> input_lod = {}; const std::vector input_length_data = {6, 5, 4}; const std::vector input_length_shape = {3, 1}; const int blank = 0; const bool merge_repeated = false; const int padding_value = 0; const std::vector output_data = { 1, 2, 2, 4, 0, 0, 4, 5, 6, 0, 0, 0, 7, 7, 7, 0, 0, 0}; const std::vector output_shape = {3, 6}; const std::vector> output_lod = {}; const std::vector output_length_data = {4, 3, 3}; const std::vector output_length_shape = {3, 1}; // Test Place place(TARGET(kHost), PRECISION(kInt32)); std::unique_ptr tester( new CtcAlignComputeTester(place, "def", input_data, input_shape, input_lod, input_length_data, input_length_shape, blank, merge_repeated, padding_value, output_data, output_shape, output_lod, output_length_data, output_length_shape)); arena::Arena arena(std::move(tester), place, 2e-5); arena.TestPrecision(); #endif } } // namespace lite } // namespace paddle