From 49fc9a5c09715e3242475698d606e0dd6b883de3 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Mon, 15 Jun 2020 13:08:32 -0500 Subject: [PATCH 1/7] Stop using deprecated cl.Device.persistent_unique_id --- loopy/target/pyopencl.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/loopy/target/pyopencl.py b/loopy/target/pyopencl.py index 845e0a432..56c19930b 100644 --- a/loopy/target/pyopencl.py +++ b/loopy/target/pyopencl.py @@ -318,20 +318,21 @@ class PyOpenCLTarget(OpenCLTarget): if self.device is not None: assert other.device is not None - return (self.device.persistent_unique_id - == other.device.persistent_unique_id) + return (self.device.hashable_model_and_version_identifier + == other.device.hashable_model_and_version_identifier) else: assert other.device is None return True def update_persistent_hash(self, key_hash, key_builder): super(PyOpenCLTarget, self).update_persistent_hash(key_hash, key_builder) - key_builder.rec(key_hash, getattr(self.device, "persistent_unique_id", None)) + key_builder.rec(key_hash, getattr( + self.device, "hashable_model_and_version_identifier", None)) def __getstate__(self): dev_id = None if self.device is not None: - dev_id = self.device.persistent_unique_id + dev_id = self.device.hashable_model_and_version_identifier return { "device_id": dev_id, @@ -354,7 +355,7 @@ class PyOpenCLTarget(OpenCLTarget): dev for plat in cl.get_platforms() for dev in plat.get_devices() - if dev.persistent_unique_id == dev_id] + if dev.hashable_model_and_version_identifier == dev_id] if matches: self.device = matches[0] -- GitLab From 6aa9100b5d189d03e436389816ddd1761dff386e Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Mon, 15 Jun 2020 13:10:32 -0500 Subject: [PATCH 2/7] PyOpenCL kernel wrapper: do not re-validate allocator --- loopy/target/pyopencl.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/loopy/target/pyopencl.py b/loopy/target/pyopencl.py index 56c19930b..9be352087 100644 --- a/loopy/target/pyopencl.py +++ b/loopy/target/pyopencl.py @@ -644,7 +644,7 @@ class PyOpenCLPythonASTBuilder(PythonASTBuilderBase): + ["wait_for=None", "allocator=None"]) from genpy import (For, Function, Suite, Import, ImportAs, Return, - FromImport, If, Assign, Line, Statement as S) + FromImport, Line, Statement as S) return Function( codegen_result.current_program(codegen_state).name, args, @@ -653,11 +653,6 @@ class PyOpenCLPythonASTBuilder(PythonASTBuilderBase): ImportAs("pyopencl", "_lpy_cl"), Import("pyopencl.tools"), Line(), - If("allocator is None", - Assign( - "allocator", - "_lpy_cl_tools.DeferredAllocator(queue.context)")), - Line(), ] + [ Line(), function_body, -- GitLab From 2bd56b5862fe423876a49cf0e17e9ad170b9bf7d Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Mon, 15 Jun 2020 13:13:45 -0500 Subject: [PATCH 3/7] PyOpenCL kernel enqueue: use allow_empty_ndrange --- loopy/target/pyopencl.py | 10 +++++++++- requirements.txt | 4 ++-- setup.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/loopy/target/pyopencl.py b/loopy/target/pyopencl.py index 9be352087..1c8bf4caa 100644 --- a/loopy/target/pyopencl.py +++ b/loopy/target/pyopencl.py @@ -727,6 +727,13 @@ class PyOpenCLPythonASTBuilder(PythonASTBuilderBase): from genpy import Suite, Assign, Assert, Line, Comment from pymbolic.mapper.stringifier import PREC_NONE + import pyopencl.version as cl_ver + if cl_ver.VERSION < (2020, 2): + from warnings import warn + warn("Your kernel invocation will likely fail because your " + "version of PyOpenCL does not support allow_empty_ndrange. " + "Please upgrade to version 2020.2 or newer.") + # TODO: Generate finer-grained dependency structure return Suite([ Comment("{{{ enqueue %s" % name), @@ -738,7 +745,8 @@ class PyOpenCLPythonASTBuilder(PythonASTBuilderBase): arry_arg_code, Assign("_lpy_evt", "%(pyopencl_module_name)s.enqueue_nd_range_kernel(" "queue, _lpy_knl, " - "%(gsize)s, %(lsize)s, wait_for=wait_for, g_times_l=True)" + "%(gsize)s, %(lsize)s, wait_for=wait_for, " + "g_times_l=True, allow_empty_ndrange=True)" % dict( pyopencl_module_name=self.target.pyopencl_module_name, gsize=ecm(gsize, prec=PREC_NONE, type_context="i"), diff --git a/requirements.txt b/requirements.txt index 97c202476..40d351ec7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ git+https://github.com/inducer/pytools.git git+https://github.com/inducer/islpy.git git+https://github.com/inducer/cgen.git -git+https://github.com/inducer/pyopencl.git +git+https://gitlab.tiker.net/inducer/pyopencl.git@better-empty-handling git+https://github.com/inducer/pymbolic.git git+https://github.com/inducer/genpy.git git+https://github.com/inducer/codepy.git @@ -9,4 +9,4 @@ git+https://github.com/inducer/codepy.git git+https://github.com/inducer/f2py # Optional, needed for using the C preprocessor on Fortran -ply>=3.6 \ No newline at end of file +ply>=3.6 diff --git a/setup.py b/setup.py index bba299869..2687d7e09 100644 --- a/setup.py +++ b/setup.py @@ -99,7 +99,7 @@ setup(name="loo.py", extras_require={ "pyopencl": [ - "pyopencl>=2015.2", + "pyopencl>=2020.2", ], "fortran": [ # Note that this is *not* regular 'f2py2e', this is -- GitLab From e85543384ed3e732117f63204f98d31b08071dce Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 18 Jun 2020 16:48:51 -0500 Subject: [PATCH 4/7] Bump data model version for new CL device identifiers for caching --- loopy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopy/version.py b/loopy/version.py index d69a3b574..4eab69c14 100644 --- a/loopy/version.py +++ b/loopy/version.py @@ -60,7 +60,7 @@ except ImportError: else: _cgen_version = cgen.version.VERSION_TEXT -DATA_MODEL_VERSION = "%s-islpy%s-cgen%s-%s-v0" % ( +DATA_MODEL_VERSION = "%s-islpy%s-cgen%s-%s-v1" % ( VERSION_TEXT, _islpy_version, _cgen_version, _git_rev) -- GitLab From d952f09a8ef0ff2a08b707bd8511d574102983f7 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 18 Jun 2020 16:50:12 -0500 Subject: [PATCH 5/7] Eliminate uses of deprecated pytools.indices_in_shape --- loopy/kernel/array.py | 3 +-- loopy/target/c/__init__.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/loopy/kernel/array.py b/loopy/kernel/array.py index 84b0a4a74..d16908ba3 100644 --- a/loopy/kernel/array.py +++ b/loopy/kernel/array.py @@ -1193,11 +1193,10 @@ class ArrayBase(ImmutableRecord): else: return idx - from pytools import indices_in_shape return [ (unwrap_1d_indices(i), self.name + "".join("_s%d" % sub_i for sub_i in i)) - for i in indices_in_shape(sep_shape)] + for i in np.ndindex(sep_shape)] # }}} diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 8869ebecf..909a8f6fb 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -251,8 +251,7 @@ def generate_linearized_array(array, value): assert array.offset == 0 - from pytools import indices_in_shape - for ituple in indices_in_shape(value.shape): + for ituple in np.ndindex(value.shape): i = sum(i_ax * strd_ax for i_ax, strd_ax in zip(ituple, strides)) data[i] = value[ituple] -- GitLab From e3fb595f40779b00ff0ac28eb4dff12639ae76c3 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 18 Jun 2020 17:13:43 -0500 Subject: [PATCH 6/7] Add tests for statically and dynamically empty domains --- test/test_loopy.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/test_loopy.py b/test/test_loopy.py index 61a3f167b..85b857a3e 100644 --- a/test/test_loopy.py +++ b/test/test_loopy.py @@ -2859,6 +2859,33 @@ def test_non_integral_array_idx_raises(): print(lp.generate_code_v2(knl).device_code()) +@pytest.mark.parametrize("tag", ["for", "l.0", "g.0", "fixed"]) +def test_empty_domain(ctx_factory, tag): + ctx = ctx_factory() + queue = cl.CommandQueue(ctx) + + prg = lp.make_kernel( + "{[i,j]: 0 <= i < n}", + """ + for i + c = 1 + end + """) + + if tag == "fixed": + prg = lp.fix_parameters(prg, n=0) + kwargs = {} + else: + prg = lp.tag_inames(prg, {"i": tag}) + kwargs = {"n": 0} + + prg = lp.set_options(prg, write_code=True) + c = cl.array.zeros(queue, (), dtype=np.int32) + prg(queue, c=c, **kwargs) + + assert (c.get() == 0).all() + + if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1]) -- GitLab From 9101f7e82167d26344fac81023fd274012fa0199 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 18 Jun 2020 17:15:26 -0500 Subject: [PATCH 7/7] Re-dangle requirements.txt to pyopencl master --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 40d351ec7..cd9b67cf4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ git+https://github.com/inducer/pytools.git git+https://github.com/inducer/islpy.git git+https://github.com/inducer/cgen.git -git+https://gitlab.tiker.net/inducer/pyopencl.git@better-empty-handling +git+https://github.com/inducer/pyopencl.git git+https://github.com/inducer/pymbolic.git git+https://github.com/inducer/genpy.git git+https://github.com/inducer/codepy.git -- GitLab