Skip to content

[Cpp Extension] Support Cpp Extension #49893

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Feb 20, 2023

Conversation

jiahy0825
Copy link
Contributor

@jiahy0825 jiahy0825 commented Jan 17, 2023

PR types

New features

PR changes

Others

Describe

飞桨框架提供了丰富的算子库和易用的自定义算子机制,能够满足绝大多数场景的使用需求。
但是在以下场景下,用户可能希望定制化 C++ 实现,从而满足特定需求:

  1. python 函数经常被调用,需要对性能做优化;
  2. 即使该函数被调用的次数很少,但是该函数开销很重,希望将实现逻辑放到 C++ 端提高性能;
  3. 函数实现依赖或者需要调用 C++ 库。

现有的自定义算子机制在下列场景下无法满足用户需求:

  1. 将 C++ 类绑定至 Python;
  2. 调用无 Tensor 参数的 C++ 函数。

为此,我们需要提供一种更为灵活的 C++ 扩展机制,以此机制实现的自定义扩展,能够 即插即用 ,不需要重新编译安装飞桨框架。

主要改动:

1. 支持 Cpp Extension 机制

  • 支持 Tensor 作为 pybind11 绑定函数的参数
  • 支持 自定义扩展函数和扩展类
  • 支持 Cpp Extension 和自定义算子的混合实现

2. 支持 setup 编译和 JIT 编译

3. 添加 Cpp Extension 单测

  • 添加 setup 编译单测
  • 添加 JIT 单测
  • 验证 链接器正确性、验证导入头文件正确性

4. 公开 pybind11 相关头文件

[Update pybind11] update pybind11 TAG, 2.4.3->2.6.0 #50068

  • 将 pybind11 升级至 2.6.0 版本,解决 windows 下 nvcc 编译 pybind11/cast.h 报错的问题
  • 修复 pybind11 升级后,VarType 无法正确打印的问题
  • 公开 pybind11 目录至 site-package/paddle/include/third_party
  • 添加 pybind11 目录至 inference_lib,修改推理头文件
  • 新建 paddle/utils/pybind.h 并添加至 paddle/extension.h 头文件,用于引入 pybind11

目前本 PR 内容相对较多,且作为整体功能比较难拆分。
为便于 PR review 和并行推进剩余工作,后续会通过一些小 PR 继续完善 TODO 项:

1. 添加多个单测,充分验证与测试 Cpp Extension 机制:

  • 添加 Cpp 与 cuda 混合调用单测
  • 添加 Cpp Extension 和自定义算子混合调用单测
  • 添加 STL 与 Tensor 组合输入输出的单测

2. 支持 Mac 和 Windows 平台

PaddlePaddle has provided a large operator library and easy-to-use custom operator mechanism, which can satisfy most scenario requirements. However, in the following scenario, users may hope to customize Cpp implementation and thus meet specific needs:

  1. python functions are called frequently and the performance needs to be optimized;
  2. Even if the function is only called several times, its cost is heavy and you want to move the implementation to Cpp to speed up the function;
  3. The implementation of the function needs to call the Cpp library.

The existing custom operator mechanism can not satisfy users' requirements in the following scenarios:

  1. Binding Cpp class to python;
  2. Calling Cpp functions without Tensor parameter.

Therefore, we need to provide a more flexible Cpp Extension mechanism and this mechanism can plug in the PaddlePaddle framework without recompiling the whole project.

Main Change:

1. Support Cpp Extension mechanism

  • Support Tensor as parameter binding to pybind11
  • Support extension functions and extension classes
  • Support mixed implementation of Cpp extension and custom operator

2. Support setup compile and Just-In-Time (JIT) compile

3. Add Cpp Extension unit test

  • Add setup compile unit test
  • Add JIT compile unit test
  • Verify the accuracy of the linker and the accuracy of including corresponding header files.

4. Disclose pybind11 header files

