Skip to content

Commit c86e7e2

Browse files
authored
Merge pull request PaddlePaddle#4101 from luotao1/use_op
auto generate USE_OP() in pybind.cc
2 parents 7a9c89f + 65bc5fc commit c86e7e2

File tree

9 files changed

+48
-88
lines changed

9 files changed

+48
-88
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ cmake-build-*
2222

2323
# generated while compiling
2424
python/paddle/v2/framework/core.so
25+
paddle/pybind/pybind.h
2526
CMakeFiles
2627
cmake_install.cmake
2728
paddle/.timestamp

cmake/cpplint.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ set(IGNORE_PATTERN
2626
.*ImportanceSampler.*
2727
.*cblas\\.h.*
2828
.*\\.pb\\.txt
29-
.*LtrDataProvider.*
3029
.*MultiDataProvider.*
31-
.*pb.*)
30+
.*pb.*
31+
.*pybind.h)
3232

3333
# add_style_check_target
3434
#

doc/howto/dev/new_op_cn.md

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Kernel实现 | CPU、GPU共享Kernel实现在`.h`文件中,否则,CPU
3434
注册Op | Op注册实现在`.cc`文件;Kernel注册CPU实现在`.cc`文件中,GPU实现在`.cu`文件中
3535

3636

37-
实现新的op都添加至目录[paddle/operators](https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/operators)下,文件命名以`*_op.h`(如有) 、 `*_op.cc``*_op.cu`(如有)结尾。
37+
实现新的op都添加至目录[paddle/operators](https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/operators)下,文件命名以`*_op.h`(如有) 、 `*_op.cc``*_op.cu`(如有)结尾。**系统会根据文件名自动构建op和其对应的Python扩展。**
3838

3939

