--- 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev