未验证 提交 f637e3d2 编写于 作者: C Chen Weihang 提交者: GitHub

[Cherry-pick] Polish custom op details (#42008)

* polish tensor api details (#41971)

* [CustomOp] Fix custom op pinned input error (#41972)

* fix custom op pinned input error

* fix compile error

* fix inference custom op (#41999)

* resolve conflict
上级 1e18b57b
...@@ -248,15 +248,21 @@ copy(inference_lib_dist ...@@ -248,15 +248,21 @@ copy(inference_lib_dist
copy(inference_lib_dist copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/phi/common/*.h SRCS ${PADDLE_SOURCE_DIR}/paddle/phi/common/*.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/common/) DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/common/)
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/phi/core/macros.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/core/)
copy(inference_lib_dist copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/any.h SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/any.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/) DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/)
copy(inference_lib_dist copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/optional.h SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/optional.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/) DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/)
copy(inference_lib_dist copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/none.h SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/none.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/) DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/)
copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/utils/flat_hash_map.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/utils/)
copy(inference_lib_dist copy(inference_lib_dist
SRCS ${PADDLE_SOURCE_DIR}/paddle/extension.h SRCS ${PADDLE_SOURCE_DIR}/paddle/extension.h
DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/) DSTS ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/)
......
...@@ -36,7 +36,8 @@ phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experiment ...@@ -36,7 +36,8 @@ phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experiment
phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/api/ext) phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/api/ext)
phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/api/include) phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/api/include)
phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/common) phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/common)
phi_header_path_compat(${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/phi/core)
# In order to be compatible with the original behavior, the header file name needs to be changed # 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 file(RENAME ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/extension.h
${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/ext_all.h) ${PADDLE_INFERENCE_INSTALL_DIR}/paddle/include/experimental/ext_all.h)
\ No newline at end of file
...@@ -33,6 +33,7 @@ limitations under the License. */ ...@@ -33,6 +33,7 @@ limitations under the License. */
#include "paddle/fluid/framework/operator.h" #include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/framework/phi_utils.h" #include "paddle/fluid/framework/phi_utils.h"
#include "paddle/fluid/framework/tensor.h" #include "paddle/fluid/framework/tensor.h"
#include "paddle/fluid/platform/device/gpu/gpu_info.h"
#include "paddle/fluid/platform/dynload/dynamic_loader.h" #include "paddle/fluid/platform/dynload/dynamic_loader.h"
#include "paddle/fluid/string/string_helper.h" #include "paddle/fluid/string/string_helper.h"
#include "paddle/phi/api/all.h" #include "paddle/phi/api/all.h"
...@@ -160,7 +161,18 @@ static void RunKernelFunc(const framework::ExecutionContext& ctx, ...@@ -160,7 +161,18 @@ static void RunKernelFunc(const framework::ExecutionContext& ctx,
"Input tensor (%s) is not initialized.", in_name)); "Input tensor (%s) is not initialized.", in_name));
paddle::experimental::Tensor custom_in; paddle::experimental::Tensor custom_in;
custom_in.set_impl(std::make_shared<phi::DenseTensor>(*x)); custom_in.set_impl(std::make_shared<phi::DenseTensor>(*x));
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
if (custom_in.is_gpu_pinned()) {
VLOG(3) << "Custom Operator: custom input is gpu pinned tensor";
auto gpu_place = phi::GPUPlace(platform::GetCurrentDeviceId());
auto custom_gpu_in = custom_in.copy_to(gpu_place, true);
kernel_ctx.EmplaceBackInput(std::move(custom_gpu_in));
} else {
kernel_ctx.EmplaceBackInput(std::move(custom_in));
}
#else
kernel_ctx.EmplaceBackInput(std::move(custom_in)); kernel_ctx.EmplaceBackInput(std::move(custom_in));
#endif
} }
} }
......
...@@ -166,7 +166,7 @@ class PADDLE_API Tensor final { ...@@ -166,7 +166,7 @@ class PADDLE_API Tensor final {
* *
* @return phi::DDim * @return phi::DDim
*/ */
phi::DDim dims() const; const phi::DDim& dims() const;
/** /**
* @brief Return the shape (dimensions) of Tensor. * @brief Return the shape (dimensions) of Tensor.
...@@ -260,7 +260,7 @@ class PADDLE_API Tensor final { ...@@ -260,7 +260,7 @@ class PADDLE_API Tensor final {
* *
* @return Place * @return Place
*/ */
Place place() const; const Place& place() const;
/** /**
* @brief Determine whether the tensor device is CPU * @brief Determine whether the tensor device is CPU
...@@ -421,7 +421,7 @@ class PADDLE_API Tensor final { ...@@ -421,7 +421,7 @@ class PADDLE_API Tensor final {
* @param blocking, Should we copy this in sync way. * @param blocking, Should we copy this in sync way.
* @return Tensor * @return Tensor
*/ */
Tensor copy_to(Place place, bool blocking) const; Tensor copy_to(const Place& place, bool blocking) const;
/** /**
* @brief Transfer the source Tensor to current Tensor. * @brief Transfer the source Tensor to current Tensor.
......
...@@ -110,7 +110,7 @@ int64_t Tensor::numel() const { return impl_->numel(); } ...@@ -110,7 +110,7 @@ int64_t Tensor::numel() const { return impl_->numel(); }
int64_t Tensor::size() const { return impl_->numel(); } int64_t Tensor::size() const { return impl_->numel(); }
phi::DDim Tensor::dims() const { return impl_->dims(); } const phi::DDim &Tensor::dims() const { return impl_->dims(); }
std::vector<int64_t> Tensor::shape() const { std::vector<int64_t> Tensor::shape() const {
auto dims = impl_->dims(); auto dims = impl_->dims();
...@@ -158,7 +158,7 @@ bool Tensor::is_string_tensor() const { ...@@ -158,7 +158,7 @@ bool Tensor::is_string_tensor() const {
} }
/* Part 3: Device and Backend methods */ /* Part 3: Device and Backend methods */
Place Tensor::place() const { const Place &Tensor::place() const {
PADDLE_ENFORCE_NOT_NULL( PADDLE_ENFORCE_NOT_NULL(
impl_, impl_,
phi::errors::PermissionDenied( phi::errors::PermissionDenied(
......
...@@ -27,13 +27,13 @@ namespace paddle { ...@@ -27,13 +27,13 @@ namespace paddle {
namespace experimental { namespace experimental {
// declare cast api // declare cast api
Tensor cast(const Tensor &x, DataType out_dtype); Tensor cast(const Tensor &x, DataType out_dtype);
Tensor copy_to(const Tensor &x, Place place, bool blocking); Tensor copy_to(const Tensor &x, const Place &place, bool blocking);
Tensor Tensor::cast(DataType target_type) const { Tensor Tensor::cast(DataType target_type) const {
return experimental::cast(*this, target_type); return experimental::cast(*this, target_type);
} }
Tensor Tensor::copy_to(Place place, bool blocking) const { Tensor Tensor::copy_to(const Place &place, bool blocking) const {
return experimental::copy_to(*this, place, blocking); return experimental::copy_to(*this, place, blocking);
} }
......
...@@ -20,6 +20,7 @@ import paddle ...@@ -20,6 +20,7 @@ import paddle
import paddle.static as static import paddle.static as static
import subprocess import subprocess
import numpy as np import numpy as np
from paddle.vision.transforms import Compose, Normalize
from paddle.utils.cpp_extension.extension_utils import run_cmd from paddle.utils.cpp_extension.extension_utils import run_cmd
from paddle.fluid.framework import _test_eager_guard from paddle.fluid.framework import _test_eager_guard
...@@ -329,6 +330,33 @@ class TestNewCustomOpSetUpInstall(unittest.TestCase): ...@@ -329,6 +330,33 @@ class TestNewCustomOpSetUpInstall(unittest.TestCase):
"custom op dx grad: {},\n paddle api dx grad: {}".format( "custom op dx grad: {},\n paddle api dx grad: {}".format(
dx_grad, pd_dx_grad)) dx_grad, pd_dx_grad))
def test_with_dataloader(self):
for device in self.devices:
paddle.set_device(device)
# data loader
transform = Compose(
[Normalize(
mean=[127.5], std=[127.5], data_format='CHW')])
train_dataset = paddle.vision.datasets.MNIST(
mode='train', transform=transform)
train_loader = paddle.io.DataLoader(
train_dataset,
batch_size=64,
shuffle=True,
drop_last=True,
num_workers=0)
for batch_id, (image, _) in enumerate(train_loader()):
out = self.custom_ops[0](image)
pd_out = paddle.nn.functional.relu(image)
self.assertTrue(
np.array_equal(out, pd_out),
"custom op out: {},\n paddle api out: {}".format(out,
pd_out))
if batch_id == 5:
break
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -103,7 +103,7 @@ class BaseAPI(object): ...@@ -103,7 +103,7 @@ class BaseAPI(object):
'double': 'double', 'double': 'double',
'bool': 'bool', 'bool': 'bool',
'str': 'const std::string&', 'str': 'const std::string&',
'Place': 'Place', 'Place': 'const Place&',
'DataLayout': 'DataLayout', 'DataLayout': 'DataLayout',
'DataType': 'DataType', 'DataType': 'DataType',
'int64_t[]': 'const std::vector<int64_t>&', 'int64_t[]': 'const std::vector<int64_t>&',
...@@ -118,7 +118,7 @@ class BaseAPI(object): ...@@ -118,7 +118,7 @@ class BaseAPI(object):
'float': 'paddle::optional<float>', 'float': 'paddle::optional<float>',
'double': 'paddle::optional<double>', 'double': 'paddle::optional<double>',
'bool': 'paddle::optional<bool>', 'bool': 'paddle::optional<bool>',
'Place': 'paddle::optional<Place>', 'Place': 'paddle::optional<const Place&>',
'DataLayout': 'paddle::optional<DataLayout>', 'DataLayout': 'paddle::optional<DataLayout>',
'DataType': 'paddle::optional<DataType>' 'DataType': 'paddle::optional<DataType>'
} }
...@@ -329,7 +329,7 @@ PADDLE_API {self.gene_return_type_code()} {self.get_api_func_name() + '_'}({self ...@@ -329,7 +329,7 @@ PADDLE_API {self.gene_return_type_code()} {self.get_api_func_name() + '_'}({self
assert len( assert len(
vars_list vars_list
) == 2, f"{self.api} api: The number of params to set backend with '>' only allows 2, but received {len(vars_list)}." ) == 2, f"{self.api} api: The number of params to set backend with '>' only allows 2, but received {len(vars_list)}."
assert (vars_list[0].strip() in self.attrs['names']) and (self.attrs['attr_info'][vars_list[0].strip()][0] == 'Place'), \ assert (vars_list[0].strip() in self.attrs['names']) and (self.attrs['attr_info'][vars_list[0].strip()][0] == 'const Place&'), \
f"{self.api} api: When use '>' to set kernel backend, the first param should be a attribute with Place type." f"{self.api} api: When use '>' to set kernel backend, the first param should be a attribute with Place type."
backend_select_code = f""" backend_select_code = f"""
kernel_backend = ParseBackendWithInputOrder({vars_list[0].strip()}, {vars_list[1].strip()}); kernel_backend = ParseBackendWithInputOrder({vars_list[0].strip()}, {vars_list[1].strip()});
...@@ -361,7 +361,7 @@ PADDLE_API {self.gene_return_type_code()} {self.get_api_func_name() + '_'}({self ...@@ -361,7 +361,7 @@ PADDLE_API {self.gene_return_type_code()} {self.get_api_func_name() + '_'}({self
attr_layout_count = 0 attr_layout_count = 0
attr_data_type_count = 0 attr_data_type_count = 0
for attr_name in attrs['names']: for attr_name in attrs['names']:
if attrs['attr_info'][attr_name][0] == 'Place': if attrs['attr_info'][attr_name][0] == 'const Place&':
assert kernel['backend'] is not None, \ assert kernel['backend'] is not None, \
f"{api} api: When there is a parameter with 'Place' type in attributes, you must set backend of kernel manually." f"{api} api: When there is a parameter with 'Place' type in attributes, you must set backend of kernel manually."
attr_backend_count = attr_backend_count + 1 attr_backend_count = attr_backend_count + 1
...@@ -421,7 +421,7 @@ PADDLE_API {self.gene_return_type_code()} {self.get_api_func_name() + '_'}({self ...@@ -421,7 +421,7 @@ PADDLE_API {self.gene_return_type_code()} {self.get_api_func_name() + '_'}({self
if len(input_names) == 0: if len(input_names) == 0:
assert attr_backend_count > 0 and attr_data_type_count > 0, \ assert attr_backend_count > 0 and attr_data_type_count > 0, \
f"{api} api: When there is no input tensor, the args must have 'Backend' and 'DataType'." f"{api} api: When there is no input tensor, the args must have 'Place' and 'DataType'."
kernel_select_args = "" kernel_select_args = ""
for input_name in input_names: for input_name in input_names:
......
...@@ -225,7 +225,7 @@ PADDLE_API {self.outputs['return_type']} {self.get_api_func_name()}({self.args_s ...@@ -225,7 +225,7 @@ PADDLE_API {self.outputs['return_type']} {self.get_api_func_name()}({self.args_s
assert len( assert len(
vars_list vars_list
) == 2, f"{api} api: The number of params to set backend with '>' only allows 2, but received {len(vars_list)}." ) == 2, f"{api} api: The number of params to set backend with '>' only allows 2, but received {len(vars_list)}."
assert (vars_list[0].strip() in attrs['names']) and (attrs['attr_info'][vars_list[0].strip()][0] == 'Place'), \ assert (vars_list[0].strip() in attrs['names']) and (attrs['attr_info'][vars_list[0].strip()][0] == 'const Place&'), \
f"{api} api: When use '>' to set kernel backend, the first param should be a attribute with Place type." f"{api} api: When use '>' to set kernel backend, the first param should be a attribute with Place type."
kernel_select_code = kernel_select_code + f""" kernel_select_code = kernel_select_code + f"""
kernel_backend = ParseBackendWithInputOrder({vars_list[0].strip()}, {vars_list[1].strip()}); kernel_backend = ParseBackendWithInputOrder({vars_list[0].strip()}, {vars_list[1].strip()});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册