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.
222 lines
6.8 KiB
222 lines
6.8 KiB
7 years ago
|
/* 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 <unistd.h>
|
||
|
#include <string>
|
||
|
#include <thread>
|
||
|
|
||
7 years ago
|
#include <google/protobuf/text_format.h>
|
||
7 years ago
|
#include "gtest/gtest.h"
|
||
|
#include "paddle/fluid/framework/lod_tensor.h"
|
||
|
#include "paddle/fluid/framework/tensor_util.h"
|
||
|
#include "paddle/fluid/framework/variable.h"
|
||
|
#include "paddle/fluid/operators/detail/sendrecvop_utils.h"
|
||
7 years ago
|
#include "paddle/fluid/operators/detail/variable_response.h"
|
||
7 years ago
|
#include "paddle/fluid/operators/math/math_function.h"
|
||
|
#include "paddle/fluid/platform/place.h"
|
||
|
#include "paddle/fluid/string/printf.h"
|
||
|
|
||
|
namespace framework = paddle::framework;
|
||
|
namespace platform = paddle::platform;
|
||
|
namespace operators = paddle::operators;
|
||
|
namespace math = paddle::operators::math;
|
||
|
namespace memory = paddle::memory;
|
||
|
|
||
7 years ago
|
void RunSerdeTestSelectedRows(platform::Place place) {
|
||
7 years ago
|
platform::DeviceContextPool& pool = platform::DeviceContextPool::Instance();
|
||
|
auto& ctx = *pool.Get(place);
|
||
7 years ago
|
|
||
|
// serialize var to ByteBuffer
|
||
|
framework::Variable var;
|
||
|
auto* slr = var.GetMutable<framework::SelectedRows>();
|
||
7 years ago
|
slr->set_height(1000);
|
||
7 years ago
|
auto* tensor = slr->mutable_value();
|
||
|
auto* rows = slr->mutable_rows();
|
||
7 years ago
|
tensor->Resize(framework::make_ddim({564, 128}));
|
||
7 years ago
|
tensor->mutable_data<float>(place);
|
||
7 years ago
|
int tensor_numel = 564 * 128;
|
||
7 years ago
|
math::set_constant(ctx, tensor, 32.7);
|
||
7 years ago
|
for (int i = 0; i < 564; ++i) rows->push_back(i);
|
||
7 years ago
|
|
||
|
::grpc::ByteBuffer msg;
|
||
|
operators::detail::SerializeToByteBuffer("myvar", &var, ctx, &msg);
|
||
|
EXPECT_GT(msg.Length(), 0);
|
||
|
|
||
|
// deserialize
|
||
|
std::vector<::grpc::Slice> slices;
|
||
|
(void)msg.Dump(&slices);
|
||
|
std::string tmp;
|
||
|
for (const auto& s : slices) {
|
||
|
tmp.append(reinterpret_cast<const char*>(s.begin()), s.size());
|
||
|
}
|
||
7 years ago
|
|
||
7 years ago
|
sendrecv::VariableMessage varmsg;
|
||
|
EXPECT_TRUE(varmsg.ParseFromString(tmp));
|
||
7 years ago
|
|
||
7 years ago
|
// deserialize bytebuffer
|
||
7 years ago
|
EXPECT_EQ(varmsg.varname(), "myvar");
|
||
7 years ago
|
EXPECT_EQ(varmsg.type(), 1);
|
||
7 years ago
|
|
||
|
const float* tensor_data =
|
||
|
reinterpret_cast<const float*>(varmsg.serialized().data());
|
||
7 years ago
|
const int64_t* rows_data =
|
||
|
reinterpret_cast<const int64_t*>(varmsg.rows().data());
|
||
7 years ago
|
for (int i = 0; i < tensor_numel; ++i) {
|
||
7 years ago
|
EXPECT_FLOAT_EQ(tensor_data[i], 32.7);
|
||
7 years ago
|
}
|
||
7 years ago
|
for (int i = 0; i < 564; ++i) {
|
||
|
EXPECT_EQ(rows_data[i], i);
|
||
|
}
|
||
|
|
||
7 years ago
|
// deserialize zero-copy
|
||
7 years ago
|
// framework::Variable var2;
|
||
|
// operators::detail::DeserializeFromByteBuffer(msg, ctx, &var2);
|
||
|
framework::Scope scope;
|
||
|
scope.Var("myvar");
|
||
7 years ago
|
operators::detail::VariableResponse resp(&scope, &ctx);
|
||
7 years ago
|
EXPECT_EQ(resp.Parse(msg), 0);
|
||
|
|
||
|
framework::Variable* var2 = resp.GetVar();
|
||
|
|
||
|
auto* slr2 = var2->GetMutable<framework::SelectedRows>();
|
||
|
auto* tensor2 = slr2->mutable_value();
|
||
|
auto* rows2 = slr2->mutable_rows();
|
||
7 years ago
|
float* tensor_data2 = nullptr;
|
||
|
framework::Tensor tmp_tensor;
|
||
|
|
||
|
if (platform::is_gpu_place(ctx.GetPlace())) {
|
||
|
platform::CPUPlace cpu;
|
||
7 years ago
|
framework::TensorCopy(*tensor2, cpu, &tmp_tensor);
|
||
7 years ago
|
tensor_data2 = tmp_tensor.data<float>();
|
||
|
} else {
|
||
7 years ago
|
tensor_data2 = const_cast<float*>(tensor2->data<float>());
|
||
7 years ago
|
}
|
||
7 years ago
|
const int64_t* rows_data2 = rows2->data();
|
||
7 years ago
|
|
||
7 years ago
|
for (int i = 0; i < tensor_numel; ++i) {
|
||
|
EXPECT_FLOAT_EQ(tensor_data2[i], 32.7);
|
||
|
}
|
||
7 years ago
|
for (int i = 0; i < rows2->size(); ++i) {
|
||
|
EXPECT_EQ(rows_data2[i], i);
|
||
|
}
|
||
7 years ago
|
EXPECT_EQ(slr2->height(), 1000);
|
||
7 years ago
|
}
|
||
|
|
||
7 years ago
|
void RunTestLodTensor(platform::Place place, int from_type = 0) {
|
||
7 years ago
|
// serialize var to ByteBuffer
|
||
|
framework::Variable var;
|
||
7 years ago
|
auto* tensor = var.GetMutable<framework::LoDTensor>();
|
||
|
tensor->Resize(framework::make_ddim({4, 8, 4, 2}));
|
||
|
framework::LoD lod;
|
||
|
lod.push_back(framework::Vector<size_t>({1, 3, 8}));
|
||
|
tensor->set_lod(lod);
|
||
|
int tensor_numel = 4 * 8 * 4 * 2;
|
||
|
platform::DeviceContextPool& pool = platform::DeviceContextPool::Instance();
|
||
|
auto& ctx = *pool.Get(place);
|
||
7 years ago
|
tensor->mutable_data<float>(place);
|
||
7 years ago
|
math::set_constant(ctx, tensor, 31.9);
|
||
7 years ago
|
|
||
|
::grpc::ByteBuffer msg;
|
||
|
operators::detail::SerializeToByteBuffer("myvar", &var, ctx, &msg);
|
||
|
EXPECT_GT(msg.Length(), 0);
|
||
|
|
||
|
// deserialize
|
||
|
std::vector<::grpc::Slice> slices;
|
||
|
(void)msg.Dump(&slices);
|
||
|
std::string tmp;
|
||
|
for (const auto& s : slices) {
|
||
|
tmp.append(reinterpret_cast<const char*>(s.begin()), s.size());
|
||
|
}
|
||
|
sendrecv::VariableMessage varmsg;
|
||
|
EXPECT_TRUE(varmsg.ParseFromString(tmp));
|
||
|
EXPECT_EQ(varmsg.varname(), "myvar");
|
||
7 years ago
|
EXPECT_EQ(varmsg.type(), 0);
|
||
|
EXPECT_EQ(varmsg.dims()[0], 4);
|
||
|
EXPECT_EQ(varmsg.dims()[1], 8);
|
||
|
EXPECT_EQ(varmsg.dims()[2], 4);
|
||
|
EXPECT_EQ(varmsg.dims()[3], 2);
|
||
|
EXPECT_EQ(varmsg.lod_level(), 1);
|
||
|
EXPECT_EQ(varmsg.lod(0).lod_data(0), 1);
|
||
|
EXPECT_EQ(varmsg.lod(0).lod_data(1), 3);
|
||
|
EXPECT_EQ(varmsg.lod(0).lod_data(2), 8);
|
||
7 years ago
|
|
||
|
const float* tensor_data =
|
||
|
reinterpret_cast<const float*>(varmsg.serialized().data());
|
||
|
for (int i = 0; i < tensor_numel; ++i) {
|
||
7 years ago
|
EXPECT_FLOAT_EQ(tensor_data[i], 31.9);
|
||
7 years ago
|
}
|
||
7 years ago
|
|
||
|
// message binary
|
||
|
std::string str;
|
||
|
varmsg.SerializeToString(&str);
|
||
|
|
||
|
// message bytebuffer
|
||
|
::grpc::Slice slices_2[1];
|
||
|
int num_slices = 1;
|
||
|
slices_2[0] = ::grpc::Slice(str.length());
|
||
|
memcpy(const_cast<uint8_t*>(slices_2[0].begin()), str.c_str(), str.length());
|
||
|
::grpc::ByteBuffer bytebuffer2(&slices_2[0], num_slices);
|
||
|
|
||
7 years ago
|
// deserialize zero-copy
|
||
7 years ago
|
framework::Scope scope;
|
||
|
scope.Var("myvar");
|
||
7 years ago
|
operators::detail::VariableResponse resp(&scope, &ctx);
|
||
7 years ago
|
if (from_type == 0) {
|
||
|
EXPECT_EQ(resp.Parse(msg), 0);
|
||
|
} else {
|
||
|
EXPECT_EQ(resp.Parse(bytebuffer2), 0);
|
||
|
}
|
||
7 years ago
|
|
||
7 years ago
|
framework::Variable* var2 = resp.GetVar();
|
||
|
|
||
|
auto tensor2 = var2->Get<framework::LoDTensor>();
|
||
7 years ago
|
float* tensor_data2 = nullptr;
|
||
|
framework::Tensor tmp_tensor;
|
||
|
|
||
|
if (platform::is_gpu_place(ctx.GetPlace())) {
|
||
|
platform::CPUPlace cpu;
|
||
7 years ago
|
framework::TensorCopy(tensor2, cpu, &tmp_tensor);
|
||
7 years ago
|
tensor_data2 = tmp_tensor.data<float>();
|
||
|
} else {
|
||
7 years ago
|
tensor_data2 = const_cast<float*>(tensor2.data<float>());
|
||
7 years ago
|
}
|
||
|
|
||
7 years ago
|
EXPECT_EQ(varmsg.lod_level(), 1);
|
||
|
EXPECT_EQ(varmsg.lod(0).lod_data(0), 1);
|
||
|
EXPECT_EQ(varmsg.lod(0).lod_data(1), 3);
|
||
|
EXPECT_EQ(varmsg.lod(0).lod_data(2), 8);
|
||
|
for (int i = 0; i < tensor_numel; ++i) EXPECT_FLOAT_EQ(tensor_data2[i], 31.9);
|
||
|
}
|
||
|
|
||
7 years ago
|
TEST(LodTensor, Run) {
|
||
|
platform::CPUPlace place;
|
||
7 years ago
|
RunTestLodTensor(place);
|
||
|
RunTestLodTensor(place, 1);
|
||
7 years ago
|
#ifdef PADDLE_WITH_CUDA
|
||
7 years ago
|
platform::CUDAPlace gpu(0);
|
||
|
RunTestLodTensor(gpu);
|
||
|
RunTestLodTensor(gpu, 1);
|
||
7 years ago
|
#endif
|
||
7 years ago
|
}
|
||
|
|
||
7 years ago
|
TEST(SelectedRows, Run) {
|
||
7 years ago
|
platform::CPUPlace place;
|
||
|
RunSerdeTestSelectedRows(place);
|
||
7 years ago
|
|
||
7 years ago
|
#ifdef PADDLE_WITH_CUDA
|
||
7 years ago
|
platform::CUDAPlace gpu;
|
||
|
RunSerdeTestSelectedRows(gpu);
|
||
7 years ago
|
#endif
|
||
7 years ago
|
}
|