pyopencl 2024.2.2__cp312-cp312-win_amd64.whl → 2024.2.4__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyopencl might be problematic. Click here for more details.

Files changed (102) hide show
  1. pyopencl/__init__.py +16 -4
  2. pyopencl/_cl.cp312-win_amd64.pyd +0 -0
  3. pyopencl/algorithm.py +3 -1
  4. pyopencl/bitonic_sort.py +2 -0
  5. pyopencl/characterize/__init__.py +23 -0
  6. pyopencl/compyte/.git +1 -0
  7. pyopencl/compyte/.github/workflows/autopush.yml +21 -0
  8. pyopencl/compyte/.github/workflows/ci.yml +30 -0
  9. pyopencl/compyte/.gitignore +21 -0
  10. pyopencl/compyte/ndarray/Makefile +31 -0
  11. pyopencl/compyte/ndarray/gpu_ndarray.h +35 -0
  12. pyopencl/compyte/ndarray/pygpu_language.h +207 -0
  13. pyopencl/compyte/ndarray/pygpu_language_cuda.cu +622 -0
  14. pyopencl/compyte/ndarray/pygpu_language_opencl.cpp +317 -0
  15. pyopencl/compyte/ndarray/pygpu_ndarray.cpp +1546 -0
  16. pyopencl/compyte/ndarray/pygpu_ndarray.h +71 -0
  17. pyopencl/compyte/ndarray/pygpu_ndarray_object.h +232 -0
  18. pyopencl/compyte/setup.cfg +9 -0
  19. pyopencl/tools.py +60 -56
  20. pyopencl/version.py +7 -3
  21. {pyopencl-2024.2.2.dist-info → pyopencl-2024.2.4.dist-info}/METADATA +105 -105
  22. pyopencl-2024.2.4.dist-info/RECORD +59 -0
  23. {pyopencl-2024.2.2.dist-info → pyopencl-2024.2.4.dist-info}/WHEEL +1 -1
  24. pyopencl-2024.2.2.data/data/CITATION.cff +0 -74
  25. pyopencl-2024.2.2.data/data/CMakeLists.txt +0 -83
  26. pyopencl-2024.2.2.data/data/Makefile.in +0 -21
  27. pyopencl-2024.2.2.data/data/README.rst +0 -70
  28. pyopencl-2024.2.2.data/data/README_SETUP.txt +0 -34
  29. pyopencl-2024.2.2.data/data/aksetup_helper.py +0 -1013
  30. pyopencl-2024.2.2.data/data/configure.py +0 -6
  31. pyopencl-2024.2.2.data/data/contrib/cldis.py +0 -91
  32. pyopencl-2024.2.2.data/data/contrib/fortran-to-opencl/README +0 -29
  33. pyopencl-2024.2.2.data/data/contrib/fortran-to-opencl/translate.py +0 -1441
  34. pyopencl-2024.2.2.data/data/contrib/pyopencl.vim +0 -84
  35. pyopencl-2024.2.2.data/data/doc/Makefile +0 -23
  36. pyopencl-2024.2.2.data/data/doc/algorithm.rst +0 -214
  37. pyopencl-2024.2.2.data/data/doc/array.rst +0 -305
  38. pyopencl-2024.2.2.data/data/doc/conf.py +0 -26
  39. pyopencl-2024.2.2.data/data/doc/howto.rst +0 -105
  40. pyopencl-2024.2.2.data/data/doc/index.rst +0 -137
  41. pyopencl-2024.2.2.data/data/doc/make_constants.py +0 -561
  42. pyopencl-2024.2.2.data/data/doc/misc.rst +0 -885
  43. pyopencl-2024.2.2.data/data/doc/runtime.rst +0 -51
  44. pyopencl-2024.2.2.data/data/doc/runtime_const.rst +0 -30
  45. pyopencl-2024.2.2.data/data/doc/runtime_gl.rst +0 -78
  46. pyopencl-2024.2.2.data/data/doc/runtime_memory.rst +0 -527
  47. pyopencl-2024.2.2.data/data/doc/runtime_platform.rst +0 -184
  48. pyopencl-2024.2.2.data/data/doc/runtime_program.rst +0 -364
  49. pyopencl-2024.2.2.data/data/doc/runtime_queue.rst +0 -182
  50. pyopencl-2024.2.2.data/data/doc/subst.rst +0 -36
  51. pyopencl-2024.2.2.data/data/doc/tools.rst +0 -4
  52. pyopencl-2024.2.2.data/data/doc/types.rst +0 -42
  53. pyopencl-2024.2.2.data/data/examples/black-hole-accretion.py +0 -2227
  54. pyopencl-2024.2.2.data/data/examples/demo-struct-reduce.py +0 -75
  55. pyopencl-2024.2.2.data/data/examples/demo.py +0 -39
  56. pyopencl-2024.2.2.data/data/examples/demo_array.py +0 -32
  57. pyopencl-2024.2.2.data/data/examples/demo_array_svm.py +0 -37
  58. pyopencl-2024.2.2.data/data/examples/demo_elementwise.py +0 -34
  59. pyopencl-2024.2.2.data/data/examples/demo_elementwise_complex.py +0 -53
  60. pyopencl-2024.2.2.data/data/examples/demo_mandelbrot.py +0 -183
  61. pyopencl-2024.2.2.data/data/examples/demo_meta_codepy.py +0 -56
  62. pyopencl-2024.2.2.data/data/examples/demo_meta_template.py +0 -55
  63. pyopencl-2024.2.2.data/data/examples/dump-performance.py +0 -38
  64. pyopencl-2024.2.2.data/data/examples/dump-properties.py +0 -86
  65. pyopencl-2024.2.2.data/data/examples/gl_interop_demo.py +0 -84
  66. pyopencl-2024.2.2.data/data/examples/gl_particle_animation.py +0 -218
  67. pyopencl-2024.2.2.data/data/examples/ipython-demo.ipynb +0 -203
  68. pyopencl-2024.2.2.data/data/examples/median-filter.py +0 -99
  69. pyopencl-2024.2.2.data/data/examples/n-body.py +0 -1070
  70. pyopencl-2024.2.2.data/data/examples/narray.py +0 -37
  71. pyopencl-2024.2.2.data/data/examples/noisyImage.jpg +0 -0
  72. pyopencl-2024.2.2.data/data/examples/pi-monte-carlo.py +0 -1166
  73. pyopencl-2024.2.2.data/data/examples/svm.py +0 -82
  74. pyopencl-2024.2.2.data/data/examples/transpose.py +0 -229
  75. pyopencl-2024.2.2.data/data/pytest.ini +0 -3
  76. pyopencl-2024.2.2.data/data/src/bitlog.cpp +0 -51
  77. pyopencl-2024.2.2.data/data/src/bitlog.hpp +0 -83
  78. pyopencl-2024.2.2.data/data/src/clinfo_ext.h +0 -134
  79. pyopencl-2024.2.2.data/data/src/mempool.hpp +0 -444
  80. pyopencl-2024.2.2.data/data/src/pyopencl_ext.h +0 -77
  81. pyopencl-2024.2.2.data/data/src/tools.hpp +0 -90
  82. pyopencl-2024.2.2.data/data/src/wrap_cl.cpp +0 -61
  83. pyopencl-2024.2.2.data/data/src/wrap_cl.hpp +0 -5853
  84. pyopencl-2024.2.2.data/data/src/wrap_cl_part_1.cpp +0 -369
  85. pyopencl-2024.2.2.data/data/src/wrap_cl_part_2.cpp +0 -702
  86. pyopencl-2024.2.2.data/data/src/wrap_constants.cpp +0 -1274
  87. pyopencl-2024.2.2.data/data/src/wrap_helpers.hpp +0 -213
  88. pyopencl-2024.2.2.data/data/src/wrap_mempool.cpp +0 -738
  89. pyopencl-2024.2.2.data/data/test/add-vectors-32.spv +0 -0
  90. pyopencl-2024.2.2.data/data/test/add-vectors-64.spv +0 -0
  91. pyopencl-2024.2.2.data/data/test/empty-header.h +0 -1
  92. pyopencl-2024.2.2.data/data/test/test_algorithm.py +0 -1180
  93. pyopencl-2024.2.2.data/data/test/test_array.py +0 -2392
  94. pyopencl-2024.2.2.data/data/test/test_arrays_in_structs.py +0 -100
  95. pyopencl-2024.2.2.data/data/test/test_clmath.py +0 -529
  96. pyopencl-2024.2.2.data/data/test/test_clrandom.py +0 -75
  97. pyopencl-2024.2.2.data/data/test/test_enqueue_copy.py +0 -271
  98. pyopencl-2024.2.2.data/data/test/test_wrapper.py +0 -1565
  99. pyopencl-2024.2.2.dist-info/LICENSE +0 -282
  100. pyopencl-2024.2.2.dist-info/RECORD +0 -123
  101. pyopencl-2024.2.2.dist-info/top_level.txt +0 -1
  102. {pyopencl-2024.2.2.data/data → pyopencl-2024.2.4.dist-info/licenses}/LICENSE +0 -0
