From a6ca297b403e3b729eb13bc5425ac7f64bacdab3 Mon Sep 17 00:00:00 2001 From: Luo Date: Fri, 12 Sep 2014 11:53:41 +0800 Subject: [PATCH] fix piglit get kernel info FUNCTION ATTRIBUTE fail. the backend need return the kernel FUNCTION ATTRIBUTE message to the clGetKernelInfo. there are 3 kind of function attribute so far, vec_type_hint parameter is not available to return due to llvm lack of such info. Signed-off-by: Luo Reviewed-by: Zhigang Gong --- backend/src/backend/program.cpp | 9 +++++++ backend/src/backend/program.h | 4 +++ backend/src/backend/program.hpp | 6 +++++ backend/src/gbe_bin_interpreter.cpp | 1 + backend/src/ir/function.hpp | 5 ++++ backend/src/llvm/llvm_gen_backend.cpp | 45 +++++++++++++++++++++++++++++++++ src/cl_api.c | 3 +++ src/cl_gbe_loader.cpp | 5 ++++ src/cl_gbe_loader.h | 1 + src/cl_kernel.c | 7 +++++ src/cl_kernel.h | 3 +++ utests/CMakeLists.txt | 1 + utests/compiler_function_qualifiers.cpp | 10 ++++++++ 13 files changed, 100 insertions(+) diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index be83108..2308770 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -154,6 +154,7 @@ namespace gbe { kernel->setImageSet(pair.second->getImageSet()); kernel->setPrintfSet(pair.second->getPrintfSet()); kernel->setCompileWorkGroupSize(pair.second->getCompileWorkGroupSize()); + kernel->setFunctionAttributes(pair.second->getFunctionAttributes()); kernels.insert(std::make_pair(name, kernel)); } return true; @@ -895,6 +896,12 @@ namespace gbe { return kernel->getName(); } + static const char *kernelGetAttributes(gbe_kernel genKernel) { + if (genKernel == NULL) return NULL; + const gbe::Kernel *kernel = (const gbe::Kernel*) genKernel; + return kernel->getFunctionAttributes(); + } + static const char *kernelGetCode(gbe_kernel genKernel) { if (genKernel == NULL) return NULL; const gbe::Kernel *kernel = (const gbe::Kernel*) genKernel; @@ -1111,6 +1118,7 @@ GBE_EXPORT_SYMBOL gbe_program_get_kernel_num_cb *gbe_program_get_kernel_num = NU GBE_EXPORT_SYMBOL gbe_program_get_kernel_by_name_cb *gbe_program_get_kernel_by_name = NULL; GBE_EXPORT_SYMBOL gbe_program_get_kernel_cb *gbe_program_get_kernel = NULL; GBE_EXPORT_SYMBOL gbe_kernel_get_name_cb *gbe_kernel_get_name = NULL; +GBE_EXPORT_SYMBOL gbe_kernel_get_attributes_cb *gbe_kernel_get_attributes = NULL; GBE_EXPORT_SYMBOL gbe_kernel_get_code_cb *gbe_kernel_get_code = NULL; GBE_EXPORT_SYMBOL gbe_kernel_get_code_size_cb *gbe_kernel_get_code_size = NULL; GBE_EXPORT_SYMBOL gbe_kernel_get_arg_num_cb *gbe_kernel_get_arg_num = NULL; @@ -1158,6 +1166,7 @@ namespace gbe gbe_program_get_kernel_by_name = gbe::programGetKernelByName; gbe_program_get_kernel = gbe::programGetKernel; gbe_kernel_get_name = gbe::kernelGetName; + gbe_kernel_get_attributes = gbe::kernelGetAttributes; gbe_kernel_get_code = gbe::kernelGetCode; gbe_kernel_get_code_size = gbe::kernelGetCodeSize; gbe_kernel_get_arg_num = gbe::kernelGetArgNum; diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h index c63ae6a..0e773f4 100644 --- a/backend/src/backend/program.h +++ b/backend/src/backend/program.h @@ -271,6 +271,10 @@ extern gbe_program_get_kernel_cb *gbe_program_get_kernel; typedef const char *(gbe_kernel_get_name_cb)(gbe_kernel); extern gbe_kernel_get_name_cb *gbe_kernel_get_name; +/*! Get the kernel attributes*/ +typedef const char *(gbe_kernel_get_attributes_cb)(gbe_kernel); +extern gbe_kernel_get_attributes_cb *gbe_kernel_get_attributes; + /*! Get the kernel source code */ typedef const char *(gbe_kernel_get_code_cb)(gbe_kernel); extern gbe_kernel_get_code_cb *gbe_kernel_get_code; diff --git a/backend/src/backend/program.hpp b/backend/src/backend/program.hpp index 6a8af61..4f9b68a 100644 --- a/backend/src/backend/program.hpp +++ b/backend/src/backend/program.hpp @@ -176,6 +176,11 @@ namespace gbe { wg_sz[1] = compileWgSize[1]; wg_sz[2] = compileWgSize[2]; } + /*! Set function attributes string. */ + void setFunctionAttributes(const std::string& functionAttributes) { this->functionAttributes= functionAttributes; } + /*! Get function attributes string. */ + const char* getFunctionAttributes(void) const {return this->functionAttributes.c_str();} + /*! Get defined image size */ size_t getImageSize(void) const { return (imageSet == NULL ? 0 : imageSet->getDataSize()); } /*! Get defined image value array */ @@ -228,6 +233,7 @@ namespace gbe { ir::ImageSet *imageSet; //!< Copy from the corresponding function. ir::PrintfSet *printfSet; //!< Copy from the corresponding function. size_t compileWgSize[3]; //!< required work group size by kernel attribute. + std::string functionAttributes; //!< function attribute qualifiers combined. GBE_CLASS(Kernel); //!< Use custom allocators }; diff --git a/backend/src/gbe_bin_interpreter.cpp b/backend/src/gbe_bin_interpreter.cpp index ecf62b1..1c67a4b 100644 --- a/backend/src/gbe_bin_interpreter.cpp +++ b/backend/src/gbe_bin_interpreter.cpp @@ -47,6 +47,7 @@ struct BinInterpCallBackInitializer gbe_kernel_get_stack_size = gbe::kernelGetStackSize; gbe_kernel_get_image_size = gbe::kernelGetImageSize; gbe_kernel_get_name = gbe::kernelGetName; + gbe_kernel_get_attributes = gbe::kernelGetAttributes; gbe_kernel_get_arg_type = gbe::kernelGetArgType; gbe_kernel_get_arg_size = gbe::kernelGetArgSize; gbe_kernel_get_arg_bti = gbe::kernelGetArgBTI; diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp index c5582b4..a9cf22c 100644 --- a/backend/src/ir/function.hpp +++ b/backend/src/ir/function.hpp @@ -406,6 +406,10 @@ namespace ir { void setCompileWorkGroupSize(size_t x, size_t y, size_t z) { compileWgSize[0] = x; compileWgSize[1] = y; compileWgSize[2] = z; } /*! Get required work group size. */ const size_t *getCompileWorkGroupSize(void) const {return compileWgSize;} + /*! Set function attributes string. */ + void setFunctionAttributes(const std::string& functionAttributes) { this->functionAttributes= functionAttributes; } + /*! Get function attributes string. */ + const std::string& getFunctionAttributes(void) const {return this->functionAttributes;} /*! Get stack size. */ INLINE uint32_t getStackSize(void) const { return this->stackSize; } /*! Push stack size. */ @@ -441,6 +445,7 @@ namespace ir { PrintfSet *printfSet; //!< printfSet store the printf info. size_t compileWgSize[3]; //!< required work group size specified by // __attribute__((reqd_work_group_size(X, Y, Z))). + std::string functionAttributes; //!< function attribute qualifiers combined. GBE_CLASS(Function); //!< Use custom allocator }; diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp index 39620f6..b0e02ca 100644 --- a/backend/src/llvm/llvm_gen_backend.cpp +++ b/backend/src/llvm/llvm_gen_backend.cpp @@ -159,6 +159,7 @@ #include "sys/set.hpp" #include "sys/cvar.hpp" #include "backend/program.h" +#include /* Not defined for LLVM 3.0 */ #if !defined(LLVM_VERSION_MAJOR) @@ -1256,6 +1257,8 @@ namespace gbe MDNode *typeQualNode = NULL; MDNode *argNameNode = NULL; + std::string functionAttributes; + /* First find the meta data belong to this function. */ for(uint i = 0; i < clKernelMetaDatas->getNumOperands(); i++) { node = clKernelMetaDatas->getOperand(i); @@ -1267,6 +1270,7 @@ namespace gbe if (!F.arg_empty()) assert(node); + for(uint j = 0; j < node->getNumOperands() - 1; j++) { MDNode *attrNode = dyn_cast_or_null(node->getOperand(1 + j)); if (attrNode == NULL) break; @@ -1282,6 +1286,19 @@ namespace gbe reqd_wg_sz[0] = x->getZExtValue(); reqd_wg_sz[1] = y->getZExtValue(); reqd_wg_sz[2] = z->getZExtValue(); + functionAttributes += attrName->getString(); + std::stringstream param; + char buffer[100]; + param <<"("; + param << reqd_wg_sz[0]; + param << ","; + param << reqd_wg_sz[1]; + param << ","; + param << reqd_wg_sz[2]; + param <<")"; + param >> buffer; + functionAttributes += buffer; + functionAttributes += " "; break; } else if (attrName->getString() == "kernel_arg_addr_space") { addrSpaceNode = attrNode; @@ -1293,11 +1310,39 @@ namespace gbe typeQualNode = attrNode; } else if (attrName->getString() == "kernel_arg_name") { argNameNode = attrNode; + } else if (attrName->getString() == "vec_type_hint") { + GBE_ASSERT(attrNode->getNumOperands() == 3); + functionAttributes += attrName->getString(); + functionAttributes += " "; + } else if (attrName->getString() == "work_group_size_hint") { + GBE_ASSERT(attrNode->getNumOperands() == 4); + ConstantInt *x = dyn_cast(attrNode->getOperand(1)); + ConstantInt *y = dyn_cast(attrNode->getOperand(2)); + ConstantInt *z = dyn_cast(attrNode->getOperand(3)); + GBE_ASSERT(x && y && z); + reqd_wg_sz[0] = x->getZExtValue(); + reqd_wg_sz[1] = y->getZExtValue(); + reqd_wg_sz[2] = z->getZExtValue(); + functionAttributes += attrName->getString(); + std::stringstream param; + char buffer[100]; + param <<"("; + param << reqd_wg_sz[0]; + param << ","; + param << reqd_wg_sz[1]; + param << ","; + param << reqd_wg_sz[2]; + param <<")"; + param >> buffer; + functionAttributes += buffer; + functionAttributes += " "; } } ctx.appendSurface(1, ir::ocl::stackbuffer); ctx.getFunction().setCompileWorkGroupSize(reqd_wg_sz[0], reqd_wg_sz[1], reqd_wg_sz[2]); + + ctx.getFunction().setFunctionAttributes(functionAttributes); // Loop over the arguments and output registers for them if (!F.arg_empty()) { uint32_t argID = 0; diff --git a/src/cl_api.c b/src/cl_api.c index 50f258a..8a2e999 100644 --- a/src/cl_api.c +++ b/src/cl_api.c @@ -1295,6 +1295,9 @@ clGetKernelInfo(cl_kernel kernel, } else if (param_name == CL_KERNEL_FUNCTION_NAME) { const char * n = cl_kernel_get_name(kernel); FILL_GETINFO_RET (cl_char, strlen(n)+1, n, CL_SUCCESS); + } else if (param_name == CL_KERNEL_ATTRIBUTES) { + const char * n = cl_kernel_get_attributes(kernel); + FILL_GETINFO_RET (cl_char, strlen(n)+1, n, CL_SUCCESS); } else { return CL_INVALID_VALUE; } diff --git a/src/cl_gbe_loader.cpp b/src/cl_gbe_loader.cpp index c95eb7c..7da0475 100644 --- a/src/cl_gbe_loader.cpp +++ b/src/cl_gbe_loader.cpp @@ -42,6 +42,7 @@ gbe_program_get_kernel_num_cb *interp_program_get_kernel_num = NULL; gbe_program_get_kernel_by_name_cb *interp_program_get_kernel_by_name = NULL; gbe_program_get_kernel_cb *interp_program_get_kernel = NULL; gbe_kernel_get_name_cb *interp_kernel_get_name = NULL; +gbe_kernel_get_attributes_cb *interp_kernel_get_attributes = NULL; gbe_kernel_get_code_cb *interp_kernel_get_code = NULL; gbe_kernel_get_code_size_cb *interp_kernel_get_code_size = NULL; gbe_kernel_get_arg_num_cb *interp_kernel_get_arg_num = NULL; @@ -127,6 +128,10 @@ struct GbeLoaderInitializer if (interp_kernel_get_name == NULL) return false; + interp_kernel_get_attributes = *(gbe_kernel_get_attributes_cb**)dlsym(dlhInterp, "gbe_kernel_get_attributes"); + if (interp_kernel_get_attributes == NULL) + return false; + interp_kernel_get_code = *(gbe_kernel_get_code_cb**)dlsym(dlhInterp, "gbe_kernel_get_code"); if (interp_kernel_get_code == NULL) return false; diff --git a/src/cl_gbe_loader.h b/src/cl_gbe_loader.h index 38b43b7..da9d034 100644 --- a/src/cl_gbe_loader.h +++ b/src/cl_gbe_loader.h @@ -42,6 +42,7 @@ extern gbe_program_get_kernel_num_cb *interp_program_get_kernel_num; extern gbe_program_get_kernel_by_name_cb *interp_program_get_kernel_by_name; extern gbe_program_get_kernel_cb *interp_program_get_kernel; extern gbe_kernel_get_name_cb *interp_kernel_get_name; +extern gbe_kernel_get_attributes_cb *interp_kernel_get_attributes; extern gbe_kernel_get_code_cb *interp_kernel_get_code; extern gbe_kernel_get_code_size_cb *interp_kernel_get_code_size; extern gbe_kernel_get_arg_num_cb *interp_kernel_get_arg_num; diff --git a/src/cl_kernel.c b/src/cl_kernel.c index d7c2f7c..55b707a 100644 --- a/src/cl_kernel.c +++ b/src/cl_kernel.c @@ -86,6 +86,13 @@ cl_kernel_get_name(cl_kernel k) return interp_kernel_get_name(k->opaque); } +LOCAL const char* +cl_kernel_get_attributes(cl_kernel k) +{ + if (UNLIKELY(k == NULL)) return NULL; + return interp_kernel_get_attributes(k->opaque); +} + LOCAL void cl_kernel_add_ref(cl_kernel k) { diff --git a/src/cl_kernel.h b/src/cl_kernel.h index 85a997d..1ed90a5 100644 --- a/src/cl_kernel.h +++ b/src/cl_kernel.h @@ -79,6 +79,9 @@ extern void cl_kernel_setup(cl_kernel k, gbe_kernel opaque); /* Get the kernel name */ extern const char *cl_kernel_get_name(cl_kernel k); +/* Get the kernel attributes*/ +extern const char *cl_kernel_get_attributes(cl_kernel k); + /* Get the simd width as used in the code */ extern uint32_t cl_kernel_get_simd_width(cl_kernel k); diff --git a/utests/CMakeLists.txt b/utests/CMakeLists.txt index 034f112..a91b6fc 100644 --- a/utests/CMakeLists.txt +++ b/utests/CMakeLists.txt @@ -166,6 +166,7 @@ set (utests_sources compiler_long_mult.cpp compiler_long_cmp.cpp compiler_function_argument3.cpp + compiler_function_qualifiers.cpp compiler_bool_cross_basic_block.cpp compiler_private_data_overflow.cpp compiler_getelementptr_bitcast.cpp diff --git a/utests/compiler_function_qualifiers.cpp b/utests/compiler_function_qualifiers.cpp index 55ddd84..622313c 100644 --- a/utests/compiler_function_qualifiers.cpp +++ b/utests/compiler_function_qualifiers.cpp @@ -3,6 +3,16 @@ void compiler_function_qualifiers(void) { OCL_CREATE_KERNEL("compiler_function_qualifiers"); + + size_t param_value_size; + void* param_value; + cl_int err; + + err = clGetKernelInfo(kernel, CL_KERNEL_ATTRIBUTES, 0, NULL, ¶m_value_size); + OCL_ASSERT(err == CL_SUCCESS); + param_value = malloc(param_value_size); + err = clGetKernelInfo(kernel, CL_KERNEL_ATTRIBUTES, param_value_size, param_value, NULL); + OCL_ASSERT(err == CL_SUCCESS); } MAKE_UTEST_FROM_FUNCTION(compiler_function_qualifiers); -- 2.7.4