diff --git a/pyopencl/array.py b/pyopencl/array.py index b43756f9a30d7612a3719a59d9c7937f1208a752..d00253a4a0f7ad16b836ef23064c7f7236dae9fd 100644 --- a/pyopencl/array.py +++ b/pyopencl/array.py @@ -57,6 +57,7 @@ except: def _dtype_is_object(t): return False + # {{{ vector types class vec: @@ -2018,6 +2019,34 @@ def diff(array, queue=None, allocator=None): _diff(result, array, queue=queue) return result + +def hstack(arrays, queue=None): + from pyopencl.array import empty + + if len(arrays) == 0: + return empty(queue, (), dtype=np.float64) + + if queue is None: + for ary in arrays: + if ary.queue is not None: + queue = ary.queue + break + + from pytools import all_equal, single_valued + if not all_equal(len(ary.shape) for ary in arrays): + raise ValueError("arguments must all have the same number of axes") + + lead_shape = single_valued(ary.shape[:-1] for ary in arrays) + + w = _builtin_sum([ary.shape[-1] for ary in arrays]) + result = empty(queue, lead_shape+(w,), arrays[0].dtype) + index = 0 + for ary in arrays: + result[..., index:index+ary.shape[-1]] = ary + index += ary.shape[-1] + + return result + # }}} diff --git a/pyopencl/cache.py b/pyopencl/cache.py index 9971b1e3da62852f2a43d2bdef83098dcfc4e7fe..113f296299aa5795d68f939d7323dd5b06f31a85 100644 --- a/pyopencl/cache.py +++ b/pyopencl/cache.py @@ -338,16 +338,15 @@ def _create_built_program_from_source_cached(ctx, src, options, devices, cache_d option_idx += 1 if cache_dir is None: - from tempfile import gettempdir - import getpass - cache_dir = join(gettempdir(), - "pyopencl-compiler-cache-v2-uid%s-py%s" % ( - getpass.getuser(), ".".join(str(i) for i in sys.version_info))) + import appdirs + cache_dir = join(appdirs.user_cache_dir("pyopencl", "pyopencl"), + "pyopencl-compiler-cache-v2-py%s" % ( + ".".join(str(i) for i in sys.version_info),)) # {{{ ensure cache directory exists try: - os.mkdir(cache_dir) + os.makedirs(cache_dir) except OSError, e: from errno import EEXIST if e.errno != EEXIST: diff --git a/pyopencl/scan.py b/pyopencl/scan.py index 3b09b7d0d097972714bed7cc8537ab286c472dc8..43e0d18b1c6e142036e7c30b095d93618b69c689 100644 --- a/pyopencl/scan.py +++ b/pyopencl/scan.py @@ -1102,9 +1102,9 @@ class GenericScanKernel(_GenericScanKernelBase): if have_sol_above_floor: # delete all solutions not meeting the wg size floor - solutions = [(total, k_group_size, wg_size) - for total, k_group_size, wg_size in solutions - if wg_size >= wg_size_floor] + solutions = [(total, try_k_group_size, try_wg_size) + for total, try_k_group_size, try_wg_size in solutions + if try_wg_size >= wg_size_floor] break _, k_group_size, max_scan_wg_size = max(solutions) diff --git a/pyopencl/tools.py b/pyopencl/tools.py index 2f1c6ce340222f1f6bdf00d4027d288aace2cedc..f9603992a81efa80c18429b1c08240d662342077 100644 --- a/pyopencl/tools.py +++ b/pyopencl/tools.py @@ -918,6 +918,10 @@ class _CLFakeArrayModule: from pyopencl.array import empty return empty(self.queue, shape, dtype, order=order) + def hstack(self, arrays): + from pyopencl.array import hstack + return hstack(arrays, self.queue) + def array_module(a): if isinstance(a, np.ndarray): diff --git a/setup.cfg b/setup.cfg index eca7b43fd4a3ea8f7a21eb2a4fbdb1aab0cd4fa1..6faef2e65abe138f9ab22c94452c43be0e52c075 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,3 @@ [flake8] -ignore = E126,E127,E128,E123,E226,E241,E242 +ignore = E126,E127,E128,E123,E226,E241,E242,E265 max-line-length=85 diff --git a/setup.py b/setup.py index d489196f574a7f171ed091c1ef0b9c391d5aa6cb..86a6bdad7e6f570048796aa19d885ab8609e4ff3 100644 --- a/setup.py +++ b/setup.py @@ -180,6 +180,7 @@ def main(): import os.path current_directory = os.path.dirname(__file__) + import shutil shutil.rmtree(os.path.join(current_directory, 'pyopencl', '__pycache__/'), ignore_errors=True) @@ -225,6 +226,7 @@ def main(): "pytest>=2", "decorator>=3.2.0", "cffi>=0.7.2", + "appdirs>=1.4.0", # "Mako>=0.3.6", ],