[PaddlePaddle/Paddle]paddle可以与pybind配合生成自定义算子吗

2023-12-19 620 views
9

看到官网写的自定义算子生成方式是使用PD_BUILD_OP和PD_BUILD_GRAD_OP接口进行,我试了发现无法导出带函数的类,像采用pybind11方法,想请问一下飞桨框架可以与pybind11配合使用吗?

回答

6

您好,我们已经收到了您的问题,会安排技术人员尽快解答您的问题,请耐心等待。请您再次检查是否提供了清晰的问题描述、复现代码、环境&版本、报错信息等。同时,您也可以通过查看官网API文档常见问题历史IssueAI社区来寻求解答。祝您生活愉快~

Hi! We've received your issue and please be patient to get responded. We will arrange technicians to answer your questions as soon as possible. Please make sure that you have posted enough message to demo your request. You may also check out the APIFAQGithub Issue and AI community to get the answer.Have a nice day!

9

那么paddle框架在使用pybind的时候,和普通框架一样通过.so编译调用就可以吗?我用gcc对pybind11进行.so编译一直不通过

1

报错是什么呢?编译指令也方便提供下吗?

6

本项目是将基于pytorch的神经网络进行框架迁移,尝试采用原框架的bash run.sh方法编译,其中pybind模块写法如图(文件shift_cuda.cpp): PYBIND11_MODULE(shift_cuda, m) { m.def("forward", &shift_forward, "shift forward (CUDA)"); m.def("backward", &shift_backward, "shift backward (CUDA)"); } setup.py内容如下 from paddle.utils.cpp_extension import CppExtension, CUDAExtension, setup

setup( name='shift_cuda_linear_cpp', ext_modules=[ CUDAExtension(sources = [ 'shift_cuda.cpp', 'shift_cuda_kernel.cu' ]), ]) 使用run.bash进行编译 cd cuda

rm -rf ./pycache rm -rf ./dist rm -rf ./build rm -rf ./shift_cuda_linear_cpp.egg-info

python setup.py install

cd ..

CUDA_VISIBLE_DEVICES="0" python demo.py 在bash之后仍然显示AttributeError: module 'shift_cuda' has no attribute 'forward'

gcc编译.so方法也尝试过,会报错#include<paddle/extension.h>文件不存在

4

这个错误看上去是编译时没有将相应的头文件链接进来,可以再编译配置里加上试试

1

请问下这里为什么需要写pybind接自定义算子?Paddle提供的自定义算子功能是不能满足什么需求吗?

2

因为我想要导出shift_cuda类之后可以引用其forward和backward函数,在paddle的文档中没有找到类似的接口 大概这种引用: class ShiftFunction(PyLayer):

@staticmethod
def forward(ctx, input,xpos,ypos,stride=1):
    if stride==1:
        xpos = xpos
        ypos = ypos
    else:
        ypos = ypos + 0.5
        # ypos = ypos + 0.5
    output = shift_cuda.forward(input,xpos,ypos,stride)
    ctx.save_for_backward(input, output, xpos, ypos)
    ctx.stride = stride
    return output

@staticmethod
def backward(ctx, grad_output): 
    grad_output = grad_output.contiguous()
    input, output, xpos, ypos = ctx.saved_variables
    grad_input,grad_xpos,grad_ypos = shift_cuda.backward(grad_output, input, output, xpos, ypos, ctx.stride)
    return grad_input, grad_xpos, grad_ypos, None
0

嗯,您发的链接我之前看过了,因为是现有代码做框架迁移所以希望尽可能少改动代码内容,想问一下paddle自带的自定义算子功能可以实现我想要的forward和backward函数封装吗?如果可以的话应该怎么做? 附:我编译出来的shift_cuda.py,并不含有以上功能。 # def shift_cuda(input,xpos,ypos,stride):

prepare inputs and outputs
ins = {'input' : input,'xpos' : xpos,'ypos' : ypos,'stride' : stride}
attrs = {}
outs = {}
out_names = ['Out']

# The output variable's dtype use default value 'float32',
# and the actual dtype of output variable will be inferred in runtime.
if in_dygraph_mode():
    ctx = CustomOpKernelContext()
    for i in [input,xpos,ypos,stride]:
        ctx.add_inputs(i)
    for j in []:
        ctx.add_attr(j)
    for out_name in out_names:
        outs[out_name] = core.eager.Tensor()
        ctx.add_outputs(outs[out_name])
    core.eager._run_custom_op(ctx, "shift_cuda", True)
else:
    if _in_legacy_dygraph():
        for out_name in out_names:
            outs[out_name] = VarBase()
        _dygraph_tracer().trace_op(type="shift_cuda", inputs=ins, outputs=outs, attrs=attrs)
    else:
        helper = LayerHelper("shift_cuda", **locals())
        for out_name in out_names:
            outs[out_name] = helper.create_variable(dtype='float32')

        helper.append_op(type="shift_cuda", inputs=ins, outputs=outs, attrs=attrs)

res = [outs[out_name] for out_name in out_names]

return res[0] if len(res)==1 else res
2

导出backward函数的作用是什么?如果只是引入一个shift_cuda算子用于组网训练的话,我理解按照自定义C++算子的格式写好算子实现后再调用编译封装好的python接口就可以了

7

好的,我再看看,谢谢您