chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
get_property(paddle_lib GLOBAL PROPERTY PADDLE_LIB_NAME)
|
||||
paddle_test(test_onednn_op_inplace SRCS test_onednn_op_inplace.cc)
|
||||
paddle_test(test_onednn_cpu_quantize_pass SRCS test_onednn_cpu_quantize_pass.cc)
|
||||
|
||||
paddle_test(test_conv_onednn_nhwc SRCS test_conv_onednn_nhwc.cc)
|
||||
|
||||
set(TEST_ONEDNN_CACHING_DEPS
|
||||
op_registry
|
||||
elementwise_mul_op
|
||||
elementwise_add_op
|
||||
activation_op
|
||||
phi
|
||||
common
|
||||
scope
|
||||
generated_static_op)
|
||||
|
||||
if(WITH_GPU OR WITH_ROCM)
|
||||
set(TEST_ONEDNN_CACHING_DEPS ${TEST_ONEDNN_CACHING_DEPS} depthwise_conv)
|
||||
endif()
|
||||
paddle_test(test_onednn_caching SRCS test_onednn_caching.cc)
|
||||
|
||||
if(WITH_TESTING)
|
||||
paddle_test(test_onednn_op_nhwc SRCS test_onednn_op_nhwc.cc)
|
||||
endif()
|
||||
|
||||
paddle_test(test_onednn_pool_adaptive_op SRCS test_onednn_pool_adaptive_op.cc)
|
||||
|
||||
paddle_test(test_onednn_squeeze SRCS test_onednn_squeeze.cc)
|
||||
|
||||
paddle_test(test_onednn_conv2d_transpose_bias SRCS
|
||||
test_onednn_conv2d_transpose_bias.cc)
|
||||
|
||||
if(WITH_ONNXRUNTIME AND WIN32)
|
||||
# Copy onnxruntime for some c++ test in Windows, since the test will
|
||||
# be build only in CI, so suppose the generator in Windows is Ninja.
|
||||
copy_onnx(test_onednn_op_nhwc)
|
||||
endif()
|
||||
@@ -0,0 +1,194 @@
|
||||
// Copyright (c) 2023 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 <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/fluid/framework/lod_tensor.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/scope.h"
|
||||
#include "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
template <typename DataType>
|
||||
void AddVarToScope(const std::string var_name,
|
||||
paddle::framework::Scope* scope,
|
||||
const phi::DDim& dims) {
|
||||
std::random_device seed;
|
||||
std::default_random_engine engine(seed());
|
||||
std::uniform_real_distribution<float> dist(0, 100);
|
||||
|
||||
phi::DenseTensor tmp_tensor;
|
||||
auto* tmp_data = tmp_tensor.mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
auto* tensor = scope->Var(var_name)->GetMutable<phi::DenseTensor>();
|
||||
tensor->mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
for (auto i = 0; i < tensor->numel(); ++i) {
|
||||
tmp_data[i] = static_cast<DataType>(dist(engine));
|
||||
}
|
||||
paddle::framework::TensorCopySync(tmp_tensor, phi::CPUPlace(), tensor);
|
||||
}
|
||||
TEST(test_conv2d_output, fp32) {
|
||||
paddle::framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
|
||||
paddle::framework::OpDesc conv2d_op(nullptr);
|
||||
conv2d_op.SetType("conv2d");
|
||||
conv2d_op.SetInput("Input", {"conv2d-X"});
|
||||
conv2d_op.SetInput("Filter", {"conv2d-Y"});
|
||||
conv2d_op.SetOutput("Output", {"conv2d-Out"});
|
||||
|
||||
AddVarToScope<float>("conv2d-X", &scope, {1, 3, 224, 224});
|
||||
AddVarToScope<float>("conv2d-Y", &scope, {64, 3, 7, 7});
|
||||
AddVarToScope<float>("conv2d-Out", &scope, {1, 64, 218, 218});
|
||||
|
||||
const std::vector<int> strides({1, 1});
|
||||
const std::vector<int> paddings({1, 1});
|
||||
const std::vector<int> dilations({1, 1});
|
||||
const int groups = 1;
|
||||
|
||||
conv2d_op.SetAttr("strides", strides);
|
||||
conv2d_op.SetAttr("paddings", paddings);
|
||||
conv2d_op.SetAttr("dilations", dilations);
|
||||
conv2d_op.SetAttr("groups", groups);
|
||||
conv2d_op.SetAttr("use_onednn", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(conv2d_op);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
TEST(test_conv2d_output, int8) {
|
||||
paddle::framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
|
||||
paddle::framework::OpDesc conv2d_op(nullptr);
|
||||
conv2d_op.SetType("conv2d");
|
||||
conv2d_op.SetInput("Input", {"conv2d-X"});
|
||||
conv2d_op.SetInput("Filter", {"conv2d-Y"});
|
||||
conv2d_op.SetOutput("Output", {"conv2d-Out"});
|
||||
|
||||
AddVarToScope<int8_t>("conv2d-X", &scope, {1, 3, 224, 224});
|
||||
AddVarToScope<int8_t>("conv2d-Y", &scope, {64, 3, 7, 7});
|
||||
AddVarToScope<int8_t>("conv2d-Out", &scope, {1, 64, 218, 218});
|
||||
|
||||
const std::vector<int> strides({1, 1});
|
||||
const std::vector<int> paddings({1, 1});
|
||||
const std::vector<int> dilations({1, 1});
|
||||
const int groups = 1;
|
||||
|
||||
conv2d_op.SetAttr("strides", strides);
|
||||
conv2d_op.SetAttr("paddings", paddings);
|
||||
conv2d_op.SetAttr("dilations", dilations);
|
||||
conv2d_op.SetAttr("groups", groups);
|
||||
conv2d_op.SetAttr("use_onednn", true);
|
||||
conv2d_op.SetAttr("onednn_data_type", std::string("int8"));
|
||||
conv2d_op.SetAttr("force_fp32_output", false);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(conv2d_op);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
TEST(test_conv2d_output, ic1) {
|
||||
paddle::framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
|
||||
paddle::framework::OpDesc conv2d_op(nullptr);
|
||||
conv2d_op.SetType("conv2d");
|
||||
conv2d_op.SetInput("Input", {"conv2d-X"});
|
||||
conv2d_op.SetInput("Filter", {"conv2d-Y"});
|
||||
conv2d_op.SetOutput("Output", {"conv2d-Out"});
|
||||
|
||||
AddVarToScope<float>("conv2d-X", &scope, {1, 1, 224, 224});
|
||||
AddVarToScope<float>("conv2d-Y", &scope, {64, 1, 7, 7});
|
||||
AddVarToScope<float>("conv2d-Out", &scope, {1, 64, 218, 218});
|
||||
|
||||
const std::vector<int> strides({1, 1});
|
||||
const std::vector<int> paddings({1, 1});
|
||||
const std::vector<int> dilations({1, 1});
|
||||
const int groups = 1;
|
||||
|
||||
conv2d_op.SetAttr("strides", strides);
|
||||
conv2d_op.SetAttr("paddings", paddings);
|
||||
conv2d_op.SetAttr("dilations", dilations);
|
||||
conv2d_op.SetAttr("groups", groups);
|
||||
conv2d_op.SetAttr("use_onednn", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(conv2d_op);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
|
||||
TEST(test_conv2d_output, ic2) {
|
||||
paddle::framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
|
||||
paddle::framework::OpDesc conv2d_op(nullptr);
|
||||
conv2d_op.SetType("conv2d");
|
||||
conv2d_op.SetInput("Input", {"conv2d-X"});
|
||||
conv2d_op.SetInput("Filter", {"conv2d-Y"});
|
||||
conv2d_op.SetOutput("Output", {"conv2d-Out"});
|
||||
|
||||
AddVarToScope<float>("conv2d-X", &scope, {1, 2, 224, 224});
|
||||
AddVarToScope<float>("conv2d-Y", &scope, {64, 2, 7, 7});
|
||||
AddVarToScope<float>("conv2d-Out", &scope, {1, 64, 218, 218});
|
||||
|
||||
const std::vector<int> strides({1, 1});
|
||||
const std::vector<int> paddings({1, 1});
|
||||
const std::vector<int> dilations({1, 1});
|
||||
const int groups = 1;
|
||||
|
||||
conv2d_op.SetAttr("strides", strides);
|
||||
conv2d_op.SetAttr("paddings", paddings);
|
||||
conv2d_op.SetAttr("dilations", dilations);
|
||||
conv2d_op.SetAttr("groups", groups);
|
||||
conv2d_op.SetAttr("use_onednn", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(conv2d_op);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
|
||||
TEST(test_conv2d_output, ic4) {
|
||||
paddle::framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
|
||||
paddle::framework::OpDesc conv2d_op(nullptr);
|
||||
conv2d_op.SetType("conv2d");
|
||||
conv2d_op.SetInput("Input", {"conv2d-X"});
|
||||
conv2d_op.SetInput("Filter", {"conv2d-Y"});
|
||||
conv2d_op.SetOutput("Output", {"conv2d-Out"});
|
||||
|
||||
AddVarToScope<float>("conv2d-X", &scope, {1, 4, 224, 224});
|
||||
AddVarToScope<float>("conv2d-Y", &scope, {64, 4, 7, 7});
|
||||
AddVarToScope<float>("conv2d-Out", &scope, {1, 64, 218, 218});
|
||||
|
||||
const std::vector<int> strides({1, 1});
|
||||
const std::vector<int> paddings({1, 1});
|
||||
const std::vector<int> dilations({1, 1});
|
||||
const int groups = 1;
|
||||
|
||||
conv2d_op.SetAttr("strides", strides);
|
||||
conv2d_op.SetAttr("paddings", paddings);
|
||||
conv2d_op.SetAttr("dilations", dilations);
|
||||
conv2d_op.SetAttr("groups", groups);
|
||||
conv2d_op.SetAttr("use_onednn", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(conv2d_op);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
// Copyright (c) 2020 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 <algorithm>
|
||||
#include <map>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/fluid/framework/lod_tensor.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/scope.h"
|
||||
#include "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace operators {
|
||||
|
||||
struct InputVars {
|
||||
std::string name;
|
||||
phi::DenseTensor *tensor;
|
||||
};
|
||||
|
||||
class CacheTester {
|
||||
public:
|
||||
CacheTester() {
|
||||
// Clear oneDNN cache
|
||||
auto &pool = phi::DeviceContextPool::Instance();
|
||||
phi::CPUPlace place;
|
||||
onednn_dev_ctx_ = dynamic_cast<phi::OneDNNContext *>(pool.Get(place));
|
||||
onednn_dev_ctx_->ResetBlobMap(nullptr);
|
||||
}
|
||||
|
||||
bool Analyze(uint16_t num_entries) {
|
||||
// Number of created objects in cache should be as expected (num_entries)
|
||||
return onednn_dev_ctx_->GetCachedObjectsNumber() == num_entries;
|
||||
}
|
||||
|
||||
private:
|
||||
phi::OneDNNContext *onednn_dev_ctx_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void RunOperator(const phi::Place &place,
|
||||
const std::string &op_type,
|
||||
const phi::DDim &dims,
|
||||
const std::string &first_input) {
|
||||
framework::Scope scope;
|
||||
|
||||
std::map<const std::string, int> num_inputs = {{"softmax", 1},
|
||||
{"relu", 1},
|
||||
{"conv2d", 2},
|
||||
{"elementwise_add", 2},
|
||||
{"elementwise_mul", 2}};
|
||||
|
||||
std::string first_input_var_name = (op_type == "conv2d") ? "Input" : "X";
|
||||
std::string second_input_var_name = (op_type == "conv2d") ? "Filter" : "Y";
|
||||
std::string output_var_name = (op_type == "conv2d") ? "Output" : "Out";
|
||||
std::string output_name = "output";
|
||||
|
||||
std::vector<InputVars> input_names = {
|
||||
{first_input, scope.Var(first_input)->GetMutable<phi::DenseTensor>()},
|
||||
{"x1",
|
||||
num_inputs[op_type] > 1 ? scope.Var("x1")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr},
|
||||
{"x2",
|
||||
num_inputs[op_type] > 2 ? scope.Var("x2")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr},
|
||||
{"x3",
|
||||
num_inputs[op_type] > 3 ? scope.Var("x3")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr},
|
||||
{"x4",
|
||||
num_inputs[op_type] > 4 ? scope.Var("x4")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr}};
|
||||
auto *y = scope.Var(output_name)->GetMutable<phi::DenseTensor>();
|
||||
|
||||
// Initialize input data
|
||||
std::uniform_real_distribution<T> dist(static_cast<T>(10.0),
|
||||
static_cast<T>(20.0));
|
||||
std::mt19937 engine;
|
||||
size_t numel = static_cast<size_t>(common::product(dims));
|
||||
for (int i = 0; i < num_inputs[op_type]; ++i) {
|
||||
input_names[i].tensor->Resize(dims);
|
||||
auto data_ptr = input_names[i].tensor->mutable_data<T>(place);
|
||||
for (size_t i = 0; i < numel; ++i) {
|
||||
data_ptr[i] = dist(engine);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize output
|
||||
y->Resize(dims);
|
||||
auto y_ptr = y->mutable_data<T>(place);
|
||||
for (size_t i = 0; i < numel; ++i) {
|
||||
y_ptr[i] = static_cast<T>(0);
|
||||
}
|
||||
|
||||
auto &pool = phi::DeviceContextPool::Instance();
|
||||
|
||||
auto op = num_inputs[op_type] > 1
|
||||
? framework::OpRegistry::CreateOp(
|
||||
op_type,
|
||||
{{first_input_var_name, {first_input}},
|
||||
{second_input_var_name, {"x1"}}},
|
||||
{{output_var_name, {output_name}}},
|
||||
{{"use_onednn", {true}}})
|
||||
: framework::OpRegistry::CreateOp(
|
||||
op_type,
|
||||
{{first_input_var_name, {first_input}}},
|
||||
{{output_var_name, {output_name}}},
|
||||
{{"use_onednn", {true}}});
|
||||
|
||||
op->Run(scope, place);
|
||||
pool.Get(place)->Wait();
|
||||
}
|
||||
|
||||
TEST(test_conv2d_reuse_cache, cpu_place) {
|
||||
phi::DDim dims({1, 16, 32, 64});
|
||||
phi::CPUPlace p;
|
||||
CacheTester ct;
|
||||
RunOperator<float>(p, "conv2d", dims, "input_signal");
|
||||
RunOperator<float>(p, "conv2d", dims, "input_signal");
|
||||
PADDLE_ENFORCE_EQ(ct.Analyze(9),
|
||||
true,
|
||||
common::errors::InvalidArgument(
|
||||
"Invalid number of cached oneDNN objects"));
|
||||
}
|
||||
|
||||
TEST(test_conv2d_noreuse_cache, cpu_place) {
|
||||
phi::DDim dims({1, 16, 32, 64});
|
||||
phi::CPUPlace p;
|
||||
CacheTester ct;
|
||||
RunOperator<float>(p, "conv2d", dims, "input_signal");
|
||||
RunOperator<float>(p, "conv2d", dims, "input_signal2");
|
||||
PADDLE_ENFORCE_EQ(ct.Analyze(18),
|
||||
true,
|
||||
common::errors::InvalidArgument(
|
||||
"Invalid number of cached oneDNN objects"));
|
||||
}
|
||||
|
||||
} // namespace operators
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,75 @@
|
||||
/* Copyright (c) 2024 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 <gtest/gtest.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "paddle/fluid/framework/lod_tensor.h"
|
||||
#include "paddle/fluid/framework/naive_executor.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/scope.h"
|
||||
#include "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace inference {
|
||||
|
||||
template <typename DataType>
|
||||
void AddVarToScope(const std::string var_name,
|
||||
paddle::framework::Scope* scope,
|
||||
const phi::DDim& dims) {
|
||||
std::random_device seed;
|
||||
std::default_random_engine engine(seed());
|
||||
std::uniform_real_distribution<float> dist(0, 100);
|
||||
|
||||
phi::DenseTensor tmp_tensor;
|
||||
auto* tmp_data = tmp_tensor.mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
auto* tensor = scope->Var(var_name)->GetMutable<phi::DenseTensor>();
|
||||
tensor->mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
for (auto i = 0; i < tensor->numel(); ++i) {
|
||||
tmp_data[i] = static_cast<DataType>(dist(engine));
|
||||
}
|
||||
paddle::framework::TensorCopySync(tmp_tensor, phi::CPUPlace(), tensor);
|
||||
}
|
||||
void test_conv2d_transpose_bias() {
|
||||
framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
// Prepare Op description
|
||||
framework::OpDesc desc;
|
||||
|
||||
desc.SetType("conv2d_transpose_bias");
|
||||
desc.SetInput("Input", {"convtranspose-Input"});
|
||||
desc.SetInput("Filter", {"convtranspose-Filter"});
|
||||
desc.SetInput("Bias", {"convtranspose-Bias"});
|
||||
desc.SetOutput("Output", {"convtranspose-Out"});
|
||||
|
||||
AddVarToScope<float>("convtranspose-Input", &scope, {1, 512, 23, 19});
|
||||
AddVarToScope<float>("convtranspose-Filter", &scope, {512, 256, 5, 5});
|
||||
AddVarToScope<float>("convtranspose-Bias", &scope, {256});
|
||||
AddVarToScope<float>("convtranspose-Out", &scope, {1, 256, 27, 23});
|
||||
|
||||
desc.SetAttr("use_onednn", true);
|
||||
desc.SetAttr("is_test", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(desc);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
|
||||
TEST(Conv2dTransposeBias, normal) { test_conv2d_transpose_bias(); }
|
||||
|
||||
} // namespace inference
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,117 @@
|
||||
/* Copyright (c) 2023 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 <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include "paddle/fluid/framework/ir/fuse_pass_base.h"
|
||||
#include "paddle/fluid/framework/ir/graph.h"
|
||||
#include "paddle/fluid/framework/ir/pass.h"
|
||||
#include "paddle/fluid/framework/ir/pass_tester_helper.h"
|
||||
#include "paddle/fluid/framework/op_desc.h"
|
||||
#include "paddle/fluid/framework/program_desc.h"
|
||||
#include "paddle/fluid/platform/enforce.h"
|
||||
|
||||
using std::pair;
|
||||
using std::string;
|
||||
using std::unordered_map;
|
||||
|
||||
PD_DEFINE_bool(enable_onednn, true, "Enable ONEDNN");
|
||||
|
||||
namespace paddle {
|
||||
namespace pass {
|
||||
|
||||
using VarQuantScale =
|
||||
std::unordered_map<std::string, std::pair<bool, phi::DenseTensor>>;
|
||||
|
||||
static float const SCALE = 2.f;
|
||||
const std::vector<std::string> PreGraphPasses({
|
||||
"conv_activation_onednn_fuse_pass",
|
||||
"cpu_quantize_placement_pass",
|
||||
"cpu_quantize_pass",
|
||||
});
|
||||
|
||||
TEST(cpuQuantizePass, ConvReLU6) {
|
||||
paddle::framework::ProgramDesc prog;
|
||||
auto* block = prog.MutableBlock(0);
|
||||
|
||||
auto* conv2d_op = block->AppendOp();
|
||||
conv2d_op->SetType("conv2d");
|
||||
conv2d_op->SetInput("Input", {"conv2d-X"});
|
||||
conv2d_op->SetInput("Filter", {"conv2d-Y"});
|
||||
conv2d_op->SetOutput("Output", {"conv2d-Out"});
|
||||
|
||||
const std::vector<int> strides({1, 1});
|
||||
const std::vector<int> paddings({1, 1});
|
||||
const std::vector<int> dilations({1, 1});
|
||||
const int groups = 1;
|
||||
|
||||
conv2d_op->SetAttr("strides", strides);
|
||||
conv2d_op->SetAttr("paddings", paddings);
|
||||
conv2d_op->SetAttr("dilations", dilations);
|
||||
conv2d_op->SetAttr("groups", groups);
|
||||
|
||||
auto* relu6_op = block->AppendOp();
|
||||
relu6_op->SetType("relu6");
|
||||
relu6_op->SetAttr("threshold", 6.f);
|
||||
relu6_op->SetInput("X", {"conv2d-Out"});
|
||||
relu6_op->SetOutput("Out", {"relu-Out"});
|
||||
|
||||
auto place = phi::CPUPlace();
|
||||
VarQuantScale* scales = new VarQuantScale();
|
||||
phi::DenseTensor scale_input_tensor;
|
||||
phi::DenseTensor scale_weight_tensor;
|
||||
scale_input_tensor.Resize({1});
|
||||
scale_weight_tensor.Resize({1});
|
||||
auto* ptr_scale_input = scale_input_tensor.mutable_data<double>(place);
|
||||
auto* ptr_scale_weight = scale_weight_tensor.mutable_data<double>(place);
|
||||
ptr_scale_input[0] = SCALE;
|
||||
ptr_scale_weight[0] = SCALE;
|
||||
|
||||
(*scales)["conv2d-X"] = std::make_pair(false, std::move(scale_input_tensor));
|
||||
(*scales)["conv2d-Y"] = std::make_pair(false, std::move(scale_weight_tensor));
|
||||
|
||||
paddle::framework::Scope scope;
|
||||
|
||||
std::unique_ptr<paddle::framework::ir::Graph> graph(
|
||||
new paddle::framework::ir::Graph(prog));
|
||||
(graph)->SetNotOwned(paddle::framework::ir::kParamScopeAttr, &scope);
|
||||
|
||||
for (const auto& pass : PreGraphPasses) {
|
||||
auto pass_ = paddle::framework::ir::PassRegistry::Instance().Get(pass);
|
||||
if (pass == "cpu_quantize_pass") {
|
||||
pass_->Set("quant_var_scales", scales);
|
||||
}
|
||||
graph.reset(pass_->Apply(graph.release()));
|
||||
}
|
||||
int fused_conv2d_num = 0;
|
||||
for (auto* node : graph->Nodes()) {
|
||||
if (node->IsOp() && node->Op() && node->Op()->Type() == "fused_conv2d") {
|
||||
PADDLE_ENFORCE_EQ(
|
||||
node->Op()->GetAttrIfExists<float>("fuse_beta"),
|
||||
6,
|
||||
common::errors::InvalidArgument("Attr fuse_beta must equal to 6. "));
|
||||
fused_conv2d_num++;
|
||||
}
|
||||
}
|
||||
PADDLE_ENFORCE_GT(
|
||||
fused_conv2d_num,
|
||||
0,
|
||||
common::errors::InvalidArgument("Graph must contain fused_conv2d. "));
|
||||
}
|
||||
|
||||
} // namespace pass
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,144 @@
|
||||
// Copyright (c) 2020 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 <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/fluid/framework/lod_tensor.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/scope.h"
|
||||
#include "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
PD_DECLARE_KERNEL(add_raw, OneDNN, ONEDNN);
|
||||
|
||||
namespace paddle {
|
||||
namespace operators {
|
||||
|
||||
struct InputVars {
|
||||
std::string name;
|
||||
phi::DenseTensor *tensor;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool TestMain(const phi::Place &place,
|
||||
const std::string &op_type,
|
||||
const phi::DDim &dims,
|
||||
const int num_inputs) {
|
||||
framework::Scope scope;
|
||||
|
||||
std::vector<InputVars> input_names = {
|
||||
{"x", scope.Var("x")->GetMutable<phi::DenseTensor>()},
|
||||
{"x1",
|
||||
num_inputs > 1 ? scope.Var("x1")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr},
|
||||
{"x2",
|
||||
num_inputs > 2 ? scope.Var("x2")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr},
|
||||
{"x3",
|
||||
num_inputs > 3 ? scope.Var("x3")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr},
|
||||
{"x4",
|
||||
num_inputs > 4 ? scope.Var("x4")->GetMutable<phi::DenseTensor>()
|
||||
: nullptr}};
|
||||
auto *y = scope.Var("y")->GetMutable<phi::DenseTensor>();
|
||||
|
||||
// Initialize input data
|
||||
std::uniform_real_distribution<T> dist(static_cast<T>(10.0),
|
||||
static_cast<T>(20.0));
|
||||
std::mt19937 engine;
|
||||
size_t numel = static_cast<size_t>(common::product(dims));
|
||||
for (int i = 0; i < num_inputs; ++i) {
|
||||
input_names[i].tensor->Resize(dims);
|
||||
auto data_ptr = input_names[i].tensor->mutable_data<T>(place);
|
||||
for (size_t i = 0; i < numel; ++i) {
|
||||
data_ptr[i] = dist(engine);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize output
|
||||
y->Resize(dims);
|
||||
auto y_ptr = y->mutable_data<T>(place);
|
||||
for (size_t i = 0; i < numel; ++i) {
|
||||
y_ptr[i] = static_cast<T>(0);
|
||||
}
|
||||
|
||||
auto &pool = phi::DeviceContextPool::Instance();
|
||||
|
||||
// Out of place (reference) computation
|
||||
auto op_ref =
|
||||
num_inputs > 1
|
||||
? framework::OpRegistry::CreateOp(op_type,
|
||||
{{"X", {"x"}}, {"Y", {"x1"}}},
|
||||
{{"Out", {"y"}}},
|
||||
{{"use_onednn", {true}}})
|
||||
: framework::OpRegistry::CreateOp(op_type,
|
||||
{{"X", {"x"}}},
|
||||
{{"Out", {"y"}}},
|
||||
{{"use_onednn", {true}}});
|
||||
|
||||
op_ref->Run(scope, place);
|
||||
pool.Get(place)->Wait();
|
||||
|
||||
// Get reference (out of place) result
|
||||
auto &ref_tensor = scope.FindVar("y")->Get<phi::DenseTensor>();
|
||||
|
||||
// In-place (to be tested) computation
|
||||
auto op = num_inputs > 1
|
||||
? framework::OpRegistry::CreateOp(op_type,
|
||||
{{"X", {"x"}}, {"Y", {"x1"}}},
|
||||
{{"Out", {"x"}}},
|
||||
{{"use_onednn", {true}}})
|
||||
: framework::OpRegistry::CreateOp(op_type,
|
||||
{{"X", {"x"}}},
|
||||
{{"Out", {"x"}}},
|
||||
{{"use_onednn", {true}}});
|
||||
|
||||
op->Run(scope, place);
|
||||
phi::DeviceContextPool::Instance().Get(place)->Wait();
|
||||
|
||||
// Get in-place result
|
||||
auto &out_tensor = scope.FindVar("x")->Get<phi::DenseTensor>();
|
||||
PADDLE_ENFORCE_EQ(
|
||||
&out_tensor,
|
||||
input_names[0].tensor,
|
||||
common::errors::InvalidArgument(
|
||||
"Input and output vars should share tensor for In-place test"));
|
||||
|
||||
// compare results
|
||||
auto *ref_ptr = ref_tensor.data<T>();
|
||||
auto *out_ptr = out_tensor.data<T>();
|
||||
bool is_equal = std::equal(out_ptr, out_ptr + numel, ref_ptr);
|
||||
return is_equal;
|
||||
}
|
||||
|
||||
TEST(test_softmax_inplace, cpu_place) {
|
||||
phi::DDim dims({32, 64});
|
||||
phi::CPUPlace p;
|
||||
ASSERT_TRUE(TestMain<float>(p, "softmax", dims, 1));
|
||||
}
|
||||
|
||||
TEST(test_relu_inplace, cpu_place) {
|
||||
phi::DDim dims({1, 12, 20, 20});
|
||||
phi::CPUPlace p;
|
||||
ASSERT_TRUE(TestMain<float>(p, "relu", dims, 1));
|
||||
}
|
||||
|
||||
} // namespace operators
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,217 @@
|
||||
// Copyright (c) 2020 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 <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/fluid/framework/lod_tensor.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/scope.h"
|
||||
#include "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace operators {
|
||||
|
||||
struct InputVars {
|
||||
std::string name;
|
||||
phi::DenseTensor *tensor;
|
||||
};
|
||||
|
||||
void Test_Pool2d_Transpose_NHWC(const std::string &transpose_type) {
|
||||
phi::DDim dims({1, 4, 8, 512}); // NHWC shape
|
||||
phi::DDim expected_dims({1, 7, 512, 3}); // NHWC expected shape
|
||||
phi::CPUPlace p;
|
||||
framework::Scope scope;
|
||||
|
||||
InputVars input_name = {"x", scope.Var("x")->GetMutable<phi::DenseTensor>()};
|
||||
// Initialize input data
|
||||
std::uniform_real_distribution<float> dist(static_cast<float>(10.0),
|
||||
static_cast<float>(20.0));
|
||||
std::mt19937 engine;
|
||||
size_t numel = static_cast<size_t>(common::product(dims));
|
||||
input_name.tensor->Resize(dims);
|
||||
auto data_ptr = input_name.tensor->mutable_data<float>(p);
|
||||
for (size_t i = 0; i < numel; ++i) {
|
||||
data_ptr[i] = dist(engine);
|
||||
}
|
||||
|
||||
scope.Var("y")->GetMutable<phi::DenseTensor>();
|
||||
auto *z = scope.Var("z")->GetMutable<phi::DenseTensor>();
|
||||
|
||||
auto &pool = phi::DeviceContextPool::Instance();
|
||||
|
||||
// Make pool2d followed by transpose
|
||||
|
||||
auto ksize = std::vector<int>(2, 2);
|
||||
auto op_pool =
|
||||
framework::OpRegistry::CreateOp("pool2d",
|
||||
{{"X", {"x"}}},
|
||||
{{"Out", {"y"}}},
|
||||
{{"pooling_type", {std::string("max")}},
|
||||
{"ksize", {ksize}},
|
||||
{"data_format", {std::string("NHWC")}},
|
||||
{"use_onednn", {true}}});
|
||||
|
||||
auto axis = std::vector<int>(4, 0);
|
||||
axis[1] = 2;
|
||||
axis[2] = 3;
|
||||
axis[3] = 1;
|
||||
auto op_transpose = framework::OpRegistry::CreateOp(
|
||||
transpose_type,
|
||||
{{"X", {"y"}}},
|
||||
{{"Out", {"z"}}},
|
||||
{{"axis", {axis}}, {"use_onednn", {true}}});
|
||||
|
||||
op_pool->Run(scope, p);
|
||||
op_transpose->Run(scope, p);
|
||||
pool.Get(p)->Wait();
|
||||
|
||||
// Verify shape of output
|
||||
PADDLE_ENFORCE_EQ(z->dims(),
|
||||
expected_dims,
|
||||
common::errors::InvalidArgument(
|
||||
"Computed shape does not match expected shape"));
|
||||
}
|
||||
|
||||
TEST(test_pool2d_transpose_nhwc, cpu_place) {
|
||||
Test_Pool2d_Transpose_NHWC({"transpose"});
|
||||
Test_Pool2d_Transpose_NHWC({"fused_transpose"});
|
||||
}
|
||||
|
||||
TEST(test_pool2d_relu_relu_nhwc, cpu_place) {
|
||||
phi::DDim dims({1, 4, 8, 512}); // NHWC shape
|
||||
phi::DDim expected_dims({1, 512, 3, 7}); // NCHW expected shape
|
||||
phi::CPUPlace p;
|
||||
framework::Scope scope;
|
||||
|
||||
InputVars input_name = {"x", scope.Var("x")->GetMutable<phi::DenseTensor>()};
|
||||
// Initialize input data
|
||||
std::uniform_real_distribution<float> dist(static_cast<float>(10.0),
|
||||
static_cast<float>(20.0));
|
||||
std::mt19937 engine;
|
||||
size_t numel = static_cast<size_t>(common::product(dims));
|
||||
input_name.tensor->Resize(dims);
|
||||
auto data_ptr = input_name.tensor->mutable_data<float>(p);
|
||||
for (size_t i = 0; i < numel; ++i) {
|
||||
data_ptr[i] = dist(engine);
|
||||
}
|
||||
|
||||
scope.Var("y")->GetMutable<phi::DenseTensor>();
|
||||
scope.Var("u")->GetMutable<phi::DenseTensor>();
|
||||
auto *z = scope.Var("z")->GetMutable<phi::DenseTensor>();
|
||||
|
||||
auto &pool = phi::DeviceContextPool::Instance();
|
||||
|
||||
// Make pool2d(oneDNN) followed by relu(CPU paddle) followed by
|
||||
// relu(oneDNN). Second relu should make a shape rotation to NCHW
|
||||
|
||||
auto ksize = std::vector<int>(2, 2);
|
||||
auto op_pool =
|
||||
framework::OpRegistry::CreateOp("pool2d",
|
||||
{{"X", {"x"}}},
|
||||
{{"Out", {"y"}}},
|
||||
{{"pooling_type", {std::string("max")}},
|
||||
{"ksize", {ksize}},
|
||||
{"data_format", {std::string("NHWC")}},
|
||||
{"use_onednn", {true}}});
|
||||
|
||||
auto axis = std::vector<int>(4, 0);
|
||||
axis[1] = 2;
|
||||
axis[2] = 3;
|
||||
axis[3] = 1;
|
||||
auto op_relu1 = framework::OpRegistry::CreateOp(
|
||||
"relu",
|
||||
{{"X", {"y"}}},
|
||||
{{"Out", {"u"}}},
|
||||
{{"axis", {axis}}, {"use_onednn", {false}}});
|
||||
|
||||
auto op_relu2 = framework::OpRegistry::CreateOp(
|
||||
"relu", {{"X", {"u"}}}, {{"Out", {"z"}}}, {{"use_onednn", {true}}});
|
||||
|
||||
op_pool->Run(scope, p);
|
||||
op_relu1->Run(scope, p);
|
||||
op_relu2->Run(scope, p);
|
||||
|
||||
pool.Get(p)->Wait();
|
||||
|
||||
// Verify shape of output
|
||||
PADDLE_ENFORCE_EQ(z->dims(),
|
||||
expected_dims,
|
||||
common::errors::InvalidArgument(
|
||||
"Computed shape does not match expected shape"));
|
||||
}
|
||||
|
||||
TEST(test_pool2d_shape_nhwc, cpu_place) {
|
||||
phi::DDim dims({1, 4, 8, 512}); // NHWC shape
|
||||
std::vector<int32_t> expected_dims{1, 3, 7, 512}; // NHWC expected shape
|
||||
phi::CPUPlace p;
|
||||
framework::Scope scope;
|
||||
|
||||
InputVars input_name = {"x", scope.Var("x")->GetMutable<phi::DenseTensor>()};
|
||||
// Initialize input data
|
||||
std::uniform_real_distribution<float> dist(static_cast<float>(10.0),
|
||||
static_cast<float>(20.0));
|
||||
std::mt19937 engine;
|
||||
size_t numel = static_cast<size_t>(common::product(dims));
|
||||
input_name.tensor->Resize(dims);
|
||||
auto data_ptr = input_name.tensor->mutable_data<float>(p);
|
||||
for (size_t i = 0; i < numel; ++i) {
|
||||
data_ptr[i] = dist(engine);
|
||||
}
|
||||
|
||||
scope.Var("y")->GetMutable<phi::DenseTensor>();
|
||||
auto *z = scope.Var("z")->GetMutable<phi::DenseTensor>();
|
||||
|
||||
auto &pool = phi::DeviceContextPool::Instance();
|
||||
|
||||
// Make pool2d followed by shape. shape for NHWC should return
|
||||
// as output tensor not-rotated shape of Pool (
|
||||
|
||||
auto ksize = std::vector<int>(2, 2);
|
||||
auto op_pool =
|
||||
framework::OpRegistry::CreateOp("pool2d",
|
||||
{{"X", {"x"}}},
|
||||
{{"Out", {"y"}}},
|
||||
{{"pooling_type", {std::string("max")}},
|
||||
{"ksize", {ksize}},
|
||||
{"data_format", {std::string("NHWC")}},
|
||||
{"use_onednn", {true}}});
|
||||
|
||||
auto op_shape = framework::OpRegistry::CreateOp(
|
||||
"shape", {{"Input", {"y"}}}, {{"Out", {"z"}}}, {{"use_onednn", {true}}});
|
||||
|
||||
op_pool->Run(scope, p);
|
||||
op_shape->Run(scope, p);
|
||||
|
||||
pool.Get(p)->Wait();
|
||||
|
||||
// repack tensor data into vector for easy comparison
|
||||
auto *zdata = z->data<int32_t>();
|
||||
std::vector<int32_t> vzdata(zdata, zdata + z->numel());
|
||||
|
||||
// Verify shape of output
|
||||
PADDLE_ENFORCE_EQ(vzdata,
|
||||
expected_dims,
|
||||
common::errors::InvalidArgument(
|
||||
"Computed shape does not match expected shape"));
|
||||
}
|
||||
|
||||
} // namespace operators
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,85 @@
|
||||
/* Copyright (c) 2023 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 <gtest/gtest.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "paddle/fluid/framework/lod_tensor.h"
|
||||
#include "paddle/fluid/framework/naive_executor.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/scope.h"
|
||||
#include "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace inference {
|
||||
namespace tensorrt {
|
||||
|
||||
template <typename DataType>
|
||||
void AddVarToScope(const std::string var_name,
|
||||
paddle::framework::Scope* scope,
|
||||
const phi::DDim& dims) {
|
||||
std::random_device seed;
|
||||
std::default_random_engine engine(seed());
|
||||
std::uniform_real_distribution<float> dist(0, 100);
|
||||
|
||||
phi::DenseTensor tmp_tensor;
|
||||
auto* tmp_data = tmp_tensor.mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
auto* tensor = scope->Var(var_name)->GetMutable<phi::DenseTensor>();
|
||||
tensor->mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
for (auto i = 0; i < tensor->numel(); ++i) {
|
||||
tmp_data[i] = static_cast<DataType>(dist(engine));
|
||||
}
|
||||
paddle::framework::TensorCopySync(tmp_tensor, phi::CPUPlace(), tensor);
|
||||
}
|
||||
void test_pool2d(bool adaptive, bool ceil_mode, std::string pool_type = "max") {
|
||||
framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
|
||||
// Prepare Op description
|
||||
framework::OpDesc desc;
|
||||
desc.SetType("pool2d");
|
||||
desc.SetInput("X", {"pool2d-X"});
|
||||
desc.SetOutput("Out", {"pool2d-Out"});
|
||||
AddVarToScope<float>("pool2d-X", &scope, {1, 3, 9, 12});
|
||||
AddVarToScope<float>("pool2d-Out", &scope, {1, 3, 2, 2});
|
||||
std::vector<int> ksize({2, 2});
|
||||
std::vector<int> strides({1, 1});
|
||||
std::vector<int> paddings({0, 0});
|
||||
std::string pooling_t = pool_type;
|
||||
|
||||
desc.SetAttr("pooling_type", pooling_t);
|
||||
desc.SetAttr("ksize", ksize);
|
||||
desc.SetAttr("strides", strides);
|
||||
desc.SetAttr("paddings", paddings);
|
||||
desc.SetAttr("adaptive", adaptive);
|
||||
desc.SetAttr("ceil_mode", ceil_mode);
|
||||
desc.SetAttr("use_onednn", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(desc);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
|
||||
TEST(Pool2dOpConverter, normal) { test_pool2d(false, false); }
|
||||
TEST(Pool2dOpConverter, adaptive) { test_pool2d(true, false); }
|
||||
|
||||
TEST(Pool2dOpConverter, max_ceil_test) { test_pool2d(false, true); }
|
||||
TEST(Pool2dOpConverter, avg_ceil_test) { test_pool2d(true, true, "avg"); }
|
||||
|
||||
} // namespace tensorrt
|
||||
} // namespace inference
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,101 @@
|
||||
/* Copyright (c) 2023 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 <gtest/gtest.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "paddle/fluid/framework/lod_tensor.h"
|
||||
#include "paddle/fluid/framework/naive_executor.h"
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/framework/operator.h"
|
||||
#include "paddle/fluid/framework/scope.h"
|
||||
#include "paddle/phi/common/place.h"
|
||||
#include "paddle/phi/core/enforce.h"
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace inference {
|
||||
namespace tensorrt {
|
||||
|
||||
template <typename DataType>
|
||||
void AddVarToScope(const std::string var_name,
|
||||
paddle::framework::Scope* scope,
|
||||
const phi::DDim& dims) {
|
||||
std::random_device seed;
|
||||
std::default_random_engine engine(seed());
|
||||
std::uniform_real_distribution<float> dist(0, 100);
|
||||
|
||||
phi::DenseTensor tmp_tensor;
|
||||
auto* tmp_data = tmp_tensor.mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
auto* tensor = scope->Var(var_name)->GetMutable<phi::DenseTensor>();
|
||||
tensor->mutable_data<DataType>(dims, phi::CPUPlace());
|
||||
for (auto i = 0; i < tensor->numel(); ++i) {
|
||||
tmp_data[i] = static_cast<DataType>(dist(engine));
|
||||
}
|
||||
paddle::framework::TensorCopySync(tmp_tensor, phi::CPUPlace(), tensor);
|
||||
}
|
||||
void test_squeeze() {
|
||||
framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
// Prepare Op description
|
||||
framework::OpDesc desc;
|
||||
// We assume it is NHWC, so that can use this transformation
|
||||
phi::OneDNNContext::tls().set_cur_paddle_data_layout(DataLayout::NHWC);
|
||||
desc.SetType("squeeze2");
|
||||
desc.SetInput("X", {"squeeze-X"});
|
||||
desc.SetOutput("Out", {"squeeze-Out"});
|
||||
// DataLayout::NHWC will make it become {2, 3, 2, 1}
|
||||
AddVarToScope<float>("squeeze-X", &scope, {2, 2, 1, 3});
|
||||
AddVarToScope<float>("squeeze-Out", &scope, {2, 3, 2});
|
||||
// transform will make it become -1
|
||||
std::vector<int> axes({-2});
|
||||
|
||||
desc.SetAttr("axes", axes);
|
||||
desc.SetAttr("use_onednn", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(desc);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
|
||||
void test_squeeze2() {
|
||||
framework::Scope scope;
|
||||
phi::CPUPlace cpu_place;
|
||||
// Prepare Op description
|
||||
framework::OpDesc desc;
|
||||
// We assume it is HNWC, so that can use this transformation
|
||||
phi::OneDNNContext::tls().set_cur_paddle_data_layout(DataLayout::NHWC);
|
||||
desc.SetType("squeeze2");
|
||||
desc.SetInput("X", {"squeeze-X"});
|
||||
desc.SetOutput("Out", {"squeeze-Out"});
|
||||
// DataLayout::NHWC will make it become {2, 1, 3, 2}
|
||||
AddVarToScope<float>("squeeze-X", &scope, {2, 3, 2, 1});
|
||||
AddVarToScope<float>("squeeze-Out", &scope, {2, 3, 2});
|
||||
// transform will make it become -3(1)
|
||||
std::vector<int> axes({-1});
|
||||
|
||||
desc.SetAttr("axes", axes);
|
||||
desc.SetAttr("use_onednn", true);
|
||||
|
||||
auto op = paddle::framework::OpRegistry::CreateOp(desc);
|
||||
|
||||
op->Run(scope, cpu_place);
|
||||
}
|
||||
|
||||
TEST(SqueezeOpConverter, normal) { test_squeeze(); }
|
||||
TEST(SqueezeOpConverter_2, normal) { test_squeeze2(); }
|
||||
|
||||
} // namespace tensorrt
|
||||
} // namespace inference
|
||||
} // namespace paddle
|
||||
Reference in New Issue
Block a user