Wrapper setuptools.setup function to valid `build_ext` command and
Wrapper setuptools.setup function to valid `build_ext` command and
implement paddle api code injection by switching `write_stub`
implement paddle api code injection by switching `write_stub`
function in bdist_egg with `custom_write_stub`.
function in bdist_egg with `custom_write_stub`.
Its usage is almost same as `setuptools.setup` except for `ext_modules`
arguments. For compiling multi custom operators, all necessary source files
can be include into just one Extension (CppExtension/CUDAExtension).
Moreover, only one `name` argument is required in `setup` and no need to spcific
`name` in Extension.
Example:
>> from paddle.utils.cpp_extension import CUDAExtension, setup
>> setup(name='custom_module',
ext_modules=CUDAExtension(
sources=['relu_op.cc', 'relu_op.cu'],
include_dirs=[], # specific user-defined include dirs
extra_compile_args=[]) # specific user-defined compil arguments.
"""
"""
cmdclass=attr.get('cmdclass',{})
cmdclass=attr.get('cmdclass',{})
assertisinstance(cmdclass,dict)
assertisinstance(cmdclass,dict)
...
@@ -46,6 +60,36 @@ def setup(**attr):
...
@@ -46,6 +60,36 @@ def setup(**attr):
no_python_abi_suffix=True)
no_python_abi_suffix=True)
attr['cmdclass']=cmdclass
attr['cmdclass']=cmdclass
error_msg="""
Required to specific `name` argument in paddle.utils.cpp_extension.setup.
It's used as `import XXX` when you want install and import your custom operators.\n
For Example:
# setup.py file
from paddle.utils.cpp_extension import CUDAExtension, setup
setup(name='custom_module',
ext_modules=CUDAExtension(
sources=['relu_op.cc', 'relu_op.cu'])
# After running `python setup.py install`
from custom_module import relue
"""
# name argument is required
if'name'notinattr:
raiseValueError(error_msg)
ext_modules=attr.get('ext_modules',[])
ifnotisinstance(ext_modules,list):
ext_modules=[ext_modules]
assertlen(
ext_modules
)==1,"Required only one Extension, but received {}. If you want to compile multi operators, you can include all necessary source files in one Extenion.".format(
len(ext_modules))
# replace Extension.name with attr['name] to keep consistant with Package name.
forext_moduleinext_modules:
ext_module.name=attr['name']
attr['ext_modules']=ext_modules
# Add rename .so hook in easy_install
# Add rename .so hook in easy_install
assert'easy_install'notincmdclass
assert'easy_install'notincmdclass
cmdclass['easy_install']=EasyInstallCommand
cmdclass['easy_install']=EasyInstallCommand
...
@@ -59,13 +103,12 @@ def setup(**attr):
...
@@ -59,13 +103,12 @@ def setup(**attr):
setuptools.setup(**attr)
setuptools.setup(**attr)
defCppExtension(name,sources,*args,**kwargs):
defCppExtension(sources,*args,**kwargs):
"""
"""
Returns setuptools.CppExtension instance for setup.py to make it easy
Returns setuptools.CppExtension instance for setup.py to make it easy
to specify compile flags while building C++ custommed op kernel.
to specify compile flags while building C++ custommed op kernel.
Args:
Args:
name(str): The extension name used as generated shared library name
sources(list[str]): The C++/CUDA source file names
sources(list[str]): The C++/CUDA source file names
args(list[options]): list of config options used to compile shared library
args(list[options]): list of config options used to compile shared library
kwargs(dict[option]): dict of config options used to compile shared library
kwargs(dict[option]): dict of config options used to compile shared library