1 /*
  2  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 #include "opencl_backend.h"
 27 
 28 template<typename T>
 29 static T info(cl_device_id device_id, cl_device_info device_info){
 30     T v;
 31     cl_int status = clGetDeviceInfo(device_id, device_info, sizeof(T), &v, nullptr);
 32     OPENCL_CHECK(status, "clGetDeviceInfo");
 33     return v;
 34 }
 35 
 36 static char *strInfo(cl_device_id device_id, cl_device_info device_info){
 37     size_t sz;
 38     cl_int  status = clGetDeviceInfo(device_id, device_info, 0, nullptr,  &sz);
 39     OPENCL_CHECK(status, "clGetDeviceInfo");
 40     auto ptr = new char[sz+1];
 41     status = clGetDeviceInfo(device_id, device_info, sz, ptr,nullptr);
 42     OPENCL_CHECK(status, "clGetDeviceInfo");
 43     return ptr;
 44 }
 45 
 46 static char *strInfo(cl_platform_id platform_id, cl_platform_info platform_info){
 47     size_t sz;
 48     cl_int  status = clGetPlatformInfo(platform_id, platform_info, 0, nullptr,  &sz);
 49     OPENCL_CHECK(status, "clGetPlatformInfo");
 50     char *ptr = new char[sz+1];
 51     status = clGetPlatformInfo(platform_id, platform_info, sz, ptr,nullptr);
 52     OPENCL_CHECK(status, "clGetPlatformInfo");
 53     return ptr;
 54 }
 55 
 56 PlatformInfo::DeviceInfo::DeviceInfo(OpenCLBackend *openclBackend):
 57     openclBackend(openclBackend),
 58     maxComputeUnits(info<cl_int>(openclBackend->device_id,CL_DEVICE_MAX_COMPUTE_UNITS)),
 59     maxWorkItemDimensions(info<cl_int>(openclBackend->device_id,CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS)),
 60     maxWorkGroupSize(info<size_t>(openclBackend->device_id,CL_DEVICE_MAX_WORK_GROUP_SIZE)),
 61     maxWorkItemSizes( new size_t[maxWorkItemDimensions]),
 62     maxMemAllocSize(info<cl_ulong>(openclBackend->device_id, CL_DEVICE_MAX_MEM_ALLOC_SIZE)),
 63     globalMemSize(info<cl_ulong>(openclBackend->device_id,CL_DEVICE_GLOBAL_MEM_SIZE)),
 64     localMemSize(info<cl_ulong>(openclBackend->device_id,CL_DEVICE_LOCAL_MEM_SIZE)),
 65     profile(strInfo(openclBackend->device_id,CL_DEVICE_PROFILE)),
 66     deviceVersion(strInfo(openclBackend->device_id, CL_DEVICE_VERSION)),
 67     driverVersion(strInfo(openclBackend->device_id, CL_DRIVER_VERSION)),
 68     cVersion(strInfo(openclBackend->device_id, CL_DEVICE_OPENCL_C_VERSION)),
 69     name(strInfo(openclBackend->device_id, CL_DEVICE_NAME)),
 70     extensions(strInfo(openclBackend->device_id, CL_DEVICE_EXTENSIONS)),
 71     builtInKernels(strInfo(openclBackend->device_id,CL_DEVICE_BUILT_IN_KERNELS)) {
 72     clGetDeviceInfo(openclBackend->device_id, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t) * maxWorkItemDimensions, maxWorkItemSizes, nullptr);
 73     clGetDeviceInfo(openclBackend->device_id, CL_DEVICE_TYPE, sizeof(deviceType), &deviceType, nullptr);
 74     const u16_t bufferSize = 512;
 75     char buf[bufferSize];
 76     buf[0]='\0';
 77     if (CL_DEVICE_TYPE_CPU == (deviceType & CL_DEVICE_TYPE_CPU)) {
 78         std::strcat(buf, "CPU ");
 79     }
 80     if (CL_DEVICE_TYPE_GPU == (deviceType & CL_DEVICE_TYPE_GPU)) {
 81         std::strcat(buf, "GPU ");
 82     }
 83     if (CL_DEVICE_TYPE_ACCELERATOR == (deviceType & CL_DEVICE_TYPE_ACCELERATOR)) {
 84         std::strcat(buf, "ACC ");
 85     }
 86     buf[bufferSize - 1] = '\0';
 87     deviceTypeStr = new char[std::strlen(buf) + 1];  // include the final '\0'
 88     std::strcpy(deviceTypeStr, buf);
 89 }
 90 
 91 PlatformInfo::DeviceInfo::~DeviceInfo(){
 92     delete [] deviceTypeStr;
 93     delete [] profile;
 94     delete [] deviceVersion;
 95     delete [] driverVersion;
 96     delete [] cVersion;
 97     delete [] name;
 98     delete [] extensions;
 99     delete [] builtInKernels;
100     delete [] maxWorkItemSizes;
101 }
102 
103 PlatformInfo::PlatformInfo(OpenCLBackend *openclBackend):
104     openclBackend(openclBackend),
105     versionName(strInfo(openclBackend->platform_id, CL_PLATFORM_VERSION)),
106     vendorName(strInfo(openclBackend->platform_id, CL_PLATFORM_VENDOR)),
107     name(strInfo(openclBackend->platform_id, CL_PLATFORM_NAME)),
108     deviceInfo(openclBackend){}
109 
110 PlatformInfo::~PlatformInfo(){
111     delete [] versionName;
112     delete [] vendorName;
113     delete [] name;
114 }
115 
116 const PlatformInfo& OpenCLBackend::getPlatformInfo() const {
117     return *_platform_info;
118 }
119 
120 const bool OpenCLBackend::isPlatformOnProfile() const {
121     return isPlatformProfileOn;
122 }
123 
124 void OpenCLBackend::shortDeviceInfo() {
125     std::cerr << "[INFO] Platform :\"" << _platform_info->vendorName <<"\""<< std::endl;
126     std::cerr << "[INFO]   Version      :\"" << _platform_info->versionName <<"\"" <<std::endl;
127     std::cerr << "[INFO]   Name         :\"" << _platform_info->name <<"\""<< std::endl;
128     std::cerr << "[INFO]   Device Type  : " <<  _platform_info->deviceInfo.deviceTypeStr << " "<<  _platform_info->deviceInfo.deviceType << std::endl;
129 }
130 
131 void OpenCLBackend::showDeviceInfo() {
132     std::cerr << "platform{" << std::endl;
133     std::cerr << "   CL_PLATFORM_VENDOR..\"" << _platform_info->vendorName <<"\""<< std::endl;
134     std::cerr << "   CL_PLATFORM_VERSION.\"" << _platform_info->versionName <<"\"" <<std::endl;
135     std::cerr << "   CL_PLATFORM_NAME....\"" << _platform_info->name <<"\""<< std::endl;
136     std::cerr << "         CL_DEVICE_TYPE..................... " <<  _platform_info->deviceInfo.deviceTypeStr << " "<<  _platform_info->deviceInfo.deviceType << std::endl;
137     std::cerr << "         CL_DEVICE_MAX_COMPUTE_UNITS........ " <<  _platform_info->deviceInfo.maxComputeUnits << std::endl;
138     std::cerr << "         CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS. " <<  _platform_info->deviceInfo.maxWorkItemDimensions << " {";
139     for (unsigned dimIdx = 0; dimIdx <  _platform_info->deviceInfo.maxWorkItemDimensions; dimIdx++) {
140         std::cerr<<  _platform_info->deviceInfo.maxWorkItemSizes[dimIdx] << " ";
141     }
142     std::cerr<< "}" << std::endl;
143     std::cerr <<  "         CL_DEVICE_MAX_WORK_GROUP_SIZE...... "<<  _platform_info->deviceInfo.maxWorkGroupSize << std::endl;
144     std::cerr <<  "         CL_DEVICE_MAX_MEM_ALLOC_SIZE....... "<<  _platform_info->deviceInfo.maxMemAllocSize << std::endl;
145     std::cerr <<  "         CL_DEVICE_GLOBAL_MEM_SIZE.......... "<<  _platform_info->deviceInfo.globalMemSize << std::endl;
146     std::cerr <<  "         CL_DEVICE_LOCAL_MEM_SIZE........... "<<  _platform_info->deviceInfo.localMemSize << std::endl;
147     std::cerr <<  "         CL_DEVICE_PROFILE.................. "<<  _platform_info->deviceInfo.profile << std::endl;
148     std::cerr <<  "         CL_DEVICE_VERSION.................. "<<  _platform_info->deviceInfo.deviceVersion << std::endl;
149     std::cerr <<  "         CL_DRIVER_VERSION.................. "<<  _platform_info->deviceInfo.driverVersion <<std::endl;
150     std::cerr <<  "         CL_DEVICE_OPENCL_C_VERSION......... "<<  _platform_info->deviceInfo.cVersion << std::endl;
151     std::cerr <<  "         CL_DEVICE_NAME..................... "<<  _platform_info->deviceInfo.name << std::endl;
152     std::cerr <<  "         CL_DEVICE_EXTENSIONS............... "<<  _platform_info->deviceInfo.extensions << std::endl;
153     std::cerr <<  "         CL_DEVICE_BUILT_IN_KERNELS......... "<<  _platform_info->deviceInfo.builtInKernels << std::endl;
154     std::cerr <<  "}" << std::endl;
155 }