1 | package net.bmahe.genetics4j.gpu; | |
2 | ||
3 | import java.io.IOException; | |
4 | import java.nio.charset.StandardCharsets; | |
5 | import java.util.ArrayList; | |
6 | import java.util.HashMap; | |
7 | import java.util.List; | |
8 | import java.util.Map; | |
9 | import java.util.Set; | |
10 | import java.util.concurrent.CompletableFuture; | |
11 | import java.util.concurrent.ExecutorService; | |
12 | ||
13 | import org.apache.commons.collections4.ListUtils; | |
14 | import org.apache.commons.io.IOUtils; | |
15 | import org.apache.commons.lang3.Validate; | |
16 | import org.apache.commons.lang3.tuple.Pair; | |
17 | import org.apache.logging.log4j.LogManager; | |
18 | import org.apache.logging.log4j.Logger; | |
19 | import org.jocl.CL; | |
20 | import org.jocl.cl_command_queue; | |
21 | import org.jocl.cl_context; | |
22 | import org.jocl.cl_context_properties; | |
23 | import org.jocl.cl_device_id; | |
24 | import org.jocl.cl_kernel; | |
25 | import org.jocl.cl_platform_id; | |
26 | import org.jocl.cl_program; | |
27 | import org.jocl.cl_queue_properties; | |
28 | ||
29 | import net.bmahe.genetics4j.core.Genotype; | |
30 | import net.bmahe.genetics4j.core.evaluation.FitnessEvaluator; | |
31 | import net.bmahe.genetics4j.gpu.opencl.DeviceReader; | |
32 | import net.bmahe.genetics4j.gpu.opencl.DeviceUtils; | |
33 | import net.bmahe.genetics4j.gpu.opencl.KernelInfoReader; | |
34 | import net.bmahe.genetics4j.gpu.opencl.OpenCLExecutionContext; | |
35 | import net.bmahe.genetics4j.gpu.opencl.PlatformReader; | |
36 | import net.bmahe.genetics4j.gpu.opencl.PlatformUtils; | |
37 | import net.bmahe.genetics4j.gpu.opencl.model.Device; | |
38 | import net.bmahe.genetics4j.gpu.opencl.model.KernelInfo; | |
39 | import net.bmahe.genetics4j.gpu.opencl.model.Platform; | |
40 | import net.bmahe.genetics4j.gpu.spec.GPUEAConfiguration; | |
41 | import net.bmahe.genetics4j.gpu.spec.GPUEAExecutionContext; | |
42 | import net.bmahe.genetics4j.gpu.spec.Program; | |
43 | ||
44 | /** | |
45 | * GPU-accelerated fitness evaluator that leverages OpenCL for high-performance evolutionary algorithm execution. | |
46 | * | |
47 | * <p>GPUFitnessEvaluator implements the core {@link FitnessEvaluator} interface to provide GPU acceleration | |
48 | * for fitness computation in evolutionary algorithms. This evaluator manages the complete OpenCL lifecycle, | |
49 | * from device discovery and kernel compilation to memory management and resource cleanup. | |
50 | * | |
51 | * <p>Key responsibilities include: | |
52 | * <ul> | |
53 | * <li><strong>OpenCL initialization</strong>: Platform and device discovery, context creation, and kernel compilation</li> | |
54 | * <li><strong>Resource management</strong>: Managing OpenCL contexts, command queues, programs, and kernels</li> | |
55 | * <li><strong>Population partitioning</strong>: Distributing work across multiple OpenCL devices</li> | |
56 | * <li><strong>Asynchronous execution</strong>: Coordinating concurrent GPU operations with CPU-side logic</li> | |
57 | * <li><strong>Memory lifecycle</strong>: Ensuring proper cleanup of GPU resources</li> | |
58 | * </ul> | |
59 | * | |
60 | * <p>Architecture overview: | |
61 | * <ol> | |
62 | * <li><strong>Initialization ({@link #preEvaluation})</strong>: Discover platforms/devices, compile kernels, create contexts</li> | |
63 | * <li><strong>Evaluation ({@link #evaluate})</strong>: Partition population, execute fitness computation on GPU</li> | |
64 | * <li><strong>Cleanup ({@link #postEvaluation})</strong>: Release all OpenCL resources and contexts</li> | |
65 | * </ol> | |
66 | * | |
67 | * <p>Multi-device support: | |
68 | * <ul> | |
69 | * <li><strong>Device filtering</strong>: Selects devices based on user-defined criteria (type, capabilities)</li> | |
70 | * <li><strong>Load balancing</strong>: Automatically distributes population across available devices</li> | |
71 | * <li><strong>Parallel execution</strong>: Concurrent fitness evaluation on multiple GPUs or devices</li> | |
72 | * <li><strong>Asynchronous coordination</strong>: Non-blocking execution with CompletableFuture-based results</li> | |
73 | * </ul> | |
74 | * | |
75 | * <p>Resource management patterns: | |
76 | * <ul> | |
77 | * <li><strong>Lazy initialization</strong>: OpenCL resources created only when needed</li> | |
78 | * <li><strong>Automatic cleanup</strong>: Guaranteed resource release through lifecycle methods</li> | |
79 | * <li><strong>Error recovery</strong>: Robust handling of OpenCL errors and device failures</li> | |
80 | * <li><strong>Memory optimization</strong>: Efficient GPU memory usage and transfer patterns</li> | |
81 | * </ul> | |
82 | * | |
83 | * <p>Example usage in GPU EA system: | |
84 | * <pre>{@code | |
85 | * // GPU configuration with OpenCL kernel | |
86 | * Program fitnessProgram = Program.ofResource("/kernels/optimization.cl"); | |
87 | * GPUEAConfiguration<Double> config = GPUEAConfigurationBuilder.<Double>builder() | |
88 | * .program(fitnessProgram) | |
89 | * .fitness(new MyGPUFitness()) | |
90 | * // ... other EA configuration | |
91 | * .build(); | |
92 | * | |
93 | * // Execution context with device preferences | |
94 | * GPUEAExecutionContext<Double> context = GPUEAExecutionContextBuilder.<Double>builder() | |
95 | * .populationSize(2000) | |
96 | * .deviceFilter(device -> device.type() == DeviceType.GPU) | |
97 | * .platformFilter(platform -> platform.profile() == PlatformProfile.FULL_PROFILE) | |
98 | * .build(); | |
99 | * | |
100 | * // Evaluator handles all OpenCL lifecycle automatically | |
101 | * GPUFitnessEvaluator<Double> evaluator = new GPUFitnessEvaluator<>(context, config, executorService); | |
102 | * | |
103 | * // Used by EA system - lifecycle managed automatically | |
104 | * EASystem<Double> system = EASystemFactory.from(config, context, executorService, evaluator); | |
105 | * }</pre> | |
106 | * | |
107 | * <p>Performance characteristics: | |
108 | * <ul> | |
109 | * <li><strong>Initialization overhead</strong>: One-time setup cost for OpenCL compilation and context creation</li> | |
110 | * <li><strong>Scalability</strong>: Performance scales with population size and problem complexity</li> | |
111 | * <li><strong>Memory bandwidth</strong>: Optimal for problems with high computational intensity</li> | |
112 | * <li><strong>Concurrency</strong>: Supports concurrent evaluation across multiple devices</li> | |
113 | * </ul> | |
114 | * | |
115 | * <p>Error handling: | |
116 | * <ul> | |
117 | * <li><strong>Device failures</strong>: Graceful degradation when devices become unavailable</li> | |
118 | * <li><strong>Memory errors</strong>: Proper cleanup and error reporting for GPU memory issues</li> | |
119 | * <li><strong>Compilation errors</strong>: Clear error messages for kernel compilation failures</li> | |
120 | * <li><strong>Resource leaks</strong>: Guaranteed cleanup even in exceptional circumstances</li> | |
121 | * </ul> | |
122 | * | |
123 | * @param <T> the type of fitness values produced, must be comparable for selection operations | |
124 | * @see FitnessEvaluator | |
125 | * @see GPUEAConfiguration | |
126 | * @see GPUEAExecutionContext | |
127 | * @see OpenCLExecutionContext | |
128 | * @see net.bmahe.genetics4j.gpu.fitness.OpenCLFitness | |
129 | */ | |
130 | public class GPUFitnessEvaluator<T extends Comparable<T>> implements FitnessEvaluator<T> { | |
131 | public static final Logger logger = LogManager.getLogger(GPUFitnessEvaluator.class); | |
132 | ||
133 | private final GPUEAExecutionContext<T> gpuEAExecutionContext; | |
134 | private final GPUEAConfiguration<T> gpuEAConfiguration; | |
135 | private final ExecutorService executorService; | |
136 | ||
137 | private List<Pair<Platform, Device>> selectedPlatformToDevice; | |
138 | ||
139 |
2
1. <init> : Removed assignment to member variable clContexts → NO_COVERAGE 2. <init> : removed call to java/util/ArrayList::<init> → NO_COVERAGE |
final List<cl_context> clContexts = new ArrayList<>(); |
140 |
2
1. <init> : removed call to java/util/ArrayList::<init> → NO_COVERAGE 2. <init> : Removed assignment to member variable clCommandQueues → NO_COVERAGE |
final List<cl_command_queue> clCommandQueues = new ArrayList<>(); |
141 |
2
1. <init> : Removed assignment to member variable clPrograms → NO_COVERAGE 2. <init> : removed call to java/util/ArrayList::<init> → NO_COVERAGE |
final List<cl_program> clPrograms = new ArrayList<>(); |
142 |
2
1. <init> : Removed assignment to member variable clKernels → NO_COVERAGE 2. <init> : removed call to java/util/ArrayList::<init> → NO_COVERAGE |
final List<Map<String, cl_kernel>> clKernels = new ArrayList<>(); |
143 |
2
1. <init> : Removed assignment to member variable clExecutionContexts → NO_COVERAGE 2. <init> : removed call to java/util/ArrayList::<init> → NO_COVERAGE |
final List<OpenCLExecutionContext> clExecutionContexts = new ArrayList<>(); |
144 | ||
145 | /** | |
146 | * Constructs a GPU fitness evaluator with the specified configuration and execution context. | |
147 | * | |
148 | * <p>Initializes the evaluator with GPU-specific configuration and execution parameters. | |
149 | * The evaluator will use the provided executor service for coordinating asynchronous | |
150 | * operations between CPU and GPU components. | |
151 | * | |
152 | * <p>The constructor performs minimal initialization - the actual OpenCL setup occurs | |
153 | * during {@link #preEvaluation()} to follow the fitness evaluator lifecycle pattern. | |
154 | * | |
155 | * @param _gpuEAExecutionContext the GPU execution context with device filters and population settings | |
156 | * @param _gpuEAConfiguration the GPU EA configuration with OpenCL program and fitness function | |
157 | * @param _executorService the executor service for managing asynchronous operations | |
158 | * @throws IllegalArgumentException if any parameter is null | |
159 | */ | |
160 | public GPUFitnessEvaluator(final GPUEAExecutionContext<T> _gpuEAExecutionContext, | |
161 | final GPUEAConfiguration<T> _gpuEAConfiguration, final ExecutorService _executorService) { | |
162 | Validate.notNull(_gpuEAExecutionContext); | |
163 | Validate.notNull(_gpuEAConfiguration); | |
164 | Validate.notNull(_executorService); | |
165 | ||
166 |
1
1. <init> : Removed assignment to member variable gpuEAExecutionContext → NO_COVERAGE |
this.gpuEAExecutionContext = _gpuEAExecutionContext; |
167 |
1
1. <init> : Removed assignment to member variable gpuEAConfiguration → NO_COVERAGE |
this.gpuEAConfiguration = _gpuEAConfiguration; |
168 |
1
1. <init> : Removed assignment to member variable executorService → NO_COVERAGE |
this.executorService = _executorService; |
169 | ||
170 |
2
1. <init> : removed call to org/jocl/CL::setExceptionsEnabled → NO_COVERAGE 2. <init> : Substituted 1 with 0 → NO_COVERAGE |
CL.setExceptionsEnabled(true); |
171 | } | |
172 | ||
173 | private String loadResource(final String filename) { | |
174 | Validate.notBlank(filename); | |
175 | ||
176 | try { | |
177 |
3
1. loadResource : replaced call to org/apache/commons/io/IOUtils::resourceToString with argument → NO_COVERAGE 2. loadResource : replaced return value with "" for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::loadResource → NO_COVERAGE 3. loadResource : removed call to org/apache/commons/io/IOUtils::resourceToString → NO_COVERAGE |
return IOUtils.resourceToString(filename, StandardCharsets.UTF_8); |
178 | } catch (IOException e) { | |
179 |
1
1. loadResource : removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE |
throw new IllegalStateException("Unable to load resource " + filename, e); |
180 | } | |
181 | } | |
182 | ||
183 | private List<String> grabProgramSources() { | |
184 |
1
1. grabProgramSources : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::program → NO_COVERAGE |
final Program programSpec = gpuEAConfiguration.program(); |
185 | ||
186 | logger.info("Load program source: {}", programSpec); | |
187 | ||
188 |
1
1. grabProgramSources : removed call to java/util/ArrayList::<init> → NO_COVERAGE |
final List<String> sources = new ArrayList<>(); |
189 | ||
190 |
2
1. grabProgramSources : removed call to net/bmahe/genetics4j/gpu/spec/Program::content → NO_COVERAGE 2. grabProgramSources : removed call to java/util/List::addAll → NO_COVERAGE |
sources.addAll(programSpec.content()); |
191 | ||
192 |
1
1. grabProgramSources : removed call to net/bmahe/genetics4j/gpu/spec/Program::resources → NO_COVERAGE |
programSpec.resources() |
193 |
1
1. grabProgramSources : removed call to java/util/Set::stream → NO_COVERAGE |
.stream() |
194 |
5
1. lambda$grabProgramSources$0 : replaced call to net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::loadResource with argument → NO_COVERAGE 2. grabProgramSources : removed call to java/util/stream/Stream::map → NO_COVERAGE 3. lambda$grabProgramSources$0 : replaced return value with "" for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$grabProgramSources$0 → NO_COVERAGE 4. lambda$grabProgramSources$0 : removed call to net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::loadResource → NO_COVERAGE 5. grabProgramSources : replaced call to java/util/stream/Stream::map with receiver → NO_COVERAGE |
.map(resource -> loadResource(resource)) |
195 |
1
1. grabProgramSources : removed call to java/util/stream/Stream::forEach → NO_COVERAGE |
.forEach(program -> { |
196 |
1
1. lambda$grabProgramSources$1 : removed call to java/util/List::add → NO_COVERAGE |
sources.add(program); |
197 | }); | |
198 | ||
199 |
1
1. grabProgramSources : replaced return value with Collections.emptyList for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::grabProgramSources → NO_COVERAGE |
return sources; |
200 | } | |
201 | ||
202 | /** | |
203 | * Initializes OpenCL resources and prepares GPU devices for fitness evaluation. | |
204 | * | |
205 | * <p>This method performs the complete OpenCL initialization sequence: | |
206 | * <ol> | |
207 | * <li><strong>Platform discovery</strong>: Enumerates available OpenCL platforms</li> | |
208 | * <li><strong>Device filtering</strong>: Selects devices based on configured filters</li> | |
209 | * <li><strong>Context creation</strong>: Creates OpenCL contexts for selected devices</li> | |
210 | * <li><strong>Queue setup</strong>: Creates command queues with profiling and out-of-order execution</li> | |
211 | * <li><strong>Program compilation</strong>: Compiles OpenCL kernels from source code</li> | |
212 | * <li><strong>Kernel preparation</strong>: Creates kernel objects and queries execution info</li> | |
213 | * <li><strong>Fitness initialization</strong>: Calls lifecycle hooks on the fitness function</li> | |
214 | * </ol> | |
215 | * | |
216 | * <p>Device selection process: | |
217 | * <ul> | |
218 | * <li>Applies platform filters to discovered OpenCL platforms</li> | |
219 | * <li>Enumerates devices for each qualifying platform</li> | |
220 | * <li>Applies device filters to select appropriate devices</li> | |
221 | * <li>Validates that at least one device is available</li> | |
222 | * </ul> | |
223 | * | |
224 | * <p>The method creates separate OpenCL contexts for each selected device to enable | |
225 | * concurrent execution and optimal resource utilization. Each context includes | |
226 | * compiled programs and kernel objects ready for fitness evaluation. | |
227 | * | |
228 | * @throws IllegalStateException if no compatible devices are found | |
229 | * @throws RuntimeException if OpenCL initialization, program compilation, or kernel creation fails | |
230 | */ | |
231 | @Override | |
232 | public void preEvaluation() { | |
233 | logger.trace("Init..."); | |
234 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluator::preEvaluation → NO_COVERAGE |
FitnessEvaluator.super.preEvaluation(); |
235 | ||
236 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/PlatformReader::<init> → NO_COVERAGE |
final var platformReader = new PlatformReader(); |
237 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/DeviceReader::<init> → NO_COVERAGE |
final var deviceReader = new DeviceReader(); |
238 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/KernelInfoReader::<init> → NO_COVERAGE |
final var kernelInfoReader = new KernelInfoReader(); |
239 | ||
240 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/PlatformUtils::numPlatforms → NO_COVERAGE |
final int numPlatforms = PlatformUtils.numPlatforms(); |
241 | logger.info("Found {} platforms", numPlatforms); | |
242 | ||
243 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/PlatformUtils::platformIds → NO_COVERAGE |
final List<cl_platform_id> platformIds = PlatformUtils.platformIds(numPlatforms); |
244 | ||
245 | logger.info("Selecting platform and devices"); | |
246 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAExecutionContext::platformFilters → NO_COVERAGE |
final var platformFilters = gpuEAExecutionContext.platformFilters(); |
247 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAExecutionContext::deviceFilters → NO_COVERAGE |
final var deviceFilters = gpuEAExecutionContext.deviceFilters(); |
248 | ||
249 |
1
1. preEvaluation : removed call to java/util/List::stream → NO_COVERAGE |
selectedPlatformToDevice = platformIds.stream() |
250 | .map(platformReader::read) | |
251 |
2
1. preEvaluation : replaced call to java/util/stream/Stream::filter with receiver → NO_COVERAGE 2. preEvaluation : removed call to java/util/stream/Stream::filter → NO_COVERAGE |
.filter(platformFilters) |
252 |
2
1. preEvaluation : replaced call to java/util/stream/Stream::flatMap with receiver → NO_COVERAGE 2. preEvaluation : removed call to java/util/stream/Stream::flatMap → NO_COVERAGE |
.flatMap(platform -> { |
253 |
1
1. lambda$preEvaluation$3 : removed call to net/bmahe/genetics4j/gpu/opencl/model/Platform::platformId → NO_COVERAGE |
final var platformId = platform.platformId(); |
254 |
1
1. lambda$preEvaluation$3 : removed call to net/bmahe/genetics4j/gpu/opencl/DeviceUtils::numDevices → NO_COVERAGE |
final int numDevices = DeviceUtils.numDevices(platformId); |
255 | logger.trace("\tPlatform {}: {} devices", platform.name(), numDevices); | |
256 | ||
257 |
1
1. lambda$preEvaluation$3 : removed call to net/bmahe/genetics4j/gpu/opencl/DeviceUtils::getDeviceIds → NO_COVERAGE |
final var deviceIds = DeviceUtils.getDeviceIds(platformId, numDevices); |
258 |
2
1. lambda$preEvaluation$3 : removed call to java/util/List::stream → NO_COVERAGE 2. lambda$preEvaluation$3 : replaced return value with Stream.empty for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$3 → NO_COVERAGE |
return deviceIds.stream() |
259 |
4
1. lambda$preEvaluation$3 : replaced call to java/util/stream/Stream::map with receiver → NO_COVERAGE 2. lambda$preEvaluation$3 : removed call to java/util/stream/Stream::map → NO_COVERAGE 3. lambda$preEvaluation$2 : removed call to org/apache/commons/lang3/tuple/Pair::of → NO_COVERAGE 4. lambda$preEvaluation$2 : replaced return value with null for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$2 → NO_COVERAGE |
.map(deviceId -> Pair.of(platform, deviceId)); |
260 | }) | |
261 |
2
1. preEvaluation : replaced call to java/util/stream/Stream::map with receiver → NO_COVERAGE 2. preEvaluation : removed call to java/util/stream/Stream::map → NO_COVERAGE |
.map(platformToDeviceId -> { |
262 |
1
1. lambda$preEvaluation$4 : removed call to org/apache/commons/lang3/tuple/Pair::getLeft → NO_COVERAGE |
final var platform = platformToDeviceId.getLeft(); |
263 |
1
1. lambda$preEvaluation$4 : removed call to net/bmahe/genetics4j/gpu/opencl/model/Platform::platformId → NO_COVERAGE |
final var platformId = platform.platformId(); |
264 |
1
1. lambda$preEvaluation$4 : removed call to org/apache/commons/lang3/tuple/Pair::getRight → NO_COVERAGE |
final var deviceID = platformToDeviceId.getRight(); |
265 | ||
266 |
3
1. lambda$preEvaluation$4 : replaced return value with null for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$4 → NO_COVERAGE 2. lambda$preEvaluation$4 : removed call to net/bmahe/genetics4j/gpu/opencl/DeviceReader::read → NO_COVERAGE 3. lambda$preEvaluation$4 : removed call to org/apache/commons/lang3/tuple/Pair::of → NO_COVERAGE |
return Pair.of(platform, deviceReader.read(platformId, deviceID)); |
267 | }) | |
268 |
6
1. lambda$preEvaluation$5 : removed call to java/util/function/Predicate::test → NO_COVERAGE 2. preEvaluation : removed call to java/util/stream/Stream::filter → NO_COVERAGE 3. lambda$preEvaluation$5 : replaced boolean return with true for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$5 → NO_COVERAGE 4. lambda$preEvaluation$5 : replaced boolean return with false for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$5 → NO_COVERAGE 5. lambda$preEvaluation$5 : removed call to org/apache/commons/lang3/tuple/Pair::getRight → NO_COVERAGE 6. preEvaluation : replaced call to java/util/stream/Stream::filter with receiver → NO_COVERAGE |
.filter(platformToDevice -> deviceFilters.test(platformToDevice.getRight())) |
269 |
2
1. preEvaluation : Removed assignment to member variable selectedPlatformToDevice → NO_COVERAGE 2. preEvaluation : removed call to java/util/stream/Stream::toList → NO_COVERAGE |
.toList(); |
270 | ||
271 | if (logger.isTraceEnabled()) { | |
272 | logger.trace("============================"); | |
273 | logger.trace("Selected devices:"); | |
274 |
1
1. preEvaluation : removed call to java/util/List::forEach → NO_COVERAGE |
selectedPlatformToDevice.forEach(pd -> { |
275 | logger.trace("{}", pd.getLeft()); | |
276 | logger.trace("\t{}", pd.getRight()); | |
277 | }); | |
278 | logger.trace("============================"); | |
279 | } | |
280 | ||
281 | Validate.isTrue(selectedPlatformToDevice.size() > 0); | |
282 | ||
283 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::grabProgramSources → NO_COVERAGE |
final List<String> programs = grabProgramSources(); |
284 |
3
1. preEvaluation : removed call to java/util/List::size → NO_COVERAGE 2. preEvaluation : replaced call to java/util/List::toArray with argument → NO_COVERAGE 3. preEvaluation : removed call to java/util/List::toArray → NO_COVERAGE |
final String[] programsArr = programs.toArray(new String[programs.size()]); |
285 | ||
286 | for (final var platformAndDevice : selectedPlatformToDevice) { | |
287 |
1
1. preEvaluation : removed call to org/apache/commons/lang3/tuple/Pair::getLeft → NO_COVERAGE |
final var platform = platformAndDevice.getLeft(); |
288 |
1
1. preEvaluation : removed call to org/apache/commons/lang3/tuple/Pair::getRight → NO_COVERAGE |
final var device = platformAndDevice.getRight(); |
289 | ||
290 | logger.info("Processing platform [{}] / device [{}]", platform.name(), device.name()); | |
291 | ||
292 | logger.info("\tCreating context"); | |
293 |
1
1. preEvaluation : removed call to org/jocl/cl_context_properties::<init> → NO_COVERAGE |
cl_context_properties contextProperties = new cl_context_properties(); |
294 |
3
1. preEvaluation : Substituted 4228 with 4229 → NO_COVERAGE 2. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/model/Platform::platformId → NO_COVERAGE 3. preEvaluation : removed call to org/jocl/cl_context_properties::addProperty → NO_COVERAGE |
contextProperties.addProperty(CL.CL_CONTEXT_PLATFORM, platform.platformId()); |
295 | ||
296 |
3
1. preEvaluation : Substituted 1 with 0 → NO_COVERAGE 2. preEvaluation : Substituted 0 with 1 → NO_COVERAGE 3. preEvaluation : Substituted 1 with 0 → NO_COVERAGE |
final cl_context context = CL |
297 |
2
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceId → NO_COVERAGE 2. preEvaluation : removed call to org/jocl/CL::clCreateContext → NO_COVERAGE |
.clCreateContext(contextProperties, 1, new cl_device_id[] { device.deviceId() }, null, null, null); |
298 | ||
299 | logger.info("\tCreating command queue"); | |
300 |
1
1. preEvaluation : removed call to org/jocl/cl_queue_properties::<init> → NO_COVERAGE |
final cl_queue_properties queueProperties = new cl_queue_properties(); |
301 |
3
1. preEvaluation : Substituted 4243 with 4244 → NO_COVERAGE 2. preEvaluation : Substituted 3 with 4 → NO_COVERAGE 3. preEvaluation : removed call to org/jocl/cl_queue_properties::addProperty → NO_COVERAGE |
queueProperties.addProperty(CL.CL_QUEUE_PROPERTIES, |
302 | CL.CL_QUEUE_PROFILING_ENABLE | CL.CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE); | |
303 | final cl_command_queue commandQueue = CL | |
304 |
2
1. preEvaluation : removed call to org/jocl/CL::clCreateCommandQueueWithProperties → NO_COVERAGE 2. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceId → NO_COVERAGE |
.clCreateCommandQueueWithProperties(context, device.deviceId(), queueProperties, null); |
305 | ||
306 | logger.info("\tCreate program"); | |
307 |
1
1. preEvaluation : removed call to org/jocl/CL::clCreateProgramWithSource → NO_COVERAGE |
final cl_program program = CL.clCreateProgramWithSource(context, programsArr.length, programsArr, null, null); |
308 | ||
309 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::program → NO_COVERAGE |
final var programSpec = gpuEAConfiguration.program(); |
310 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/Program::buildOptions → NO_COVERAGE |
final var buildOptions = programSpec.buildOptions() |
311 |
2
1. preEvaluation : replaced call to java/util/Optional::orElse with argument → NO_COVERAGE 2. preEvaluation : removed call to java/util/Optional::orElse → NO_COVERAGE |
.orElse(null); |
312 | logger.info("\tBuilding program with options: {}", buildOptions); | |
313 |
3
1. preEvaluation : Substituted 0 with 1 → NO_COVERAGE 2. preEvaluation : replaced call to org/jocl/CL::clBuildProgram with argument → NO_COVERAGE 3. preEvaluation : removed call to org/jocl/CL::clBuildProgram → NO_COVERAGE |
CL.clBuildProgram(program, 0, null, buildOptions, null, null); |
314 | ||
315 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::program → NO_COVERAGE |
final Set<String> kernelNames = gpuEAConfiguration.program() |
316 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/Program::kernelNames → NO_COVERAGE |
.kernelNames(); |
317 | ||
318 |
1
1. preEvaluation : removed call to java/util/HashMap::<init> → NO_COVERAGE |
final Map<String, cl_kernel> kernels = new HashMap<>(); |
319 |
1
1. preEvaluation : removed call to java/util/HashMap::<init> → NO_COVERAGE |
final Map<String, KernelInfo> kernelInfos = new HashMap<>(); |
320 | for (final String kernelName : kernelNames) { | |
321 | ||
322 | logger.info("\tCreate kernel {}", kernelName); | |
323 |
1
1. preEvaluation : removed call to org/jocl/CL::clCreateKernel → NO_COVERAGE |
final cl_kernel kernel = CL.clCreateKernel(program, kernelName, null); |
324 | Validate.notNull(kernel); | |
325 | ||
326 |
2
1. preEvaluation : removed call to java/util/Map::put → NO_COVERAGE 2. preEvaluation : replaced call to java/util/Map::put with argument → NO_COVERAGE |
kernels.put(kernelName, kernel); |
327 | ||
328 |
2
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/KernelInfoReader::read → NO_COVERAGE 2. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceId → NO_COVERAGE |
final var kernelInfo = kernelInfoReader.read(device.deviceId(), kernel, kernelName); |
329 | logger.trace("\t{}", kernelInfo); | |
330 |
2
1. preEvaluation : replaced call to java/util/Map::put with argument → NO_COVERAGE 2. preEvaluation : removed call to java/util/Map::put → NO_COVERAGE |
kernelInfos.put(kernelName, kernelInfo); |
331 | } | |
332 | ||
333 |
1
1. preEvaluation : removed call to java/util/List::add → NO_COVERAGE |
clContexts.add(context); |
334 |
1
1. preEvaluation : removed call to java/util/List::add → NO_COVERAGE |
clCommandQueues.add(commandQueue); |
335 |
1
1. preEvaluation : removed call to java/util/List::add → NO_COVERAGE |
clKernels.add(kernels); |
336 |
1
1. preEvaluation : removed call to java/util/List::add → NO_COVERAGE |
clPrograms.add(program); |
337 | ||
338 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::builder → NO_COVERAGE |
final var openCLExecutionContext = OpenCLExecutionContext.builder() |
339 |
2
1. preEvaluation : replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::platform with receiver → NO_COVERAGE 2. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::platform → NO_COVERAGE |
.platform(platform) |
340 |
2
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::device → NO_COVERAGE 2. preEvaluation : replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::device with receiver → NO_COVERAGE |
.device(device) |
341 |
2
1. preEvaluation : replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clContext with receiver → NO_COVERAGE 2. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clContext → NO_COVERAGE |
.clContext(context) |
342 |
2
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clCommandQueue → NO_COVERAGE 2. preEvaluation : replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clCommandQueue with receiver → NO_COVERAGE |
.clCommandQueue(commandQueue) |
343 |
2
1. preEvaluation : replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernels with receiver → NO_COVERAGE 2. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernels → NO_COVERAGE |
.kernels(kernels) |
344 |
2
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernelInfos → NO_COVERAGE 2. preEvaluation : replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernelInfos with receiver → NO_COVERAGE |
.kernelInfos(kernelInfos) |
345 |
2
1. preEvaluation : replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clProgram with receiver → NO_COVERAGE 2. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clProgram → NO_COVERAGE |
.clProgram(program) |
346 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::build → NO_COVERAGE |
.build(); |
347 | ||
348 |
1
1. preEvaluation : removed call to java/util/List::add → NO_COVERAGE |
clExecutionContexts.add(openCLExecutionContext); |
349 | } | |
350 | ||
351 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::fitness → NO_COVERAGE |
final var fitness = gpuEAConfiguration.fitness(); |
352 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeAllEvaluations → NO_COVERAGE |
fitness.beforeAllEvaluations(); |
353 | for (final OpenCLExecutionContext clExecutionContext : clExecutionContexts) { | |
354 |
1
1. preEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeAllEvaluations → NO_COVERAGE |
fitness.beforeAllEvaluations(clExecutionContext, executorService); |
355 | } | |
356 | } | |
357 | ||
358 | /** | |
359 | * Evaluates fitness for a population of genotypes using GPU acceleration. | |
360 | * | |
361 | * <p>This method implements the core fitness evaluation logic by distributing the population | |
362 | * across available OpenCL devices and executing fitness computation concurrently. The | |
363 | * evaluation process follows these steps: | |
364 | * | |
365 | * <ol> | |
366 | * <li><strong>Population partitioning</strong>: Divides genotypes across available devices</li> | |
367 | * <li><strong>Parallel dispatch</strong>: Submits evaluation tasks to each device asynchronously</li> | |
368 | * <li><strong>GPU execution</strong>: Executes OpenCL kernels for fitness computation</li> | |
369 | * <li><strong>Result collection</strong>: Gathers fitness values from all devices</li> | |
370 | * <li><strong>Result aggregation</strong>: Combines results preserving original order</li> | |
371 | * </ol> | |
372 | * | |
373 | * <p>Load balancing strategy: | |
374 | * <ul> | |
375 | * <li>Automatically calculates partition size based on population and device count</li> | |
376 | * <li>Round-robin assignment of partitions to devices for balanced workload</li> | |
377 | * <li>Asynchronous execution allows devices to work at their optimal pace</li> | |
378 | * </ul> | |
379 | * | |
380 | * <p>The method coordinates with the configured fitness function through lifecycle hooks: | |
381 | * <ul> | |
382 | * <li>{@code beforeEvaluation()}: Called before each device partition evaluation</li> | |
383 | * <li>{@code compute()}: Executes the actual GPU fitness computation</li> | |
384 | * <li>{@code afterEvaluation()}: Called after each device partition completes</li> | |
385 | * </ul> | |
386 | * | |
387 | * <p>Concurrency and performance: | |
388 | * <ul> | |
389 | * <li>Multiple devices execute evaluation partitions concurrently</li> | |
390 | * <li>CompletableFuture-based coordination for non-blocking execution</li> | |
391 | * <li>Automatic workload distribution across available GPU resources</li> | |
392 | * </ul> | |
393 | * | |
394 | * @param generation the current generation number for context and logging | |
395 | * @param genotypes the population of genotypes to evaluate | |
396 | * @return fitness values corresponding to each genotype in the same order | |
397 | * @throws IllegalArgumentException if genotypes is null or empty | |
398 | * @throws RuntimeException if GPU evaluation fails or OpenCL errors occur | |
399 | */ | |
400 | @Override | |
401 | public List<T> evaluate(final long generation, final List<Genotype> genotypes) { | |
402 | ||
403 |
1
1. evaluate : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::fitness → NO_COVERAGE |
final var fitness = gpuEAConfiguration.fitness(); |
404 | ||
405 | /** | |
406 | * TODO make it configurable from execution context | |
407 | */ | |
408 |
5
1. evaluate : removed call to java/util/List::size → NO_COVERAGE 2. evaluate : Replaced double division with multiplication → NO_COVERAGE 3. evaluate : removed call to java/util/List::size → NO_COVERAGE 4. evaluate : removed call to java/lang/Math::ceil → NO_COVERAGE 5. evaluate : replaced call to java/lang/Math::ceil with argument → NO_COVERAGE |
final int partitionSize = (int) (Math.ceil((double) genotypes.size() / clExecutionContexts.size())); |
409 |
2
1. evaluate : replaced call to org/apache/commons/collections4/ListUtils::partition with argument → NO_COVERAGE 2. evaluate : removed call to org/apache/commons/collections4/ListUtils::partition → NO_COVERAGE |
final var subGenotypes = ListUtils.partition(genotypes, partitionSize); |
410 | logger.debug("Genotype decomposed in {} partition(s)", subGenotypes.size()); | |
411 | if (logger.isTraceEnabled()) { | |
412 |
6
1. evaluate : removed conditional - replaced comparison check with true → NO_COVERAGE 2. evaluate : negated conditional → NO_COVERAGE 3. evaluate : changed conditional boundary → NO_COVERAGE 4. evaluate : Substituted 0 with 1 → NO_COVERAGE 5. evaluate : removed call to java/util/List::size → NO_COVERAGE 6. evaluate : removed conditional - replaced comparison check with false → NO_COVERAGE |
for (int i = 0; i < subGenotypes.size(); i++) { |
413 |
1
1. evaluate : removed call to java/util/List::get → NO_COVERAGE |
final List<Genotype> subGenotype = subGenotypes.get(i); |
414 | logger.trace("\tPartition {} with {} elements", i, subGenotype.size()); | |
415 | } | |
416 | } | |
417 | ||
418 |
1
1. evaluate : removed call to java/util/ArrayList::<init> → NO_COVERAGE |
final List<CompletableFuture<List<T>>> subResultsCF = new ArrayList<>(); |
419 |
6
1. evaluate : removed conditional - replaced comparison check with false → NO_COVERAGE 2. evaluate : removed call to java/util/List::size → NO_COVERAGE 3. evaluate : Substituted 0 with 1 → NO_COVERAGE 4. evaluate : removed conditional - replaced comparison check with true → NO_COVERAGE 5. evaluate : negated conditional → NO_COVERAGE 6. evaluate : changed conditional boundary → NO_COVERAGE |
for (int i = 0; i < subGenotypes.size(); i++) { |
420 |
3
1. evaluate : removed call to java/util/List::size → NO_COVERAGE 2. evaluate : removed call to java/util/List::get → NO_COVERAGE 3. evaluate : Replaced integer modulus with multiplication → NO_COVERAGE |
final var openCLExecutionContext = clExecutionContexts.get(i % clExecutionContexts.size()); |
421 |
1
1. evaluate : removed call to java/util/List::get → NO_COVERAGE |
final var subGenotype = subGenotypes.get(i); |
422 | ||
423 |
1
1. evaluate : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeEvaluation → NO_COVERAGE |
fitness.beforeEvaluation(generation, subGenotype); |
424 |
1
1. evaluate : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeEvaluation → NO_COVERAGE |
fitness.beforeEvaluation(openCLExecutionContext, executorService, generation, subGenotype); |
425 | ||
426 |
1
1. evaluate : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::compute → NO_COVERAGE |
final var resultsCF = fitness.compute(openCLExecutionContext, executorService, generation, subGenotype) |
427 |
2
1. evaluate : removed call to java/util/concurrent/CompletableFuture::thenApply → NO_COVERAGE 2. evaluate : replaced call to java/util/concurrent/CompletableFuture::thenApply with receiver → NO_COVERAGE |
.thenApply((results) -> { |
428 | ||
429 |
1
1. lambda$evaluate$7 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterEvaluation → NO_COVERAGE |
fitness.afterEvaluation(openCLExecutionContext, executorService, generation, subGenotype); |
430 |
1
1. lambda$evaluate$7 : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterEvaluation → NO_COVERAGE |
fitness.afterEvaluation(generation, subGenotype); |
431 | ||
432 |
1
1. lambda$evaluate$7 : replaced return value with Collections.emptyList for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$evaluate$7 → NO_COVERAGE |
return results; |
433 | }); | |
434 | ||
435 |
1
1. evaluate : removed call to java/util/List::add → NO_COVERAGE |
subResultsCF.add(resultsCF); |
436 | } | |
437 | ||
438 |
2
1. evaluate : removed call to java/util/ArrayList::<init> → NO_COVERAGE 2. evaluate : removed call to java/util/List::size → NO_COVERAGE |
final List<T> resultsEvaluation = new ArrayList<>(genotypes.size()); |
439 | for (final CompletableFuture<List<T>> subResultCF : subResultsCF) { | |
440 |
1
1. evaluate : removed call to java/util/concurrent/CompletableFuture::join → NO_COVERAGE |
final var fitnessResults = subResultCF.join(); |
441 |
1
1. evaluate : removed call to java/util/List::addAll → NO_COVERAGE |
resultsEvaluation.addAll(fitnessResults); |
442 | } | |
443 |
1
1. evaluate : replaced return value with Collections.emptyList for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::evaluate → NO_COVERAGE |
return resultsEvaluation; |
444 | } | |
445 | ||
446 | /** | |
447 | * Cleans up OpenCL resources and releases GPU memory after evaluation completion. | |
448 | * | |
449 | * <p>This method performs comprehensive cleanup of all OpenCL resources in the proper order | |
450 | * to prevent memory leaks and ensure clean shutdown. The cleanup sequence follows OpenCL | |
451 | * best practices for resource deallocation: | |
452 | * | |
453 | * <ol> | |
454 | * <li><strong>Fitness cleanup</strong>: Calls lifecycle hooks on the fitness function</li> | |
455 | * <li><strong>Kernel release</strong>: Releases all compiled kernel objects</li> | |
456 | * <li><strong>Program release</strong>: Releases compiled OpenCL programs</li> | |
457 | * <li><strong>Queue release</strong>: Releases command queues and pending operations</li> | |
458 | * <li><strong>Context release</strong>: Releases OpenCL contexts and associated memory</li> | |
459 | * <li><strong>Reference cleanup</strong>: Clears internal data structures and references</li> | |
460 | * </ol> | |
461 | * | |
462 | * <p>Resource management guarantees: | |
463 | * <ul> | |
464 | * <li>All GPU memory allocations are properly released</li> | |
465 | * <li>OpenCL objects are released in dependency order to avoid errors</li> | |
466 | * <li>No resource leaks occur even if individual cleanup operations fail</li> | |
467 | * <li>Evaluator returns to a clean state ready for potential reinitialization</li> | |
468 | * </ul> | |
469 | * | |
470 | * <p>The method coordinates with the configured fitness function to ensure any | |
471 | * fitness-specific resources (buffers, textures, etc.) are also properly cleaned up | |
472 | * through the {@code afterAllEvaluations()} lifecycle hooks. | |
473 | * | |
474 | * @throws RuntimeException if cleanup operations fail (logged but not propagated to prevent | |
475 | * interference with EA system shutdown) | |
476 | */ | |
477 | @Override | |
478 | public void postEvaluation() { | |
479 | ||
480 |
1
1. postEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::fitness → NO_COVERAGE |
final var fitness = gpuEAConfiguration.fitness(); |
481 | ||
482 | for (final OpenCLExecutionContext clExecutionContext : clExecutionContexts) { | |
483 |
1
1. postEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterAllEvaluations → NO_COVERAGE |
fitness.afterAllEvaluations(clExecutionContext, executorService); |
484 | } | |
485 |
1
1. postEvaluation : removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterAllEvaluations → NO_COVERAGE |
fitness.afterAllEvaluations(); |
486 | ||
487 | logger.debug("Releasing kernels"); | |
488 | ||
489 | for (final Map<String, cl_kernel> kernels : clKernels) { | |
490 |
1
1. postEvaluation : removed call to java/util/Map::values → NO_COVERAGE |
for (final cl_kernel clKernel : kernels.values()) { |
491 |
1
1. postEvaluation : removed call to org/jocl/CL::clReleaseKernel → NO_COVERAGE |
CL.clReleaseKernel(clKernel); |
492 | } | |
493 | } | |
494 |
1
1. postEvaluation : removed call to java/util/List::clear → NO_COVERAGE |
clKernels.clear(); |
495 | ||
496 | logger.debug("Releasing programs"); | |
497 | for (final cl_program clProgram : clPrograms) { | |
498 |
1
1. postEvaluation : removed call to org/jocl/CL::clReleaseProgram → NO_COVERAGE |
CL.clReleaseProgram(clProgram); |
499 | } | |
500 |
1
1. postEvaluation : removed call to java/util/List::clear → NO_COVERAGE |
clPrograms.clear(); |
501 | ||
502 | logger.debug("Releasing command queues"); | |
503 | for (final cl_command_queue clCommandQueue : clCommandQueues) { | |
504 |
1
1. postEvaluation : removed call to org/jocl/CL::clReleaseCommandQueue → NO_COVERAGE |
CL.clReleaseCommandQueue(clCommandQueue); |
505 | } | |
506 |
1
1. postEvaluation : removed call to java/util/List::clear → NO_COVERAGE |
clCommandQueues.clear(); |
507 | ||
508 | logger.debug("Releasing contexts"); | |
509 | for (final cl_context clContext : clContexts) { | |
510 |
1
1. postEvaluation : removed call to org/jocl/CL::clReleaseContext → NO_COVERAGE |
CL.clReleaseContext(clContext); |
511 | } | |
512 |
1
1. postEvaluation : removed call to java/util/List::clear → NO_COVERAGE |
clContexts.clear(); |
513 | ||
514 |
1
1. postEvaluation : removed call to java/util/List::clear → NO_COVERAGE |
clExecutionContexts.clear(); |
515 |
1
1. postEvaluation : Removed assignment to member variable selectedPlatformToDevice → NO_COVERAGE |
selectedPlatformToDevice = null; |
516 | ||
517 |
1
1. postEvaluation : removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluator::postEvaluation → NO_COVERAGE |
FitnessEvaluator.super.postEvaluation(); |
518 | } | |
519 | } | |
Mutations | ||
139 |
1.1 2.2 |
|
140 |
1.1 2.2 |
|
141 |
1.1 2.2 |
|
142 |
1.1 2.2 |
|
143 |
1.1 2.2 |
|
166 |
1.1 |
|
167 |
1.1 |
|
168 |
1.1 |
|
170 |
1.1 2.2 |
|
177 |
1.1 2.2 3.3 |
|
179 |
1.1 |
|
184 |
1.1 |
|
188 |
1.1 |
|
190 |
1.1 2.2 |
|
192 |
1.1 |
|
193 |
1.1 |
|
194 |
1.1 2.2 3.3 4.4 5.5 |
|
195 |
1.1 |
|
196 |
1.1 |
|
199 |
1.1 |
|
234 |
1.1 |
|
236 |
1.1 |
|
237 |
1.1 |
|
238 |
1.1 |
|
240 |
1.1 |
|
243 |
1.1 |
|
246 |
1.1 |
|
247 |
1.1 |
|
249 |
1.1 |
|
251 |
1.1 2.2 |
|
252 |
1.1 2.2 |
|
253 |
1.1 |
|
254 |
1.1 |
|
257 |
1.1 |
|
258 |
1.1 2.2 |
|
259 |
1.1 2.2 3.3 4.4 |
|
261 |
1.1 2.2 |
|
262 |
1.1 |
|
263 |
1.1 |
|
264 |
1.1 |
|
266 |
1.1 2.2 3.3 |
|
268 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
269 |
1.1 2.2 |
|
274 |
1.1 |
|
283 |
1.1 |
|
284 |
1.1 2.2 3.3 |
|
287 |
1.1 |
|
288 |
1.1 |
|
293 |
1.1 |
|
294 |
1.1 2.2 3.3 |
|
296 |
1.1 2.2 3.3 |
|
297 |
1.1 2.2 |
|
300 |
1.1 |
|
301 |
1.1 2.2 3.3 |
|
304 |
1.1 2.2 |
|
307 |
1.1 |
|
309 |
1.1 |
|
310 |
1.1 |
|
311 |
1.1 2.2 |
|
313 |
1.1 2.2 3.3 |
|
315 |
1.1 |
|
316 |
1.1 |
|
318 |
1.1 |
|
319 |
1.1 |
|
323 |
1.1 |
|
326 |
1.1 2.2 |
|
328 |
1.1 2.2 |
|
330 |
1.1 2.2 |
|
333 |
1.1 |
|
334 |
1.1 |
|
335 |
1.1 |
|
336 |
1.1 |
|
338 |
1.1 |
|
339 |
1.1 2.2 |
|
340 |
1.1 2.2 |
|
341 |
1.1 2.2 |
|
342 |
1.1 2.2 |
|
343 |
1.1 2.2 |
|
344 |
1.1 2.2 |
|
345 |
1.1 2.2 |
|
346 |
1.1 |
|
348 |
1.1 |
|
351 |
1.1 |
|
352 |
1.1 |
|
354 |
1.1 |
|
403 |
1.1 |
|
408 |
1.1 2.2 3.3 4.4 5.5 |
|
409 |
1.1 2.2 |
|
412 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
413 |
1.1 |
|
418 |
1.1 |
|
419 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
420 |
1.1 2.2 3.3 |
|
421 |
1.1 |
|
423 |
1.1 |
|
424 |
1.1 |
|
426 |
1.1 |
|
427 |
1.1 2.2 |
|
429 |
1.1 |
|
430 |
1.1 |
|
432 |
1.1 |
|
435 |
1.1 |
|
438 |
1.1 2.2 |
|
440 |
1.1 |
|
441 |
1.1 |
|
443 |
1.1 |
|
480 |
1.1 |
|
483 |
1.1 |
|
485 |
1.1 |
|
490 |
1.1 |
|
491 |
1.1 |
|
494 |
1.1 |
|
498 |
1.1 |
|
500 |
1.1 |
|
504 |
1.1 |
|
506 |
1.1 |
|
510 |
1.1 |
|
512 |
1.1 |
|
514 |
1.1 |
|
515 |
1.1 |
|
517 |
1.1 |