mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-25 16:29:03 +00:00
Split offline compilation into multiple functions
This commit is contained in:
committed by
Kévin Petit
parent
9c337d5f37
commit
912bfbe466
@@ -74,6 +74,18 @@ std::vector<char> get_file_content(const std::string &fileName)
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string get_kernel_content(unsigned int numKernelLines, const char *const *kernelProgram)
|
||||||
|
{
|
||||||
|
std::string kernel;
|
||||||
|
for (size_t i = 0; i < numKernelLines; ++i)
|
||||||
|
{
|
||||||
|
std::string chunk(kernelProgram[i], 0, std::string::npos);
|
||||||
|
kernel += chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kernel;
|
||||||
|
}
|
||||||
|
|
||||||
std::string get_kernel_name(const std::string &source)
|
std::string get_kernel_name(const std::string &source)
|
||||||
{
|
{
|
||||||
// Count CRC
|
// Count CRC
|
||||||
@@ -215,125 +227,15 @@ static std::string get_offline_compilation_file_type_str(const CompilationMode c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cl_int get_first_device_id(const cl_context context, cl_device_id &device)
|
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)
|
||||||
{
|
{
|
||||||
cl_uint numDevices = 0;
|
|
||||||
cl_int error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDevices, NULL);
|
|
||||||
test_error(error, "clGetContextInfo failed getting CL_CONTEXT_NUM_DEVICES");
|
|
||||||
|
|
||||||
if (numDevices == 0)
|
|
||||||
{
|
|
||||||
log_error("ERROR: No CL devices found\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<cl_device_id> devices(numDevices, 0);
|
|
||||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDevices*sizeof(cl_device_id), &devices[0], NULL);
|
|
||||||
test_error(error, "clGetContextInfo failed getting CL_CONTEXT_DEVICES");
|
|
||||||
|
|
||||||
device = devices[0];
|
|
||||||
return CL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cl_int get_first_device_address_bits(const cl_context context, cl_uint &device_address_space_size)
|
|
||||||
{
|
|
||||||
cl_device_id device;
|
|
||||||
cl_int error = get_first_device_id(context, device);
|
|
||||||
if (error != CL_SUCCESS)
|
|
||||||
{
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), &device_address_space_size, NULL);
|
|
||||||
test_error(error, "Unable to obtain device address bits");
|
|
||||||
|
|
||||||
if (device_address_space_size != 32 && device_address_space_size != 64)
|
|
||||||
{
|
|
||||||
log_error("ERROR: Unexpected number of device address bits: %u\n", device_address_space_size);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CL_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int create_single_kernel_helper_create_program(cl_context context,
|
|
||||||
cl_program *outProgram,
|
|
||||||
unsigned int numKernelLines,
|
|
||||||
const char **kernelProgram,
|
|
||||||
const char *buildOptions,
|
|
||||||
CompilationMode compilationMode)
|
|
||||||
{
|
|
||||||
int error = CL_SUCCESS;
|
|
||||||
|
|
||||||
if (compilationMode != kOnline)
|
|
||||||
{
|
|
||||||
std::string kernel;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < numKernelLines; ++i)
|
|
||||||
{
|
|
||||||
std::string chunk(kernelProgram[i], 0, std::string::npos);
|
|
||||||
kernel += chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string kernelName = get_kernel_name(kernel);
|
|
||||||
|
|
||||||
// set build options
|
|
||||||
std::string bOptions;
|
|
||||||
bOptions += buildOptions ? std::string(buildOptions) : "";
|
|
||||||
|
|
||||||
kernelName = add_build_options(kernelName, buildOptions);
|
|
||||||
|
|
||||||
std::string sourceFilename = gCompilationCachePath + slash + kernelName + ".cl";
|
|
||||||
std::string outputFilename = gCompilationCachePath + slash + kernelName;
|
|
||||||
|
|
||||||
std::string size_t_width_str;
|
|
||||||
|
|
||||||
cl_uint device_address_space_size = 0;
|
|
||||||
if (compilationMode == kSpir_v)
|
|
||||||
{
|
|
||||||
cl_int error = get_first_device_address_bits(context, device_address_space_size);
|
|
||||||
if (error != CL_SUCCESS)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
std::ostringstream extension;
|
|
||||||
extension << ".spv" << device_address_space_size;
|
|
||||||
outputFilename += extension.str();
|
|
||||||
|
|
||||||
std::ostringstream size_t_width_stream;
|
std::ostringstream size_t_width_stream;
|
||||||
size_t_width_stream << device_address_space_size;
|
size_t_width_stream << device_address_space_size;
|
||||||
size_t_width_str = size_t_width_stream.str();
|
std::string size_t_width_str = size_t_width_stream.str();
|
||||||
}
|
|
||||||
|
|
||||||
// try to read cached output file when test is run with gCompilationCacheMode != kCacheModeOverwrite
|
|
||||||
std::ifstream ifs(outputFilename.c_str(), std::ios::binary);
|
|
||||||
|
|
||||||
if (gCompilationCacheMode == kCacheModeOverwrite || !ifs.good())
|
|
||||||
{
|
|
||||||
std::string file_type = get_offline_compilation_file_type_str(compilationMode);
|
|
||||||
|
|
||||||
if (gCompilationCacheMode == kCacheModeForceRead)
|
|
||||||
{
|
|
||||||
log_info("OfflineCompiler: can't open cached %s file: %s\n",
|
|
||||||
file_type.c_str(), outputFilename.c_str());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifs.close();
|
|
||||||
|
|
||||||
if (gCompilationCacheMode != kCacheModeOverwrite)
|
|
||||||
log_info("OfflineCompiler: can't find cached %s file: %s\n",
|
|
||||||
file_type.c_str(), outputFilename.c_str());
|
|
||||||
|
|
||||||
std::ofstream ofs(sourceFilename.c_str(), std::ios::binary);
|
|
||||||
if (!ofs.good())
|
|
||||||
{
|
|
||||||
log_info("OfflineCompiler: can't create source file: %s\n", sourceFilename.c_str());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write source to input file
|
|
||||||
ofs.write(kernel.c_str(), kernel.size());
|
|
||||||
ofs.close();
|
|
||||||
|
|
||||||
// set output type and default script
|
// set output type and default script
|
||||||
std::string outputTypeStr;
|
std::string outputTypeStr;
|
||||||
@@ -400,6 +302,20 @@ static int create_single_kernel_helper_create_program(cl_context context,
|
|||||||
// set script command line
|
// set script command line
|
||||||
std::string scriptToRunString = defaultScript + scriptArgs;
|
std::string scriptToRunString = defaultScript + scriptArgs;
|
||||||
|
|
||||||
|
return scriptToRunString;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int invoke_offline_compiler(cl_context context,
|
||||||
|
const cl_uint device_address_space_size,
|
||||||
|
const CompilationMode compilationMode,
|
||||||
|
const std::string &bOptions,
|
||||||
|
const std::string &sourceFilename,
|
||||||
|
const std::string &outputFilename)
|
||||||
|
{
|
||||||
|
std::string scriptToRunString =
|
||||||
|
get_offline_compilation_command(device_address_space_size, compilationMode, bOptions,
|
||||||
|
sourceFilename, outputFilename);
|
||||||
|
|
||||||
// execute script
|
// execute script
|
||||||
log_info("Executing command: %s\n", scriptToRunString.c_str());
|
log_info("Executing command: %s\n", scriptToRunString.c_str());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@@ -409,6 +325,110 @@ static int create_single_kernel_helper_create_program(cl_context context,
|
|||||||
log_error("Command finished with error: 0x%x\n", returnCode);
|
log_error("Command finished with error: 0x%x\n", returnCode);
|
||||||
return CL_COMPILE_PROGRAM_FAILURE;
|
return CL_COMPILE_PROGRAM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cl_int get_first_device_id(const cl_context context, cl_device_id &device)
|
||||||
|
{
|
||||||
|
cl_uint numDevices = 0;
|
||||||
|
cl_int error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), &numDevices, NULL);
|
||||||
|
test_error(error, "clGetContextInfo failed getting CL_CONTEXT_NUM_DEVICES");
|
||||||
|
|
||||||
|
if (numDevices == 0)
|
||||||
|
{
|
||||||
|
log_error("ERROR: No CL devices found\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cl_device_id> devices(numDevices, 0);
|
||||||
|
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, numDevices*sizeof(cl_device_id), &devices[0], NULL);
|
||||||
|
test_error(error, "clGetContextInfo failed getting CL_CONTEXT_DEVICES");
|
||||||
|
|
||||||
|
device = devices[0];
|
||||||
|
return CL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cl_int get_first_device_address_bits(const cl_context context, cl_uint &device_address_space_size)
|
||||||
|
{
|
||||||
|
cl_device_id device;
|
||||||
|
cl_int error = get_first_device_id(context, device);
|
||||||
|
if (error != CL_SUCCESS)
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), &device_address_space_size, NULL);
|
||||||
|
test_error(error, "Unable to obtain device address bits");
|
||||||
|
|
||||||
|
if (device_address_space_size != 32 && device_address_space_size != 64)
|
||||||
|
{
|
||||||
|
log_error("ERROR: Unexpected number of device address bits: %u\n", device_address_space_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_offline_compiler_output(std::ifstream &ifs,
|
||||||
|
cl_context context,
|
||||||
|
const std::string &kernel,
|
||||||
|
const CompilationMode compilationMode,
|
||||||
|
const std::string &bOptions,
|
||||||
|
const std::string &kernelName)
|
||||||
|
{
|
||||||
|
std::string sourceFilename = gCompilationCachePath + slash + kernelName + ".cl";
|
||||||
|
|
||||||
|
// Get device CL_DEVICE_ADDRESS_BITS
|
||||||
|
cl_uint device_address_space_size = 0;
|
||||||
|
int error = get_first_device_address_bits(context, device_address_space_size);
|
||||||
|
if (error != CL_SUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
std::string outputFilename = gCompilationCachePath + slash + kernelName;
|
||||||
|
if (compilationMode == kSpir_v)
|
||||||
|
{
|
||||||
|
std::ostringstream extension;
|
||||||
|
extension << ".spv" << device_address_space_size;
|
||||||
|
outputFilename += extension.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to read cached output file when test is run with gCompilationCacheMode != kCacheModeOverwrite
|
||||||
|
ifs.open(outputFilename.c_str(), std::ios::binary);
|
||||||
|
|
||||||
|
if (gCompilationCacheMode == kCacheModeOverwrite || !ifs.good())
|
||||||
|
{
|
||||||
|
std::string file_type = get_offline_compilation_file_type_str(compilationMode);
|
||||||
|
|
||||||
|
if (gCompilationCacheMode == kCacheModeForceRead)
|
||||||
|
{
|
||||||
|
log_info("OfflineCompiler: can't open cached %s file: %s\n",
|
||||||
|
file_type.c_str(), outputFilename.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifs.close();
|
||||||
|
|
||||||
|
if (gCompilationCacheMode != kCacheModeOverwrite)
|
||||||
|
log_info("OfflineCompiler: can't find cached %s file: %s\n",
|
||||||
|
file_type.c_str(), outputFilename.c_str());
|
||||||
|
|
||||||
|
std::ofstream ofs(sourceFilename.c_str(), std::ios::binary);
|
||||||
|
if (!ofs.good())
|
||||||
|
{
|
||||||
|
log_info("OfflineCompiler: can't create source file: %s\n", sourceFilename.c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write source to input file
|
||||||
|
ofs.write(kernel.c_str(), kernel.size());
|
||||||
|
ofs.close();
|
||||||
|
|
||||||
|
error = invoke_offline_compiler(context, device_address_space_size, compilationMode,
|
||||||
|
bOptions, sourceFilename, outputFilename);
|
||||||
|
if (error != CL_SUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
// read output file
|
// read output file
|
||||||
ifs.open(outputFilename.c_str(), std::ios::binary);
|
ifs.open(outputFilename.c_str(), std::ios::binary);
|
||||||
if (!ifs.good())
|
if (!ifs.good())
|
||||||
@@ -419,6 +439,31 @@ static int create_single_kernel_helper_create_program(cl_context context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create_single_kernel_helper_create_program_offline(cl_context context,
|
||||||
|
cl_program *outProgram,
|
||||||
|
unsigned int numKernelLines,
|
||||||
|
const char *const *kernelProgram,
|
||||||
|
const char *buildOptions,
|
||||||
|
CompilationMode compilationMode)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
std::string kernel = get_kernel_content(numKernelLines, kernelProgram);
|
||||||
|
std::string kernelName = get_kernel_name(kernel);
|
||||||
|
|
||||||
|
// set build options
|
||||||
|
std::string bOptions;
|
||||||
|
bOptions += buildOptions ? std::string(buildOptions) : "";
|
||||||
|
|
||||||
|
kernelName = add_build_options(kernelName, buildOptions);
|
||||||
|
|
||||||
|
std::ifstream ifs;
|
||||||
|
error = get_offline_compiler_output(ifs, context, kernel, compilationMode, bOptions, kernelName);
|
||||||
|
if (error != CL_SUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
ifs.seekg(0, ifs.end);
|
ifs.seekg(0, ifs.end);
|
||||||
int length = ifs.tellg();
|
int length = ifs.tellg();
|
||||||
ifs.seekg(0, ifs.beg);
|
ifs.seekg(0, ifs.beg);
|
||||||
@@ -465,9 +510,21 @@ static int create_single_kernel_helper_create_program(cl_context context,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CL_SUCCESS;
|
||||||
}
|
}
|
||||||
else // compilationMode == kOnline
|
|
||||||
|
static int create_single_kernel_helper_create_program(cl_context context,
|
||||||
|
cl_program *outProgram,
|
||||||
|
unsigned int numKernelLines,
|
||||||
|
const char **kernelProgram,
|
||||||
|
const char *buildOptions,
|
||||||
|
CompilationMode compilationMode)
|
||||||
{
|
{
|
||||||
|
if (compilationMode == kOnline)
|
||||||
|
{
|
||||||
|
int error = CL_SUCCESS;
|
||||||
|
|
||||||
/* Create the program object from source */
|
/* Create the program object from source */
|
||||||
*outProgram = clCreateProgramWithSource(context, numKernelLines, kernelProgram, NULL, &error);
|
*outProgram = clCreateProgramWithSource(context, numKernelLines, kernelProgram, NULL, &error);
|
||||||
if (*outProgram == NULL || error != CL_SUCCESS)
|
if (*outProgram == NULL || error != CL_SUCCESS)
|
||||||
@@ -475,8 +532,13 @@ static int create_single_kernel_helper_create_program(cl_context context,
|
|||||||
print_error(error, "clCreateProgramWithSource failed");
|
print_error(error, "clCreateProgramWithSource failed");
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
return CL_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return create_single_kernel_helper_create_program_offline(context, outProgram, numKernelLines,
|
||||||
|
kernelProgram, buildOptions, compilationMode);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_single_kernel_helper_create_program(cl_context context,
|
int create_single_kernel_helper_create_program(cl_context context,
|
||||||
|
|||||||
Reference in New Issue
Block a user