Ho il codice CUDA che voglio creare una libreria dinamica su Python usando le distutils. Ma sembra che distutils non riconosca il file ".cu" anche se il compilatore "nvcc" è installato. Non sei sicuro di come farlo.Le distutils python possono compilare il codice CUDA?
risposta
Distutils non è in grado di compilare CUDA per impostazione predefinita, poiché non supporta l'utilizzo simultaneo di più compilatori. Per impostazione predefinita, imposta sul compilatore solo in base alla tua piattaforma, non sul tipo di codice sorgente che hai.
Ho un progetto di esempio su github che contiene alcune patch di scimmia in distutils per hackerare il supporto per questo. Il progetto di esempio è una classe C++ che gestisce una memoria GPU e un kernel CUDA, racchiusi in swig e tutti compilati con solo python setup.py install
. L'attenzione è focalizzata sulle operazioni dell'array, quindi usiamo anche numpy. Tutto il kernel fa per questo progetto di esempio è incrementare di un elemento ogni array in un array.
Il codice è qui: https://github.com/rmcgibbo/npcuda-example. Ecco lo script setup.py. La chiave per l'intero codice è customize_compiler_for_nvcc()
.
import os
from os.path import join as pjoin
from setuptools import setup
from distutils.extension import Extension
from distutils.command.build_ext import build_ext
import subprocess
import numpy
def find_in_path(name, path):
"Find a file in a search path"
#adapted fom http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/
for dir in path.split(os.pathsep):
binpath = pjoin(dir, name)
if os.path.exists(binpath):
return os.path.abspath(binpath)
return None
def locate_cuda():
"""Locate the CUDA environment on the system
Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64'
and values giving the absolute path to each directory.
Starts by looking for the CUDAHOME env variable. If not found, everything
is based on finding 'nvcc' in the PATH.
"""
# first check if the CUDAHOME env variable is in use
if 'CUDAHOME' in os.environ:
home = os.environ['CUDAHOME']
nvcc = pjoin(home, 'bin', 'nvcc')
else:
# otherwise, search the PATH for NVCC
nvcc = find_in_path('nvcc', os.environ['PATH'])
if nvcc is None:
raise EnvironmentError('The nvcc binary could not be '
'located in your $PATH. Either add it to your path, or set $CUDAHOME')
home = os.path.dirname(os.path.dirname(nvcc))
cudaconfig = {'home':home, 'nvcc':nvcc,
'include': pjoin(home, 'include'),
'lib64': pjoin(home, 'lib64')}
for k, v in cudaconfig.iteritems():
if not os.path.exists(v):
raise EnvironmentError('The CUDA %s path could not be located in %s' % (k, v))
return cudaconfig
CUDA = locate_cuda()
# Obtain the numpy include directory. This logic works across numpy versions.
try:
numpy_include = numpy.get_include()
except AttributeError:
numpy_include = numpy.get_numpy_include()
ext = Extension('_gpuadder',
sources=['src/swig_wrap.cpp', 'src/manager.cu'],
library_dirs=[CUDA['lib64']],
libraries=['cudart'],
runtime_library_dirs=[CUDA['lib64']],
# this syntax is specific to this build system
# we're only going to use certain compiler args with nvcc and not with gcc
# the implementation of this trick is in customize_compiler() below
extra_compile_args={'gcc': [],
'nvcc': ['-arch=sm_20', '--ptxas-options=-v', '-c', '--compiler-options', "'-fPIC'"]},
include_dirs = [numpy_include, CUDA['include'], 'src'])
# check for swig
if find_in_path('swig', os.environ['PATH']):
subprocess.check_call('swig -python -c++ -o src/swig_wrap.cpp src/swig.i', shell=True)
else:
raise EnvironmentError('the swig executable was not found in your PATH')
def customize_compiler_for_nvcc(self):
"""inject deep into distutils to customize how the dispatch
to gcc/nvcc works.
If you subclass UnixCCompiler, it's not trivial to get your subclass
injected in, and still have the right customizations (i.e.
distutils.sysconfig.customize_compiler) run on it. So instead of going
the OO route, I have this. Note, it's kindof like a wierd functional
subclassing going on."""
# tell the compiler it can processes .cu
self.src_extensions.append('.cu')
# save references to the default compiler_so and _comple methods
default_compiler_so = self.compiler_so
super = self._compile
# now redefine the _compile method. This gets executed for each
# object but distutils doesn't have the ability to change compilers
# based on source extension: we add it.
def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts):
if os.path.splitext(src)[1] == '.cu':
# use the cuda for .cu files
self.set_executable('compiler_so', CUDA['nvcc'])
# use only a subset of the extra_postargs, which are 1-1 translated
# from the extra_compile_args in the Extension class
postargs = extra_postargs['nvcc']
else:
postargs = extra_postargs['gcc']
super(obj, src, ext, cc_args, postargs, pp_opts)
# reset the default compiler_so, which we might have changed for cuda
self.compiler_so = default_compiler_so
# inject our redefined _compile method into the class
self._compile = _compile
# run the customize_compiler
class custom_build_ext(build_ext):
def build_extensions(self):
customize_compiler_for_nvcc(self.compiler)
build_ext.build_extensions(self)
setup(name='gpuadder',
# random metadata. there's more you can supploy
author='Robert McGibbon',
version='0.1',
# this is necessary so that the swigged python file gets picked up
py_modules=['gpuadder'],
package_dir={'': 'src'},
ext_modules = [ext],
# inject our custom trigger
cmdclass={'build_ext': custom_build_ext},
# since the package has c code, the egg cannot be zipped
zip_safe=False)
È una specie di vecchia domanda ma hai qualche idea su come farlo su Windows? Il problema è che il metodo ** _ compile ** non è usato da ** msvccompiler **. – rAyyy
- 1. come installare le distutils python
- 2. Come compilare semplice programma embeded Python usando distutils
- 3. Distribuire il modulo di estensione python precompilato con le distutils
- 4. Come posso compilare manualmente il codice Cython che usa C++?
- 5. Compilare CUDA con Visual Studio 2010
- 6. Compilare il codice Python e collegarlo al programma C++?
- 7. Impossibile compilare il codice che contiene il parallelismo dinamico
- 8. Come compilare ed eseguire il codice dinamicamente?
- 9. Can GHCJS/Haste si possono compilare?
- 10. Come specificare C++ 11 con distutils?
- 11. Come valutare le prestazioni CUDA?
- 12. Configurazione opzioni del compilatore Distutils
- 13. Perché le variabili membro non possono essere condivise?
- 14. CUDA: Capire le informazioni PTX
- 15. compilare il codice JavaFX utilizzando ANT
- 16. Come compilare il codice objc su Linux?
- 17. Come compilare il codice da stdin?
- 18. Compilare codice C# nell'applicazione
- 19. Come compilare e installare il codice sorgente su OpenShift?
- 20. Confusione con il codice PTX CUDA e memoria di registro
- 21. Come separare il codice CUDA in più file
- 22. Le interfacce possono evolversi con il tempo?
- 23. fanno distutils in Python trovano automaticamente i pacchetti
- 24. Eseguire un'installazione post script Python utilizzando distutils/setuptools
- 25. Utilizzo memoria costante nel codice CUDA
- 26. Utilizzo di openMP nel codice host cuda?
- 27. Distutils Python, come ottenere un compilatore che verrà utilizzato?
- 28. Compilare CUDA senza Visual Studio - "Impossibile trovare il compilatore cl.exe nel percorso"
- 29. Esistono gemme che possono imporre le convenzioni del codice Ruby?
- 30. Come si disinstalla un pacchetto python installato con distutils?
Puoi pubblicare del codice in modo che possiamo vedere cosa hai provato? Inoltre, se il kernel CUDA è la parte chiave, puoi provare a usare PyCUDA per renderlo disponibile a python. –
Cosa intendi con "non riconosce"? Non include i file .cu nell'uovo? Aggiungi package_data = {'': ['* .cu']} al tuo setup (...) allora. –