4040
下面以矩阵乘操作,即[MulOp](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/mul_op.cc)为例来介绍如何写带Kernel的Operator。
@@ -224,45 +224,15 @@ MulOp(const std::string &type, const framework::VariableNameMap &inputs,
224224

225225
### 5. 编译
226226

227-
- 简单**无特殊依赖**的OP无需修改CMakeList.txt文件。[paddle/operators/CMakeLists.txt](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/CMakeLists.txt) 会自动将 `paddle/operators` 目录下新增的 `*_op.cc` 文件加入编译。
228-
- 较为复杂、**有额外依赖** 的operator仍需要修改[paddle/operators/CMakeLists.txt](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/CMakeLists.txt)。如,`mul_op` 依赖 `math_function`,需要在`CMakeLists.txt`中添加如下内容:
227+
运行下面命令可以进行编译:
229228

230-
```
231-
op_library(mul_op SRCS mul_op.cc mul_op.cu DEPS math_function) +
232-
```
233-
234-
- 运行下面命令可以进行编译:
235-
236-
```
237-
make mul_op
238-
```
229+
```
230+
make mul_op
231+
```
239232

240233
## 绑定Python
241234

242-
- 绑定Python
243-
244-
在 [`paddle/pybind/pybind.cc
245-
`](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/pybind/pybind.cc) 使用`USE_OP`告知编译器需要链接的Op,具体解释参考[代码注释](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/op_registry.h#L81)。
246-
247-
```
248-
USE_OP(mul);
249-
```
250-
如果只实现了CPU版本,则使用`USE_CPU_ONLY_OP`:
251-
252-
```
253-
USE_CPU_ONLY_OP(gather);
254-
```
255-
256-
如果OP不带Kernel,则使用`USE_NO_KENREL_OP`:
257-
258-
```
259-
USE_NO_KENREL_OP(recurrent);
260-
```
261-
262-
263-
- 生成库
264-
265-
`paddle/operators` 目录下新增的 `*_op.cc` 文件会被自动添加链接到生成的lib库中。
235+
系统会对新增的op自动绑定Python,并链接到生成的lib库中。
266236

267237
## 实现单元测试
268238

@@ -367,3 +337,10 @@ make test ARGS="-R test_mul_op -V"
367337
```bash
368338
ctest -R test_mul_op
369339
```
340+
341+
## 注意事项
342+
343+
- 为每个Op创建单独的`*_op.h`(如有)、`*_op.cc``*_op.cu`(如有)。不允许一个文件中包含多个Op,这将会导致编译出错。
344+
- 注册Op时的类型名,需要和该Op的名字一样。即不允许在`A_op.cc`里面,注册`REGISTER_OP(B, ...)`等,这将会导致单元测试出错。
345+
- 如果Op没有实现GPU Kernel,请不要创建空的`*_op.cu`,这将会导致单元测试出错。
346+
- 如果多个Op依赖一些共用的函数,可以创建非`*_op.*`格式的文件来存放,如`gather.h`文件。

paddle/operators/CMakeLists.txt

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
file(GLOB GENERAL_OPS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*_op.cc")
22
string(REPLACE ".cc" "" GENERAL_OPS "${GENERAL_OPS}")
3+
set(pybind_file ${PADDLE_SOURCE_DIR}/paddle/pybind/pybind.h)
4+
file(WRITE ${pybind_file} "// Generated by the paddle/operator/CMakeLists.txt. DO NOT EDIT!\n\n")
35
function(op_library TARGET)
46
# op_library is a function to create op library. The interface is same as
57
# cc_library. But it handle split GPU/CPU code and link some common library
@@ -11,6 +13,7 @@ function(op_library TARGET)
1113
set(options "")
1214
set(oneValueArgs "")
1315
set(multiValueArgs SRCS DEPS)
16+
set(pybind_flag 0)
1417
cmake_parse_arguments(op_library "${options}" "${oneValueArgs}"
1518
"${multiValueArgs}" ${ARGN})
1619

@@ -46,15 +49,40 @@ function(op_library TARGET)
4649
cc_library(${TARGET} SRCS ${cc_srcs} DEPS ${op_library_DEPS}
4750
${op_common_deps})
4851
endif()
52+
53+
# net_op doesn't need pybind
54+
if ("${TARGET}" STREQUAL "net_op")
55+
set(pybind_flag 1)
56+
endif()
57+
58+
# pybind USE_NO_KERNEL_OP
59+
file(READ ${TARGET}.cc TARGET_CONTENT)
60+
string(REGEX MATCH "OperatorWithKernel" regex_result "${TARGET_CONTENT}")
61+
string(REPLACE "_op" "" TARGET "${TARGET}")
62+
if (${pybind_flag} EQUAL 0 AND regex_result STREQUAL "")
63+
file(APPEND ${pybind_file} "USE_NO_KERNEL_OP(${TARGET});\n")
64+
set(pybind_flag 1)
65+
endif()
66+
67+
# pybind USE_CPU_ONLY_OP
68+
list(LENGTH cu_srcs cu_srcs_len)
69+
if (${pybind_flag} EQUAL 0 AND ${cu_srcs_len} EQUAL 0)
70+
file(APPEND ${pybind_file} "USE_CPU_ONLY_OP(${TARGET});\n")
71+
set(pybind_flag 1)
72+
endif()
73+
74+
# pybind USE_OP
75+
if (${pybind_flag} EQUAL 0)
76+
file(APPEND ${pybind_file} "USE_OP(${TARGET});\n")
77+
endif()
4978
endfunction()
5079

5180
add_subdirectory(math)
5281

5382
set(DEPS_OPS
5483
recurrent_op)
55-
5684
op_library(recurrent_op SRCS recurrent_op.cc rnn/recurrent_op_utils.cc
57-
DEPS framework_proto tensor operator net_op)
85+
DEPS framework_proto tensor net_op)
5886

5987
list(REMOVE_ITEM GENERAL_OPS ${DEPS_OPS})
6088
foreach(src ${GENERAL_OPS})

paddle/operators/concat_op.cu

Lines changed: 0 additions & 19 deletions
This file was deleted.

paddle/operators/cross_entropy_op.cc renamed to paddle/operators/onehot_cross_entropy_op.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
See the License for the specific language governing permissions and
1313
limitations under the License. */
1414

15-
#include "paddle/operators/cross_entropy_op.h"
15+
#include "paddle/operators/onehot_cross_entropy_op.h"
1616

1717
namespace paddle {
1818
namespace operators {
File renamed without changes.
File renamed without changes.

paddle/pybind/pybind.cc

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ limitations under the License. */
2323
#include "paddle/operators/recurrent_op.h"
2424
#include "paddle/platform/enforce.h"
2525
#include "paddle/platform/place.h"
26+
#include "paddle/pybind/pybind.h"
2627
#include "paddle/pybind/tensor_py.h"
2728
#include "paddle/string/to_string.h"
2829
#include "pybind11/numpy.h"
@@ -31,34 +32,6 @@ limitations under the License. */
3132

3233
namespace py = pybind11;
3334

34-
USE_OP(add);
35-
USE_OP(onehot_cross_entropy);
36-
USE_OP(sgd);
37-
USE_OP(mul);
38-
USE_OP(elementwise_mul);
39-
USE_OP(mean);
40-
USE_OP(sigmoid);
41-
USE_OP(softmax);
42-
USE_OP(rowwise_add);
43-
USE_OP(fill_zeros_like);
44-
USE_NO_KERNEL_OP(recurrent);
45-
USE_OP(gaussian_random);
46-
USE_OP(uniform_random);
47-
USE_OP(lookup_table);
48-
USE_OP(scale);
49-
USE_NO_KERNEL_OP(identity);
50-
USE_OP(minus);
51-
USE_OP(cos_sim);
52-
USE_CPU_ONLY_OP(gather);
53-
USE_OP(pad);
54-
USE_CPU_ONLY_OP(scatter);
55-
USE_OP(accuracy);
56-
USE_CPU_ONLY_OP(concat);
57-
USE_OP(top_k);
58-
USE_OP(squared_l2_distance);
59-
USE_OP(sum);
60-
USE_OP(reshape);
61-
6235
namespace paddle {
6336
namespace framework {
6437

0 commit comments

Comments
 (0)