Skip to content

Commit

Permalink
Align offline compilation with cl21_trunk (#400)
Browse files Browse the repository at this point in the history
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 <kevin.petit@arm.com>
  • Loading branch information
kpet committed Jul 30, 2019
1 parent bcf994c commit be80a7f
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 29 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Expand Up @@ -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"
..
Expand Down
24 changes: 12 additions & 12 deletions CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -214,4 +214,4 @@ if(MSVC)
endif(MSVC)

set_property(TARGET COPY_FILES${CONFORMANCE_SUFFIX} PROPERTY FOLDER "CONFORMANCE${CONFORMANCE_SUFFIX}")
add_subdirectory( "test_extensions" )
add_subdirectory( "test_extensions" )
2 changes: 1 addition & 1 deletion build_lnx.sh
Expand Up @@ -2,5 +2,5 @@

mkdir -p build_lnx
cd build_lnx
cmake -g "Unix Makefiles" ../ -DCL_OFFLINE_COMPILER=<TO_SET> -DCL_LIBCLCXX_DIR=<TO_SET> -DCL_INCLUDE_DIR=<TO_SET> -DCL_LIB_DIR=<TO_SET> -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL
cmake -g "Unix Makefiles" ../ -DKHRONOS_OFFLINE_COMPILER=<TO_SET> -DCL_LIBCLCXX_DIR=<TO_SET> -DCL_INCLUDE_DIR=<TO_SET> -DCL_LIB_DIR=<TO_SET> -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL
make --jobs 8
2 changes: 1 addition & 1 deletion build_win.bat
Expand Up @@ -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=<TO_SET> -DCL_LIBCLCXX_DIR=<TO_SET> -DCL_INCLUDE_DIR=<TO_SET> -DCL_LIB_DIR=<TO_SET> -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL
cmake -G "Visual Studio 14 2015 Win64" ..\. -DKHRONOS_OFFLINE_COMPILER=<TO_SET> -DCL_LIBCLCXX_DIR=<TO_SET> -DCL_INCLUDE_DIR=<TO_SET> -DCL_LIB_DIR=<TO_SET> -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL
) else (
echo "Solution file found CLConform.sln "
)
Expand Down
116 changes: 102 additions & 14 deletions test_common/harness/kernelHelpers.c
Expand Up @@ -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,
Expand Down Expand Up @@ -261,30 +261,122 @@ 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
compilerOptions += " " + bOptions;
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());
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
}

Expand Down

0 comments on commit be80a7f

Please sign in to comment.