@@ -1,1013 +0,0 @@
1
- import os
2
- import sys
3
-
4
-
5
- try:
6
- from setuptools import Extension
7
- from setuptools.command.build_ext import \
8
- build_ext as BaseBuildExtCommand # noqa: N812
9
-
10
- except ImportError:
11
- class Extension:
12
- pass
13
-
14
- class BaseBuildExtCommand:
15
- pass
16
-
17
-
18
- def count_down_delay(delay):
19
- from time import sleep
20
- while delay:
21
- sys.stdout.write("Continuing in %d seconds... \r" % delay)
22
- sys.stdout.flush()
23
- delay -= 1
24
- sleep(1)
25
- print("")
26
-
27
-
28
- DASH_SEPARATOR = 75 * "-"
29
-
30
-
31
- def setup(*args, **kwargs):
32
- from setuptools import setup
33
- try:
34
- setup(*args, **kwargs)
35
- except KeyboardInterrupt:
36
- raise
37
- except SystemExit:
38
- raise
39
- except Exception:
40
- print(DASH_SEPARATOR)
41
- print("Sorry, your build failed. Try rerunning configure.py with "
42
- "different options.")
43
- print(DASH_SEPARATOR)
44
- raise
45
-
46
-
47
- def get_numpy_incpath():
48
- from importlib.util import find_spec
49
- from os.path import dirname, exists, join
50
- origin = find_spec("numpy").origin
51
- if origin is None:
52
- raise RuntimeError("origin of numpy package not found")
53
-
54
- pathname = dirname(origin)
55
- for p in [
56
- join(pathname, "_core", "include"), # numpy 2 onward
57
- join(pathname, "core", "include"), # numpy prior to 2
58
- ]:
59
- if exists(join(p, "numpy", "arrayobject.h")):
60
- return p
61
-
62
- raise RuntimeError("no valid path for numpy found")
63
-
64
-
65
- class NumpyExtension(Extension):
66
- # nicked from
67
- # http://mail.python.org/pipermail/distutils-sig/2007-September/008253.html
68
- # solution by Michael Hoffmann
69
- def __init__(self, *args, **kwargs):
70
- Extension.__init__(self, *args, **kwargs)
71
- self._include_dirs = self.include_dirs
72
- del self.include_dirs # restore overwritten property
73
-
74
- def get_additional_include_dirs(self):
75
- return [get_numpy_incpath()]
76
-
77
- def get_include_dirs(self):
78
- return self._include_dirs + self.get_additional_include_dirs()
79
-
80
- def set_include_dirs(self, value):
81
- self._include_dirs = value
82
-
83
- def del_include_dirs(self):
84
- pass
85
-
86
- include_dirs = property(get_include_dirs, set_include_dirs, del_include_dirs)
87
-
88
-
89
- class ExtensionUsingNumpy(Extension):
90
- """Unlike :class:`NumpyExtension`, this class does not require numpy to be
91
- importable upon extension module creation, allowing ``setup_requires=["numpy"]``
92
- to work. On the other hand, it requires the use of::
93
-
94
- setup(...,
95
- cmdclass={'build_ext': NumpyBuildExtCommand})
96
-
97
- or
98
-
99
- setup(...,
100
- cmdclass={'build_ext': PybindBuildExtCommand})
101
- """
102
-
103
-
104
- class NumpyBuildExtCommand(BaseBuildExtCommand):
105
- def build_extension(self, extension):
106
- # We add the numpy include dir right before building the
107
- # extension, in order to avoid having to import numpy when
108
- # the setup script is imported, which would prevent
109
- # installation before manual installation of numpy.
110
- if isinstance(extension, ExtensionUsingNumpy):
111
- numpy_incpath = get_numpy_incpath()
112
- if numpy_incpath not in extension.include_dirs:
113
- extension.include_dirs.append(numpy_incpath)
114
-
115
- BaseBuildExtCommand.build_extension(self, extension)
116
-
117
-
118
- # {{{ tools
119
-
120
- def flatten(lst):
121
- """For an iterable of sub-iterables, generate each member of each
122
- sub-iterable in turn, i.e. a flattened version of that super-iterable.
123
-
124
- Example: Turn [[a,b,c],[d,e,f]] into [a,b,c,d,e,f].
125
- """
126
- for sublist in lst:
127
- for j in sublist:
128
- yield j
129
-
130
-
131
- def humanize(sym_str):
132
- words = sym_str.lower().replace("_", " ").split(" ")
133
- return " ".join([word.capitalize() for word in words])
134
-
135
- # }}}
136
-
137
-
138
- # {{{ siteconf handling
139
-
140
- def get_config(schema=None, warn_about_no_config=True):
141
- if schema is None:
142
- from setup import get_config_schema
143
- schema = get_config_schema()
144
-
145
- if (not schema.have_config() and not schema.have_global_config()
146
- and warn_about_no_config):
147
- print("*************************************************************")
148
- print("*** I have detected that you have not run configure.py.")
149
- print("*************************************************************")
150
- print("*** Additionally, no global config files were found.")
151
- print("*** I will go ahead with the default configuration.")
152
- print("*** In all likelihood, this will not work out.")
153
- print("*** ")
154
- print("*** See README_SETUP.txt for more information.")
155
- print("*** ")
156
- print("*** If the build does fail, just re-run configure.py with the")
157
- print("*** correct arguments, and then retry. Good luck!")
158
- print("*************************************************************")
159
- print("*** HIT Ctrl-C NOW IF THIS IS NOT WHAT YOU WANT")
160
- print("*************************************************************")
161
-
162
- count_down_delay(delay=10)
163
-
164
- config = expand_options(schema.read_config())
165
- schema.update_config_from_and_modify_command_line(config, sys.argv)
166
- return config
167
-
168
-
169
- def hack_distutils(debug=False, fast_link=True, what_opt=3):
170
- # hack distutils.sysconfig to eliminate debug flags
171
- # stolen from mpi4py
172
-
173
- def remove_prefixes(optlist, bad_prefixes):
174
- for bad_prefix in bad_prefixes:
175
- for i, flag in enumerate(optlist):
176
- if flag.startswith(bad_prefix):
177
- optlist.pop(i)
178
- break
179
- return optlist
180
-
181
- if not sys.platform.lower().startswith("win"):
182
- from distutils import sysconfig
183
-
184
- cvars = sysconfig.get_config_vars()
185
-
186
- bad_prefixes = ["-g", "-O", "-Wstrict-prototypes", "-DNDEBUG"]
187
-
188
- cflags = cvars.get("OPT")
189
- if cflags:
190
- cflags = remove_prefixes(cflags.split(), bad_prefixes)
191
- if debug:
192
- cflags.append("-g")
193
- else:
194
- if what_opt is None:
195
- pass
196
- else:
197
- cflags.append("-O%s" % what_opt)
198
- cflags.append("-DNDEBUG")
199
-
200
- cvars["OPT"] = str.join(" ", cflags)
201
-
202
- cflags = cvars.get("CONFIGURE_CFLAGS")
203
- if cflags:
204
- cflags = remove_prefixes(cflags.split(), bad_prefixes)
205
- cvars["CONFIGURE_CFLAGS"] = str.join(" ", cflags)
206
-
207
- if "BASECFLAGS" in cvars:
208
- cvars["CFLAGS"] = cvars["BASECFLAGS"] + " " + cvars.get("OPT", "")
209
- else:
210
- assert "CFLAGS" in cvars
211
-
212
- if fast_link:
213
- for varname in ["LDSHARED", "BLDSHARED"]:
214
- ldsharedflags = cvars.get(varname)
215
- if ldsharedflags:
216
- ldsharedflags = remove_prefixes(ldsharedflags.split(),
217
- ["-Wl,-O"])
218
- cvars[varname] = str.join(" ", ldsharedflags)
219
-
220
- # }}}
221
-
222
-
223
- # {{{ configure guts
224
-
225
- def default_or(a, b):
226
- if a is None:
227
- return b
228
- else:
229
- return a
230
-
231
-
232
- def expand_str(s, options):
233
- import re
234
-
235
- def my_repl(match):
236
- sym = match.group(1)
237
- try:
238
- repl = options[sym]
239
- except KeyError:
240
- from os import environ
241
- repl = environ[sym]
242
-
243
- return expand_str(repl, options)
244
-
245
- return re.subn(r"\$\{([a-zA-Z0-9_]+)\}", my_repl, s)[0]
246
-
247
-
248
- def expand_value(v, options):
249
- if isinstance(v, str):
250
- return expand_str(v, options)
251
- elif isinstance(v, list):
252
- result = []
253
- for i in v:
254
- try:
255
- exp_i = expand_value(i, options)
256
- except Exception:
257
- pass
258
- else:
259
- result.append(exp_i)
260
-
261
- return result
262
- else:
263
- return v
264
-
265
-
266
- def expand_options(options):
267
- return dict(
268
- (k, expand_value(v, options)) for k, v in options.items())
269
-
270
-
271
- class ConfigSchema:
272
- def __init__(self, options, conf_file="siteconf.py", conf_dir=os.path.dirname(__file__)):
273
- self.optdict = dict((opt.name, opt) for opt in options)
274
- self.options = options
275
- self.conf_dir = conf_dir
276
- self.conf_file = conf_file
277
-
278
- from os.path import expanduser
279
- self.user_conf_file = expanduser("~/.aksetup-defaults.py")
280
-
281
- if not sys.platform.lower().startswith("win"):
282
- self.global_conf_file = "/etc/aksetup-defaults.py"
283
- else:
284
- self.global_conf_file = None
285
-
286
- def get_conf_file(self):
287
- import os
288
- return os.path.join(self.conf_dir, self.conf_file)
289
-
290
- def set_conf_dir(self, conf_dir):
291
- self.conf_dir = conf_dir
292
-
293
- def get_default_config(self):
294
- return dict((opt.name, opt.default) for opt in self.options)
295
-
296
- def read_config_from_pyfile(self, filename):
297
- result = {}
298
- filevars = {}
299
- infile = open(filename, "r")
300
- try:
301
- contents = infile.read()
302
- finally:
303
- infile.close()
304
-
305
- exec(compile(contents, filename, "exec"), filevars)
306
-
307
- for key, value in filevars.items():
308
- if key in self.optdict:
309
- result[key] = value
310
-
311
- return result
312
-
313
- def update_conf_file(self, filename, config):
314
- result = {}
315
- filevars = {}
316
-
317
- try:
318
- exec(compile(open(filename, "r").read(), filename, "exec"), filevars)
319
- except IOError:
320
- pass
321
-
322
- if "__builtins__" in filevars:
323
- del filevars["__builtins__"]
324
-
325
- for key, value in config.items():
326
- if value is not None:
327
- filevars[key] = value
328
-
329
- keys = list(filevars.keys())
330
- keys.sort()
331
-
332
- outf = open(filename, "w")
333
- for key in keys:
334
- outf.write("%s = %s\n" % (key, repr(filevars[key])))
335
- outf.close()
336
-
337
- return result
338
-
339
- def update_user_config(self, config):
340
- self.update_conf_file(self.user_conf_file, config)
341
-
342
- def update_global_config(self, config):
343
- if self.global_conf_file is not None:
344
- self.update_conf_file(self.global_conf_file, config)
345
-
346
- def get_default_config_with_files(self):
347
- result = self.get_default_config()
348
-
349
- import os
350
-
351
- confignames = []
352
- if self.global_conf_file is not None:
353
- confignames.append(self.global_conf_file)
354
- confignames.append(self.user_conf_file)
355
-
356
- for fn in confignames:
357
- if os.access(fn, os.R_OK):
358
- result.update(self.read_config_from_pyfile(fn))
359
-
360
- return result
361
-
362
- def have_global_config(self):
363
- import os
364
- result = os.access(self.user_conf_file, os.R_OK)
365
-
366
- if self.global_conf_file is not None:
367
- result = result or os.access(self.global_conf_file, os.R_OK)
368
-
369
- return result
370
-
371
- def have_config(self):
372
- import os
373
- return os.access(self.get_conf_file(), os.R_OK)
374
-
375
- def update_from_python_snippet(self, config, py_snippet, filename):
376
- filevars = {}
377
- exec(compile(py_snippet, filename, "exec"), filevars)
378
-
379
- for key, value in filevars.items():
380
- if key in self.optdict:
381
- config[key] = value
382
- elif key == "__builtins__":
383
- pass
384
- else:
385
- raise KeyError("invalid config key in %s: %s" % (
386
- filename, key))
387
-
388
- def update_config_from_and_modify_command_line(self, config, argv):
389
- cfg_prefix = "--conf:"
390
-
391
- i = 0
392
- while i < len(argv):
393
- arg = argv[i]
394
-
395
- if arg.startswith(cfg_prefix):
396
- del argv[i]
397
- self.update_from_python_snippet(
398
- config, arg[len(cfg_prefix):], "<command line>")
399
- else:
400
- i += 1
401
-
402
- return config
403
-
404
- def read_config(self):
405
- import os
406
- cfile = self.get_conf_file()
407
-
408
- result = self.get_default_config_with_files()
409
- if os.access(cfile, os.R_OK):
410
- with open(cfile, "r") as inf:
411
- py_snippet = inf.read()
412
- self.update_from_python_snippet(result, py_snippet, cfile)
413
-
414
- return result
415
-
416
- def add_to_configparser(self, parser, def_config=None):
417
- if def_config is None:
418
- def_config = self.get_default_config_with_files()
419
-
420
- for opt in self.options:
421
- default = default_or(def_config.get(opt.name), opt.default)
422
- opt.add_to_configparser(parser, default)
423
-
424
- def get_from_configparser(self, options):
425
- result = {}
426
- for opt in self.options:
427
- result[opt.name] = opt.take_from_configparser(options)
428
- return result
429
-
430
- def write_config(self, config):
431
- outf = open(self.get_conf_file(), "w")
432
- for opt in self.options:
433
- value = config[opt.name]
434
- if value is not None:
435
- outf.write("%s = %s\n" % (opt.name, repr(config[opt.name])))
436
- outf.close()
437
-
438
- def make_substitutions(self, config):
439
- return dict((opt.name, opt.value_to_str(config[opt.name]))
440
- for opt in self.options)
441
-
442
-
443
- class Option(object):
444
- def __init__(self, name, default=None, help=None):
445
- self.name = name
446
- self.default = default
447
- self.help = help
448
-
449
- def as_option(self):
450
- return self.name.lower().replace("_", "-")
451
-
452
- def metavar(self):
453
- last_underscore = self.name.rfind("_")
454
- return self.name[last_underscore+1:]
455
-
456
- def get_help(self, default):
457
- result = self.help
458
- if self.default:
459
- result += " (default: %s)" % self.value_to_str(
460
- default_or(default, self.default))
461
- return result
462
-
463
- def value_to_str(self, default):
464
- return default
465
-
466
- def add_to_configparser(self, parser, default=None):
467
- default = default_or(default, self.default)
468
- default_str = self.value_to_str(default)
469
- parser.add_option(
470
- "--" + self.as_option(), dest=self.name,
471
- default=default_str,
472
- metavar=self.metavar(), help=self.get_help(default))
473
-
474
- def take_from_configparser(self, options):
475
- return getattr(options, self.name)
476
-
477
-
478
- class Switch(Option):
479
- def add_to_configparser(self, parser, default=None):
480
- if not isinstance(self.default, bool):
481
- raise ValueError("Switch options must have a default")
482
-
483
- if default is None:
484
- default = self.default
485
-
486
- option_name = self.as_option()
487
-
488
- if default:
489
- option_name = "no-" + option_name
490
- action = "store_false"
491
- else:
492
- action = "store_true"
493
-
494
- parser.add_option(
495
- "--" + option_name,
496
- dest=self.name,
497
- help=self.get_help(default),
498
- default=default,
499
- action=action)
500
-
501
-
502
- class StringListOption(Option):
503
- def value_to_str(self, default):
504
- if default is None:
505
- return None
506
-
507
- return ",".join([str(el).replace(",", r"\,") for el in default])
508
-
509
- def get_help(self, default):
510
- return Option.get_help(self, default) + " (several ok)"
511
-
512
- def take_from_configparser(self, options):
513
- opt = getattr(options, self.name)
514
- if opt is None:
515
- return None
516
- else:
517
- if opt:
518
- import re
519
- sep = re.compile(r"(?<!\\),")
520
- result = sep.split(opt)
521
- result = [i.replace(r"\,", ",") for i in result]
522
- return result
523
- else:
524
- return []
525
-
526
-
527
- class IncludeDir(StringListOption):
528
- def __init__(self, lib_name, default=None, human_name=None, help=None):
529
- StringListOption.__init__(self, "%s_INC_DIR" % lib_name, default,
530
- help=help or ("Include directories for %s"
531
- % (human_name or humanize(lib_name))))
532
-
533
-
534
- class LibraryDir(StringListOption):
535
- def __init__(self, lib_name, default=None, human_name=None, help=None):
536
- StringListOption.__init__(self, "%s_LIB_DIR" % lib_name, default,
537
- help=help or ("Library directories for %s"
538
- % (human_name or humanize(lib_name))))
539
-
540
-
541
- class Libraries(StringListOption):
542
- def __init__(self, lib_name, default=None, human_name=None, help=None):
543
- StringListOption.__init__(self, "%s_LIBNAME" % lib_name, default,
544
- help=help or ("Library names for %s (without lib or .so)"
545
- % (human_name or humanize(lib_name))))
546
-
547
- # }}}
548
-
549
-
550
- # {{{ configure options for specific software
551
-
552
- class BoostLibraries(Libraries):
553
- def __init__(self, lib_base_name, default_lib_name=None):
554
- if default_lib_name is None:
555
- if lib_base_name == "python":
556
- default_lib_name = "boost_python-py%d%d" % sys.version_info[:2]
557
- else:
558
- default_lib_name = "boost_%s" % lib_base_name
559
-
560
- Libraries.__init__(self, "BOOST_%s" % lib_base_name.upper(),
561
- [default_lib_name],
562
- help="Library names for Boost C++ %s library (without lib or .so)"
563
- % humanize(lib_base_name))
564
-
565
-
566
- def set_up_shipped_boost_if_requested(project_name, conf, source_path=None,
567
- boost_chrono=False):
568
- """Set up the package to use a shipped version of Boost.
569
-
570
- Return a tuple of a list of extra C files to build and extra
571
- defines to be used.
572
-
573
- :arg boost_chrono: one of *False* and ``"header_only"``
574
- (only relevant in shipped mode)
575
- """
576
- from os.path import exists
577
-
578
- if source_path is None:
579
- source_path = "bpl-subset/bpl_subset"
580
-
581
- if conf["USE_SHIPPED_BOOST"]:
582
- if not exists("%s/boost/version.hpp" % source_path):
583
- print(DASH_SEPARATOR)
584
- print("The shipped Boost library was not found, but "
585
- "USE_SHIPPED_BOOST is True.")
586
- print("(The files should be under %s/.)" % source_path)
587
- print(DASH_SEPARATOR)
588
- print("If you got this package from git, you probably want to do")
589
- print("")
590
- print(" $ git submodule update --init")
591
- print("")
592
- print("to fetch what you are presently missing. If you got this from")
593
- print("a distributed package on the net, that package is broken and")
594
- print("should be fixed. For now, I will turn off 'USE_SHIPPED_BOOST'")
595
- print("to try and see if the build succeeds that way, but in the long")
596
- print("run you might want to either get the missing bits or turn")
597
- print("'USE_SHIPPED_BOOST' off.")
598
- print(DASH_SEPARATOR)
599
- conf["USE_SHIPPED_BOOST"] = False
600
-
601
- count_down_delay(delay=10)
602
-
603
- if conf["USE_SHIPPED_BOOST"]:
604
- conf["BOOST_INC_DIR"] = [source_path]
605
- conf["BOOST_LIB_DIR"] = []
606
- conf["BOOST_PYTHON_LIBNAME"] = []
607
- conf["BOOST_THREAD_LIBNAME"] = []
608
-
609
- from glob import glob
610
- source_files = (glob(source_path + "/libs/*/*/*/*.cpp")
611
- + glob(source_path + "/libs/*/*/*.cpp")
612
- + glob(source_path + "/libs/*/*.cpp"))
613
-
614
- # make sure next line succeeds even on Windows
615
- source_files = [f.replace("\\", "/") for f in source_files]
616
-
617
- source_files = [f for f in source_files
618
- if not f.startswith(source_path + "/libs/thread/src")]
619
-
620
- if sys.platform == "win32":
621
- source_files += glob(
622
- source_path + "/libs/thread/src/win32/*.cpp")
623
- source_files += glob(
624
- source_path + "/libs/thread/src/tss_null.cpp")
625
- else:
626
- source_files += glob(
627
- source_path + "/libs/thread/src/pthread/*.cpp")
628
-
629
- source_files = [f for f in source_files
630
- if not f.endswith("once_atomic.cpp")]
631
-
632
- from os.path import isdir
633
- main_boost_inc = source_path + "/boost"
634
- bpl_project_boost_inc = source_path + "/%sboost" % project_name
635
-
636
- if not isdir(bpl_project_boost_inc):
637
- try:
638
- from os import symlink
639
- symlink("boost", bpl_project_boost_inc)
640
- except (ImportError, OSError):
641
- from shutil import copytree
642
- print("Copying files, hang on... (do not interrupt)")
643
- copytree(main_boost_inc, bpl_project_boost_inc)
644
-
645
- defines = {
646
- # do not pick up libboost link dependency on windows
647
- "BOOST_ALL_NO_LIB": 1,
648
- "BOOST_THREAD_BUILD_DLL": 1,
649
-
650
- "BOOST_MULTI_INDEX_DISABLE_SERIALIZATION": 1,
651
- "BOOST_PYTHON_SOURCE": 1,
652
- "boost": "%sboost" % project_name,
653
- }
654
-
655
- if boost_chrono is False:
656
- defines["BOOST_THREAD_DONT_USE_CHRONO"] = 1
657
- elif boost_chrono == "header_only":
658
- defines["BOOST_CHRONO_HEADER_ONLY"] = 1
659
- else:
660
- raise ValueError("invalid value of 'boost_chrono'")
661
-
662
- return (source_files, defines)
663
- else:
664
- return [], {}
665
-
666
-
667
- def make_boost_base_options():
668
- return [
669
- IncludeDir("BOOST", []),
670
- LibraryDir("BOOST", []),
671
- Option("BOOST_COMPILER", default="gcc43",
672
- help="The compiler with which Boost C++ was compiled, e.g. gcc43"),
673
- ]
674
-
675
- # }}}
676
-
677
-
678
- # {{{ configure frontend
679
-
680
- def configure_frontend():
681
- from optparse import OptionParser
682
-
683
- from setup import get_config_schema
684
- schema = get_config_schema()
685
- if schema.have_config():
686
- print("************************************************************")
687
- print("*** I have detected that you have already run configure.")
688
- print("*** I'm taking the configured values as defaults for this")
689
- print("*** configure run. If you don't want this, delete the file")
690
- print("*** %s." % schema.get_conf_file())
691
- print("************************************************************")
692
-
693
- description = "generate a configuration file for this software package"
694
- parser = OptionParser(description=description)
695
- parser.add_option(
696
- "--python-exe", dest="python_exe", default=sys.executable,
697
- help="Which Python interpreter to use", metavar="PATH")
698
-
699
- parser.add_option("--prefix", default=None,
700
- help="Ignored")
701
- parser.add_option("--enable-shared", help="Ignored", action="store_false")
702
- parser.add_option("--disable-static", help="Ignored", action="store_false")
703
- parser.add_option("--update-user",
704
- help="Update user config file (%s)" % schema.user_conf_file,
705
- action="store_true")
706
- parser.add_option("--update-global",
707
- help="Update global config file (%s)" % schema.global_conf_file,
708
- action="store_true")
709
-
710
- schema.add_to_configparser(parser, schema.read_config())
711
-
712
- options, args = parser.parse_args()
713
-
714
- config = schema.get_from_configparser(options)
715
- schema.write_config(config)
716
-
717
- if options.update_user:
718
- schema.update_user_config(config)
719
-
720
- if options.update_global:
721
- schema.update_global_config(config)
722
-
723
- import os
724
- if os.access("Makefile.in", os.F_OK):
725
- substs = schema.make_substitutions(config)
726
- substs["PYTHON_EXE"] = options.python_exe
727
-
728
- substitute(substs, "Makefile")
729
-
730
- # }}}
731
-
732
-
733
- def substitute(substitutions, fname):
734
- import re
735
- var_re = re.compile(r"\$\{([A-Za-z_0-9]+)\}")
736
- string_var_re = re.compile(r"\$str\{([A-Za-z_0-9]+)\}")
737
-
738
- fname_in = fname+".in"
739
- with open(fname_in, "r") as inf:
740
- lines = inf.readlines()
741
-
742
- new_lines = []
743
- for line in lines:
744
- made_change = True
745
- while made_change:
746
- made_change = False
747
- match = var_re.search(line)
748
- if match:
749
- varname = match.group(1)
750
- line = (
751
- line[:match.start()]
752
- + str(substitutions[varname])
753
- + line[match.end():])
754
- made_change = True
755
-
756
- match = string_var_re.search(line)
757
- if match:
758
- varname = match.group(1)
759
- subst = substitutions[varname]
760
- if subst is None:
761
- subst = ""
762
- else:
763
- subst = '"%s"' % subst
764
-
765
- line = line[:match.start()] + subst + line[match.end():]
766
- made_change = True
767
- new_lines.append(line)
768
- new_lines.insert(1, "# DO NOT EDIT THIS FILE -- "
769
- "it was generated by configure.py\n")
770
- new_lines.insert(2, "# %s\n" % (" ".join(sys.argv)))
771
- with open(fname, "w") as outf:
772
- outf.write("".join(new_lines))
773
-
774
- from os import chmod, stat
775
- infile_stat_res = stat(fname_in)
776
- chmod(fname, infile_stat_res.st_mode)
777
-
778
-
779
- # {{{ git bits
780
-
781
- def _run_git_command(cmd):
782
- git_error = None
783
- from subprocess import PIPE, Popen
784
- stdout = None
785
- try:
786
- popen = Popen(["git"] + cmd, stdout=PIPE)
787
- stdout, stderr = popen.communicate()
788
- if popen.returncode != 0:
789
- git_error = "git returned error code %d: %s" % (popen.returncode, stderr)
790
- except OSError:
791
- git_error = "(OS error, likely git not found)"
792
-
793
- if git_error is not None:
794
- print(DASH_SEPARATOR)
795
- print("Trouble invoking git")
796
- print(DASH_SEPARATOR)
797
- print("The package directory appears to be a git repository, but I could")
798
- print("not invoke git to check whether my submodules are up to date.")
799
- print("")
800
- print("The error was:")
801
- print(git_error)
802
- print("Hit Ctrl-C now if you'd like to think about the situation.")
803
- print(DASH_SEPARATOR)
804
- count_down_delay(delay=0)
805
- if stdout:
806
- return stdout.decode("utf-8"), git_error
807
- else:
808
- return "", "(subprocess call to git did not succeed)"
809
-
810
-
811
- def check_git_submodules():
812
- from os.path import isdir
813
- if not isdir(".git"):
814
- # not a git repository
815
- return
816
- if isdir("../.repo"):
817
- # assume repo is in charge and bail
818
- return
819
-
820
- stdout, git_error = _run_git_command(["submodule", "status"])
821
- if git_error is not None:
822
- return
823
-
824
- pkg_warnings = []
825
-
826
- lines = stdout.split("\n")
827
- for ln in lines:
828
- if not ln.strip():
829
- continue
830
-
831
- status = ln[0]
832
- sha, package = ln[1:].split(" ", 1)
833
-
834
- if package == "bpl-subset" or (
835
- package.startswith("boost") and package.endswith("subset")):
836
- # treated separately
837
- continue
838
-
839
- if status == "+":
840
- pkg_warnings.append("version of '%s' is not what this "
841
- "outer package wants" % package)
842
- elif status == "-":
843
- pkg_warnings.append("subpackage '%s' is not initialized"
844
- % package)
845
- elif status == " ":
846
- pass
847
- else:
848
- pkg_warnings.append("subpackage '%s' has unrecognized status '%s'"
849
- % package)
850
-
851
- if pkg_warnings:
852
- print(DASH_SEPARATOR)
853
- print("git submodules are not up-to-date or in odd state")
854
- print(DASH_SEPARATOR)
855
- print("If this makes no sense, you probably want to say")
856
- print("")
857
- print(" $ git submodule update --init")
858
- print("")
859
- print("to fetch what you are presently missing and "
860
- "move on with your life.")
861
- print("If you got this from a distributed package on the "
862
- "net, that package is")
863
- print("broken and should be fixed. Please inform whoever "
864
- "gave you this package.")
865
- print("")
866
- print("These issues were found:")
867
- for w in pkg_warnings:
868
- print(" %s" % w)
869
- print("")
870
- print("I will try to initialize the submodules for you "
871
- "after a short wait.")
872
- print(DASH_SEPARATOR)
873
- print("Hit Ctrl-C now if you'd like to think about the situation.")
874
- print(DASH_SEPARATOR)
875
-
876
- from os.path import exists
877
- if not exists(".dirty-git-ok"):
878
- count_down_delay(delay=10)
879
- stdout, git_error = _run_git_command(
880
- ["submodule", "update", "--init"])
881
- if git_error is None:
882
- print(DASH_SEPARATOR)
883
- print("git submodules initialized successfully")
884
- print(DASH_SEPARATOR)
885
-
886
- # }}}
887
-
888
-
889
- # {{{ pybind11
890
-
891
- def check_pybind11():
892
- try:
893
- import pybind11 # noqa
894
- except ImportError:
895
- print(DASH_SEPARATOR)
896
- print("Pybind11 is not installed.")
897
- print(DASH_SEPARATOR)
898
- print("Very likely, the build process after this message will fail.")
899
- print("")
900
- print("Simply press Ctrl+C and type")
901
- print("python -m pip install pybind11")
902
- print("to fix this. If you don't, the build will continue ")
903
- print("in a few seconds.")
904
- print("")
905
- print("[1] https://pybind11.readthedocs.io/en/stable/")
906
- print(DASH_SEPARATOR)
907
-
908
- from aksetup_helper import count_down_delay
909
- count_down_delay(delay=10)
910
-
911
-
912
- # {{{ (modified) boilerplate from https://github.com/pybind/python_example/blob/2ed5a68759cd6ff5d2e5992a91f08616ef457b5c/setup.py # noqa
913
-
914
- class get_pybind_include(object): # noqa: N801
915
- """Helper class to determine the pybind11 include path
916
-
917
- The purpose of this class is to postpone importing pybind11
918
- until it is actually installed, so that the ``get_include()``
919
- method can be invoked. """
920
-
921
- def __init__(self, user=False):
922
- self.user = user
923
-
924
- def __str__(self):
925
- import pybind11
926
- return pybind11.get_include(self.user)
927
-
928
-
929
- # As of Python 3.6, CCompiler has a `has_flag` method.
930
- # cf http://bugs.python.org/issue26689
931
- def has_flag(compiler, flagname):
932
- """Return a boolean indicating whether a flag name is supported on
933
- the specified compiler.
934
- """
935
- import tempfile
936
- with tempfile.NamedTemporaryFile("w", suffix=".cpp", delete=False) as f:
937
- f.write("int main (int argc, char **argv) { return 0; }")
938
- fname = f.name
939
-
940
- import setuptools
941
-
942
- try:
943
- compiler.compile([fname], extra_postargs=[flagname])
944
- except setuptools.distutils.errors.CompileError:
945
- return False
946
- return True
947
-
948
-
949
- def cpp_flag(compiler):
950
- """Return the -std=c++[11/14] compiler flag.
951
-
952
- C++14 is preferred over C++11 (when it is available).
953
- """
954
- if has_flag(compiler, "-std=gnu++14"):
955
- return "-std=gnu++14"
956
- elif has_flag(compiler, "-std=c++14"):
957
- return "-std=c++14"
958
- elif has_flag(compiler, "-std=c++11"):
959
- return "-std=c++11"
960
- else:
961
- raise RuntimeError("Unsupported compiler -- at least C++11 support "
962
- "is needed!")
963
-
964
-
965
- class PybindBuildExtCommand(NumpyBuildExtCommand):
966
- """A custom build extension for adding compiler-specific options."""
967
- c_opts = {
968
- "msvc": ["/EHsc"],
969
- "unix": [],
970
- }
971
-
972
- def build_extensions(self):
973
- ct = self.compiler.compiler_type
974
- opts = self.c_opts.get(ct, [])
975
- cxx_opts = []
976
-
977
- if ct in ["unix", "mingw32"]:
978
- opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version())
979
- cxx_opts.append(cpp_flag(self.compiler))
980
- if has_flag(self.compiler, "-fvisibility=hidden"):
981
- opts.append("-fvisibility=hidden")
982
- if sys.platform == "darwin":
983
- if has_flag(self.compiler, "-stdlib=libc++"):
984
- opts.append("-stdlib=libc++")
985
- if has_flag(self.compiler, "-mmacosx-version-min=10.7"):
986
- opts.append("-mmacosx-version-min=10.7")
987
- elif ct == "msvc":
988
- opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version())
989
- for ext in self.extensions:
990
- ext.extra_compile_args = ext.extra_compile_args + opts
991
-
992
- prev__compile = self.compiler._compile
993
-
994
- # -std=... used on C files causes an error on Apple LLVM
995
- # https://gitlab.tiker.net/inducer/pymetis/-/jobs/102421
996
- def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts):
997
- if ext == ".cpp":
998
- cc_args = cc_args + cxx_opts
999
-
1000
- return prev__compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
1001
-
1002
- self.compiler._compile = _compile
1003
-
1004
- try:
1005
- NumpyBuildExtCommand.build_extensions(self)
1006
- finally:
1007
- self.compiler._compile = prev__compile
1008
-
1009
- # }}}
1010
-
1011
- # }}}
1012
-
1013
- # vim: foldmethod=marker