Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
Browse files Browse the repository at this point in the history
… fix_transform
  • Loading branch information
zhiqiu committed Nov 23, 2021
2 parents 6391c4c + 90dad8b commit c29a9f4
Show file tree
Hide file tree
Showing 123 changed files with 3,368 additions and 633 deletions.
27 changes: 14 additions & 13 deletions cmake/inference_lib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,7 @@ copy(inference_lib_dist
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/crypto/)
include_directories(${CMAKE_BINARY_DIR}/../paddle/fluid/framework/io)

# TODO(chenweihang, before 11.27) Here, the header file of pten is copied to
# the experimental directory, the include path needs to be changed, so the
# header file path needs to be processed here
# copy api headers for custom op
# copy api headers for pten & custom op
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/pten/api/ext/*
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/api/ext/)
Expand All @@ -231,21 +228,25 @@ copy(inference_lib_dist
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/api/)
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/pten/common/*
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common/)
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/fluid/platform/complex.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common/)
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/fluid/platform/float16.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common/)
${PADDLE_SOURCE_DIR}/paddle/fluid/platform/bfloat16.h
${PADDLE_SOURCE_DIR}/paddle/fluid/platform/complex.h
${PADDLE_SOURCE_DIR}/paddle/fluid/platform/float16.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common/
${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common/
${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common/
${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common/)
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/any.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/)
# In order to be compatible with the original behavior, the header file name needs to be changed
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/extension.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/ext_all.h)
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/)

# the header file of pten is copied to the experimental directory,
# the include path of pten needs to be changed to adapt to inference api path
add_custom_command(TARGET inference_lib_dist POST_BUILD
COMMAND ${CMAKE_COMMAND} -P "${PADDLE_SOURCE_DIR}/cmake/pten.cmake"
COMMENT "Change pten header include path to adapt to inference api path")

# CAPI inference library for only inference
set(PADDLE_INFERENCE_C_INSTALL_DIR "${CMAKE_BINARY_DIR}/paddle_inference_c_install_dir" CACHE STRING
Expand Down
43 changes: 43 additions & 0 deletions cmake/pten.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 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.

set(PADDLE_INFERENCE_INSTALL_DIR "${CMAKE_BINARY_DIR}/paddle_inference_install_dir")

function(pten_header_path_compat TARGET_PATH)
message(STATUS "pten header path compat processing: ${TARGET_PATH}")
string(FIND ${TARGET_PATH} "experimental" pos)
if (pos GREATER 1)
file(GLOB HEADERS "${TARGET_PATH}/*" "*.h")
foreach(header ${HEADERS})
string(FIND ${header} ".h" hpos)
if (hpos GREATER 1)
file(READ ${header} HEADER_CONTENT)
string(REPLACE "paddle/pten/" "paddle/include/experimental/pten/" HEADER_CONTENT "${HEADER_CONTENT}")
string(REPLACE "paddle/utils/" "paddle/include/experimental/utils/" HEADER_CONTENT "${HEADER_CONTENT}")
file(WRITE ${header} "${HEADER_CONTENT}")
message(STATUS "pten header path compat processing complete: ${header}")
endif()
endforeach()
endif()
endfunction()

pten_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental)
pten_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/api)
pten_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/api/ext)
pten_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/api/include)
pten_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/pten/common)

# In order to be compatible with the original behavior, the header file name needs to be changed
file(RENAME ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/extension.h
${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/ext_all.h)
1 change: 1 addition & 0 deletions paddle/fluid/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_subdirectory(imperative)
add_subdirectory(operators)
add_subdirectory(string)
add_subdirectory(pybind)
add_subdirectory(eager)

# NOTE: please add subdirectory inference at last.
add_subdirectory(inference)
1 change: 1 addition & 0 deletions paddle/fluid/eager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(tests)
264 changes: 264 additions & 0 deletions paddle/fluid/eager/eager_tensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
// 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
// framework deps
#include "paddle/fluid/framework/data_layout_transform.h"
#include "paddle/fluid/framework/pten_utils.h"
#include "paddle/fluid/framework/tensor.h"
#include "paddle/fluid/framework/variable.h"
// pten deps
#include "paddle/pten/all.h"
#include "paddle/pten/api/all.h"
#include "paddle/pten/api/lib/utils/tensor_utils.h"
/**
* This class is used by Eager mode for now. It's painful to do this in Eager
* Mode, the better
* choice is to use paddle::experimental::Tensor directly. However, we have a
* punch of nested kernel code, and
* they use paddle::framework::Variable in inner logic code. So, we have to
* provide variable in
* paddle::framework::ExecutionContext to support it. We should remove this as
* soon as we finish our latest
* Pten Lib, and use paddle::experimental::Tensor instead.
*
* Note: Keep this class as clean as possible.
* This class should only support method declared in
* paddle::experimental::Tensor with access method of
* paddle::framework::Variable no more members are acceptable.
* **/

