From de0c27ce64ed1ec40bda608c550e700cce46667b Mon Sep 17 00:00:00 2001 From: mit kotak Date: Wed, 28 Jul 2021 21:11:50 -0500 Subject: [PATCH 01/10] Implemented PyCUDAArrayContextForTest + added import gpuarray to init + removed loopy-calls --- arraycontext/impl/pycuda/__init__.py | 110 ++++++++++++++++++ arraycontext/impl/pycuda/fake_numpy.py | 154 +++++++++++++++++++++++++ arraycontext/pytest.py | 26 +++++ test/test_arraycontext.py | 19 ++- 4 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 arraycontext/impl/pycuda/__init__.py create mode 100644 arraycontext/impl/pycuda/fake_numpy.py diff --git a/arraycontext/impl/pycuda/__init__.py b/arraycontext/impl/pycuda/__init__.py new file mode 100644 index 0000000..4e525d6 --- /dev/null +++ b/arraycontext/impl/pycuda/__init__.py @@ -0,0 +1,110 @@ +""" +.. currentmodule:: arraycontext +.. autoclass:: PyCudaOpenCLArrayContext +""" + +__copyright__ = """ +Copyright (C) 2020-1 University of Illinois Board of Trustees +""" + +__license__ = """ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +""" + +from warnings import warn +from typing import Dict, List, Sequence, Optional, Union, TYPE_CHECKING + +import numpy as np + +from pytools.tag import Tag + +from arraycontext.context import ArrayContext + + +if TYPE_CHECKING: + import pyopencl + import loopy as lp + + +# {{{ PyCUDAArrayContext + +class PyCUDAArrayContext(ArrayContext): + """ + A :class:`ArrayContext` that uses :class:`pycuda.gpuarray.GPUArray` instances + for its base array class. + + .. attribute:: allocator + + A PyOpenCL memory allocator. Can also be `None` (default) or `False` to + use the default allocator. + + .. automethod:: __init__ + """ + + def __init__(self, allocator=None): + super().__init__() + self.allocator = allocator + + + def _get_fake_numpy_namespace(self): + from arraycontext.impl.pycuda.fake_numpy import PyCUDAFakeNumpyNamespace + return PyCUDAFakeNumpyNamespace(self) + + # {{{ ArrayContext interface + + def empty(self, shape, dtype): + import pycuda.gpuarray as gpuarray + return gpuarray.empty(shape=shape, dtype=dtype, + allocator=self.allocator) + + def zeros(self, shape, dtype): + import pycuda.gpuarray as gpuarray + return gpuarray.zeros(shape=shape, dtype=dtype, + allocator=self.allocator) + + def from_numpy(self, array: np.ndarray): + import pycuda.gpuarray as gpuarray + return gpuarray.to_gpu(array, allocator=self.allocator) + + def to_numpy(self, array): + import pycuda.gpuarray as gpuarray + return array.get() + + def call_loopy(self, t_unit, **kwargs): + raise NotImplementedError('Waiting for loopy to be more capable') + + def freeze(self, array): + array.finish() + return array + + def thaw(self, array): + return array + + # }}} + + def clone(self): + return type(self)(self.allocator)) + + @property + def permits_inplace_modification(self): + return True + +# }}} + +# vim: foldmethod=marker diff --git a/arraycontext/impl/pycuda/fake_numpy.py b/arraycontext/impl/pycuda/fake_numpy.py new file mode 100644 index 0000000..a2c520f --- /dev/null +++ b/arraycontext/impl/pycuda/fake_numpy.py @@ -0,0 +1,154 @@ +""" +.. currentmodule:: arraycontext +.. autoclass:: PyOpenCLArrayContext +""" +__copyright__ = """ +Copyright (C) 2020-1 University of Illinois Board of Trustees +""" + +__license__ = """ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +""" + +from functools import partial, reduce +import operator + +from arraycontext.fake_numpy import \ + BaseFakeNumpyNamespace, BaseFakeNumpyLinalgNamespace +from arraycontext.container.traversal import ( + rec_multimap_array_container, rec_map_array_container, + rec_map_reduce_array_container, + ) + +try: + import pycuda.gpuarray as gpuarray a +except ImportError: + pass + + +# {{{ fake numpy + +class PyCUDAFakeNumpyNamespace(BaseFakeNumpyNamespace): + def _get_fake_numpy_linalg_namespace(self): + return _PyCUDAFakeNumpyLinalgNamespace(self._array_context) + + # {{{ comparisons + + # FIXME: This should be documentation, not a comment. + # These are here mainly because some arrays may choose to interpret + # equality comparison as a binary predicate of structural identity, + # i.e. more like "are you two equal", and not like numpy semantics. + # These operations provide access to numpy-style comparisons in that + # case. + + def equal(self, x, y): + return rec_multimap_array_container(operator.eq, x, y) + + def not_equal(self, x, y): + return rec_multimap_array_container(operator.ne, x, y) + + def greater(self, x, y): + return rec_multimap_array_container(operator.gt, x, y) + + def greater_equal(self, x, y): + return rec_multimap_array_container(operator.ge, x, y) + + def less(self, x, y): + return rec_multimap_array_container(operator.lt, x, y) + + def less_equal(self, x, y): + return rec_multimap_array_container(operator.le, x, y) + + # }}} + + def ones_like(self, ary): + def _ones_like(subary): + ones = self._array_context.empty_like(subary) + ones.fill(1) + return ones + + return self._new_like(ary, _ones_like) + + def maximum(self, x, y): + return rec_multimap_array_container(gpuarray.maximum,x, y) + + def minimum(self, x, y): + return rec_multimap_array_container(gpuarray.minimum,x, y) + + def where(self, criterion, then, else_): + return rec_multimap_array_container(gpuarray.where, criterion, then, else_) + + def sum(self, a, dtype=None): + def _gpuarray_sum(ary): + if dtype not in [ary.dtype, None]: + raise NotImplementedError + + return gpuarray.sum(ary) + + return rec_map_reduce_array_container(sum, _gpuarray_sum, a) + + def min(self, a): + return rec_map_reduce_array_container( + partial(reduce, gpuarray.minimum), gpuarray.amin, a) + + def max(self, a): + return rec_map_reduce_array_container( + partial(reduce, gpuarray.maximum), gpuarray.amax, a) + + def stack(self, arrays, axis=0): + return rec_multimap_array_container( + lambda *args: gpuarray.stack(arrays=args, axis=axis, + self._array_context.allocator), + *arrays) + + def reshape(self, a, newshape): + return gpuarray.reshape(a, newshape) + + def concatenate(self, arrays, axis=0): + return gpuarray.concatenate( + arrays, axis, + self._array_context.allocator + ) + + def ravel(self, a, order="C"): + def _rec_ravel(a): + if order in "FCA": + return a.reshape(-1, order=order) + + elif order == "K": + raise NotImplementedError("PyCUDAArrayContext.np.ravel not " + "implemented for 'order=K'") + else: + raise ValueError("`order` can be one of 'F', 'C', 'A' or 'K'. " + f"(got {order})") + + return rec_map_array_container(_rec_ravel, a) + +# }}} + + +# {{{ fake np.linalg + +class _PyCUDAFakeNumpyLinalgNamespace(BaseFakeNumpyLinalgNamespace): + pass + +# }}} + + +# vim: foldmethod=marker diff --git a/arraycontext/pytest.py b/arraycontext/pytest.py index e93a8b3..885db48 100644 --- a/arraycontext/pytest.py +++ b/arraycontext/pytest.py @@ -34,6 +34,7 @@ THE SOFTWARE. from typing import Any, Callable, Dict, Sequence, Type, Union import pyopencl as cl +import pycuda from arraycontext.context import ArrayContext @@ -70,6 +71,22 @@ class PytestPyOpenCLArrayContextFactory: raise NotImplementedError +class PytestPyCUDAArrayContextFactory: + """ + .. automethod:: __init__ + .. automethod:: __call__ + """ + + def __init__(self, allocator): + """ + :arg allocator: a :class:`gpuarray.allocator`. + """ + self.allocator = allocator + + def __call__(self) -> ArrayContext: + raise NotImplementedError + + class _PytestPyOpenCLArrayContextFactoryWithClass(PytestPyOpenCLArrayContextFactory): force_device_scalars = True @@ -126,6 +143,15 @@ class _PytestPytatoPyOpenCLArrayContextFactory( self.device.platform.name.strip())) +class _PytestPyCUDAArrayContextFactory( + PytestPyCUDAArrayContextFactory): + + def __call__(self): + from arraycontext import PyCUDAArrayContext + allocator = None + return self.actx_class(allocator) + + _ARRAY_CONTEXT_FACTORY_REGISTRY: \ Dict[str, Type[PytestPyOpenCLArrayContextFactory]] = { "pyopencl": _PytestPyOpenCLArrayContextFactoryWithClass, diff --git a/test/test_arraycontext.py b/test/test_arraycontext.py index 668e320..d7f7267 100644 --- a/test/test_arraycontext.py +++ b/test/test_arraycontext.py @@ -34,12 +34,14 @@ from arraycontext import ( FirstAxisIsElementsTag, PyOpenCLArrayContext, PytatoPyOpenCLArrayContext, + PyCUDAArrayContext, ArrayContainer,) from arraycontext import ( # noqa: F401 pytest_generate_tests_for_array_contexts, ) from arraycontext.pytest import (_PytestPyOpenCLArrayContextFactoryWithClass, - _PytestPytatoPyOpenCLArrayContextFactory) + _PytestPytatoPyOpenCLArrayContextFactory, + _PyCUDAArrayContextFactory) import logging @@ -66,6 +68,15 @@ class _PytatoPyOpenCLArrayContextForTests(PytatoPyOpenCLArrayContext): def transform_loopy_program(self, t_unit): return t_unit +class _PyCUDAArrayContextForTests(PyCUDAArrayContext): + """Like :class:`PyCUDAArrayContext`, but applies no program + transformations whatsoever. Only to be used for testing internal to + :mod:`arraycontext`. + """ + + def transform_loopy_program(self, t_unit): + return t_unit + class _PyOpenCLArrayContextWithHostScalarsForTestsFactory( _PytestPyOpenCLArrayContextFactoryWithClass): @@ -82,10 +93,16 @@ class _PytatoPyOpenCLArrayContextForTestsFactory( actx_class = _PytatoPyOpenCLArrayContextForTests +class _PyCUDAArrayContextForTestsFactory( + _PyCUDAArrayContextFactory): + actx_class = _PyCUDAArrayContextForTests + + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ _PyOpenCLArrayContextForTestsFactory, _PyOpenCLArrayContextWithHostScalarsForTestsFactory, _PytatoPyOpenCLArrayContextForTestsFactory, + _PyCUDAArrayContextForTestsFactory, ]) -- GitLab From ca50b5a4eaad6c53aeda397453e7520a5c651877 Mon Sep 17 00:00:00 2001 From: mit kotak Date: Thu, 29 Jul 2021 12:29:33 -0500 Subject: [PATCH 02/10] Resolved issues in fake_numpy.py and __init__.py --- arraycontext/__init__.py | 5 ++++- arraycontext/impl/pycuda/__init__.py | 12 +++++------- arraycontext/impl/pycuda/fake_numpy.py | 27 ++++---------------------- arraycontext/pytest.py | 10 +++++++--- 4 files changed, 20 insertions(+), 34 deletions(-) diff --git a/arraycontext/__init__.py b/arraycontext/__init__.py index aafcfd8..5bf92e6 100644 --- a/arraycontext/__init__.py +++ b/arraycontext/__init__.py @@ -59,9 +59,11 @@ from .container.traversal import ( from .impl.pyopencl import PyOpenCLArrayContext from .impl.pytato import PytatoPyOpenCLArrayContext +from .impl.pycuda import PyCUDAArrayContext from .pytest import ( PytestPyOpenCLArrayContextFactory, + PytestPyCUDAArrayContextFactory, pytest_generate_tests_for_array_contexts, pytest_generate_tests_for_pyopencl_array_context) @@ -89,11 +91,12 @@ __all__ = ( "thaw", "freeze", "from_numpy", "to_numpy", - "PyOpenCLArrayContext", "PytatoPyOpenCLArrayContext", + "PyOpenCLArrayContext", "PytatoPyOpenCLArrayContext","PyCUDAArrayContext", "make_loopy_program", "PytestPyOpenCLArrayContextFactory", + "PyCUDAArrayContextFactory", "pytest_generate_tests_for_array_contexts", "pytest_generate_tests_for_pyopencl_array_context" ) diff --git a/arraycontext/impl/pycuda/__init__.py b/arraycontext/impl/pycuda/__init__.py index 4e525d6..c490772 100644 --- a/arraycontext/impl/pycuda/__init__.py +++ b/arraycontext/impl/pycuda/__init__.py @@ -1,10 +1,10 @@ """ .. currentmodule:: arraycontext -.. autoclass:: PyCudaOpenCLArrayContext +.. autoclass:: PyCUDAArrayContext """ __copyright__ = """ -Copyright (C) 2020-1 University of Illinois Board of Trustees +Copyright (C) 2021 University of Illinois Board of Trustees """ __license__ = """ @@ -38,8 +38,7 @@ from arraycontext.context import ArrayContext if TYPE_CHECKING: - import pyopencl - import loopy as lp + import pycuda # {{{ PyCUDAArrayContext @@ -51,7 +50,7 @@ class PyCUDAArrayContext(ArrayContext): .. attribute:: allocator - A PyOpenCL memory allocator. Can also be `None` (default) or `False` to + A PyCUDA memory allocator. Can also be `None` (default) or `False` to use the default allocator. .. automethod:: __init__ @@ -90,7 +89,6 @@ class PyCUDAArrayContext(ArrayContext): raise NotImplementedError('Waiting for loopy to be more capable') def freeze(self, array): - array.finish() return array def thaw(self, array): @@ -99,7 +97,7 @@ class PyCUDAArrayContext(ArrayContext): # }}} def clone(self): - return type(self)(self.allocator)) + return type(self)(self.allocator) @property def permits_inplace_modification(self): diff --git a/arraycontext/impl/pycuda/fake_numpy.py b/arraycontext/impl/pycuda/fake_numpy.py index a2c520f..885f559 100644 --- a/arraycontext/impl/pycuda/fake_numpy.py +++ b/arraycontext/impl/pycuda/fake_numpy.py @@ -1,9 +1,9 @@ """ .. currentmodule:: arraycontext -.. autoclass:: PyOpenCLArrayContext +.. autoclass:: PyCUDAArrayContext """ __copyright__ = """ -Copyright (C) 2020-1 University of Illinois Board of Trustees +Copyright (C) 2021 University of Illinois Board of Trustees """ __license__ = """ @@ -37,7 +37,7 @@ from arraycontext.container.traversal import ( ) try: - import pycuda.gpuarray as gpuarray a + import pycuda.gpuarray as gpuarray except ImportError: pass @@ -77,14 +77,6 @@ class PyCUDAFakeNumpyNamespace(BaseFakeNumpyNamespace): # }}} - def ones_like(self, ary): - def _ones_like(subary): - ones = self._array_context.empty_like(subary) - ones.fill(1) - return ones - - return self._new_like(ary, _ones_like) - def maximum(self, x, y): return rec_multimap_array_container(gpuarray.maximum,x, y) @@ -127,18 +119,7 @@ class PyCUDAFakeNumpyNamespace(BaseFakeNumpyNamespace): ) def ravel(self, a, order="C"): - def _rec_ravel(a): - if order in "FCA": - return a.reshape(-1, order=order) - - elif order == "K": - raise NotImplementedError("PyCUDAArrayContext.np.ravel not " - "implemented for 'order=K'") - else: - raise ValueError("`order` can be one of 'F', 'C', 'A' or 'K'. " - f"(got {order})") - - return rec_map_array_container(_rec_ravel, a) + return gpuarray.reshape(a,-1,order=order) # }}} diff --git a/arraycontext/pytest.py b/arraycontext/pytest.py index 885db48..9f3b70c 100644 --- a/arraycontext/pytest.py +++ b/arraycontext/pytest.py @@ -2,6 +2,7 @@ .. currentmodule:: arraycontext .. autoclass:: PytestPyOpenCLArrayContextFactory +.. autoclass:: PytestPyCUDAArrayContextFactory .. autofunction:: pytest_generate_tests_for_array_contexts .. autofunction:: pytest_generate_tests_for_pyopencl_array_context @@ -146,10 +147,13 @@ class _PytestPytatoPyOpenCLArrayContextFactory( class _PytestPyCUDAArrayContextFactory( PytestPyCUDAArrayContextFactory): - def __call__(self): + @property + def actx_class(self): from arraycontext import PyCUDAArrayContext - allocator = None - return self.actx_class(allocator) + return PyCUDAArrayContext + + def __call__(self): + return self.actx_class(None) _ARRAY_CONTEXT_FACTORY_REGISTRY: \ -- GitLab From a663bac3e69853e64a7be93c7cdbf1d2aae3fd00 Mon Sep 17 00:00:00 2001 From: mit kotak Date: Sun, 1 Aug 2021 18:10:27 -0500 Subject: [PATCH 03/10] Migrating stuff to dunkel --- arraycontext/.pytest.py.swm | Bin 0 -> 20480 bytes arraycontext/.pytest.py.swn | Bin 0 -> 24576 bytes arraycontext/impl/pycuda/__init__.py | 6 ++++++ arraycontext/pytest.py | 3 +++ test/test_arraycontext.py | 6 +++--- 5 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 arraycontext/.pytest.py.swm create mode 100644 arraycontext/.pytest.py.swn diff --git a/arraycontext/.pytest.py.swm b/arraycontext/.pytest.py.swm new file mode 100644 index 0000000000000000000000000000000000000000..76d766eb6afded79da5bfdcbeed45a1d8c874513 GIT binary patch literal 20480 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 fruob;of)QeL`P Date: Tue, 3 Aug 2021 22:14:58 -0500 Subject: [PATCH 04/10] commented out BaseClass __attr__ --- arraycontext/fake_numpy.py | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/arraycontext/fake_numpy.py b/arraycontext/fake_numpy.py index cdb9534..c3af098 100644 --- a/arraycontext/fake_numpy.py +++ b/arraycontext/fake_numpy.py @@ -145,30 +145,30 @@ class BaseFakeNumpyNamespace: _c_to_numpy_arc_functions = {c_name: numpy_name for numpy_name, c_name in _numpy_to_c_arc_functions.items()} - def __getattr__(self, name): - def loopy_implemented_elwise_func(*args): - actx = self._array_context - prg = _get_scalar_func_loopy_program(actx, - c_name, nargs=len(args), naxes=len(args[0].shape)) - outputs = actx.call_loopy(prg, - **{"inp%d" % i: arg for i, arg in enumerate(args)}) - return outputs["out"] - - if name in self._c_to_numpy_arc_functions: - from warnings import warn - warn(f"'{name}' in ArrayContext.np is deprecated. " - "Use '{c_to_numpy_arc_functions[name]}' as in numpy. " - "The old name will stop working in 2021.", - DeprecationWarning, stacklevel=3) + #def __getattr__(self, name): + #def loopy_implemented_elwise_func(*args): + #actx = self._array_context + #prg = _get_scalar_func_loopy_program(actx, + #c_name, nargs=len(args), naxes=len(args[0].shape)) + #outputs = actx.call_loopy(prg, + # **{"inp%d" % i: arg for i, arg in enumerate(args)}) + #return outputs["out"] + + #if name in self._c_to_numpy_arc_functions: + #from warnings import warn + #warn(f"'{name}' in ArrayContext.np is deprecated. " + #"Use '{c_to_numpy_arc_functions[name]}' as in numpy. " + #"The old name will stop working in 2021.", + #DeprecationWarning, stacklevel=3) # normalize to C names anyway - c_name = self._numpy_to_c_arc_functions.get(name, name) + #c_name = self._numpy_to_c_arc_functions.get(name, name) # limit which functions we try to hand off to loopy - if name in self._numpy_math_functions: - return multimapped_over_array_containers(loopy_implemented_elwise_func) - else: - raise AttributeError(name) + #if name in self._numpy_math_functions: + # return multimapped_over_array_containers(loopy_implemented_elwise_func) + #else: + #raise AttributeError(name) def _new_like(self, ary, alloc_like): from numbers import Number -- GitLab From a5ee9d4c1f253407c63b8494e20931796e501858 Mon Sep 17 00:00:00 2001 From: mit kotak Date: Tue, 3 Aug 2021 22:17:58 -0500 Subject: [PATCH 05/10] Implemented PyCUDAArrayContext __attr__ --- arraycontext/impl/pycuda/__init__.py | 9 ++++++-- arraycontext/impl/pycuda/fake_numpy.py | 29 ++++++++++++++++++++------ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/arraycontext/impl/pycuda/__init__.py b/arraycontext/impl/pycuda/__init__.py index fae9ad6..b6a0611 100644 --- a/arraycontext/impl/pycuda/__init__.py +++ b/arraycontext/impl/pycuda/__init__.py @@ -57,9 +57,14 @@ class PyCUDAArrayContext(ArrayContext): """ def __init__(self, allocator=None): + import pycuda super().__init__() - self.allocator = allocator - + if allocator == None: + self.allocator = pycuda.driver.mem_alloc + from warnings import warn + warn("Allocator is None") + else: + self.allocator = allocator def _get_fake_numpy_namespace(self): from arraycontext.impl.pycuda.fake_numpy import PyCUDAFakeNumpyNamespace diff --git a/arraycontext/impl/pycuda/fake_numpy.py b/arraycontext/impl/pycuda/fake_numpy.py index 885f559..ce9ceb2 100644 --- a/arraycontext/impl/pycuda/fake_numpy.py +++ b/arraycontext/impl/pycuda/fake_numpy.py @@ -36,6 +36,8 @@ from arraycontext.container.traversal import ( rec_map_reduce_array_container, ) +import pycuda + try: import pycuda.gpuarray as gpuarray except ImportError: @@ -48,6 +50,17 @@ class PyCUDAFakeNumpyNamespace(BaseFakeNumpyNamespace): def _get_fake_numpy_linalg_namespace(self): return _PyCUDAFakeNumpyLinalgNamespace(self._array_context) + def __getattr__(self, name): + print(name) + pycuda_funcs = ["abs", "sin", "cos", "tan", "arcsin", "arccos", "arctan", + "sinh", "cosh", "tanh", "exp", "log", "log10", "isnan", + "sqrt", "exp"] + if name in pycuda_funcs: + from functools import partial + return partial(rec_map_array_container, getattr(pycuda, name)) + + return super().__getattr__(name) + # {{{ comparisons # FIXME: This should be documentation, not a comment. @@ -84,7 +97,12 @@ class PyCUDAFakeNumpyNamespace(BaseFakeNumpyNamespace): return rec_multimap_array_container(gpuarray.minimum,x, y) def where(self, criterion, then, else_): - return rec_multimap_array_container(gpuarray.where, criterion, then, else_) + def where_inner(inner_crit, inner_then, inner_else): + if isinstance(inner_crit, bool): + return inner_then if inner_crit else inner_else + return gpuarray.if_positive(inner_crit != 0, inner_then, inner_else) + + return rec_multimap_array_container(where_inner, criterion, then, else_) def sum(self, a, dtype=None): def _gpuarray_sum(ary): @@ -97,16 +115,15 @@ class PyCUDAFakeNumpyNamespace(BaseFakeNumpyNamespace): def min(self, a): return rec_map_reduce_array_container( - partial(reduce, gpuarray.minimum), gpuarray.amin, a) + partial(reduce, partial(gpuarray.minimum)),partial(gpuarray.min),a) def max(self, a): return rec_map_reduce_array_container( - partial(reduce, gpuarray.maximum), gpuarray.amax, a) + partial(reduce, partial(gpuarray.maximum)), partial(gpuarray.max), a) def stack(self, arrays, axis=0): - return rec_multimap_array_container( - lambda *args: gpuarray.stack(arrays=args, axis=axis, - self._array_context.allocator), + return rec_multimap_array_container( + lambda *args: gpuarray.stack(arrays=args, axis=axis), *arrays) def reshape(self, a, newshape): -- GitLab From 7934c2b8ea6630ac6639c84bfbb69c44112bf3ce Mon Sep 17 00:00:00 2001 From: mit kotak Date: Tue, 3 Aug 2021 22:27:17 -0500 Subject: [PATCH 06/10] Skipped pytest.PyCUDAArrayContext.where --- arraycontext/pytest.py | 60 +++++++++++++++++++++++++++++++++++++-- test/test_arraycontext.py | 15 ++++++---- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/arraycontext/pytest.py b/arraycontext/pytest.py index 33aa865..9b6ebfb 100644 --- a/arraycontext/pytest.py +++ b/arraycontext/pytest.py @@ -153,10 +153,64 @@ class _PytestPyCUDAArrayContextFactory( return PyCUDAArrayContext def __call__(self): + def make_default_context(ctx_maker=None): + if ctx_maker is None: + + def ctx_maker(dev): + return dev.make_context() + + ndevices = cuda.Device.count() + if ndevices == 0: + raise RuntimeError( + "No CUDA enabled device found. " "Please check your installation." + ) + + # Is CUDA_DEVICE set? + import os + + devn = os.environ.get("CUDA_DEVICE") + + # Is $HOME/.cuda_device set ? + if devn is None: + try: + homedir = os.environ.get("HOME") + assert homedir is not None + devn = open(os.path.join(homedir, ".cuda_device")).read().strip() + except Exception: + pass + + # If either CUDA_DEVICE or $HOME/.cuda_device is set, try to use it + if devn is not None: + try: + devn = int(devn) + except TypeError: + raise TypeError( + "CUDA device number (CUDA_DEVICE or ~/.cuda_device)" + " must be an integer" + ) + + dev = cuda.Device(devn) + return ctx_maker(dev) + + # Otherwise, try to use any available device + else: + for devn in range(ndevices): + dev = cuda.Device(devn) + try: + return ctx_maker(dev) + except cuda.Error: + pass + + raise RuntimeError( + "make_default_context() wasn't able to create a context " + "on any of the %d detected devices" % ndevices + ) + import pycuda.driver as cuda - dev = cuda.init() - ctx = dev.make_default_context() - return self.actx_class(None) + actx_class = self.actx_class(None) + cuda.init() + ctx = make_default_context() + return actx_class _ARRAY_CONTEXT_FACTORY_REGISTRY: \ diff --git a/test/test_arraycontext.py b/test/test_arraycontext.py index e721cd3..5869186 100644 --- a/test/test_arraycontext.py +++ b/test/test_arraycontext.py @@ -98,14 +98,17 @@ class _PyCUDAArrayContextForTestsFactory( actx_class = _PyCUDAArrayContextForTests +#pytest_generate_tests = pytest_generate_tests_for_array_contexts([ + #_PyOpenCLArrayContextForTestsFactory, + #_PyOpenCLArrayContextWithHostScalarsForTestsFactory, + #_PytatoPyOpenCLArrayContextForTestsFactory, + #_PyCUDAArrayContextForTestsFactory, + #]) + pytest_generate_tests = pytest_generate_tests_for_array_contexts([ - _PyOpenCLArrayContextForTestsFactory, - _PyOpenCLArrayContextWithHostScalarsForTestsFactory, - _PytatoPyOpenCLArrayContextForTestsFactory, - _PyCUDAArrayContextForTestsFactory, + _PyCUDAArrayContextForTestsFactory ]) - def _acf(): import pyopencl as cl @@ -322,6 +325,8 @@ def test_array_context_np_workalike(actx_factory, sym_name, n_args, dtype): ]) def test_array_context_np_like(actx_factory, sym_name, n_args, dtype): actx = actx_factory() + if not hasattr(actx.np, sym_name): + pytest.skip(f"'{sym_name}' not implemented on '{type(actx).__name__}'") ndofs = 512 args = [randn(ndofs, dtype) for i in range(n_args)] -- GitLab From 7db2774fc6c8e16c84368441304a2db017bec083 Mon Sep 17 00:00:00 2001 From: mit kotak Date: Fri, 27 Aug 2021 15:50:14 -0500 Subject: [PATCH 07/10] Bringing back arraycontext/fake_numpy.__getattr__ --- arraycontext/fake_numpy.py | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/arraycontext/fake_numpy.py b/arraycontext/fake_numpy.py index c3af098..d835efd 100644 --- a/arraycontext/fake_numpy.py +++ b/arraycontext/fake_numpy.py @@ -145,30 +145,30 @@ class BaseFakeNumpyNamespace: _c_to_numpy_arc_functions = {c_name: numpy_name for numpy_name, c_name in _numpy_to_c_arc_functions.items()} - #def __getattr__(self, name): - #def loopy_implemented_elwise_func(*args): - #actx = self._array_context - #prg = _get_scalar_func_loopy_program(actx, - #c_name, nargs=len(args), naxes=len(args[0].shape)) - #outputs = actx.call_loopy(prg, - # **{"inp%d" % i: arg for i, arg in enumerate(args)}) - #return outputs["out"] - - #if name in self._c_to_numpy_arc_functions: - #from warnings import warn - #warn(f"'{name}' in ArrayContext.np is deprecated. " - #"Use '{c_to_numpy_arc_functions[name]}' as in numpy. " - #"The old name will stop working in 2021.", - #DeprecationWarning, stacklevel=3) - - # normalize to C names anyway - #c_name = self._numpy_to_c_arc_functions.get(name, name) + def __getattr__(self, name): + def loopy_implemented_elwise_func(*args): + actx = self._array_context + prg = _get_scalar_func_loopy_program(actx, + c_name, nargs=len(args), naxes=len(args[0].shape)) + outputs = actx.call_loopy(prg, + **{"inp%d" % i: arg for i, arg in enumerate(args)}) + return outputs["out"] + + if name in self._c_to_numpy_arc_functions: + from warnings import warn + warn(f"'{name}' in ArrayContext.np is deprecated. " + "Use '{c_to_numpy_arc_functions[name]}' as in numpy. " + "The old name will stop working in 2021.", + DeprecationWarning, stacklevel=3) + + #normalize to C names anyway + c_name = self._numpy_to_c_arc_functions.get(name, name) # limit which functions we try to hand off to loopy - #if name in self._numpy_math_functions: - # return multimapped_over_array_containers(loopy_implemented_elwise_func) - #else: - #raise AttributeError(name) + if name in self._numpy_math_functions: + return multimapped_over_array_containers(loopy_implemented_elwise_func) + else: + raise AttributeError(name) def _new_like(self, ary, alloc_like): from numbers import Number -- GitLab From 87f940f7e1701ce3836c17165bcb9b189c2df28f Mon Sep 17 00:00:00 2001 From: mit kotak Date: Fri, 27 Aug 2021 20:23:32 -0500 Subject: [PATCH 08/10] Implemented loopy.BaseFakeNumpy --- arraycontext/loopy.py | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/arraycontext/loopy.py b/arraycontext/loopy.py index f4c9775..64d57dd 100644 --- a/arraycontext/loopy.py +++ b/arraycontext/loopy.py @@ -70,5 +70,47 @@ def get_default_entrypoint(t_unit): # }}} - -# vim: foldmethod=marker +class BaseFakeNumpyNamespace: + _numpy_to_c_arc_functions = { + "arcsin": "asin", + "arccos": "acos", + "arctan": "atan", + "arctan2": "atan2", + + "arcsinh": "asinh", + "arccosh": "acosh", + "arctanh": "atanh", + } + + _c_to_numpy_arc_functions = {c_name: numpy_name + for numpy_name, c_name in _numpy_to_c_arc_functions.items()} + + def __getattr__(self, name): + def loopy_implemented_elwise_func(*args): + actx = self._array_context + prg = _get_scalar_func_loopy_program(actx, + c_name, nargs=len(args), naxes=len(args[0].shape)) + outputs = actx.call_loopy(prg, + **{"inp%d" % i: arg for i, arg in enumerate(args)}) + return outputs["out"] + + if name in self._c_to_numpy_arc_functions: + from warnings import warn + warn(f"'{name}' in ArrayContext.np is deprecated. " + "Use '{c_to_numpy_arc_functions[name]}' as in numpy. " + "The old name will stop working in 2022.", + DeprecationWarning, stacklevel=3) + + # normalize to C names anyway + c_name = self._numpy_to_c_arc_functions.get(name, name) + + # limit which functions we try to hand off to loopy + if name in self._numpy_math_functions: + return multimapped_over_array_containers(loopy_implemented_elwise_func) + else: + raise AttributeError(name) + + + + +vim: foldmethod=marker -- GitLab From a35a4e6960895007adbbdc50d3785bb30124c271 Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Wed, 8 Sep 2021 22:25:37 +0000 Subject: [PATCH 09/10] BaseFakeNumpyNamespace -> LoopyBasedFakeNumpyspace --- arraycontext/loopy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arraycontext/loopy.py b/arraycontext/loopy.py index 64d57dd..b5a33b7 100644 --- a/arraycontext/loopy.py +++ b/arraycontext/loopy.py @@ -70,7 +70,7 @@ def get_default_entrypoint(t_unit): # }}} -class BaseFakeNumpyNamespace: +class LoopyBasedFakeNumpyNamespace: _numpy_to_c_arc_functions = { "arcsin": "asin", "arccos": "acos", @@ -111,6 +111,6 @@ class BaseFakeNumpyNamespace: raise AttributeError(name) - + vim: foldmethod=marker -- GitLab From 062e500c3d2aaecae8a1d8b28294a6c6cd9ca9d7 Mon Sep 17 00:00:00 2001 From: Mit Kotak Date: Wed, 8 Sep 2021 22:42:09 +0000 Subject: [PATCH 10/10] Migrated arraycontext.fake_numpy.getattr to impl.pyopencl.fake_numpy.getattr --- arraycontext/fake_numpy.py | 25 ------------------------ arraycontext/impl/pyopencl/fake_numpy.py | 15 +++++++++++++- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/arraycontext/fake_numpy.py b/arraycontext/fake_numpy.py index d835efd..fdfc3c6 100644 --- a/arraycontext/fake_numpy.py +++ b/arraycontext/fake_numpy.py @@ -145,31 +145,6 @@ class BaseFakeNumpyNamespace: _c_to_numpy_arc_functions = {c_name: numpy_name for numpy_name, c_name in _numpy_to_c_arc_functions.items()} - def __getattr__(self, name): - def loopy_implemented_elwise_func(*args): - actx = self._array_context - prg = _get_scalar_func_loopy_program(actx, - c_name, nargs=len(args), naxes=len(args[0].shape)) - outputs = actx.call_loopy(prg, - **{"inp%d" % i: arg for i, arg in enumerate(args)}) - return outputs["out"] - - if name in self._c_to_numpy_arc_functions: - from warnings import warn - warn(f"'{name}' in ArrayContext.np is deprecated. " - "Use '{c_to_numpy_arc_functions[name]}' as in numpy. " - "The old name will stop working in 2021.", - DeprecationWarning, stacklevel=3) - - #normalize to C names anyway - c_name = self._numpy_to_c_arc_functions.get(name, name) - - # limit which functions we try to hand off to loopy - if name in self._numpy_math_functions: - return multimapped_over_array_containers(loopy_implemented_elwise_func) - else: - raise AttributeError(name) - def _new_like(self, ary, alloc_like): from numbers import Number diff --git a/arraycontext/impl/pyopencl/fake_numpy.py b/arraycontext/impl/pyopencl/fake_numpy.py index 01054ba..e9a2cfa 100644 --- a/arraycontext/impl/pyopencl/fake_numpy.py +++ b/arraycontext/impl/pyopencl/fake_numpy.py @@ -31,6 +31,8 @@ import operator from arraycontext.fake_numpy import \ BaseFakeNumpyNamespace, BaseFakeNumpyLinalgNamespace +from arraycontext.loopy import \ + LoopyBasedFakeNumpyspace from arraycontext.container.traversal import ( rec_multimap_array_container, rec_map_array_container, rec_map_reduce_array_container, @@ -45,7 +47,7 @@ except ImportError: # {{{ fake numpy -class PyOpenCLFakeNumpyNamespace(BaseFakeNumpyNamespace): +class PyOpenCLFakeNumpyNamespace(BaseFakeNumpyNameSpace, LoopyBasedFakeNumpyNamespace): def _get_fake_numpy_linalg_namespace(self): return _PyOpenCLFakeNumpyLinalgNamespace(self._array_context) @@ -58,6 +60,17 @@ class PyOpenCLFakeNumpyNamespace(BaseFakeNumpyNamespace): # These operations provide access to numpy-style comparisons in that # case. + def __getattr__(self, name): + print(name) + cl_funcs = ["abs", "sin", "cos", "tan", "arcsin", "arccos", "arctan", + "sinh", "cosh", "tanh", "exp", "log", "log10", "isnan", + "sqrt", "exp"] + if name in cl_funcs: + from functools import partial + return partial(rec_map_array_container, getattr(cl, name)) + + return super().__getattr__(name) + def equal(self, x, y): return rec_multimap_array_container(operator.eq, x, y) -- GitLab