|
|
@ -11,6 +11,7 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License. */
|
|
|
|
limitations under the License. */
|
|
|
|
|
|
|
|
#include <paddle/fluid/operators/math/concat.h>
|
|
|
|
#include <numeric>
|
|
|
|
#include <numeric>
|
|
|
|
|
|
|
|
|
|
|
|
#include "paddle/fluid/framework/lod_rank_table.h"
|
|
|
|
#include "paddle/fluid/framework/lod_rank_table.h"
|
|
|
@ -24,6 +25,50 @@ namespace operators {
|
|
|
|
|
|
|
|
|
|
|
|
using LoD = framework::LoD;
|
|
|
|
using LoD = framework::LoD;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ArrayToLoDFunctor;
|
|
|
|
|
|
|
|
template <typename DeviceContext>
|
|
|
|
|
|
|
|
struct ArrayToLoDFunctorImpl {
|
|
|
|
|
|
|
|
const ArrayToLoDFunctor *prev_functor_;
|
|
|
|
|
|
|
|
DeviceContext *dev_ctx_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
|
|
|
void apply();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ArrayToLoDFunctor : public boost::static_visitor<void> {
|
|
|
|
|
|
|
|
std::vector<framework::Tensor> in;
|
|
|
|
|
|
|
|
mutable framework::Tensor *out;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename Place>
|
|
|
|
|
|
|
|
void operator()(Place place) const {
|
|
|
|
|
|
|
|
auto &pool = platform::DeviceContextPool::Instance();
|
|
|
|
|
|
|
|
if (std::is_same<Place, platform::CPUPlace>::value) {
|
|
|
|
|
|
|
|
Apply(static_cast<platform::CPUDeviceContext *>(pool.Get(place)));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
#ifdef PADDLE_WITH_CUDA
|
|
|
|
|
|
|
|
Apply(static_cast<platform::CUDADeviceContext *>(pool.Get(place)));
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
PADDLE_THROW("Fluid is not compiled with CUDA");
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename DeviceContext>
|
|
|
|
|
|
|
|
void Apply(DeviceContext *dev_ctx) const {
|
|
|
|
|
|
|
|
ArrayToLoDFunctorImpl<DeviceContext> functor;
|
|
|
|
|
|
|
|
functor.dev_ctx_ = dev_ctx;
|
|
|
|
|
|
|
|
functor.prev_functor_ = this;
|
|
|
|
|
|
|
|
framework::VisitDataType(framework::ToDataType(out->type()), functor);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename DeviceContext>
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
|
|
|
void ArrayToLoDFunctorImpl<DeviceContext>::apply() {
|
|
|
|
|
|
|
|
math::ConcatFunctor<DeviceContext, T> func;
|
|
|
|
|
|
|
|
func(*dev_ctx_, prev_functor_->in, 0, prev_functor_->out);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class ArrayToLoDTensorOp : public framework::OperatorBase {
|
|
|
|
class ArrayToLoDTensorOp : public framework::OperatorBase {
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
ArrayToLoDTensorOp(const std::string &type,
|
|
|
|
ArrayToLoDTensorOp(const std::string &type,
|
|
|
@ -47,14 +92,18 @@ class ArrayToLoDTensorOp : public framework::OperatorBase {
|
|
|
|
int rank = x[0].dims().size();
|
|
|
|
int rank = x[0].dims().size();
|
|
|
|
platform::Place place = x[0].place();
|
|
|
|
platform::Place place = x[0].place();
|
|
|
|
std::type_index data_type = x[0].type();
|
|
|
|
std::type_index data_type = x[0].type();
|
|
|
|
framework::DDim ins_dims = framework::slice_ddim(x[0].dims(), 1, rank);
|
|
|
|
|
|
|
|
int64_t batch_size = x[0].dims()[0];
|
|
|
|
int64_t batch_size = x[0].dims()[0];
|
|
|
|
|
|
|
|
framework::DDim ins_dims = rank > 1
|
|
|
|
|
|
|
|
? framework::slice_ddim(x[0].dims(), 1, rank)
|
|
|
|
|
|
|
|
: framework::make_ddim({0});
|
|
|
|
for (size_t i = 1; i < x.size(); ++i) {
|
|
|
|
for (size_t i = 1; i < x.size(); ++i) {
|
|
|
|
PADDLE_ENFORCE_EQ(framework::slice_ddim(x[i].dims(), 1, rank), ins_dims,
|
|
|
|
auto ins_i_dims = rank > 1 ? framework::slice_ddim(x[i].dims(), 1, rank)
|
|
|
|
|
|
|
|
: framework::make_ddim({0});
|
|
|
|
|
|
|
|
PADDLE_ENFORCE_EQ(ins_i_dims, ins_dims,
|
|
|
|
"The dimension of the %zu'th element in LoDTensorArray "
|
|
|
|
"The dimension of the %zu'th element in LoDTensorArray "
|
|
|
|
"differs from previous ones.",
|
|
|
|
"differs from previous ones.",
|
|
|
|
i);
|
|
|
|
i);
|
|
|
|
PADDLE_ENFORCE(platform::places_are_same_class(x[i].place(), place),
|
|
|
|
PADDLE_ENFORCE(x[i].place() == place,
|
|
|
|
"The place class of the %zu'th element in LoDTensorArray "
|
|
|
|
"The place class of the %zu'th element in LoDTensorArray "
|
|
|
|
"differs from previous ones.",
|
|
|
|
"differs from previous ones.",
|
|
|
|
i);
|
|
|
|
i);
|
|
|
@ -82,13 +131,14 @@ class ArrayToLoDTensorOp : public framework::OperatorBase {
|
|
|
|
// Build LoDTensor `out`
|
|
|
|
// Build LoDTensor `out`
|
|
|
|
framework::LoD *out_lod = out->mutable_lod();
|
|
|
|
framework::LoD *out_lod = out->mutable_lod();
|
|
|
|
out_lod->clear();
|
|
|
|
out_lod->clear();
|
|
|
|
size_t out_offset = 0;
|
|
|
|
|
|
|
|
auto prefix_lod = rank_table.coarse_lod();
|
|
|
|
auto prefix_lod = rank_table.coarse_lod();
|
|
|
|
prefix_lod.emplace_back();
|
|
|
|
prefix_lod.emplace_back();
|
|
|
|
auto &cur_level_lod = prefix_lod.back();
|
|
|
|
auto &cur_level_lod = prefix_lod.back();
|
|
|
|
cur_level_lod.push_back(0);
|
|
|
|
cur_level_lod.push_back(0);
|
|
|
|
|
|
|
|
ArrayToLoDFunctor functor;
|
|
|
|
for (size_t idx : table_item_idx) {
|
|
|
|
for (size_t idx : table_item_idx) {
|
|
|
|
cur_level_lod.push_back(cur_level_lod.back() + table_items[idx].length);
|
|
|
|
cur_level_lod.push_back(cur_level_lod.back() + table_items[idx].length);
|
|
|
|
|
|
|
|
PADDLE_ENFORCE_LE(table_items[idx].length, x.size());
|
|
|
|
for (size_t x_idx = 0; x_idx < table_items[idx].length; ++x_idx) {
|
|
|
|
for (size_t x_idx = 0; x_idx < table_items[idx].length; ++x_idx) {
|
|
|
|
auto lod_and_offset = framework::GetSubLoDAndAbsoluteOffset(
|
|
|
|
auto lod_and_offset = framework::GetSubLoDAndAbsoluteOffset(
|
|
|
|
x[x_idx].lod(), idx, idx + 1, 0);
|
|
|
|
x[x_idx].lod(), idx, idx + 1, 0);
|
|
|
@ -106,17 +156,11 @@ class ArrayToLoDTensorOp : public framework::OperatorBase {
|
|
|
|
if (len == 0) {
|
|
|
|
if (len == 0) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
auto slice = out->Slice(out_offset, out_offset + len);
|
|
|
|
functor.in.emplace_back(x[x_idx].Slice(start_offset, end_offset));
|
|
|
|
|
|
|
|
|
|
|
|
platform::DeviceContextPool &pool =
|
|
|
|
|
|
|
|
platform::DeviceContextPool::Instance();
|
|
|
|
|
|
|
|
auto &dev_ctx = *pool.Get(place);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
framework::TensorCopy(x[x_idx].Slice(start_offset, end_offset), place,
|
|
|
|
|
|
|
|
dev_ctx, &slice);
|
|
|
|
|
|
|
|
out_offset += len;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
functor.out = out;
|
|
|
|
|
|
|
|
platform::VisitPlace(place, functor);
|
|
|
|
out_lod->insert(out_lod->begin(), prefix_lod.begin(), prefix_lod.end());
|
|
|
|
out_lod->insert(out_lod->begin(), prefix_lod.begin(), prefix_lod.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|