Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor OpenCL integration using maintained OpenCL C++ interface #60

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions SuperBuild.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ set(Autoscoper_DEPENDENCIES
GLEW
TIFF
)
if(Autoscoper_RENDERING_BACKEND STREQUAL "OpenCL")
list(APPEND Autoscoper_DEPENDENCIES
OpenCL-CLHPP
OpenCL-ICD-Loader
)
endif()

set(proj ${SUPERBUILD_TOPLEVEL_PROJECT})

Expand Down
68 changes: 68 additions & 0 deletions Superbuild/External_OpenCL-CLHPP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

set(proj OpenCL-CLHPP)

set(${proj}_DEPENDENCIES "OpenCL-Headers")

# Include dependent projects if any
ExternalProject_Include_Dependencies(${proj} PROJECT_VAR proj DEPENDS_VAR ${proj}_DEPENDENCIES)

if(Autoscoper_USE_SYSTEM_${proj})
message(FATAL_ERROR "Enabling Autoscoper_USE_SYSTEM_${proj} is not supported !")
endif()

# Sanity checks
if(DEFINED OpenCLHeadersCpp_DIR AND NOT EXISTS ${OpenCLHeadersCpp_DIR})
message(FATAL_ERROR "OpenCLHeadersCpp_DIR variable is defined but corresponds to nonexistent directory")
endif()

if(NOT DEFINED OpenCLHeadersCpp_DIR AND NOT Autoscoper_USE_SYSTEM_${proj})

set(EP_SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj})
set(EP_BINARY_DIR ${CMAKE_BINARY_DIR}/${proj}-build)

set(EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS)

if(NOT CMAKE_CONFIGURATION_TYPES)
list(APPEND EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
)
endif()

ExternalProject_Add(${proj}
${${proj}_EP_ARGS}
GIT_REPOSITORY https://github.com/KhronosGroup/OpenCL-CLHPP.git
GIT_TAG v2022.09.30
SOURCE_DIR ${EP_SOURCE_DIR}
BINARY_DIR ${EP_BINARY_DIR}
INSTALL_DIR ${EP_INSTALL_DIR}
CMAKE_CACHE_ARGS
# Compiler settings
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
-DCMAKE_CXX_EXTENSIONS:BOOL=${CMAKE_CXX_EXTENSIONS}
-DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD}
-DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED}
# Options
-DBUILD_DOCS:BOOL=OFF
-DBUILD_EXAMPLES:BOOL=OFF
-DBUILD_TESTING:BOOL=OFF
-DOPENCL_CLHPP_BUILD_TESTING:BOOL=OFF
# Install directories
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
# Dependencies
-DOpenCLHeaders_DIR:PATH=${OpenCLHeaders_DIR}
${EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS}
INSTALL_COMMAND ""
DEPENDS
${${proj}_DEPENDENCIES}
)
set(OpenCLHeadersCpp_DIR ${EP_BINARY_DIR}/OpenCLHeadersCpp)

endif()

mark_as_superbuild(
VARS
OpenCLHeadersCpp_DIR:PATH
)

ExternalProject_Message(${proj} "OpenCLHeadersCpp_DIR:${OpenCLHeadersCpp_DIR}")
60 changes: 60 additions & 0 deletions Superbuild/External_OpenCL-Headers.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

set(proj OpenCL-Headers)

set(${proj}_DEPENDENCIES "")

# Include dependent projects if any
ExternalProject_Include_Dependencies(${proj} PROJECT_VAR proj DEPENDS_VAR ${proj}_DEPENDENCIES)

if(Autoscoper_USE_SYSTEM_${proj})
message(FATAL_ERROR "Enabling Autoscoper_USE_SYSTEM_${proj} is not supported !")
endif()

# Sanity checks
if(DEFINED OpenCLHeaders_DIR AND NOT EXISTS ${OpenCLHeaders_DIR})
message(FATAL_ERROR "OpenCLHeaders_DIR variable is defined but corresponds to nonexistent directory")
endif()

