• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bernardladenthin / BitcoinAddressFinder / #287

12 Apr 2025 09:07AM UTC coverage: 67.536% (+3.4%) from 64.134%
#287

push

bernardladenthin
Add assumeOpenCLLibraryLoadable.

1165 of 1725 relevant lines covered (67.54%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.93
/src/main/java/net/ladenthin/bitcoinaddressfinder/opencl/OpenCLBuilder.java
1
// @formatter:off
2
/**
3
 * Copyright 2022 Bernard Ladenthin bernard.ladenthin@gmail.com
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *    http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
// @formatter:on
19
package net.ladenthin.bitcoinaddressfinder.opencl;
20

21
import java.lang.reflect.Field;
22
import java.nio.ByteBuffer;
23
import java.nio.ByteOrder;
24
import java.util.ArrayList;
25
import java.util.List;
26
import net.ladenthin.bitcoinaddressfinder.ByteBufferUtility;
27
import org.apache.maven.artifact.versioning.ComparableVersion;
28
import static org.jocl.CL.CL_DEVICE_ADDRESS_BITS;
29
import static org.jocl.CL.CL_DEVICE_ERROR_CORRECTION_SUPPORT;
30
import static org.jocl.CL.CL_DEVICE_EXTENSIONS;
31
import static org.jocl.CL.CL_DEVICE_GLOBAL_MEM_SIZE;
32
import static org.jocl.CL.CL_DEVICE_IMAGE2D_MAX_HEIGHT;
33
import static org.jocl.CL.CL_DEVICE_IMAGE2D_MAX_WIDTH;
34
import static org.jocl.CL.CL_DEVICE_IMAGE3D_MAX_DEPTH;
35
import static org.jocl.CL.CL_DEVICE_IMAGE3D_MAX_HEIGHT;
36
import static org.jocl.CL.CL_DEVICE_IMAGE3D_MAX_WIDTH;
37
import static org.jocl.CL.CL_DEVICE_IMAGE_SUPPORT;
38
import static org.jocl.CL.CL_DEVICE_LOCAL_MEM_SIZE;
39
import static org.jocl.CL.CL_DEVICE_LOCAL_MEM_TYPE;
40
import static org.jocl.CL.CL_DEVICE_MAX_CLOCK_FREQUENCY;
41
import static org.jocl.CL.CL_DEVICE_MAX_COMPUTE_UNITS;
42
import static org.jocl.CL.CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE;
43
import static org.jocl.CL.CL_DEVICE_MAX_MEM_ALLOC_SIZE;
44
import static org.jocl.CL.CL_DEVICE_MAX_READ_IMAGE_ARGS;
45
import static org.jocl.CL.CL_DEVICE_MAX_WORK_GROUP_SIZE;
46
import static org.jocl.CL.CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS;
47
import static org.jocl.CL.CL_DEVICE_MAX_WORK_ITEM_SIZES;
48
import static org.jocl.CL.CL_DEVICE_MAX_WRITE_IMAGE_ARGS;
49
import static org.jocl.CL.CL_DEVICE_NAME;
50
import static org.jocl.CL.CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR;
51
import static org.jocl.CL.CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE;
52
import static org.jocl.CL.CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT;
53
import static org.jocl.CL.CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT;
54
import static org.jocl.CL.CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG;
55
import static org.jocl.CL.CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT;
56
import static org.jocl.CL.CL_DEVICE_PROFILE;
57
import static org.jocl.CL.CL_DEVICE_QUEUE_PROPERTIES;
58
import static org.jocl.CL.CL_DEVICE_SINGLE_FP_CONFIG;
59
import static org.jocl.CL.CL_DEVICE_TYPE;
60
import static org.jocl.CL.CL_DEVICE_TYPE_ALL;
61
import static org.jocl.CL.CL_DEVICE_VENDOR;
62
import static org.jocl.CL.CL_DEVICE_VERSION;
63
import static org.jocl.CL.CL_DRIVER_VERSION;
64
import static org.jocl.CL.CL_PLATFORM_NAME;
65
import static org.jocl.CL.clGetDeviceIDs;
66
import static org.jocl.CL.clGetDeviceInfo;
67
import static org.jocl.CL.clGetPlatformIDs;
68
import static org.jocl.CL.clGetPlatformInfo;
69
import org.jocl.Pointer;
70
import org.jocl.Sizeof;
71
import org.jocl.cl_device_id;
72
import org.jocl.cl_platform_id;
73

74
public class OpenCLBuilder {
1✔
75
    
76
    public static boolean TRANSFORM_TO_PRINT = true;
1✔
77
    
78
    public List<OpenCLPlatform> build() {
79
        // Obtain the number of platforms
80
        int numPlatforms[] = new int[1];
×
81
        clGetPlatformIDs(0, null, numPlatforms);
×
82

83
        // Obtain the platform IDs
84
        List<OpenCLPlatform> openCLPlatforms = new ArrayList<>();
×
85
        cl_platform_id platforms[] = new cl_platform_id[numPlatforms[0]];
×
86
        clGetPlatformIDs(platforms.length, platforms, null);
×
87

88
        for (int i=0; i<platforms.length; i++) {
×
89
            // Collect all devices of all platforms
90
            final cl_platform_id platformId = platforms[i];
×
91

92
            String platformName = getString(platformId, CL_PLATFORM_NAME);
×
93
            
94
            // Obtain the number of devices for the current platform
95
            int numDevices[] = new int[1];
×
96
            clGetDeviceIDs(platformId, CL_DEVICE_TYPE_ALL, 0, null, numDevices);
×
97
            
98
            cl_device_id devicesArray[] = new cl_device_id[numDevices[0]];
×
99
            clGetDeviceIDs(platformId, CL_DEVICE_TYPE_ALL, numDevices[0], devicesArray, null);
×
100

101
            List<OpenCLDevice> openCLDevices = new ArrayList<>();
×
102
            for (cl_device_id device : devicesArray) {
×
103
                OpenCLDevice openCLDevice = createOpenCLDevice(device);
×
104
                openCLDevices.add(openCLDevice);
×
105
            }
106
            
107
            OpenCLPlatform openCLPlatform = new OpenCLPlatform(platformName, openCLDevices);
×
108
            openCLPlatforms.add(openCLPlatform);
×
109
        }
110
        
111
        return openCLPlatforms;
×
112
    }
113

114
    private OpenCLDevice createOpenCLDevice(cl_device_id device) {
115
        String deviceName = getString(device, CL_DEVICE_NAME);
×
116
        String deviceVendor = getString(device, CL_DEVICE_VENDOR);
×
117
        String driverVersion = getString(device, CL_DRIVER_VERSION);
×
118
        String deviceProfile = getString(device, CL_DEVICE_PROFILE);
×
119
        String deviceVersion = getString(device, CL_DEVICE_VERSION);
×
120
        String deviceExtensions = getString(device, CL_DEVICE_EXTENSIONS);
×
121
        long deviceType = getLong(device, CL_DEVICE_TYPE);
×
122
        int maxComputeUnits = getInt(device, CL_DEVICE_MAX_COMPUTE_UNITS);
×
123
        long maxWorkItemDimensions = getLong(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
×
124
        long maxWorkItemSizes[] = getSizes(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, 3);
×
125
        long maxWorkGroupSize = getSize(device, CL_DEVICE_MAX_WORK_GROUP_SIZE);
×
126
        long maxClockFrequency = getLong(device, CL_DEVICE_MAX_CLOCK_FREQUENCY);
×
127
        int addressBits = getInt(device, CL_DEVICE_ADDRESS_BITS);
×
128
        long maxMemAllocSize = getLong(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE);
×
129
        long globalMemSize = getLong(device, CL_DEVICE_GLOBAL_MEM_SIZE);
×
130
        int errorCorrectionSupport = getInt(device, CL_DEVICE_ERROR_CORRECTION_SUPPORT);
×
131
        int localMemType = getInt(device, CL_DEVICE_LOCAL_MEM_TYPE);
×
132
        long localMemSize = getLong(device, CL_DEVICE_LOCAL_MEM_SIZE);
×
133
        long maxConstantBufferSize = getLong(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE);
×
134
        long queueProperties = getLong(device, CL_DEVICE_QUEUE_PROPERTIES);
×
135
        int imageSupport = getInt(device, CL_DEVICE_IMAGE_SUPPORT);
×
136
        int maxReadImageArgs = getInt(device, CL_DEVICE_MAX_READ_IMAGE_ARGS);
×
137
        int maxWriteImageArgs = getInt(device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS);
×
138
        long singleFpConfig = getLong(device, CL_DEVICE_SINGLE_FP_CONFIG);
×
139
        long image2dMaxWidth = getSize(device, CL_DEVICE_IMAGE2D_MAX_WIDTH);
×
140
        long image2dMaxHeight = getSize(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT);
×
141
        long image3dMaxWidth = getSize(device, CL_DEVICE_IMAGE3D_MAX_WIDTH);
×
142
        long image3dMaxHeight = getSize(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT);
×
143
        long image3dMaxDepth = getSize(device, CL_DEVICE_IMAGE3D_MAX_DEPTH);
×
144
        int preferredVectorWidthChar = getInt(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR);
×
145
        int preferredVectorWidthShort = getInt(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT);
×
146
        int preferredVectorWidthInt = getInt(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT);
×
147
        int preferredVectorWidthLong = getInt(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG);
×
148
        int preferredVectorWidthFloat = getInt(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT);
×
149
        int preferredVectorWidthDouble = getInt(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE);
×
150
        
151
        OpenCLDevice openCLDevice = new OpenCLDevice(
×
152
                deviceName,
153
                deviceVendor,
154
                driverVersion,
155
                deviceProfile,
156
                deviceVersion,
157
                deviceExtensions,
158
                deviceType,
159
                maxComputeUnits,
160
                maxWorkItemDimensions,
161
                maxWorkItemSizes,
162
                maxWorkGroupSize,
163
                maxClockFrequency,
164
                addressBits,
165
                maxMemAllocSize,
166
                globalMemSize,
167
                errorCorrectionSupport,
168
                localMemType,
169
                localMemSize,
170
                maxConstantBufferSize,
171
                queueProperties,
172
                imageSupport,
173
                maxReadImageArgs,
174
                maxWriteImageArgs,
175
                singleFpConfig,
176
                image2dMaxWidth,
177
                image2dMaxHeight,
178
                image3dMaxWidth,
179
                image3dMaxHeight,
180
                image3dMaxDepth,
181
                preferredVectorWidthChar,
182
                preferredVectorWidthShort,
183
                preferredVectorWidthInt,
184
                preferredVectorWidthLong,
185
                preferredVectorWidthFloat,
186
                preferredVectorWidthDouble
187
        );
188
        
189
        return openCLDevice;
×
190
    }
191
    
192
    
193
    public static boolean isOpenCLnativeLibraryLoadable() {
194
        try {
195
            Class.forName("org.jocl.CL");
×
196
            Field field = org.jocl.CL.class.getDeclaredField("nativeLibraryLoaded");
×
197
            field.setAccessible(true);
×
198
            return field.getBoolean(null);
×
199
        } catch(java.lang.UnsatisfiedLinkError e) {
1✔
200
            return false;
1✔
201
        } catch (java.lang.NoClassDefFoundError e) {
1✔
202
            return false;
1✔
203
        } catch (Exception e) {
×
204
            e.printStackTrace();
×
205
            return false;
×
206
        }
207
    }
208
    
209
    public static boolean isOneOpenCL2_0OrGreaterDeviceAvailable(List<OpenCLPlatform> openCLPlatforms) {
210
        for (OpenCLPlatform openCLPlatform : openCLPlatforms) {
×
211
            List<OpenCLDevice> openCLDevices = openCLPlatform.openCLDevices();
×
212
            for (OpenCLDevice openCLDevice : openCLDevices) {
×
213
                if (isOpenCL2_0OrGreater(openCLDevice.getDeviceVersionAsComparableVersion())) {
×
214
                    return true;
×
215
                }
216
            }
×
217
        }
×
218
        return false;
×
219
    }
220

221
    public static boolean isOpenCL2_0OrGreater(ComparableVersion openCLDeviceVersion) {
222
        final ComparableVersion v2_0 = new ComparableVersion("2.0");
1✔
223
        if (openCLDeviceVersion.compareTo(v2_0) >= 0) {
1✔
224
            return true;
1✔
225
        }
226
        return false;
1✔
227
    }
228
    
229
    /**
230
     * Returns the value of the device info parameter with the given name
231
     *
232
     * @param device The device
233
     * @param paramName The parameter name
234
     * @return The value
235
     */
236
    private static int getInt(cl_device_id device, int paramName)
237
    {
238
        return getInts(device, paramName, 1)[0];
×
239
    }
240

241
    /**
242
     * Returns the values of the device info parameter with the given name
243
     *
244
     * @param device The device
245
     * @param paramName The parameter name
246
     * @param numValues The number of values
247
     * @return The value
248
     */
249
    private static int[] getInts(cl_device_id device, int paramName, int numValues)
250
    {
251
        int values[] = new int[numValues];
×
252
        clGetDeviceInfo(device, paramName, (long)Sizeof.cl_int * numValues, Pointer.to(values), null);
×
253
        return values;
×
254
    }
255

256
    /**
257
     * Returns the value of the device info parameter with the given name
258
     *
259
     * @param device The device
260
     * @param paramName The parameter name
261
     * @return The value
262
     */
263
    private static long getLong(cl_device_id device, int paramName)
264
    {
265
        return getLongs(device, paramName, 1)[0];
×
266
    }
267

268
    /**
269
     * Returns the values of the device info parameter with the given name
270
     *
271
     * @param device The device
272
     * @param paramName The parameter name
273
     * @param numValues The number of values
274
     * @return The value
275
     */
276
    private static long[] getLongs(cl_device_id device, int paramName, int numValues)
277
    {
278
        long values[] = new long[numValues];
×
279
        clGetDeviceInfo(device, paramName, (long)Sizeof.cl_long * numValues, Pointer.to(values), null);
×
280
        return values;
×
281
    }
282

283
    /**
284
     * Returns the value of the device info parameter with the given name
285
     *
286
     * @param device The device
287
     * @param paramName The parameter name
288
     * @return The value
289
     */
290
    private static String getString(cl_device_id device, int paramName)
291
    {
292
        // Obtain the length of the string that will be queried
293
        long size[] = new long[1];
×
294
        clGetDeviceInfo(device, paramName, 0, null, size);
×
295

296
        // Create a buffer of the appropriate size and fill it with the info
297
        byte buffer[] = new byte[(int)size[0]];
×
298
        clGetDeviceInfo(device, paramName, buffer.length, Pointer.to(buffer), null);
×
299

300
        // Create a string from the buffer (excluding the trailing \0 byte)
301
        return new String(buffer, 0, buffer.length-1);
×
302
    }
303

304
    /**
305
     * Returns the value of the platform info parameter with the given name
306
     *
307
     * @param platform The platform
308
     * @param paramName The parameter name
309
     * @return The value
310
     */
311
    private static String getString(cl_platform_id platform, int paramName)
312
    {
313
        // Obtain the length of the string that will be queried
314
        long size[] = new long[1];
×
315
        clGetPlatformInfo(platform, paramName, 0, null, size);
×
316

317
        // Create a buffer of the appropriate size and fill it with the info
318
        byte buffer[] = new byte[(int)size[0]];
×
319
        clGetPlatformInfo(platform, paramName, buffer.length, Pointer.to(buffer), null);
×
320

321
        // Create a string from the buffer (excluding the trailing \0 byte)
322
        return new String(buffer, 0, buffer.length-1);
×
323
    }
324
    
325
    /**
326
     * Returns the value of the device info parameter with the given name
327
     *
328
     * @param device The device
329
     * @param paramName The parameter name
330
     * @return The value
331
     */
332
    private static long getSize(cl_device_id device, int paramName)
333
    {
334
        return getSizes(device, paramName, 1)[0];
×
335
    }
336
    
337
    /**
338
     * Returns the values of the device info parameter with the given name
339
     *
340
     * @param device The device
341
     * @param paramName The parameter name
342
     * @param numValues The number of values
343
     * @return The value
344
     */
345
    static long[] getSizes(cl_device_id device, int paramName, int numValues)
346
    {
347
        // The size of the returned data has to depend on 
348
        // the size of a size_t, which is handled here
349
        long size = (long)numValues * Sizeof.size_t;
×
350
        ByteBuffer buffer = ByteBuffer.allocate(
×
351
            ByteBufferUtility.ensureByteBufferCapacityFitsInt(size)).order(ByteOrder.nativeOrder());
×
352
        clGetDeviceInfo(device, paramName, size, 
×
353
            Pointer.to(buffer), null);
×
354
        long values[] = new long[numValues];
×
355
        if (Sizeof.size_t == 4)
×
356
        {
357
            for (int i=0; i<numValues; i++)
×
358
            {
359
                values[i] = buffer.getInt(i * Sizeof.size_t);
×
360
            }
361
        }
362
        else
363
        {
364
            for (int i=0; i<numValues; i++)
×
365
            {
366
                values[i] = buffer.getLong(i * Sizeof.size_t);
×
367
            }
368
        }
369
        return values;
×
370
    }
371
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc