// Copyright 2020 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. #pragma once #include #include #include #include #include #include #include #include "subgraph-tester.h" namespace xnnpack { class RuntimeTester : public SubgraphTester { public: using SubgraphTester::SubgraphTester; template inline std::vector RunWithFusion() { Run(); std::vector& tensor = this->external_tensors_.at(this->output_id_); std::vector output = std::vector(tensor.size() / sizeof(float)); std::memcpy(output.data(), tensor.data(), tensor.size()); return output; } template inline std::vector RunWithoutFusion() { Run(XNN_FLAG_NO_OPERATOR_FUSION); std::vector& tensor = this->external_tensors_.at(this->output_id_); std::vector output = std::vector(tensor.size() / sizeof(float)); memcpy(output.data(), tensor.data(), tensor.size()); return output; } size_t NumOperators() { size_t count = 0; for (size_t i = 0; i < runtime_->num_ops; i++) { if (runtime_->opdata[i].operator_objects[0] != NULL) { count++; } } return count; } private: void Run(uint32_t flags = 0) { xnn_runtime_t runtime = nullptr; ASSERT_EQ(xnn_status_success, xnn_create_runtime_v3(this->subgraph_.get(), nullptr, nullptr, flags, &runtime)); ASSERT_NE(nullptr, runtime); runtime_.reset(runtime); std::vector externals; for (auto it = this->external_tensors_.begin(); it != this->external_tensors_.end(); ++it) { if (it->first == this->output_id_) { // Scramble output tensor. std::fill(it->second.begin(), it->second.end(), 0xA8); } externals.push_back(xnn_external_value{it->first, it->second.data()}); } ASSERT_EQ(xnn_status_success, xnn_setup_runtime(runtime, externals.size(), externals.data())); ASSERT_EQ(xnn_status_success, xnn_invoke_runtime(runtime)); }; std::unique_ptr runtime_{nullptr, xnn_delete_runtime}; }; } // namespace xnnpack