chore: import upstream snapshot with attribution
This commit is contained in:
@@ -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})
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user