summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunyan He <junyan.he@linux.intel.com>2014-09-10 15:39:41 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-09-10 15:52:13 +0800
commit72141a4bcc1e7e59787940d022d93b8de1757fe2 (patch)
tree79b4c36f5300afe027f2ceec44558ba11a02ab68
parentddc0c25adc2c27450e7296cfc0b4931129280081 (diff)
Fix the issue of -cl-std=CLX.X option.
The -cl-std= will specify the least version to compile the source code providing to our API. So we need to check it early, and return failure if our platform's version can not meet the request. In the backend, we just ignore this cmd line option. Signed-off-by: Junyan He <junyan.he@linux.intel.com> Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
-rw-r--r--backend/src/backend/program.cpp37
-rw-r--r--backend/src/libocl/tmpl/ocl_defines.tmpl.h3
-rw-r--r--src/cl_program.c50
3 files changed, 82 insertions, 8 deletions
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index 8c41d5e..b9dfc75 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -617,12 +617,15 @@ namespace gbe {
SVAR(OCL_PCH_PATH, OCL_PCH_OBJECT);
SVAR(OCL_HEADER_FILE_DIR, OCL_HEADER_DIR);
- static void processSourceAndOption(const char *source,
+ static bool processSourceAndOption(const char *source,
const char *options,
const char *temp_header_path,
std::vector<std::string>& clOpt,
std::string& clName,
- int& optLevel)
+ int& optLevel,
+ size_t stringSize,
+ char *err,
+ size_t *errSize)
{
std::string dirs = OCL_PCH_PATH;
std::istringstream idirs(dirs);
@@ -646,6 +649,7 @@ namespace gbe {
assert(findOcl);
std::string includePath = "-I" + headerFilePath;
clOpt.push_back(includePath);
+ bool useDefaultCLCVersion = true;
if (options) {
char *str = (char *)malloc(sizeof(char) * (strlen(options) + 1));
@@ -656,7 +660,6 @@ namespace gbe {
const std::string uncompatiblePCHOptions = ("-cl-single-precision-constant, -cl-fast-relaxed-math");
const std::string fastMathOption = ("-cl-fast-relaxed-math");
-
while (end != std::string::npos) {
end = optionStr.find(' ', start);
std::string str = optionStr.substr(start, end - start);
@@ -664,8 +667,23 @@ namespace gbe {
if(str.size() == 0)
continue;
- if(unsupportedOptions.find(str) != std::string::npos)
+ if(unsupportedOptions.find(str) != std::string::npos) {
+ continue;
+ }
+
+ if(str.find("-cl-std=") != std::string::npos) {
+ useDefaultCLCVersion = false;
+ if (str == "-cl-std=CL1.1")
+ clOpt.push_back("-D__OPENCL_C_VERSION__=110");
+ else if (str == "-cl-std=CL1.2")
+ clOpt.push_back("-D__OPENCL_C_VERSION__=120");
+ else {
+ if (err && stringSize > 0 && errSize)
+ *errSize = snprintf(err, stringSize, "Invalid build option: %s\n", str.c_str());
+ return false;
+ }
continue;
+ }
if (uncompatiblePCHOptions.find(str) != std::string::npos)
invalidPCH = true;
@@ -680,6 +698,8 @@ namespace gbe {
free(str);
}
+ if (useDefaultCLCVersion)
+ clOpt.push_back("-D__OPENCL_C_VERSION__=120");
//for clCompilerProgram usage.
if(temp_header_path){
clOpt.push_back("-I");
@@ -712,6 +732,7 @@ namespace gbe {
// Write the source to the cl file
fwrite(source, strlen(source), 1, clFile);
fclose(clFile);
+ return true;
}
static gbe_program programNewFromSource(uint32_t deviceID,
@@ -724,7 +745,9 @@ namespace gbe {
int optLevel = 1;
std::vector<std::string> clOpt;
std::string clName;
- processSourceAndOption(source, options, NULL, clOpt, clName, optLevel);
+ if (!processSourceAndOption(source, options, NULL, clOpt, clName,
+ optLevel, stringSize, err, errSize))
+ return NULL;
gbe_program p;
// will delete the module and act in GenProgram::CleanLlvmResource().
@@ -775,7 +798,9 @@ namespace gbe {
int optLevel = 1;
std::vector<std::string> clOpt;
std::string clName;
- processSourceAndOption(source, options, temp_header_path, clOpt, clName, optLevel);
+ if (!processSourceAndOption(source, options, temp_header_path, clOpt, clName,
+ optLevel, stringSize, err, errSize))
+ return NULL;
gbe_program p;
acquireLLVMContextLock();
diff --git a/backend/src/libocl/tmpl/ocl_defines.tmpl.h b/backend/src/libocl/tmpl/ocl_defines.tmpl.h
index 4548faf..446691c 100644
--- a/backend/src/libocl/tmpl/ocl_defines.tmpl.h
+++ b/backend/src/libocl/tmpl/ocl_defines.tmpl.h
@@ -18,9 +18,10 @@
#ifndef __OCL_COMMON_DEF_H__
#define __OCL_COMMON_DEF_H__
-#define __OPENCL_VERSION__ 110
+#define __OPENCL_VERSION__ 120
#define __CL_VERSION_1_0__ 100
#define __CL_VERSION_1_1__ 110
+#define __CL_VERSION_1_2__ 120
#define __ENDIAN_LITTLE__ 1
#define __IMAGE_SUPPORT__ 1
#define __kernel_exec(X, TYPE) __kernel __attribute__((work_group_size_hint(X,1,1))) \
diff --git a/src/cl_program.c b/src/cl_program.c
index a745c00..3ecc49f 100644
--- a/src/cl_program.c
+++ b/src/cl_program.c
@@ -424,6 +424,43 @@ error:
goto exit;
}
+/* Before we do the real work, we need to check whether our platform
+ cl version can meet -cl-std= */
+static int check_cl_version_option(cl_program p, const char* options) {
+ const char* s = NULL;
+ int ver1 = 0;
+ int ver2 = 0;
+ char version_str[64];
+
+ if (options && (s = strstr(options, "-cl-std="))) {
+
+ if (s + strlen("-cl-std=CLX.X") > options + strlen(options)) {
+ return 0;
+ }
+
+ if (s[8] != 'C' || s[9] != 'L' || s[10] > '9' || s[10] < '0' || s[11] != '.'
+ || s[12] > '9' || s[12] < '0') {
+ return 0;
+ }
+
+ ver1 = (s[10] - '0') * 10 + (s[12] - '0');
+
+ if (cl_get_device_info(p->ctx->device, CL_DEVICE_OPENCL_C_VERSION, sizeof(version_str),
+ version_str, NULL) != CL_SUCCESS)
+ return 0;
+
+ assert(strstr(version_str, "OpenCL") && version_str[0] == 'O');
+ ver2 = (version_str[9] - '0') * 10 + (version_str[11] - '0');
+
+ if (ver2 < ver1)
+ return 0;
+
+ return 1;
+ }
+
+ return 1;
+}
+
LOCAL cl_int
cl_program_build(cl_program p, const char *options)
{
@@ -434,6 +471,9 @@ cl_program_build(cl_program p, const char *options)
if (p->ref_n > 1)
return CL_INVALID_OPERATION;
+ if (!check_cl_version_option(p, options))
+ return CL_BUILD_PROGRAM_FAILURE;
+
if (options) {
if(p->build_opts == NULL || strcmp(options, p->build_opts) != 0) {
if(p->build_opts) {
@@ -526,11 +566,16 @@ cl_program_link(cl_context context,
cl_int* errcode_ret)
{
cl_program p = NULL;
- cl_int err=CL_SUCCESS;
+ cl_int err = CL_SUCCESS;
cl_int i = 0;
int copyed = 0;
p = cl_program_new(context);
+ if (!check_cl_version_option(p, options)) {
+ err = CL_BUILD_PROGRAM_FAILURE;
+ goto error;
+ }
+
p->opaque = compiler_program_new_gen_program(context->device->vendor_id, NULL, NULL);
for(i = 0; i < num_input_programs; i++) {
@@ -588,6 +633,9 @@ cl_program_compile(cl_program p,
if (p->ref_n > 1)
return CL_INVALID_OPERATION;
+ if (!check_cl_version_option(p, options))
+ return CL_BUILD_PROGRAM_FAILURE;
+
if (options) {
if(p->build_opts == NULL || strcmp(options, p->build_opts) != 0) {
if(p->build_opts) {