1 | package net.bmahe.genetics4j.gpu.spec.fitness; | |
2 | ||
3 | import java.util.HashMap; | |
4 | import java.util.List; | |
5 | import java.util.Map; | |
6 | import java.util.concurrent.CompletableFuture; | |
7 | import java.util.concurrent.ConcurrentHashMap; | |
8 | import java.util.concurrent.ExecutorService; | |
9 | ||
10 | import org.apache.commons.collections4.MapUtils; | |
11 | import org.apache.commons.lang3.Validate; | |
12 | import org.apache.logging.log4j.LogManager; | |
13 | import org.apache.logging.log4j.Logger; | |
14 | import org.jocl.CL; | |
15 | import org.jocl.Pointer; | |
16 | import org.jocl.Sizeof; | |
17 | ||
18 | import net.bmahe.genetics4j.core.Genotype; | |
19 | import net.bmahe.genetics4j.gpu.opencl.OpenCLExecutionContext; | |
20 | import net.bmahe.genetics4j.gpu.opencl.model.Device; | |
21 | import net.bmahe.genetics4j.gpu.spec.fitness.cldata.CLData; | |
22 | import net.bmahe.genetics4j.gpu.spec.fitness.kernelcontext.KernelExecutionContext; | |
23 | ||
24 | /** | |
25 | * GPU-accelerated fitness evaluator that executes a single OpenCL kernel for fitness computation. | |
26 | * | |
27 | * <p>SingleKernelFitness provides a comprehensive framework for implementing fitness evaluation using | |
28 | * a single OpenCL kernel. It manages the complete lifecycle of GPU computation including data loading, | |
29 | * kernel execution, and result extraction, making it suitable for most GPU-accelerated evolutionary | |
30 | * algorithm scenarios. | |
31 | * | |
32 | * <p>Key features: | |
33 | * <ul> | |
34 | * <li><strong>Single kernel execution</strong>: Executes one OpenCL kernel per fitness evaluation</li> | |
35 | * <li><strong>Data management</strong>: Handles static data, dynamic data, and result allocation</li> | |
36 | * <li><strong>Memory lifecycle</strong>: Automatic cleanup of OpenCL memory objects</li> | |
37 | * <li><strong>Multi-device support</strong>: Supports concurrent execution across multiple devices</li> | |
38 | * <li><strong>Local memory</strong>: Configurable local memory allocation for kernel optimization</li> | |
39 | * </ul> | |
40 | * | |
41 | * <p>Data flow architecture: | |
42 | * <ul> | |
43 | * <li><strong>Static data</strong>: Algorithm parameters loaded once before all evaluations</li> | |
44 | * <li><strong>Dynamic data</strong>: Population data loaded before each generation</li> | |
45 | * <li><strong>Local memory</strong>: Work group local memory allocated based on kernel requirements</li> | |
46 | * <li><strong>Result data</strong>: Output buffers allocated for fitness results and intermediate data</li> | |
47 | * </ul> | |
48 | * | |
49 | * <p>Typical usage pattern: | |
50 | * <pre>{@code | |
51 | * // Define kernel and data configuration | |
52 | * SingleKernelFitnessDescriptor descriptor = SingleKernelFitnessDescriptor.builder() | |
53 | * .kernelName("fitness_evaluation") | |
54 | * .addDataLoader(0, populationDataLoader) | |
55 | * .addStaticDataLoader(1, parametersDataLoader) | |
56 | * .addResultAllocator(2, fitnessResultAllocator) | |
57 | * .kernelExecutionContextComputer(executionContextComputer) | |
58 | * .build(); | |
59 | * | |
60 | * // Define fitness extraction from GPU results | |
61 | * FitnessExtractor<Double> extractor = (context, kernelCtx, executor, generation, genotypes, results) -> { | |
62 | * float[] fitnessValues = results.extractFloatArray(context, 2); | |
63 | * return Arrays.stream(fitnessValues) | |
64 | * .mapToDouble(f -> (double) f) | |
65 | * .boxed() | |
66 | * .collect(Collectors.toList()); | |
67 | * }; | |
68 | * | |
69 | * // Create single kernel fitness evaluator | |
70 | * SingleKernelFitness<Double> fitness = SingleKernelFitness.of(descriptor, extractor); | |
71 | * }</pre> | |
72 | * | |
73 | * <p>Kernel execution workflow: | |
74 | * <ol> | |
75 | * <li><strong>Initialization</strong>: Load static data once before all evaluations</li> | |
76 | * <li><strong>Data preparation</strong>: Load generation-specific data and allocate result buffers</li> | |
77 | * <li><strong>Kernel setup</strong>: Configure kernel arguments with data references</li> | |
78 | * <li><strong>Execution</strong>: Launch kernel with optimized work group configuration</li> | |
79 | * <li><strong>Result extraction</strong>: Extract fitness values from GPU memory</li> | |
80 | * <li><strong>Cleanup</strong>: Release generation-specific memory resources</li> | |
81 | * </ol> | |
82 | * | |
83 | * <p>Memory management strategy: | |
84 | * <ul> | |
85 | * <li><strong>Static data persistence</strong>: Static data remains allocated across generations</li> | |
86 | * <li><strong>Dynamic allocation</strong>: Generation data is allocated and released per evaluation</li> | |
87 | * <li><strong>Result buffer reuse</strong>: Result buffers can be reused with proper sizing</li> | |
88 | * <li><strong>Automatic cleanup</strong>: Memory is automatically released in lifecycle methods</li> | |
89 | * </ul> | |
90 | * | |
91 | * <p>Performance optimization features: | |
92 | * <ul> | |
93 | * <li><strong>Asynchronous execution</strong>: Kernel execution returns CompletableFuture for pipeline processing</li> | |
94 | * <li><strong>Work group optimization</strong>: Configurable work group sizes for optimal device utilization</li> | |
95 | * <li><strong>Memory coalescing</strong>: Support for optimized memory access patterns</li> | |
96 | * <li><strong>Local memory utilization</strong>: Efficient use of device local memory for performance</li> | |
97 | * </ul> | |
98 | * | |
99 | * @param <T> the fitness value type, must be Comparable for optimization algorithms | |
100 | * @see OpenCLFitness | |
101 | * @see SingleKernelFitnessDescriptor | |
102 | * @see FitnessExtractor | |
103 | * @see net.bmahe.genetics4j.gpu.spec.fitness.cldata.DataLoader | |
104 | */ | |
105 | public class SingleKernelFitness<T extends Comparable<T>> extends OpenCLFitness<T> { | |
106 | public static final Logger logger = LogManager.getLogger(SingleKernelFitness.class); | |
107 | ||
108 | private final SingleKernelFitnessDescriptor singleKernelFitnessDescriptor; | |
109 | private final FitnessExtractor<T> fitnessExtractor; | |
110 | ||
111 |
2
1. <init> : removed call to java/util/concurrent/ConcurrentHashMap::<init> → NO_COVERAGE 2. <init> : Removed assignment to member variable staticData → NO_COVERAGE |
private final Map<Device, Map<Integer, CLData>> staticData = new ConcurrentHashMap<>(); |
112 |
2
1. <init> : Removed assignment to member variable data → NO_COVERAGE 2. <init> : removed call to java/util/concurrent/ConcurrentHashMap::<init> → NO_COVERAGE |
private final Map<Device, Map<Integer, CLData>> data = new ConcurrentHashMap<>(); |
113 |
2
1. <init> : removed call to java/util/concurrent/ConcurrentHashMap::<init> → NO_COVERAGE 2. <init> : Removed assignment to member variable resultData → NO_COVERAGE |
private final Map<Device, Map<Integer, CLData>> resultData = new ConcurrentHashMap<>(); |
114 | ||
115 |
2
1. <init> : removed call to java/util/concurrent/ConcurrentHashMap::<init> → NO_COVERAGE 2. <init> : Removed assignment to member variable kernelExecutionContexts → NO_COVERAGE |
private final Map<Device, KernelExecutionContext> kernelExecutionContexts = new ConcurrentHashMap<>(); |
116 | ||
117 | protected void clearStaticData(final Device device) { | |
118 |
10
1. clearStaticData : replaced call to java/util/Map::get with argument → NO_COVERAGE 2. clearStaticData : removed conditional - replaced equality check with true → NO_COVERAGE 3. clearStaticData : removed call to org/apache/commons/collections4/MapUtils::isEmpty → NO_COVERAGE 4. clearStaticData : removed conditional - replaced equality check with false → NO_COVERAGE 5. clearStaticData : negated conditional → NO_COVERAGE 6. clearStaticData : removed call to java/util/Map::get → NO_COVERAGE 7. clearStaticData : negated conditional → NO_COVERAGE 8. clearStaticData : removed conditional - replaced equality check with false → NO_COVERAGE 9. clearStaticData : removed call to org/apache/commons/collections4/MapUtils::isEmpty → NO_COVERAGE 10. clearStaticData : removed conditional - replaced equality check with true → NO_COVERAGE |
if (MapUtils.isEmpty(staticData) || MapUtils.isEmpty(staticData.get(device))) { |
119 | return; | |
120 | } | |
121 | ||
122 |
2
1. clearStaticData : replaced call to java/util/Map::get with argument → NO_COVERAGE 2. clearStaticData : removed call to java/util/Map::get → NO_COVERAGE |
final Map<Integer, CLData> mapData = staticData.get(device); |
123 |
1
1. clearStaticData : removed call to java/util/Map::values → NO_COVERAGE |
for (final CLData clData : mapData.values()) { |
124 |
2
1. clearStaticData : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/CLData::clMem → NO_COVERAGE 2. clearStaticData : removed call to org/jocl/CL::clReleaseMemObject → NO_COVERAGE |
CL.clReleaseMemObject(clData.clMem()); |
125 | } | |
126 | ||
127 |
1
1. clearStaticData : removed call to java/util/Map::clear → NO_COVERAGE |
mapData.clear(); |
128 |
2
1. clearStaticData : removed call to java/util/Map::remove → NO_COVERAGE 2. clearStaticData : replaced call to java/util/Map::remove with argument → NO_COVERAGE |
staticData.remove(device); |
129 | } | |
130 | ||
131 | protected void clearData(final Device device) { | |
132 |
10
1. clearData : replaced call to java/util/Map::get with argument → NO_COVERAGE 2. clearData : removed conditional - replaced equality check with true → NO_COVERAGE 3. clearData : removed call to org/apache/commons/collections4/MapUtils::isEmpty → NO_COVERAGE 4. clearData : removed conditional - replaced equality check with false → NO_COVERAGE 5. clearData : negated conditional → NO_COVERAGE 6. clearData : negated conditional → NO_COVERAGE 7. clearData : removed conditional - replaced equality check with true → NO_COVERAGE 8. clearData : removed call to org/apache/commons/collections4/MapUtils::isEmpty → NO_COVERAGE 9. clearData : removed conditional - replaced equality check with false → NO_COVERAGE 10. clearData : removed call to java/util/Map::get → NO_COVERAGE |
if (MapUtils.isEmpty(data) || MapUtils.isEmpty(data.get(device))) { |
133 | return; | |
134 | } | |
135 | ||
136 |
2
1. clearData : replaced call to java/util/Map::get with argument → NO_COVERAGE 2. clearData : removed call to java/util/Map::get → NO_COVERAGE |
final Map<Integer, CLData> mapData = data.get(device); |
137 |
1
1. clearData : removed call to java/util/Map::values → NO_COVERAGE |
for (final CLData clData : mapData.values()) { |
138 |
2
1. clearData : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/CLData::clMem → NO_COVERAGE 2. clearData : removed call to org/jocl/CL::clReleaseMemObject → NO_COVERAGE |
CL.clReleaseMemObject(clData.clMem()); |
139 | } | |
140 | ||
141 |
1
1. clearData : removed call to java/util/Map::clear → NO_COVERAGE |
mapData.clear(); |
142 |
2
1. clearData : removed call to java/util/Map::remove → NO_COVERAGE 2. clearData : replaced call to java/util/Map::remove with argument → NO_COVERAGE |
data.remove(device); |
143 | } | |
144 | ||
145 | protected void clearResultData(final Device device) { | |
146 |
10
1. clearResultData : removed conditional - replaced equality check with false → NO_COVERAGE 2. clearResultData : removed call to org/apache/commons/collections4/MapUtils::isEmpty → NO_COVERAGE 3. clearResultData : replaced call to java/util/Map::get with argument → NO_COVERAGE 4. clearResultData : removed conditional - replaced equality check with true → NO_COVERAGE 5. clearResultData : removed call to java/util/Map::get → NO_COVERAGE 6. clearResultData : negated conditional → NO_COVERAGE 7. clearResultData : removed call to org/apache/commons/collections4/MapUtils::isEmpty → NO_COVERAGE 8. clearResultData : removed conditional - replaced equality check with false → NO_COVERAGE 9. clearResultData : negated conditional → NO_COVERAGE 10. clearResultData : removed conditional - replaced equality check with true → NO_COVERAGE |
if (MapUtils.isEmpty(resultData) || MapUtils.isEmpty(resultData.get(device))) { |
147 | return; | |
148 | } | |
149 | ||
150 |
2
1. clearResultData : replaced call to java/util/Map::get with argument → NO_COVERAGE 2. clearResultData : removed call to java/util/Map::get → NO_COVERAGE |
final Map<Integer, CLData> mapData = resultData.get(device); |
151 |
1
1. clearResultData : removed call to java/util/Map::values → NO_COVERAGE |
for (final CLData clData : mapData.values()) { |
152 |
2
1. clearResultData : removed call to org/jocl/CL::clReleaseMemObject → NO_COVERAGE 2. clearResultData : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/CLData::clMem → NO_COVERAGE |
CL.clReleaseMemObject(clData.clMem()); |
153 | } | |
154 | ||
155 |
1
1. clearResultData : removed call to java/util/Map::clear → NO_COVERAGE |
mapData.clear(); |
156 |
2
1. clearResultData : removed call to java/util/Map::remove → NO_COVERAGE 2. clearResultData : replaced call to java/util/Map::remove with argument → NO_COVERAGE |
resultData.remove(device); |
157 | } | |
158 | ||
159 | /** | |
160 | * Constructs a SingleKernelFitness with the specified kernel descriptor and fitness extractor. | |
161 | * | |
162 | * @param _singleKernelFitnessDescriptor configuration for kernel execution and data management | |
163 | * @param _fitnessExtractor function to extract fitness values from GPU computation results | |
164 | * @throws IllegalArgumentException if any parameter is null | |
165 | */ | |
166 | public SingleKernelFitness(final SingleKernelFitnessDescriptor _singleKernelFitnessDescriptor, | |
167 | final FitnessExtractor<T> _fitnessExtractor) { | |
168 | Validate.notNull(_singleKernelFitnessDescriptor); | |
169 | Validate.notNull(_fitnessExtractor); | |
170 | ||
171 |
1
1. <init> : Removed assignment to member variable singleKernelFitnessDescriptor → NO_COVERAGE |
this.singleKernelFitnessDescriptor = _singleKernelFitnessDescriptor; |
172 |
1
1. <init> : Removed assignment to member variable fitnessExtractor → NO_COVERAGE |
this.fitnessExtractor = _fitnessExtractor; |
173 | } | |
174 | ||
175 | @Override | |
176 | public void beforeAllEvaluations(final OpenCLExecutionContext openCLExecutionContext, | |
177 | final ExecutorService executorService) { | |
178 |
1
1. beforeAllEvaluations : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeAllEvaluations → NO_COVERAGE |
super.beforeAllEvaluations(openCLExecutionContext, executorService); |
179 | ||
180 |
1
1. beforeAllEvaluations : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::device → NO_COVERAGE |
final var device = openCLExecutionContext.device(); |
181 |
1
1. beforeAllEvaluations : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::clearStaticData → NO_COVERAGE |
clearStaticData(device); |
182 | ||
183 |
1
1. beforeAllEvaluations : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitnessDescriptor::staticDataLoaders → NO_COVERAGE |
final var staticDataLoaders = singleKernelFitnessDescriptor.staticDataLoaders(); |
184 |
1
1. beforeAllEvaluations : removed call to java/util/Map::entrySet → NO_COVERAGE |
for (final var entry : staticDataLoaders.entrySet()) { |
185 |
2
1. beforeAllEvaluations : removed call to java/util/Map$Entry::getKey → NO_COVERAGE 2. beforeAllEvaluations : removed call to java/lang/Integer::intValue → NO_COVERAGE |
final int argumentIdx = entry.getKey(); |
186 |
1
1. beforeAllEvaluations : removed call to java/util/Map$Entry::getValue → NO_COVERAGE |
final var dataSupplier = entry.getValue(); |
187 | ||
188 | if (logger.isTraceEnabled()) { | |
189 |
1
1. beforeAllEvaluations : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::device → NO_COVERAGE |
final var deviceName = openCLExecutionContext.device() |
190 |
1
1. beforeAllEvaluations : removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::name → NO_COVERAGE |
.name(); |
191 | logger.trace("[{}] Loading static data for index {}", deviceName, argumentIdx); | |
192 | } | |
193 |
1
1. beforeAllEvaluations : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/StaticDataLoader::load → NO_COVERAGE |
final CLData clData = dataSupplier.load(openCLExecutionContext); |
194 | ||
195 |
4
1. beforeAllEvaluations : removed call to java/util/Map::computeIfAbsent → NO_COVERAGE 2. lambda$beforeAllEvaluations$0 : removed call to java/util/HashMap::<init> → NO_COVERAGE 3. beforeAllEvaluations : replaced call to java/util/Map::computeIfAbsent with argument → NO_COVERAGE 4. lambda$beforeAllEvaluations$0 : replaced return value with Collections.emptyMap for net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::lambda$beforeAllEvaluations$0 → NO_COVERAGE |
final var mapData = staticData.computeIfAbsent(device, k -> new HashMap<>()); |
196 |
6
1. beforeAllEvaluations : replaced call to java/util/Map::put with argument → NO_COVERAGE 2. beforeAllEvaluations : removed call to java/util/Map::put → NO_COVERAGE 3. beforeAllEvaluations : removed call to java/lang/Integer::valueOf → NO_COVERAGE 4. beforeAllEvaluations : removed conditional - replaced equality check with false → NO_COVERAGE 5. beforeAllEvaluations : negated conditional → NO_COVERAGE 6. beforeAllEvaluations : removed conditional - replaced equality check with true → NO_COVERAGE |
if (mapData.put(argumentIdx, clData) != null) { |
197 |
1
1. beforeAllEvaluations : removed call to java/lang/IllegalArgumentException::<init> → NO_COVERAGE |
throw new IllegalArgumentException("Multiple data configured for index " + argumentIdx); |
198 | } | |
199 | } | |
200 | } | |
201 | ||
202 | @Override | |
203 | public void beforeEvaluation(OpenCLExecutionContext openCLExecutionContext, ExecutorService executorService, | |
204 | long generation, final List<Genotype> genotypes) { | |
205 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeEvaluation → NO_COVERAGE |
super.beforeEvaluation(openCLExecutionContext, executorService, generation, genotypes); |
206 | ||
207 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::device → NO_COVERAGE |
final var device = openCLExecutionContext.device(); |
208 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::kernels → NO_COVERAGE |
final var kernels = openCLExecutionContext.kernels(); |
209 | ||
210 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitnessDescriptor::kernelName → NO_COVERAGE |
final var kernelName = singleKernelFitnessDescriptor.kernelName(); |
211 |
2
1. beforeEvaluation : removed call to java/util/Map::get → NO_COVERAGE 2. beforeEvaluation : replaced call to java/util/Map::get with argument → NO_COVERAGE |
final var kernel = kernels.get(kernelName); |
212 | ||
213 |
4
1. beforeEvaluation : removed call to java/util/Map::containsKey → NO_COVERAGE 2. beforeEvaluation : negated conditional → NO_COVERAGE 3. beforeEvaluation : removed conditional - replaced equality check with true → NO_COVERAGE 4. beforeEvaluation : removed conditional - replaced equality check with false → NO_COVERAGE |
if (kernelExecutionContexts.containsKey(device)) { |
214 |
1
1. beforeEvaluation : removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE |
throw new IllegalStateException("Found existing kernelExecutionContext"); |
215 | } | |
216 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitnessDescriptor::kernelExecutionContextComputer → NO_COVERAGE |
final var kernelExecutionContextComputer = singleKernelFitnessDescriptor.kernelExecutionContextComputer(); |
217 | final var kernelExecutionContext = kernelExecutionContextComputer | |
218 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/kernelcontext/KernelExecutionContextComputer::compute → NO_COVERAGE |
.compute(openCLExecutionContext, kernelName, generation, genotypes); |
219 |
2
1. beforeEvaluation : removed call to java/util/Map::put → NO_COVERAGE 2. beforeEvaluation : replaced call to java/util/Map::put with argument → NO_COVERAGE |
kernelExecutionContexts.put(device, kernelExecutionContext); |
220 | ||
221 |
2
1. beforeEvaluation : replaced call to java/util/Map::get with argument → NO_COVERAGE 2. beforeEvaluation : removed call to java/util/Map::get → NO_COVERAGE |
final var mapData = staticData.get(device); |
222 |
4
1. beforeEvaluation : removed conditional - replaced equality check with false → NO_COVERAGE 2. beforeEvaluation : removed conditional - replaced equality check with true → NO_COVERAGE 3. beforeEvaluation : removed call to org/apache/commons/collections4/MapUtils::isNotEmpty → NO_COVERAGE 4. beforeEvaluation : negated conditional → NO_COVERAGE |
if (MapUtils.isNotEmpty(mapData)) { |
223 |
1
1. beforeEvaluation : removed call to java/util/Map::entrySet → NO_COVERAGE |
for (final var entry : mapData.entrySet()) { |
224 |
2
1. beforeEvaluation : removed call to java/lang/Integer::intValue → NO_COVERAGE 2. beforeEvaluation : removed call to java/util/Map$Entry::getKey → NO_COVERAGE |
final int argumentIdx = entry.getKey(); |
225 |
1
1. beforeEvaluation : removed call to java/util/Map$Entry::getValue → NO_COVERAGE |
final var clStaticData = entry.getValue(); |
226 | ||
227 | logger.trace("[{}] Loading static data for index {}", device.name(), argumentIdx); | |
228 | ||
229 |
4
1. beforeEvaluation : removed call to org/jocl/Pointer::to → NO_COVERAGE 2. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/CLData::clMem → NO_COVERAGE 3. beforeEvaluation : removed call to org/jocl/CL::clSetKernelArg → NO_COVERAGE 4. beforeEvaluation : replaced call to org/jocl/CL::clSetKernelArg with argument → NO_COVERAGE |
CL.clSetKernelArg(kernel, argumentIdx, Sizeof.cl_mem, Pointer.to(clStaticData.clMem())); |
230 | } | |
231 | } | |
232 | ||
233 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitnessDescriptor::dataLoaders → NO_COVERAGE |
final var dataLoaders = singleKernelFitnessDescriptor.dataLoaders(); |
234 |
4
1. beforeEvaluation : removed conditional - replaced equality check with false → NO_COVERAGE 2. beforeEvaluation : removed conditional - replaced equality check with true → NO_COVERAGE 3. beforeEvaluation : removed call to org/apache/commons/collections4/MapUtils::isNotEmpty → NO_COVERAGE 4. beforeEvaluation : negated conditional → NO_COVERAGE |
if (MapUtils.isNotEmpty(dataLoaders)) { |
235 |
1
1. beforeEvaluation : removed call to java/util/Map::entrySet → NO_COVERAGE |
for (final var entry : dataLoaders.entrySet()) { |
236 |
2
1. beforeEvaluation : removed call to java/lang/Integer::intValue → NO_COVERAGE 2. beforeEvaluation : removed call to java/util/Map$Entry::getKey → NO_COVERAGE |
final int argumentIdx = entry.getKey(); |
237 |
1
1. beforeEvaluation : removed call to java/util/Map$Entry::getValue → NO_COVERAGE |
final var dataLoader = entry.getValue(); |
238 | ||
239 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/DataLoader::load → NO_COVERAGE |
final var clDdata = dataLoader.load(openCLExecutionContext, generation, genotypes); |
240 | ||
241 |
4
1. beforeEvaluation : removed call to java/util/Map::computeIfAbsent → NO_COVERAGE 2. lambda$beforeEvaluation$1 : removed call to java/util/HashMap::<init> → NO_COVERAGE 3. beforeEvaluation : replaced call to java/util/Map::computeIfAbsent with argument → NO_COVERAGE 4. lambda$beforeEvaluation$1 : replaced return value with Collections.emptyMap for net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::lambda$beforeEvaluation$1 → NO_COVERAGE |
final var dataMapping = data.computeIfAbsent(device, k -> new HashMap<>()); |
242 |
6
1. beforeEvaluation : replaced call to java/util/Map::put with argument → NO_COVERAGE 2. beforeEvaluation : removed conditional - replaced equality check with false → NO_COVERAGE 3. beforeEvaluation : removed conditional - replaced equality check with true → NO_COVERAGE 4. beforeEvaluation : removed call to java/util/Map::put → NO_COVERAGE 5. beforeEvaluation : removed call to java/lang/Integer::valueOf → NO_COVERAGE 6. beforeEvaluation : negated conditional → NO_COVERAGE |
if (dataMapping.put(argumentIdx, clDdata) != null) { |
243 |
1
1. beforeEvaluation : removed call to java/lang/IllegalArgumentException::<init> → NO_COVERAGE |
throw new IllegalArgumentException("Multiple data configured for index " + argumentIdx); |
244 | } | |
245 | logger.trace("[{}] Loading data for index {}", device.name(), argumentIdx); | |
246 | ||
247 |
4
1. beforeEvaluation : removed call to org/jocl/CL::clSetKernelArg → NO_COVERAGE 2. beforeEvaluation : removed call to org/jocl/Pointer::to → NO_COVERAGE 3. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/CLData::clMem → NO_COVERAGE 4. beforeEvaluation : replaced call to org/jocl/CL::clSetKernelArg with argument → NO_COVERAGE |
CL.clSetKernelArg(kernel, argumentIdx, Sizeof.cl_mem, Pointer.to(clDdata.clMem())); |
248 | } | |
249 | } | |
250 | ||
251 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitnessDescriptor::localMemoryAllocators → NO_COVERAGE |
final var localMemoryAllocators = singleKernelFitnessDescriptor.localMemoryAllocators(); |
252 |
4
1. beforeEvaluation : negated conditional → NO_COVERAGE 2. beforeEvaluation : removed conditional - replaced equality check with false → NO_COVERAGE 3. beforeEvaluation : removed conditional - replaced equality check with true → NO_COVERAGE 4. beforeEvaluation : removed call to org/apache/commons/collections4/MapUtils::isNotEmpty → NO_COVERAGE |
if (MapUtils.isNotEmpty(localMemoryAllocators)) { |
253 |
1
1. beforeEvaluation : removed call to java/util/Map::entrySet → NO_COVERAGE |
for (final var entry : localMemoryAllocators.entrySet()) { |
254 |
2
1. beforeEvaluation : removed call to java/lang/Integer::intValue → NO_COVERAGE 2. beforeEvaluation : removed call to java/util/Map$Entry::getKey → NO_COVERAGE |
final int argumentIdx = entry.getKey(); |
255 |
1
1. beforeEvaluation : removed call to java/util/Map$Entry::getValue → NO_COVERAGE |
final var localMemoryAllocator = entry.getValue(); |
256 | ||
257 | final var size = localMemoryAllocator | |
258 |
2
1. beforeEvaluation : replaced call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/LocalMemoryAllocator::load with argument → NO_COVERAGE 2. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/LocalMemoryAllocator::load → NO_COVERAGE |
.load(openCLExecutionContext, kernelExecutionContext, generation, genotypes); |
259 | logger.trace("[{}] Setting local data for index {} with size of {}", device.name(), argumentIdx, size); | |
260 | ||
261 |
2
1. beforeEvaluation : removed call to org/jocl/CL::clSetKernelArg → NO_COVERAGE 2. beforeEvaluation : replaced call to org/jocl/CL::clSetKernelArg with argument → NO_COVERAGE |
CL.clSetKernelArg(kernel, argumentIdx, size, null); |
262 | } | |
263 | } | |
264 | ||
265 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitnessDescriptor::resultAllocators → NO_COVERAGE |
final var resultAllocators = singleKernelFitnessDescriptor.resultAllocators(); |
266 |
4
1. beforeEvaluation : negated conditional → NO_COVERAGE 2. beforeEvaluation : removed conditional - replaced equality check with false → NO_COVERAGE 3. beforeEvaluation : removed conditional - replaced equality check with true → NO_COVERAGE 4. beforeEvaluation : removed call to org/apache/commons/collections4/MapUtils::isNotEmpty → NO_COVERAGE |
if (MapUtils.isNotEmpty(resultAllocators)) { |
267 |
1
1. beforeEvaluation : removed call to java/util/Map::entrySet → NO_COVERAGE |
for (final var entry : resultAllocators.entrySet()) { |
268 |
2
1. beforeEvaluation : removed call to java/util/Map$Entry::getKey → NO_COVERAGE 2. beforeEvaluation : removed call to java/lang/Integer::intValue → NO_COVERAGE |
final int argumentIdx = entry.getKey(); |
269 |
1
1. beforeEvaluation : removed call to java/util/Map$Entry::getValue → NO_COVERAGE |
final var resultAllocator = entry.getValue(); |
270 | ||
271 | final var clDdata = resultAllocator | |
272 |
1
1. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/ResultAllocator::load → NO_COVERAGE |
.load(openCLExecutionContext, kernelExecutionContext, generation, genotypes); |
273 | ||
274 |
4
1. lambda$beforeEvaluation$2 : removed call to java/util/HashMap::<init> → NO_COVERAGE 2. lambda$beforeEvaluation$2 : replaced return value with Collections.emptyMap for net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::lambda$beforeEvaluation$2 → NO_COVERAGE 3. beforeEvaluation : removed call to java/util/Map::computeIfAbsent → NO_COVERAGE 4. beforeEvaluation : replaced call to java/util/Map::computeIfAbsent with argument → NO_COVERAGE |
final var dataMapping = resultData.computeIfAbsent(device, k -> new HashMap<>()); |
275 |
6
1. beforeEvaluation : removed conditional - replaced equality check with false → NO_COVERAGE 2. beforeEvaluation : removed call to java/lang/Integer::valueOf → NO_COVERAGE 3. beforeEvaluation : removed conditional - replaced equality check with true → NO_COVERAGE 4. beforeEvaluation : removed call to java/util/Map::put → NO_COVERAGE 5. beforeEvaluation : negated conditional → NO_COVERAGE 6. beforeEvaluation : replaced call to java/util/Map::put with argument → NO_COVERAGE |
if (dataMapping.put(argumentIdx, clDdata) != null) { |
276 |
1
1. beforeEvaluation : removed call to java/lang/IllegalArgumentException::<init> → NO_COVERAGE |
throw new IllegalArgumentException("Multiple result allocators configured for index " + argumentIdx); |
277 | } | |
278 | logger.trace("[{}] Preparing result data memory for index {}", device.name(), argumentIdx); | |
279 | ||
280 |
4
1. beforeEvaluation : removed call to org/jocl/CL::clSetKernelArg → NO_COVERAGE 2. beforeEvaluation : removed call to org/jocl/Pointer::to → NO_COVERAGE 3. beforeEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/cldata/CLData::clMem → NO_COVERAGE 4. beforeEvaluation : replaced call to org/jocl/CL::clSetKernelArg with argument → NO_COVERAGE |
CL.clSetKernelArg(kernel, argumentIdx, Sizeof.cl_mem, Pointer.to(clDdata.clMem())); |
281 | } | |
282 | } | |
283 | ||
284 | } | |
285 | ||
286 | @Override | |
287 | public CompletableFuture<List<T>> compute(final OpenCLExecutionContext openCLExecutionContext, | |
288 | final ExecutorService executorService, final long generation, List<Genotype> genotypes) { | |
289 | ||
290 |
2
1. compute : removed call to java/util/concurrent/CompletableFuture::supplyAsync → NO_COVERAGE 2. compute : replaced return value with null for net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::compute → NO_COVERAGE |
return CompletableFuture.supplyAsync(() -> { |
291 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::clCommandQueue → NO_COVERAGE |
final var clCommandQueue = openCLExecutionContext.clCommandQueue(); |
292 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::kernels → NO_COVERAGE |
final var kernels = openCLExecutionContext.kernels(); |
293 | ||
294 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitnessDescriptor::kernelName → NO_COVERAGE |
final var kernelName = singleKernelFitnessDescriptor.kernelName(); |
295 |
2
1. lambda$compute$3 : replaced call to java/util/Map::get with argument → NO_COVERAGE 2. lambda$compute$3 : removed call to java/util/Map::get → NO_COVERAGE |
final var kernel = kernels.get(kernelName); |
296 |
3
1. lambda$compute$3 : removed conditional - replaced equality check with false → NO_COVERAGE 2. lambda$compute$3 : negated conditional → NO_COVERAGE 3. lambda$compute$3 : removed conditional - replaced equality check with true → NO_COVERAGE |
if (kernel == null) { |
297 |
1
1. lambda$compute$3 : removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE |
throw new IllegalStateException("Could not find kernel [" + kernelName + "]"); |
298 | } | |
299 | ||
300 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::device → NO_COVERAGE |
final var device = openCLExecutionContext.device(); |
301 |
2
1. lambda$compute$3 : removed call to java/util/Map::get → NO_COVERAGE 2. lambda$compute$3 : replaced call to java/util/Map::get with argument → NO_COVERAGE |
final var kernelExecutionContext = kernelExecutionContexts.get(device); |
302 | ||
303 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/kernelcontext/KernelExecutionContext::globalWorkDimensions → NO_COVERAGE |
final var globalWorkDimensions = kernelExecutionContext.globalWorkDimensions(); |
304 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/kernelcontext/KernelExecutionContext::globalWorkSize → NO_COVERAGE |
final var globalWorkSize = kernelExecutionContext.globalWorkSize(); |
305 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/kernelcontext/KernelExecutionContext::workGroupSize → NO_COVERAGE |
final long[] workGroupSize = kernelExecutionContext.workGroupSize() |
306 |
2
1. lambda$compute$3 : removed call to java/util/Optional::orElse → NO_COVERAGE 2. lambda$compute$3 : replaced call to java/util/Optional::orElse with argument → NO_COVERAGE |
.orElse(null); |
307 | ||
308 | logger.trace( | |
309 | "Starting computation on kernel {} for {} genotypes and global work size {} and local work size {}", | |
310 | kernelName, | |
311 |
2
1. lambda$compute$3 : removed call to java/util/List::size → NO_COVERAGE 2. lambda$compute$3 : removed call to java/lang/Integer::valueOf → NO_COVERAGE |
genotypes.size(), |
312 | globalWorkSize, | |
313 | workGroupSize); | |
314 |
1
1. lambda$compute$3 : removed call to java/lang/System::nanoTime → NO_COVERAGE |
final long startTime = System.nanoTime(); |
315 |
3
1. lambda$compute$3 : Substituted 0 with 1 → NO_COVERAGE 2. lambda$compute$3 : replaced call to org/jocl/CL::clEnqueueNDRangeKernel with argument → NO_COVERAGE 3. lambda$compute$3 : removed call to org/jocl/CL::clEnqueueNDRangeKernel → NO_COVERAGE |
CL.clEnqueueNDRangeKernel(clCommandQueue, |
316 | kernel, | |
317 | globalWorkDimensions, | |
318 | null, | |
319 | globalWorkSize, | |
320 | workGroupSize, | |
321 | 0, | |
322 | null, | |
323 | null); | |
324 | ||
325 |
1
1. lambda$compute$3 : removed call to java/lang/System::nanoTime → NO_COVERAGE |
final long endTime = System.nanoTime(); |
326 |
1
1. lambda$compute$3 : Replaced long subtraction with addition → NO_COVERAGE |
final long duration = endTime - startTime; |
327 | if (logger.isDebugEnabled()) { | |
328 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::device → NO_COVERAGE |
final var deviceName = openCLExecutionContext.device() |
329 |
1
1. lambda$compute$3 : removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::name → NO_COVERAGE |
.name(); |
330 | logger.debug("{} - Took {} microsec for {} genotypes", deviceName, duration / 1000., genotypes.size()); | |
331 | } | |
332 |
1
1. lambda$compute$3 : replaced return value with null for net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::lambda$compute$3 → NO_COVERAGE |
return kernelExecutionContext; |
333 | }, executorService) | |
334 |
2
1. compute : replaced call to java/util/concurrent/CompletableFuture::thenApply with receiver → NO_COVERAGE 2. compute : removed call to java/util/concurrent/CompletableFuture::thenApply → NO_COVERAGE |
.thenApply(kernelExecutionContext -> { |
335 | ||
336 |
1
1. lambda$compute$4 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/ResultExtractor::<init> → NO_COVERAGE |
final var resultExtractor = new ResultExtractor(resultData); |
337 |
3
1. lambda$compute$4 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/FitnessExtractor::compute → NO_COVERAGE 2. lambda$compute$4 : replaced return value with Collections.emptyList for net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::lambda$compute$4 → NO_COVERAGE 3. lambda$compute$4 : replaced call to net/bmahe/genetics4j/gpu/spec/fitness/FitnessExtractor::compute with argument → NO_COVERAGE |
return fitnessExtractor.compute(openCLExecutionContext, |
338 | kernelExecutionContext, | |
339 | executorService, | |
340 | generation, | |
341 | genotypes, | |
342 | resultExtractor); | |
343 | }); | |
344 | } | |
345 | ||
346 | @Override | |
347 | public void afterEvaluation(OpenCLExecutionContext openCLExecutionContext, ExecutorService executorService, | |
348 | long generation, List<Genotype> genotypes) { | |
349 |
1
1. afterEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterEvaluation → NO_COVERAGE |
super.afterEvaluation(openCLExecutionContext, executorService, generation, genotypes); |
350 | ||
351 |
1
1. afterEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::device → NO_COVERAGE |
final var device = openCLExecutionContext.device(); |
352 | logger.trace("[{}] Releasing data", device.name()); | |
353 |
1
1. afterEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::clearData → NO_COVERAGE |
clearData(device); |
354 |
1
1. afterEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::clearResultData → NO_COVERAGE |
clearResultData(device); |
355 |
2
1. afterEvaluation : removed call to java/util/Map::remove → NO_COVERAGE 2. afterEvaluation : replaced call to java/util/Map::remove with argument → NO_COVERAGE |
kernelExecutionContexts.remove(device); |
356 | } | |
357 | ||
358 | @Override | |
359 | public void afterAllEvaluations(final OpenCLExecutionContext openCLExecutionContext, | |
360 | final ExecutorService executorService) { | |
361 |
1
1. afterAllEvaluations : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterAllEvaluations → NO_COVERAGE |
super.afterAllEvaluations(openCLExecutionContext, executorService); |
362 | ||
363 |
1
1. afterAllEvaluations : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::device → NO_COVERAGE |
final var device = openCLExecutionContext.device(); |
364 | logger.trace("[{}] Releasing static data", device.name()); | |
365 |
1
1. afterAllEvaluations : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::clearStaticData → NO_COVERAGE |
clearStaticData(device); |
366 | } | |
367 | ||
368 | /** | |
369 | * Creates a new SingleKernelFitness instance with the specified configuration. | |
370 | * | |
371 | * @param <U> the fitness value type | |
372 | * @param singleKernelFitnessDescriptor configuration for kernel execution and data management | |
373 | * @param fitnessExtractor function to extract fitness values from GPU computation results | |
374 | * @return a new SingleKernelFitness instance | |
375 | * @throws IllegalArgumentException if any parameter is null | |
376 | */ | |
377 | public static <U extends Comparable<U>> SingleKernelFitness<U> of( | |
378 | final SingleKernelFitnessDescriptor singleKernelFitnessDescriptor, | |
379 | final FitnessExtractor<U> fitnessExtractor) { | |
380 | Validate.notNull(singleKernelFitnessDescriptor); | |
381 | Validate.notNull(fitnessExtractor); | |
382 | ||
383 |
2
1. of : replaced return value with null for net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::of → NO_COVERAGE 2. of : removed call to net/bmahe/genetics4j/gpu/spec/fitness/SingleKernelFitness::<init> → NO_COVERAGE |
return new SingleKernelFitness<>(singleKernelFitnessDescriptor, fitnessExtractor); |
384 | } | |
385 | } | |
Mutations | ||
111 |
1.1 2.2 |
|
112 |
1.1 2.2 |
|
113 |
1.1 2.2 |
|
115 |
1.1 2.2 |
|
118 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.10 |
|
122 |
1.1 2.2 |
|
123 |
1.1 |
|
124 |
1.1 2.2 |
|
127 |
1.1 |
|
128 |
1.1 2.2 |
|
132 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.10 |
|
136 |
1.1 2.2 |
|
137 |
1.1 |
|
138 |
1.1 2.2 |
|
141 |
1.1 |
|
142 |
1.1 2.2 |
|
146 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.10 |
|
150 |
1.1 2.2 |
|
151 |
1.1 |
|
152 |
1.1 2.2 |
|
155 |
1.1 |
|
156 |
1.1 2.2 |
|
171 |
1.1 |
|
172 |
1.1 |
|
178 |
1.1 |
|
180 |
1.1 |
|
181 |
1.1 |
|
183 |
1.1 |
|
184 |
1.1 |
|
185 |
1.1 2.2 |
|
186 |
1.1 |
|
189 |
1.1 |
|
190 |
1.1 |
|
193 |
1.1 |
|
195 |
1.1 2.2 3.3 4.4 |
|
196 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
197 |
1.1 |
|
205 |
1.1 |
|
207 |
1.1 |
|
208 |
1.1 |
|
210 |
1.1 |
|
211 |
1.1 2.2 |
|
213 |
1.1 2.2 3.3 4.4 |
|
214 |
1.1 |
|
216 |
1.1 |
|
218 |
1.1 |
|
219 |
1.1 2.2 |
|
221 |
1.1 2.2 |
|
222 |
1.1 2.2 3.3 4.4 |
|
223 |
1.1 |
|
224 |
1.1 2.2 |
|
225 |
1.1 |
|
229 |
1.1 2.2 3.3 4.4 |
|
233 |
1.1 |
|
234 |
1.1 2.2 3.3 4.4 |
|
235 |
1.1 |
|
236 |
1.1 2.2 |
|
237 |
1.1 |
|
239 |
1.1 |
|
241 |
1.1 2.2 3.3 4.4 |
|
242 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
243 |
1.1 |
|
247 |
1.1 2.2 3.3 4.4 |
|
251 |
1.1 |
|
252 |
1.1 2.2 3.3 4.4 |
|
253 |
1.1 |
|
254 |
1.1 2.2 |
|
255 |
1.1 |
|
258 |
1.1 2.2 |
|
261 |
1.1 2.2 |
|
265 |
1.1 |
|
266 |
1.1 2.2 3.3 4.4 |
|
267 |
1.1 |
|
268 |
1.1 2.2 |
|
269 |
1.1 |
|
272 |
1.1 |
|
274 |
1.1 2.2 3.3 4.4 |
|
275 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
276 |
1.1 |
|
280 |
1.1 2.2 3.3 4.4 |
|
290 |
1.1 2.2 |
|
291 |
1.1 |
|
292 |
1.1 |
|
294 |
1.1 |
|
295 |
1.1 2.2 |
|
296 |
1.1 2.2 3.3 |
|
297 |
1.1 |
|
300 |
1.1 |
|
301 |
1.1 2.2 |
|
303 |
1.1 |
|
304 |
1.1 |
|
305 |
1.1 |
|
306 |
1.1 2.2 |
|
311 |
1.1 2.2 |
|
314 |
1.1 |
|
315 |
1.1 2.2 3.3 |
|
325 |
1.1 |
|
326 |
1.1 |
|
328 |
1.1 |
|
329 |
1.1 |
|
332 |
1.1 |
|
334 |
1.1 2.2 |
|
336 |
1.1 |
|
337 |
1.1 2.2 3.3 |
|
349 |
1.1 |
|
351 |
1.1 |
|
353 |
1.1 |
|
354 |
1.1 |
|
355 |
1.1 2.2 |
|
361 |
1.1 |
|
363 |
1.1 |
|
365 |
1.1 |
|
383 |
1.1 2.2 |