[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