Commit 16ba8a21 authored by schultezub's avatar schultezub
Browse files

started implementing an own OpenCL wrapper library

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@236 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 7fa2684d
......@@ -17,6 +17,7 @@ OPTION(TUMVIS_BUILD_APPLICATION "Build TUMVis Application"
OPTION(TUMVIS_BUILD_CORE "Build TUMVis Core" ON )
OPTION(TUMVIS_BUILD_MODULES "Build TUMVis Modules" ON )
OPTION(TUMVIS_BUILD_LIB_TGT "Build TGT Library" ON )
OPTION(TUMVIS_BUILD_LIB_CLLIB "Build CLLib Library" ON )
IF(WIN32)
OPTION(TUMVIS_COPY_EXTERNAL_DLLS "Copy external DLLs to bin directory?" ON )
......@@ -34,6 +35,10 @@ IF(TUMVIS_BUILD_LIB_TGT)
ADD_SUBDIRECTORY(ext/tgt)
ENDIF()
IF(TUMVIS_BUILD_LIB_CLLIB)
ADD_SUBDIRECTORY(ext/cllib)
ENDIF()
IF(TUMVIS_BUILD_CORE)
ADD_SUBDIRECTORY(core)
ENDIF()
......
......@@ -45,4 +45,4 @@ ADD_EXECUTABLE(tumvis-application
)
ADD_DEFINITIONS(${TUMVIS_DEFINITIONS} ${QT_DEFINITIONS})
INCLUDE_DIRECTORIES(${TUMVIS_INCLUDE_DIRECTORIES})
TARGET_LINK_LIBRARIES(tumvis-application tumvis-core tumvis-modules tgt ${TUMVIS_EXTERNAL_LIBRARIES} ${QT_LIBRARIES})
TARGET_LINK_LIBRARIES(tumvis-application tumvis-core tumvis-modules tgt cllib ${TUMVIS_EXTERNAL_LIBRARIES} ${QT_LIBRARIES})
IF(WIN32)
FIND_PATH(
OPENCL_SDK
NAMES CL/cl.h OpenCL/common/inc/CL/cl.h
DOC "Path to the OpenCL SDK (Nvidia GPU Computing / AMD APP SDK)"
)
IF(NOT EXISTS ${OPENCL_SDK})
MESSAGE(FATAL_ERROR "OpenCL SDK (Nvidia GPU Computing / AMD APP SDK) not found! Please set Option 'OPENCL_SDK'!")
ENDIF()
FIND_PATH(
OPENCL_INCLUDE_DIR
NAMES CL/cl.h
PATHS ${OPENCL_SDK}
PATH_SUFFIXES include OpenCL/common/inc
)
IF(TUMVIS_WIN32)
FIND_LIBRARY(
OPENCL_LIBRARY
NAMES OpenCL.lib
PATHS ${OPENCL_SDK}
PATH_SUFFIXES lib/Win32 OpenCL/common/lib/Win32
)
ELSEIF(TUMVIS_WIN64)
FIND_LIBRARY(
OPENCL_LIBRARY
NAMES OpenCL.lib
PATHS ${OPENCL_SDK}
PATH_SUFFIXES lib/x64 OpenCL/common/lib/x64
)
ENDIF()
ELSEIF(UNIX)
FIND_PATH(
OPENCL_INCLUDE_DIR
NAMES CL/cl.h
PATHS ${OPENCL_INCLUDE_DIR}
${OPENCL_DIR}/include
${OPENCL_DIR}/OpenCL/common/inc
$ENV{OPENCL_INCLUDE_DIR}
$ENV{OPENCL_DIR}/include
$ENV{OPENCL_DIR}/OpenCL/common/inc
/usr/local/cuda/include
/usr/local/include
/usr/include
)
FIND_LIBRARY(
OPENCL_LIBRARY
NAMES OpenCL
PATHS ${OPENCL_LIBRARY_DIR}
${OPENCL_DIR}/lib
${OPENCL_DIR}/lib/x86
$ENV{OPENCL_LIBRARY_DIR}
$ENV{OPENCL_DIR}/lib
$ENV{OPENCL_DIR}/lib/x86
/usr/local/lib64
/usr/local/lib
/usr/lib64
/usr/lib
)
ENDIF()
IF(OPENCL_INCLUDE_DIR AND OPENCL_LIBRARY)
SET(OPENCL_FOUND TRUE)
MARK_AS_ADVANCED(OPENCL_INCLUDE_DIR OPENCL_LIBRARY)
ELSE()
MESSAGE(FATAL_ERROR "OpenCL library not found (OPENCL_INCLUDE_DIR and/or OPENCL_LIBRARY missing)!")
MARK_AS_ADVANCED(CLEAR OPENCL_INCLUDE_DIR OPENCL_LIBRARY)
ENDIF()
......@@ -175,6 +175,15 @@ ELSE(TBB_FOUND)
MESSAGE(FATAL_ERROR "TBB not found!")
ENDIF(TBB_FOUND)
# OpenCL
FIND_PACKAGE(CL REQUIRED)
MESSAGE(STATUS "* Found OpenCL")
LIST(APPEND TUMVIS_INCLUDE_DIRECTORIES ${OPENCL_INCLUDE_DIR})
LIST(APPEND TUMVIS_EXTERNAL_LIBRARIES ${OPENCL_LIBRARY})
IF (OPENCL_FOUND)
ELSE(OPENCL_FOUND)
MESSAGE(FATAL_ERROR "OpenCL not found!")
ENDIF(OPENCL_FOUND)
SET(COMMONCONF_PROCESSED TRUE)
ENDIF(NOT COMMONCONF_PROCESSED)
......@@ -50,4 +50,4 @@ ADD_LIBRARY(tumvis-core
)
ADD_DEFINITIONS(${TUMVIS_DEFINITIONS} ${QT_DEFINITIONS})
INCLUDE_DIRECTORIES(${TUMVIS_INCLUDE_DIRECTORIES})
TARGET_LINK_LIBRARIES(tumvis-core tgt ${TUMVIS_EXTERNAL_LIBRARIES} ${QT_LIBRARIES})
TARGET_LINK_LIBRARIES(tumvis-core tgt cllib ${TUMVIS_EXTERNAL_LIBRARIES} ${QT_LIBRARIES})
......@@ -46,8 +46,8 @@ namespace TUMVis {
RaycastingProcessor::RaycastingProcessor(GenericProperty<tgt::ivec2>& renderTargetSize, const std::string& fragmentShaderFileName, bool bindEntryExitDepthTextures)
: VisualizationProcessor(renderTargetSize)
, _sourceImageID("sourceImageID", "Input Image", "")
, _entryImageID("entryImageID", "Output Entry Points Image", "")
, _exitImageID("exitImageID", "Output Exit Points Image", "")
, _entryImageID("entryImageID", "Input Entry Points Image", "")
, _exitImageID("exitImageID", "Input Exit Points Image", "")
, _camera("camera", "Camera")
, _transferFunction("transferFunction", "Transfer Function", new SimpleTransferFunction(256))
, _samplingStepSize("samplingStepSize", "Sampling Step Size", .1f, 0.001f, 1.f)
......
......@@ -730,7 +730,11 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE = C:/Users/Christian/Documents/TUM/code/tumvis/ext
EXCLUDE = C:/Users/Christian/Documents/TUM/code/tumvis/ext/tbb \
C:/Users/Christian/Documents/TUM/code/tumvis/ext/boost \
C:/Users/Christian/Documents/TUM/code/tumvis/ext/glew \
C:/Users/Christian/Documents/TUM/code/tumvis/ext/glut \
C:/Users/Christian/Documents/TUM/code/tumvis/ext/sigslot
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
......
......@@ -4797,7 +4797,7 @@ public:
}
cl_int enqueueNativeKernel(
void (CL_CALLBACK *userFptr)(void *),
void (*userFptr)(void *),
std::pair<void*, ::size_t> args,
const VECTOR_CLASS<Memory>* mem_objects = NULL,
const VECTOR_CLASS<const void*>* mem_locs = NULL,
......
################################################################################
# Project file for the cllib library
################################################################################
PROJECT(cllib)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0 FATAL_ERROR)
INCLUDE(../../cmake/commonconf.cmake)
MESSAGE(STATUS "Configuring cllib Library")
# headers
FILE(GLOB CLLIB_HEADERS *.h CL/*.hpp)
# sources
FILE(GLOB CLLIB_SOURCES *.cpp)
################################################################################
# define library target
################################################################################
ADD_LIBRARY(cllib ${CLLIB_SOURCES} ${CLLIB_HEADERS})
ADD_DEFINITIONS(${TUMVIS_DEFINITIONS} ${TUMVIS_MODULE_DEFINITIONS})
IF(TUMVIS_SHARED_LIBS AND MSVC)
ADD_DEFINITIONS("-DCLLIB_BUILD_DLL")
ENDIF()
INCLUDE_DIRECTORIES(${TUMVIS_INCLUDE_DIRECTORIES} ${TUMVIS_MODULE_INCLUDE_DIRECTORIES})
TARGET_LINK_LIBRARIES(cllib ${TUMVIS_EXTERNAL_LIBRARIES})
################################################################################
# deployment
################################################################################
IF(TUMVIS_ADD_INSTALL_TARGET)
INSTALL(TARGETS cllib
RUNTIME DESTINATION .
)
ENDIF()
#include "cldevicemanager.h"
#include "tgt/logmanager.h"
namespace cllib {
const std::string DeviceManager::loggerCat_ = "cllib.DeviceManager";
DeviceManager::DeviceManager() {
cl_uint numPlatforms;
LCL_ERROR(clGetPlatformIDs(0, 0, &numPlatforms));
LINFO("Number of platformIds: " << numPlatforms);
cl_platform_id* platformIds = new cl_platform_id[numPlatforms];
LCL_ERROR(clGetPlatformIDs(numPlatforms, platformIds, 0));
for(cl_uint i=0; i<numPlatforms; ++i) {
_platforms.push_back(new Platform(platformIds[i]));
}
delete[] platformIds;
}
DeviceManager::~DeviceManager() {
for (std::vector<Platform*>::iterator it = _platforms.begin(); it != _platforms.end(); ++it)
delete *it;
}
}
\ No newline at end of file
#ifndef CLDEVICEMANAGER_H__
#define CLDEVICEMANAGER_H__
#include "tgt/tgt_gl.h"
#include "tgt/manager.h"
#include "tgt/singleton.h"
#include "CL/cl.hpp"
#include "cllib/platform.h"
#include "cllib/device.h"
#include <string>
namespace cllib {
class DeviceManager {
public:
DeviceManager();
~DeviceManager();
private:
std::vector<Platform*> _platforms;
static const std::string loggerCat_;
};
}
#endif // CLDEVICEMANAGER_H__
#include "cllib.h"
#include "tgt/logmanager.h"
#include "cllib/stringutils.h"
namespace cllib {
std::string clErrorToString(cl_int err) {
std::string toReturn;
switch(err) {
case(CL_SUCCESS): toReturn = "CL_SUCCESS"; break;
case(CL_BUILD_PROGRAM_FAILURE): toReturn = "CL_BUILD_PROGRAM_FAILURE"; break;
case(CL_COMPILER_NOT_AVAILABLE): toReturn = "CL_COMPILER_NOT_AVAILABLE"; break;
case(CL_DEVICE_NOT_AVAILABLE): toReturn = "CL_DEVICE_NOT_AVAILABLE"; break;
case(CL_DEVICE_NOT_FOUND): toReturn = "CL_DEVICE_NOT_FOUND"; break;
case(CL_IMAGE_FORMAT_MISMATCH): toReturn = "CL_IMAGE_FORMAT_MISMATCH"; break;
case(CL_IMAGE_FORMAT_NOT_SUPPORTED): toReturn = "CL_IMAGE_FORMAT_NOT_SUPPORTED"; break;
case(CL_INVALID_ARG_INDEX): toReturn = "CL_INVALID_ARG_INDEX"; break;
case(CL_INVALID_ARG_SIZE): toReturn = "CL_INVALID_ARG_SIZE"; break;
case(CL_INVALID_ARG_VALUE): toReturn = "CL_INVALID_ARG_VALUE"; break;
case(CL_INVALID_BINARY): toReturn = "CL_INVALID_BINARY"; break;
case(CL_INVALID_BUFFER_SIZE): toReturn = "CL_INVALID_BUFFER_SIZE"; break;
case(CL_INVALID_BUILD_OPTIONS): toReturn = "CL_INVALID_BUILD_OPTIONS"; break;
case(CL_INVALID_COMMAND_QUEUE): toReturn = "CL_INVALID_COMMAND_QUEUE"; break;
case(CL_INVALID_CONTEXT): toReturn = "CL_INVALID_CONTEXT"; break;
case(CL_INVALID_DEVICE): toReturn = "CL_INVALID_DEVICE"; break;
case(CL_INVALID_DEVICE_TYPE): toReturn = "CL_INVALID_DEVICE_TYPE"; break;
case(CL_INVALID_EVENT): toReturn = "CL_INVALID_EVENT"; break;
case(CL_INVALID_EVENT_WAIT_LIST): toReturn = "CL_INVALID_EVENT_WAIT_LIST"; break;
case(CL_INVALID_GLOBAL_OFFSET): toReturn = "CL_INVALID_GLOBAL_OFFSET"; break;
case(CL_INVALID_GLOBAL_WORK_SIZE): toReturn = "CL_INVALID_GLOBAL_WORK_SIZE"; break;
case(CL_INVALID_GL_OBJECT): toReturn = "CL_INVALID_GL_OBJECT"; break;
case(CL_INVALID_HOST_PTR): toReturn = "CL_INVALID_HOST_PTR"; break;
case(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR): toReturn = "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; break;
case(CL_INVALID_IMAGE_SIZE): toReturn = "CL_INVALID_IMAGE_SIZE"; break;
case(CL_INVALID_KERNEL): toReturn = "CL_INVALID_KERNEL"; break;
case(CL_INVALID_KERNEL_ARGS): toReturn = "CL_INVALID_KERNEL_ARGS"; break;
case(CL_INVALID_KERNEL_DEFINITION): toReturn = "CL_INVALID_KERNEL_DEFINITION"; break;
case(CL_INVALID_KERNEL_NAME): toReturn = "CL_INVALID_KERNEL_NAME"; break;
case(CL_INVALID_MEM_OBJECT): toReturn = "CL_INVALID_MEM_OBJECT"; break;
case(CL_INVALID_MIP_LEVEL): toReturn = "CL_INVALID_MIP_LEVEL"; break;
case(CL_INVALID_OPERATION): toReturn = "CL_INVALID_OPERATION"; break;
case(CL_INVALID_PLATFORM): toReturn = "CL_INVALID_PLATFORM"; break;
case(CL_INVALID_PROGRAM): toReturn = "CL_INVALID_PROGRAM"; break;
case(CL_INVALID_PROGRAM_EXECUTABLE): toReturn = "CL_INVALID_PROGRAM_EXECUTABLE"; break;
case(CL_INVALID_QUEUE_PROPERTIES): toReturn = "CL_INVALID_QUEUE_PROPERTIES"; break;
case(CL_INVALID_SAMPLER): toReturn = "CL_INVALID_SAMPLER"; break;
case(CL_INVALID_VALUE): toReturn = "CL_INVALID_VALUE"; break;
case(CL_INVALID_WORK_DIMENSION): toReturn = "CL_INVALID_WORK_DIMENSION"; break;
case(CL_INVALID_WORK_GROUP_SIZE): toReturn = "CL_INVALID_WORK_GROUP_SIZE"; break;
case(CL_INVALID_WORK_ITEM_SIZE): toReturn = "CL_INVALID_WORK_ITEM_SIZE"; break;
case(CL_MAP_FAILURE): toReturn = "CL_MAP_FAILURE"; break;
case(CL_MEM_COPY_OVERLAP): toReturn = "CL_MEM_COPY_OVERLAP"; break;
case(CL_MEM_OBJECT_ALLOCATION_FAILURE): toReturn = "CL_MEM_OBJECT_ALLOCATION_FAILURE"; break;
case(CL_OUT_OF_HOST_MEMORY): toReturn = "CL_OUT_OF_HOST_MEMORY"; break;
case(CL_OUT_OF_RESOURCES): toReturn = "CL_OUT_OF_RESOURCES"; break;
case(CL_PROFILING_INFO_NOT_AVAILABLE): toReturn = "CL_PROFILING_INFO_NOT_AVAILABLE"; break;
default:
toReturn = "unknown";
}
std::ostringstream tmp;
tmp << toReturn << " (" << (int)err << ")";
return tmp.str();
}
cl_int _lCLError(cl_int err, int line, const char* file) {
if (err != CL_SUCCESS) {
std::ostringstream tmp2, loggerCat;
if (file) {
tmp2 << " File: " << file << "@" << line;
loggerCat << "cl-error:" << file << ':' << line;
}
LogMgr.log(loggerCat.str(), tgt::Error, clErrorToString(err), tmp2.str());
}
return err;
}
// ================================================================================================
ClVersion::ClVersion(int major /*= 0*/, int minor /*= 0*/)
: major_(major)
, minor_(minor)
{
}
ClVersion::ClVersion(const std::string& versionString)
: major_(-1)
, minor_(-1)
{
//remove "OpenCL ":
std::string str = versionString.substr(7);
//ignore vendor specific part of the string:
size_t spacePos = str.find_first_of(" ");
if (spacePos != std::string::npos)
str = str.substr(0, spacePos);
else
str = str;
//explode version string with delimiter ".":
std::vector<std::string> exploded = StringUtils::split(str, ".");
// parse numbers
if (exploded.size() < 2) {
LERRORC("cllib.ClVersion", "Version string too short to parse!");
}
else {
major_ = StringUtils::fromString<int>(exploded[0]);
minor_ = StringUtils::fromString<int>(exploded[1]);
}
}
bool operator==(const ClVersion& x, const ClVersion& y) {
if ((x.major_ == y.major_) && (x.minor_ == y.minor_))
return true;
else
return false;
}
bool operator!=(const ClVersion& x, const ClVersion& y) {
if ((x.major_ != y.major_) || (x.minor_ != y.minor_))
return true;
else
return false;
}
bool operator<(const ClVersion& x, const ClVersion& y) {
if (x.major_ < y.major_)
return true;
else if (x.major_ == y.major_)
if (x.minor_ < y.minor_)
return true;
return false;
}
bool operator<=(const ClVersion& x, const ClVersion& y) {
if (x.major_ < y.major_)
return true;
else if (x.major_ == y.major_)
if (x.minor_ < y.minor_)
return true;
return false;
}
bool operator>(const ClVersion& x, const ClVersion& y) {
if (x.major_ > y.major_)
return true;
else if (x.major_ == y.major_)
if (x.minor_ > y.minor_)
return true;
return false;
}
bool operator>=(const ClVersion& x, const ClVersion& y) {
if (x.major_ > y.major_)
return true;
else if (x.major_ == y.major_)
if (x.minor_ > y.minor_)
return true;
return false;
}
std::ostream& operator<<(std::ostream& s, const ClVersion& v) {
if (v.major_ == -1)
return (s << "unknown");
else
return (s << v.major_ << "." << v.minor_);
}
}
#ifndef CLLIB_H__
#define CLLIB_H__
#include "tgt/tgt_gl.h"
#include "CL/cl.hpp"
#include <string>
namespace cllib {
/**
* Helper function to transform an OpenCL error code to a string.
* \param err OpenCL error code.
* \return String representation of the error code.
*/
std::string clErrorToString(cl_int err);
/**
* Helper function for debugging OpenCL errors.
* \param err OpenCL error code.
* \param line code line
* \param file code file
* \return err
*/
cl_int _lCLError(cl_int err, int line, const char* file);
#define LCL_ERROR(err) _lCLError(err, __LINE__, __FILE__)
/**
* Enum for OpenCL profile
*/
enum Profile {
FULL_PROFILE,
EMBEDDED_PROFILE,
UNKNOWN
};
/**
* Specifies the version of the platform OpenCL implementation.
*/
struct ClVersion {
/**
* Creates a ClVersion with given major and minor version.
* \param major major version
* \param minor minor version
*/
ClVersion(int major = 0, int minor = 0);
/**
* Creates a ClVersion from the given version string.
* \param versionString The CL_PLATFORM_VERSION string.
*/
ClVersion(const std::string& versionString);
int major_; ///< OpenCL major version
int minor_; ///< OpenCL minor version
friend bool operator==(const ClVersion& x, const ClVersion& y);
friend bool operator!=(const ClVersion& x, const ClVersion& y);
friend bool operator<(const ClVersion& x, const ClVersion& y);
friend bool operator<=(const ClVersion& x, const ClVersion& y);
friend bool operator>(const ClVersion& x, const ClVersion& y);
friend bool operator>=(const ClVersion& x, const ClVersion& y);
friend std::ostream& operator<<(std::ostream& s, const ClVersion& v);
};
}
#endif // CLLIB_H__
#include "device.h"
#include "tgt/logmanager.h"
#include "core/tools/stringutils.h"
namespace cllib {
const std::string Device::loggerCat_ = "cllib.Device";
Device::Device(cl_device_id id)
: _id(id)
{
// parse device profile
std::string profileString = getInfo<std::string>(CL_DEVICE_PROFILE);
if (profileString == "FULL_PROFILE")
_profile = FULL_PROFILE;
else if (profileString == "EMBEDDED_PROFILE") {
_profile = EMBEDDED_PROFILE;
LWARNING("Embedded profile!");
}
else {
LERROR("Unknown profile!");
}
// get other device information strings
_name = getInfo<std::string>(CL_DEVICE_NAME);
LINFO("Name: " << _name);
_vendor = getInfo<std::string>(CL_DEVICE_VENDOR);
_version = ClVersion(getInfo<std::string>(CL_DEVICE_VERSION));
//explode extensions string with space as delimiter and insert them into set:
std::vector<std::string> exploded = TUMVis::StringUtils::split(getInfo<std::string>(CL_DEVICE_EXTENSIONS), " ");
_extensions.insert(exploded.begin(), exploded.end());
_deviceType = getInfo<cl_device_type>(CL_DEVICE_TYPE);
_maxClockFrequency = getInfo<cl_uint>(CL_DEVICE_MAX_CLOCK_FREQUENCY);
_maxComputeUnits = getInfo<cl_uint>(CL_DEVICE_MAX_COMPUTE_UNITS);
LCL_ERROR(clGetDeviceInfo(_id, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(tgt::svec3), _maxWorkItemSizes.elem, 0));
_maxWorkGroupSize = getInfo<size_t>(CL_DEVICE_MAX_WORK_GROUP_SIZE);
_maxMemAllocSize = getInfo<cl_ulong>(CL_DEVICE_MAX_MEM_ALLOC_SIZE);
_globalMemSize = getInfo<cl_ulong>(CL_DEVICE_GLOBAL_MEM_SIZE);
_localMemSize = getInfo<cl_ulong>(CL_DEVICE_LOCAL_MEM_SIZE);
if(getInfo<cl_bool>(CL_DEVICE_IMAGE_SUPPORT)) {
maxImageSize2D_.x = static_cast<int>(getInfo<size_t>(CL_DEVICE_IMAGE2D_MAX_WIDTH));
maxImageSize2D_.y = static_cast<int>(getInfo<size_t>(CL_DEVICE_IMAGE2D_MAX_HEIGHT));
maxImageSize3D_.x = static_cast<int>(getInfo<size_t>(CL_DEVICE_IMAGE3D_MAX_WIDTH));
maxImageSize3D_.y = static_cast<int>(getInfo<size_t>(CL_DEVICE_IMAGE3D_MAX_HEIGHT));
maxImageSize3D_.z = static_cast<int>(getInfo<size_t>(CL_DEVICE_IMAGE3D_MAX_DEPTH));
}
//Log infos:
LINFO("Profile: " << profileString);
LINFO("Version: " << _version);
LINFO("Vendor: " << _vendor);
LINFO("Extensions:");
for(std::set<std::string>::const_iterator iter = _extensions.begin(); iter != _extensions.end(); ++iter) {
LINFO("> " << *iter);
}
if (!isExtensionSupported("cl_khr_gl_sharing"))
LWARNING("GL sharing is not supported.");
LINFO("Device Type: " << _deviceType);
LINFO("Max Clock Frequency: " << _maxClockFrequency);
LINFO("Max Compute Units: " << _maxComputeUnits);
LINFO("Max Work Item Sizes: " << _maxWorkItemSizes);
LINFO("Max Work Group Size: " << _maxWorkGroupSize);
LINFO("Max Mem Alloc Size: " << _maxMemAllocSize);
LINFO("Global Mem Size: " << _globalMemSize);
LINFO("Local Mem Size: " << _localMemSize);
}
Device::~Device() {
}
cllib::Profile Device::getProfile() const {
return _profile;
}
std::string Device::getName() const {
return _name;
}
std::string Device::getVendor() const {
return _vendor;
}
const std::set<std::string>& Device::getExtensions() const {
return _extensions;
}