[Mesa-dev] [PATCH v2] clover: add GetKernelArgInfo (CL 1.2)
Vedran Miletić
vedran at miletic.net
Wed Oct 5 13:24:40 UTC 2016
On 10/01/2016 03:54 PM, Serge Martin wrote:
> ---
> src/gallium/state_trackers/clover/api/kernel.cpp | 47 ++++++++++++++++--
> src/gallium/state_trackers/clover/core/kernel.cpp | 6 +++
> src/gallium/state_trackers/clover/core/kernel.hpp | 1 +
> src/gallium/state_trackers/clover/core/module.hpp | 19 +++++--
> .../state_trackers/clover/llvm/codegen/common.cpp | 58 +++++++++++++++++++++-
> .../state_trackers/clover/llvm/metadata.hpp | 16 ++++++
> .../state_trackers/clover/tgsi/compiler.cpp | 2 +-
> 7 files changed, 141 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp
> index 73ba34a..13cfc08 100644
> --- a/src/gallium/state_trackers/clover/api/kernel.cpp
> +++ b/src/gallium/state_trackers/clover/api/kernel.cpp
> @@ -192,9 +192,50 @@ clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev,
> CLOVER_API cl_int
> clGetKernelArgInfo(cl_kernel d_kern,
> cl_uint idx, cl_kernel_arg_info param,
> - size_t size, void *r_buf, size_t *r_size) {
> - CLOVER_NOT_SUPPORTED_UNTIL("1.2");
> - return CL_KERNEL_ARG_INFO_NOT_AVAILABLE;
> + size_t size, void *r_buf, size_t *r_size) try {
> + property_buffer buf { r_buf, size, r_size };
> + const auto &kern = obj(d_kern);
> + const auto args_info = kern.args_info();
> +
> + if (args_info.size() == 0)
> + throw error(CL_KERNEL_ARG_INFO_NOT_AVAILABLE);
> +
> + if (idx >= args_info.size())
> + throw error(CL_INVALID_ARG_INDEX);
> +
> + const auto &info = args_info[idx];
> +
> + switch (param) {
> + case CL_KERNEL_ARG_ADDRESS_QUALIFIER:
> + buf.as_scalar<cl_kernel_arg_address_qualifier>() =
> + info.address_qualifier;
> + break;
> +
> + case CL_KERNEL_ARG_ACCESS_QUALIFIER:
> + buf.as_scalar<cl_kernel_arg_access_qualifier>() =
> + info.access_qualifier;
> + break;
> +
> + case CL_KERNEL_ARG_TYPE_NAME:
> + buf.as_string() = info.type_name;
> + break;
> +
> + case CL_KERNEL_ARG_TYPE_QUALIFIER:
> + buf.as_scalar<cl_kernel_arg_type_qualifier>() = info.type_qualifier;
> + break;
> +
> + case CL_KERNEL_ARG_NAME:
> + buf.as_string() = info.arg_name;
> + break;
> +
> + default:
> + throw error(CL_INVALID_VALUE);
> + }
> +
> + return CL_SUCCESS;
> +
> +} catch (error &e) {
> + return e.get();
> }
>
> namespace {
> diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
> index 962f555..18dcd5c 100644
> --- a/src/gallium/state_trackers/clover/core/kernel.cpp
> +++ b/src/gallium/state_trackers/clover/core/kernel.cpp
> @@ -140,6 +140,12 @@ kernel::args() const {
> return map(derefs(), _args);
> }
>
> +std::vector<clover::module::argument_info>
> +kernel::args_info() const {
> + const auto &syms = program().symbols();
> + return find(name_equals(_name), syms).args_info;
> +}
> +
> const module &
> kernel::module(const command_queue &q) const {
> return program().build(q.device()).binary;
> diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp
> index 4ba6ff4..aae51bc 100644
> --- a/src/gallium/state_trackers/clover/core/kernel.hpp
> +++ b/src/gallium/state_trackers/clover/core/kernel.hpp
> @@ -134,6 +134,7 @@ namespace clover {
>
> argument_range args();
> const_argument_range args() const;
> + std::vector<clover::module::argument_info> args_info() const;
>
> const intrusive_ref<clover::program> program;
>
> diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp
> index 5db0548..5ce9492 100644
> --- a/src/gallium/state_trackers/clover/core/module.hpp
> +++ b/src/gallium/state_trackers/clover/core/module.hpp
> @@ -102,16 +102,29 @@ namespace clover {
> semantic semantic;
> };
>
> + struct argument_info {
> + argument_info() { }
> +
> + uint32_t address_qualifier;
> + uint32_t access_qualifier;
> + std::string type_name;
> + uint32_t type_qualifier;
> + std::string arg_name;
> + };
> +
> struct symbol {
> symbol(const std::string &name, resource_id section,
> - size_t offset, const std::vector<argument> &args) :
> - name(name), section(section), offset(offset), args(args) { }
> - symbol() : name(), section(0), offset(0), args() { }
> + size_t offset, const std::vector<argument> &args,
> + const std::vector<argument_info> &args_info) :
> + name(name), section(section), offset(offset),
> + args(args), args_info(args_info) { }
> + symbol() : name(), section(0), offset(0), args(), args_info() { }
>
> std::string name;
> resource_id section;
> size_t offset;
> std::vector<argument> args;
> + std::vector<argument_info> args_info;
> };
>
> void serialize(std::ostream &os) const;
> diff --git a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
> index 834b06a..07f45f9 100644
> --- a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
> +++ b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp
> @@ -66,6 +66,60 @@ namespace {
> unreachable("Unknown image type");
> }
>
> + std::vector<module::argument_info>
> + make_args_infos(const Module &mod, const std::string &kernel_name,
> + const bool has_args_infos) {
> + if (!has_args_infos)
> + return {};
> +
> + const Function &f = *mod.getFunction(kernel_name);
> +
> + std::vector<module::argument_info> infos;
> + for (const auto &arg : f.args()) {
> + module::argument_info info;
> +
> + const auto addr_space = get_uint_argument_metadata(f, arg,
> + "kernel_arg_addr_space");
> + if (addr_space == 0)
> + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_PRIVATE;
> + else if (addr_space == 1)
> + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL;
> + else if (addr_space == 2)
> + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT;
> + else if (addr_space == 3)
> + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL;
> +
Is this intentionally AMDGPU-specific? NVPTX has different IDs. Refer to
tables docs/AMDGPUUsage.rst and docs/NVPTXUsage.rst in LLVM source.
> + const auto access_qual = get_argument_metadata(f, arg,
> + "kernel_arg_access_qual");
> + if (access_qual == "read_only")
> + info.access_qualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY;
> + else if (access_qual == "write_only")
> + info.access_qualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
> + else if (access_qual == "read_write")
> + info.access_qualifier = CL_KERNEL_ARG_ACCESS_READ_WRITE;
> + else if (access_qual == "none")
> + info.access_qualifier = CL_KERNEL_ARG_ACCESS_NONE;
> +
> + info.type_name = get_argument_metadata(f, arg, "kernel_arg_type");
> +
> + const auto type_qual = get_argument_metadata(f, arg,
> + "kernel_arg_type_qual");
> + info.type_qualifier = CL_KERNEL_ARG_TYPE_NONE;
> + if (type_qual.find("const") != std::string::npos)
> + info.type_qualifier |= CL_KERNEL_ARG_TYPE_CONST;
> + if (type_qual.find("restrict") != std::string::npos)
> + info.type_qualifier |= CL_KERNEL_ARG_TYPE_RESTRICT;
> + if (type_qual.find("volatile") != std::string::npos)
> + info.type_qualifier |= CL_KERNEL_ARG_TYPE_VOLATILE;
> +
> + info.arg_name = get_argument_metadata(f, arg, "kernel_arg_name");
> +
> + infos.emplace_back(info);
> + }
> +
> + return infos;
> + }
> +
> std::vector<module::argument>
> make_kernel_args(const Module &mod, const std::string &kernel_name,
> const clang::CompilerInstance &c) {
> @@ -196,12 +250,14 @@ clover::llvm::build_module_common(const Module &mod,
> unsigned> &offsets,
> const clang::CompilerInstance &c) {
> module m;
> + const bool has_args_infos = c.getCodeGenOpts().EmitOpenCLArgMetadata;
>
> for (const auto &name : map(std::mem_fn(&Function::getName),
> get_kernels(mod))) {
> if (offsets.count(name))
> m.syms.emplace_back(name, 0, offsets.at(name),
> - make_kernel_args(mod, name, c));
> + make_kernel_args(mod, name, c),
> + make_args_infos(mod, name, has_args_infos));
> }
>
> m.secs.push_back(make_text_section(code));
> diff --git a/src/gallium/state_trackers/clover/llvm/metadata.hpp b/src/gallium/state_trackers/clover/llvm/metadata.hpp
> index 814c830..ddc5259 100644
> --- a/src/gallium/state_trackers/clover/llvm/metadata.hpp
> +++ b/src/gallium/state_trackers/clover/llvm/metadata.hpp
> @@ -32,6 +32,7 @@
> #include "util/algorithm.hpp"
>
> #include <vector>
> +#include <llvm/IR/Constants.h>
> #include <llvm/IR/Module.h>
> #include <llvm/IR/Metadata.h>
>
> @@ -112,6 +113,21 @@ namespace clover {
> }
>
> ///
> + /// Extract the uint metadata node \p name corresponding to the kernel
> + /// argument given by \p arg.
> + ///
> + inline uint64_t
> + get_uint_argument_metadata(const ::llvm::Function &f,
> + const ::llvm::Argument &arg,
> + const std::string &name) {
> + return ::llvm::cast<::llvm::ConstantInt>(
> + ::llvm::dyn_cast<::llvm::ConstantAsMetadata>(
> + detail::get_kernel_metadata_operands(f, name)[arg.getArgNo()])
> + ->getValue())
> + ->getLimitedValue(UINT_MAX);
> + }
> +
> + ///
> /// Return a vector with all CL kernel functions found in the LLVM
> /// module \p mod.
> ///
> diff --git a/src/gallium/state_trackers/clover/tgsi/compiler.cpp b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
> index 9bbd454..f94d19f 100644
> --- a/src/gallium/state_trackers/clover/tgsi/compiler.cpp
> +++ b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
> @@ -76,7 +76,7 @@ namespace {
> }
> }
>
> - m.syms.push_back({ name, 0, offset, args });
> + m.syms.push_back({ name, 0, offset, args, {} });
> }
> }
>
>
--
Vedran Miletić
vedran.miletic.net
More information about the mesa-dev
mailing list