Пример #1
0
    def __call__(self, kernel, codegen_result):
        """
        Generates the wrapping python invoker for this execution target

        :arg kernel: the loopy :class:`LoopKernel`(s) to be executued
        :codegen_result: the loopy :class:`CodeGenerationResult` created
        by code generation

        :returns: A python callable that handles execution of this
            kernel
        """

        options = kernel.options
        implemented_data_info = codegen_result.implemented_data_info

        from loopy.kernel.data import KernelArgument
        gen = PythonFunctionGenerator(
            "invoke_%s_loopy_kernel" % kernel.name, self.system_args + [
                "%s=None" % idi.name for idi in implemented_data_info
                if issubclass(idi.arg_class, KernelArgument)
            ])

        gen.add_to_preamble("from __future__ import division")
        gen.add_to_preamble("")
        self.target_specific_preamble(gen)
        gen.add_to_preamble("")
        self.generate_host_code(gen, codegen_result)
        gen.add_to_preamble("")

        self.initialize_system_args(gen)

        self.generate_integer_arg_finding_from_shapes(gen, kernel,
                                                      implemented_data_info)
        self.generate_integer_arg_finding_from_offsets(gen, kernel,
                                                       implemented_data_info)
        self.generate_integer_arg_finding_from_strides(gen, kernel,
                                                       implemented_data_info)
        self.generate_value_arg_check(gen, kernel, implemented_data_info)

        args = self.generate_arg_setup(gen, kernel, implemented_data_info,
                                       options)

        self.generate_invocation(gen, codegen_result.host_program.name, args,
                                 kernel, implemented_data_info)

        self.generate_output_handler(gen, options, kernel,
                                     implemented_data_info)

        if options.write_wrapper:
            output = gen.get()
            if options.highlight_wrapper:
                output = get_highlighted_python_code(output)

            if options.write_wrapper is True:
                print(output)
            else:
                with open(options.write_wrapper, "w") as outf:
                    outf.write(output)

        return gen.get_picklable_function()
Пример #2
0
def generate_invoker(kernel, cl_kernel, impl_arg_info, options):
    system_args = [
            "cl_kernel", "queue", "allocator=None", "wait_for=None",
            # ignored if options.no_numpy
            "out_host=None"
            ]

    gen = PythonFunctionGenerator(
            "invoke_%s_loopy_kernel" % kernel.name,
            system_args + ["%s=None" % iai.name for iai in impl_arg_info])

    gen.add_to_preamble("from __future__ import division")
    gen.add_to_preamble("")
    gen.add_to_preamble("import pyopencl as _lpy_cl")
    gen.add_to_preamble("import pyopencl.array as _lpy_cl_array")
    gen.add_to_preamble("import pyopencl.tools as _lpy_cl_tools")
    gen.add_to_preamble("import numpy as _lpy_np")
    gen.add_to_preamble("from struct import pack as _lpy_pack")
    gen.add_to_preamble("")

    gen("if allocator is None:")
    with Indentation(gen):
        gen("allocator = _lpy_cl_tools.DeferredAllocator(queue.context)")
    gen("")

    generate_integer_arg_finding_from_shapes(gen, kernel, impl_arg_info, options)
    generate_integer_arg_finding_from_offsets(gen, kernel, impl_arg_info, options)
    generate_integer_arg_finding_from_strides(gen, kernel, impl_arg_info, options)

    arg_idx_to_cl_arg_idx = \
            generate_value_arg_setup(gen, kernel, cl_kernel, impl_arg_info, options)
    generate_array_arg_setup(gen, kernel, impl_arg_info, options,
            arg_idx_to_cl_arg_idx)

    # {{{ generate invocation

    from loopy.symbolic import StringifyMapper

    strify = StringifyMapper()
    gsize_expr, lsize_expr = kernel.get_grid_sizes_as_exprs()

    if not gsize_expr:
        gsize_expr = (1,)
    if not lsize_expr:
        lsize_expr = (1,)

    def strify_tuple(t):
        return "(%s,)" % (
                ", ".join("int(%s)" % strify(t_i) for t_i in t))

    gen("_lpy_evt = _lpy_cl.enqueue_nd_range_kernel(queue, cl_kernel, "
            "%(gsize)s, %(lsize)s,  wait_for=wait_for, g_times_l=True)"
            % dict(
                gsize=strify_tuple(gsize_expr),
                lsize=strify_tuple(lsize_expr)))
    gen("")

    # }}}

    # {{{ output

    if not options.no_numpy:
        gen("if out_host is None and (_lpy_encountered_numpy "
                "and not _lpy_encountered_dev):")
        with Indentation(gen):
            gen("out_host = True")

        gen("if out_host:")
        with Indentation(gen):
            gen("pass")  # if no outputs (?!)
            for arg_idx, arg in enumerate(impl_arg_info):
                is_written = arg.base_name in kernel.get_written_variables()
                if is_written:
                    gen("%s = %s.get(queue=queue)" % (arg.name, arg.name))

        gen("")

    if options.return_dict:
        gen("return _lpy_evt, {%s}"
                % ", ".join("\"%s\": %s" % (arg.name, arg.name)
                    for arg in impl_arg_info
                    if arg.base_name in kernel.get_written_variables()))
    else:
        out_args = [arg
                for arg in impl_arg_info
                if arg.base_name in kernel.get_written_variables()]
        if out_args:
            gen("return _lpy_evt, (%s,)"
                    % ", ".join(arg.name for arg in out_args))
        else:
            gen("return _lpy_evt, ()")

    # }}}

    if options.write_wrapper:
        output = gen.get()
        if options.highlight_wrapper:
            output = get_highlighted_python_code(output)

        if options.write_wrapper is True:
            print(output)
        else:
            with open(options.write_wrapper, "w") as outf:
                outf.write(output)

    return gen.get_function()