namespace egr {
class EagerTensor final {
public:
/* Part 1: Constructors */
EagerTensor()
: tensor_(std::make_shared<paddle::experimental::Tensor>()),
var_(paddle::framework::Variable()) {}
explicit EagerTensor(const std::string& name)
: tensor_(std::make_shared<paddle::experimental::Tensor>(name)),
var_(paddle::framework::Variable()) {}
/**
* @description: Use a TensorImpl pointer to construct a Tensor
* @param {shared_ptr<TensorBase>} tensor_impl
* @return {Tensor}
*/
explicit EagerTensor(const std::shared_ptr<pten::TensorBase>& tensor_impl)
: tensor_(std::make_shared<paddle::experimental::Tensor>(tensor_impl)),
var_(paddle::framework::Variable()) {}
EagerTensor(const EagerTensor&) = default;
EagerTensor(EagerTensor&&) = default;

/* Part 2: Name access methods */
/**
* @description: Return the name of current Tensor.
* @param None
* @return {const std::string&}
*/
const std::string& name() const { return tensor_->name(); }
/**
* @description: Set the name of current Tensor.
* @param {const std::string& name}
* @return None
*/
void set_name(const std::string& name) { tensor_->set_name(name); }

/* Part 3: Dimension, DataType and DataLayout methods */
/**
* @description: Return the number of elements of current Tensor.
* @param None
* @return {int64_t}
*/
int64_t numel() const { return tensor_->numel(); }
/**
* @description: Return the shape (dimensions) of current Tensor.
* @param None
* @return {DDim}
*/
paddle::framework::DDim shape() const { return tensor_->dims(); }

/**
* @description: Return the data type of current Tensor.
* @param None
* @return {DataType}
*/
paddle::experimental::DataType type() const { return tensor_->type(); }

/**
* @description: Return the layout of current Tensor.
* @param None
* @return {DataLayout}
*/
paddle::experimental::DataLayout layout() const { return tensor_->layout(); }

/* Part 3: Device and Backend methods */
/**
* @description: Return the place (device) of current Tensor.
* @param None
* @return {Place}
*/
paddle::platform::Place place() const { return tensor_->inner_place(); }

/**
* Backend judgment APIs, shield the concept of Backend.
*/
bool is_cpu() const { return paddle::platform::is_cpu_place(place()); }
bool is_cuda() const { return paddle::platform::is_gpu_place(place()); }

/* Part 4: Data Access methods */
/**
* @description: Return the implemention of current Tensor.
* @param None
* @return {std::shared_ptr<TensorBase>}
*/
std::shared_ptr<pten::TensorBase> impl() const { return tensor_->impl(); }

/**
* @description: Set the implemention of current Tensor.
* @param {std::shared_ptr<TensorBase>}
* @return None
*/
void set_impl(const std::shared_ptr<pten::TensorBase>& impl) {
tensor_->set_impl(impl);
}

// TODO(chenweihang): Whether API Tensor need `data` and `mutable_data`?

// TODO(chenweihang): slice and split methods use kernels?

/* Part 5: Status utils methods */
/**
* @description: Determine whether it is a meaningful Tensor
* @param None
* @return {bool}
*/
bool defined() const { return tensor_->defined(); }

/**
* @description: Determine whether Tensor is initialized
* @param None
* @return {bool}
*/
bool initialized() const { return tensor_->initialized(); }

/**
* @description: Reset the Tensor implementation
* @param None
* @return {void}
*/
void reset() { tensor_->reset(); }

/* Part 6: Operator overloading */
EagerTensor& operator=(const EagerTensor& x) & {
tensor_ = x.tensor_;
var_ = x.var_;
return *this;
}
EagerTensor& operator=(EagerTensor&& x) & {
tensor_ = std::move(x.tensor_);
var_ = std::move(x.var_);
return *this;
}

/* Part 7: Autograd methods */
paddle::experimental::AbstractAutogradMeta* get_autograd_meta() const {
return tensor_->get_autograd_meta();
}
void set_autograd_meta(
std::shared_ptr<paddle::experimental::AbstractAutogradMeta>
autograd_meta) {
tensor_->set_autograd_meta(autograd_meta);
}

/** Part 9: Get framework::Variable from EagerTensor **/
const paddle::framework::Variable& Var() const { return var_; }

paddle::framework::Variable* MutableVar() { return &var_; }

/** Part 10: Sync paddle::framework::Variable with pten::Tensor **/
void SyncToVar(paddle::framework::proto::VarType_Type type =
paddle::framework::proto::VarType::LOD_TENSOR) {
// Synchronize allocation only once.
if (!var_.IsInitialized()) {
// TODO(jiabin): Support selected rows later.
if (this->initialized()) {
if (type == paddle::framework::proto::VarType::LOD_TENSOR) {
auto* framework_tensor =
var_.GetMutable<paddle::framework::LoDTensor>();
framework_tensor->Resize(tensor_->dims());
framework_tensor->set_layout(
pten::TransToFluidDataLayout(tensor_->layout()));
// Contruct framework::Tensor from egr::EagerTensor
auto tensor_dense =
std::dynamic_pointer_cast<pten::DenseTensor>(tensor_->impl());
if (tensor_dense) {
paddle::experimental::MovesStorage(tensor_dense.get(),
framework_tensor);
} else {
PADDLE_THROW(paddle::platform::errors::Fatal(
"Unrecognized egr::EagerTensor type, only "
"DenseTensor is supported for now."));
}
}
} else {
PADDLE_THROW(paddle::platform::errors::Fatal(
"Can not Sync EagerTensor %s whose "
"pten::DenseTensor is not initialized!",
name()));
}
}
}
/** Part 11: Sync paddle::framework::Variable with pten::Tensor **/
void SyncToTensor() {
// Synchronize allocation only once.
if (!this->defined() || !this->initialized()) {
// TODO(jiabin): Support selected rows later.
if (var_.IsInitialized()) {
if (var_.IsType<paddle::framework::LoDTensor>()) {
SetImplWithLegacyTensor<paddle::framework::LoDTensor,
pten::DenseTensor>();
} else if (var_.IsType<paddle::framework::Tensor>()) {
SetImplWithLegacyTensor<paddle::framework::Tensor,
pten::DenseTensor>();
} else {
PADDLE_THROW(paddle::platform::errors::Fatal(
"Unable to fetch underlying tensor "
"from VarBase, only LoDTensor and "
"Tensor are supported for now"));
}
} else {
PADDLE_THROW(paddle::platform::errors::Fatal(
"Can not Sync EagerTensor %s whose paddle::framework::Variable is "
"not initialized!",
name()));
}
}
}

void ResetVar(const paddle::framework::Variable& src) { var_ = src; }

private:
template <typename LEGACY_TYPE, typename TYPE>
void SetImplWithLegacyTensor() {
const auto& framework_tensor = var_.Get<LEGACY_TYPE>();
this->set_impl(
std::move(paddle::experimental::MakePtenDenseTensor(framework_tensor)));
var_.Clear();
}

private:
std::shared_ptr<paddle::experimental::Tensor> tensor_ = nullptr;
paddle::framework::Variable var_;
};
} // namespace egr
2 changes: 2 additions & 0 deletions paddle/fluid/eager/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
set(eager_deps pten pten_api)
add_subdirectory(data_structure_tests)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cc_test(test_egr_ds_eager_tensor SRCS eager_tensor_test.cc DEPS ${eager_deps})
Loading

1 comment on commit c29a9f4

@paddle-bot-old
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulation! Your pull request passed all required CI. You could ask reviewer(s) to approve and merge. 🎉

Please sign in to comment.