diff --git a/doc/source/tools.rst b/doc/source/tools.rst index 0af6ea8e53eeab6c97239792967fe5885faf7e30..b63856a7bdcc8279298f64b6784d0ff1729de71d 100644 --- a/doc/source/tools.rst +++ b/doc/source/tools.rst @@ -90,3 +90,24 @@ Kernel Caching all held reference contexts. If it is important to you that the program detaches from its context, you might need to call this function to free all remaining references to your context. + +Testing +------- + +.. function:: pytest_generate_tests_for_pyopencl(metafunc) + + Using the line:: + + from pyopencl.tools import pytest_generate_tests_for_pyopencl \ + as pytest_generate_tests + + in your `py.test <http://pytest.org>`_ test scripts allows you to use the + arguments *ctx_factory*, *device*, or *platform* in your test functions, + and they will automatically be run for each OpenCL device/platform in the + system, as appropriate. + + The following two environment variables are also supported to control + device/platform choice:: + + PYOPENCL_TEST_PLATFORM_BLACKLIST=nvidia,intel + PYOPENCL_TEST_DEVICE_BLACKLIST=nvidia:260,intel:i5 diff --git a/pyopencl/tools.py b/pyopencl/tools.py index 986eb885d23d50dd436c7bd45623693698c77208..bce2111f1164551832743c16d8357997c464ad63 100644 --- a/pyopencl/tools.py +++ b/pyopencl/tools.py @@ -110,6 +110,21 @@ def pytest_generate_tests_for_pyopencl(metafunc): def __str__(self): return "<context factory for %s>" % self.device + platform_blacklist = [] + device_blacklist = [] + + import os + bl_string = os.environ.get("PYOPENCL_TEST_PLATFORM_BLACKLIST", "") + if bl_string: + platform_blacklist = [s.lower() for s in bl_string.split(",")] + bl_string = os.environ.get("PYOPENCL_TEST_DEVICE_BLACKLIST", "") + if bl_string: + for s in bl_string.split(","): + vendor_name, device_name = s.split(":") + device_blacklist.append((vendor_name.lower(), device_name.lower())) + + from pytools import any + if ("device" in metafunc.funcargnames or "ctx_factory" in metafunc.funcargnames or "ctx_getter" in metafunc.funcargnames): @@ -119,7 +134,17 @@ def pytest_generate_tests_for_pyopencl(metafunc): if "platform" in metafunc.funcargnames: arg_dict["platform"] = platform + platform_ish = (platform.name + ' ' + platform.vendor).lower() + if any(bl_plat in platform_ish for bl_plat in platform_blacklist): + continue + for device in platform.get_devices(): + + device_ish = (device.name + ' ' + platform.vendor).lower() + if any(bl_plat in platform_ish and bl_dev in device_ish + for bl_plat, bl_dev in device_blacklist): + continue + if "device" in metafunc.funcargnames: arg_dict["device"] = device @@ -138,6 +163,11 @@ def pytest_generate_tests_for_pyopencl(metafunc): elif "platform" in metafunc.funcargnames: for platform in cl.get_platforms(): + + platform_ish = (platform.name + ' ' + platform.vendor).lower() + if any(bl_plat in platform_ish for bl_plat in platform_blacklist): + continue + metafunc.addcall( funcargs=dict(platform=platform), id=str(platform))