You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
6.6 KiB
263 lines
6.6 KiB
7 years ago
|
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
|
||
|
|
||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
you may not use this file except in compliance with the License.
|
||
|
You may obtain a copy of the License at
|
||
|
|
||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
||
|
Unless required by applicable law or agreed to in writing, software
|
||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
See the License for the specific language governing permissions and
|
||
|
limitations under the License. */
|
||
|
|
||
|
#include "paddle/fluid/operators/math/concat.h"
|
||
|
#include <gtest/gtest.h>
|
||
|
#include <vector>
|
||
|
#include "paddle/fluid/framework/tensor_util.h"
|
||
|
|
||
|
using namespace paddle::framework;
|
||
|
using namespace paddle::platform;
|
||
|
|
||
|
template <typename DeviceContext, typename Place>
|
||
|
void testConcat() {
|
||
|
Tensor input_a_cpu;
|
||
|
Tensor input_b_cpu;
|
||
|
Tensor out_cpu;
|
||
|
Tensor input_a;
|
||
|
Tensor input_b;
|
||
|
Tensor out;
|
||
|
|
||
|
DeviceContext* context = new DeviceContext(Place());
|
||
|
// DeviceContext context(Place());
|
||
|
|
||
|
/**
|
||
|
* cast1:
|
||
|
* inputs:
|
||
|
* t_a.shape: [2, 3, 4]
|
||
|
* t_b.shape: [3, 3, 4]
|
||
|
* output:
|
||
|
* out.shape: [5, 3, 4]
|
||
|
*/
|
||
|
auto dim_a = make_ddim({2, 3, 4});
|
||
|
auto dim_b = make_ddim({3, 3, 4});
|
||
|
auto dim_out = make_ddim({5, 3, 4});
|
||
|
|
||
|
input_a.mutable_data<int>(dim_a, Place());
|
||
|
input_b.mutable_data<int>(dim_b, Place());
|
||
|
out.mutable_data<int>(dim_out, Place());
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
input_a_cpu.mutable_data<int>(dim_a, CPUPlace());
|
||
|
input_b_cpu.mutable_data<int>(dim_b, CPUPlace());
|
||
|
out_cpu.mutable_data<int>(dim_out, CPUPlace());
|
||
|
}
|
||
|
|
||
|
int* a_ptr;
|
||
|
int* b_ptr;
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
a_ptr = input_a_cpu.data<int>();
|
||
|
b_ptr = input_b_cpu.data<int>();
|
||
|
} else {
|
||
|
a_ptr = input_a.data<int>();
|
||
|
b_ptr = input_b.data<int>();
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < 2 * 3 * 4; ++i) {
|
||
|
a_ptr[i] = i;
|
||
|
}
|
||
|
for (int i = 0; i < 3 * 3 * 4; ++i) {
|
||
|
b_ptr[i] = i;
|
||
|
}
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
TensorCopy(input_a_cpu, Place(), *context, &input_a);
|
||
|
TensorCopy(input_b_cpu, Place(), *context, &input_b);
|
||
|
}
|
||
|
|
||
|
std::vector<Tensor> input;
|
||
|
input.push_back(input_a);
|
||
|
input.push_back(input_b);
|
||
|
|
||
|
paddle::operators::math::ConcatFunctor<DeviceContext, int> concat_functor;
|
||
|
concat_functor(*context, input, 0, &out);
|
||
|
|
||
|
// check the dim of input_a, input_b
|
||
|
PADDLE_ENFORCE_EQ(input_a.dims(), dim_a);
|
||
|
PADDLE_ENFORCE_EQ(input_b.dims(), dim_b);
|
||
|
|
||
|
int* out_ptr;
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
TensorCopy(out, CPUPlace(), *context, &out_cpu);
|
||
|
out_ptr = out_cpu.data<int>();
|
||
|
} else {
|
||
|
out_ptr = out.data<int>();
|
||
|
}
|
||
|
|
||
|
int cols = 2 * 3 * 4;
|
||
|
int idx_a = 0, idx_b = 0;
|
||
|
for (int j = 0; j < 5 * 3 * 4; ++j) {
|
||
|
if (j >= cols) {
|
||
|
PADDLE_ENFORCE_EQ(out_ptr[j], b_ptr[idx_b]);
|
||
|
++idx_b;
|
||
|
} else {
|
||
|
PADDLE_ENFORCE_EQ(out_ptr[j], a_ptr[idx_a]);
|
||
|
++idx_a;
|
||
|
}
|
||
|
}
|
||
|
//
|
||
|
/**
|
||
|
* cast2:
|
||
|
* inputs:
|
||
|
* t_a.shape: [2, 3, 4]
|
||
|
* t_b.shape: [2, 4, 4]
|
||
|
* output:
|
||
|
* out.shape: [2, 7, 4]
|
||
|
*/
|
||
|
dim_a = make_ddim({2, 3, 4});
|
||
|
dim_b = make_ddim({2, 4, 4});
|
||
|
dim_out = make_ddim({2, 7, 4});
|
||
|
|
||
|
input_a.Resize(dim_a);
|
||
|
input_b.Resize(dim_b);
|
||
|
out.Resize(dim_out);
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
input_a_cpu.Resize(dim_a);
|
||
|
input_b_cpu.Resize(dim_b);
|
||
|
out_cpu.Resize(dim_out);
|
||
|
}
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
a_ptr = input_a_cpu.data<int>();
|
||
|
b_ptr = input_b_cpu.data<int>();
|
||
|
} else {
|
||
|
a_ptr = input_a.data<int>();
|
||
|
b_ptr = input_b.data<int>();
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < 2 * 3 * 4; ++i) {
|
||
|
a_ptr[i] = i;
|
||
|
}
|
||
|
for (int i = 0; i < 2 * 4 * 4; ++i) {
|
||
|
b_ptr[i] = i;
|
||
|
}
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
TensorCopy(input_a_cpu, Place(), *context, &input_a);
|
||
|
TensorCopy(input_b_cpu, Place(), *context, &input_b);
|
||
|
}
|
||
|
|
||
|
input.clear();
|
||
|
input.push_back(input_a);
|
||
|
input.push_back(input_b);
|
||
|
|
||
|
concat_functor(*context, input, 1, &out);
|
||
|
|
||
|
// check the dim of input_a, input_b
|
||
|
PADDLE_ENFORCE_EQ(input_a.dims(), dim_a);
|
||
|
PADDLE_ENFORCE_EQ(input_b.dims(), dim_b);
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
TensorCopy(out, CPUPlace(), *context, &out_cpu);
|
||
|
out_ptr = out_cpu.data<int>();
|
||
|
} else {
|
||
|
out_ptr = out.data<int>();
|
||
|
}
|
||
|
|
||
|
cols = 3 * 4;
|
||
|
idx_a = 0, idx_b = 0;
|
||
|
for (int i = 0; i < 2; ++i) {
|
||
|
for (int j = 0; j < 28; ++j) {
|
||
|
if (j >= cols) {
|
||
|
PADDLE_ENFORCE_EQ(out_ptr[i * 28 + j], b_ptr[idx_b]);
|
||
|
++idx_b;
|
||
|
} else {
|
||
|
PADDLE_ENFORCE_EQ(out_ptr[i * 28 + j], a_ptr[idx_a]);
|
||
|
++idx_a;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* cast3:
|
||
|
* inputs:
|
||
|
* t_a.shape: [2, 3, 5]
|
||
|
* t_b.shape: [2, 3, 4]
|
||
|
* output:
|
||
|
* out.shape: [2, 3, 9]
|
||
|
*/
|
||
|
dim_a = make_ddim({2, 3, 4});
|
||
|
dim_b = make_ddim({2, 3, 5});
|
||
|
dim_out = make_ddim({2, 3, 9});
|
||
|
|
||
|
input_a.Resize(dim_a);
|
||
|
input_b.Resize(dim_b);
|
||
|
out.Resize(dim_out);
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
input_a_cpu.Resize(dim_a);
|
||
|
input_b_cpu.Resize(dim_b);
|
||
|
out_cpu.Resize(dim_out);
|
||
|
}
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
a_ptr = input_a_cpu.data<int>();
|
||
|
b_ptr = input_b_cpu.data<int>();
|
||
|
} else {
|
||
|
a_ptr = input_a.data<int>();
|
||
|
b_ptr = input_b.data<int>();
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < 2 * 3 * 4; ++i) {
|
||
|
a_ptr[i] = i;
|
||
|
}
|
||
|
for (int i = 0; i < 2 * 3 * 5; ++i) {
|
||
|
b_ptr[i] = i;
|
||
|
}
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
TensorCopy(input_a_cpu, Place(), *context, &input_a);
|
||
|
TensorCopy(input_b_cpu, Place(), *context, &input_b);
|
||
|
}
|
||
|
|
||
|
input.clear();
|
||
|
input.push_back(input_a);
|
||
|
input.push_back(input_b);
|
||
|
|
||
|
concat_functor(*context, input, 2, &out);
|
||
|
|
||
|
// check the dim of input_a, input_b
|
||
|
PADDLE_ENFORCE_EQ(input_a.dims(), dim_a);
|
||
|
PADDLE_ENFORCE_EQ(input_b.dims(), dim_b);
|
||
|
|
||
|
if (paddle::platform::is_gpu_place(Place())) {
|
||
|
TensorCopy(out, CPUPlace(), *context, &out_cpu);
|
||
|
out_ptr = out_cpu.data<int>();
|
||
|
} else {
|
||
|
out_ptr = out.data<int>();
|
||
|
}
|
||
|
|
||
|
// check the data
|
||
|
cols = 4;
|
||
|
idx_a = 0, idx_b = 0;
|
||
|
for (int i = 0; i < 6; ++i) {
|
||
|
for (int j = 0; j < 9; ++j) {
|
||
|
if (j >= cols) {
|
||
|
PADDLE_ENFORCE_EQ(out_ptr[i * 9 + j], b_ptr[idx_b]);
|
||
|
++idx_b;
|
||
|
} else {
|
||
|
PADDLE_ENFORCE_EQ(out_ptr[i * 9 + j], a_ptr[idx_a]);
|
||
|
++idx_a;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TEST(math, concat) {
|
||
|
testConcat<paddle::platform::CPUDeviceContext, paddle::platform::CPUPlace>();
|
||
|
#ifdef PADDLE_WITH_CUDA
|
||
|
testConcat<paddle::platform::CUDADeviceContext,
|
||
|
paddle::platform::CUDAPlace>();
|
||
|
#endif
|
||
|
}
|