[Update pybind11] update pybind11 TAG, 2.4.3->2.6.0 #50068

  • Upgrade pybind11 from 2.4.3 to 2.6.0, which solves the error of compiling pybind11/cast.h with nvcc compiler under windows.
  • Fix the error of incorrect print message of VarType after upgrading pybind11
  • Disclose the pybind11 directory to site-package/paddle/include/third_party
  • Add pybind11 directory to inference_lib and changes inference header files
  • Add paddle/utils/pybind.h to paddle/extension.h, which helps to import the pybind11 library

This PR is relatively large and hard to split. To simplify the review process and finish remained work parallelly, some small PRs will be created to finish the TODO list.

1. Add multiple unit tests to fully verify the Cpp Extension mechanism

  • Add the unit test of mixed calling of Cpp and cuda
  • Add the unit test of mixed calling of Cpp Extension and custom operator
  • Add the unit test of the combination use of STL and Tensor

2. Support Mac and Windows platform

@paddle-bot
Copy link

paddle-bot bot commented Jan 17, 2023

你的PR提交成功,感谢你对开源项目的贡献!
请关注后续CI自动化测试结果,详情请参考Paddle-CI手册
Your PR has been submitted. Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

YuanRisheng
YuanRisheng previously approved these changes Feb 1, 2023
Comment on lines 304 to 308
if(WITH_PYTHON)
include(external/python) # find python and python_module
include(external/pybind11) # download pybind11
list(APPEND third_party_deps extern_pybind)
endif()
Copy link
Contributor

Choose a reason for hiding this comment

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

这里去掉WITH_PYTHON可开关会不会对推理的编译产生影响?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks,计划将 if(WITH_PYTHON) 改为 if(NOT ON_INFER)

Maybe change if(WITH_PYTHON) to if(NOT ON_INFER) would be better.

Comment on lines +182 to +185
if os.name == 'nt' or sys.platform.startswith('darwin'):
# Cpp Extension only support Linux now
mod = types.ModuleType(__name__)
else:
Copy link
Contributor

Choose a reason for hiding this comment

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

这里的平台限制问题后续可以解决吗?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Windows 和 Mac 平台和 Linux 平台编译的差别较大,需要线下评估这项需求和排期。

There are differences between Windows, Mac, and Linux, we need to assess this requirement offline.

Comment on lines 26 to 37
if os.name == 'nt' or sys.platform.startswith('darwin'):
# only support Linux now
exit()

# Because Windows don't use docker, the shared lib already exists in the
# cache dir, it will not be compiled again unless the shared lib is removed.
file = '{}\\custom_cpp_extension\\custom_cpp_extension.pyd'.format(
get_build_directory()
)
if os.name == 'nt' and os.path.isfile(file):
cmd = 'del {}'.format(file)
run_cmd(cmd, True)
Copy link
Contributor

Choose a reason for hiding this comment

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

这部分代码可以封装起来吗?用户在参考示例代码的时候这里看上去可能会有一些干扰

Copy link
Contributor Author

Choose a reason for hiding this comment

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

感谢,原本此处代码是留作扩展 Windows 的,可以先删除这部分代码,保持单测的整洁

Thanks, these codes are kept for Windows, I can delete this part temporarily to keep unit test clean.

// limitations under the License.

#include "paddle/utils/pybind.h"
#include "paddle/fluid/platform/enforce.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

这里能否用phi的,utils下的文件是对外放出的,但是platform下的文件没有放出,可能会编译错误

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, thx~

@jiahy0825 jiahy0825 force-pushed the support_C++_extension branch from 4dc1572 to 941d674 Compare February 15, 2023 03:14
Copy link
Contributor

@zhangbo9674 zhangbo9674 left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@XieYunshen XieYunshen left a comment

Choose a reason for hiding this comment

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

LGTM for
set_tests_properties(test_cpp_extension_setup PROPERTIES TIMEOUT 120) set_tests_properties(test_cpp_extension_jit PROPERTIES TIMEOUT 120)

Copy link
Contributor

@XiaoguangHu01 XiaoguangHu01 left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants