From 488245535c738247037b912962819318e0b173d2 Mon Sep 17 00:00:00 2001 From: Shane-J-Latham Date: Tue, 14 Jun 2016 08:11:55 +1000 Subject: [PATCH] Added support for cl_device_topology_amd device-info (CL_DEVICE_TOPOLOGY_AMD parameter). --- cl_types.h | 6 ++++++ pyopencl/__init__.py | 1 + pyopencl/cffi_cl.py | 46 ++++++++++++++++++++++++++++++++++++++++ src/c_wrapper/clhelper.h | 11 ++++++++++ src/c_wrapper/device.cpp | 30 +++++++++++++++++++++----- test/test_wrapper.py | 9 ++++++++ 6 files changed, 98 insertions(+), 5 deletions(-) diff --git a/cl_types.h b/cl_types.h index 2feb15c9..5df16013 100644 --- a/cl_types.h +++ b/cl_types.h @@ -105,6 +105,12 @@ typedef struct _cl_buffer_region { /* cl_ext.h */ +typedef union +{ + struct { cl_uint type; cl_uint data[5]; } raw; + struct { cl_uint type; cl_char unused[17]; cl_char bus; cl_char device; cl_char function; } pcie; +} cl_device_topology_amd; + /* typedef cl_ulong cl_device_partition_property_ext; typedef cl_uint cl_image_pitch_info_qcom; diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py index ded51a4d..2f95679b 100644 --- a/pyopencl/__init__.py +++ b/pyopencl/__init__.py @@ -165,6 +165,7 @@ from pyopencl.cffi_cl import ( # noqa Image, Sampler, GLTexture, + DeviceTopologyAmd, ) if _cl.have_gl(): diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index 5864f213..7962bf8d 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -169,6 +169,8 @@ def _generic_info_to_python(info): if type_ == 'char*': ret = _ffi_pystr(value) + elif type_ == 'cl_device_topology_amd*': + ret = DeviceTopologyAmd(value.pcie.bus, value.pcie.device, value.pcie.function) elif type_.startswith('char*['): ret = list(map(_ffi_pystr, value)) _lib.free_pointer_array(info.value, len(value)) @@ -1980,4 +1982,48 @@ class GLTexture(Image, _GLObject): # }}} +class DeviceTopologyAmd(object): + # Hack around fmt.__dict__ check in test_wrapper.py + __dict__ = {} + __slots__ = ('ptr',) + + def __init__(self, bus=0, device=0, function=0): + self.ptr = _ffi.new("cl_device_topology_amd*") + self.bus = bus + self.device = device + self.function = function + + def _check_range(self, value, prop=None): + if (value < -127) or (value > 127): + raise ValueError("Value %s not in range [-127, 127].") + + @_cffi_property('pcie') + def _pcie(self): + return self.ptr + + @property + def bus(self): + return self._pcie.bus + + @bus.setter + def bus(self, value): + self._check_range(value) + self._pcie.bus = value + + @property + def device(self): + return self._pcie.device + + @device.setter + def device(self, value): + self._pcie.device = value + + @property + def function(self): + return self._pcie.function + + @function.setter + def function(self, value): + self._pcie.function = value + # vim: foldmethod=marker diff --git a/src/c_wrapper/clhelper.h b/src/c_wrapper/clhelper.h index 2fb6cfd2..c88c0051 100644 --- a/src/c_wrapper/clhelper.h +++ b/src/c_wrapper/clhelper.h @@ -243,4 +243,15 @@ operator<<(std::ostream &stm, const cl_image_format &fmt) return stm; } +#ifdef CL_DEVICE_TOPOLOGY_AMD +static PYOPENCL_INLINE std::ostream& +operator<<(std::ostream &stm, const cl_device_topology_amd &topol) +{ + stm << "pcie.bus: " << topol.pcie.bus + << ",\npcie.device: " << topol.pcie.device + << ",\npcie.function: " << topol.pcie.function + << ",\npcie.type: " << topol.pcie.type; + return stm; +} +#endif #endif diff --git a/src/c_wrapper/device.cpp b/src/c_wrapper/device.cpp index 4bb882ca..3e0525cd 100644 --- a/src/c_wrapper/device.cpp +++ b/src/c_wrapper/device.cpp @@ -28,6 +28,27 @@ device::~device() #endif } +#ifdef CL_DEVICE_TOPOLOGY_AMD +template +PYOPENCL_USE_RESULT static PYOPENCL_INLINE generic_info +get_device_topology_amd(ArgTypes&&... args) +{ + const char * tpname = "cl_device_topology_amd*"; + cl_device_topology_amd value; + const char * fname = "clGetDeviceInfo"; + call_guarded(clGetDeviceInfo, fname, args..., size_arg(value), nullptr); + generic_info info; + info.dontfree = 0; + info.opaque_class = CLASS_NONE; + info.type = tpname; + info.value = cl_memdup(&value); + return info; +} + +#define pyopencl_get_device_topology_amd(...) get_device_topology_amd(__VA_ARGS__) + +#endif + generic_info device::get_info(cl_uint param_name) const { @@ -227,11 +248,10 @@ device::get_info(cl_uint param_name) const case CL_DEVICE_PROFILING_TIMER_OFFSET_AMD: return DEV_GET_INT_INF(cl_ulong); #endif - /* FIXME - #ifdef CL_DEVICE_TOPOLOGY_AMD - case CL_DEVICE_TOPOLOGY_AMD: - #endif - */ +#ifdef CL_DEVICE_TOPOLOGY_AMD + case CL_DEVICE_TOPOLOGY_AMD: + return pyopencl_get_device_topology_amd(PYOPENCL_CL_CASTABLE_THIS, param_name); +#endif #ifdef CL_DEVICE_THREAD_TRACE_SUPPORTED_AMD case CL_DEVICE_THREAD_TRACE_SUPPORTED_AMD: return DEV_GET_INT_INF(cl_bool); diff --git a/test/test_wrapper.py b/test/test_wrapper.py index e7f86c2e..6b25e85e 100644 --- a/test/test_wrapper.py +++ b/test/test_wrapper.py @@ -293,6 +293,15 @@ def test_image_format_constructor(): assert iform.channel_data_type == cl.channel_type.FLOAT assert not iform.__dict__ +def test_device_topology_amd_constructor(): + # doesn't need image support to succeed + topol = cl.DeviceTopologyAmd(3,4,5) + + assert topol.bus == 3 + assert topol.device == 4 + assert topol.function == 5 + + assert not topol.__dict__ def test_nonempty_supported_image_formats(ctx_factory): context = ctx_factory() -- GitLab