[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