chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:42 +08:00
commit e25996e7db
15472 changed files with 3536181 additions and 0 deletions
+37
View File
@@ -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