def _add_functionality(): cls_to_info_cls = { _cl.Platform: (_cl.Platform.get_info, _cl.platform_info), _cl.Device: (_cl.Device.get_info, _cl.device_info), _cl.Context: (_cl.Context.get_info, _cl.context_info), _cl.CommandQueue: (_cl.CommandQueue.get_info, _cl.command_queue_info), _cl.Event: (_cl.Event.get_info, _cl.event_info), _cl.MemoryObjectHolder: (MemoryObjectHolder.get_info, _cl.mem_info), Image: (_cl.Image.get_image_info, _cl.image_info), Program: (Program.get_info, _cl.program_info), Kernel: (Kernel.get_info, _cl.kernel_info), _cl.Sampler: (Sampler.get_info, _cl.sampler_info), } def to_string(cls, value, default_format=None): for name in dir(cls): if (not name.startswith("_") and getattr(cls, name) == value): return name if default_format is None: raise ValueError("a name for value %d was not found in %s" % (value, cls.__name__)) else: return default_format % value for cls in CONSTANT_CLASSES: cls.to_string = classmethod(to_string) # {{{ get_info attributes ------------------------------------------------- def make_getinfo(info_method, info_attr): def result(self): return info_method(self, info_attr) return property(result) for cls, (info_method, info_class) in cls_to_info_cls.iteritems(): for info_name, info_value in info_class.__dict__.iteritems(): if info_name == "to_string" or info_name.startswith("_"): continue setattr(cls, info_name.lower(), make_getinfo( info_method, getattr(info_class, info_name))) # }}} # {{{ Platform def platform_repr(self): return "<pyopencl.Platform '%s' at 0x%x>" % (self.name, self.int_ptr) Platform.__repr__ = platform_repr # }}} # {{{ Device def device_repr(self): return "<pyopencl.Device '%s' on '%s' at 0x%x>" % ( self.name.strip(), self.platform.name.strip(), self.int_ptr) def device_persistent_unique_id(self): return (self.vendor, self.vendor_id, self.name, self.version) Device.__repr__ = device_repr # undocumented for now: Device.persistent_unique_id = property(device_persistent_unique_id) # }}} # {{{ Context def context_repr(self): return "<pyopencl.Context at 0x%x on %s>" % (self.int_ptr, ", ".join(repr(dev) for dev in self.devices)) def context_get_cl_version(self): import re platform = self.devices[0].platform plat_version_string = platform.version match = re.match(r"^OpenCL ([0-9]+)\.([0-9]+) .*$", plat_version_string) if match is None: raise RuntimeError("platform %s returned non-conformant " "platform version string '%s'" % (platform, plat_version_string)) return int(match.group(1)), int(match.group(2)) Context.__repr__ = context_repr from pytools import memoize_method Context._get_cl_version = memoize_method(context_get_cl_version) # }}} # {{{ CommandQueue def command_queue_enter(self): return self def command_queue_exit(self, exc_type, exc_val, exc_tb): self.finish() def command_queue_get_cl_version(self): return self.context._get_cl_version() CommandQueue.__enter__ = command_queue_enter CommandQueue.__exit__ = command_queue_exit CommandQueue._get_cl_version = memoize_method(command_queue_get_cl_version) # }}} # {{{ _Program (the internal, non-caching version) def program_get_build_logs(self): build_logs = [] for dev in self.get_info(_cl.program_info.DEVICES): try: log = self.get_build_info(dev, program_build_info.LOG) except: log = "<error retrieving log>" build_logs.append((dev, log)) return build_logs def program_build(self, options=[], devices=None): if isinstance(options, list): options = " ".join(options) err = None try: self._build(options=options, devices=devices) except Exception, e: from pytools import Record class ErrorRecord(Record): pass what = e.what + "\n\n" + (75*"="+"\n").join( "Build on %s:\n\n%s" % (dev, log) for dev, log in self._get_build_logs()) code = e.code routine = e.routine err = _cl.RuntimeError( ErrorRecord( what=lambda: what, code=lambda: code, routine=lambda: routine)) if err is not None: # Python 3.2 outputs the whole list of currently active exceptions # This serves to remove one (redundant) level from that nesting. raise err message = (75*"="+"\n").join( "Build on %s succeeded, but said:\n\n%s" % (dev, log) for dev, log in self._get_build_logs() if log is not None and log.strip()) if message: if self.kind() == program_kind.SOURCE: build_type = "From-source build" elif self.kind() == program_kind.BINARY: build_type = "From-binary build" else: build_type = "Build" compiler_output("%s succeeded, but resulted in non-empty logs:\n%s" % (build_type, message)) return self
def _add_functionality(): cls_to_info_cls = { _cl.Platform: (_cl.Platform.get_info, _cl.platform_info), _cl.Device: (_cl.Device.get_info, _cl.device_info), _cl.Context: (_cl.Context.get_info, _cl.context_info), _cl.CommandQueue: (_cl.CommandQueue.get_info, _cl.command_queue_info), _cl.Event: (_cl.Event.get_info, _cl.event_info), _cl.MemoryObjectHolder: (MemoryObjectHolder.get_info, _cl.mem_info), Image: (_cl.Image.get_image_info, _cl.image_info), Program: (Program.get_info, _cl.program_info), Kernel: (Kernel.get_info, _cl.kernel_info), _cl.Sampler: (Sampler.get_info, _cl.sampler_info), } def to_string(cls, value, default_format=None): for name in dir(cls): if (not name.startswith("_") and getattr(cls, name) == value): return name if default_format is None: raise ValueError("a name for value %d was not found in %s" % (value, cls.__name__)) else: return default_format % value for cls in CONSTANT_CLASSES: cls.to_string = classmethod(to_string) # {{{ get_info attributes ------------------------------------------------- def make_getinfo(info_method, info_attr): def result(self): return info_method(self, info_attr) return property(result) for cls, (info_method, info_class) in cls_to_info_cls.iteritems(): for info_name, info_value in info_class.__dict__.iteritems(): if info_name == "to_string" or info_name.startswith("_"): continue setattr(cls, info_name.lower(), make_getinfo(info_method, getattr(info_class, info_name))) # }}} # {{{ Platform def platform_repr(self): return "<pyopencl.Platform '%s' at 0x%x>" % (self.name, self.int_ptr) Platform.__repr__ = platform_repr # }}} # {{{ Device def device_repr(self): return "<pyopencl.Device '%s' on '%s' at 0x%x>" % ( self.name.strip(), self.platform.name.strip(), self.int_ptr) def device_persistent_unique_id(self): return (self.vendor, self.vendor_id, self.name, self.version) Device.__repr__ = device_repr # undocumented for now: Device.persistent_unique_id = property(device_persistent_unique_id) # }}} # {{{ Context def context_repr(self): return "<pyopencl.Context at 0x%x on %s>" % (self.int_ptr, ", ".join( repr(dev) for dev in self.devices)) def context_get_cl_version(self): import re platform = self.devices[0].platform plat_version_string = platform.version match = re.match(r"^OpenCL ([0-9]+)\.([0-9]+) .*$", plat_version_string) if match is None: raise RuntimeError("platform %s returned non-conformant " "platform version string '%s'" % (platform, plat_version_string)) return int(match.group(1)), int(match.group(2)) Context.__repr__ = context_repr from pytools import memoize_method Context._get_cl_version = memoize_method(context_get_cl_version) # }}} # {{{ CommandQueue def command_queue_enter(self): return self def command_queue_exit(self, exc_type, exc_val, exc_tb): self.finish() def command_queue_get_cl_version(self): return self.context._get_cl_version() CommandQueue.__enter__ = command_queue_enter CommandQueue.__exit__ = command_queue_exit CommandQueue._get_cl_version = memoize_method(command_queue_get_cl_version) # }}} # {{{ _Program (the internal, non-caching version) def program_get_build_logs(self): build_logs = [] for dev in self.get_info(_cl.program_info.DEVICES): try: log = self.get_build_info(dev, program_build_info.LOG) except: log = "<error retrieving log>" build_logs.append((dev, log)) return build_logs def program_build(self, options=[], devices=None): if isinstance(options, list): options = " ".join(options) err = None try: self._build(options=options, devices=devices) except Exception, e: from pytools import Record class ErrorRecord(Record): pass what = e.what + "\n\n" + (75 * "=" + "\n").join( "Build on %s:\n\n%s" % (dev, log) for dev, log in self._get_build_logs()) code = e.code routine = e.routine err = _cl.RuntimeError( ErrorRecord(what=lambda: what, code=lambda: code, routine=lambda: routine)) if err is not None: # Python 3.2 outputs the whole list of currently active exceptions # This serves to remove one (redundant) level from that nesting. raise err message = (75 * "=" + "\n").join( "Build on %s succeeded, but said:\n\n%s" % (dev, log) for dev, log in self._get_build_logs() if log is not None and log.strip()) if message: if self.kind() == program_kind.SOURCE: build_type = "From-source build" elif self.kind() == program_kind.BINARY: build_type = "From-binary build" else: build_type = "Build" compiler_output( "%s succeeded, but resulted in non-empty logs:\n%s" % (build_type, message)) return self