Skip to content

Commit

Permalink
Different log when the OpenCL library cannot be loaded (#2840)
Browse files Browse the repository at this point in the history
* Different log when the OpenCL library cannot be loaded

Currently the only message is "0 platforms" which is misleading.

* Fix test

* Use extern to ensure only one copy of the variable exists (Wes review)

* Define opencl_loaded in openclwork.cpp to ensure it is initialized even if there are
no platform definitions
  • Loading branch information
guilhermelawless authored Jul 15, 2020
1 parent 1111079 commit 3fd6754
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 86 deletions.
2 changes: 1 addition & 1 deletion nano/core_test/work_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ TEST (work, opencl)
nano::logger_mt logger;
bool error (false);
nano::opencl_environment environment (error);
ASSERT_FALSE (error);
ASSERT_TRUE (!error || !nano::opencl_loaded);
if (!environment.platforms.empty () && !environment.platforms.begin ()->devices.empty ())
{
nano::opencl_config config (0, 0, 16 * 1024);
Expand Down
186 changes: 101 additions & 85 deletions nano/node/openclwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <string>
#include <vector>

bool nano::opencl_loaded{ false };

namespace
{
std::string opencl_program = R"%%%(
Expand Down Expand Up @@ -389,111 +391,125 @@ void printstate (blake2b_state * S)

nano::opencl_environment::opencl_environment (bool & error_a)
{
cl_uint platformIdCount = 0;
clGetPlatformIDs (0, nullptr, &platformIdCount);
std::vector<cl_platform_id> platformIds (platformIdCount);
clGetPlatformIDs (platformIdCount, platformIds.data (), nullptr);
for (auto i (platformIds.begin ()), n (platformIds.end ()); i != n; ++i)
if (nano::opencl_loaded)
{
nano::opencl_platform platform;
platform.platform = *i;
cl_uint deviceIdCount = 0;
clGetDeviceIDs (*i, CL_DEVICE_TYPE_ALL, 0, nullptr, &deviceIdCount);
std::vector<cl_device_id> deviceIds (deviceIdCount);
clGetDeviceIDs (*i, CL_DEVICE_TYPE_ALL, deviceIdCount, deviceIds.data (), nullptr);
for (auto j (deviceIds.begin ()), m (deviceIds.end ()); j != m; ++j)
cl_uint platformIdCount = 0;
clGetPlatformIDs (0, nullptr, &platformIdCount);
std::vector<cl_platform_id> platformIds (platformIdCount);
clGetPlatformIDs (platformIdCount, platformIds.data (), nullptr);
for (auto i (platformIds.begin ()), n (platformIds.end ()); i != n; ++i)
{
platform.devices.push_back (*j);
nano::opencl_platform platform;
platform.platform = *i;
cl_uint deviceIdCount = 0;
clGetDeviceIDs (*i, CL_DEVICE_TYPE_ALL, 0, nullptr, &deviceIdCount);
std::vector<cl_device_id> deviceIds (deviceIdCount);
clGetDeviceIDs (*i, CL_DEVICE_TYPE_ALL, deviceIdCount, deviceIds.data (), nullptr);
for (auto j (deviceIds.begin ()), m (deviceIds.end ()); j != m; ++j)
{
platform.devices.push_back (*j);
}
platforms.push_back (platform);
}
platforms.push_back (platform);
}
else
{
error_a = true;
}
}

void nano::opencl_environment::dump (std::ostream & stream)
{
auto index (0);
size_t device_count (0);
for (auto & i : platforms)
{
device_count += i.devices.size ();
}
stream << boost::str (boost::format ("OpenCL found %1% platforms and %2% devices\n") % platforms.size () % device_count);
for (auto i (platforms.begin ()), n (platforms.end ()); i != n; ++i, ++index)
if (nano::opencl_loaded)
{
std::vector<unsigned> queries = { CL_PLATFORM_PROFILE, CL_PLATFORM_VERSION, CL_PLATFORM_NAME, CL_PLATFORM_VENDOR, CL_PLATFORM_EXTENSIONS };
stream << "Platform: " << index << std::endl;
for (auto j (queries.begin ()), m (queries.end ()); j != m; ++j)
auto index (0);
size_t device_count (0);
for (auto & i : platforms)
{
size_t platformInfoCount = 0;
clGetPlatformInfo (i->platform, *j, 0, nullptr, &platformInfoCount);
std::vector<char> info (platformInfoCount);
clGetPlatformInfo (i->platform, *j, info.size (), info.data (), nullptr);
stream << info.data () << std::endl;
device_count += i.devices.size ();
}
for (auto j (i->devices.begin ()), m (i->devices.end ()); j != m; ++j)
stream << boost::str (boost::format ("OpenCL found %1% platforms and %2% devices\n") % platforms.size () % device_count);
for (auto i (platforms.begin ()), n (platforms.end ()); i != n; ++i, ++index)
{
std::vector<unsigned> queries = { CL_DEVICE_NAME, CL_DEVICE_VENDOR, CL_DEVICE_PROFILE };
stream << "Device: " << j - i->devices.begin () << std::endl;
for (auto k (queries.begin ()), o (queries.end ()); k != o; ++k)
std::vector<unsigned> queries = { CL_PLATFORM_PROFILE, CL_PLATFORM_VERSION, CL_PLATFORM_NAME, CL_PLATFORM_VENDOR, CL_PLATFORM_EXTENSIONS };
stream << "Platform: " << index << std::endl;
for (auto j (queries.begin ()), m (queries.end ()); j != m; ++j)
{
size_t platformInfoCount = 0;
clGetDeviceInfo (*j, *k, 0, nullptr, &platformInfoCount);
clGetPlatformInfo (i->platform, *j, 0, nullptr, &platformInfoCount);
std::vector<char> info (platformInfoCount);
clGetDeviceInfo (*j, *k, info.size (), info.data (), nullptr);
stream << '\t' << info.data () << std::endl;
clGetPlatformInfo (i->platform, *j, info.size (), info.data (), nullptr);
stream << info.data () << std::endl;
}
size_t deviceTypeCount = 0;
clGetDeviceInfo (*j, CL_DEVICE_TYPE, 0, nullptr, &deviceTypeCount);
std::vector<uint8_t> deviceTypeInfo (deviceTypeCount);
clGetDeviceInfo (*j, CL_DEVICE_TYPE, deviceTypeCount, deviceTypeInfo.data (), 0);
std::string device_type_string;
switch (deviceTypeInfo[0])
for (auto j (i->devices.begin ()), m (i->devices.end ()); j != m; ++j)
{
case CL_DEVICE_TYPE_ACCELERATOR:
device_type_string = "ACCELERATOR";
break;
case CL_DEVICE_TYPE_CPU:
device_type_string = "CPU";
break;
case CL_DEVICE_TYPE_CUSTOM:
device_type_string = "CUSTOM";
break;
case CL_DEVICE_TYPE_DEFAULT:
device_type_string = "DEFAULT";
break;
case CL_DEVICE_TYPE_GPU:
device_type_string = "GPU";
break;
default:
device_type_string = "Unknown";
break;
std::vector<unsigned> queries = { CL_DEVICE_NAME, CL_DEVICE_VENDOR, CL_DEVICE_PROFILE };
stream << "Device: " << j - i->devices.begin () << std::endl;
for (auto k (queries.begin ()), o (queries.end ()); k != o; ++k)
{
size_t platformInfoCount = 0;
clGetDeviceInfo (*j, *k, 0, nullptr, &platformInfoCount);
std::vector<char> info (platformInfoCount);
clGetDeviceInfo (*j, *k, info.size (), info.data (), nullptr);
stream << '\t' << info.data () << std::endl;
}
size_t deviceTypeCount = 0;
clGetDeviceInfo (*j, CL_DEVICE_TYPE, 0, nullptr, &deviceTypeCount);
std::vector<uint8_t> deviceTypeInfo (deviceTypeCount);
clGetDeviceInfo (*j, CL_DEVICE_TYPE, deviceTypeCount, deviceTypeInfo.data (), 0);
std::string device_type_string;
switch (deviceTypeInfo[0])
{
case CL_DEVICE_TYPE_ACCELERATOR:
device_type_string = "ACCELERATOR";
break;
case CL_DEVICE_TYPE_CPU:
device_type_string = "CPU";
break;
case CL_DEVICE_TYPE_CUSTOM:
device_type_string = "CUSTOM";
break;
case CL_DEVICE_TYPE_DEFAULT:
device_type_string = "DEFAULT";
break;
case CL_DEVICE_TYPE_GPU:
device_type_string = "GPU";
break;
default:
device_type_string = "Unknown";
break;
}
stream << '\t' << device_type_string << std::endl;
size_t compilerAvailableCount = 0;
clGetDeviceInfo (*j, CL_DEVICE_COMPILER_AVAILABLE, 0, nullptr, &compilerAvailableCount);
std::vector<uint8_t> compilerAvailableInfo (compilerAvailableCount);
clGetDeviceInfo (*j, CL_DEVICE_COMPILER_AVAILABLE, compilerAvailableCount, compilerAvailableInfo.data (), 0);
stream << "\tCompiler available: " << (compilerAvailableInfo[0] ? "true" : "false") << std::endl;
size_t computeUnitsAvailableCount = 0;
clGetDeviceInfo (*j, CL_DEVICE_MAX_COMPUTE_UNITS, 0, nullptr, &computeUnitsAvailableCount);
std::vector<uint8_t> computeUnitsAvailableInfo (computeUnitsAvailableCount);
clGetDeviceInfo (*j, CL_DEVICE_MAX_COMPUTE_UNITS, computeUnitsAvailableCount, computeUnitsAvailableInfo.data (), 0);
uint64_t computeUnits (computeUnitsAvailableInfo[0] | (computeUnitsAvailableInfo[1] << 8) | (computeUnitsAvailableInfo[2] << 16) | (computeUnitsAvailableInfo[3] << 24));
stream << "\tCompute units available: " << computeUnits << std::endl;
cl_ulong size{ 0 };
clGetDeviceInfo (*j, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\tMemory size" << std::endl;
stream << "\t\tConstant buffer: " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_LOCAL_MEM_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tLocal memory : " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tGlobal memory : " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tGlobal cache : " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tMax allocation : " << size << std::endl;
}
stream << '\t' << device_type_string << std::endl;
size_t compilerAvailableCount = 0;
clGetDeviceInfo (*j, CL_DEVICE_COMPILER_AVAILABLE, 0, nullptr, &compilerAvailableCount);
std::vector<uint8_t> compilerAvailableInfo (compilerAvailableCount);
clGetDeviceInfo (*j, CL_DEVICE_COMPILER_AVAILABLE, compilerAvailableCount, compilerAvailableInfo.data (), 0);
stream << "\tCompiler available: " << (compilerAvailableInfo[0] ? "true" : "false") << std::endl;
size_t computeUnitsAvailableCount = 0;
clGetDeviceInfo (*j, CL_DEVICE_MAX_COMPUTE_UNITS, 0, nullptr, &computeUnitsAvailableCount);
std::vector<uint8_t> computeUnitsAvailableInfo (computeUnitsAvailableCount);
clGetDeviceInfo (*j, CL_DEVICE_MAX_COMPUTE_UNITS, computeUnitsAvailableCount, computeUnitsAvailableInfo.data (), 0);
uint64_t computeUnits (computeUnitsAvailableInfo[0] | (computeUnitsAvailableInfo[1] << 8) | (computeUnitsAvailableInfo[2] << 16) | (computeUnitsAvailableInfo[3] << 24));
stream << "\tCompute units available: " << computeUnits << std::endl;
cl_ulong size{ 0 };
clGetDeviceInfo (*j, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\tMemory size" << std::endl;
stream << "\t\tConstant buffer: " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_LOCAL_MEM_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tLocal memory : " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tGlobal memory : " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tGlobal cache : " << size << std::endl;
clGetDeviceInfo (*j, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof (cl_ulong), &size, 0);
stream << "\t\tMax allocation : " << size << std::endl;
}
}
else
{
stream << boost::str (boost::format ("OpenCL library could not be found\n"));
}
}

nano::opencl_work::opencl_work (bool & error_a, nano::opencl_config const & config_a, nano::opencl_environment & environment_a, nano::logger_mt & logger_a) :
Expand Down
1 change: 1 addition & 0 deletions nano/node/openclwork.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

namespace nano
{
extern bool opencl_loaded;
class logger_mt;
class opencl_platform
{
Expand Down
2 changes: 2 additions & 0 deletions nano/node/plat/posix/openclapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ class opencl_initializer
clEnqueueNDRangeKernel = reinterpret_cast<decltype (clEnqueueNDRangeKernel)> (dlsym (opencl_library, "clEnqueueNDRangeKernel"));
clEnqueueReadBuffer = reinterpret_cast<decltype (clEnqueueReadBuffer)> (dlsym (opencl_library, "clEnqueueReadBuffer"));
clFinish = reinterpret_cast<decltype (clFinish)> (dlsym (opencl_library, "clFinish"));
nano::opencl_loaded = true;
}
}
~opencl_initializer ()
{
if (opencl_library != nullptr)
{
nano::opencl_loaded = false;
dlclose (opencl_library);
}
}
Expand Down
2 changes: 2 additions & 0 deletions nano/node/plat/windows/openclapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ class opencl_initializer
clEnqueueNDRangeKernel = reinterpret_cast<decltype (clEnqueueNDRangeKernel)> (GetProcAddress (opencl_library, "clEnqueueNDRangeKernel"));
clEnqueueReadBuffer = reinterpret_cast<decltype (clEnqueueReadBuffer)> (GetProcAddress (opencl_library, "clEnqueueReadBuffer"));
clFinish = reinterpret_cast<decltype (clFinish)> (GetProcAddress (opencl_library, "clFinish"));
nano::opencl_loaded = true;
}
}
~opencl_initializer ()
{
if (opencl_library != nullptr)
{
nano::opencl_loaded = false;
FreeLibrary (opencl_library);
}
}
Expand Down

0 comments on commit 3fd6754

Please sign in to comment.