chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
if(NOT (NOT WITH_PYTHON AND ON_INFER))
|
||||
if(WITH_CINN)
|
||||
set(eager_deps ${eager_deps} python)
|
||||
endif()
|
||||
cc_library(performance_benchmark_utils SRCS benchmark_utils.cc)
|
||||
add_dependencies(
|
||||
performance_benchmark_utils
|
||||
${eager_deps}
|
||||
${fluid_deps}
|
||||
${generated_deps}
|
||||
eager_scale
|
||||
scale_node
|
||||
generated_op
|
||||
generated_static_op
|
||||
dygraph_function
|
||||
eager_prim_api)
|
||||
|
||||
paddle_test(test_egr_performance_benchmark_eager_cpu SRCS
|
||||
benchmark_eager_cpu.cc DEPS performance_benchmark_utils)
|
||||
paddle_test(test_egr_performance_benchmark_fluid_cpu SRCS
|
||||
benchmark_fluid_cpu.cc DEPS performance_benchmark_utils)
|
||||
|
||||
if(WITH_GPU)
|
||||
paddle_test(test_egr_performance_benchmark_eager_cuda SRCS
|
||||
benchmark_eager_cuda.cc DEPS performance_benchmark_utils)
|
||||
paddle_test(test_egr_performance_benchmark_fluid_cuda SRCS
|
||||
benchmark_fluid_cuda.cc DEPS performance_benchmark_utils)
|
||||
endif()
|
||||
|
||||
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(performance_benchmark_utils)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,242 @@
|
||||
// Copyright (c) 2021 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.
|
||||
|
||||
// Eager Dygraph
|
||||
|
||||
#include <paddle/fluid/framework/op_registry.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/common/flags.h"
|
||||
#include "paddle/fluid/eager/api/all.h"
|
||||
#include "paddle/fluid/eager/autograd_meta.h"
|
||||
#include "paddle/fluid/eager/backward.h"
|
||||
#include "paddle/fluid/imperative/tracer.h"
|
||||
#include "test/cpp/eager/performance_tests/benchmark_utils.h"
|
||||
#include "test/cpp/eager/test_utils.h"
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
#include "gperftools/profiler.h"
|
||||
#endif
|
||||
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
using namespace egr; // NOLINT
|
||||
using namespace egr_utils_api; // NOLINT
|
||||
|
||||
TEST(Benchmark, EagerScaleCPU) {
|
||||
// Prepare Device Contexts
|
||||
eager_test::InitEnv(phi::CPUPlace());
|
||||
|
||||
for (const std::string mode : {"Accuracy", "Performance"}) {
|
||||
phi::DDim ddim = common::make_ddim({2, 4, 4, 4});
|
||||
paddle::Tensor tensor =
|
||||
eager_test::CreateTensorWithValue(ddim,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
5.0,
|
||||
true);
|
||||
RetainGradForTensor(tensor);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_scale(tensor, true /* accuracy_check*/);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_scale_cpu.out");
|
||||
#endif
|
||||
benchmark_eager_scale(tensor);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, EagerMatmulCPU) {
|
||||
// Prepare Device Contexts
|
||||
eager_test::InitEnv(phi::CPUPlace());
|
||||
|
||||
for (const std::string mode : {"Accuracy", "Performance"}) {
|
||||
phi::DDim ddimX = common::make_ddim({2, 2});
|
||||
paddle::Tensor X = eager_test::CreateTensorWithValue(ddimX,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
1.0,
|
||||
true);
|
||||
RetainGradForTensor(X);
|
||||
|
||||
phi::DDim ddimY = common::make_ddim({2, 2});
|
||||
paddle::Tensor Y = eager_test::CreateTensorWithValue(ddimY,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
2.0,
|
||||
true);
|
||||
RetainGradForTensor(Y);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_matmul(X, Y, true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_matmul_cpu.out");
|
||||
#endif
|
||||
benchmark_eager_matmul(X, Y);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, EagerIntermediateMatmulCPU) {
|
||||
// Prepare Device Contexts
|
||||
eager_test::InitEnv(phi::CPUPlace());
|
||||
|
||||
auto tracer = std::make_shared<paddle::imperative::Tracer>();
|
||||
paddle::imperative::SetCurrentTracer(tracer);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "Performance"}) {
|
||||
phi::DDim ddimX = common::make_ddim({2, 2});
|
||||
paddle::Tensor X = eager_test::CreateTensorWithValue(ddimX,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
1.0,
|
||||
true);
|
||||
RetainGradForTensor(X);
|
||||
|
||||
phi::DDim ddimY = common::make_ddim({2, 2});
|
||||
paddle::Tensor Y = eager_test::CreateTensorWithValue(ddimY,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
2.0,
|
||||
true);
|
||||
RetainGradForTensor(Y);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_intermediate_matmul(X, Y, true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_intermediate_matmul_cpu.out");
|
||||
#endif
|
||||
benchmark_eager_intermediate_matmul(X, Y);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, EagerIntermediateMLPCPU) {
|
||||
// Prepare Device Contexts
|
||||
eager_test::InitEnv(phi::CPUPlace());
|
||||
|
||||
auto tracer = std::make_shared<paddle::imperative::Tracer>();
|
||||
paddle::imperative::SetCurrentTracer(tracer);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "Performance"}) {
|
||||
phi::DDim ddimX = common::make_ddim({MLP_M, MLP_N});
|
||||
paddle::Tensor X = eager_test::CreateTensorWithValue(ddimX,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
MLP_X_VAL,
|
||||
true);
|
||||
RetainGradForTensor(X);
|
||||
|
||||
std::vector<paddle::Tensor> Ws;
|
||||
std::vector<paddle::Tensor> Bs;
|
||||
for (size_t i = 0; i < MLP_NUM_LINEAR; i++) {
|
||||
phi::DDim ddimW = common::make_ddim({MLP_N, MLP_K});
|
||||
paddle::Tensor W =
|
||||
eager_test::CreateTensorWithValue(ddimW,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
MLP_W_VAL,
|
||||
true);
|
||||
RetainGradForTensor(W);
|
||||
|
||||
phi::DDim ddimB = common::make_ddim({MLP_K});
|
||||
paddle::Tensor B =
|
||||
eager_test::CreateTensorWithValue(ddimB,
|
||||
phi::CPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
MLP_B_VAL,
|
||||
true);
|
||||
RetainGradForTensor(B);
|
||||
|
||||
Ws.emplace_back(std::move(W));
|
||||
Bs.emplace_back(std::move(B));
|
||||
}
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_intermediate_mlp(X, Ws, Bs, true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_intermediate_mlp_cpu.out");
|
||||
#endif
|
||||
benchmark_eager_intermediate_mlp(X, Ws, Bs);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
// Copyright (c) 2021 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.
|
||||
|
||||
// Eager Dygraph
|
||||
#include <paddle/fluid/framework/op_registry.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/common/flags.h"
|
||||
#include "paddle/fluid/eager/api/all.h"
|
||||
#include "paddle/fluid/eager/autograd_meta.h"
|
||||
#include "paddle/fluid/eager/backward.h"
|
||||
#include "paddle/fluid/imperative/tracer.h"
|
||||
#include "test/cpp/eager/performance_tests/benchmark_utils.h"
|
||||
#include "test/cpp/eager/test_utils.h"
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
#include "gperftools/profiler.h"
|
||||
#endif
|
||||
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
using namespace egr; // NOLINT
|
||||
using namespace egr_utils_api; // NOLINT
|
||||
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
|
||||
|
||||
TEST(Benchmark, EagerScaleCUDA) {
|
||||
eager_test::InitEnv(phi::GPUPlace());
|
||||
|
||||
for (const std::string mode : {"Accuracy", "WarmUp", "Performance"}) {
|
||||
phi::DDim ddim = common::make_ddim({2, 4, 4, 4});
|
||||
paddle::Tensor tensor =
|
||||
eager_test::CreateTensorWithValue(ddim,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
5.0 /*value*/,
|
||||
true /*is_leaf*/);
|
||||
RetainGradForTensor(tensor);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_scale(tensor, true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "WarmUp") {
|
||||
benchmark_eager_scale(tensor);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_scale_cuda.out");
|
||||
#endif
|
||||
benchmark_eager_scale(tensor);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, EagerMatmulCUDA) {
|
||||
phi::GPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "WarmUp", "Performance"}) {
|
||||
phi::DDim ddimX = common::make_ddim({2, 2});
|
||||
paddle::Tensor X = eager_test::CreateTensorWithValue(ddimX,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
1.0,
|
||||
true);
|
||||
RetainGradForTensor(X);
|
||||
|
||||
phi::DDim ddimY = common::make_ddim({2, 2});
|
||||
paddle::Tensor Y = eager_test::CreateTensorWithValue(ddimY,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
2.0,
|
||||
true);
|
||||
RetainGradForTensor(Y);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_matmul(X, Y, true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "WarmUp") {
|
||||
benchmark_eager_matmul(X, Y);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_matmul_cuda.out");
|
||||
#endif
|
||||
benchmark_eager_matmul(X, Y);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, EagerIntermediateMatmulCUDA) {
|
||||
phi::GPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
auto tracer = std::make_shared<paddle::imperative::Tracer>();
|
||||
tracer->SetExpectedPlace(place);
|
||||
paddle::imperative::SetCurrentTracer(tracer);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "WarmUp", "Performance"}) {
|
||||
phi::DDim ddimX = common::make_ddim({2, 2});
|
||||
paddle::Tensor X = eager_test::CreateTensorWithValue(ddimX,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
1.0,
|
||||
true);
|
||||
RetainGradForTensor(X);
|
||||
|
||||
phi::DDim ddimY = common::make_ddim({2, 2});
|
||||
paddle::Tensor Y = eager_test::CreateTensorWithValue(ddimY,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
2.0,
|
||||
true);
|
||||
RetainGradForTensor(Y);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_intermediate_matmul(X, Y, true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "WarmUp") {
|
||||
benchmark_eager_intermediate_matmul(X, Y);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_intermediate_matmul_cuda.out");
|
||||
#endif
|
||||
benchmark_eager_intermediate_matmul(X, Y);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, EagerIntermediateMLPCUDA) {
|
||||
phi::GPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
auto tracer = std::make_shared<paddle::imperative::Tracer>();
|
||||
tracer->SetExpectedPlace(place);
|
||||
paddle::imperative::SetCurrentTracer(tracer);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "WarmUp", "Performance"}) {
|
||||
phi::DDim ddimX = common::make_ddim({MLP_M, MLP_N});
|
||||
paddle::Tensor X = eager_test::CreateTensorWithValue(ddimX,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
MLP_X_VAL,
|
||||
true);
|
||||
RetainGradForTensor(X);
|
||||
|
||||
std::vector<paddle::Tensor> Ws;
|
||||
std::vector<paddle::Tensor> Bs;
|
||||
for (size_t i = 0; i < MLP_NUM_LINEAR; i++) {
|
||||
phi::DDim ddimW = common::make_ddim({MLP_N, MLP_K});
|
||||
paddle::Tensor W =
|
||||
eager_test::CreateTensorWithValue(ddimW,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
MLP_W_VAL,
|
||||
true);
|
||||
RetainGradForTensor(W);
|
||||
|
||||
phi::DDim ddimB = common::make_ddim({MLP_K});
|
||||
paddle::Tensor B =
|
||||
eager_test::CreateTensorWithValue(ddimB,
|
||||
phi::GPUPlace(),
|
||||
phi::DataType::FLOAT32,
|
||||
phi::DataLayout::NCHW,
|
||||
MLP_B_VAL,
|
||||
true);
|
||||
RetainGradForTensor(B);
|
||||
|
||||
Ws.emplace_back(std::move(W));
|
||||
Bs.emplace_back(std::move(B));
|
||||
}
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_eager_intermediate_mlp(X, Ws, Bs, true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "WarmUp") {
|
||||
benchmark_eager_intermediate_mlp(X, Ws, Bs);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("eager_intermediate_mlp_cuda.out");
|
||||
#endif
|
||||
benchmark_eager_intermediate_mlp(X, Ws, Bs);
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PADDLE_WITH_CUDA || PADDLE_WITH_HIP
|
||||
@@ -0,0 +1,230 @@
|
||||
// Copyright (c) 2021 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 <paddle/fluid/framework/op_registry.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/fluid/imperative/basic_engine.h"
|
||||
#include "paddle/fluid/imperative/tracer.h"
|
||||
#include "paddle/phi/core/memory/memcpy.h"
|
||||
#include "test/cpp/eager/performance_tests/benchmark_utils.h"
|
||||
#include "test/cpp/eager/test_utils.h"
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
#include "gperftools/profiler.h"
|
||||
#endif
|
||||
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace imperative {
|
||||
|
||||
TEST(Benchmark, FluidScaleCPU) {
|
||||
// Prepare Device Contexts
|
||||
phi::CPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "Performance"}) {
|
||||
std::shared_ptr<imperative::VarBase> X(new imperative::VarBase(true, "X"));
|
||||
X->SetOverriddenStopGradient(false);
|
||||
|
||||
std::vector<float> src_data(128, 5.0);
|
||||
std::vector<int64_t> dims = {2, 4, 4, 4};
|
||||
|
||||
auto* x_tensor = X->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
x_tensor->Resize(common::make_ddim(dims));
|
||||
auto* mutable_x = x_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_x,
|
||||
place,
|
||||
src_data.data(),
|
||||
sizeof(float) * src_data.size());
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_fluid_scale(X, phi::Place(place), true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("fluid_scale_cpu.out");
|
||||
#endif
|
||||
benchmark_fluid_scale(X, phi::Place(place));
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, FluidMatmulCPU) {
|
||||
// Prepare Device Contexts
|
||||
phi::CPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "Performance"}) {
|
||||
std::shared_ptr<imperative::VarBase> X(new imperative::VarBase(true, "X"));
|
||||
X->SetOverriddenStopGradient(false);
|
||||
std::shared_ptr<imperative::VarBase> Y(new imperative::VarBase(true, "Y"));
|
||||
Y->SetOverriddenStopGradient(false);
|
||||
|
||||
std::vector<float> x_src_data(4, 1.0);
|
||||
std::vector<float> y_src_data(4, 2.0);
|
||||
std::vector<int64_t> dims = {2, 2};
|
||||
|
||||
auto* x_tensor = X->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
x_tensor->Resize(common::make_ddim(dims));
|
||||
auto* mutable_x = x_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_x,
|
||||
place,
|
||||
x_src_data.data(),
|
||||
sizeof(float) * x_src_data.size());
|
||||
|
||||
auto* y_tensor = Y->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
y_tensor->Resize(common::make_ddim(dims));
|
||||
auto* mutable_y = y_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_y,
|
||||
place,
|
||||
y_src_data.data(),
|
||||
sizeof(float) * y_src_data.size());
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_fluid_matmul(
|
||||
X, Y, phi::Place(place), true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("fluid_matmul_cpu.out");
|
||||
#endif
|
||||
benchmark_fluid_matmul(X, Y, phi::Place(place));
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, FluidMLPCPU) {
|
||||
// Prepare Device Contexts
|
||||
phi::CPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "Performance"}) {
|
||||
std::vector<float> x_src_data(MLP_M * MLP_N, MLP_X_VAL);
|
||||
std::vector<float> w_src_data(MLP_N * MLP_K, MLP_W_VAL);
|
||||
std::vector<float> b_src_data(MLP_K, MLP_B_VAL);
|
||||
|
||||
std::vector<int64_t> x_dims = {MLP_M, MLP_N};
|
||||
std::vector<int64_t> w_dims = {MLP_N, MLP_K};
|
||||
std::vector<int64_t> b_dims = {MLP_K};
|
||||
|
||||
std::shared_ptr<imperative::VarBase> X(new imperative::VarBase(true, "X"));
|
||||
X->SetOverriddenStopGradient(false);
|
||||
|
||||
auto* x_tensor = X->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
x_tensor->Resize(common::make_ddim(x_dims));
|
||||
auto* mutable_x = x_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_x,
|
||||
place,
|
||||
x_src_data.data(),
|
||||
sizeof(float) * x_src_data.size());
|
||||
|
||||
std::vector<std::shared_ptr<imperative::VarBase>> Ws;
|
||||
std::vector<std::shared_ptr<imperative::VarBase>> Bs;
|
||||
for (size_t i = 0; i < MLP_NUM_LINEAR; i++) {
|
||||
std::shared_ptr<imperative::VarBase> W(
|
||||
new imperative::VarBase(true, "W"));
|
||||
W->SetOverriddenStopGradient(false);
|
||||
std::shared_ptr<imperative::VarBase> B(
|
||||
new imperative::VarBase(true, "B"));
|
||||
B->SetOverriddenStopGradient(false);
|
||||
|
||||
auto* w_tensor = W->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
w_tensor->Resize(common::make_ddim(w_dims));
|
||||
auto* mutable_w = w_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_w,
|
||||
place,
|
||||
w_src_data.data(),
|
||||
sizeof(float) * w_src_data.size());
|
||||
|
||||
auto* b_tensor = B->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
b_tensor->Resize(common::make_ddim(b_dims));
|
||||
auto* mutable_b = b_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_b,
|
||||
place,
|
||||
b_src_data.data(),
|
||||
sizeof(float) * b_src_data.size());
|
||||
|
||||
Ws.emplace_back(std::move(W));
|
||||
Bs.emplace_back(std::move(B));
|
||||
}
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_fluid_mlp(
|
||||
X, Ws, Bs, phi::Place(place), true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("fluid_mlp_cpu.out");
|
||||
#endif
|
||||
benchmark_fluid_mlp(X, Ws, Bs, phi::Place(place));
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace imperative
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,258 @@
|
||||
// Copyright (c) 2021 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 <paddle/fluid/framework/op_registry.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "paddle/fluid/imperative/basic_engine.h"
|
||||
#include "paddle/fluid/imperative/tracer.h"
|
||||
#include "paddle/phi/core/memory/memcpy.h"
|
||||
#include "test/cpp/eager/performance_tests/benchmark_utils.h"
|
||||
#include "test/cpp/eager/test_utils.h"
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
#include "gperftools/profiler.h"
|
||||
#endif
|
||||
|
||||
#include "paddle/phi/core/kernel_registry.h"
|
||||
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
|
||||
namespace paddle {
|
||||
namespace imperative {
|
||||
|
||||
TEST(Benchmark, FluidScaleCUDA) {
|
||||
// Prepare Device Contexts
|
||||
phi::GPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "WarmUp", "Performance"}) {
|
||||
std::shared_ptr<imperative::VarBase> X(new imperative::VarBase(true, "X"));
|
||||
X->SetOverriddenStopGradient(false);
|
||||
|
||||
std::vector<float> src_data(128, 5.0);
|
||||
std::vector<int64_t> dims = {2, 4, 4, 4};
|
||||
|
||||
auto* x_tensor = X->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
x_tensor->Resize(common::make_ddim(dims));
|
||||
auto* mutable_x = x_tensor->mutable_data<float>(place);
|
||||
|
||||
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
|
||||
auto* dev_ctx = dynamic_cast<phi::GPUContext*>(pool.Get(place));
|
||||
auto stream = dev_ctx->stream();
|
||||
paddle::memory::Copy(place,
|
||||
mutable_x,
|
||||
phi::CPUPlace(),
|
||||
src_data.data(),
|
||||
sizeof(float) * src_data.size(),
|
||||
stream);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_fluid_scale(X, phi::Place(place), true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "WarmUp") {
|
||||
benchmark_fluid_scale(X, phi::Place(place));
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("fluid_scale_cuda.out");
|
||||
#endif
|
||||
benchmark_fluid_scale(X, phi::Place(place));
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, FluidMatmulCUDA) {
|
||||
// Prepare Device Contexts
|
||||
phi::GPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "WarmUp", "Performance"}) {
|
||||
std::shared_ptr<imperative::VarBase> X(new imperative::VarBase(true, "X"));
|
||||
X->SetOverriddenStopGradient(false);
|
||||
std::shared_ptr<imperative::VarBase> Y(new imperative::VarBase(true, "Y"));
|
||||
Y->SetOverriddenStopGradient(false);
|
||||
|
||||
std::vector<float> x_src_data(4, 1.0);
|
||||
std::vector<float> y_src_data(4, 2.0);
|
||||
std::vector<int64_t> dims = {2, 2};
|
||||
|
||||
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
|
||||
auto* dev_ctx = dynamic_cast<phi::GPUContext*>(pool.Get(place));
|
||||
auto stream = dev_ctx->stream();
|
||||
|
||||
auto* x_tensor = X->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
x_tensor->Resize(common::make_ddim(dims));
|
||||
auto* mutable_x = x_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_x,
|
||||
phi::CPUPlace(),
|
||||
x_src_data.data(),
|
||||
sizeof(float) * x_src_data.size(),
|
||||
stream);
|
||||
|
||||
auto* y_tensor = Y->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
y_tensor->Resize(common::make_ddim(dims));
|
||||
auto* mutable_y = y_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_y,
|
||||
phi::CPUPlace(),
|
||||
y_src_data.data(),
|
||||
sizeof(float) * y_src_data.size(),
|
||||
stream);
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_fluid_matmul(
|
||||
X, Y, phi::Place(place), true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "WarmUp") {
|
||||
benchmark_fluid_matmul(X, Y, phi::Place(place));
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("fluid_matmul_cuda.out");
|
||||
#endif
|
||||
benchmark_fluid_matmul(X, Y, phi::Place(place));
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Benchmark, FluidMLPCUDA) {
|
||||
// Prepare Device Contexts
|
||||
phi::GPUPlace place;
|
||||
eager_test::InitEnv(place);
|
||||
|
||||
for (const std::string mode : {"Accuracy", "WarmUp", "Performance"}) {
|
||||
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
|
||||
auto* dev_ctx = dynamic_cast<phi::GPUContext*>(pool.Get(place));
|
||||
auto stream = dev_ctx->stream();
|
||||
|
||||
std::vector<float> x_src_data(MLP_M * MLP_N, MLP_X_VAL);
|
||||
std::vector<float> w_src_data(MLP_N * MLP_K, MLP_W_VAL);
|
||||
std::vector<float> b_src_data(MLP_K, MLP_B_VAL);
|
||||
|
||||
std::vector<int64_t> x_dims = {MLP_M, MLP_N};
|
||||
std::vector<int64_t> w_dims = {MLP_N, MLP_K};
|
||||
std::vector<int64_t> b_dims = {MLP_K};
|
||||
|
||||
std::shared_ptr<imperative::VarBase> X(new imperative::VarBase(true, "X"));
|
||||
X->SetOverriddenStopGradient(false);
|
||||
|
||||
auto* x_tensor = X->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
x_tensor->Resize(common::make_ddim(x_dims));
|
||||
auto* mutable_x = x_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_x,
|
||||
phi::CPUPlace(),
|
||||
x_src_data.data(),
|
||||
sizeof(float) * x_src_data.size(),
|
||||
stream);
|
||||
|
||||
std::vector<std::shared_ptr<imperative::VarBase>> Ws;
|
||||
std::vector<std::shared_ptr<imperative::VarBase>> Bs;
|
||||
for (size_t i = 0; i < MLP_NUM_LINEAR; i++) {
|
||||
std::shared_ptr<imperative::VarBase> W(
|
||||
new imperative::VarBase(true, "W"));
|
||||
W->SetOverriddenStopGradient(false);
|
||||
std::shared_ptr<imperative::VarBase> B(
|
||||
new imperative::VarBase(true, "B"));
|
||||
B->SetOverriddenStopGradient(false);
|
||||
|
||||
auto* w_tensor = W->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
w_tensor->Resize(common::make_ddim(w_dims));
|
||||
auto* mutable_w = w_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_w,
|
||||
phi::CPUPlace(),
|
||||
w_src_data.data(),
|
||||
sizeof(float) * w_src_data.size(),
|
||||
stream);
|
||||
|
||||
auto* b_tensor = B->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
b_tensor->Resize(common::make_ddim(b_dims));
|
||||
auto* mutable_b = b_tensor->mutable_data<float>(place);
|
||||
paddle::memory::Copy(place,
|
||||
mutable_b,
|
||||
phi::CPUPlace(),
|
||||
b_src_data.data(),
|
||||
sizeof(float) * b_src_data.size(),
|
||||
stream);
|
||||
|
||||
Ws.emplace_back(std::move(W));
|
||||
Bs.emplace_back(std::move(B));
|
||||
}
|
||||
|
||||
if (mode == "Accuracy") {
|
||||
benchmark_fluid_mlp(
|
||||
X, Ws, Bs, phi::Place(place), true /* accuracy_check */);
|
||||
|
||||
} else if (mode == "WarmUp") {
|
||||
benchmark_fluid_mlp(X, Ws, Bs, phi::Place(place));
|
||||
|
||||
} else if (mode == "Performance") {
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStart("fluid_mlp_cuda.out");
|
||||
#endif
|
||||
benchmark_fluid_mlp(X, Ws, Bs, phi::Place(place));
|
||||
|
||||
#ifdef WITH_GPERFTOOLS
|
||||
ProfilerStop();
|
||||
#endif
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
double elapsed_time_ms =
|
||||
std::chrono::duration<double, std::milli>(t_end - t_start).count();
|
||||
|
||||
std::cout << "Duration: " << elapsed_time_ms << " ms" << std::endl;
|
||||
|
||||
} else {
|
||||
PADDLE_THROW(common::errors::Fatal("Unknown benchmark mode"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace imperative
|
||||
} // namespace paddle
|
||||
#endif // PADDLE_WITH_CUDA || PADDLE_WITH_HIP
|
||||
@@ -0,0 +1,348 @@
|
||||
// Copyright (c) 2021 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 "test/cpp/eager/performance_tests/benchmark_utils.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Eager
|
||||
#include "paddle/fluid/eager/api/all.h"
|
||||
#include "paddle/fluid/eager/autograd_meta.h"
|
||||
#include "paddle/fluid/eager/backward.h"
|
||||
#include "paddle/fluid/eager/utils.h"
|
||||
#include "test/cpp/eager/test_utils.h"
|
||||
|
||||
// Eager Generated
|
||||
#include "paddle/fluid/eager/api/generated/eager_generated/forwards/dygraph_functions.h"
|
||||
#include "paddle/fluid/eager/api/generated/fluid_generated/dygraph_forward_api.h"
|
||||
|
||||
// Fluid
|
||||
#include "paddle/fluid/framework/op_registry.h"
|
||||
#include "paddle/fluid/imperative/basic_engine.h"
|
||||
#include "paddle/fluid/imperative/tracer.h"
|
||||
#include "paddle/phi/core/memory/memcpy.h"
|
||||
|
||||
static size_t max_num_benchmark_runs = 4000;
|
||||
|
||||
namespace egr {
|
||||
|
||||
/* --------------------- */
|
||||
/* ---- Eager Scale ---- */
|
||||
/* --------------------- */
|
||||
void benchmark_eager_scale(const paddle::Tensor& tensor, bool accuracy_check) {
|
||||
paddle::Tensor input_tensor = tensor;
|
||||
float scale = 2.0;
|
||||
float bias = 3.0;
|
||||
|
||||
size_t max_num_runs = accuracy_check ? 10 : max_num_benchmark_runs;
|
||||
for (size_t i = 0; i < max_num_runs; i++) {
|
||||
input_tensor = egr::scale(input_tensor,
|
||||
scale,
|
||||
bias,
|
||||
true /*bias_after_scale*/,
|
||||
true /*trace_backward*/);
|
||||
}
|
||||
|
||||
std::vector<paddle::Tensor> target_tensors = {input_tensor};
|
||||
Backward(target_tensors, {});
|
||||
|
||||
if (accuracy_check) {
|
||||
// Examine Forward Grad (w.r.t max_num_runs = 10)
|
||||
eager_test::CompareTensorWithValue<float>(input_tensor, 8189.0);
|
||||
// Examine Backward Grad (w.r.t max_num_runs = 10)
|
||||
eager_test::CompareGradTensorWithValue<float>(tensor, 1024.0);
|
||||
}
|
||||
}
|
||||
|
||||
void benchmark_eager_matmul(const paddle::Tensor& X,
|
||||
const paddle::Tensor& Y,
|
||||
bool accuracy_check) {
|
||||
paddle::Tensor input_tensor0 = X;
|
||||
|
||||
size_t max_num_runs = accuracy_check ? 2 : max_num_benchmark_runs;
|
||||
for (size_t i = 0; i < max_num_runs; i++) {
|
||||
input_tensor0 = matmul_ad_func(input_tensor0, Y, false, false);
|
||||
}
|
||||
|
||||
std::vector<paddle::Tensor> target_tensors = {input_tensor0};
|
||||
Backward(target_tensors, {});
|
||||
|
||||
if (accuracy_check) {
|
||||
// Examine Forward Grad (w.r.t max_num_runs = 2)
|
||||
eager_test::CompareTensorWithValue<float>(input_tensor0, 16);
|
||||
// Examine Backward Grad (w.r.t max_num_runs = 2)
|
||||
eager_test::CompareGradTensorWithValue<float>(X, 16);
|
||||
eager_test::CompareGradTensorWithValue<float>(Y, 16);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------- */
|
||||
/* ---- Eager Intermediate Matmul ---- */
|
||||
/* ----------------------------------- */
|
||||
void benchmark_eager_intermediate_matmul(const paddle::Tensor& X,
|
||||
const paddle::Tensor& Y,
|
||||
bool accuracy_check) {
|
||||
paddle::Tensor input_tensor0 = X;
|
||||
|
||||
size_t max_num_runs = accuracy_check ? 2 : max_num_benchmark_runs;
|
||||
for (size_t i = 0; i < max_num_runs; i++) {
|
||||
input_tensor0 = matmul_v2_dygraph_function(
|
||||
input_tensor0, Y, {{"trans_x", false}, {"trans_y", false}});
|
||||
}
|
||||
|
||||
std::vector<paddle::Tensor> target_tensors = {input_tensor0};
|
||||
Backward(target_tensors, {});
|
||||
|
||||
if (accuracy_check) {
|
||||
// Examine Forward Grad (w.r.t max_num_runs = 2)
|
||||
eager_test::CompareTensorWithValue<float>(input_tensor0, 16);
|
||||
// Examine Backward Grad (w.r.t max_num_runs = 2)
|
||||
eager_test::CompareGradTensorWithValue<float>(X, 16);
|
||||
eager_test::CompareGradTensorWithValue<float>(Y, 16);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------- */
|
||||
/* ---- Eager Intermediate MLP ---- */
|
||||
/* -------------------------------- */
|
||||
void benchmark_eager_intermediate_mlp(const paddle::Tensor& X,
|
||||
const std::vector<paddle::Tensor>& Ws,
|
||||
const std::vector<paddle::Tensor>& Bs,
|
||||
bool accuracy_check) {
|
||||
paddle::Tensor input0 = X;
|
||||
|
||||
for (size_t i = 0; i < MLP_NUM_LINEAR; i++) {
|
||||
paddle::Tensor Out = matmul_v2_dygraph_function(
|
||||
input0, Ws[i], {{"trans_x", false}, {"trans_y", false}});
|
||||
|
||||
input0 = elementwise_add_dygraph_function(Out, Bs[i], {});
|
||||
}
|
||||
|
||||
paddle::Tensor Out =
|
||||
reduce_sum_dygraph_function(input0, {{"reduce_all", true}});
|
||||
|
||||
std::vector<paddle::Tensor> target_tensors = {Out};
|
||||
Backward(target_tensors, {});
|
||||
|
||||
if (accuracy_check) {
|
||||
std::unordered_map<std::string, float> result =
|
||||
compute_mlp_expected_results();
|
||||
|
||||
// Examine Forward Grad (w.r.t max_num_runs = 2)
|
||||
eager_test::CompareTensorWithValue<float>(Out, result["Out"]);
|
||||
|
||||
// Examine Backward Grad (w.r.t max_num_runs = 2)
|
||||
eager_test::CompareGradTensorWithValue<float>(X, result["GradX"]);
|
||||
eager_test::CompareGradTensorWithValue<float>(Ws[0], result["GradW"]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace egr
|
||||
|
||||
namespace paddle {
|
||||
namespace imperative {
|
||||
|
||||
static void FluidCheckTensorValue(const std::shared_ptr<imperative::VarBase>& X,
|
||||
const phi::Place& place,
|
||||
float value) {
|
||||
auto* tensor = X->MutableVar()->GetMutable<phi::DenseTensor>();
|
||||
float* t_ptr = tensor->mutable_data<float>(place);
|
||||
std::vector<float> host_data(tensor->numel());
|
||||
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
|
||||
if (place == phi::GPUPlace()) {
|
||||
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
|
||||
auto* dev_ctx = dynamic_cast<phi::GPUContext*>(pool.Get(place));
|
||||
auto stream = dev_ctx->stream();
|
||||
|
||||
paddle::memory::Copy(phi::CPUPlace(),
|
||||
host_data.data(),
|
||||
phi::GPUPlace(),
|
||||
t_ptr,
|
||||
sizeof(float) * tensor->numel(),
|
||||
stream);
|
||||
t_ptr = host_data.data();
|
||||
}
|
||||
#endif
|
||||
|
||||
VLOG(6) << "Tensor Value: " << t_ptr[0] << ", Expected Value: " << value;
|
||||
PADDLE_ENFORCE(
|
||||
t_ptr[0] == value,
|
||||
common::errors::Fatal(
|
||||
"Detected numerical Error, Expected %f but got %f", value, t_ptr[0]));
|
||||
}
|
||||
|
||||
static void FluidCheckGradTensorValue(
|
||||
const std::shared_ptr<imperative::VarBase>& X,
|
||||
const phi::Place& place,
|
||||
float value) {
|
||||
auto* grad_tensor = X->MutableGradVar()->GetMutable<phi::DenseTensor>();
|
||||
float* g_ptr = grad_tensor->mutable_data<float>(place);
|
||||
std::vector<float> g_host_data(grad_tensor->numel());
|
||||
|
||||
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
|
||||
if (place == phi::GPUPlace()) {
|
||||
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
|
||||
auto* dev_ctx = dynamic_cast<phi::GPUContext*>(pool.Get(place));
|
||||
auto stream = dev_ctx->stream();
|
||||
|
||||
paddle::memory::Copy(phi::CPUPlace(),
|
||||
g_host_data.data(),
|
||||
phi::GPUPlace(),
|
||||
g_ptr,
|
||||
sizeof(float) * grad_tensor->numel(),
|
||||
stream);
|
||||
g_ptr = g_host_data.data();
|
||||
}
|
||||
#endif
|
||||
|
||||
VLOG(6) << "Tensor Value: " << g_ptr[0] << ", Expected Value: " << value;
|
||||
PADDLE_ENFORCE(
|
||||
g_ptr[0] == value,
|
||||
common::errors::Fatal(
|
||||
"Detected numerical Error, Expected %f but got %f", value, g_ptr[0]));
|
||||
}
|
||||
|
||||
/* --------------------- */
|
||||
/* ---- Fluid Scale ---- */
|
||||
/* --------------------- */
|
||||
// TODO(jiabin): Change this and remove nolint
|
||||
void benchmark_fluid_scale(const std::shared_ptr<imperative::VarBase>& X,
|
||||
const phi::Place& place,
|
||||
bool accuracy_check) {
|
||||
imperative::Tracer tracer;
|
||||
framework::AttributeMap attrs;
|
||||
|
||||
attrs["use_onednn"] = false;
|
||||
attrs["scale"] = 2;
|
||||
attrs["bias"] = 3;
|
||||
attrs["bias_after_scale"] = true;
|
||||
|
||||
std::shared_ptr<imperative::VarBase> tmp_out = X;
|
||||
|
||||
size_t max_num_runs = accuracy_check ? 10 : max_num_benchmark_runs;
|
||||
for (size_t i = 0; i < max_num_runs; i++) {
|
||||
imperative::NameVarBaseMap ins = {{"X", {tmp_out}}};
|
||||
imperative::NameVarBaseMap outs = {
|
||||
{"Out", {std::make_shared<imperative::VarBase>(true, "Out")}}};
|
||||
|
||||
tracer.TraceOp<VarBase>("scale", ins, outs, attrs, place, true);
|
||||
|
||||
tmp_out = outs["Out"][0];
|
||||
}
|
||||
|
||||
auto* engine = tracer.GetEngine();
|
||||
std::vector<std::shared_ptr<imperative::VarBase>> grad_tensors{nullptr};
|
||||
engine->Init({tmp_out}, grad_tensors, false /*retain_graph*/);
|
||||
engine->Execute();
|
||||
|
||||
if (accuracy_check) {
|
||||
FluidCheckTensorValue(tmp_out, place, 8189.0);
|
||||
FluidCheckGradTensorValue(X, place, 1024.0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
/* ---- Fluid Matmul ---- */
|
||||
/* ---------------------- */
|
||||
void benchmark_fluid_matmul(const std::shared_ptr<imperative::VarBase>& X,
|
||||
const std::shared_ptr<imperative::VarBase>& Y,
|
||||
const phi::Place& place,
|
||||
bool accuracy_check) {
|
||||
imperative::Tracer tracer;
|
||||
|
||||
std::shared_ptr<imperative::VarBase> tmp_out = X;
|
||||
|
||||
size_t max_num_runs = accuracy_check ? 2 : max_num_benchmark_runs;
|
||||
for (size_t i = 0; i < max_num_runs; i++) {
|
||||
framework::AttributeMap attrs;
|
||||
imperative::NameVarBaseMap ins = {{"X", {tmp_out}}, {"Y", {Y}}};
|
||||
imperative::NameVarBaseMap outs = {
|
||||
{"Out", {std::make_shared<imperative::VarBase>(true, "Out")}}};
|
||||
|
||||
tracer.TraceOp<VarBase>("matmul_v2", ins, outs, attrs, place, true);
|
||||
|
||||
tmp_out = outs["Out"][0];
|
||||
}
|
||||
|
||||
auto* engine = tracer.GetEngine();
|
||||
std::vector<std::shared_ptr<imperative::VarBase>> grad_tensors{nullptr};
|
||||
engine->Init({tmp_out}, grad_tensors, false /*retain_graph*/);
|
||||
engine->Execute();
|
||||
|
||||
if (accuracy_check) {
|
||||
FluidCheckTensorValue(tmp_out, place, 16);
|
||||
FluidCheckGradTensorValue(X, place, 16);
|
||||
FluidCheckGradTensorValue(Y, place, 16);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
/* ---- Fluid MLP ---- */
|
||||
/* ------------------- */
|
||||
void benchmark_fluid_mlp(
|
||||
const std::shared_ptr<imperative::VarBase>& X,
|
||||
const std::vector<std::shared_ptr<imperative::VarBase>>& Ws,
|
||||
const std::vector<std::shared_ptr<imperative::VarBase>>& Bs,
|
||||
const phi::Place& place,
|
||||
bool accuracy_check) {
|
||||
imperative::Tracer tracer;
|
||||
|
||||
imperative::NameVarBaseMap ins;
|
||||
imperative::NameVarBaseMap outs;
|
||||
framework::AttributeMap attrs;
|
||||
std::shared_ptr<imperative::VarBase> input0 = X;
|
||||
for (size_t i = 0; i < MLP_NUM_LINEAR; i++) {
|
||||
// Matmul0
|
||||
ins = {{"X", {input0}}, {"Y", {Ws[0]}}};
|
||||
outs = {{"Out", {std::make_shared<imperative::VarBase>(true, "Out")}}};
|
||||
|
||||
tracer.TraceOp<VarBase>("matmul_v2", ins, outs, attrs, place, true);
|
||||
|
||||
// EW-Add0
|
||||
ins = {{"X", outs["Out"]}, {"Y", {Bs[i]}}};
|
||||
outs = {{"Out", {std::make_shared<imperative::VarBase>(true, "Out")}}};
|
||||
|
||||
tracer.TraceOp<VarBase>("elementwise_add", ins, outs, attrs, place, true);
|
||||
input0 = outs["Out"][0];
|
||||
}
|
||||
|
||||
// ReduceSum
|
||||
ins = {{"X", {input0}}};
|
||||
outs = {{"Out", {std::make_shared<imperative::VarBase>(true, "Out")}}};
|
||||
attrs = {{"reduce_all", true}};
|
||||
|
||||
tracer.TraceOp<VarBase>("reduce_sum", ins, outs, attrs, place, true);
|
||||
|
||||
auto* engine = tracer.GetEngine();
|
||||
std::vector<std::shared_ptr<imperative::VarBase>> grad_tensors{nullptr};
|
||||
engine->Init(outs["Out"], grad_tensors, false /*retain_graph*/);
|
||||
engine->Execute();
|
||||
|
||||
if (accuracy_check) {
|
||||
std::unordered_map<std::string, float> result =
|
||||
egr::compute_mlp_expected_results();
|
||||
|
||||
FluidCheckTensorValue(outs["Out"][0], place, result["Out"]);
|
||||
FluidCheckGradTensorValue(X, place, result["GradX"]);
|
||||
FluidCheckGradTensorValue(Ws[0], place, result["GradW"]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace imperative
|
||||
} // namespace paddle
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2021 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "paddle/fluid/eager/eager_tensor.h"
|
||||
#include "paddle/fluid/imperative/layer.h"
|
||||
#include "paddle/phi/api/all.h"
|
||||
|
||||
/* MLP Configurations */
|
||||
// Out1 = X[M, N] x W[N, K] + B[K]
|
||||
// ... x MLP_NUM_LINEAR
|
||||
// Out = ReduceSum(OutN)
|
||||
#define MLP_M 4
|
||||
#define MLP_N 16
|
||||
#define MLP_K MLP_N
|
||||
#define MLP_X_VAL 1.0
|
||||
#define MLP_W_VAL 2.0
|
||||
#define MLP_B_VAL 3.0
|
||||
#define MLP_NUM_LINEAR 1000
|
||||
|
||||
namespace egr {
|
||||
|
||||
inline std::unordered_map<std::string, float> compute_mlp_expected_results() {
|
||||
float Out = MLP_X_VAL;
|
||||
for (size_t i = 0; i < MLP_NUM_LINEAR; i++) {
|
||||
Out = Out * MLP_W_VAL * MLP_N + MLP_B_VAL;
|
||||
}
|
||||
Out = Out * MLP_M * MLP_N;
|
||||
|
||||
float GradX = 1.0 * pow((MLP_W_VAL * MLP_N), MLP_NUM_LINEAR);
|
||||
float GradW0 =
|
||||
1.0 * pow((MLP_W_VAL * MLP_N), (MLP_NUM_LINEAR - 1)) * MLP_X_VAL * MLP_M;
|
||||
return {{"Out", Out}, {"GradX", GradX}, {"GradW", GradW0}};
|
||||
}
|
||||
|
||||
/* ---- Eager Scale ---- */
|
||||
void benchmark_eager_scale(const paddle::Tensor& tensor,
|
||||
bool accuracy_check = false);
|
||||
|
||||
/* ---- Eager MatMul ---- */
|
||||
void benchmark_eager_matmul(const paddle::Tensor& X,
|
||||
const paddle::Tensor& Y,
|
||||
bool accuracy_check = false);
|
||||
|
||||
void benchmark_eager_intermediate_matmul(const paddle::Tensor& X,
|
||||
const paddle::Tensor& Y,
|
||||
bool accuracy_check = false);
|
||||
|
||||
void benchmark_eager_intermediate_mlp(const paddle::Tensor& X,
|
||||
const std::vector<paddle::Tensor>& Ws,
|
||||
const std::vector<paddle::Tensor>& Bs,
|
||||
bool accuracy_check = false);
|
||||
|
||||
} // namespace egr
|
||||
|
||||
namespace paddle {
|
||||
namespace imperative {
|
||||
/* ---- Fluid Scale ---- */
|
||||
// TODO(jiabin): Change this and remove nolint
|
||||
void benchmark_fluid_scale(
|
||||
const std::shared_ptr<imperative::VarBase>& X, // NOLINT
|
||||
const phi::Place& place,
|
||||
bool accuracy_check = false);
|
||||
|
||||
/* ---- Fluid MatMul ---- */
|
||||
void benchmark_fluid_matmul(
|
||||
const std::shared_ptr<imperative::VarBase>& X,
|
||||
const std::shared_ptr<imperative::VarBase>& Y, // NOLINT
|
||||
const phi::Place& place,
|
||||
bool accuracy_check = false);
|
||||
|
||||
/* ---- Fluid MLP ---- */
|
||||
void benchmark_fluid_mlp(
|
||||
const std::shared_ptr<imperative::VarBase>& X,
|
||||
const std::vector<std::shared_ptr<imperative::VarBase>>& Ws,
|
||||
const std::vector<std::shared_ptr<imperative::VarBase>>& Bs,
|
||||
const phi::Place& place,
|
||||
bool accuracy_check = false);
|
||||
|
||||
} // namespace imperative
|
||||
} // namespace paddle
|
||||
Reference in New Issue
Block a user