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
+80
View File
@@ -0,0 +1,80 @@
if(WIN32)
set(COMMON_API_TEST_DEPS type_info common)
else()
set(COMMON_API_TEST_DEPS phi common)
endif()
if(WITH_GPU)
nv_test(
test_phi_tensor
SRCS test_phi_tensor.cc
DEPS glog ${COMMON_API_TEST_DEPS})
nv_test(
test_allocator
SRCS test_allocator.cu
DEPS phi common)
nv_test(
test_cuda_stream
SRCS test_cuda_stream.cu
DEPS phi common)
nv_test(
test_from_blob
SRCS test_from_blob.cc
DEPS ${COMMON_API_TEST_DEPS})
elseif(WITH_ROCM)
hip_test(
test_phi_tensor
SRCS test_phi_tensor.cc
DEPS glog ${COMMON_API_TEST_DEPS})
hip_test(
test_allocator
SRCS test_allocator.cu
DEPS phi common)
hip_test(
test_cuda_stream
SRCS test_cuda_stream.cu
DEPS phi common)
hip_test(
test_from_blob
SRCS test_from_blob.cc
DEPS ${COMMON_API_TEST_DEPS})
else()
cc_test(
test_phi_tensor
SRCS test_phi_tensor.cc
DEPS glog ${COMMON_API_TEST_DEPS})
cc_test(
test_from_blob
SRCS test_from_blob.cc
DEPS ${COMMON_API_TEST_DEPS})
endif()
cc_test(
test_phi_exception
SRCS test_phi_exception.cc
DEPS gtest)
cc_test(
test_to_api
SRCS test_to_api.cc
DEPS ${COMMON_API_TEST_DEPS})
cc_test(
test_slice_api
SRCS test_slice_api.cc
DEPS ${COMMON_API_TEST_DEPS})
cc_test(
test_scale_benchmark
SRCS test_scale_benchmark.cc
DEPS ${COMMON_API_TEST_DEPS})
cc_test(
test_data_transform
SRCS test_data_transform.cc
DEPS ${COMMON_API_TEST_DEPS})
cc_test(
test_strings_empty_api
SRCS test_strings_empty_api.cc
DEPS ${COMMON_API_TEST_DEPS})
cc_test(
test_strings_lower_upper_api
SRCS test_strings_lower_upper_api.cc
DEPS ${COMMON_API_TEST_DEPS})
+286
View File
@@ -0,0 +1,286 @@
// 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 "glog/logging.h"
#include "paddle/common/flags.h"
#include "paddle/phi/api/include/tensor.h"
#include "paddle/phi/api/lib/kernel_dispatch.h"
#include "paddle/phi/api/lib/utils/allocator.h"
#include "paddle/phi/common/int_array.h"
#include "paddle/phi/common/scalar.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/core/meta_tensor.h"
#include "paddle/phi/infermeta/unary.h"
#include "paddle/phi/kernels/scale_kernel.h"
COMMON_DECLARE_int32(low_precision_op_list);
namespace paddle {
namespace experimental {
Tensor scale_kernel_context(const Tensor& x,
const Scalar& scale,
const Scalar& bias,
bool bias_after_scale) {
Backend kernel_backend = Backend::UNDEFINED;
DataLayout kernel_layout = DataLayout::UNDEFINED;
DataType kernel_data_type = DataType::UNDEFINED;
if (kernel_backend == Backend::UNDEFINED ||
kernel_layout == DataLayout::UNDEFINED ||
kernel_data_type == DataType::UNDEFINED) {
auto kernel_key_set = ParseKernelKeyByInputArgs(x);
auto kernel_key = kernel_key_set.GetHighestPriorityKernelKey();
if (kernel_backend == Backend::UNDEFINED) {
kernel_backend = kernel_key.backend();
}
if (kernel_layout == DataLayout::UNDEFINED) {
kernel_layout = kernel_key.layout();
}
if (kernel_data_type == DataType::UNDEFINED) {
kernel_data_type = kernel_key.dtype();
}
}
auto kernel_result = phi::KernelFactory::Instance().SelectKernelOrThrowError(
"scale", {kernel_backend, kernel_layout, kernel_data_type});
const auto& kernel = kernel_result.kernel;
if (FLAGS_low_precision_op_list) {
phi::KernelFactory::Instance().AddToLowPrecisionKernelList(
"scale", kernel_data_type);
}
VLOG(6) << "scale API kernel key: [" << kernel_backend << ", "
<< kernel_layout << ", " << kernel_data_type << "]";
VLOG(6) << "scale API kernel: " << kernel;
auto* dev_ctx = GetDeviceContextByBackend(kernel_backend);
auto kernel_context = phi::KernelContext(dev_ctx);
auto dense_x = std::dynamic_pointer_cast<phi::DenseTensor>(x.impl());
kernel_context.EmplaceBackInput(dense_x.get());
kernel_context.EmplaceBackAttr(scale);
kernel_context.EmplaceBackAttr(bias);
kernel_context.EmplaceBackAttr(bias_after_scale);
auto dense_out = std::make_shared<phi::DenseTensor>();
phi::MetaTensor meta_out(dense_out.get());
phi::UnchangedInferMeta(*dense_x, &meta_out);
kernel_context.EmplaceBackOutput(dense_out.get());
Tensor out;
out.set_impl(dense_out);
kernel(&kernel_context);
return out;
}
static void ScaleCPU(DataType kernel_dtype,
const phi::CPUContext& dev_ctx,
const phi::DenseTensor& x,
const Scalar& scale,
const Scalar& bias,
bool bias_after_scale,
phi::DenseTensor* dense_out) {
switch (kernel_dtype) {
case phi::DataType::FLOAT64: {
phi::ScaleKernel<double>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::FLOAT32: {
phi::ScaleKernel<float>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::BFLOAT16: {
phi::ScaleKernel<phi::dtype::bfloat16>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT64: {
phi::ScaleKernel<int64_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT32: {
phi::ScaleKernel<int32_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT16: {
phi::ScaleKernel<int16_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT8: {
phi::ScaleKernel<int8_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::UINT8: {
phi::ScaleKernel<uint8_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
default: {
PADDLE_THROW(common::errors::Fatal(
"Detected unsupported data type."
"Only Float64, Float32, BFloat16, Int64, Int32, Int16, Int8, UInt8 "
"are supported for now."));
break;
}
}
}
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
static void ScaleGPU(DataType kernel_dtype,
const phi::GPUContext& dev_ctx,
const phi::DenseTensor& x,
const Scalar& scale,
const Scalar& bias,
bool bias_after_scale,
phi::DenseTensor* dense_out) {
switch (kernel_dtype) {
case phi::DataType::FLOAT64: {
phi::ScaleKernel<double>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::FLOAT32: {
phi::ScaleKernel<float>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::FLOAT16: {
phi::ScaleKernel<phi::dtype::float16>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT64: {
phi::ScaleKernel<int64_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT32: {
phi::ScaleKernel<int32_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT16: {
phi::ScaleKernel<int16_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::INT8: {
phi::ScaleKernel<int8_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
case phi::DataType::UINT8: {
phi::ScaleKernel<uint8_t>(
dev_ctx, x, scale, bias, bias_after_scale, dense_out);
break;
}
default: {
PADDLE_THROW(common::errors::Fatal(
"Detected unsupported data type."
"Only Float64, Float32, Float16, Int64, Int32, Int16, Int8, UInt8 "
"are "
"supported for now."));
break;
}
}
}
#endif
Tensor scale_switch_case(const Tensor& x,
const Scalar& scale,
const Scalar& bias,
bool bias_after_scale) {
Backend kernel_backend = Backend::UNDEFINED;
DataLayout kernel_layout = DataLayout::UNDEFINED;
DataType kernel_data_type = DataType::UNDEFINED;
if (kernel_backend == Backend::UNDEFINED ||
kernel_layout == DataLayout::UNDEFINED ||
kernel_data_type == DataType::UNDEFINED) {
auto kernel_key_set = ParseKernelKeyByInputArgs(x);
auto kernel_key = kernel_key_set.GetHighestPriorityKernelKey();
if (kernel_backend == Backend::UNDEFINED) {
kernel_backend = kernel_key.backend();
}
if (kernel_layout == DataLayout::UNDEFINED) {
kernel_layout = kernel_key.layout();
}
if (kernel_data_type == DataType::UNDEFINED) {
kernel_data_type = kernel_key.dtype();
}
}
auto kernel_result = phi::KernelFactory::Instance().SelectKernelOrThrowError(
"scale", {kernel_backend, kernel_layout, kernel_data_type});
const auto& kernel = kernel_result.kernel;
if (FLAGS_low_precision_op_list) {
phi::KernelFactory::Instance().AddToLowPrecisionKernelList(
"scale", kernel_data_type);
}
VLOG(6) << "scale API kernel key: [" << kernel_backend << ", "
<< kernel_layout << ", " << kernel_data_type << "]";
VLOG(6) << "scale API kernel: " << kernel;
auto* dev_ctx = GetDeviceContextByBackend(kernel_backend);
auto dense_x = std::dynamic_pointer_cast<phi::DenseTensor>(x.impl());
auto dense_out = std::make_shared<phi::DenseTensor>();
phi::MetaTensor meta_out(dense_out.get());
phi::UnchangedInferMeta(*dense_x, &meta_out);
Tensor out;
out.set_impl(dense_out);
switch (kernel_backend) {
case Backend::CPU:
ScaleCPU(kernel_data_type,
static_cast<const phi::CPUContext&>(*dev_ctx),
*dense_x,
scale,
bias,
bias_after_scale,
dense_out.get());
break;
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
case Backend::GPU:
ScaleGPU(kernel_data_type,
static_cast<const phi::GPUContext&>(*dev_ctx),
*dense_x,
scale,
bias,
bias_after_scale,
dense_out.get());
break;
#endif
default:
PADDLE_THROW(common::errors::Fatal(
"Detected unsupported backend."
"Only CPU and CUDA Backend are supported for now."
"Please double check if your backend falls into the above two "
"categories."));
}
return out;
}
} // namespace experimental
} // namespace paddle
+72
View File
@@ -0,0 +1,72 @@
/* 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 "paddle/phi/api/include/context_pool.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/common/memory_utils.h"
#include "paddle/phi/common/place.h"
#include "paddle/phi/common/transform.h"
#include "paddle/phi/core/allocator.h"
#include "paddle/phi/core/device_context.h"
using phi::memory_utils::Copy;
template <typename T>
class Scale {
public:
explicit Scale(const T& scale) : scale_(scale) {}
HOSTDEVICE T operator()(const T& a) const { return a * scale_; }
private:
T scale_;
};
TEST(Allocator, CPU) {
phi::Allocator* allocator = paddle::GetAllocator(phi::CPUPlace());
auto cpu_allocation = allocator->Allocate(sizeof(float) * 4);
float* cpu_buf = static_cast<float*>(cpu_allocation->ptr());
ASSERT_NE(cpu_buf, nullptr);
cpu_buf[0] = 1.0f;
cpu_buf[1] = 2.0f;
cpu_buf[2] = 3.0f;
cpu_buf[3] = 4.0f;
for (size_t i = 0; i < 4; ++i) {
cpu_buf[i] = cpu_buf[i] + 1;
}
for (size_t i = 0; i < 4; ++i) {
ASSERT_NEAR(cpu_buf[i], static_cast<float>(2.0 + i), 1e-5);
}
}
TEST(Allocator, GPU) {
phi::GPUPlace gpu0(0);
float cpu_buf[4] = {0.1, 0.2, 0.3, 0.4};
phi::Allocator* allocator = paddle::GetAllocator(gpu0);
auto gpu_allocation = allocator->Allocate(sizeof(cpu_buf));
float* gpu_buf = static_cast<float*>(gpu_allocation->ptr());
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
auto* ctx = reinterpret_cast<phi::GPUContext*>(pool.Get(gpu0));
Copy(gpu0, gpu_buf, phi::CPUPlace(), cpu_buf, sizeof(cpu_buf), ctx->stream());
phi::Transform<phi::GPUContext> trans;
trans(*ctx, gpu_buf, gpu_buf + 4, gpu_buf, Scale<float>(10));
ctx->Wait();
Copy(phi::CPUPlace(), cpu_buf, gpu0, gpu_buf, sizeof(cpu_buf), ctx->stream());
for (int i = 0; i < 4; ++i) {
ASSERT_NEAR(cpu_buf[i], static_cast<float>(i + 1), 1e-5);
}
}
+26
View File
@@ -0,0 +1,26 @@
/* 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 "paddle/phi/api/include/context_pool.h"
#include "paddle/phi/core/cuda_stream.h"
TEST(CUDAStream, GPU) {
phi::GPUPlace gpu0(0);
phi::CUDAStream* stream = paddle::GetCurrentCUDAStream(gpu0);
EXPECT_TRUE(stream != nullptr);
gpuStream_t raw_stream = stream->raw_stream();
EXPECT_TRUE(raw_stream != nullptr);
}
+107
View File
@@ -0,0 +1,107 @@
/* Copyright (c) 2022 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 <memory>
#include "paddle/phi/api/include/api.h"
#include "paddle/phi/common/complex.h"
#include "paddle/phi/common/place.h"
#include "paddle/phi/core/compat/convert_utils.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/kernel_registry.h"
PD_DECLARE_KERNEL(full, CPU, ALL_LAYOUT);
PD_DECLARE_KERNEL(matmul, CPU, ALL_LAYOUT);
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
PD_DECLARE_KERNEL(full, GPU, ALL_LAYOUT);
PD_DECLARE_KERNEL(matmul, GPU, ALL_LAYOUT);
#endif
namespace paddle {
namespace tests {
// TODO(chenweihang): Remove this test after the API is used in the dygraph
TEST(API, data_transform_same_place) {
// 1. create tensor
auto x =
paddle::experimental::full({3, 3}, 1.0, DataType::COMPLEX128, CPUPlace());
auto y =
paddle::experimental::full({3, 3}, 2.0, DataType::FLOAT32, CPUPlace());
std::vector<phi::dtype::complex<double>> sum(9, 6.0);
// 2. test API
auto out = paddle::experimental::matmul(x, y, false, false);
// 3. check result
ASSERT_EQ(out.dims().size(), 2);
ASSERT_EQ(out.dims()[0], 3);
ASSERT_EQ(out.dims()[1], 3);
ASSERT_EQ(out.numel(), 9);
ASSERT_EQ(out.type(), phi::DataType::COMPLEX128);
ASSERT_EQ(out.layout(), phi::DataLayout::NCHW);
ASSERT_EQ(out.initialized(), true);
auto dense_out = std::dynamic_pointer_cast<phi::DenseTensor>(out.impl());
for (size_t i = 0; i < 9; i++) {
ASSERT_NEAR(sum[i].real,
dense_out->data<phi::dtype::complex<double>>()[i].real,
1e-6f);
ASSERT_NEAR(sum[i].imag,
dense_out->data<phi::dtype::complex<double>>()[i].imag,
1e-6f);
}
}
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
TEST(Tensor, data_transform_diff_place) {
// 1. create tensor
auto x = paddle::experimental::full(
{3, 3}, 1.0, phi::DataType::FLOAT64, CPUPlace());
auto y = paddle::experimental::full(
{3, 3}, 2.0, phi::DataType::FLOAT64, GPUPlace());
std::vector<float> sum(9, 6.0);
// 2. test API
auto out = paddle::experimental::matmul(x, y, false, false);
// 3. check result
ASSERT_EQ(out.dims().size(), 2);
ASSERT_EQ(out.dims()[0], 3);
ASSERT_EQ(out.dims()[1], 3);
ASSERT_EQ(out.numel(), 9);
ASSERT_EQ(out.dtype(), phi::DataType::FLOAT64);
ASSERT_EQ(out.layout(), phi::DataLayout::NCHW);
ASSERT_EQ(out.initialized(), true);
ASSERT_EQ(out.impl()->place(), phi::TransToPhiPlace(phi::Backend::GPU));
auto ref_out = experimental::copy_to(out, CPUPlace(), true);
auto dense_out = std::dynamic_pointer_cast<phi::DenseTensor>(ref_out.impl());
for (size_t i = 0; i < 9; i++) {
ASSERT_NEAR(sum[i], dense_out->data<double>()[i], 1e-6f);
}
}
#endif
} // namespace tests
} // namespace paddle
+233
View File
@@ -0,0 +1,233 @@
/* 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 "paddle/phi/api/include/api.h"
#include "paddle/phi/api/include/tensor_utils.h"
#include "paddle/phi/core/kernel_registry.h"
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
#include "paddle/phi/api/include/context_pool.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/backends/gpu/gpu_info.h"
#include "paddle/phi/common/memory_utils.h"
#endif
PD_DECLARE_KERNEL(pow, CPU, ALL_LAYOUT);
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
PD_DECLARE_KERNEL(pow, GPU, ALL_LAYOUT);
#endif
using paddle::from_blob;
using phi::DataType;
namespace paddle {
phi::Place GetPlaceFromPtr(void* data);
} // namespace paddle
TEST(from_blob, CPU) {
// 1. create data
int64_t data[] = {4, 3, 2, 1}; // NOLINT
ASSERT_EQ(paddle::GetPlaceFromPtr(data), phi::CPUPlace());
// 2. test API
auto test_tensor = from_blob(data, {1, 2, 2}, DataType::INT64);
// 3. check result
// 3.1 check tensor attributes
ASSERT_EQ(test_tensor.dims().size(), 3);
ASSERT_EQ(test_tensor.dims()[0], 1);
ASSERT_EQ(test_tensor.dims()[1], 2);
ASSERT_EQ(test_tensor.dims()[2], 2);
ASSERT_EQ(test_tensor.numel(), 4);
ASSERT_EQ(test_tensor.is_cpu(), true);
ASSERT_EQ(test_tensor.dtype(), DataType::INT64);
ASSERT_EQ(test_tensor.layout(), phi::DataLayout::NCHW);
ASSERT_EQ(test_tensor.is_dense_tensor(), true);
// 3.2 check tensor values
auto* test_tensor_data = test_tensor.template data<int64_t>();
for (int64_t i = 0; i < 4; i++) {
ASSERT_EQ(test_tensor_data[i], 4 - i);
}
// 3.3 check whether memory is shared
ASSERT_EQ(data, test_tensor_data);
// 3.4 test other API
auto test_tensor_pow = paddle::experimental::pow(test_tensor, 2);
auto* test_tensor_pow_data = test_tensor_pow.template data<int64_t>();
for (int64_t i = 0; i < 4; i++) {
ASSERT_EQ(test_tensor_pow_data[i],
static_cast<int64_t>(std::pow(4 - i, 2)));
}
}
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
using phi::memory_utils::Copy;
TEST(GetPlaceFromPtr, GPU) {
using paddle::GetPlaceFromPtr;
std::array<float, 6> cpu_data = {};
auto cpu_data_place = GetPlaceFromPtr(cpu_data.data());
ASSERT_EQ(cpu_data_place, phi::CPUPlace());
std::cout << "cpu_data_place: " << cpu_data_place << std::endl;
auto alloc_ptr =
paddle::GetAllocator(phi::GPUPlace(0))->Allocate(sizeof(cpu_data));
float* gpu0_data = static_cast<float*>(alloc_ptr->ptr());
auto gpu0_data_place = GetPlaceFromPtr(gpu0_data);
ASSERT_EQ(gpu0_data_place, phi::GPUPlace(0));
std::cout << "gpu0_data_place: " << gpu0_data_place << std::endl;
alloc_ptr.release();
if (phi::backends::gpu::GetGPUDeviceCount() > 1) {
float* gpu1_data =
static_cast<float*>(paddle::GetAllocator(phi::GPUPlace(1))
->Allocate(sizeof(cpu_data))
->ptr());
auto gpu1_data_place = GetPlaceFromPtr(gpu1_data);
ASSERT_EQ(gpu1_data_place, phi::GPUPlace(1));
std::cout << "gpu1_data_place: " << gpu1_data_place << std::endl;
}
// Test GPUPinnedPlace (cudaMemoryTypeHost)
auto pinned_alloc_ptr =
paddle::GetAllocator(phi::GPUPinnedPlace())->Allocate(sizeof(cpu_data));
float* pinned_data = static_cast<float*>(pinned_alloc_ptr->ptr());
auto pinned_data_place = GetPlaceFromPtr(pinned_data);
ASSERT_EQ(pinned_data_place, phi::GPUPinnedPlace());
std::cout << "pinned_data_place: " << pinned_data_place << std::endl;
pinned_alloc_ptr.release();
}
TEST(from_blob, GPU) {
// 1. create data
std::array<float, 6> cpu_data = {0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f};
phi::GPUPlace gpu0(0);
phi::Allocator* allocator = paddle::GetAllocator(gpu0);
auto gpu_allocation = allocator->Allocate(sizeof(cpu_data));
float* gpu_data = static_cast<float*>(gpu_allocation->ptr());
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
auto* ctx = reinterpret_cast<phi::GPUContext*>(pool.Get(gpu0));
Copy(gpu0,
gpu_data,
phi::CPUPlace(),
cpu_data.data(),
sizeof(cpu_data),
ctx->stream());
// 2. test API
auto gpu_tensor = from_blob(gpu_data, {2, 3}, DataType::FLOAT32);
// 3. check result
// 3.1 check tensor attributes
ASSERT_EQ(gpu_tensor.dims().size(), 2);
ASSERT_EQ(gpu_tensor.dims()[0], 2);
ASSERT_EQ(gpu_tensor.dims()[1], 3);
ASSERT_EQ(gpu_tensor.numel(), 6);
// ASSERT_EQ(gpu_tensor.is_gpu(), true);
ASSERT_EQ(gpu_tensor.dtype(), DataType::FLOAT32);
// 3.2 check tensor values
auto* gpu_tensor_data = gpu_tensor.template data<float>();
std::array<float, 6> gpu_tensor_data_cpu = {};
Copy(phi::CPUPlace(),
gpu_tensor_data_cpu.data(),
gpu0,
gpu_tensor_data,
sizeof(cpu_data),
ctx->stream());
for (int64_t i = 0; i < 6; i++) {
ASSERT_NEAR(
gpu_tensor_data_cpu[i], static_cast<float>((i + 1) * 0.1f), 1e-5);
}
// 3.3 check whether memory is shared
ASSERT_EQ(gpu_data, gpu_tensor_data);
// 3.4 test other API
auto gpu_tensor_pow = paddle::experimental::pow(gpu_tensor, 2);
auto* gpu_tensor_pow_data = gpu_tensor_pow.template data<float>();
std::array<float, 6> gpu_tensor_pow_data_cpu = {};
Copy(phi::CPUPlace(),
gpu_tensor_pow_data_cpu.data(),
gpu0,
gpu_tensor_pow_data,
sizeof(cpu_data),
ctx->stream());
for (int64_t i = 0; i < 6; i++) {
ASSERT_NEAR(gpu_tensor_pow_data_cpu[i],
static_cast<float>(std::pow(i + 1, 2) * 0.01f),
1e-5);
}
}
#endif
TEST(from_blob, Option) {
int delete_count = 0, f_delete_count = 0;
auto deleter = [&delete_count](void* data) {
delete[] static_cast<int64_t*>(data);
delete_count++;
};
auto f_deleter = [&f_delete_count](void* ptr) {
delete[] static_cast<float*>(ptr);
f_delete_count++;
};
{
auto data = new int64_t[8];
for (int64_t i = 0; i < 8; i++) {
data[i] = i;
}
auto test_tensor = from_blob(data,
{1, 2, 2, 2},
DataType::INT64,
phi::DataLayout::NHWC,
phi::CPUPlace(),
deleter);
ASSERT_EQ(test_tensor.layout(), phi::DataLayout::NHWC);
ASSERT_EQ(delete_count, 0);
auto f_data = new float[8];
for (int i = 0; i < 8; i++) {
f_data[i] = static_cast<float>(i);
}
auto test_tensor_f = from_blob(f_data,
{1, 2, 2, 2},
DataType::FLOAT32,
common::DataLayout::NHWC,
phi::CPUPlace(),
f_deleter);
ASSERT_EQ(test_tensor_f.layout(), phi::DataLayout::NHWC);
ASSERT_EQ(f_delete_count, 0);
}
ASSERT_EQ(delete_count, 1);
ASSERT_EQ(f_delete_count, 1);
}
TEST(from_blob, Strides) {
int64_t data[8] = {0, 1, 2, 3, 4, 5, 6, 7};
auto test_tensor =
from_blob(data, {1, 2, 2, 1}, {0, 4, 2, 0}, DataType::INT64);
ASSERT_EQ(test_tensor.shape()[1], 2);
ASSERT_EQ(test_tensor.shape()[2], 2);
ASSERT_EQ(test_tensor.strides()[1], 4);
ASSERT_EQ(test_tensor.strides()[2], 2);
}
+164
View File
@@ -0,0 +1,164 @@
/* 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 <iostream>
#include <string>
#include "gtest/gtest.h"
#include "paddle/common/exception.h"
namespace paddle {
namespace tests {
TEST(PD_THROW, empty) {
bool caught_exception = false;
try {
PD_THROW();
} catch (const std::exception& e) {
caught_exception = true;
std::string err_msg = e.what();
EXPECT_TRUE(err_msg.find("An error occurred.") != std::string::npos);
#if _WIN32
EXPECT_TRUE(err_msg.find("test\\cpp\\phi\\api\\test_phi_exception.cc") !=
std::string::npos);
#else
EXPECT_TRUE(err_msg.find("test/cpp/phi/api/test_phi_exception.cc") !=
std::string::npos);
#endif
}
EXPECT_TRUE(caught_exception);
}
TEST(PD_THROW, non_empty) {
bool caught_exception = false;
try {
PD_THROW("PD_THROW returns ",
false,
". DataType of ",
1,
" is INT. ",
"DataType of ",
0.23,
" is FLOAT. ");
} catch (const std::exception& e) {
caught_exception = true;
std::string err_msg = e.what();
EXPECT_TRUE(err_msg.find("PD_THROW returns 0. DataType of 1 is INT. ") !=
std::string::npos);
#if _WIN32
EXPECT_TRUE(err_msg.find("test\\cpp\\phi\\api\\test_phi_exception.cc") !=
std::string::npos);
#else
EXPECT_TRUE(err_msg.find("test/cpp/phi/api/test_phi_exception.cc") !=
std::string::npos);
#endif
}
EXPECT_TRUE(caught_exception);
}
TEST(PD_CHECK, OK) {
PD_CHECK(true);
PD_CHECK(true, "PD_CHECK returns ", true, "now");
const size_t a = 1;
const size_t b = 10;
PD_CHECK(a < b);
PD_CHECK(a < b, "PD_CHECK returns ", true, a, "should < ", b);
}
TEST(PD_CHECK, FAILED) {
bool caught_exception = false;
try {
PD_CHECK(false);
} catch (const std::exception& e) {
caught_exception = true;
std::string err_msg = e.what();
EXPECT_TRUE(err_msg.find("Expected false, but it's not satisfied.") !=
std::string::npos);
#if _WIN32
EXPECT_TRUE(err_msg.find("test\\cpp\\phi\\api\\test_phi_exception.cc") !=
std::string::npos);
#else
EXPECT_TRUE(err_msg.find("test/cpp/phi/api/test_phi_exception.cc") !=
std::string::npos);
#endif
}
EXPECT_TRUE(caught_exception);
caught_exception = false;
try {
PD_CHECK(false,
"PD_CHECK returns ",
false,
". DataType of ",
1,
" is INT. ",
"DataType of ",
0.23,
" is FLOAT. ");
} catch (const std::exception& e) {
caught_exception = true;
std::string err_msg = e.what();
EXPECT_TRUE(err_msg.find("PD_CHECK returns 0. DataType of 1 is INT. ") !=
std::string::npos);
#if _WIN32
EXPECT_TRUE(err_msg.find("test\\cpp\\phi\\api\\test_phi_exception.cc") !=
std::string::npos);
#else
EXPECT_TRUE(err_msg.find("test/cpp/phi/api/test_phi_exception.cc") !=
std::string::npos);
#endif
}
EXPECT_TRUE(caught_exception);
const size_t a = 1;
const size_t b = 10;
caught_exception = false;
try {
PD_CHECK(a > b);
} catch (const std::exception& e) {
caught_exception = true;
std::string err_msg = e.what();
EXPECT_TRUE(err_msg.find("Expected a > b, but it's not satisfied.") !=
std::string::npos);
#if _WIN32
EXPECT_TRUE(err_msg.find("test\\cpp\\phi\\api\\test_phi_exception.cc") !=
std::string::npos);
#else
EXPECT_TRUE(err_msg.find("test/cpp/phi/api/test_phi_exception.cc") !=
std::string::npos);
#endif
}
EXPECT_TRUE(caught_exception);
const size_t c = 123;
const float d = 0.345;
caught_exception = false;
try {
PD_CHECK(c < d, "PD_CHECK returns ", false, ", because ", c, " > ", d);
} catch (const std::exception& e) {
caught_exception = true;
std::string err_msg = e.what();
EXPECT_TRUE(err_msg.find("PD_CHECK returns 0, because 123 > 0.345") !=
std::string::npos);
#if _WIN32
EXPECT_TRUE(err_msg.find("test\\cpp\\phi\\api\\test_phi_exception.cc") !=
std::string::npos);
#else
EXPECT_TRUE(err_msg.find("test/cpp/phi/api/test_phi_exception.cc") !=
std::string::npos);
#endif
}
EXPECT_TRUE(caught_exception);
}
} // namespace tests
} // namespace paddle
+431
View File
@@ -0,0 +1,431 @@
// 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 "glog/logging.h"
#include "gtest/gtest.h"
#include "paddle/phi/api/include/api.h"
#include "paddle/phi/api/include/tensor.h"
#include "paddle/phi/common/data_type.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/core/selected_rows.h"
PD_DECLARE_KERNEL(empty, CPU, ALL_LAYOUT);
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
PD_DECLARE_KERNEL(empty, GPU, ALL_LAYOUT);
#endif
namespace paddle {
namespace tests {
using Tensor = paddle::Tensor;
using DataType = phi::DataType;
template <typename T>
Tensor InitCPUTensorForTest() {
std::vector<int64_t> tensor_shape{5, 5};
DataType dtype = phi::CppTypeToDataType<T>::Type();
Tensor t1 = paddle::experimental::empty(tensor_shape, dtype, phi::CPUPlace());
auto* p_data_ptr = t1.data<T>();
for (int64_t i = 0; i < t1.size(); i++) {
p_data_ptr[i] = T(5);
}
return t1;
}
template <typename T>
void TestCopyTensor() {
auto t1 = InitCPUTensorForTest<T>();
auto t1_cpu_cp = t1.copy_to(phi::CPUPlace(), /*blocking=*/false);
PADDLE_ENFORCE_EQ(t1_cpu_cp.place(),
phi::CPUPlace(),
common::errors::InvalidArgument("t1_cpu_cp should copy to "
"CPUPlace, but got %s",
t1_cpu_cp.place()));
for (int64_t i = 0; i < t1.size(); i++) {
PADDLE_ENFORCE_EQ(
t1_cpu_cp.template data<T>()[i],
T(5),
common::errors::InvalidArgument(
"t1_cpu_cp.template data<T>()[%d] should be equal to T(5) ", i));
}
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
VLOG(2) << "Do GPU copy test";
auto t1_gpu_cp = t1_cpu_cp.copy_to(phi::GPUPlace(), /*blocking=*/false);
PADDLE_ENFORCE_EQ(t1_gpu_cp.place(),
phi::GPUPlace(),
common::errors::InvalidArgument("t1_gpu_cp should copy to "
"GPUPlace, but got %s",
t1_gpu_cp.place()));
auto t1_gpu_cp_cp = t1_gpu_cp.copy_to(phi::GPUPlace(), /*blocking=*/false);
PADDLE_ENFORCE_EQ(
t1_gpu_cp_cp.place(),
phi::GPUPlace(),
common::errors::InvalidArgument("t1_gpu_cp_cp should copy to "
"GPUPlace, but got %s",
t1_gpu_cp_cp.place()));
auto t1_gpu_cp_cp_cpu =
t1_gpu_cp_cp.copy_to(phi::CPUPlace(), /*blocking=*/false);
PADDLE_ENFORCE_EQ(
t1_gpu_cp_cp_cpu.place(),
phi::CPUPlace(),
common::errors::InvalidArgument("t1_gpu_cp_cp_cpu should copy to "
"CPUPlace, but got %s",
t1_gpu_cp_cp_cpu.place()));
for (int64_t i = 0; i < t1.size(); i++) {
PADDLE_ENFORCE_EQ(
t1_gpu_cp_cp_cpu.template data<T>()[i],
T(5),
common::errors::InvalidArgument(
"t1_gpu_cp_cp_cpu.template data<T>()[%d] should be equal to T(5) ",
i));
}
#endif
}
void TestAPIPlace() {
std::vector<int64_t> tensor_shape = {5, 5};
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
auto t1 = paddle::experimental::empty(
tensor_shape, DataType::FLOAT32, phi::GPUPlace());
PADDLE_ENFORCE_EQ(t1.place(),
phi::GPUPlace(),
common::errors::InvalidArgument(
"t1 should copy to GPUPlace, but got %s", t1.place()));
#endif
auto t2 = paddle::experimental::empty(
tensor_shape, DataType::FLOAT32, phi::CPUPlace());
PADDLE_ENFORCE_EQ(t2.place(),
phi::CPUPlace(),
common::errors::InvalidArgument(
"t2 should copy to CPUPlace, but got %s", t2.place()));
}
void TestAPISizeAndShape() {
std::vector<int64_t> tensor_shape = {5, 5};
auto t1 = paddle::experimental::empty(tensor_shape);
PADDLE_ENFORCE_EQ(
t1.size(),
25,
common::errors::InvalidArgument("t1.size should be equal to 25, "
"but got %d",
t1.size()));
PADDLE_ENFORCE_EQ(t1.shape(),
tensor_shape,
common::errors::InvalidArgument(
"t1.shape should be equal to tensor_shape, "));
}
void TestAPISlice() {
std::vector<int64_t> tensor_shape_origin1 = {5, 5};
std::vector<int64_t> tensor_shape_sub1 = {3, 5};
std::vector<int64_t> tensor_shape_origin2 = {5, 5, 5};
std::vector<int64_t> tensor_shape_sub2 = {1, 5, 5};
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
auto t1 = paddle::experimental::empty(
tensor_shape_origin1, DataType::FLOAT32, phi::GPUPlace());
PADDLE_ENFORCE_EQ(
t1.slice(0, 5).shape(),
tensor_shape_origin1,
common::errors::InvalidArgument("t1.slice(0, 5).shape should be equal to "
"{5, 5}"));
PADDLE_ENFORCE_EQ(
t1.slice(0, 3).shape(),
tensor_shape_sub1,
common::errors::InvalidArgument("t1.slice(0, 3).shape should be equal to "
"{3, 5}"));
auto t2 = paddle::experimental::empty(
tensor_shape_origin2, DataType::FLOAT32, phi::GPUPlace());
PADDLE_ENFORCE_EQ(
t2.slice(4, 5).shape(),
tensor_shape_sub2,
common::errors::InvalidArgument("t2.slice(4, 5).shape should be equal to "
"{1, 5, 5}"));
#endif
auto t3 = paddle::experimental::empty(
tensor_shape_origin1, DataType::FLOAT32, phi::CPUPlace());
PADDLE_ENFORCE_EQ(
t3.slice(0, 5).shape(),
tensor_shape_origin1,
common::errors::InvalidArgument("t3.slice(0, 5).shape should be equal to "
"{5, 5}"));
PADDLE_ENFORCE_EQ(
t3.slice(0, 3).shape(),
tensor_shape_sub1,
common::errors::InvalidArgument("t3.slice(0, 3).shape should be equal to "
"{3, 5}"));
auto t4 = paddle::experimental::empty(
tensor_shape_origin2, DataType::FLOAT32, phi::CPUPlace());
PADDLE_ENFORCE_EQ(
t4.slice(4, 5).shape(),
tensor_shape_sub2,
common::errors::InvalidArgument("t4.slice(4, 5).shape should be equal to "
"{1, 5, 5}"));
// Test writing function for sliced tensor
auto t = InitCPUTensorForTest<float>();
auto t_sliced = t.slice(0, 1);
auto* t_sliced_data_ptr = t_sliced.data<float>();
for (int64_t i = 0; i < t_sliced.size(); i++) {
t_sliced_data_ptr[i] += static_cast<float>(5);
}
auto* t_data_ptr = t.data<float>();
for (int64_t i = 0; i < t_sliced.size(); i++) {
PADDLE_ENFORCE_EQ(t_data_ptr[i],
static_cast<float>(10),
common::errors::InvalidArgument(
"Required t_data_ptr[%d] should be equal "
"to static_cast<float>(10) ",
i));
}
}
template <typename T>
paddle::DataType TestDtype() {
std::vector<int64_t> tensor_shape = {5, 5};
DataType dtype = phi::CppTypeToDataType<T>::Type();
auto t1 = paddle::experimental::empty(tensor_shape, dtype, phi::CPUPlace());
return t1.type();
}
template <typename T>
void TestCast(paddle::DataType data_type) {
std::vector<int64_t> tensor_shape = {5, 5};
DataType dtype = phi::CppTypeToDataType<T>::Type();
auto t1 = paddle::experimental::empty(tensor_shape, dtype, phi::CPUPlace());
auto t2 = t1.cast(data_type);
PADDLE_ENFORCE_EQ(
t2.type(),
data_type,
common::errors::InvalidArgument("t2.type() should be equal to data_type, "
"but got %s",
t2.type()));
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
auto tg1 = paddle::experimental::empty(tensor_shape, dtype, phi::GPUPlace());
auto tg2 = tg1.cast(data_type);
PADDLE_ENFORCE_EQ(tg2.type(),
data_type,
common::errors::InvalidArgument(
"tg2.type() should be equal to data_type, "
"but got %s",
tg2.type()));
#endif
}
void GroupTestCopy() {
VLOG(2) << "Float cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<float>();
VLOG(2) << "Double cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<double>();
VLOG(2) << "int cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<int32_t>();
VLOG(2) << "int64 cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<int64_t>();
VLOG(2) << "int16 cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<int16_t>();
VLOG(2) << "int8 cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<int8_t>();
VLOG(2) << "uint8 cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<uint8_t>();
VLOG(2) << "complex<float> cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<paddle::complex64>();
VLOG(2) << "complex<double> cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<paddle::complex128>();
VLOG(2) << "Fp16 cpu-cpu-gpu-gpu-cpu";
TestCopyTensor<paddle::float16>();
}
void GroupTestCast() {
VLOG(2) << "int16_t cast";
TestCast<int16_t>(paddle::DataType::FLOAT32);
VLOG(2) << "int32 cast";
TestCast<int32_t>(paddle::DataType::FLOAT32);
VLOG(2) << "int64 cast";
TestCast<int64_t>(paddle::DataType::FLOAT32);
VLOG(2) << "double cast";
TestCast<double>(paddle::DataType::FLOAT32);
VLOG(2) << "bool cast";
TestCast<bool>(paddle::DataType::FLOAT32);
VLOG(2) << "uint8 cast";
TestCast<uint8_t>(paddle::DataType::FLOAT32);
VLOG(2) << "float cast";
TestCast<float>(paddle::DataType::FLOAT32);
VLOG(2) << "complex<float> cast";
TestCast<paddle::complex64>(paddle::DataType::FLOAT32);
VLOG(2) << "complex<double> cast";
TestCast<paddle::complex128>(paddle::DataType::FLOAT32);
VLOG(2) << "float16 cast";
TestCast<paddle::float16>(paddle::DataType::FLOAT16);
}
void GroupTestDtype() {
PADDLE_ENFORCE_EQ(
TestDtype<bool>(),
paddle::DataType::BOOL,
common::errors::InvalidArgument("TestDtype<bool>() should be equal to "
"paddle::DataType::BOOL, but got %s",
TestDtype<bool>()));
PADDLE_ENFORCE_EQ(
TestDtype<int8_t>(),
paddle::DataType::INT8,
common::errors::InvalidArgument("TestDtype<int8_t>() should be equal to "
"paddle::DataType::INT8, but got %s",
TestDtype<int8_t>()));
PADDLE_ENFORCE_EQ(
TestDtype<uint8_t>(),
paddle::DataType::UINT8,
common::errors::InvalidArgument("TestDtype<uint8_t>() should be equal to "
"paddle::DataType::UINT8, but got %s",
TestDtype<uint8_t>()));
PADDLE_ENFORCE_EQ(
TestDtype<int16_t>(),
paddle::DataType::INT16,
common::errors::InvalidArgument("TestDtype<int16_t>() should be equal to "
"paddle::DataType::INT16, but got %s",
TestDtype<int16_t>()));
PADDLE_ENFORCE_EQ(
TestDtype<int32_t>(),
paddle::DataType::INT32,
common::errors::InvalidArgument("TestDtype<int32_t>() should be equal to "
"paddle::DataType::INT32, but got %s",
TestDtype<int32_t>()));
PADDLE_ENFORCE_EQ(
TestDtype<int64_t>(),
paddle::DataType::INT64,
common::errors::InvalidArgument("TestDtype<int64_t>() should be equal to "
"paddle::DataType::INT64, but got %s",
TestDtype<int64_t>()));
PADDLE_ENFORCE_EQ(TestDtype<paddle::float16>(),
paddle::DataType::FLOAT16,
common::errors::InvalidArgument(
"TestDtype<paddle::float16>() should be equal to "
"paddle::DataType::FLOAT16, but got %s",
TestDtype<paddle::float16>()));
PADDLE_ENFORCE_EQ(
TestDtype<float>(),
paddle::DataType::FLOAT32,
common::errors::InvalidArgument("TestDtype<float>() should be equal to "
"paddle::DataType::FLOAT32, but got %s",
TestDtype<float>()));
PADDLE_ENFORCE_EQ(
TestDtype<double>(),
paddle::DataType::FLOAT64,
common::errors::InvalidArgument("TestDtype<double>() should be equal to "
"paddle::DataType::FLOAT64, but got %s",
TestDtype<double>()));
PADDLE_ENFORCE_EQ(TestDtype<paddle::complex64>(),
paddle::DataType::COMPLEX64,
common::errors::InvalidArgument(
"TestDtype<paddle::complex64>() should be equal to "
"paddle::DataType::COMPLEX64, but got %s",
TestDtype<paddle::complex64>()));
PADDLE_ENFORCE_EQ(TestDtype<paddle::complex128>(),
paddle::DataType::COMPLEX128,
common::errors::InvalidArgument(
"TestDtype<paddle::complex128>() should be equal to "
"paddle::DataType::COMPLEX128, but got %s",
TestDtype<paddle::complex128>()));
}
void TestInitialized() {
auto test_tensor = paddle::experimental::empty({1, 1});
PADDLE_ENFORCE_EQ(test_tensor.initialized(),
true,
common::errors::InvalidArgument(
"test_tensor should be initialized, but got %s",
test_tensor.initialized()));
float* tensor_data = test_tensor.data<float>();
for (int i = 0; i < test_tensor.size(); i++) {
tensor_data[i] = 0.5;
}
for (int i = 0; i < test_tensor.size(); i++) {
PADDLE_ENFORCE_EQ(tensor_data[i],
0.5,
common::errors::InvalidArgument(
"tensor_data[%d] should be equal to 0.5, "
"but got %f",
i,
tensor_data[i]));
}
}
void TestDataInterface() {
// Test DenseTensor
auto test_tensor = paddle::experimental::empty({1, 1});
PADDLE_ENFORCE_EQ(test_tensor.initialized(),
true,
common::errors::InvalidArgument(
"test_tensor should be initialized, but got %s",
test_tensor.initialized()));
void* tensor_ptr = test_tensor.data();
PADDLE_ENFORCE_NE(
tensor_ptr,
nullptr,
common::errors::InvalidArgument(
"test_tensor should not be NULL, but got %p", tensor_ptr));
const void* const_tensor_ptr = test_tensor.data();
PADDLE_ENFORCE_NE(
const_tensor_ptr,
nullptr,
common::errors::InvalidArgument("const_tensor should not be NULL, "
"but got %p",
const_tensor_ptr));
// Test SelectedRows
std::vector<int64_t> rows = {0};
std::shared_ptr<phi::SelectedRows> selected_rows =
std::make_shared<phi::SelectedRows>(rows, 1);
selected_rows->mutable_value()->Resize(common::make_ddim({1, 1}));
selected_rows->mutable_value()->mutable_data<float>(phi::CPUPlace())[0] =
static_cast<float>(10.0f);
paddle::Tensor sr_tensor = paddle::Tensor(selected_rows);
PADDLE_ENFORCE_EQ(sr_tensor.initialized(),
true,
common::errors::InvalidArgument(
"sr_tensor should be initialized, but got %s",
sr_tensor.initialized()));
tensor_ptr = sr_tensor.data();
PADDLE_ENFORCE_NE(tensor_ptr,
nullptr,
common::errors::InvalidArgument(
"tensor should not be NULL, but got %p", tensor_ptr));
const_tensor_ptr = sr_tensor.data();
PADDLE_ENFORCE_NE(
const_tensor_ptr,
nullptr,
common::errors::InvalidArgument("const_tensor should not be NULL, "
"but got %p",
const_tensor_ptr));
}
TEST(PhiTensor, All) {
VLOG(2) << "TestCopy";
GroupTestCopy();
VLOG(2) << "TestDtype";
GroupTestDtype();
VLOG(2) << "TestShape";
TestAPISizeAndShape();
VLOG(2) << "TestPlace";
TestAPIPlace();
VLOG(2) << "TestSlice";
TestAPISlice();
VLOG(2) << "TestCast";
GroupTestCast();
VLOG(2) << "TestInitialized";
TestInitialized();
VLOG(2) << "TestDataInterface";
TestDataInterface();
}
} // namespace tests
} // namespace paddle
+64
View File
@@ -0,0 +1,64 @@
/* 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 <gtest/gtest.h>
#include <memory>
#include "paddle/phi/api/include/api.h"
#include "paddle/phi/api/lib/utils/allocator.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/kernel_registry.h"
#include "test/cpp/phi/api/scale_api.h"
#include "test/cpp/phi/core/timer.h"
PD_DECLARE_KERNEL(full, CPU, ALL_LAYOUT);
namespace paddle {
namespace tests {
TEST(API, scale) {
auto x = experimental::full({3, 4}, 1.0, phi::DataType::FLOAT32, CPUPlace());
const size_t cycles = 300;
phi::tests::Timer timer;
double t1{}, t2{}, t3{};
for (size_t i = 0; i < cycles; ++i) {
timer.tic();
for (size_t i = 0; i < cycles; ++i) {
auto out = experimental::scale_kernel_context(x, 2.0, 1.0, true);
}
t1 += timer.toc();
timer.tic();
for (size_t i = 0; i < cycles; ++i) {
auto out = experimental::scale(x, 2.0, 1.0, true);
}
t2 += timer.toc();
timer.tic();
for (size_t i = 0; i < cycles; ++i) {
auto out = experimental::scale_switch_case(x, 2.0, 1.0, true);
}
t3 += timer.toc();
}
LOG(INFO) << "The cost of kernel_context is " << t1 << "ms.";
LOG(INFO) << "The cost of variadic_args_kernel_fn is " << t2 << "ms.";
LOG(INFO) << "The cost of switch_case is " << t3 << "ms.";
}
} // namespace tests
} // namespace paddle
+47
View File
@@ -0,0 +1,47 @@
/* 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 <gtest/gtest.h>
#include <memory>
#include "paddle/phi/api/include/api.h"
#include "paddle/phi/api/include/tensor.h"
#include "paddle/phi/core/kernel_registry.h"
PD_DECLARE_KERNEL(full, CPU, ALL_LAYOUT);
namespace paddle {
namespace tests {
TEST(Tensor, slice) {
auto x = paddle::experimental::full({4, 3}, 1, phi::DataType::INT64);
auto slice_x = x.slice(1, 2);
// check slice result
ASSERT_EQ(slice_x.dims().size(), 2);
ASSERT_EQ(slice_x.dims()[0], 1);
ASSERT_EQ(slice_x.dims()[1], 3);
ASSERT_EQ(slice_x.numel(), 3);
ASSERT_EQ(slice_x.is_cpu(), true);
ASSERT_EQ(slice_x.type(), phi::DataType::INT64);
ASSERT_EQ(slice_x.layout(), phi::DataLayout::NCHW);
ASSERT_EQ(slice_x.initialized(), true);
for (int64_t i = 0; i < slice_x.numel(); ++i) {
ASSERT_EQ(slice_x.mutable_data<int64_t>()[i], 1);
}
}
} // namespace tests
} // namespace paddle
@@ -0,0 +1,87 @@
/* Copyright (c) 2022 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 <memory>
#include "paddle/phi/api/include/strings_api.h"
#include "paddle/phi/api/lib/utils/allocator.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/common/backend.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/core/string_tensor.h"
PD_DECLARE_KERNEL(strings_empty, CPU, ALL_LAYOUT);
PD_DECLARE_KERNEL(strings_empty_like, CPU, ALL_LAYOUT);
namespace paddle {
namespace tests {
using phi::CPUPlace;
using phi::StringTensor;
using phi::StringTensorMeta;
TEST(API, strings_empty) {
// 1. create tensor
auto cpu = CPUPlace();
const auto alloc =
std::make_shared<paddle::experimental::DefaultAllocator>(cpu);
auto dense_shape = std::make_shared<phi::DenseTensor>(
alloc.get(),
phi::DenseTensorMeta(
phi::DataType::INT64, common::make_ddim({2}), phi::DataLayout::NCHW));
auto* dev_ctx =
phi::DeviceContextPool::Instance().GetByPlace(phi::CPUPlace());
auto* shape_data = dev_ctx->template Alloc<int64_t>(dense_shape.get());
shape_data[0] = 2;
shape_data[1] = 3;
paddle::Tensor tensor_shape(dense_shape);
// 2. test API
auto empty_out = paddle::experimental::strings::empty(tensor_shape);
// 3. check result
ASSERT_EQ(empty_out.dims().size(), 2);
ASSERT_EQ(empty_out.dims()[0], 2);
ASSERT_EQ(empty_out.dims()[1], 3);
ASSERT_EQ(empty_out.numel(), 6);
}
TEST(API, strings_empty_like) {
auto cpu = CPUPlace();
const auto alloc =
std::make_shared<paddle::experimental::DefaultAllocator>(cpu);
// 1. create tensor
const phi::DDim dims({1, 2});
StringTensorMeta meta(dims);
auto cpu_strings_x = std::make_shared<phi::StringTensor>(
alloc.get(), phi::StringTensorMeta(meta));
// 2. test API
paddle::Tensor x(cpu_strings_x);
auto empty_like_out = paddle::experimental::strings::empty_like(x);
// 3. check result
ASSERT_EQ(empty_like_out.dims().size(), 2);
ASSERT_EQ(empty_like_out.dims()[0], 1);
ASSERT_EQ(empty_like_out.numel(), 2);
}
} // namespace tests
} // namespace paddle
@@ -0,0 +1,147 @@
/* Copyright (c) 2022 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 <memory>
#include "paddle/phi/api/include/strings_api.h"
#include "paddle/phi/api/lib/utils/allocator.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/common/pstring.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/core/string_tensor.h"
PD_DECLARE_KERNEL(strings_lower, CPU, ALL_LAYOUT);
PD_DECLARE_KERNEL(strings_upper, CPU, ALL_LAYOUT);
namespace paddle {
namespace tests {
using phi::CPUPlace;
using phi::StringTensor;
using phi::StringTensorMeta;
TEST(API, case_convert) {
auto cpu = CPUPlace();
const auto alloc =
std::make_shared<paddle::experimental::DefaultAllocator>(cpu);
// 1. create tensor
const phi::DDim dims({1, 2});
StringTensorMeta meta(dims);
auto cpu_strings_x = std::make_shared<phi::StringTensor>(
alloc.get(), phi::StringTensorMeta(meta));
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
auto* dev_ctx = pool.Get(phi::CPUPlace());
pstring* cpu_strings_x_data =
dev_ctx->template Alloc<pstring>(cpu_strings_x.get());
std::string strs[] = {"A Short Pstring.", // NOLINT
"A Large Pstring Whose Length Is Longer Than 22."};
for (int i = 0; i < 2; ++i) {
cpu_strings_x_data[i] = strs[i];
}
// 2. get expected results
std::string expected_results[] = {// NOLINT
strs[0],
strs[0],
strs[1],
strs[1]};
std::transform(
strs[0].begin(), strs[0].end(), expected_results[0].begin(), ::tolower);
std::transform(
strs[0].begin(), strs[0].end(), expected_results[1].begin(), ::toupper);
std::transform(
strs[1].begin(), strs[1].end(), expected_results[2].begin(), ::tolower);
std::transform(
strs[1].begin(), strs[1].end(), expected_results[3].begin(), ::toupper);
// 3. test API, ascii encoding
paddle::Tensor x(cpu_strings_x);
auto lower_out = paddle::experimental::strings::lower(x, false);
auto upper_out = paddle::experimental::strings::upper(x, false);
auto lower_tensor =
std::dynamic_pointer_cast<phi::StringTensor>(lower_out.impl());
auto upper_tensor =
std::dynamic_pointer_cast<phi::StringTensor>(upper_out.impl());
ASSERT_EQ(lower_tensor->dims(), dims);
ASSERT_EQ(upper_tensor->dims(), dims);
auto lower_tensor_ptr = lower_tensor->data();
auto upper_tensor_ptr = upper_tensor->data();
const std::string cpu_results[] = {// NOLINT
lower_tensor_ptr[0].data(),
upper_tensor_ptr[0].data(),
lower_tensor_ptr[1].data(),
upper_tensor_ptr[1].data()};
for (int i = 0; i < 4; ++i) {
ASSERT_EQ(cpu_results[i], expected_results[i]);
}
}
TEST(API, case_convert_utf8) {
auto cpu = CPUPlace();
const auto alloc =
std::make_shared<paddle::experimental::DefaultAllocator>(cpu);
// 1. create tensor
const phi::DDim dims({1, 2});
StringTensorMeta meta(dims);
auto cpu_strings_x = std::make_shared<phi::StringTensor>(
alloc.get(), phi::StringTensorMeta(meta));
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
auto* dev_ctx = pool.Get(phi::CPUPlace());
pstring* cpu_strings_x_data =
dev_ctx->template Alloc<pstring>(cpu_strings_x.get());
std::string strs[] = {"óÓsscHloëË", // NOLINT
"óÓsscHloëËóÓsscHloëËóÓsscHloëË"};
for (int i = 0; i < 2; ++i) {
cpu_strings_x_data[i] = strs[i];
}
// 2. get expected results
std::string expected_results[] = {// NOLINT
"óósschloëë",
"ÓÓSSCHLOËË",
"óósschloëëóósschloëëóósschloëë",
"ÓÓSSCHLOËËÓÓSSCHLOËËÓÓSSCHLOËË"};
// 3. test API, ascii encoding
paddle::Tensor x(cpu_strings_x);
auto lower_out = paddle::experimental::strings::lower(x, true);
auto upper_out = paddle::experimental::strings::upper(x, true);
auto lower_tensor =
std::dynamic_pointer_cast<phi::StringTensor>(lower_out.impl());
auto upper_tensor =
std::dynamic_pointer_cast<phi::StringTensor>(upper_out.impl());
ASSERT_EQ(lower_tensor->dims(), dims);
ASSERT_EQ(upper_tensor->dims(), dims);
auto lower_tensor_ptr = lower_tensor->data();
auto upper_tensor_ptr = upper_tensor->data();
const char* cpu_results[] = {// NOLINT
lower_tensor_ptr[0].data(),
upper_tensor_ptr[0].data(),
lower_tensor_ptr[1].data(),
upper_tensor_ptr[1].data()};
for (int i = 0; i < 4; ++i) {
ASSERT_EQ(std::string(cpu_results[i]), expected_results[i]);
}
}
} // namespace tests
} // namespace paddle
+96
View File
@@ -0,0 +1,96 @@
/* 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 <gtest/gtest.h>
#include <memory>
#include "paddle/phi/api/include/api.h"
#include "paddle/phi/api/lib/utils/allocator.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/kernel_registry.h"
namespace paddle {
namespace tests {
using DDim = phi::DDim;
paddle::Tensor CreateInputTensor() {
const auto alloc =
std::make_unique<paddle::experimental::DefaultAllocator>(phi::CPUPlace());
auto dense_x = std::make_shared<phi::DenseTensor>(
alloc.get(),
phi::DenseTensorMeta(phi::DataType::INT64,
common::make_ddim({3, 4}),
phi::DataLayout::NCHW));
auto* dev_ctx =
phi::DeviceContextPool::Instance().GetByPlace(phi::CPUPlace());
auto* dense_x_data = dev_ctx->template Alloc<int64_t>(dense_x.get());
for (int64_t i = 0; i < 12; ++i) {
dense_x_data[i] = i;
}
return paddle::Tensor(dense_x);
}
void CheckOutputResult(const paddle::Tensor& out) {
ASSERT_EQ(out.dims().size(), 2);
ASSERT_EQ(out.dims()[0], 3);
ASSERT_EQ(out.dims()[1], 4);
ASSERT_EQ(out.is_cpu(), true);
ASSERT_EQ(out.type(), phi::DataType::INT64);
ASSERT_EQ(out.layout(), phi::DataLayout::NCHW);
ASSERT_EQ(out.initialized(), true);
for (int64_t i = 0; i < 12; ++i) {
ASSERT_EQ(out.data<int64_t>()[i], i);
}
}
TEST(API, copy_to) {
// 1. create tensor
auto x = CreateInputTensor();
// 2. test API
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
auto tmp = paddle::experimental::copy_to(x, phi::GPUPlace(), false);
auto out = paddle::experimental::copy_to(tmp, phi::CPUPlace(), true);
#else
auto out = paddle::experimental::copy_to(x, phi::CPUPlace(), false);
#endif
// 3. check result
CheckOutputResult(out);
}
TEST(Tensor, copy_to) {
// 1. create tensor
auto x = CreateInputTensor();
// 2. test API
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
auto tmp = x.copy_to(phi::GPUPlace(), false);
auto out = tmp.copy_to(phi::CPUPlace(), true);
#else
auto out = x.copy_to(phi::CPUPlace(), false);
#endif
// 3. check result
CheckOutputResult(out);
}
} // namespace tests
} // namespace paddle