Пример #3
0
def generate_invoker(kernel, codegen_result):
    options = kernel.options
    implemented_data_info = codegen_result.implemented_data_info
    host_code = codegen_result.host_code()

    system_args = [
        "_lpy_cl_kernels",
        "queue",
        "allocator=None",
        "wait_for=None",
        # ignored if options.no_numpy
        "out_host=None"
    ]

    from loopy.kernel.data import KernelArgument
    gen = PythonFunctionGenerator(
        "invoke_%s_loopy_kernel" % kernel.name, system_args + [
            "%s=None" % idi.name for idi in implemented_data_info
            if issubclass(idi.arg_class, KernelArgument)
        ])

    gen.add_to_preamble("from __future__ import division")
    gen.add_to_preamble("")
    gen.add_to_preamble("import pyopencl as _lpy_cl")
    gen.add_to_preamble("import pyopencl.array as _lpy_cl_array")
    gen.add_to_preamble("import pyopencl.tools as _lpy_cl_tools")
    gen.add_to_preamble("import numpy as _lpy_np")
    gen.add_to_preamble("")
    gen.add_to_preamble(host_code)
    gen.add_to_preamble("")

    gen("if allocator is None:")
    with Indentation(gen):
        gen("allocator = _lpy_cl_tools.DeferredAllocator(queue.context)")
    gen("")

    generate_integer_arg_finding_from_shapes(gen, kernel,
                                             implemented_data_info)
    generate_integer_arg_finding_from_offsets(gen, kernel,
                                              implemented_data_info)
    generate_integer_arg_finding_from_strides(gen, kernel,
                                              implemented_data_info)
    generate_value_arg_check(gen, kernel, implemented_data_info)

    args = generate_arg_setup(gen, kernel, implemented_data_info, options)

    # {{{ generate invocation

    gen("_lpy_evt = {kernel_name}({args})".format(
        kernel_name=codegen_result.host_program.name,
        args=", ".join(["_lpy_cl_kernels", "queue"] + args +
                       ["wait_for=wait_for"])))

    # }}}

    # {{{ output

    if not options.no_numpy:
        gen("if out_host is None and (_lpy_encountered_numpy "
            "and not _lpy_encountered_dev):")
        with Indentation(gen):
            gen("out_host = True")

        gen("if out_host:")
        with Indentation(gen):
            gen("pass")  # if no outputs (?!)
            for arg in implemented_data_info:
                if not issubclass(arg.arg_class, KernelArgument):
                    continue

                is_written = arg.base_name in kernel.get_written_variables()
                if is_written:
                    gen("%s = %s.get(queue=queue)" % (arg.name, arg.name))

        gen("")

    if options.return_dict:
        gen("return _lpy_evt, {%s}" %
            ", ".join("\"%s\": %s" % (arg.name, arg.name)
                      for arg in implemented_data_info
                      if issubclass(arg.arg_class, KernelArgument)
                      if arg.base_name in kernel.get_written_variables()))
    else:
        out_args = [
            arg for arg in implemented_data_info
            if issubclass(arg.arg_class, KernelArgument)
            if arg.base_name in kernel.get_written_variables()
        ]
        if out_args:
            gen("return _lpy_evt, (%s,)" % ", ".join(arg.name
                                                     for arg in out_args))
        else:
            gen("return _lpy_evt, ()")

    # }}}

    if options.write_wrapper:
        output = gen.get()
        if options.highlight_wrapper:
            output = get_highlighted_python_code(output)

        if options.write_wrapper is True:
            print(output)
        else:
            with open(options.write_wrapper, "w") as outf:
                outf.write(output)

    return gen.get_function()