if(NOT DEFINED OpenCLHeaders_DIR AND NOT Autoscoper_USE_SYSTEM_${proj})

set(EP_SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj})
set(EP_BINARY_DIR ${CMAKE_BINARY_DIR}/${proj}-build)

set(EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS)

if(NOT CMAKE_CONFIGURATION_TYPES)
list(APPEND EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
)
endif()

ExternalProject_Add(${proj}
${${proj}_EP_ARGS}
GIT_REPOSITORY https://github.com/KhronosGroup/OpenCL-Headers.git
GIT_TAG v2022.09.30
SOURCE_DIR ${EP_SOURCE_DIR}
BINARY_DIR ${EP_BINARY_DIR}
INSTALL_DIR ${EP_INSTALL_DIR}
CMAKE_CACHE_ARGS
# Compiler settings
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
# Options
-DBUILD_TESTING:BOOL=OFF
-DOPENCL_HEADERS_BUILD_TESTING:BOOL=OFF
# Install directories
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
${EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS}
INSTALL_COMMAND ""
DEPENDS
${${proj}_DEPENDENCIES}
)
set(OpenCLHeaders_DIR ${EP_BINARY_DIR}/OpenCLHeaders)

endif()

mark_as_superbuild(
VARS
OpenCLHeaders_DIR:PATH
)

ExternalProject_Message(${proj} "OpenCLHeaders_DIR:${OpenCLHeaders_DIR}")
64 changes: 64 additions & 0 deletions Superbuild/External_OpenCL-ICD-Loader.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

set(proj OpenCL-ICD-Loader)

set(${proj}_DEPENDENCIES
OpenCL-Headers
)

# Include dependent projects if any
ExternalProject_Include_Dependencies(${proj} PROJECT_VAR proj DEPENDS_VAR ${proj}_DEPENDENCIES)

if(Autoscoper_USE_SYSTEM_${proj})
message(FATAL_ERROR "Enabling Autoscoper_USE_SYSTEM_${proj} is not supported !")
endif()

# Sanity checks
if(DEFINED OpenCLICDLoader_DIR AND NOT EXISTS ${OpenCLICDLoader_DIR})
message(FATAL_ERROR "OpenCLICDLoader_DIR variable is defined but corresponds to nonexistent directory")
endif()

if(NOT DEFINED OpenCLICDLoader_DIR AND NOT Autoscoper_USE_SYSTEM_${proj})

set(EP_SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj})
set(EP_BINARY_DIR ${CMAKE_BINARY_DIR}/${proj}-build)

set(EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS)

if(NOT CMAKE_CONFIGURATION_TYPES)
list(APPEND EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
)
endif()

ExternalProject_Add(${proj}
${${proj}_EP_ARGS}
GIT_REPOSITORY https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
GIT_TAG v2022.09.30
SOURCE_DIR ${EP_SOURCE_DIR}
BINARY_DIR ${EP_BINARY_DIR}
INSTALL_DIR ${EP_INSTALL_DIR}
CMAKE_CACHE_ARGS
# Compiler settings
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
# Options
-DBUILD_TESTING:BOOL=OFF
-DOPENCL_ICD_LOADER_BUILD_TESTING:BOOL=OFF
# Install directories
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
# Depdendencies
-DOpenCLHeaders_DIR:PATH=${OpenCLHeaders_DIR}
${EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS}
INSTALL_COMMAND ""
DEPENDS
${${proj}_DEPENDENCIES}
)
set(OpenCLICDLoader_DIR ${EP_BINARY_DIR}/OpenCLHeaders)

endif()

mark_as_superbuild(
VARS
OpenCLICDLoader_DIR:PATH
)

