[Mesa-dev] [PATCH] clover: CL 1.2 add GetKernelArgInfo

EdB edb+mesa at sigluy.net
Fri Jan 23 10:32:25 PST 2015


---
 depends on clLinkProgram serie

 src/gallium/state_trackers/clover/api/dispatch.cpp |  2 +-
 src/gallium/state_trackers/clover/api/dispatch.hpp |  8 +-
 src/gallium/state_trackers/clover/api/kernel.cpp   | 51 ++++++++++++
 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  | 17 +++-
 .../state_trackers/clover/llvm/invocation.cpp      | 95 +++++++++++++++++++++-
 7 files changed, 175 insertions(+), 5 deletions(-)

diff --git a/src/gallium/state_trackers/clover/api/dispatch.cpp b/src/gallium/state_trackers/clover/api/dispatch.cpp
index 44bff4f..c0388ec 100644
--- a/src/gallium/state_trackers/clover/api/dispatch.cpp
+++ b/src/gallium/state_trackers/clover/api/dispatch.cpp
@@ -125,7 +125,7 @@ namespace clover {
       clCompileProgram,
       clLinkProgram,
       clUnloadPlatformCompiler,
-      NULL, // clGetKernelArgInfo
+      clGetKernelArgInfo,
       NULL, // clEnqueueFillBuffer
       NULL, // clEnqueueFillImage
       NULL, // clEnqueueMigrateMemObjects
diff --git a/src/gallium/state_trackers/clover/api/dispatch.hpp b/src/gallium/state_trackers/clover/api/dispatch.hpp
index ffae1ae..ffe8556 100644
--- a/src/gallium/state_trackers/clover/api/dispatch.hpp
+++ b/src/gallium/state_trackers/clover/api/dispatch.hpp
@@ -693,7 +693,13 @@ struct _cl_icd_dispatch {
    CL_API_ENTRY cl_int (CL_API_CALL *clUnloadPlatformCompiler)(
       cl_platform_id platform);
 
-   void *clGetKernelArgInfo;
+   CL_API_ENTRY cl_int (CL_API_CALL *clGetKernelArgInfo)(
+      cl_kernel kernel,
+      cl_uint arg_indx,
+      cl_kernel_arg_info  param_name,
+      size_t param_value_size,
+      void * param_value,
+      size_t * param_value_size_ret);
 
    CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueFillBuffer)(
       cl_command_queue command_queue,
diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp
index 4fe1756..7f4ae9d 100644
--- a/src/gallium/state_trackers/clover/api/kernel.cpp
+++ b/src/gallium/state_trackers/clover/api/kernel.cpp
@@ -148,6 +148,57 @@ clGetKernelInfo(cl_kernel d_kern, cl_kernel_info param,
 }
 
 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) 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() =
+                  std::string(info.type_name.begin(), info.type_name.size());
+      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() =
+                  std::string(info.arg_name.begin(), info.arg_name.size());
+      break;
+
+   default:
+      throw error(CL_INVALID_VALUE);
+   }
+
+   return CL_SUCCESS;
+
+} catch (error &e) {
+   return e.get();
+}
+
+CLOVER_API cl_int
 clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev,
                          cl_kernel_work_group_info param,
                          size_t size, void *r_buf, size_t *r_size) try {
diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index ed4b9b0..a212cc1 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -134,6 +134,12 @@ kernel::args() const {
    return map(derefs(), _args);
 }
 
+compat::vector<clover::module::argument_info>
+kernel::args_info() const {
+   auto &syms = program().symbols();
+   return find(name_equals(_name), syms).args_info;
+}
+
 const module &
 kernel::module(const command_queue &q) const {
    return program().binary(q.device());
diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp
index bf5998d..5ae4690 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;
+      compat::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 200b9de..4a747d5 100644
--- a/src/gallium/state_trackers/clover/core/module.hpp
+++ b/src/gallium/state_trackers/clover/core/module.hpp
@@ -23,6 +23,8 @@
 #ifndef CLOVER_CORE_MODULE_HPP
 #define CLOVER_CORE_MODULE_HPP
 
+#include "CL/cl.h"
+
 #include "util/compat.hpp"
 
 namespace clover {
@@ -101,16 +103,29 @@ namespace clover {
          semantic semantic;
       };
 
+      struct argument_info {
+         argument_info() : address_qualifier(CL_KERNEL_ARG_ADDRESS_PRIVATE),
+            access_qualifier(CL_KERNEL_ARG_ACCESS_NONE), type_name(),
+            type_qualifier(CL_KERNEL_ARG_TYPE_NONE), arg_name() { }
+
+         cl_kernel_arg_address_qualifier address_qualifier;
+         cl_kernel_arg_access_qualifier access_qualifier;
+         compat::vector<char> type_name;
+         cl_kernel_arg_type_qualifier type_qualifier;
+         compat::vector<char> arg_name;
+      };
+
       struct symbol {
          symbol(const compat::vector<char> &name, resource_id section,
                 size_t offset, const compat::vector<argument> &args) :
                 name(name), section(section), offset(offset), args(args) { }
-         symbol() : name(), section(0), offset(0), args() { }
+         symbol() : name(), section(0), offset(0), args(), args_info() { }
 
          compat::vector<char> name;
          resource_id section;
          size_t offset;
          compat::vector<argument> args;
+         compat::vector<argument_info> args_info;
       };
 
       void serialize(compat::ostream &os) const;
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index 41d5838..51c502e 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -53,7 +53,7 @@
 #include <llvm/Transforms/IPO.h>
 #include <llvm/Transforms/IPO/PassManagerBuilder.h>
 #include <llvm/Transforms/Utils/Cloning.h>
-
+#include <llvm/IR/Constants.h>
 
 #include <llvm/IR/DataLayout.h>
 #include <llvm/Target/TargetLibraryInfo.h>
@@ -291,6 +291,95 @@ namespace {
    }
 
    void
+   find_kernels_metadata(llvm::Module *mod, module &m) {
+      const llvm::NamedMDNode *root_node =
+                                 mod->getNamedMetadata("opencl.kernels");
+      if (!root_node) {
+         return;
+      }
+
+      for (unsigned i = 0; i < root_node->getNumOperands(); ++i) {
+         llvm::MDNode *kernel_node = root_node->getOperand(i);
+
+         for (unsigned j = 1; j < kernel_node->getNumOperands(); ++j) {
+            llvm::MDNode *meta_node =
+                        llvm::cast<llvm::MDNode>(kernel_node->getOperand(j));
+
+            const uint num_ope = meta_node->getNumOperands();
+            if (num_ope == 1) //no kernel argument
+               continue;
+
+            m.syms[i].args_info.resize(num_ope-1);
+
+            //info name
+            llvm::MDString *md_name =
+                        llvm::cast<llvm::MDString>(meta_node->getOperand(0));
+            std::string name = md_name->getString().str();
+
+            //info value
+            for (uint k = 1; k < num_ope; ++k) {
+               llvm::Value *value = meta_node->getOperand(k);
+               module::argument_info &arg_info = m.syms[i].args_info[k-1];
+
+               if (name == "kernel_arg_addr_space") {
+                  int v =
+                     (llvm::cast<llvm::ConstantInt>(value))->getLimitedValue();
+
+                  switch(v) {
+                  case 0:
+                     arg_info.address_qualifier = CL_KERNEL_ARG_ADDRESS_PRIVATE;
+                     break;
+                  case 1:
+                     arg_info.address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL;
+                     break;
+                  case 2:
+                     arg_info.address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT;
+                     break;
+                  case 3:
+                     arg_info.address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL;
+                     break;
+                  }
+
+               } else {
+                  std::string v =
+                        (llvm::cast<llvm::MDString>(value))->getString().str();
+
+                  if (name == "kernel_arg_access_qual") {
+                     if (v == "read_only")
+                        arg_info.access_qualifier =
+                                              CL_KERNEL_ARG_ACCESS_READ_ONLY;
+                     else if (v == "write_only")
+                        arg_info.access_qualifier =
+                                              CL_KERNEL_ARG_ACCESS_WRITE_ONLY;
+                     else if (v == "read_write")
+                        arg_info.access_qualifier =
+                                              CL_KERNEL_ARG_ACCESS_READ_WRITE;
+                     else /*if (v == "none")*/
+                        arg_info.access_qualifier =
+                                              CL_KERNEL_ARG_ACCESS_NONE;
+
+                  } else if (name == "kernel_arg_type") {
+                     arg_info.type_name = v;
+
+                  } else if (name == "kernel_arg_type_qual") {
+                     arg_info.type_qualifier = CL_KERNEL_ARG_TYPE_NONE;
+                     if (v.find("const") != std::string::npos)
+                        arg_info.type_qualifier |= CL_KERNEL_ARG_TYPE_CONST;
+                     if (v.find("restrict") != std::string::npos)
+                        arg_info.type_qualifier |= CL_KERNEL_ARG_TYPE_RESTRICT;
+                     if (v.find("volatile") != std::string::npos)
+                        arg_info.type_qualifier |= CL_KERNEL_ARG_TYPE_VOLATILE;
+
+                  } else if (name == "kernel_arg_name") {
+                     arg_info.arg_name = v;
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   void
    optimize(llvm::Module *mod, unsigned optimization_level,
             const std::vector<llvm::Function *> &kernels) {
 
@@ -747,6 +836,8 @@ clover::build_program_llvm(const compat::string &source,
          break;
       }
    }
+
+   find_kernels_metadata(mod, m);
 #if HAVE_LLVM >= 0x0306
    // LLVM 3.6 and newer, the user takes ownership of the module.
    delete mod;
@@ -939,7 +1030,7 @@ clover::link_program_llvm(const compat::vector<module> &modules,
             break;
          }
       }
-
+      find_kernels_metadata(&linked_mod, m);
    }
 
    return m;
-- 
2.1.0



More information about the mesa-dev mailing list