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);
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));
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);
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;
free(str);
}
+ if (useDefaultCLCVersion)
+ clOpt.push_back("-D__OPENCL_C_VERSION__=120");
//for clCompilerProgram usage.
if(temp_header_path){
clOpt.push_back("-I");
// Write the source to the cl file
fwrite(source, strlen(source), 1, clFile);
fclose(clFile);
+ return true;
}
static gbe_program programNewFromSource(uint32_t deviceID,
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().
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();
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)
{
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) {
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++) {
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) {