ExternalProject_Message(${proj} "OpenCLICDLoader_DIR:${OpenCLICDLoader_DIR}")
12 changes: 10 additions & 2 deletions autoscoper/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,19 @@ if(Autoscoper_RENDERING_BACKEND STREQUAL "CUDA")
)
elseif(Autoscoper_RENDERING_BACKEND STREQUAL "OpenCL")
find_package(OpenCL ${Autoscoper_OpenCL_MINIMUM_REQUIRED_VERSION} REQUIRED)
target_include_directories(autoscoper PUBLIC ${OPENCL_INCLUDE_DIRS})
find_package(OpenCLHeaders REQUIRED)
find_package(OpenCLHeadersCpp REQUIRED)
#target_include_directories(autoscoper PUBLIC ${OPENCL_INCLUDE_DIRS})
set(GPU_LIBRARIES
${OpenCL_LIBRARIES}
OpenCL::HeadersCpp
)
target_compile_definitions(autoscoper PRIVATE
CL_TARGET_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION}
CL_HPP_TARGET_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION}
CL_HPP_MINIMUM_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION}
CL_HPP_ENABLE_EXCEPTIONS
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They may want to disable this and only rely on error checking (at least while we are refactoring the Autoscoper API)

)
target_compile_definitions(autoscoper PRIVATE CL_TARGET_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION})
else()
message(FATAL_ERROR "Setting Autoscoper_RENDERING_BACKEND to '${Autoscoper_RENDERING_BACKEND}' is not supported")
endif()
Expand Down
14 changes: 12 additions & 2 deletions libautoscoper/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,21 @@ if(Autoscoper_RENDERING_BACKEND STREQUAL "CUDA")
target_include_directories(libautoscoper PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/cuda/cutil)
elseif(Autoscoper_RENDERING_BACKEND STREQUAL "OpenCL")
find_package(OpenCL ${Autoscoper_OpenCL_MINIMUM_REQUIRED_VERSION} REQUIRED)
find_package(OpenCLHeaders REQUIRED)
find_package(OpenCLHeadersCpp REQUIRED)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/gpu/opencl/CMakeLists.txt)
add_library(libautoscoper STATIC ${libautoscoper_SOURCES} ${libautoscoper_HEADERS} ${opencl_SOURCES} ${opencl_HEADERS})
target_include_directories(libautoscoper PUBLIC ${OpenCL_INCLUDE_DIRS})
#target_include_directories(libautoscoper PUBLIC ${OpenCL_INCLUDE_DIRS})
add_dependencies(libautoscoper ${SHADER_TO_HEADER})
target_compile_definitions(libautoscoper PRIVATE CL_TARGET_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION})
target_link_libraries(libautoscoper PUBLIC
OpenCL::HeadersCpp
)
target_compile_definitions(libautoscoper PRIVATE
CL_TARGET_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION}
CL_HPP_TARGET_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION}
CL_HPP_MINIMUM_OPENCL_VERSION=${Autoscoper_CL_TARGET_OPENCL_VERSION}
CL_HPP_ENABLE_EXCEPTIONS
)
else()
message(FATAL_ERROR "Setting Autoscoper_RENDERING_BACKEND to '${Autoscoper_RENDERING_BACKEND}' is not supported")
endif()
Expand Down
44 changes: 13 additions & 31 deletions libautoscoper/src/gpu/opencl/OpenCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ static const char* opencl_error(cl_int err)
case CL_INVALID_COMPILER_OPTIONS: return "CL_INVALID_COMPILER_OPTIONS";
case CL_INVALID_LINKER_OPTIONS: return "CL_INVALID_LINKER_OPTIONS";
case CL_INVALID_DEVICE_PARTITION_COUNT: return "CL_INVALID_DEVICE_PARTITION_COUNT";
#endif
#ifdef CL_VERSION_2_0
case CL_INVALID_PIPE_SIZE: return "CL_INVALID_PIPE_SIZE";
case CL_INVALID_DEVICE_QUEUE: return "CL_INVALID_DEVICE_QUEUE";
#endif
#ifdef CL_VERSION_2_2
case CL_INVALID_SPEC_ID: return "CL_INVALID_SPEC_ID";
case CL_MAX_SIZE_RESTRICTION_EXCEEDED: return "CL_MAX_SIZE_RESTRICTION_EXCEEDED";
#endif
default: return "Unknown";
}
Expand Down Expand Up @@ -693,7 +701,7 @@ cl_int opencl_global_context()
return CL_SUCCESS;
}

