Exemplo n.º 1
0
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
Exemplo n.º 2
0
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