commit
1a0d8fab97
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,110 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
||||
|
||||
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 <vector>
|
||||
|
||||
#include "paddle/framework/lod_tensor.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
|
||||
/*
|
||||
* DyBatchSeqPosition stores indices of the basic element in tensor. It is used
|
||||
* after lod-tensor's re-assembling, its info can be used to recover the order
|
||||
* in original lod-tensor.
|
||||
*/
|
||||
struct DySeqMeta {
|
||||
size_t begin;
|
||||
size_t end; // not included
|
||||
size_t ori_idx;
|
||||
};
|
||||
|
||||
/*
|
||||
* TensorArray is a C-array-like array of tensors, it is meant to be used with
|
||||
* dynamic iteration primitives such as while_loop. It is used to segment inputs
|
||||
* and store states in all time steps.
|
||||
*
|
||||
* By providing some methods similar to a C++ array, the difinition of some
|
||||
* state-based dynamic models such as RNN cound be more natural and highly
|
||||
* flexible.
|
||||
*/
|
||||
class TensorArray {
|
||||
public:
|
||||
using value_type = float;
|
||||
|
||||
// max number of values allowed to store.
|
||||
const size_t MAX_SIZE{100000};
|
||||
|
||||
/*
|
||||
* Read the value at location `index` in the `TensorArray`.
|
||||
*/
|
||||
const LoDTensor &Read(size_t index) const;
|
||||
|
||||
/*
|
||||
* Write value into the index of the TensorArray.
|
||||
*/
|
||||
void Write(size_t index, const LoDTensor &value);
|
||||
|
||||
/*
|
||||
* Write value into the index of the TensorArray, with memory shared.
|
||||
*/
|
||||
void WriteShared(size_t index, const LoDTensor &value);
|
||||
|
||||
/*
|
||||
* Recover the original LoD-arranged LoDTensor with the `values`, `level` and
|
||||
* `indice_map`.
|
||||
*/
|
||||
LoDTensor Pack(size_t level, const std::vector<DySeqMeta> &meta,
|
||||
const LoD &lod) const;
|
||||
|
||||
/*
|
||||
* Split LoDTensor in some `level` and write the generated batches to
|
||||
* `values`, if set `desend`, will sort by length in descending order else in
|
||||
* ascending order.
|
||||
*/
|
||||
std::vector<DySeqMeta> Unpack(const LoDTensor &source, int level,
|
||||
bool length_desend);
|
||||
|
||||
/*
|
||||
* Pack the values into a tensor with rank one higher than each tensor in
|
||||
* values.
|
||||
*/
|
||||
LoDTensor Stack() const;
|
||||
|
||||
/*
|
||||
* Unpacks the given division of a rank-`R` tensor into rank-`(R-1)` tensors.
|
||||
*/
|
||||
void Unstack(const LoDTensor &source) const;
|
||||
|
||||
/*
|
||||
* Unpacks the given division of a rank-`R` tensor into rank-`(R-1)` tensors,
|
||||
* with memory of tensors shared.
|
||||
*/
|
||||
void UnstackShared(const LoDTensor &source) const;
|
||||
|
||||
/*
|
||||
* Return the number of values.
|
||||
*/
|
||||
size_t size() const;
|
||||
|
||||
protected:
|
||||
void Unstack(const LoDTensor &source, bool data_shared) const;
|
||||
|
||||
private:
|
||||
mutable std::vector<LoDTensor> values_;
|
||||
}; // class TensorArray
|
||||
|
||||
} // namespace framework
|
||||
} // namespace paddle
|
@ -0,0 +1,130 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
||||
|
||||
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/framework/tensor_array.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
|
||||
class TensorArrayTester : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
LoDTensor source;
|
||||
source.Resize(make_ddim({batch_size, dim}));
|
||||
int* data = source.mutable_data<int>(platform::CPUPlace());
|
||||
for (int i = 0; i < 16 * 32; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
ta.Unstack(source);
|
||||
}
|
||||
|
||||
TensorArray ta;
|
||||
const int batch_size = 16;
|
||||
const int dim = 32;
|
||||
};
|
||||
|
||||
TEST_F(TensorArrayTester, Read) {
|
||||
for (int i = 0; i < batch_size; i++) {
|
||||
const auto& tensor = ta.Read(i);
|
||||
ASSERT_EQ(tensor.dims()[0], 1);
|
||||
ASSERT_EQ(tensor.dims()[1], dim);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TensorArrayTester, Write) {
|
||||
LoDTensor source;
|
||||
source.Resize(make_ddim({1, dim}));
|
||||
for (int i = 0; i < dim; i++) {
|
||||
*(source.mutable_data<int>(platform::CPUPlace()) + i) = i;
|
||||
}
|
||||
|
||||
ta.Write(2, source);
|
||||
|
||||
const auto& tensor = ta.Read(2);
|
||||
for (int i = 0; i < dim; i++) {
|
||||
EXPECT_EQ(*(tensor.data<int>() + i), *(source.data<int>() + i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TensorArrayTester, WriteShared) {
|
||||
LoDTensor source;
|
||||
source.Resize(make_ddim({1, dim}));
|
||||
for (int i = 0; i < dim; i++) {
|
||||
*(source.mutable_data<int>(platform::CPUPlace()) + i) = i;
|
||||
}
|
||||
|
||||
ta.WriteShared(2, source);
|
||||
|
||||
const auto& tensor = ta.Read(2);
|
||||
for (int i = 0; i < dim; i++) {
|
||||
EXPECT_EQ(*(tensor.data<int>() + i), *(source.data<int>() + i));
|
||||
}
|
||||
|
||||
EXPECT_EQ(source.data<int>(), tensor.data<int>());
|
||||
}
|
||||
|
||||
class TensorArrayPackTester : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() override {
|
||||
lod.push_back(std::vector<size_t>{0, 2, 9, 13});
|
||||
|
||||
source.set_lod(lod);
|
||||
source.Resize(make_ddim({13, 128}));
|
||||
source.mutable_data<int>(platform::CPUPlace());
|
||||
|
||||
// content of each setence: 0 1 2 3 4
|
||||
const auto& level = lod.front();
|
||||
for (size_t i = 0; i < level.size() - 1; i++) {
|
||||
size_t begin = level[i];
|
||||
size_t end = level[i + 1];
|
||||
for (size_t j = begin; j < end; j++) {
|
||||
auto record = source.Slice<int>(j, j + 1);
|
||||
for (int dim = 0; dim < 128; dim++) {
|
||||
record.mutable_data<int>(platform::CPUPlace())[dim] = j - begin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unpack
|
||||
meta = ta.Unpack(source, 0, true);
|
||||
}
|
||||
|
||||
LoD lod;
|
||||
TensorArray ta;
|
||||
LoDTensor source;
|
||||
std::vector<DySeqMeta> meta;
|
||||
};
|
||||
|
||||
TEST_F(TensorArrayPackTester, Unpack) {
|
||||
ASSERT_EQ(ta.size(), 7UL);
|
||||
|
||||
const auto& t0 = ta.Read(0);
|
||||
const auto& t1 = ta.Read(1);
|
||||
|
||||
ASSERT_EQ(t0.data<int>()[0], int(0));
|
||||
ASSERT_EQ(t1.data<int>()[0], int(1));
|
||||
}
|
||||
|
||||
TEST_F(TensorArrayPackTester, Pack) {
|
||||
LoDTensor packed = ta.Pack(0, meta, lod);
|
||||
}
|
||||
|
||||
TEST_F(TensorArrayTester, size) {
|
||||
ASSERT_EQ(ta.size(), static_cast<size_t>(batch_size));
|
||||
}
|
||||
|
||||
} // namespace framework
|
||||
} // namespace paddle
|
@ -0,0 +1,38 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
|
||||
|
||||
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 <functional>
|
||||
#include <map>
|
||||
#include "paddle/platform/variant.h"
|
||||
|
||||
namespace paddle {
|
||||
namespace framework {
|
||||
class OperatorBase;
|
||||
using VariableNameMap = std::map<std::string, std::vector<std::string>>;
|
||||
|
||||
// The order should be as same as framework.proto
|
||||
using Attribute =
|
||||
boost::variant<boost::blank, int, float, std::string, std::vector<int>,
|
||||
std::vector<float>, std::vector<std::string>, bool,
|
||||
std::vector<bool>, BlockDesc*>;
|
||||
|
||||
using AttributeMap = std::unordered_map<std::string, Attribute>;
|
||||
|
||||
using OpCreator = std::function<OperatorBase*(
|
||||
const std::string& /*type*/, const VariableNameMap& /*inputs*/,
|
||||
const VariableNameMap& /*outputs*/, const AttributeMap& /*attrs*/)>;
|
||||
|
||||
} // namespace framework
|
||||
} // namespace paddle
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue