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

bernardladenthin / BitcoinAddressFinder / #315

23 May 2025 03:19PM UTC coverage: 66.005% (-1.9%) from 67.925%
#315

push

bernardladenthin
Refactor OpenCL resource handling and improve consistency across API

- Introduced AutoCloseable for OpenCL resources (OpenClTask, OpenCLContext)
- Replaced manual release() methods with try-with-resources using close()
- Added isClosed() for defensive resource lifecycle checks
- Refactored buffer handling to separate host and device pointers
- Renamed createSecrets() param for clarity (overallWorkSize instead of batchSizeInBits)
- Updated all tests and affected logic to match new API and lifecycle
- Enhanced OpenCLGridResult to avoid unnecessary buffer duplication
- Improved benchmark documentation in README with CPU column
- Added optional LMDB in-memory caching in configuration

11 of 118 new or added lines in 10 files covered. (9.32%)

3 existing lines in 2 files now uncovered.

1231 of 1865 relevant lines covered (66.01%)

0.66 hits per line

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

0.0
/src/main/java/net/ladenthin/bitcoinaddressfinder/OpenCLContext.java
1
// @formatter:off
2
/**
3
 * Copyright 2020 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;
20

21
import com.google.common.io.Resources;
22
import java.io.IOException;
23
import java.math.BigInteger;
24
import java.net.URL;
25
import java.nio.ByteBuffer;
26
import java.nio.charset.StandardCharsets;
27
import java.util.ArrayList;
28
import java.util.List;
29
import net.ladenthin.bitcoinaddressfinder.configuration.CProducerOpenCL;
30
import net.ladenthin.bitcoinaddressfinder.opencl.OpenCLBuilder;
31
import net.ladenthin.bitcoinaddressfinder.opencl.OpenCLDevice;
32
import net.ladenthin.bitcoinaddressfinder.opencl.OpenCLDeviceSelection;
33
import net.ladenthin.bitcoinaddressfinder.opencl.OpenCLPlatform;
34
import net.ladenthin.bitcoinaddressfinder.opencl.OpenCLPlatformSelector;
35
import static org.jocl.CL.clBuildProgram;
36
import static org.jocl.CL.clCreateCommandQueueWithProperties;
37
import static org.jocl.CL.clCreateContext;
38
import static org.jocl.CL.clCreateKernel;
39
import static org.jocl.CL.clCreateProgramWithSource;
40
import static org.jocl.CL.clReleaseCommandQueue;
41
import static org.jocl.CL.clReleaseContext;
42
import org.jocl.cl_command_queue;
43
import org.jocl.cl_context;
44
import org.jocl.cl_context_properties;
45
import org.jocl.cl_device_id;
46
import org.jocl.cl_kernel;
47
import org.jocl.cl_program;
48
import org.jocl.cl_queue_properties;
49
import org.jocl.CL;
50
import static org.jocl.CL.clReleaseKernel;
51
import static org.jocl.CL.clReleaseProgram;
52
import org.slf4j.Logger;
53
import org.slf4j.LoggerFactory;
54

55
public class OpenCLContext implements ReleaseCLObject {
56

57
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
×
58
    
59
    public String[] getOpenCLPrograms() throws IOException {
60
        List<String> resourceNamesContent = getResourceNamesContent(getResourceNames());
×
61
        List<String> resourceNamesContentWithReplacements = new ArrayList<>();
×
62
        for (String content : resourceNamesContent) {
×
63
            String contentWithReplacements = content;
×
64
            contentWithReplacements = contentWithReplacements.replaceAll("#include.*", "");
×
65
            resourceNamesContentWithReplacements.add(contentWithReplacements);
×
66
        }
×
67
        String[] openClPrograms = resourceNamesContentWithReplacements.toArray(new String[0]);
×
68
        return openClPrograms;
×
69
    }
70
    
71
    private List<String> getResourceNames() {
72
        List<String> resourceNames = new ArrayList<>();
×
73
        resourceNames.add("inc_defines.h");
×
74
        resourceNames.add("copyfromhashcat/inc_vendor.h");
×
75
        resourceNames.add("copyfromhashcat/inc_types.h");
×
76
        resourceNames.add("copyfromhashcat/inc_platform.h");
×
77
        resourceNames.add("copyfromhashcat/inc_platform.cl");
×
78
        resourceNames.add("copyfromhashcat/inc_common.h");
×
79
        resourceNames.add("copyfromhashcat/inc_common.cl");
×
80
        resourceNames.add("copyfromhashcat/inc_hash_sha256.h");
×
81
        resourceNames.add("copyfromhashcat/inc_hash_sha256.cl");
×
82
        resourceNames.add("copyfromhashcat/inc_hash_ripemd160.h");
×
83
        resourceNames.add("copyfromhashcat/inc_hash_ripemd160.cl");
×
84

85
        resourceNames.add("copyfromhashcat/inc_ecc_secp256k1.h");
×
86
        resourceNames.add("copyfromhashcat/inc_ecc_secp256k1.cl");
×
87
        resourceNames.add("inc_ecc_secp256k1custom.cl");
×
88
        return resourceNames;
×
89
    }
90
    
91
    private final static String KERNEL_NAME = "generateKeysKernel_grid";
92
    private final static boolean EXCEPTIONS_ENABLED = true;
93
    
94
    private final CProducerOpenCL producerOpenCL;
95
    private final BitHelper bitHelper;
96

97
    private OpenCLDevice device;
98
    private cl_context context;
99
    private cl_command_queue commandQueue;
100
    private cl_program program;
101
    private cl_kernel kernel;
102
    private OpenClTask openClTask;
103
    private ByteBufferUtility byteBufferUtility;
104
    
NEW
105
    private boolean closed = false;
×
106
    
107
    public OpenCLContext(CProducerOpenCL producerOpenCL, BitHelper bitHelper) {
×
108
        this.producerOpenCL = producerOpenCL;
×
109
        this.bitHelper = bitHelper;
×
110
        this.byteBufferUtility = new ByteBufferUtility(true);
×
111
    }
×
112
    
113
    public void init() throws IOException {
114
        
115
        // #################### general ####################
116
        
117
        // Enable exceptions and subsequently omit error checks in this sample
118
        CL.setExceptionsEnabled(EXCEPTIONS_ENABLED);
×
119
        
120
        List<OpenCLPlatform> platforms = new OpenCLBuilder().build();
×
121

122
        OpenCLDeviceSelection selection = OpenCLPlatformSelector.select(
×
123
            platforms,
124
            producerOpenCL.platformIndex,
125
            producerOpenCL.deviceType,
126
            producerOpenCL.deviceIndex
127
        );
128
        
129
        device = selection.getDevice();
×
130
        cl_context_properties contextProperties = selection.getContextProperties();
×
131
        cl_device_id[] cl_device_ids = new cl_device_id[]{device.device()};
×
132
        
133
        // Create a context for the selected device
134
        context = clCreateContext(contextProperties, 1, cl_device_ids, null, null, null);
×
135
        
136
        // Create a command-queue for the selected device
137
        cl_queue_properties properties = new cl_queue_properties();
×
138
        commandQueue = clCreateCommandQueueWithProperties(context, device.device(), properties, null);
×
139
        
140
        // #################### kernel specifix ####################
141
        
142
        String[] openCLPrograms = getOpenCLPrograms();
×
143
        // Create the program from the source code
144
        program = clCreateProgramWithSource(context, openCLPrograms.length, openCLPrograms, null, null);
×
145

146
        // Build the program
147
        clBuildProgram(program, 0, null, null, null, null);
×
148
        
149
        // Create the kernel
150
        kernel = clCreateKernel(program, KERNEL_NAME, null);
×
151
        
152
        openClTask = new OpenClTask(context, producerOpenCL, bitHelper, byteBufferUtility);
×
153
    }
×
154

155
    OpenClTask getOpenClTask() {
156
        return openClTask;
×
157
    }
158
    
159
    @Override
160
    public boolean isClosed() {
NEW
161
        return closed;
×
162
    }
163

164
    @Override
165
    public void close() {
NEW
166
        if (!closed) {
×
NEW
167
            openClTask.close();
×
NEW
168
            clReleaseKernel(kernel);
×
NEW
169
            clReleaseProgram(program);
×
NEW
170
            clReleaseCommandQueue(commandQueue);
×
NEW
171
            clReleaseContext(context);
×
NEW
172
            closed = true;
×
173
        }
UNCOV
174
    }
×
175

176
    public OpenCLGridResult createKeys(BigInteger privateKeyBase) {
177
        openClTask.setSrcPrivateKeyChunk(privateKeyBase);
×
178
        ByteBuffer dstByteBuffer = openClTask.executeKernel(kernel, commandQueue);
×
179

NEW
180
        OpenCLGridResult openCLGridResult = new OpenCLGridResult(privateKeyBase, producerOpenCL.getOverallWorkSize(bitHelper), dstByteBuffer);
×
181
        return openCLGridResult;
×
182
    }
183

184
    private static List<String> getResourceNamesContent(List<String> resourceNames) throws IOException {
185
        List<String> contents = new ArrayList<>();
×
186
        for (String resourceName : resourceNames) {
×
187
            URL url = Resources.getResource(resourceName);
×
188
            String content = Resources.toString(url, StandardCharsets.UTF_8);
×
189
            contents.add(content);
×
190
        }
×
191
        return contents;
×
192
    }
193

194
}
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

© 2025 Coveralls, Inc