Пример #4
0
def generate_invoker(kernel, codegen_result):
    options = kernel.options
    implemented_data_info = codegen_result.implemented_data_info
    host_code = codegen_result.host_code()

    system_args = [
            "_lpy_cl_kernels", "queue", "allocator=None", "wait_for=None",
            # ignored if options.no_numpy
            "out_host=None"
            ]

    from loopy.kernel.data import KernelArgument
    gen = PythonFunctionGenerator(
            "invoke_%s_loopy_kernel" % kernel.name,
            system_args + [
                "%s=None" % idi.name
                for idi in implemented_data_info
                if issubclass(idi.arg_class, KernelArgument)
                ])

    gen.add_to_preamble("from __future__ import division")
    gen.add_to_preamble("")
    gen.add_to_preamble("import pyopencl as _lpy_cl")
    gen.add_to_preamble("import pyopencl.array as _lpy_cl_array")
    gen.add_to_preamble("import pyopencl.tools as _lpy_cl_tools")
    gen.add_to_preamble("import numpy as _lpy_np")
    gen.add_to_preamble("")
    gen.add_to_preamble(host_code)
    gen.add_to_preamble("")

    gen("if allocator is None:")
    with Indentation(gen):
        gen("allocator = _lpy_cl_tools.DeferredAllocator(queue.context)")
    gen("")

    generate_integer_arg_finding_from_shapes(gen, kernel, implemented_data_info)
    generate_integer_arg_finding_from_offsets(gen, kernel, implemented_data_info)
    generate_integer_arg_finding_from_strides(gen, kernel, implemented_data_info)
    generate_value_arg_check(gen, kernel, implemented_data_info)

    args = generate_arg_setup(gen, kernel, implemented_data_info, options)

    # {{{ generate invocation

    gen("_lpy_evt = {kernel_name}({args})"
            .format(
                kernel_name=codegen_result.host_program.name,
                args=", ".join(
                    ["_lpy_cl_kernels", "queue"]
                    + args
                    + ["wait_for=wait_for"])))

    # }}}

    # {{{ output

    if not options.no_numpy:
        gen("if out_host is None and (_lpy_encountered_numpy "
                "and not _lpy_encountered_dev):")
        with Indentation(gen):
            gen("out_host = True")

        gen("if out_host:")
        with Indentation(gen):
            gen("pass")  # if no outputs (?!)
            for arg in implemented_data_info:
                if not issubclass(arg.arg_class, KernelArgument):
                    continue

                is_written = arg.base_name in kernel.get_written_variables()
                if is_written:
                    gen("%s = %s.get(queue=queue)" % (arg.name, arg.name))

        gen("")

    if options.return_dict:
        gen("return _lpy_evt, {%s}"
                % ", ".join("\"%s\": %s" % (arg.name, arg.name)
                    for arg in implemented_data_info
                    if issubclass(arg.arg_class, KernelArgument)
                    if arg.base_name in kernel.get_written_variables()))
    else:
        out_args = [arg
                for arg in implemented_data_info
                    if issubclass(arg.arg_class, KernelArgument)
                if arg.base_name in kernel.get_written_variables()]
        if out_args:
            gen("return _lpy_evt, (%s,)"
                    % ", ".join(arg.name for arg in out_args))
        else:
            gen("return _lpy_evt, ()")

    # }}}

    if options.write_wrapper:
        output = gen.get()
        if options.highlight_wrapper:
            output = get_highlighted_python_code(output)

        if options.write_wrapper is True:
            print(output)
        else:
            with open(options.write_wrapper, "w") as outf:
                outf.write(output)

    return gen.get_function()
Пример #5
0
    def __call__(self, kernel, codegen_result):
        """
        Generates the wrapping python invoker for this execution target

        :arg kernel: the loopy :class:`LoopKernel`(s) to be executued
        :codegen_result: the loopy :class:`CodeGenerationResult` created
        by code generation

        :returns: A python callable that handles execution of this
            kernel
        """

        options = kernel.options
        implemented_data_info = codegen_result.implemented_data_info

        from loopy.kernel.data import KernelArgument
        gen = PythonFunctionGenerator(
                "invoke_%s_loopy_kernel" % kernel.name,
                self.system_args + [
                    "%s=None" % idi.name
                    for idi in implemented_data_info
                    if issubclass(idi.arg_class, KernelArgument)
                    ])

        gen.add_to_preamble("from __future__ import division")
        gen.add_to_preamble("")
        self.target_specific_preamble(gen)
        gen.add_to_preamble("")
        self.generate_host_code(gen, codegen_result)
        gen.add_to_preamble("")

        self.initialize_system_args(gen)

        self.generate_integer_arg_finding_from_shapes(
            gen, kernel, implemented_data_info)
        self.generate_integer_arg_finding_from_offsets(
            gen, kernel, implemented_data_info)
        self.generate_integer_arg_finding_from_strides(
            gen, kernel, implemented_data_info)
        self.generate_value_arg_check(
            gen, kernel, implemented_data_info)

        args = self.generate_arg_setup(
            gen, kernel, implemented_data_info, options)

        self.generate_invocation(gen, codegen_result.host_program.name, args,
                kernel, implemented_data_info)

        self.generate_output_handler(gen, options, kernel, implemented_data_info)

        if options.write_wrapper:
            output = gen.get()
            if options.highlight_wrapper:
                output = get_highlighted_python_code(output)

            if options.write_wrapper is True:
                print(output)
            else:
                with open(options.write_wrapper, "w") as outf:
                    outf.write(output)

        return gen.get_picklable_function()