From be80a7feaf7e749ba100167a3087fdeb77b358f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Petit?= Date: Tue, 30 Jul 2019 11:52:31 +0100 Subject: [PATCH] Align offline compilation with cl21_trunk (#400) Add a special case for the Khronos compiler and always use it for OpenCL C++, otherwise use the same logic as on the cl21_trunk branch. The CMake option to pass the path to the khronos compiler has been renamed to KHRONOS_OFFLINE_COMPILER_OPTIONS and is no longer mandatory. Signed-off-by: Kevin Petit --- .travis.yml | 1 - CMakeLists.txt | 24 +++--- build_lnx.sh | 2 +- build_win.bat | 2 +- test_common/harness/kernelHelpers.c | 116 ++++++++++++++++++++++++---- 5 files changed, 116 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml index d850c324..2738618d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,6 @@ script: - cmake -DCL_INCLUDE_DIR=${TOP}/OpenCL-Headers -DCL_LIB_DIR=${TOP}/OpenCL-ICD-Loader/build -DCL_LIBCLCXX_DIR=${TOP}/libclcxx - -DCL_OFFLINE_COMPILER=/dummy/path/to/compiler -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin -DOPENCL_LIBRARIES="-lOpenCL -lpthread" .. diff --git a/CMakeLists.txt b/CMakeLists.txt index cec3d3b7..c0242c6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,18 +92,18 @@ endif(CLPP_DEVELOPMENT_OPTIONS) # Path to offline OpenCL C/C++ compiler provided by Khronos. # See https://github.com/KhronosGroup/SPIR/ (spirv-1.1 branch or newer SPIR-V-ready # branch should be used). -if(CL_OFFLINE_COMPILER) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCL_OFFLINE_COMPILER=${CL_OFFLINE_COMPILER}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCL_OFFLINE_COMPILER=${CL_OFFLINE_COMPILER}") +if(KHRONOS_OFFLINE_COMPILER) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DKHRONOS_OFFLINE_COMPILER=${KHRONOS_OFFLINE_COMPILER}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKHRONOS_OFFLINE_COMPILER=${KHRONOS_OFFLINE_COMPILER}") # Additional OpenCL C/C++ compiler option. - if(CL_OFFLINE_COMPILER_OPTIONS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCL_OFFLINE_COMPILER_OPTIONS=${CL_OFFLINE_COMPILER_OPTIONS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCL_OFFLINE_COMPILER_OPTIONS=${CL_OFFLINE_COMPILER_OPTIONS}") - endif(CL_OFFLINE_COMPILER_OPTIONS) -else(CL_OFFLINE_COMPILER) - message(STATUS "OpenCL C/C++ compiler hasn't been found!") - message(FATAL_ERROR "Pass path to OpenCL C/C++ compiler in CL_OFFLINE_COMPILER") -endif(CL_OFFLINE_COMPILER) + if(KHRONOS_OFFLINE_COMPILER_OPTIONS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DKHRONOS_OFFLINE_COMPILER_OPTIONS=${KHRONOS_OFFLINE_COMPILER_OPTIONS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKHRONOS_OFFLINE_COMPILER_OPTIONS=${KHRONOS_OFFLINE_COMPILER_OPTIONS}") + endif(KHRONOS_OFFLINE_COMPILER_OPTIONS) +else(KHRONOS_OFFLINE_COMPILER) + message(WARNING "KHRONOS_OFFLINE_COMPILER is not defined!") + message(WARNING "Running CL C++ tests will not be possible.") +endif(KHRONOS_OFFLINE_COMPILER) # CL_LIBCLCXX_DIR - path to dir with OpenCL C++ STL (libclcxx) # CL_INCLUDE_DIR - path to dir with OpenCL headers @@ -214,4 +214,4 @@ if(MSVC) endif(MSVC) set_property(TARGET COPY_FILES${CONFORMANCE_SUFFIX} PROPERTY FOLDER "CONFORMANCE${CONFORMANCE_SUFFIX}") -add_subdirectory( "test_extensions" ) \ No newline at end of file +add_subdirectory( "test_extensions" ) diff --git a/build_lnx.sh b/build_lnx.sh index c9bde6e1..f1c71f8f 100755 --- a/build_lnx.sh +++ b/build_lnx.sh @@ -2,5 +2,5 @@ mkdir -p build_lnx cd build_lnx -cmake -g "Unix Makefiles" ../ -DCL_OFFLINE_COMPILER= -DCL_LIBCLCXX_DIR= -DCL_INCLUDE_DIR= -DCL_LIB_DIR= -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL +cmake -g "Unix Makefiles" ../ -DKHRONOS_OFFLINE_COMPILER= -DCL_LIBCLCXX_DIR= -DCL_INCLUDE_DIR= -DCL_LIB_DIR= -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL make --jobs 8 diff --git a/build_win.bat b/build_win.bat index 0e715656..6ae31827 100644 --- a/build_win.bat +++ b/build_win.bat @@ -20,7 +20,7 @@ mkdir build_win pushd build_win IF NOT EXIST CLConform.sln ( echo "Solution file not found, running Cmake" - cmake -G "Visual Studio 14 2015 Win64" ..\. -DCL_OFFLINE_COMPILER= -DCL_LIBCLCXX_DIR= -DCL_INCLUDE_DIR= -DCL_LIB_DIR= -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL + cmake -G "Visual Studio 14 2015 Win64" ..\. -DKHRONOS_OFFLINE_COMPILER= -DCL_LIBCLCXX_DIR= -DCL_INCLUDE_DIR= -DCL_LIB_DIR= -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL ) else ( echo "Solution file found CLConform.sln " ) diff --git a/test_common/harness/kernelHelpers.c b/test_common/harness/kernelHelpers.c index f4993287..ee7c5c70 100644 --- a/test_common/harness/kernelHelpers.c +++ b/test_common/harness/kernelHelpers.c @@ -227,7 +227,7 @@ static std::string get_offline_compilation_file_type_str(const CompilationMode c } } -static std::string get_offline_compilation_command(const cl_uint device_address_space_size, +static std::string get_khronos_compiler_command(const cl_uint device_address_space_size, const bool openclCXX, const std::string &bOptions, const std::string &sourceFilename, @@ -261,8 +261,8 @@ static std::string get_offline_compilation_command(const cl_uint device_address_ compilerOptions += " -include opencl.h"; } -#ifdef CL_OFFLINE_COMPILER_OPTIONS - compilerOptions += STRINGIFY_VALUE(CL_OFFLINE_COMPILER_OPTIONS); +#ifdef KHRONOS_OFFLINE_COMPILER_OPTIONS + compilerOptions += STRINGIFY_VALUE(KHRONOS_OFFLINE_COMPILER_OPTIONS); #endif // Add build options passed to this function @@ -270,21 +270,113 @@ static std::string get_offline_compilation_command(const cl_uint device_address_ compilerOptions += " " + sourceFilename + " -o " + outputFilename; - std::string runString = STRINGIFY_VALUE(CL_OFFLINE_COMPILER) + compilerOptions; + std::string runString = STRINGIFY_VALUE(KHRONOS_OFFLINE_COMPILER) + compilerOptions; return runString; } +static std::string get_offline_compilation_command(const cl_uint device_address_space_size, + const CompilationMode compilationMode, + const std::string &bOptions, + const std::string &sourceFilename, + const std::string &outputFilename) +{ + std::ostringstream size_t_width_stream; + size_t_width_stream << device_address_space_size; + std::string size_t_width_str = size_t_width_stream.str(); + + // set output type and default script + std::string outputTypeStr; + std::string defaultScript; + if (compilationMode == kBinary) + { + outputTypeStr = "binary"; + #if defined(_WIN32) + defaultScript = "..\\build_script_binary.py "; + #else + defaultScript = "../build_script_binary.py "; + #endif + } + else if (compilationMode == kSpir_v) + { + outputTypeStr = "spir_v"; + #if defined(_WIN32) + defaultScript = "..\\build_script_spirv.py "; + #else + defaultScript = "../build_script_spirv.py "; + #endif + } + + // set script arguments + std::string scriptArgs = sourceFilename + " " + outputFilename + " " + size_t_width_str + " " + outputTypeStr; + + if (!bOptions.empty()) + { + //search for 2.0 build options + std::string oclVersion; + std::string buildOptions20 = "-cl-std=CL2.0"; + std::size_t found = bOptions.find(buildOptions20); + + if (found != std::string::npos) + oclVersion = "20"; + else + oclVersion = "12"; + + std::string bOptionsWRemovedStd20 = bOptions; + + std::string::size_type i = bOptions.find(buildOptions20); + + if (i != std::string::npos) + bOptionsWRemovedStd20.erase(i, buildOptions20.length()); + + //remove space before -cl-std=CL2.0 if it was first build option + size_t spacePos = bOptionsWRemovedStd20.find_last_of(" \t\r\n", i); + if (spacePos != std::string::npos && i == 0) + bOptionsWRemovedStd20.erase(spacePos, sizeof(char)); + + //remove space after -cl-std=CL2.0 + spacePos = bOptionsWRemovedStd20.find_first_of(" \t\r\n", i - 1); + if (spacePos != std::string::npos) + bOptionsWRemovedStd20.erase(spacePos, sizeof(char)); + + if (!bOptionsWRemovedStd20.empty()) + scriptArgs += " " + oclVersion + " \"" + bOptionsWRemovedStd20 + "\""; + else + scriptArgs += " " + oclVersion; + } + else + scriptArgs += " 12"; + + // set script command line + std::string scriptToRunString = defaultScript + scriptArgs; + + return scriptToRunString; +} + static int invoke_offline_compiler(cl_context context, const cl_uint device_address_space_size, - const bool openclCXX, + const CompilationMode compilationMode, const std::string &bOptions, const std::string &sourceFilename, - const std::string &outputFilename) + const std::string &outputFilename, + const bool openclCXX) { - std::string runString = - get_offline_compilation_command(device_address_space_size, openclCXX, bOptions, + std::string runString; + if (openclCXX) + { +#ifndef KHRONOS_OFFLINE_COMPILER + log_error("CL C++ compilation is not possible: KHRONOS_OFFLINE_COMPILER was not defined.\n"); + return CL_INVALID_OPERATION; +#else + runString = get_khronos_compiler_command(device_address_space_size, openclCXX, bOptions, sourceFilename, outputFilename); +#endif + } + else + { + runString = get_offline_compilation_command(device_address_space_size, compilationMode, bOptions, + sourceFilename, outputFilename); + } // execute script log_info("Executing command: %s\n", runString.c_str()); @@ -395,8 +487,8 @@ static int get_offline_compiler_output(std::ifstream &ifs, ofs.write(kernel.c_str(), kernel.size()); ofs.close(); - error = invoke_offline_compiler(context, device_address_space_size, openclCXX, - bOptions, sourceFilename, outputFilename); + error = invoke_offline_compiler(context, device_address_space_size, compilationMode, + bOptions, sourceFilename, outputFilename, openclCXX); if (error != CL_SUCCESS) return error; @@ -520,13 +612,9 @@ static int create_single_kernel_helper_create_program(cl_context context, } else { -#ifdef CL_OFFLINE_COMPILER return create_single_kernel_helper_create_program_offline(context, outProgram, numKernelLines, kernelProgram, buildOptions, openclCXX, compilationMode); -#endif - log_error("Offline compilation is not possible: CL_OFFLINE_COMPILER was not defined.\n"); - return -1; } }