Add context::attach().
[pycuda.git] / setup.py
1 #!/usr/bin/env python
2 # -*- coding: latin-1 -*-
3 from os.path import dirname, join, normpath
4
5
6 def search_on_path(filenames):
7     """Find file on system path."""
8     # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52224
9
10     from os.path import exists, abspath
11     from os import pathsep, environ
12
13     search_path = environ["PATH"]
14
15     paths = search_path.split(pathsep)
16     for path in paths:
17         for filename in filenames:
18             if exists(join(path, filename)):
19                 return abspath(join(path, filename))
20
21 def get_config_schema():
22     from aksetup_helper import ConfigSchema, Option, \
23             IncludeDir, LibraryDir, Libraries, BoostLibraries, \
24             Switch, StringListOption, make_boost_base_options
25
26     nvcc_path = search_on_path(["nvcc", "nvcc.exe"])
27     if nvcc_path is None:
28         print("*** nvcc not in path. Giving up.")
29         import sys
30         sys.exit(1)
31
32     cuda_root_default = normpath(join(dirname(nvcc_path), ".."))
33
34     return ConfigSchema(make_boost_base_options() + [
35         Switch("USE_SHIPPED_BOOST", True, "Use included Boost library"),
36
37         BoostLibraries("python"),
38         BoostLibraries("thread"),
39
40         Switch("CUDA_TRACE", False, "Enable CUDA API tracing"),
41         Option("CUDA_ROOT", default=cuda_root_default, help="Path to the CUDA toolkit"),
42         Option("CUDA_PRETEND_VERSION", help="Assumed CUDA version, in the form 3010 for 3.1."),
43         IncludeDir("CUDA", None),
44
45         Switch("CUDA_ENABLE_GL", False, "Enable CUDA GL interoperability"),
46         Switch("CUDA_ENABLE_CURAND", True, "Enable CURAND library"),
47
48         LibraryDir("CUDADRV", ["${CUDA_ROOT}/lib", "${CUDA_ROOT}/lib64"]),
49         Libraries("CUDADRV", ["cuda"]),
50
51         LibraryDir("CUDART", ["${CUDA_ROOT}/lib", "${CUDA_ROOT}/lib64"]),
52         Libraries("CUDART", ["cudart"]),
53
54         LibraryDir("CURAND", ["${CUDA_ROOT}/lib", "${CUDA_ROOT}/lib64"]),
55         Libraries("CURAND", ["curand"]),
56
57         StringListOption("CXXFLAGS", [],
58             help="Any extra C++ compiler options to include"),
59         StringListOption("LDFLAGS", [],
60             help="Any extra linker options to include"),
61         ])
62
63
64
65
66
67 def main():
68     import glob
69     import sys
70
71     from aksetup_helper import (hack_distutils, get_config, setup, \
72             NumpyExtension, Extension, set_up_shipped_boost_if_requested,
73             check_git_submodules)
74
75     check_git_submodules()
76
77     hack_distutils(debug=True)
78     conf = get_config(get_config_schema())
79     EXTRA_SOURCES, EXTRA_DEFINES = set_up_shipped_boost_if_requested("pycuda", conf)
80
81     EXTRA_DEFINES["PYGPU_PACKAGE"] = "pycuda"
82     EXTRA_DEFINES["PYGPU_PYCUDA"] = "1"
83
84     LIBRARY_DIRS = conf["BOOST_LIB_DIR"] + conf["CUDADRV_LIB_DIR"]
85     LIBRARIES = (conf["BOOST_PYTHON_LIBNAME"] + conf["BOOST_THREAD_LIBNAME"]
86             + conf["CUDADRV_LIBNAME"])
87
88     if not conf["CUDA_INC_DIR"]:
89         conf["CUDA_INC_DIR"] = [join(conf["CUDA_ROOT"], "include")]
90
91     if conf["CUDA_TRACE"]:
92         EXTRA_DEFINES["CUDAPP_TRACE_CUDA"] = 1
93
94     if conf["CUDA_PRETEND_VERSION"]:
95         EXTRA_DEFINES["CUDAPP_PRETEND_CUDA_VERSION"] = conf["CUDA_PRETEND_VERSION"]
96
97     INCLUDE_DIRS = ['src/cpp'] + conf["BOOST_INC_DIR"] + conf["CUDA_INC_DIR"]
98     conf["USE_CUDA"] = True
99
100     if 'darwin' in sys.platform and sys.maxsize == 2147483647:
101         # The Python interpreter is running in 32 bit mode on OS X
102         if "-arch" not in conf["CXXFLAGS"]:
103             conf["CXXFLAGS"].extend(['-arch', 'i386', '-m32'])
104         if "-arch" not in conf["LDFLAGS"]:
105             conf["LDFLAGS"].extend(['-arch', 'i386', '-m32'])
106
107     if 'darwin' in sys.platform:
108         # set path to Cuda dynamic libraries,
109         # as a safe substitute for DYLD_LIBRARY_PATH
110         for lib_dir in conf["CUDADRV_LIB_DIR"]:
111             conf["LDFLAGS"].extend(["-Xlinker", "-rpath", "-Xlinker", lib_dir])
112
113     if conf["CUDA_ENABLE_GL"]:
114         EXTRA_SOURCES.append("src/wrapper/wrap_cudagl.cpp")
115         EXTRA_DEFINES["HAVE_GL"] = 1
116
117     if conf["CUDA_ENABLE_CURAND"]:
118         EXTRA_DEFINES["HAVE_CURAND"] = 1
119         EXTRA_SOURCES.extend([
120             "src/wrapper/wrap_curand.cpp"
121             ])
122         LIBRARIES.extend(conf["CURAND_LIBNAME"])
123         LIBRARY_DIRS.extend(conf["CURAND_LIB_DIR"])
124
125     ver_dic = {}
126     exec(compile(open("pycuda/__init__.py").read(), "pycuda/__init__.py", 'exec'), ver_dic)
127
128     try:
129         from distutils.command.build_py import build_py_2to3 as build_py
130     except ImportError:
131         # 2.x
132         from distutils.command.build_py import build_py
133
134     setup(name="pycuda",
135             # metadata
136             version=ver_dic["VERSION_TEXT"],
137             description="Python wrapper for Nvidia CUDA",
138             long_description="""
139             PyCUDA lets you access `Nvidia <http://nvidia.com>`_'s `CUDA
140             <http://nvidia.com/cuda/>`_ parallel computation API from Python.
141             Several wrappers of the CUDA API already exist-so what's so special
142             about PyCUDA?
143
144             * Object cleanup tied to lifetime of objects. This idiom, often
145               called
146               `RAII <http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization>`_
147               in C++, makes it much easier to write correct, leak- and
148               crash-free code. PyCUDA knows about dependencies, too, so (for
149               example) it won't detach from a context before all memory
150               allocated in it is also freed.
151
152             * Convenience. Abstractions like pycuda.driver.SourceModule and
153               pycuda.gpuarray.GPUArray make CUDA programming even more
154               convenient than with Nvidia's C-based runtime.
155
156             * Completeness. PyCUDA puts the full power of CUDA's driver API at
157               your disposal, if you wish. It also includes code for
158               interoperability with OpenGL.
159
160             * Automatic Error Checking. All CUDA errors are automatically
161               translated into Python exceptions.
162
163             * Speed. PyCUDA's base layer is written in C++, so all the niceties
164               above are virtually free.
165
166             * Helpful `Documentation <http://documen.tician.de/pycuda>`_ and a
167               `Wiki <http://wiki.tiker.net/PyCuda>`_.
168
169             Relatedly, like-minded computing goodness for `OpenCL <http://khronos.org>`_
170             is provided by PyCUDA's sister project `PyOpenCL <http://pypi.python.org/pypi/pyopencl>`_.
171             """,
172             author="Andreas Kloeckner",
173             author_email="inform@tiker.net",
174             license = "MIT",
175             url="http://mathema.tician.de/software/pycuda",
176             classifiers=[
177               'Environment :: Console',
178               'Development Status :: 5 - Production/Stable',
179               'Intended Audience :: Developers',
180               'Intended Audience :: Other Audience',
181               'Intended Audience :: Science/Research',
182               'License :: OSI Approved :: MIT License',
183               'Natural Language :: English',
184               'Programming Language :: C++',
185               'Programming Language :: Python',
186               'Topic :: Scientific/Engineering',
187               'Topic :: Scientific/Engineering :: Mathematics',
188               'Topic :: Scientific/Engineering :: Physics',
189               'Topic :: Scientific/Engineering :: Visualization',
190               ],
191
192             # build info
193             packages=["pycuda", "pycuda.gl", "pycuda.sparse", "pycuda.compyte"],
194
195             install_requires=[
196                 "pytools>=2011.2",
197                 "pytest>=2",
198                 "decorator>=3.2.0"
199                 ],
200
201             ext_package="pycuda",
202             ext_modules=[
203                 NumpyExtension("_driver",
204                     [
205                         "src/cpp/cuda.cpp",
206                         "src/cpp/bitlog.cpp",
207                         "src/wrapper/wrap_cudadrv.cpp",
208                         "src/wrapper/mempool.cpp",
209                         ]+EXTRA_SOURCES,
210                     include_dirs=INCLUDE_DIRS,
211                     library_dirs=LIBRARY_DIRS,
212                     libraries=LIBRARIES,
213                     define_macros=list(EXTRA_DEFINES.items()),
214                     extra_compile_args=conf["CXXFLAGS"],
215                     extra_link_args=conf["LDFLAGS"],
216                     ),
217                 NumpyExtension("_pvt_struct",
218                     ["src/wrapper/_pycuda_struct.cpp"],
219                     extra_compile_args=conf["CXXFLAGS"],
220                     extra_link_args=conf["LDFLAGS"],
221                     ),
222                 ],
223
224             data_files=[
225                 ("include/pycuda", glob.glob("src/cuda/*.hpp"))
226                 ],
227
228             # 2to3 invocation
229             cmdclass={'build_py': build_py})
230
231
232 if __name__ == '__main__':
233     main()