Kernel::Kernel(cl_program program, const char* func)
Kernel::Kernel(const cl::Program& program, const char* func)
{
err_ = opencl_global_context();
CHECK_CL
Expand Down Expand Up @@ -873,44 +881,18 @@ void Kernel::setArg(cl_uint i, size_t size, const void* value)
CHECK_CL
}

Program::Program() { compiled_ = false; }

Kernel* Program::compile(const char* code, const char* func)
{
if (!compiled_)
{
err_ = opencl_global_context();
CHECK_CL

size_t len = strlen(code);
program_ = clCreateProgramWithSource(context_, 1, &code, &len, &err_);
CHECK_CL

err_ = clBuildProgram(program_, 1, devices_, NULL, NULL, NULL);
if (err_ == CL_BUILD_PROGRAM_FAILURE) {
size_t log_size;
err_ = clGetProgramBuildInfo(
program_, devices_[0], CL_PROGRAM_BUILD_LOG,
0, NULL, &log_size);
CHECK_CL
char* build_log = (char*)malloc(log_size+1);
if (!build_log) ERROR("malloc for build log");
err_ = clGetProgramBuildInfo(
program_, devices_[0], CL_PROGRAM_BUILD_LOG,
log_size, build_log, NULL);
CHECK_CL
build_log[log_size] = '\0';
if (program_.compile(code) != CL_SUCCESS)
{
cerr << "OpenCL build failure for kernel function '" << func
<< "':\n" << build_log << endl;
free(build_log);
<< "':\n" << program_.getBuildInfo<CL_PROGRAM_BUILD_LOG>() << endl;
exit(1);
} else {
CHECK_CL
}

compiled_ = true;
}

return new Kernel(program_, func);
}

Expand Down Expand Up @@ -986,7 +968,7 @@ void Buffer::fill(const float val) const
#endif
}

GLBuffer::GLBuffer(GLuint pbo, cl_mem_flags access)
GLBuffer::GLBuffer(cl_GLuint pbo, cl_mem_flags access)
{
err_ = opencl_global_context();
CHECK_CL
Expand Down
19 changes: 5 additions & 14 deletions libautoscoper/src/gpu/opencl/OpenCL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,11 @@
#ifndef XROMM_HPP
#define XROMM_HPP

#include <CL/opencl.hpp>

#include <iostream>
#include <vector>

#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/opencl.h>
#include <OpenGL/OpenGL.h>
#else
#if defined(_WIN32)
#include <windows.h>
#endif
#include <CL/opencl.h>
#include <GL/gl.h>
#endif

namespace xromm { namespace gpu {

void opencl_global_gl_context();
Expand All @@ -74,7 +65,7 @@ class Image;
class Kernel
{
public:
Kernel(cl_program program, const char* func);
Kernel(const cl::Program& program, const char* func);
void reset();

static size_t getLocalMemSize();
Expand Down Expand Up @@ -114,7 +105,7 @@ class Program
Program();
Kernel* compile(const char* code, const char* func);
protected:
cl_program program_;
cl::Program program_;
bool compiled_;
};

Expand All @@ -140,7 +131,7 @@ class Buffer
class GLBuffer
{
public:
GLBuffer(GLuint pbo, cl_mem_flags access=CL_MEM_READ_WRITE);
GLBuffer(cl_GLuint pbo, cl_mem_flags access=CL_MEM_READ_WRITE);
~GLBuffer();
friend class Kernel;
protected:
Expand Down