inducer / pyopencl

OpenCL integration for Python, plus shiny features
http://mathema.tician.de/software/pyopencl
Other
1.04k stars 238 forks source link

TypeError: __class__ assignment: 'KernelWithCustomEnqueue' object layout differs from 'pyopencl._cl.Kernel' #661

Closed anbe42 closed 1 year ago

anbe42 commented 1 year ago

While building pyopencl on Debian with python 3.11 as supported version we got this error:

https://bugs.debian.org/1024046

self = <pyopencl._cl.Kernel object at 0x7ff216810ef0>
arg_types = (<class 'numpy.int32'>, <class 'numpy.int32'>, <class 'numpy.int32'>, <class 'numpy.int32'>, <class 'numpy.int32'>, None, ...)

    def kernel_set_arg_types(self, arg_types):
        arg_types = tuple(arg_types)

        # {{{ arg counting bug handling

        # For example:
        # https://github.com/pocl/pocl/issues/197
        # (but Apple CPU has a similar bug)

        work_around_arg_count_bug = False
        warn_about_arg_count_bug = False

        from pyopencl.characterize import has_struct_arg_count_bug

        count_bug_per_dev = [
                has_struct_arg_count_bug(dev, self.context)
                for dev in self.context.devices]

        from pytools import single_valued
        if any(count_bug_per_dev):
            if all(count_bug_per_dev):
                work_around_arg_count_bug = single_valued(count_bug_per_dev)
            else:
                warn_about_arg_count_bug = True

        # }}}

        from pyopencl.invoker import generate_enqueue_and_set_args
        enqueue, my_set_args = \
                generate_enqueue_and_set_args(
                        self.function_name,
                        len(arg_types), self.num_args,
                        arg_types,
                        warn_about_arg_count_bug=warn_about_arg_count_bug,
                        work_around_arg_count_bug=work_around_arg_count_bug,
                        devs=self.context.devices)

        # Make ourselves a kernel-specific class, so that we're able to override
        # __call__. Inspired by https://stackoverflow.com/a/38541437
        class KernelWithCustomEnqueue(type(self)):
            __call__ = enqueue
            set_args = my_set_args

>       self.__class__ = KernelWithCustomEnqueue
E       TypeError: __class__ assignment: 'KernelWithCustomEnqueue' object layout differs from 'pyopencl._cl.Kernel'

I can reproduce this locally with 2022.2.4, too, but haven't tried git HEAD, yet.

(I updated pocl in Debian a few days ago to cherry-pick some svm fixes that otherwise made pyopencl 2022.2.* fail even with python 3.10)

matthiasdiener commented 1 year ago

I think this was fixed as part of #636, but there hasn't been a new release yet.

anbe42 commented 1 year ago

Thanks, that worked. It wasn't obvious from title and description that this MR contained the solution. (I had looked for something mentioning python 3.11 or 'object layout differs'.)