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
+117
View File
@@ -0,0 +1,117 @@
cc_test(
test_custom_kernel
SRCS test_custom_kernel.cc
DEPS phi common)
if(WIN32)
cc_test(
test_dense_tensor
SRCS test_dense_tensor.cc
DEPS type_info common)
else()
cc_test(
test_dense_tensor
SRCS test_dense_tensor.cc
DEPS phi common)
endif()
cc_test(test_intrusive_ptr SRCS test_intrusive_ptr.cc)
cc_test(test_type_info SRCS test_type_info.cc)
if(WIN32)
paddle_test(test_kernel_factory SRCS test_kernel_factory.cc DEPS phi common)
else()
cc_test(
test_kernel_factory
SRCS test_kernel_factory.cc
DEPS phi common)
endif()
cc_test(
test_sparse_coo_tensor
SRCS test_sparse_coo_tensor.cc
DEPS phi common)
cc_test(
test_sparse_csr_tensor
SRCS test_sparse_csr_tensor.cc
DEPS phi common)
cc_test(
test_op_utils
SRCS test_op_utils.cc
DEPS op_compat_infos)
cc_test(
test_meta_fn_utils
SRCS test_meta_fn_utils.cc
DEPS phi common)
if(WIN32)
cc_test(
test_ddim
SRCS test_ddim.cc
DEPS type_info common)
else()
cc_test(
test_ddim
SRCS test_ddim.cc
DEPS phi common)
endif()
if(WITH_GPU)
nv_test(
test_dim
SRCS test_dim.cu
DEPS phi common)
elseif(WITH_ROCM)
hip_test(
test_dim
SRCS test_dim.cu
DEPS phi common)
endif()
cc_test(
selected_rows_test
SRCS test_selected_rows.cc
DEPS phi common)
if(WITH_TESTING AND TEST selected_rows_test)
set_tests_properties(selected_rows_test PROPERTIES TIMEOUT 120)
endif()
if(NOT WIN32)
cc_test(test_rw_lock SRCS test_rw_lock.cc)
endif()
cc_test(
test_string_tensor
SRCS test_string_tensor.cc
DEPS phi common)
cc_test(unroll_array_ops_test SRCS unroll_array_ops_test.cc)
cc_test(
test_tensor_array
SRCS test_tensor_array.cc
DEPS phi common)
if(WITH_GPU)
if(WIN32)
nv_test(
test_mixed_vector
SRCS test_mixed_vector.cc test_mixed_vector.cu
DEPS type_info common tensor)
else()
nv_test(
test_mixed_vector
SRCS test_mixed_vector.cc test_mixed_vector.cu
DEPS phi common tensor)
endif()
elseif(WITH_ROCM)
hip_test(
test_mixed_vector
SRCS test_mixed_vector.cc test_mixed_vector.cu
DEPS phi common tensor)
else()
cc_test(
test_mixed_vector
SRCS test_mixed_vector.cc
DEPS phi common tensor)
endif()
if(NOT WIN32)
paddle_test(test_c_tcp_store SRCS test_tcp_store.cc DEPS phi common)
endif()
if(WITH_XPU)
paddle_test(data_type_transform_test_xpu SRCS data_type_transform_test_xpu.cc)
endif()
+38
View File
@@ -0,0 +1,38 @@
/* 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 <memory>
#include "paddle/phi/core/allocator.h"
namespace phi {
namespace tests {
class FancyAllocator : public phi::Allocator {
public:
static void Delete(Allocation* allocation) {
::operator delete(allocation->ptr());
}
AllocationPtr Allocate(size_t bytes_size) override {
void* data = ::operator new(bytes_size);
auto* allocation = new phi::Allocation(data, bytes_size, phi::CPUPlace());
return AllocationPtr(allocation, Delete);
}
};
} // namespace tests
} // namespace phi
@@ -0,0 +1,219 @@
// Copyright (c) 2025 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/fluid/framework/tensor_util.h"
#include "paddle/phi/core/framework/data_type_transform.h"
#include "paddle/phi/core/kernel_factory.h"
template <typename InT, typename OutT>
void TransformTest(const phi::KernelKey& kernel_type_for_var,
const phi::KernelKey& expected_kernel_type,
const phi::CPUPlace& cpu_place,
const phi::XPUPlace& xpu_place,
const InT* cpu_data,
const int data_number) {
phi::XPUContext context(xpu_place);
phi::DenseTensor in;
phi::DenseTensor in_xpu;
phi::DenseTensor out;
phi::DenseTensor out_xpu;
// copy from cpu_data to cpu tensor
InT* in_ptr =
in.mutable_data<InT>(common::make_ddim({data_number}), cpu_place);
memcpy(in_ptr, cpu_data, sizeof(InT) * data_number);
// test case 1: on xpu
{
// copy from cpu tensor to xpu tensor
paddle::framework::TensorCopy(in, xpu_place, context, &in_xpu);
context.Wait();
// call trans data
phi::TransDataType(
kernel_type_for_var, expected_kernel_type, in_xpu, &out_xpu);
// copy from xpu tensor to cpu tensor
paddle::framework::TensorCopy(out_xpu, cpu_place, context, &out);
context.Wait();
// check result
OutT* out_ptr = out.data<OutT>();
for (int i = 0; i < data_number; ++i) {
EXPECT_EQ(out_ptr[i], static_cast<OutT>(cpu_data[i]));
}
}
// test case 2: on cpu
{
// call trans data
phi::TransDataType(kernel_type_for_var, expected_kernel_type, in, &out);
// check result
OutT* out_ptr = out.data<OutT>();
for (int i = 0; i < data_number; ++i) {
EXPECT_EQ(out_ptr[i], static_cast<OutT>(cpu_data[i]));
}
}
}
TEST(DataTypeTransform, XPUTransform) {
auto cpu_place = phi::CPUPlace();
auto xpu_place = phi::XPUPlace(0);
phi::XPUContext context(xpu_place);
auto kernel_fp16 = phi::KernelKey(
xpu_place, phi::DataLayout::ALL_LAYOUT, phi::DataType::FLOAT16);
auto kernel_fp32 = phi::KernelKey(
xpu_place, phi::DataLayout::ALL_LAYOUT, phi::DataType::FLOAT32);
auto kernel_fp64 = phi::KernelKey(
xpu_place, phi::DataLayout::ALL_LAYOUT, phi::DataType::FLOAT64);
auto kernel_int16 = phi::KernelKey(
xpu_place, phi::DataLayout::ALL_LAYOUT, phi::DataType::INT16);
auto kernel_int32 = phi::KernelKey(
xpu_place, phi::DataLayout::ALL_LAYOUT, phi::DataType::INT32);
auto kernel_int64 = phi::KernelKey(
xpu_place, phi::DataLayout::ALL_LAYOUT, phi::DataType::INT64);
auto kernel_bool = phi::KernelKey(
xpu_place, phi::DataLayout::ALL_LAYOUT, phi::DataType::BOOL);
{
// float16 -> any
phi::dtype::float16 cpu_data[6] = {phi::dtype::float16(0),
phi::dtype::float16(1),
phi::dtype::float16(2),
phi::dtype::float16(3),
phi::dtype::float16(4),
phi::dtype::float16(5)};
TransformTest<phi::dtype::float16, float>(
kernel_fp16, kernel_fp32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<phi::dtype::float16, double>(
kernel_fp16, kernel_fp64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<phi::dtype::float16, int32_t>(
kernel_fp16, kernel_int32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<phi::dtype::float16, int64_t>(
kernel_fp16, kernel_int64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<phi::dtype::float16, bool>(
kernel_fp16, kernel_bool, cpu_place, xpu_place, cpu_data, 6);
}
{
// float -> any
float cpu_data[6] = {0, 1, 2, 3, 4, 5};
TransformTest<float, phi::dtype::float16>(
kernel_fp32, kernel_fp16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<float, float>(
kernel_fp32, kernel_fp32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<float, double>(
kernel_fp32, kernel_fp64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<float, int16_t>(
kernel_fp32, kernel_int16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<float, int32_t>(
kernel_fp32, kernel_int32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<float, int64_t>(
kernel_fp32, kernel_int64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<float, bool>(
kernel_fp32, kernel_bool, cpu_place, xpu_place, cpu_data, 6);
}
{
// double -> any
double cpu_data[6] = {0, 1, 2, 3, 4, 5};
TransformTest<double, phi::dtype::float16>(
kernel_fp64, kernel_fp16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<double, float>(
kernel_fp64, kernel_fp32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<double, double>(
kernel_fp64, kernel_fp64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<double, int16_t>(
kernel_fp64, kernel_int16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<double, int32_t>(
kernel_fp64, kernel_int32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<double, int64_t>(
kernel_fp64, kernel_int64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<double, bool>(
kernel_fp64, kernel_bool, cpu_place, xpu_place, cpu_data, 6);
}
{
// int16 -> any
int16_t cpu_data[6] = {0, 1, 2, 3, 4, 5};
TransformTest<int16_t, phi::dtype::float16>(
kernel_int16, kernel_fp16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int16_t, float>(
kernel_int16, kernel_fp32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int16_t, double>(
kernel_int16, kernel_fp64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int16_t, int16_t>(
kernel_int16, kernel_int16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int16_t, int32_t>(
kernel_int16, kernel_int32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int16_t, int64_t>(
kernel_int16, kernel_int64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int16_t, bool>(
kernel_int16, kernel_bool, cpu_place, xpu_place, cpu_data, 6);
}
{
// int32 -> any
int32_t cpu_data[6] = {0, 1, 2, 3, 4, 5};
TransformTest<int32_t, phi::dtype::float16>(
kernel_int32, kernel_fp16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int32_t, float>(
kernel_int32, kernel_fp32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int32_t, double>(
kernel_int32, kernel_fp64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int32_t, int16_t>(
kernel_int32, kernel_int16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int32_t, int32_t>(
kernel_int32, kernel_int32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int32_t, int64_t>(
kernel_int32, kernel_int64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int32_t, bool>(
kernel_int32, kernel_bool, cpu_place, xpu_place, cpu_data, 6);
}
{
// int64 -> any
int64_t cpu_data[6] = {0, 1, 2, 3, 4, 5};
TransformTest<int64_t, phi::dtype::float16>(
kernel_int64, kernel_fp16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int64_t, float>(
kernel_int64, kernel_fp32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int64_t, double>(
kernel_int64, kernel_fp64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int64_t, int16_t>(
kernel_int64, kernel_int16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int64_t, int32_t>(
kernel_int64, kernel_int32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int64_t, int64_t>(
kernel_int64, kernel_int64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<int64_t, bool>(
kernel_int64, kernel_bool, cpu_place, xpu_place, cpu_data, 6);
}
{
// bool -> any
bool cpu_data[6] = {0, 1, 0, 1, 1, 0};
TransformTest<bool, phi::dtype::float16>(
kernel_bool, kernel_fp16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<bool, float>(
kernel_bool, kernel_fp32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<bool, double>(
kernel_bool, kernel_fp64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<bool, int16_t>(
kernel_bool, kernel_int16, cpu_place, xpu_place, cpu_data, 6);
TransformTest<bool, int32_t>(
kernel_bool, kernel_int32, cpu_place, xpu_place, cpu_data, 6);
TransformTest<bool, int64_t>(
kernel_bool, kernel_int64, cpu_place, xpu_place, cpu_data, 6);
TransformTest<bool, bool>(
kernel_bool, kernel_bool, cpu_place, xpu_place, cpu_data, 6);
}
}
+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. */
#pragma once
#include <random>
#include <type_traits>
namespace phi {
namespace tests {
template <typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value>::type>
class RandomGenerator {
using distribution_type =
typename std::conditional<std::is_integral<T>::value,
std::uniform_int_distribution<T>,
std::uniform_real_distribution<T>>::type;
std::default_random_engine engine;
distribution_type distribution;
public:
auto operator()() -> decltype(distribution(engine)) {
return distribution(engine);
}
};
template <typename Container, typename T = typename Container::value_type>
auto make_generator(Container const&) -> decltype(RandomGenerator<T>()) {
return RandomGenerator<T>();
}
} // namespace tests
} // namespace phi
+303
View File
@@ -0,0 +1,303 @@
/* 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. */
#if defined _WIN32 || defined __APPLE__
#else
#define _LINUX
#endif
#include <gtest/gtest.h>
#ifdef _LINUX
#include "paddle/phi/api/lib/utils/allocator.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/common/int_array.h"
#include "paddle/phi/common/scalar.h"
#include "paddle/phi/core/kernel_context.h"
#include "paddle/phi/core/kernel_factory.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/core/meta_tensor.h"
#include "paddle/phi/infermeta/binary.h"
// user kernel function
namespace custom_kernel {
// Here we use fake_dot for test
// input 3: two Tensors and one std::vector<Tensor>
// attribute 11: fake_attributes
// output 2: one Tensor* and one std::vector<Tensor*>
template <typename T, typename Context>
void FakeDot(const Context& dev_ctx,
const phi::DenseTensor& x,
const phi::DenseTensor& y,
const std::vector<const phi::DenseTensor*>& fake_input_vec,
bool fake_attr_bool,
int fake_attr_int,
float fake_attr_float,
double fake_attr_double,
int64_t fake_attr_int64,
phi::DataType fake_attr_dtype,
const phi::Scalar& fake_attr_scalar,
const phi::IntArray& fake_attr_int_array,
const std::vector<int64_t>& fake_attr_int64_vec,
const std::vector<int>& fake_attr_int_vec,
phi::DenseTensor* out,
std::vector<phi::DenseTensor*> fake_out_vec) {
// print param info
std::cout << "fake_input_vec.size: " << fake_input_vec.size() << std::endl;
std::cout << "fake_attr_bool: " << fake_attr_bool << std::endl;
std::cout << "fake_attr_int: " << fake_attr_int << std::endl;
std::cout << "fake_attr_float: " << fake_attr_float << std::endl;
std::cout << "fake_attr_double: " << fake_attr_double << std::endl;
std::cout << "fake_attr_int64: " << fake_attr_int64 << std::endl;
std::cout << "fake_attr_dtype: " << fake_attr_dtype << std::endl;
std::cout << "fake_attr_int64_vec: " << fake_attr_int64_vec.size()
<< std::endl;
std::cout << "fake_attr_int_vec: " << fake_attr_int_vec.size() << std::endl;
std::cout << "fake_out_vec: " << fake_out_vec.size() << std::endl;
// assert check
assert(fake_input_vec.size() == 2);
assert(fake_attr_bool == false);
assert(fake_attr_int == 1);
assert(fake_attr_float == 2);
assert(fake_attr_double == 3);
assert(fake_attr_int64 == 4);
assert(fake_attr_dtype == phi::DataType::UINT32);
assert(fake_attr_int64_vec.empty());
assert(fake_attr_int_vec.empty());
assert(fake_out_vec.size() == 2);
auto const *x_ptr = x.data<T>(), *x_ptr_ = &x_ptr[0];
auto const *y_ptr = y.data<T>(), *y_ptr_ = &y_ptr[0];
T* z = dev_ctx.template Alloc<T>(out);
auto&& d = x.dims();
auto const N = x.numel();
auto const B = d[d.size() - 1];
for (int j = 0; j < N / B; j++) {
T ss = 0;
for (int i = 0; i < B; i++) ss += (*x_ptr_++) * (*y_ptr_++);
z[j] = ss;
}
}
} // namespace custom_kernel
PD_REGISTER_BUILTIN_KERNEL(fake_dot,
CPU,
ALL_LAYOUT,
custom_kernel::FakeDot,
float,
double,
int,
int64_t,
int8_t,
uint8_t) {}
namespace phi {
namespace tests {
// Upper code will store dot kernels info into OpKernelInfoMap
TEST(CustomKernel, custom_kernel_dot) {
std::string op_name = "fake_dot";
phi::Backend backend = phi::Backend::CPU;
phi::DataLayout layout = phi::DataLayout::ALL_LAYOUT;
// 1.custom kernel info parsed and store
EXPECT_TRUE(phi::CustomKernelMap::Instance().GetMap().find(op_name) !=
phi::CustomKernelMap::Instance().GetMap().end());
auto& custom_kernels = phi::CustomKernelMap::Instance().Kernels();
// 2.info check
EXPECT_EQ(6, static_cast<int>(custom_kernels[op_name].size()));
auto& custom_fake_dot_kernels = custom_kernels[op_name];
EXPECT_TRUE(custom_fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::FLOAT32)) !=
custom_fake_dot_kernels.end());
EXPECT_TRUE(custom_fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::FLOAT64)) !=
custom_fake_dot_kernels.end());
EXPECT_TRUE(custom_fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT32)) !=
custom_fake_dot_kernels.end());
EXPECT_TRUE(custom_fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT64)) !=
custom_fake_dot_kernels.end());
EXPECT_TRUE(custom_fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT8)) !=
custom_fake_dot_kernels.end());
EXPECT_TRUE(custom_fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::UINT8)) !=
custom_fake_dot_kernels.end());
// 3.before register
auto& kernels = phi::KernelFactory::Instance().kernels();
EXPECT_TRUE(kernels.find(op_name) == kernels.end());
// mock fake_dot is supported by phi for check while registering
auto& fake_dot_kernels = kernels[op_name];
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::FLOAT32)) ==
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::FLOAT64)) ==
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT32)) ==
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT64)) ==
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT8)) ==
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::UINT8)) ==
fake_dot_kernels.end());
// register
phi::CustomKernelMap::Instance().RegisterCustomKernels();
EXPECT_EQ(0, static_cast<int>(custom_fake_dot_kernels.size()));
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::FLOAT32)) !=
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::FLOAT64)) !=
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT32)) !=
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT64)) !=
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::INT8)) !=
fake_dot_kernels.end());
EXPECT_TRUE(fake_dot_kernels.find(
phi::KernelKey(backend, layout, phi::DataType::UINT8)) !=
fake_dot_kernels.end());
// 4.kernel select
auto kernel_result = phi::KernelFactory::Instance().SelectKernelOrThrowError(
op_name, phi::KernelKey(backend, layout, phi::DataType::UINT8));
const auto& kernel = kernel_result.kernel;
// 5.prepare parameters for kernel
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::UINT8,
common::make_ddim({2, 3}),
phi::DataLayout::NCHW));
auto* dev_ctx = phi::DeviceContextPool::Instance().Get(phi::CPUPlace());
auto* dense_x_data = dev_ctx->template Alloc<uint8_t>(dense_x.get());
auto dense_y = std::make_shared<phi::DenseTensor>(
alloc.get(),
phi::DenseTensorMeta(phi::DataType::UINT8,
common::make_ddim({2, 3}),
phi::DataLayout::NCHW));
auto* dense_y_data = dev_ctx->template Alloc<uint8_t>(dense_y.get());
// dot x,y and result
std::array<uint8_t, 2> sum = {0, 0};
for (size_t i = 0; i < 2; ++i) {
for (size_t j = 0; j < 3; ++j) {
dense_x_data[i * 3 + j] = (i * 3 + j);
dense_y_data[i * 3 + j] = (i * 3 + j);
sum[i] += (i * 3 + j) * (i * 3 + j);
}
}
// 6.prepare kernel_context
auto kernel_context = phi::KernelContext(dev_ctx);
kernel_context.EmplaceBackInput(dense_x.get()); // idx:0, index:[0,1)
kernel_context.EmplaceBackInput(dense_y.get()); // idx:1, index:[1,2)
// fake_input_vec: idx:2, index:[2,4)
size_t fake_input_vec_idx = 2;
size_t fake_input_vec_index_start = 2;
size_t fake_input_vec_index_end = 4;
kernel_context.EmplaceBackInputWithoutSetRange(dense_x.get());
kernel_context.EmplaceBackInputWithoutSetRange(dense_y.get());
kernel_context.AssignInputRange(
std::make_pair(fake_input_vec_index_start, fake_input_vec_index_end),
fake_input_vec_idx);
bool fake_attr_bool = false;
int fake_attr_int = 1;
float fake_attr_float = 2.0;
double fake_attr_double = 3.0;
int64_t fake_attr_int64 = 4;
phi::DataType fake_attr_dtype = phi::DataType::UINT32;
phi::DenseTensor tmp_tensor;
tmp_tensor.Resize({1});
dev_ctx->template Alloc<uint8_t>(&tmp_tensor);
phi::Scalar fake_attr_scalar{tmp_tensor};
phi::IntArray fake_attr_int_array;
std::vector<int64_t> fake_attr_int64_vec;
std::vector<int> fake_attr_int_vec;
kernel_context.EmplaceBackAttr(fake_attr_bool);
kernel_context.EmplaceBackAttr(fake_attr_int);
kernel_context.EmplaceBackAttr(fake_attr_float);
kernel_context.EmplaceBackAttr(fake_attr_double);
kernel_context.EmplaceBackAttr(fake_attr_int64);
kernel_context.EmplaceBackAttr(fake_attr_dtype);
kernel_context.EmplaceBackAttr(fake_attr_scalar);
kernel_context.EmplaceBackAttr(fake_attr_int_array);
kernel_context.EmplaceBackAttr(fake_attr_int64_vec);
kernel_context.EmplaceBackAttr(fake_attr_int_vec);
auto dense_out = std::make_shared<phi::DenseTensor>();
phi::MetaTensor meta_out(dense_out.get());
phi::DotInferMeta(*dense_x, *dense_y, &meta_out);
kernel_context.EmplaceBackOutput(dense_out.get()); // idx:0 index:[0,1)
// fake_input_vec: idx:1, index:[1,3)
size_t fake_out_vec_idx = 1;
size_t fake_out_vec_index_start = 1;
size_t fake_out_vec_index_end = 3;
kernel_context.EmplaceBackOutputWithoutSetRange(dense_out.get());
kernel_context.EmplaceBackOutputWithoutSetRange(dense_out.get());
kernel_context.AssignOutputRange(
std::make_pair(fake_out_vec_index_start, fake_out_vec_index_end),
fake_out_vec_idx);
// 7.kernel call
kernel(&kernel_context);
// 8.check result
ASSERT_EQ(dense_out->dims().size(), 1);
ASSERT_EQ(dense_out->dims()[0], 2);
ASSERT_EQ(dense_out->numel(), 2);
ASSERT_EQ(dense_out->dtype(), phi::DataType::UINT8);
ASSERT_EQ(dense_out->layout(), phi::DataLayout::NCHW);
ASSERT_EQ(dense_out->initialized(), true);
auto expect_result = sum;
auto actual_result0 = dense_out->data<uint8_t>()[0];
auto actual_result1 = dense_out->data<uint8_t>()[1];
ASSERT_EQ(expect_result[0], actual_result0);
ASSERT_EQ(expect_result[1], actual_result1);
}
} // namespace tests
} // namespace phi
#endif
+136
View File
@@ -0,0 +1,136 @@
// 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 <sstream>
#include "gtest/gtest.h"
#include "paddle/phi/core/ddim.h"
namespace phi {
namespace tests {
TEST(DDim, Equality) {
// default construct ddim
phi::DDim default_ddim;
EXPECT_EQ(arity(default_ddim), -1);
EXPECT_EQ(default_ddim[0], 0);
// construct a zero-DDim
phi::DDim zero_ddim = common::make_ddim({});
EXPECT_EQ(arity(zero_ddim), 0);
EXPECT_EQ(zero_ddim.size(), 0);
EXPECT_EQ(common::product(zero_ddim), 1);
std::vector<int64_t> zero_vec;
phi::DDim zero_ddim1 = common::make_ddim(zero_vec);
EXPECT_EQ(arity(zero_ddim1), 0);
EXPECT_EQ(zero_ddim1.size(), 0);
EXPECT_EQ(common::product(zero_ddim1), 1);
// zero-DDim to vector
std::vector<int64_t> zero_ddim_vec = common::vectorize(zero_ddim);
EXPECT_EQ(zero_ddim_vec.size(), size_t(0));
// reshape zero-DDim
std::vector<int> reshape_vec = {1};
phi::DDim reshape_ddim = zero_ddim.reshape(reshape_vec);
EXPECT_EQ(arity(reshape_ddim), 1);
EXPECT_EQ(reshape_ddim.size(), 1);
EXPECT_EQ(common::product(reshape_ddim), 1);
// construct a DDim from an initialization list
phi::DDim ddim = common::make_ddim({9, 1, 5});
EXPECT_EQ(ddim[0], 9);
EXPECT_EQ(ddim[1], 1);
EXPECT_EQ(ddim[2], 5);
// arity of a DDim
EXPECT_EQ(common::arity(ddim), 3);
EXPECT_EQ(ddim.size(), 3);
// mutate a DDim
ddim[1] = 2;
EXPECT_EQ(ddim[1], 2);
ddim[0] = 6;
EXPECT_EQ(ddim[0], 6);
// construct a DDim from a vector
std::vector<int64_t> vec({9, 1, 5});
phi::DDim vddim = common::make_ddim(vec);
EXPECT_EQ(vddim[0], 9);
EXPECT_EQ(vddim[1], 1);
EXPECT_EQ(vddim[2], 5);
// vectorize a DDim
std::vector<int64_t> res_vec = common::vectorize(vddim);
EXPECT_EQ(res_vec[0], 9);
EXPECT_EQ(res_vec[1], 1);
EXPECT_EQ(res_vec[2], 5);
phi::Dim<3> d(3, 2, 1);
res_vec = common::vectorize(phi::DDim(d));
EXPECT_EQ(res_vec[0], 3);
EXPECT_EQ(res_vec[1], 2);
EXPECT_EQ(res_vec[2], 1);
// product of a DDim
EXPECT_EQ(common::product(vddim), 45);
EXPECT_EQ(common::product(common::make_ddim({3, 2, 5, 3})), 90);
// slice a DDim
phi::DDim ddim2 = common::make_ddim({1, 2, 3, 4, 5, 6});
phi::DDim slice_dim1 = common::slice_ddim(ddim2, 2, 5);
EXPECT_EQ(arity(slice_dim1), 3);
EXPECT_EQ(slice_dim1[0], 3);
EXPECT_EQ(slice_dim1[1], 4);
EXPECT_EQ(slice_dim1[2], 5);
phi::DDim slice_dim2 = common::slice_ddim(ddim2, 0, 6);
EXPECT_EQ(arity(slice_dim2), 6);
EXPECT_EQ(slice_dim2[0], 1);
EXPECT_EQ(slice_dim2[1], 2);
EXPECT_EQ(slice_dim2[2], 3);
EXPECT_EQ(slice_dim2[3], 4);
EXPECT_EQ(slice_dim2[4], 5);
EXPECT_EQ(slice_dim2[5], 6);
phi::DDim slice_dim3 = common::slice_ddim(ddim2, 1, 1);
EXPECT_EQ(arity(slice_dim3), 0);
EXPECT_EQ(slice_dim3.size(), 0);
EXPECT_EQ(common::product(slice_dim3), 1);
}
TEST(DDim, Print) {
// print a DDim
std::stringstream ss1;
phi::DDim ddim = common::make_ddim({2, 3, 4});
ss1 << ddim;
EXPECT_EQ("2, 3, 4", ss1.str());
// print a zero-DDim
std::stringstream ss2;
phi::DDim zero_ddim = common::make_ddim({});
ss2 << zero_ddim;
EXPECT_EQ("", ss2.str());
}
TEST(DDim, Hash) {
// hash a DDim
std::size_t h = 0;
phi::DDim ddim = common::make_ddim({2, 3, 4});
h = std::hash<phi::DDim>()(ddim);
EXPECT_EQ(h, 0xa16fb2b2967ul);
}
} // namespace tests
} // namespace phi
+376
View File
@@ -0,0 +1,376 @@
/* 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/core/dense_tensor.h"
#include "test/cpp/phi/core/allocator.h"
namespace phi {
namespace tests {
TEST(dense_tensor, meta) {
const DDim dims({1, 2});
const DataType dtype{DataType::INT8};
const DataLayout layout{DataLayout::NHWC};
// TODO(Shixiaowei02): need to check the lod is valid.
const LegacyLoD lod{};
DenseTensorMeta meta_0;
PADDLE_ENFORCE_EQ(meta_0.valid(),
false,
common::errors::InvalidArgument(
"Fail in default DenseTensorMeta. Expected "
"meta_0 to be invalid, but got: %s",
meta_0.valid()));
DenseTensorMeta meta_1(dtype, dims);
PADDLE_ENFORCE_EQ(
meta_1.dtype,
dtype,
common::errors::InvalidArgument("Fail in DenseTensorMeta with dtype and "
"dims. Expected dtype: %s, but got: %s",
dtype,
meta_1.dtype));
PADDLE_ENFORCE_EQ(
meta_1.dims,
dims,
common::errors::InvalidArgument("Fail in DenseTensorMeta with dtype and "
"dims. Expected dims: %s, but got: %s",
dims,
meta_1.dims));
PADDLE_ENFORCE_EQ(meta_1.valid(),
true,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype and dims. Expected "
"meta_1 to be valid, but got: %s",
meta_1.valid()));
DenseTensorMeta meta_2(dtype, dims, layout);
PADDLE_ENFORCE_EQ(meta_2.dtype,
dtype,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims and layout. "
"Expected dtype: %s, but got: %s",
dtype,
meta_2.dtype));
PADDLE_ENFORCE_EQ(meta_2.dims,
dims,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims "
"and layout. Expected dims: %s, but got: %s",
dims,
meta_2.dims));
PADDLE_ENFORCE_EQ(meta_2.layout,
layout,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims and layout. "
"Expected layout: %s, but got: %s",
layout,
meta_2.layout));
PADDLE_ENFORCE_EQ(meta_2.valid(),
true,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims and layout. "
"Expected meta_2 to be valid, but got: %s",
meta_2.valid()));
DenseTensorMeta meta_3(dtype, dims, layout, lod);
PADDLE_ENFORCE_EQ(meta_3.dtype,
dtype,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims, layout and "
"lod. Expected dtype: %s, but got: %s",
dtype,
meta_3.dtype));
PADDLE_ENFORCE_EQ(meta_3.dims,
dims,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims, layout and "
"lod. Expected dims: %s, but got: %s",
dims,
meta_3.dims));
PADDLE_ENFORCE_EQ(meta_3.layout,
layout,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims, layout and "
"lod. Expected layout: %s, but got: %s",
layout,
meta_3.layout));
PADDLE_ENFORCE_EQ(meta_3.legacy_lod,
lod,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims, layout and "
"lod. Expected lod: %s, but got: %s",
lod,
meta_3.legacy_lod));
PADDLE_ENFORCE_EQ(meta_3.valid(),
true,
common::errors::InvalidArgument(
"Fail in DenseTensorMeta with dtype, dims, layout and "
"lod. Expected meta_3 to be valid, but got: %s",
meta_3.valid()));
DenseTensorMeta meta_4(meta_3);
PADDLE_ENFORCE_EQ(
meta_4.dtype,
dtype,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected dtype: %s, but got: %s",
dtype,
meta_4.dtype));
PADDLE_ENFORCE_EQ(
meta_4.dims,
dims,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected dims: %s, but got: %s",
dims,
meta_4.dims));
PADDLE_ENFORCE_EQ(
meta_4.layout,
layout,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected layout: %s, but got: %s",
layout,
meta_4.layout));
PADDLE_ENFORCE_EQ(
meta_4.legacy_lod,
lod,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected lod: %s, but got: %s",
lod,
meta_4.legacy_lod));
PADDLE_ENFORCE_EQ(
meta_4.valid(),
true,
common::errors::InvalidArgument("Fail in copy DenseTensorMeta. Expected "
"meta_4 to be valid, but got: %s",
meta_4.valid()));
DenseTensorMeta meta_5(meta_4);
PADDLE_ENFORCE_EQ(
meta_5.dtype,
dtype,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected dtype: %s, but got: %s",
dtype,
meta_5.dtype));
PADDLE_ENFORCE_EQ(
meta_5.dims,
dims,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected dims: %s, but got: %s",
dims,
meta_5.dims));
PADDLE_ENFORCE_EQ(
meta_5.layout,
layout,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected layout: %s, but got: %s",
layout,
meta_5.layout));
PADDLE_ENFORCE_EQ(
meta_5.legacy_lod,
lod,
common::errors::InvalidArgument(
"Fail in copy DenseTensorMeta. Expected lod: %s, but got: %s",
lod,
meta_5.legacy_lod));
PADDLE_ENFORCE_EQ(
meta_5.valid(),
true,
common::errors::InvalidArgument("Fail in copy DenseTensorMeta. Expected "
"meta_5 to be valid, but got: %s",
meta_5.valid()));
}
TEST(dense_tensor, zero_size_strides) {
const auto zero_size_dims = common::make_ddim({0, 2048});
const auto zero_size_strides = DenseTensorMeta::calc_strides(zero_size_dims);
const auto expected_zero_size_strides = common::make_ddim({2048, 1});
EXPECT_EQ(zero_size_strides, expected_zero_size_strides);
DenseTensorMeta zero_size_meta(DataType::FLOAT32, zero_size_dims);
EXPECT_EQ(zero_size_meta.strides, expected_zero_size_strides);
EXPECT_TRUE(zero_size_meta.is_contiguous());
const auto reshaped_zero_size_dims = common::make_ddim({0, 512, 4});
EXPECT_EQ(DenseTensorMeta::calc_strides(reshaped_zero_size_dims),
common::make_ddim({2048, 4, 1}));
const auto unknown_dims = common::make_ddim({-1, 2048});
EXPECT_EQ(DenseTensorMeta::calc_strides(unknown_dims), unknown_dims);
}
TEST(dense_tensor, def_ctor) {
DenseTensor tensor_0;
PADDLE_ENFORCE_EQ(
tensor_0.valid(),
true,
common::errors::InvalidArgument("Fail in default DenseTensor. Expected "
"tensor_0 to be valid, but got: %s",
tensor_0.valid()));
}
TEST(dense_tensor, ctor) {
const DDim dims({1, 2});
const DataType dtype{DataType::INT8};
const DataLayout layout{DataLayout::NHWC};
const LegacyLoD lod{};
DenseTensorMeta meta(dtype, dims, layout, lod);
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto* alloc = fancy_allocator.get();
auto check_dense_tensor = [](const DenseTensor& t,
const DenseTensorMeta& m) -> bool {
bool r{true};
r = r && (t.numel() == product(m.dims));
r = r && (t.dims() == m.dims);
r = r && (t.dtype() == m.dtype);
r = r && (t.layout() == m.layout);
r = r && (t.place() == phi::CPUPlace());
r = r && t.initialized();
r = r && t.IsSharedWith(t);
return r;
};
DenseTensor tensor_0(alloc, meta);
check_dense_tensor(tensor_0, meta);
DenseTensor tensor_1(alloc, DenseTensorMeta(meta));
check_dense_tensor(tensor_0, meta);
}
TEST(dense_tensor, resize) {
const DDim dims({1, 2});
const DataType dtype{DataType::INT8};
const DataLayout layout{DataLayout::NHWC};
const LegacyLoD lod{};
DenseTensorMeta meta(dtype, dims, layout, lod);
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto* alloc = fancy_allocator.get();
DenseTensor tensor_0(alloc, meta);
PADDLE_ENFORCE_EQ(
tensor_0.capacity(),
2u,
common::errors::InvalidArgument(
"Fail to initialize DenseTensor. Expected capacity: 2, but got: %s",
tensor_0.capacity()));
tensor_0.ResizeAndAllocate({1, 2, 3});
PADDLE_ENFORCE_EQ(
tensor_0.capacity(),
6u,
common::errors::InvalidArgument(
"Fail to resize DenseTensor. Expected capacity: 6, but got: %s",
tensor_0.capacity()));
}
TEST(dense_tensor, shallow_copy) {
const DDim dims({1, 2});
const DataType dtype{DataType::INT8};
const DataLayout layout{DataLayout::NHWC};
const LegacyLoD lod{};
DenseTensorMeta meta(dtype, dims, layout, lod);
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto* alloc = fancy_allocator.get();
DenseTensor tensor_0(alloc, meta);
DenseTensor tensor_1(tensor_0);
PADDLE_ENFORCE_EQ(tensor_0.meta(),
tensor_1.meta(),
common::errors::InvalidArgument(
"Fail to copy DenseTensor. Expected tensor_0 and "
"tensor_1 to have the same meta"));
}
TEST(dense_tensor, dim_indexing) {
const DDim dims({4, 3, 2, 0});
const DataType dtype{DataType::INT8};
const DataLayout layout{DataLayout::NHWC};
const LegacyLoD lod{};
DenseTensorMeta meta(dtype, dims, layout, lod);
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto* alloc = fancy_allocator.get();
DenseTensor tensor_0(alloc, meta);
int ndim = tensor_0.dims().size();
auto tensor_0_dims = tensor_0.dims();
for (int i = -ndim; i < ndim; ++i) {
PADDLE_ENFORCE_EQ(
tensor_0_dims[(i + ndim) % ndim],
tensor_0.dims(i),
common::errors::InvalidArgument(
"Dimension mismatch at index %d. Expected: %d, but got: %d",
i,
tensor_0_dims[i],
tensor_0.dims(i)));
}
// throw exception for index >= ndim
bool caught_exception = false;
try {
tensor_0.dims(ndim);
} catch (const common::enforce::EnforceNotMet& error) {
caught_exception = true;
}
PADDLE_ENFORCE_EQ(
caught_exception,
true,
common::errors::InvalidArgument(
"Expected an exception to be thrown for index >= ndim"));
// throw exception for index < -ndim
caught_exception = false;
try {
tensor_0.dims(-ndim - 1);
} catch (const common::enforce::EnforceNotMet& error) {
caught_exception = true;
}
PADDLE_ENFORCE_EQ(
caught_exception,
true,
common::errors::InvalidArgument(
"Expected an exception to be thrown for index < -ndim"));
}
TEST(dense_tensor, storage_properties) {
const DataType dtype{DataType::FLOAT32};
const DDim dims({1, 2});
DenseTensorMeta meta(dtype, dims);
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
DenseTensor tensor(fancy_allocator.get(), meta);
// test error type storage properties
#ifdef PADDLE_WITH_DNNL
bool caught_exception = false;
try {
tensor.storage_properties<OneDNNStorageProperties>();
} catch (common::enforce::EnforceNotMet& error) {
caught_exception = true;
}
PADDLE_ENFORCE_EQ(caught_exception,
true,
common::errors::InvalidArgument(
"Fail to get storage properties. Expected an exception "
"to be thrown for OneDNNStorageProperties"));
#endif
}
} // namespace tests
} // namespace phi
+102
View File
@@ -0,0 +1,102 @@
// 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 <thrust/device_vector.h>
#include <sstream>
#include "gtest/gtest.h"
#include "paddle/common/dim.h"
namespace phi {
namespace tests {
__global__ void test(phi::Dim<2>* o) { o[0] = common::make_dim(5, 6); }
__global__ void dyn_idx_gpu(int64_t* o) {
auto d = common::make_dim(5, 6);
o[0] = d[1];
}
TEST(Dim, Equality) {
// construct a Dim on the CPU
auto a = common::make_dim(3, 4);
EXPECT_EQ(a[0], 3);
EXPECT_EQ(a[1], 4);
// construct a Dim on the GPU
thrust::device_vector<phi::Dim<2>> t(2);
#ifdef PADDLE_WITH_HIP
hipLaunchKernelGGL(
test, dim3(1), dim3(1), 0, 0, thrust::raw_pointer_cast(t.data()));
#else
test<<<1, 1>>>(thrust::raw_pointer_cast(t.data()));
#endif
a = t[0];
EXPECT_EQ(a[0], 5);
EXPECT_EQ(a[1], 6);
// product
EXPECT_EQ(common::product(a), 30);
// mutate a Dim
auto b = common::make_dim(7, 8);
b[1] = 10;
EXPECT_EQ(b[0], 7);
EXPECT_EQ(b[1], 10);
b[0] = 8;
b[1] = 11;
EXPECT_EQ(b[0], 8);
EXPECT_EQ(b[1], 11);
// dynamic access on GPU
thrust::device_vector<int64_t> r(1);
#ifdef PADDLE_WITH_HIP
hipLaunchKernelGGL(
dyn_idx_gpu, dim3(1), dim3(1), 0, 0, thrust::raw_pointer_cast(r.data()));
#else
dyn_idx_gpu<<<1, 1>>>(thrust::raw_pointer_cast(r.data()));
#endif
int64_t res = r[0];
EXPECT_EQ(res, 6);
}
TEST(Dim, Bool) {
auto a = common::make_dim(3, 4);
auto b = common::make_dim(5, 6);
auto c = common::make_dim(3, 4);
// comparison
EXPECT_TRUE(a == a);
EXPECT_FALSE(a == b);
EXPECT_TRUE(a == c);
}
TEST(Dim, Print) {
{
std::stringstream ss;
auto a = common::make_dim(2, 3);
ss << a;
EXPECT_EQ(ss.str(), "2, 3");
}
{
std::stringstream ss;
ss << common::make_dim(8);
EXPECT_EQ(ss.str(), "8");
}
}
} // namespace tests
} // namespace phi
+157
View File
@@ -0,0 +1,157 @@
/* 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 <future>
#include <vector>
#include "gtest/gtest.h"
#include "paddle/phi/core/utils/intrusive_ptr.h"
#include "paddle/phi/core/utils/intrusive_ref_counter.h"
namespace phi {
namespace tests {
struct SharedObject : public intrusive_ref_counter<SharedObject> {
int i{0};
};
TEST(intrusive_ref_counter, async) {
SharedObject obj;
const size_t num{100};
std::vector<std::future<void>> results;
auto add_ref_and_release = [](const SharedObject* p) {
intrusive_ptr_add_ref<SharedObject>(p);
intrusive_ptr_release<SharedObject>(p);
};
for (size_t i = 0; i < num; ++i) {
results.emplace_back(std::async(add_ref_and_release, &obj));
}
for (auto& result : results) {
result.get();
}
PADDLE_ENFORCE_EQ(obj.use_count(),
1U,
common::errors::InvalidArgument(
"Required obj.use_count() should be equal to 1, "
"But received obj.use_count() = %d.",
obj.use_count()));
}
TEST(intrusive_ptr, default_ctor) {
intrusive_ptr<SharedObject> p;
PADDLE_ENFORCE_EQ(p == nullptr,
true,
common::errors::Fatal("Input pointer is not a nullptr"));
}
TEST(intrusive_ptr, private_ctor) {
auto p = make_intrusive<SharedObject>();
const auto* ptr0 = p.get();
auto p1 = std::move(p);
intrusive_ptr<intrusive_ref_counter<SharedObject>> p2(std::move(p1));
const auto* ptr1 = p2.get();
PADDLE_ENFORCE_EQ(ptr0,
ptr1,
common::errors::InvalidArgument(
"Required ptr0 should be equal to ptr1. "));
}
TEST(intrusive_ptr, reset_with_obj) {
SharedObject obj;
obj.i = 1;
intrusive_ptr<SharedObject> p;
p.reset(&obj, true);
PADDLE_ENFORCE_EQ(p->i,
obj.i,
common::errors::InvalidArgument(
"Required p->i should be equal to obj.i. "));
}
TEST(intrusive_ptr, reset_with_ptr) {
auto* ptr = new SharedObject;
ptr->i = 1;
intrusive_ptr<SharedObject> p;
p.reset(ptr, false);
PADDLE_ENFORCE_EQ((*p).i,
ptr->i,
common::errors::InvalidArgument(
"Required (*p).i should be equal to ptr->i. "));
p.reset();
PADDLE_ENFORCE_EQ(
p == nullptr,
true,
common::errors::Fatal(
"p is not a nullptr, something wrong with intrusive_ptr<T>.reset"));
}
TEST(intrusive_ptr, op_comp) {
auto p = make_intrusive<SharedObject>();
auto copy = copy_intrusive<SharedObject>(p);
auto null = intrusive_ptr<SharedObject>();
auto p1 = make_intrusive<SharedObject>();
PADDLE_ENFORCE_EQ(p == copy,
true,
common::errors::Fatal(
"intrusive_ptr p is not equal to its copy, something "
"wrong with copy constructor "));
PADDLE_ENFORCE_EQ(
p != p1,
true,
common::errors::Fatal("intrusive_ptr p is equal to another pointer, "
"something wrong with constructor"));
PADDLE_ENFORCE_EQ(
p == copy.get(),
true,
common::errors::Fatal(
"blank intrusive_ptr p's content is not equal to its copy, something "
"wrong with constructor or get function"));
PADDLE_ENFORCE_EQ(
p != p1.get(),
true,
common::errors::Fatal(
"intrusive_ptr p's content is equal to another blank pointer, "
"something wrong with constructor or get function"));
PADDLE_ENFORCE_EQ(
p.get() == copy,
true,
common::errors::Fatal(
"blank intrusive_ptr p's content is not equal to its copy, something "
"wrong with constructor or get function"));
PADDLE_ENFORCE_EQ(
p.get() != p1,
true,
common::errors::Fatal(
"intrusive_ptr p's content is equal to another blank pointer, "
"something wrong with constructor or get function"));
PADDLE_ENFORCE_EQ(
null == nullptr,
true,
common::errors::Fatal("variable or constant whose name is null is not a "
"nullptr, something wrong with operator=="));
PADDLE_ENFORCE_EQ(
nullptr == null,
true,
common::errors::Fatal("variable or constant whose name is null is not a "
"nullptr, something wrong with operator=="));
PADDLE_ENFORCE_EQ(p != nullptr,
true,
common::errors::Fatal(
"intrusive_ptr p is not not_equal to null, something "
"wrong with constructor or operator!= "));
PADDLE_ENFORCE_EQ(nullptr != p,
true,
common::errors::Fatal(
"intrusive_ptr p is not not_equal to null, something "
"wrong with constructor or operator!= "));
}
} // namespace tests
} // namespace phi
+149
View File
@@ -0,0 +1,149 @@
/* 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 <sstream>
#include "gtest/gtest.h"
#include "paddle/phi/common/float16.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/kernel_factory.h"
#include "paddle/phi/core/kernel_registry.h"
PD_DECLARE_KERNEL(scale, CPU, ALL_LAYOUT);
namespace phi {
namespace tests {
// TODO(chenweihang): add more unittests later
TEST(KernelKey, ConstructAndOStream) {
phi::KernelKey key(
phi::Backend::CPU, phi::DataLayout::NCHW, phi::DataType::FLOAT32);
EXPECT_EQ(key.backend(), phi::Backend::CPU);
EXPECT_EQ(key.layout(), phi::DataLayout::NCHW);
EXPECT_EQ(key.dtype(), phi::DataType::FLOAT32);
std::ostringstream oss;
oss << key;
std::cout << oss.str();
oss.flush();
}
TEST(KernelFactory, SelectedKernelMap) {
auto kernel_map = phi::KernelFactory::Instance().SelectKernelMap("scale");
EXPECT_GT(kernel_map.size(), 1UL);
for (auto& iter : kernel_map) {
std::cout << iter.first << ": " << iter.second;
}
}
template <typename T, typename Context>
void TestKernel(const Context& dev_ctx,
const DenseTensor& x,
const DenseTensor& param,
DenseTensor* out) {}
TEST(KernelRegistry, SetFP32Input) {
phi::KernelKey kernel_key(
phi::Backend::CPU, phi::DataLayout::ALL_LAYOUT, phi::DataType::FLOAT16);
auto test_kernel =
phi::KernelFactory::Instance().SelectKernel("test", kernel_key);
EXPECT_TRUE(test_kernel.IsValid());
auto& arg_defs = test_kernel.args_def();
auto& input_defs = arg_defs.input_defs();
auto& attr_defs = arg_defs.attribute_defs();
auto& output_defs = arg_defs.output_defs();
EXPECT_EQ(input_defs.size(), 2UL);
EXPECT_EQ(attr_defs.size(), 0UL);
EXPECT_EQ(output_defs.size(), 1UL);
EXPECT_EQ(input_defs.at(0).dtype, phi::DataType::FLOAT16);
EXPECT_EQ(input_defs.at(1).dtype, phi::DataType::FLOAT32);
EXPECT_EQ(output_defs.at(0).dtype, phi::DataType::FLOAT16);
}
TEST(AttributeType, OStream) {
std::ostringstream oss;
oss << phi::AttributeType::UNDEFINED;
EXPECT_EQ(oss.str(), "Undefined");
oss.str("");
oss << phi::AttributeType::BOOL;
EXPECT_EQ(oss.str(), "bool");
oss.str("");
oss << phi::AttributeType::INT32;
EXPECT_EQ(oss.str(), "int");
oss.str("");
oss << phi::AttributeType::INT64;
EXPECT_EQ(oss.str(), "int64_t");
oss.str("");
oss << phi::AttributeType::FLOAT32;
EXPECT_EQ(oss.str(), "float");
oss.str("");
oss << phi::AttributeType::FLOAT64;
EXPECT_EQ(oss.str(), "double");
oss.str("");
oss << phi::AttributeType::STRING;
EXPECT_EQ(oss.str(), "string");
oss.str("");
oss << phi::AttributeType::BOOLS;
EXPECT_EQ(oss.str(), "vector<bool>");
oss.str("");
oss << phi::AttributeType::INT32S;
EXPECT_EQ(oss.str(), "vector<int>");
oss.str("");
oss << phi::AttributeType::INT64S;
EXPECT_EQ(oss.str(), "vector<int64_t>");
oss.str("");
oss << phi::AttributeType::FLOAT32S;
EXPECT_EQ(oss.str(), "vector<float>");
oss.str("");
oss << phi::AttributeType::FLOAT64S;
EXPECT_EQ(oss.str(), "vector<double>");
oss.str("");
oss << phi::AttributeType::STRINGS;
EXPECT_EQ(oss.str(), "vector<string>");
oss.str("");
oss << phi::AttributeType::SCALAR;
EXPECT_EQ(oss.str(), "Scalar");
oss.str("");
oss << phi::AttributeType::SCALARS;
EXPECT_EQ(oss.str(), "vector<Scalar>");
oss.str("");
oss << phi::AttributeType::INT_ARRAY;
EXPECT_EQ(oss.str(), "IntArray");
oss.str("");
oss << phi::AttributeType::DATA_TYPE;
EXPECT_EQ(oss.str(), "DataType");
oss.str("");
oss << phi::AttributeType::DATA_LAYOUT;
EXPECT_EQ(oss.str(), "DataLayout");
oss.str("");
oss << phi::AttributeType::PLACE;
EXPECT_EQ(oss.str(), "Place");
oss.str("");
}
} // namespace tests
} // namespace phi
PD_REGISTER_KERNEL(test,
CPU,
ALL_LAYOUT,
phi::tests::TestKernel,
float,
double,
phi::dtype::float16) {
if (kernel_key.dtype() == phi::DataType::FLOAT16) {
kernel->InputAt(1).SetDataType(phi::DataType::FLOAT32);
}
}
+50
View File
@@ -0,0 +1,50 @@
/* 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 <iostream>
#include "gtest/gtest.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/infermeta_utils.h"
#include "paddle/phi/infermeta/unary.h"
namespace phi {
namespace tests {
TEST(MetaFnFactory, InferMetaFnExists) {
phi::DenseTensor dense_x;
dense_x.Resize(common::make_ddim({3, 4}));
phi::MetaTensor meta_x(&dense_x);
phi::DenseTensor dense_out1;
phi::MetaTensor meta_out(&dense_out1);
phi::UnchangedInferMeta(meta_x, &meta_out);
}
void TestEmptyVectorInputInferMeta(const std::vector<const MetaTensor*>& inputs,
std::vector<MetaTensor*> outputs) {
ASSERT_EQ(inputs.size(), 0UL);
ASSERT_EQ(outputs.size(), 0UL);
}
TEST(MetaFnFactory, EmptyVectorInputInferMetaFn) {
phi::InferMetaContext ctx;
ctx.EmplaceBackInput(MetaTensor());
ctx.EmplaceBackOutput(MetaTensor());
PD_INFER_META(TestEmptyVectorInputInferMeta)(&ctx);
}
} // namespace tests
} // namespace phi
+74
View File
@@ -0,0 +1,74 @@
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/phi/core/mixed_vector.h"
#include "glog/logging.h"
#include "gtest/gtest-message.h"
#include "gtest/gtest-test-part.h"
#include "gtest/gtest.h"
#include "gtest/gtest_pred_impl.h"
template <typename T>
using vec = phi::Vector<T>;
TEST(mixed_vector, CPU_VECTOR) {
vec<int> tmp;
for (int i = 0; i < 10; ++i) {
tmp.push_back(i);
}
ASSERT_EQ(tmp.size(), 10UL);
vec<int> tmp2;
tmp2 = tmp;
ASSERT_EQ(tmp2.size(), 10UL);
for (int i = 0; i < 10; ++i) {
ASSERT_EQ(tmp2[i], i);
ASSERT_EQ(tmp2[i], tmp[i]);
}
int cnt = 0;
for (auto& t : tmp2) {
ASSERT_EQ(t, cnt);
++cnt;
}
}
TEST(mixed_vector, InitWithCount) {
phi::Vector<int> vec(10, 10);
for (int i = 0; i < 10; ++i) {
ASSERT_EQ(vec[i], 10);
}
}
TEST(mixed_vector, ForEach) {
vec<int> tmp;
for (auto& v : tmp) {
VLOG(3) << v;
}
}
TEST(mixed_vector, Reserve) {
phi::Vector<int> vec;
vec.reserve(1);
vec.push_back(0);
vec.push_back(0);
vec.push_back(0);
}
TEST(mixed_vector, Resize) {
phi::Vector<int> vec;
vec.resize(1);
vec.push_back(0);
vec.push_back(0);
vec.push_back(0);
}
+111
View File
@@ -0,0 +1,111 @@
/* Copyright (c) 2016 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. */
#ifdef PADDLE_WITH_CUDA
#include <cuda_runtime.h>
#endif
#ifdef PADDLE_WITH_HIP
#include <hip/hip_runtime.h>
#endif
#include <memory>
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/backends/gpu/gpu_info.h"
#include "paddle/phi/common/place.h"
#include "paddle/phi/core/mixed_vector.h"
template <typename T>
using vec = phi::MixVector<T>;
using gpuStream_t = phi::gpuStream_t;
static __global__ void multiply_10(int* ptr) {
for (int i = 0; i < 10; ++i) {
ptr[i] *= 10;
}
}
gpuStream_t GetCUDAStream(phi::GPUPlace place) {
return reinterpret_cast<const phi::GPUContext*>(
phi::DeviceContextPool::Instance().Get(place))
->stream();
}
TEST(mixed_vector, GPU_VECTOR) {
std::vector<int> x;
for (int i = 0; i < 10; ++i) {
x.push_back(i);
}
vec<int> tmp(&x);
ASSERT_EQ(tmp.size(), 10UL);
phi::GPUPlace gpu(0);
#ifdef PADDLE_WITH_HIP
hipLaunchKernelGGL(multiply_10,
dim3(1),
dim3(1),
0,
GetCUDAStream(gpu),
tmp.MutableData(gpu));
#else
multiply_10<<<1, 1, 0, GetCUDAStream(gpu)>>>(tmp.MutableData(gpu));
#endif
for (int i = 0; i < 10; ++i) {
ASSERT_EQ(tmp[i], i * 10);
}
}
TEST(mixed_vector, MultiGPU) {
if (phi::backends::gpu::GetGPUDeviceCount() < 2) {
LOG(WARNING) << "Skip mixed_vector.MultiGPU since there are not multiple "
"GPUs in your machine.";
return;
}
std::vector<int> x;
for (int i = 0; i < 10; ++i) {
x.push_back(i);
}
vec<int> tmp(&x);
ASSERT_EQ(tmp.size(), 10UL);
phi::GPUPlace gpu0(0);
phi::backends::gpu::SetDeviceId(0);
#ifdef PADDLE_WITH_HIP
hipLaunchKernelGGL(multiply_10,
dim3(1),
dim3(1),
0,
GetCUDAStream(gpu0),
tmp.MutableData(gpu0));
#else
multiply_10<<<1, 1, 0, GetCUDAStream(gpu0)>>>(tmp.MutableData(gpu0));
#endif
phi::GPUPlace gpu1(1);
auto* gpu1_ptr = tmp.MutableData(gpu1);
phi::backends::gpu::SetDeviceId(1);
#ifdef PADDLE_WITH_HIP
hipLaunchKernelGGL(
multiply_10, dim3(1), dim3(1), 0, GetCUDAStream(gpu1), gpu1_ptr);
#else
multiply_10<<<1, 1, 0, GetCUDAStream(gpu1)>>>(gpu1_ptr);
#endif
for (int i = 0; i < 10; ++i) {
ASSERT_EQ(tmp[i], i * 100);
}
}
+32
View File
@@ -0,0 +1,32 @@
/* 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 "gtest/gtest.h"
#include "paddle/fluid/operators/ops_signature/signatures.h"
#include "paddle/phi/core/compat/op_utils.h"
namespace phi {
namespace tests {
TEST(OpUtilsMap, ArgMappingFnExists) {
std::cout << "enter ArgMappingFnExists";
auto scale_arg_mapping_fn =
phi::OpUtilsMap::Instance().GetArgumentMappingFn("scale");
EXPECT_NE(scale_arg_mapping_fn, nullptr);
}
} // namespace tests
} // namespace phi
+84
View File
@@ -0,0 +1,84 @@
/* 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> // NOLINT
#include <thread> // NOLINT
#include "paddle/phi/core/utils/rw_lock.h"
namespace phi {
namespace tests {
void f1(phi::RWLock *lock) {
lock->RDLock();
lock->UNLock();
}
TEST(RWLOCK, read_read) {
phi::RWLock lock;
lock.RDLock();
std::thread t1(f1, &lock);
std::thread t2(f1, &lock);
t1.join();
t2.join();
lock.UNLock();
}
void f2(phi::RWLock *lock, std::vector<int> *result) {
lock->RDLock();
ASSERT_EQ(result->size(), 0UL);
lock->UNLock();
}
void f3(phi::RWLock *lock, std::vector<int> *result) {
lock->WRLock();
result->push_back(1);
lock->UNLock();
}
TEST(RWLOCK, read_write) {
phi::RWLock lock;
std::vector<int> result;
lock.RDLock();
std::thread t1(f2, &lock, &result);
t1.join();
std::thread t2(f3, &lock, &result);
std::this_thread::sleep_for(std::chrono::seconds(1));
ASSERT_EQ(result.size(), 0UL);
lock.UNLock();
t2.join();
ASSERT_EQ(result.size(), 1UL);
}
void f4(phi::RWLock *lock, std::vector<int> *result) {
lock->RDLock();
ASSERT_EQ(result->size(), 1UL);
lock->UNLock();
}
TEST(RWLOCK, write_read) {
phi::RWLock lock;
std::vector<int> result;
lock.WRLock();
std::thread t1(f4, &lock, &result);
std::this_thread::sleep_for(std::chrono::seconds(1));
result.push_back(1);
lock.UNLock();
t1.join();
}
} // namespace tests
} // namespace phi
+185
View File
@@ -0,0 +1,185 @@
/* 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 <ctime>
#include <thread> // NOLINT
#include "gtest/gtest.h"
#include "paddle/phi/core/selected_rows.h"
namespace phi {
namespace tests {
class SelectedRowsTester : public ::testing::Test {
public:
void SetUp() override {
std::vector<int64_t> rows{0, 4, 7};
int64_t height = 10;
int64_t row_numel = 100;
selected_rows_ = std::make_unique<SelectedRows>(rows, height);
phi::DenseTensor* value = selected_rows_->mutable_value();
auto* data = value->mutable_data<float>(
common::make_ddim({static_cast<int64_t>(rows.size()), row_numel}),
place_);
for (int64_t i = 0; i < value->numel(); ++i) {
data[i] = static_cast<float>(i);
}
}
protected:
phi::CPUPlace place_;
std::unique_ptr<phi::SelectedRows> selected_rows_{nullptr};
};
TEST_F(SelectedRowsTester, height) { ASSERT_EQ(selected_rows_->height(), 10); }
TEST_F(SelectedRowsTester, dims) {
ASSERT_EQ(selected_rows_->value().dims(), common::make_ddim({3, 100}));
}
TEST_F(SelectedRowsTester, complete_dims) {
ASSERT_EQ(selected_rows_->GetCompleteDims(), common::make_ddim({10, 100}));
}
TEST(SelectedRows, SparseTable) {
phi::CPUPlace cpu;
SelectedRows table;
int64_t table_size = 100;
int64_t embedding_width = 8;
// initialize a sparse table
table.mutable_value()->Resize(
common::make_ddim({table_size, embedding_width}));
auto* data = table.mutable_value()->mutable_data<float>(cpu);
for (int64_t i = 0; i < table_size; ++i) {
for (int64_t j = 0; j < embedding_width; ++j) {
data[i * embedding_width + j] = static_cast<float>(i);
}
}
ASSERT_EQ(table.AutoGrownIndex(10, true, false), 0);
ASSERT_EQ(table.AutoGrownIndex(8, true, false), 1);
ASSERT_EQ(table.AutoGrownIndex(8, true, false), 1);
ASSERT_EQ(table.AutoGrownIndex(6, true, false), 2);
for (int64_t i = 11; i < 20; i++) {
ASSERT_EQ(table.AutoGrownIndex(i, true, true), -1);
ASSERT_TRUE(!table.HasKey(i));
}
ASSERT_TRUE(table.HasKey(10));
ASSERT_TRUE(table.HasKey(8));
ASSERT_TRUE(table.HasKey(6));
ASSERT_EQ(table.rows().size(), 3UL);
phi::DenseTensor ids;
ids.Resize(common::make_ddim({4}));
auto* ids_data = ids.mutable_data<int64_t>(cpu);
ids_data[0] = static_cast<int64_t>(6);
ids_data[1] = static_cast<int64_t>(6);
ids_data[2] = static_cast<int64_t>(8);
ids_data[3] = static_cast<int64_t>(10);
phi::DenseTensor get_value;
auto* value_data = get_value.mutable_data<float>(
common::make_ddim({4, embedding_width}), cpu);
table.Get(ids, &get_value);
for (int j = 0; j < embedding_width; ++j) {
ASSERT_EQ(value_data[0 * embedding_width + j], 2);
}
for (int j = 0; j < embedding_width; ++j) {
ASSERT_EQ(value_data[1 * embedding_width + j], 2);
}
for (int j = 0; j < embedding_width; ++j) {
ASSERT_EQ(value_data[2 * embedding_width + j], 1);
}
for (int j = 0; j < embedding_width; ++j) {
ASSERT_EQ(value_data[3 * embedding_width + j], 0);
}
}
void f1(SelectedRows* table, int table_size) {
for (int i = 1000000; i > 0; --i) {
auto id = i % table_size;
int64_t index1 = table->AutoGrownIndex(id, true);
int64_t index2 = table->AutoGrownIndex(id, false);
int64_t index3 = table->AutoGrownIndex(id, true);
ASSERT_EQ(index1, index2);
ASSERT_EQ(index2, index3);
}
}
void f2(SelectedRows* table, int table_size) {
for (int i = 0; i < 1000000; ++i) {
auto id = i % table_size;
int64_t index1 = table->AutoGrownIndex(id, true);
int64_t index2 = table->AutoGrownIndex(id, false);
int64_t index3 = table->AutoGrownIndex(id, true);
ASSERT_EQ(index1, index2);
ASSERT_EQ(index2, index3);
}
}
void f3(SelectedRows* table, int table_size) {
clock_t t1 = clock();
for (int i = 100000; i > 0; --i) {
auto id1 = table->AutoGrownIndex(i % table_size, true);
auto id2 = table->Index(i % table_size);
ASSERT_EQ(id1, id2);
}
clock_t t2 = clock();
std::cout << "f3 run time:" << t2 - t1 << std::endl;
}
void f4(SelectedRows* table, int table_size) {
clock_t t1 = clock();
for (int i = 0; i < 100000; ++i) {
auto id1 = table->AutoGrownIndex(i % table_size, true);
auto id2 = table->Index(i % table_size);
ASSERT_EQ(id1, id2);
}
clock_t t2 = clock();
std::cout << "f4 run time:" << t2 - t1 << std::endl;
}
TEST(SelectedRows, MultiThreadAutoIndex) {
phi::CPUPlace cpu;
SelectedRows table;
int64_t table_size = 100000;
int64_t embedding_width = 8;
// initialize a sparse table
table.mutable_value()->Resize(
common::make_ddim({table_size, embedding_width}));
auto* data = table.mutable_value()->mutable_data<float>(cpu);
for (int64_t i = 0; i < table_size; ++i) {
for (int64_t j = 0; j < embedding_width; ++j) {
data[i * embedding_width + j] = static_cast<float>(i);
}
}
std::thread t1(f1, &table, table_size);
std::thread t11(f1, &table, table_size);
std::thread t2(f2, &table, table_size);
std::thread t22(f2, &table, table_size);
t1.join();
t11.join();
t2.join();
t22.join();
std::thread t3(f3, &table, table_size);
std::thread t4(f4, &table, table_size);
t3.join();
t4.join();
}
} // namespace tests
} // namespace phi
+114
View File
@@ -0,0 +1,114 @@
/* 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/core/dense_tensor.h"
#include "paddle/phi/core/sparse_coo_tensor.h"
#include "test/cpp/phi/core/allocator.h"
namespace phi {
namespace tests {
TEST(sparse_coo_tensor, construct) {
phi::CPUPlace cpu;
auto dense_dims = common::make_ddim({3, 3});
std::vector<float> non_zero_data = {1.0, 2.0, 3.0};
std::vector<int64_t> indices_data = {0, 1, 2, 0, 2, 1};
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto* alloc = fancy_allocator.get();
auto indices_dims =
common::make_ddim({2, static_cast<int>(non_zero_data.size())});
DenseTensorMeta indices_meta(DataType::INT64, indices_dims, DataLayout::NCHW);
DenseTensor indices(alloc, indices_meta);
memcpy(indices.mutable_data<int64_t>(cpu),
&indices_data[0],
indices_data.size() * sizeof(int64_t));
auto elements_dims =
common::make_ddim({static_cast<int>(non_zero_data.size())});
DenseTensorMeta elements_meta(
DataType::FLOAT32, elements_dims, DataLayout::NCHW);
DenseTensor elements(alloc, elements_meta);
memcpy(elements.mutable_data<float>(cpu),
&non_zero_data[0],
non_zero_data.size() * sizeof(float));
SparseCooTensor sparse(indices, elements, dense_dims);
CHECK(sparse.initialized() == true);
PADDLE_ENFORCE_EQ(
sparse.nnz(),
non_zero_data.size(),
common::errors::InvalidArgument(
"Required sparse.nnz() should be equal to non_zero_data.size(). "));
PADDLE_ENFORCE_EQ(sparse.numel(),
9,
common::errors::InvalidArgument(
"Required sparse.numel() should be equal to 9. "));
CHECK(sparse.dims() == dense_dims);
CHECK(sparse.dtype() == DataType::FLOAT32);
CHECK(sparse.place() == phi::CPUPlace());
}
TEST(sparse_coo_tensor, other_function) {
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto* alloc = fancy_allocator.get();
auto dense_dims = common::make_ddim({4, 4});
const int non_zero_num = 2;
auto indices_dims = common::make_ddim({2, non_zero_num});
DenseTensorMeta indices_meta(DataType::INT64, indices_dims, DataLayout::NCHW);
DenseTensor indices(alloc, indices_meta);
auto elements_dims = common::make_ddim({non_zero_num});
DenseTensorMeta elements_meta(
DataType::FLOAT32, elements_dims, DataLayout::NCHW);
DenseTensor elements(alloc, elements_meta);
SparseCooTensor coo(indices, elements, dense_dims);
CHECK(coo.initialized());
PADDLE_ENFORCE_EQ(coo.dims(),
dense_dims,
common::errors::InvalidArgument(
"Required coo.dims() should be equal to dense_dims. "));
// Test Resize
auto dense_dims_3d = common::make_ddim({2, 4, 4});
coo.Resize(dense_dims_3d, 1, 3);
PADDLE_ENFORCE_EQ(coo.nnz(),
3,
common::errors::InvalidArgument(
"Required coo.nnz() should be equal to 3. "));
// Test shallow_copy
SparseCooTensor coo2(coo);
PADDLE_ENFORCE_EQ(
coo.dims(),
coo2.dims(),
common::errors::Fatal("`coo.dims()` is not equal to `coo2.dims()`, "
"something wrong with shallow copy assignment"));
// Test shallow_copy_assignment
SparseCooTensor coo3 = coo2;
CHECK(coo3.dims() == coo2.dims());
PADDLE_ENFORCE_EQ(
coo3.dims(),
coo2.dims(),
common::errors::Fatal("`coo3.dims()` is not equal to `coo2.dims()`, "
"something wrong with shallow copy assignment"));
}
} // namespace tests
} // namespace phi
+125
View File
@@ -0,0 +1,125 @@
/* 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/lib/utils/allocator.h"
#include "paddle/phi/core/dense_tensor.h"
#include "paddle/phi/core/sparse_csr_tensor.h"
#include "test/cpp/phi/core/allocator.h"
namespace phi {
namespace tests {
TEST(sparse_csr_tensor, construct) {
phi::CPUPlace cpu;
auto dense_dims = common::make_ddim({3, 3});
std::vector<float> non_zero_data = {1.0, 2.0, 3.0};
std::vector<int64_t> crows_data = {0, 1, 1, 3};
std::vector<int64_t> cols_data = {1, 0, 2};
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto alloc = fancy_allocator.get();
// create non_zero_crows
auto crows_dims = common::make_ddim({static_cast<int>(crows_data.size())});
DenseTensorMeta crows_meta(DataType::INT64, crows_dims, DataLayout::NCHW);
DenseTensor crows(alloc, crows_meta);
memcpy(crows.mutable_data<int64_t>(cpu),
&crows_data[0],
crows_data.size() * sizeof(int64_t));
// create non_zero_cols
auto cols_dims = common::make_ddim({static_cast<int>(cols_data.size())});
DenseTensorMeta cols_meta(DataType::INT64, cols_dims, DataLayout::NCHW);
DenseTensor cols(alloc, cols_meta);
memcpy(cols.mutable_data<int64_t>(cpu),
&cols_data[0],
cols_data.size() * sizeof(int64_t));
// create non_zero_elements
auto elements_dims =
common::make_ddim({static_cast<int>(non_zero_data.size())});
DenseTensorMeta elements_meta(
DataType::FLOAT32, elements_dims, DataLayout::NCHW);
DenseTensor elements(alloc, elements_meta);
memcpy(elements.mutable_data<float>(cpu),
&non_zero_data[0],
non_zero_data.size() * sizeof(float));
SparseCsrTensor sparse(crows, cols, elements, dense_dims);
PADDLE_ENFORCE_EQ(sparse.non_zero_cols().numel(),
non_zero_data.size(),
common::errors::InvalidArgument(
"Required sparse.non_zero_cols().numel() should be "
"equal to non_zero_data.size(). "));
PADDLE_ENFORCE_EQ(sparse.numel(),
9,
common::errors::InvalidArgument(
"Required sparse.numel() should be equal to 9. "));
CHECK(sparse.dims() == dense_dims);
CHECK(sparse.dtype() == DataType::FLOAT32);
CHECK(sparse.place() == phi::CPUPlace());
CHECK(sparse.initialized() == true);
}
TEST(sparse_csr_tensor, other_function) {
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto alloc = fancy_allocator.get();
auto dense_dims = common::make_ddim({4, 4});
auto crows_dims = common::make_ddim({dense_dims[0] + 1});
DenseTensorMeta crows_meta(DataType::INT64, crows_dims, DataLayout::NCHW);
DenseTensor crows(alloc, crows_meta);
const int64_t non_zero_num = 5;
auto cols_dims = common::make_ddim({non_zero_num});
DenseTensorMeta cols_meta(DataType::INT64, cols_dims, DataLayout::NCHW);
DenseTensor cols(alloc, cols_meta);
DenseTensorMeta values_meta(DataType::FLOAT32, cols_dims, DataLayout::NCHW);
DenseTensor values(alloc, values_meta);
SparseCsrTensor csr(crows, cols, values, dense_dims);
CHECK(csr.initialized());
PADDLE_ENFORCE_EQ(csr.dims(),
dense_dims,
common::errors::InvalidArgument(
"Required csr.dims() should be equal to dense_dims. "));
// Test Resize
auto dense_dims_3d = common::make_ddim({2, 4, 4});
csr.Resize(dense_dims_3d, 2);
PADDLE_ENFORCE_EQ(
csr.non_zero_cols().numel(),
2,
common::errors::InvalidArgument(
"Required csr.non_zero_cols().numel() should be equal to 2. "));
// Test shallow_copy
SparseCsrTensor csr2(csr);
PADDLE_ENFORCE_EQ(
csr.dims(),
csr2.dims(),
common::errors::Fatal("`csr.dims()` should be equal to `csr2.dims()`, "
"something wrong with shallow copy"));
// Test shallow_copy_assignment
SparseCsrTensor csr3 = csr2;
PADDLE_ENFORCE_EQ(
csr3.dims(),
csr2.dims(),
common::errors::Fatal("``csr3.dims()` should be equal to `csr2.dims()`, "
"something wrong with shallow copy assignment"));
}
} // namespace tests
} // namespace phi
+356
View File
@@ -0,0 +1,356 @@
/* 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 <sstream>
#include <string>
#include <utility>
#include "glog/logging.h"
#include "gtest/gtest.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/string_tensor.h"
#include "test/cpp/phi/core/allocator.h"
namespace phi {
namespace tests {
using pstring = ::phi::dtype::pstring;
TEST(string_tensor, ctor) {
const DDim dims({1, 2});
StringTensorMeta meta(dims);
const auto string_allocator =
std::make_unique<paddle::experimental::DefaultAllocator>(phi::CPUPlace());
const auto alloc = string_allocator.get();
auto check_string_tensor = [](const StringTensor& t,
const StringTensorMeta& m) -> bool {
bool r{true};
r = r && (t.numel() == product(m.dims));
r = r && (t.dims() == m.dims);
r = r && (t.place() == phi::CPUPlace());
r = r && t.initialized();
r = r && t.IsSharedWith(t);
r = r && (t.meta() == m);
return r;
};
auto cpu = CPUPlace();
phi::DeviceContextPool& pool = phi::DeviceContextPool::Instance();
CPUContext* cpu_ctx = reinterpret_cast<CPUContext*>(pool.Get(cpu));
StringTensor tensor_0(alloc, meta);
check_string_tensor(tensor_0, meta);
pstring pshort_str = pstring("A short pstring.");
pstring plong_str =
pstring("A large pstring whose length is longer than 22.");
pstring* data = cpu_ctx->template Alloc<pstring>(&tensor_0);
data[0] = plong_str;
data[1] = pshort_str;
PADDLE_ENFORCE_EQ(tensor_0.data()[0],
plong_str,
common::errors::InvalidArgument(
"The tensor_0 should be equal to '%s', but got '%s'.",
plong_str,
tensor_0.data()[0]));
PADDLE_ENFORCE_EQ(tensor_0.data()[1],
pshort_str,
common::errors::InvalidArgument(
"The tensor_0 should be equal to '%s', but got '%s'.",
pshort_str,
tensor_0.data()[1]));
// Test Copy Constructor
StringTensor tensor_1(tensor_0);
PADDLE_ENFORCE_EQ(tensor_1.data()[0],
plong_str,
common::errors::InvalidArgument(
"The tensor_1 should be equal to '%s', but got '%s'.",
plong_str,
tensor_1.data()[0]));
PADDLE_ENFORCE_EQ(tensor_1.data()[1],
pshort_str,
common::errors::InvalidArgument(
"The tensor_1 should be equal to '%s', but got '%s'.",
pshort_str,
tensor_1.data()[1]));
// Test Copy Assignment
StringTensor tensor_2(alloc, meta);
tensor_2 = tensor_1;
PADDLE_ENFORCE_EQ(tensor_2.data()[0],
plong_str,
common::errors::InvalidArgument(
"The tensor_2 should be equal to '%s', but got '%s'.",
plong_str,
tensor_2.data()[0]));
PADDLE_ENFORCE_EQ(tensor_2.data()[1],
pshort_str,
common::errors::InvalidArgument(
"The tensor_2 should be equal to '%s', but got '%s'.",
pshort_str,
tensor_2.data()[1]));
// Test Move Assignment
StringTensor tensor_3(alloc, meta);
tensor_3 = std::move(tensor_1);
PADDLE_ENFORCE_EQ(tensor_3.data()[0],
plong_str,
common::errors::InvalidArgument(
"The tensor_3 should be equal to '%s', but got '%s'.",
plong_str,
tensor_3.data()[0]));
PADDLE_ENFORCE_EQ(tensor_3.data()[1],
pshort_str,
common::errors::InvalidArgument(
"The tensor_3 should be equal to '%s', but got '%s'.",
pshort_str,
tensor_3.data()[1]));
tensor_3.set_meta(meta);
}
TEST(pstring, func) {
// Test Ctor
pstring empty_str;
pstring nchar_str(5, 'A');
pstring copy_nchar_str(nchar_str);
PADDLE_ENFORCE_EQ(
empty_str,
"",
common::errors::InvalidArgument(
"The empty_str should be empty, but got '%s'.", empty_str));
PADDLE_ENFORCE_EQ(
nchar_str,
"AAAAA",
common::errors::InvalidArgument(
"The nchar_str should be 'AAAAA', but got '%s'.", nchar_str));
PADDLE_ENFORCE_EQ(copy_nchar_str,
"AAAAA",
common::errors::InvalidArgument(
"The copy_nchar_str should be 'AAAAA', but got '%s'.",
copy_nchar_str));
// Test Move Ctor
pstring move_nchar_str(nchar_str);
PADDLE_ENFORCE_EQ(move_nchar_str,
"AAAAA",
common::errors::InvalidArgument(
"The move_nchar_str should be 'AAAAA', but got '%s'.",
move_nchar_str));
pstring std_str(std::string("BBBB"));
PADDLE_ENFORCE_EQ(
std_str,
"BBBB",
common::errors::InvalidArgument(
"The std_str should be 'BBBB', but got '%s'.", std_str));
pstring long_str = "A large pstring whose length is longer than 22.";
pstring short_str = "A short pstring.";
// Test operator+
pstring plus_str = move_nchar_str + std_str;
PADDLE_ENFORCE_EQ(
plus_str,
"AAAAABBBB",
common::errors::InvalidArgument(
"The plus_str should be 'AAAAABBBB', but got '%s'.", plus_str));
// Test insert
plus_str.insert(5, 1, 'C');
PADDLE_ENFORCE_EQ(
plus_str,
"AAAAACBBBB",
common::errors::InvalidArgument(
"The plus_str should be 'AAAAABBBB', but got '%s'.", plus_str));
plus_str.insert(5, "DDD", 0, 2);
PADDLE_ENFORCE_EQ(
plus_str,
"AAAAADDCBBBB",
common::errors::InvalidArgument(
"The plus_str should be 'AAAAABBBB', but got '%s'.", plus_str));
// Test pushback
plus_str.push_back('E');
PADDLE_ENFORCE_EQ(
plus_str,
"AAAAADDCBBBBE",
common::errors::InvalidArgument(
"The plus_str should be 'AAAAADDCBBBBE', but got '%s'.", plus_str));
// Test append
plus_str.append("FF");
PADDLE_ENFORCE_EQ(
plus_str,
"AAAAADDCBBBBEFF",
common::errors::InvalidArgument(
"The plus_str should be 'AAAAADDCBBBBEFF', but got '%s'.", plus_str));
plus_str.append(2, 'G');
PADDLE_ENFORCE_EQ(
plus_str,
"AAAAADDCBBBBEFFGG",
common::errors::InvalidArgument(
"The plus_str should be 'AAAAADDCBBBBEFFGG', but got '%s'.",
plus_str));
// Test operator[]
PADDLE_ENFORCE_EQ(
long_str[0],
'A',
common::errors::InvalidArgument(
"The long_str[0] should be 'A', but got '%s'.", long_str[0]));
PADDLE_ENFORCE_EQ(
short_str[0],
'A',
common::errors::InvalidArgument(
"The short_str[0] should be 'A', but got '%s'.", short_str[0]));
// Test capacity
PADDLE_ENFORCE_EQ(short_str.capacity(),
22UL,
common::errors::InvalidArgument(
"The short_str's capacity should be 22, but got %d.",
short_str.capacity()));
// Test reserve
pstring reserve_str;
PADDLE_ENFORCE_EQ(reserve_str.capacity(),
22UL,
common::errors::InvalidArgument(
"The reserve_str's capacity should be 22, but got %d.",
reserve_str.capacity()));
// small -> large
reserve_str.reserve(100);
PADDLE_ENFORCE_EQ(reserve_str.capacity(),
111UL,
common::errors::InvalidArgument(
"The reserve_str's capacity should be 111, but got %d.",
reserve_str.capacity())); // align(100) - 1 = 111
// reserve more memory
reserve_str.reserve(200);
PADDLE_ENFORCE_EQ(reserve_str.capacity(),
207UL,
common::errors::InvalidArgument(
"The reserve_str's capacity should be 207, but got %d.",
reserve_str.capacity())); // align(200) - 1 = 207
// Test operator<<
std::ostringstream oss1, oss2;
oss1 << long_str;
PADDLE_ENFORCE_EQ(
oss1.str(),
long_str,
common::errors::InvalidArgument(
"The oss1 should be '%s', but got '%s'.", long_str, oss1.str()));
// Test iterator
for (auto str_item : long_str) {
oss2 << str_item;
}
PADDLE_ENFORCE_EQ(
oss2.str(),
long_str,
common::errors::InvalidArgument(
"The oss2 should be '%s', but got '%s'.", long_str, oss2.str()));
// Test comparison operators
PADDLE_ENFORCE_EQ((long_str < short_str),
true,
common::errors::InvalidArgument(
"The long_str should be less than short_str."));
PADDLE_ENFORCE_EQ((long_str > short_str),
false,
common::errors::InvalidArgument(
"The long_str should not be greater than short_str."));
PADDLE_ENFORCE_EQ((long_str == short_str),
false,
common::errors::InvalidArgument(
"The long_str should not be equal to short_str."));
PADDLE_ENFORCE_EQ((long_str != short_str),
true,
common::errors::InvalidArgument(
"The long_str should not be equal to short_str."));
PADDLE_ENFORCE_EQ((short_str < long_str),
false,
common::errors::InvalidArgument(
"The short_str should not be less than long_str."));
PADDLE_ENFORCE_EQ((short_str > long_str),
true,
common::errors::InvalidArgument(
"The short_str should be greater than long_str."));
PADDLE_ENFORCE_EQ((move_nchar_str < plus_str),
true,
common::errors::InvalidArgument(
"The move_nchar_str should be less than plus_str."));
PADDLE_ENFORCE_EQ((plus_str > move_nchar_str),
true,
common::errors::InvalidArgument(
"The plus_str should be greater than move_nchar_str."));
// Test empty
PADDLE_ENFORCE_EQ(
empty_str.empty(),
true,
common::errors::InvalidArgument("The empty_str should be empty."));
PADDLE_ENFORCE_EQ(
nchar_str.empty(),
false,
common::errors::InvalidArgument("The nchar_str should not be empty."));
PADDLE_ENFORCE_EQ(empty_str.length(),
0UL,
common::errors::InvalidArgument(
"The empty_str's length should be 0, but got %d.",
empty_str.length()));
// Test Resize
nchar_str.resize(6, 'B');
PADDLE_ENFORCE_EQ(
nchar_str,
"AAAAAB",
common::errors::InvalidArgument(
"The nchar_str should be 'AAAAAB', but got '%s'.", nchar_str));
// Test operator =
long_str = std::move(nchar_str);
PADDLE_ENFORCE_EQ(
long_str,
"AAAAAB",
common::errors::InvalidArgument(
"The long_str should be 'AAAAAB', but got '%s'.", long_str));
long_str = short_str;
PADDLE_ENFORCE_EQ(
short_str,
long_str,
common::errors::InvalidArgument(
"The short_str should be '%s', but got '%s'.", long_str, short_str));
short_str = 'A';
PADDLE_ENFORCE_EQ(
short_str,
"A",
common::errors::InvalidArgument(
"The short_str should be 'A', but got '%s'.", short_str));
short_str = std::move(copy_nchar_str);
PADDLE_ENFORCE_EQ(
short_str,
"AAAAA",
common::errors::InvalidArgument(
"The short_str should be 'AAAAA', but got '%s'.", short_str));
}
} // namespace tests
} // namespace phi
+54
View File
@@ -0,0 +1,54 @@
// 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 "paddle/phi/core/distributed/store/tcp_store.h"
#include "paddle/phi/core/distributed/store/tcp_utils.h"
#ifdef _WIN32
#include <windows.h>
#endif
namespace phi {
namespace distributed {
TEST(MasterDaemon, init) {
int socket = tcputils::tcp_listen("", std::to_string(0), AF_INET);
std::unique_ptr<detail::MasterDaemon> d =
detail::MasterDaemon::createDaemon(socket, 1, 100);
d->start();
printf("started to sleep 2s\n");
#ifdef _WIN32
Sleep(2 * 1000);
#else
usleep(2 * 1000 * 1000);
#endif
printf("end to reset\n");
d.reset();
}
/* now for only c compile test
TEST(TCPStore, init) {
TCPStore store("127.0.0.1", 6170, true, 1);
store.add("my", 3);
auto ret1 = store.get("my");
store.add("my", 3);
auto ret2 = store.get("my");
PADDLE_ENFORCE_EQ(ret1[0] + 3, ret2[0],
paddle::errors::Fatal("result of add is not right"));
}
*/
} // namespace distributed
} // namespace phi
+122
View File
@@ -0,0 +1,122 @@
/* 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 <sstream>
#include <string>
#include <utility>
#include "gtest/gtest.h"
#include "paddle/common/errors.h"
#include "paddle/phi/backends/all_context.h"
#include "paddle/phi/core/enforce.h"
#include "paddle/phi/core/tensor_array.h"
#include "test/cpp/phi/core/allocator.h"
namespace phi {
namespace tests {
using pstring = ::phi::dtype::pstring;
TEST(tensor_array, tensor_array_not_init) {
const DDim dims({1, 2});
const DataType dtype{DataType::INT8};
const DataLayout layout{DataLayout::NHWC};
const LegacyLoD lod{};
DenseTensorMeta meta(dtype, dims, layout, lod);
DenseTensor tensor_0;
tensor_0.set_meta(meta);
std::vector<DenseTensor> tensors;
tensors.push_back(tensor_0);
tensors.push_back(tensor_0);
tensors.push_back(tensor_0);
TensorArray tensor_array(tensors);
try {
tensor_array.dims();
} catch (const common::enforce::EnforceNotMet& error) {
std::string ex_msg = error.what();
EXPECT_TRUE(ex_msg.find("dims") != std::string::npos);
}
try {
tensor_array.place();
} catch (const common::enforce::EnforceNotMet& error) {
std::string ex_msg = error.what();
EXPECT_TRUE(ex_msg.find("place") != std::string::npos);
}
try {
tensor_array.dtype();
} catch (const common::enforce::EnforceNotMet& error) {
std::string ex_msg = error.what();
EXPECT_TRUE(ex_msg.find("dtype") != std::string::npos);
}
try {
tensor_array.layout();
} catch (const common::enforce::EnforceNotMet& error) {
std::string ex_msg = error.what();
EXPECT_TRUE(ex_msg.find("layout") != std::string::npos);
}
try {
tensor_array.numel();
} catch (const common::enforce::EnforceNotMet& error) {
std::string ex_msg = error.what();
EXPECT_TRUE(ex_msg.find("numel") != std::string::npos);
}
try {
tensor_array.valid();
} catch (const common::enforce::EnforceNotMet& error) {
std::string ex_msg = error.what();
EXPECT_TRUE(ex_msg.find("valid") != std::string::npos);
}
EXPECT_TRUE(!tensor_array.initialized());
}
TEST(tensor_array, tensor_array_init) {
const DDim dims1({1, 2});
const DDim dims2({1, 2, 3});
const DataType dtype{DataType::INT8};
const DataLayout layout{DataLayout::NHWC};
const LegacyLoD lod{};
DenseTensorMeta meta1(dtype, dims1, layout, lod);
DenseTensorMeta meta2(dtype, dims2, layout, lod);
auto fancy_allocator = std::unique_ptr<Allocator>(new FancyAllocator);
auto* alloc = fancy_allocator.get();
DenseTensor tensor_0;
tensor_0.set_meta(meta1);
DenseTensor tensor_1;
tensor_1.set_meta(meta2);
std::vector<DenseTensor> tensors;
tensors.push_back(tensor_0);
tensors.push_back(tensor_1);
tensors.push_back(tensor_0);
TensorArray tensor_array(tensors);
tensor_array.AllocateFrom(alloc, DataType::INT8);
EXPECT_TRUE(tensor_array.initialized());
}
} // namespace tests
} // namespace phi
+86
View File
@@ -0,0 +1,86 @@
/* 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 <memory>
#include "gtest/gtest.h"
#include "paddle/phi/core/utils/type_registry.h"
namespace phi {
template <typename BaseT, typename DerivedT>
const TypeInfo<BaseT> TypeInfoTraits<BaseT, DerivedT>::kType =
RegisterStaticType<BaseT>(DerivedT::name());
template <typename BaseT, typename DerivedT>
bool TypeInfoTraits<BaseT, DerivedT>::classof(const BaseT* obj) {
return obj->type_info() == kType;
}
template <typename BaseT, typename DerivedT>
TypeInfoTraits<BaseT, DerivedT>::TypeInfoTraits() {
static_cast<BaseT*>(static_cast<DerivedT*>(this))->type_info_ = kType;
}
namespace tests {
template <typename T>
class Base {
public:
TypeInfo<Base<T>> type_info() const { return type_info_; }
private:
template <typename T1, typename T2>
friend class phi::TypeInfoTraits;
TypeInfo<Base<T>> type_info_{TypeInfo<Base<T>>::kUnknownType};
};
template <typename T>
class DerivedA : public Base<T>, public TypeInfoTraits<Base<T>, DerivedA<T>> {
public:
static const char* name() { return "DerivedA"; }
};
template <typename T>
class DerivedB : public Base<T>, public TypeInfoTraits<Base<T>, DerivedB<T>> {
public:
static const char* name() { return "DerivedB"; }
};
template <typename T>
void check_type_info() {
std::unique_ptr<Base<T>> base(new Base<T>);
std::unique_ptr<Base<T>> derived_a(new DerivedA<T>);
std::unique_ptr<Base<T>> derived_b(new DerivedB<T>);
EXPECT_EQ(DerivedA<T>::classof(derived_a.get()), true);
EXPECT_EQ(DerivedB<T>::classof(derived_b.get()), true);
EXPECT_EQ(DerivedB<T>::classof(derived_a.get()), false);
EXPECT_EQ(DerivedA<T>::classof(derived_b.get()), false);
EXPECT_EQ(base->type_info().id(), 0);
EXPECT_EQ(derived_a->type_info().id(), 1);
EXPECT_EQ(derived_b->type_info().id(), 2);
EXPECT_EQ(base->type_info().name(), "Unknown");
EXPECT_EQ(derived_a->type_info().name(), "DerivedA");
EXPECT_EQ(derived_b->type_info().name(), "DerivedB");
}
TEST(type_info, base) {
check_type_info<int>();
check_type_info<float>();
}
} // namespace tests
} // namespace phi
+39
View File
@@ -0,0 +1,39 @@
/* 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 <chrono> // NOLINT
namespace phi {
namespace tests {
class Timer {
public:
std::chrono::high_resolution_clock::time_point start;
std::chrono::high_resolution_clock::time_point startu;
void tic() { start = std::chrono::high_resolution_clock::now(); }
double toc() {
startu = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> time_span =
std::chrono::duration_cast<std::chrono::duration<double>>(startu -
start);
double used_time_ms = static_cast<double>(time_span.count()) * 1000.0;
return used_time_ms;
}
};
} // namespace tests
} // namespace phi
@@ -0,0 +1,83 @@
// 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 "paddle/common/unroll_array_ops.h"
#include <gtest/gtest.h>
#include <array>
namespace phi {
namespace framework {
template <typename T>
bool CheckEquality(const T* p, size_t n, T val) {
return std::all_of(p, p + n, [val](const T& v) { return v == val; });
}
template <int D1, int D2>
bool FillConstantTestMain() {
static_assert(D1 >= D2);
std::array<int, D1> arr = {};
arr.fill(0);
common::UnrollFillConstant<D2>::Run(arr.data(), 1);
return CheckEquality(arr.data(), D2, 1) &&
CheckEquality(arr.data() + D2, arr.size() - D2, 0);
}
TEST(unroll_ops, fill_constant) {
EXPECT_TRUE((FillConstantTestMain<9, 0>()));
EXPECT_TRUE((FillConstantTestMain<9, 1>()));
EXPECT_TRUE((FillConstantTestMain<9, 4>()));
EXPECT_TRUE((FillConstantTestMain<9, 9>()));
}
TEST(unroll_ops, assign) {
const int a[] = {1, 2, 3, 4, 5}; // NOLINT
int b[] = {0, 0, 0, 0, 0}; // NOLINT
common::UnrollAssign<3>::Run(a, b);
EXPECT_EQ(b[0], 1);
EXPECT_EQ(b[1], 2);
EXPECT_EQ(b[2], 3);
EXPECT_EQ(b[3], 0);
EXPECT_EQ(b[4], 0);
}
TEST(unroll_ops, var_args_assign) {
int a[] = {0, 0, 0}; // NOLINT
common::UnrollVarArgsAssign<int>::Run(a, 1, 2);
EXPECT_EQ(a[0], 1);
EXPECT_EQ(a[1], 2);
EXPECT_EQ(a[2], 0);
}
TEST(unroll_ops, compare) {
int a[] = {1, 2, 3}; // NOLINT
int b[] = {1, 2, 4}; // NOLINT
EXPECT_TRUE(common::UnrollCompare<2>::Run(a, b));
EXPECT_FALSE(common::UnrollCompare<3>::Run(a, b));
b[0] = -1;
EXPECT_TRUE(common::UnrollCompare<0>::Run(a, b));
EXPECT_FALSE(common::UnrollCompare<1>::Run(a, b));
}
TEST(unroll_ops, product) {
int a[] = {2, 3, 4}; // NOLINT
EXPECT_EQ(common::UnrollProduct<3>::Run(a), a[0] * a[1] * a[2]);
}
} // namespace framework
} // namespace phi