GPUFitnessEvaluator.java

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
Location : <init>
Killed by : none
Removed assignment to member variable clContexts → NO_COVERAGE

2.2
Location : <init>
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

140

1.1
Location : <init>
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

2.2
Location : <init>
Killed by : none
Removed assignment to member variable clCommandQueues → NO_COVERAGE

141

1.1
Location : <init>
Killed by : none
Removed assignment to member variable clPrograms → NO_COVERAGE

2.2
Location : <init>
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

142

1.1
Location : <init>
Killed by : none
Removed assignment to member variable clKernels → NO_COVERAGE

2.2
Location : <init>
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

143

1.1
Location : <init>
Killed by : none
Removed assignment to member variable clExecutionContexts → NO_COVERAGE

2.2
Location : <init>
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

166

1.1
Location : <init>
Killed by : none
Removed assignment to member variable gpuEAExecutionContext → NO_COVERAGE

167

1.1
Location : <init>
Killed by : none
Removed assignment to member variable gpuEAConfiguration → NO_COVERAGE

168

1.1
Location : <init>
Killed by : none
Removed assignment to member variable executorService → NO_COVERAGE

170

1.1
Location : <init>
Killed by : none
removed call to org/jocl/CL::setExceptionsEnabled → NO_COVERAGE

2.2
Location : <init>
Killed by : none
Substituted 1 with 0 → NO_COVERAGE

177

1.1
Location : loadResource
Killed by : none
replaced call to org/apache/commons/io/IOUtils::resourceToString with argument → NO_COVERAGE

2.2
Location : loadResource
Killed by : none
replaced return value with "" for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::loadResource → NO_COVERAGE

3.3
Location : loadResource
Killed by : none
removed call to org/apache/commons/io/IOUtils::resourceToString → NO_COVERAGE

179

1.1
Location : loadResource
Killed by : none
removed call to java/lang/IllegalStateException::<init> → NO_COVERAGE

184

1.1
Location : grabProgramSources
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::program → NO_COVERAGE

188

1.1
Location : grabProgramSources
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

190

1.1
Location : grabProgramSources
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/Program::content → NO_COVERAGE

2.2
Location : grabProgramSources
Killed by : none
removed call to java/util/List::addAll → NO_COVERAGE

192

1.1
Location : grabProgramSources
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/Program::resources → NO_COVERAGE

193

1.1
Location : grabProgramSources
Killed by : none
removed call to java/util/Set::stream → NO_COVERAGE

194

1.1
Location : lambda$grabProgramSources$0
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::loadResource with argument → NO_COVERAGE

2.2
Location : grabProgramSources
Killed by : none
removed call to java/util/stream/Stream::map → NO_COVERAGE

3.3
Location : lambda$grabProgramSources$0
Killed by : none
replaced return value with "" for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$grabProgramSources$0 → NO_COVERAGE

4.4
Location : lambda$grabProgramSources$0
Killed by : none
removed call to net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::loadResource → NO_COVERAGE

5.5
Location : grabProgramSources
Killed by : none
replaced call to java/util/stream/Stream::map with receiver → NO_COVERAGE

195

1.1
Location : grabProgramSources
Killed by : none
removed call to java/util/stream/Stream::forEach → NO_COVERAGE

196

1.1
Location : lambda$grabProgramSources$1
Killed by : none
removed call to java/util/List::add → NO_COVERAGE

199

1.1
Location : grabProgramSources
Killed by : none
replaced return value with Collections.emptyList for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::grabProgramSources → NO_COVERAGE

234

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluator::preEvaluation → NO_COVERAGE

236

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/PlatformReader::<init> → NO_COVERAGE

237

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/DeviceReader::<init> → NO_COVERAGE

238

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/KernelInfoReader::<init> → NO_COVERAGE

240

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/PlatformUtils::numPlatforms → NO_COVERAGE

243

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/PlatformUtils::platformIds → NO_COVERAGE

246

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAExecutionContext::platformFilters → NO_COVERAGE

247

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAExecutionContext::deviceFilters → NO_COVERAGE

249

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::stream → NO_COVERAGE

251

1.1
Location : preEvaluation
Killed by : none
replaced call to java/util/stream/Stream::filter with receiver → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to java/util/stream/Stream::filter → NO_COVERAGE

252

1.1
Location : preEvaluation
Killed by : none
replaced call to java/util/stream/Stream::flatMap with receiver → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to java/util/stream/Stream::flatMap → NO_COVERAGE

253

1.1
Location : lambda$preEvaluation$3
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/model/Platform::platformId → NO_COVERAGE

254

1.1
Location : lambda$preEvaluation$3
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/DeviceUtils::numDevices → NO_COVERAGE

257

1.1
Location : lambda$preEvaluation$3
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/DeviceUtils::getDeviceIds → NO_COVERAGE

258

1.1
Location : lambda$preEvaluation$3
Killed by : none
removed call to java/util/List::stream → NO_COVERAGE

2.2
Location : lambda$preEvaluation$3
Killed by : none
replaced return value with Stream.empty for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$3 → NO_COVERAGE

259

1.1
Location : lambda$preEvaluation$3
Killed by : none
replaced call to java/util/stream/Stream::map with receiver → NO_COVERAGE

2.2
Location : lambda$preEvaluation$3
Killed by : none
removed call to java/util/stream/Stream::map → NO_COVERAGE

3.3
Location : lambda$preEvaluation$2
Killed by : none
removed call to org/apache/commons/lang3/tuple/Pair::of → NO_COVERAGE

4.4
Location : lambda$preEvaluation$2
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$2 → NO_COVERAGE

261

1.1
Location : preEvaluation
Killed by : none
replaced call to java/util/stream/Stream::map with receiver → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to java/util/stream/Stream::map → NO_COVERAGE

262

1.1
Location : lambda$preEvaluation$4
Killed by : none
removed call to org/apache/commons/lang3/tuple/Pair::getLeft → NO_COVERAGE

263

1.1
Location : lambda$preEvaluation$4
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/model/Platform::platformId → NO_COVERAGE

264

1.1
Location : lambda$preEvaluation$4
Killed by : none
removed call to org/apache/commons/lang3/tuple/Pair::getRight → NO_COVERAGE

266

1.1
Location : lambda$preEvaluation$4
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$4 → NO_COVERAGE

2.2
Location : lambda$preEvaluation$4
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/DeviceReader::read → NO_COVERAGE

3.3
Location : lambda$preEvaluation$4
Killed by : none
removed call to org/apache/commons/lang3/tuple/Pair::of → NO_COVERAGE

268

1.1
Location : lambda$preEvaluation$5
Killed by : none
removed call to java/util/function/Predicate::test → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to java/util/stream/Stream::filter → NO_COVERAGE

3.3
Location : lambda$preEvaluation$5
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$5 → NO_COVERAGE

4.4
Location : lambda$preEvaluation$5
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$preEvaluation$5 → NO_COVERAGE

5.5
Location : lambda$preEvaluation$5
Killed by : none
removed call to org/apache/commons/lang3/tuple/Pair::getRight → NO_COVERAGE

6.6
Location : preEvaluation
Killed by : none
replaced call to java/util/stream/Stream::filter with receiver → NO_COVERAGE

269

1.1
Location : preEvaluation
Killed by : none
Removed assignment to member variable selectedPlatformToDevice → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to java/util/stream/Stream::toList → NO_COVERAGE

274

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::forEach → NO_COVERAGE

283

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::grabProgramSources → NO_COVERAGE

284

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
replaced call to java/util/List::toArray with argument → NO_COVERAGE

3.3
Location : preEvaluation
Killed by : none
removed call to java/util/List::toArray → NO_COVERAGE

287

1.1
Location : preEvaluation
Killed by : none
removed call to org/apache/commons/lang3/tuple/Pair::getLeft → NO_COVERAGE

288

1.1
Location : preEvaluation
Killed by : none
removed call to org/apache/commons/lang3/tuple/Pair::getRight → NO_COVERAGE

293

1.1
Location : preEvaluation
Killed by : none
removed call to org/jocl/cl_context_properties::<init> → NO_COVERAGE

294

1.1
Location : preEvaluation
Killed by : none
Substituted 4228 with 4229 → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/model/Platform::platformId → NO_COVERAGE

3.3
Location : preEvaluation
Killed by : none
removed call to org/jocl/cl_context_properties::addProperty → NO_COVERAGE

296

1.1
Location : preEvaluation
Killed by : none
Substituted 1 with 0 → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

3.3
Location : preEvaluation
Killed by : none
Substituted 1 with 0 → NO_COVERAGE

297

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceId → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to org/jocl/CL::clCreateContext → NO_COVERAGE

300

1.1
Location : preEvaluation
Killed by : none
removed call to org/jocl/cl_queue_properties::<init> → NO_COVERAGE

301

1.1
Location : preEvaluation
Killed by : none
Substituted 4243 with 4244 → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
Substituted 3 with 4 → NO_COVERAGE

3.3
Location : preEvaluation
Killed by : none
removed call to org/jocl/cl_queue_properties::addProperty → NO_COVERAGE

304

1.1
Location : preEvaluation
Killed by : none
removed call to org/jocl/CL::clCreateCommandQueueWithProperties → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceId → NO_COVERAGE

307

1.1
Location : preEvaluation
Killed by : none
removed call to org/jocl/CL::clCreateProgramWithSource → NO_COVERAGE

309

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::program → NO_COVERAGE

310

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/Program::buildOptions → NO_COVERAGE

311

1.1
Location : preEvaluation
Killed by : none
replaced call to java/util/Optional::orElse with argument → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to java/util/Optional::orElse → NO_COVERAGE

313

1.1
Location : preEvaluation
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
replaced call to org/jocl/CL::clBuildProgram with argument → NO_COVERAGE

3.3
Location : preEvaluation
Killed by : none
removed call to org/jocl/CL::clBuildProgram → NO_COVERAGE

315

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::program → NO_COVERAGE

316

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/Program::kernelNames → NO_COVERAGE

318

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/HashMap::<init> → NO_COVERAGE

319

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/HashMap::<init> → NO_COVERAGE

323

1.1
Location : preEvaluation
Killed by : none
removed call to org/jocl/CL::clCreateKernel → NO_COVERAGE

326

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/Map::put → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
replaced call to java/util/Map::put with argument → NO_COVERAGE

328

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/KernelInfoReader::read → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceId → NO_COVERAGE

330

1.1
Location : preEvaluation
Killed by : none
replaced call to java/util/Map::put with argument → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to java/util/Map::put → NO_COVERAGE

333

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::add → NO_COVERAGE

334

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::add → NO_COVERAGE

335

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::add → NO_COVERAGE

336

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::add → NO_COVERAGE

338

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext::builder → NO_COVERAGE

339

1.1
Location : preEvaluation
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::platform with receiver → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::platform → NO_COVERAGE

340

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::device → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::device with receiver → NO_COVERAGE

341

1.1
Location : preEvaluation
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clContext with receiver → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clContext → NO_COVERAGE

342

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clCommandQueue → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clCommandQueue with receiver → NO_COVERAGE

343

1.1
Location : preEvaluation
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernels with receiver → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernels → NO_COVERAGE

344

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernelInfos → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::kernelInfos with receiver → NO_COVERAGE

345

1.1
Location : preEvaluation
Killed by : none
replaced call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clProgram with receiver → NO_COVERAGE

2.2
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::clProgram → NO_COVERAGE

346

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/OpenCLExecutionContext$Builder::build → NO_COVERAGE

348

1.1
Location : preEvaluation
Killed by : none
removed call to java/util/List::add → NO_COVERAGE

351

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::fitness → NO_COVERAGE

352

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeAllEvaluations → NO_COVERAGE

354

1.1
Location : preEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeAllEvaluations → NO_COVERAGE

403

1.1
Location : evaluate
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::fitness → NO_COVERAGE

408

1.1
Location : evaluate
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

2.2
Location : evaluate
Killed by : none
Replaced double division with multiplication → NO_COVERAGE

3.3
Location : evaluate
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

4.4
Location : evaluate
Killed by : none
removed call to java/lang/Math::ceil → NO_COVERAGE

5.5
Location : evaluate
Killed by : none
replaced call to java/lang/Math::ceil with argument → NO_COVERAGE

409

1.1
Location : evaluate
Killed by : none
replaced call to org/apache/commons/collections4/ListUtils::partition with argument → NO_COVERAGE

2.2
Location : evaluate
Killed by : none
removed call to org/apache/commons/collections4/ListUtils::partition → NO_COVERAGE

412

1.1
Location : evaluate
Killed by : none
removed conditional - replaced comparison check with true → NO_COVERAGE

2.2
Location : evaluate
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : evaluate
Killed by : none
changed conditional boundary → NO_COVERAGE

4.4
Location : evaluate
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

5.5
Location : evaluate
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

6.6
Location : evaluate
Killed by : none
removed conditional - replaced comparison check with false → NO_COVERAGE

413

1.1
Location : evaluate
Killed by : none
removed call to java/util/List::get → NO_COVERAGE

418

1.1
Location : evaluate
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

419

1.1
Location : evaluate
Killed by : none
removed conditional - replaced comparison check with false → NO_COVERAGE

2.2
Location : evaluate
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

3.3
Location : evaluate
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

4.4
Location : evaluate
Killed by : none
removed conditional - replaced comparison check with true → NO_COVERAGE

5.5
Location : evaluate
Killed by : none
negated conditional → NO_COVERAGE

6.6
Location : evaluate
Killed by : none
changed conditional boundary → NO_COVERAGE

420

1.1
Location : evaluate
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

2.2
Location : evaluate
Killed by : none
removed call to java/util/List::get → NO_COVERAGE

3.3
Location : evaluate
Killed by : none
Replaced integer modulus with multiplication → NO_COVERAGE

421

1.1
Location : evaluate
Killed by : none
removed call to java/util/List::get → NO_COVERAGE

423

1.1
Location : evaluate
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeEvaluation → NO_COVERAGE

424

1.1
Location : evaluate
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::beforeEvaluation → NO_COVERAGE

426

1.1
Location : evaluate
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::compute → NO_COVERAGE

427

1.1
Location : evaluate
Killed by : none
removed call to java/util/concurrent/CompletableFuture::thenApply → NO_COVERAGE

2.2
Location : evaluate
Killed by : none
replaced call to java/util/concurrent/CompletableFuture::thenApply with receiver → NO_COVERAGE

429

1.1
Location : lambda$evaluate$7
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterEvaluation → NO_COVERAGE

430

1.1
Location : lambda$evaluate$7
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterEvaluation → NO_COVERAGE

432

1.1
Location : lambda$evaluate$7
Killed by : none
replaced return value with Collections.emptyList for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::lambda$evaluate$7 → NO_COVERAGE

435

1.1
Location : evaluate
Killed by : none
removed call to java/util/List::add → NO_COVERAGE

438

1.1
Location : evaluate
Killed by : none
removed call to java/util/ArrayList::<init> → NO_COVERAGE

2.2
Location : evaluate
Killed by : none
removed call to java/util/List::size → NO_COVERAGE

440

1.1
Location : evaluate
Killed by : none
removed call to java/util/concurrent/CompletableFuture::join → NO_COVERAGE

441

1.1
Location : evaluate
Killed by : none
removed call to java/util/List::addAll → NO_COVERAGE

443

1.1
Location : evaluate
Killed by : none
replaced return value with Collections.emptyList for net/bmahe/genetics4j/gpu/GPUFitnessEvaluator::evaluate → NO_COVERAGE

480

1.1
Location : postEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/GPUEAConfiguration::fitness → NO_COVERAGE

483

1.1
Location : postEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterAllEvaluations → NO_COVERAGE

485

1.1
Location : postEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/fitness/OpenCLFitness::afterAllEvaluations → NO_COVERAGE

490

1.1
Location : postEvaluation
Killed by : none
removed call to java/util/Map::values → NO_COVERAGE

491

1.1
Location : postEvaluation
Killed by : none
removed call to org/jocl/CL::clReleaseKernel → NO_COVERAGE

494

1.1
Location : postEvaluation
Killed by : none
removed call to java/util/List::clear → NO_COVERAGE

498

1.1
Location : postEvaluation
Killed by : none
removed call to org/jocl/CL::clReleaseProgram → NO_COVERAGE

500

1.1
Location : postEvaluation
Killed by : none
removed call to java/util/List::clear → NO_COVERAGE

504

1.1
Location : postEvaluation
Killed by : none
removed call to org/jocl/CL::clReleaseCommandQueue → NO_COVERAGE

506

1.1
Location : postEvaluation
Killed by : none
removed call to java/util/List::clear → NO_COVERAGE

510

1.1
Location : postEvaluation
Killed by : none
removed call to org/jocl/CL::clReleaseContext → NO_COVERAGE

512

1.1
Location : postEvaluation
Killed by : none
removed call to java/util/List::clear → NO_COVERAGE

514

1.1
Location : postEvaluation
Killed by : none
removed call to java/util/List::clear → NO_COVERAGE

515

1.1
Location : postEvaluation
Killed by : none
Removed assignment to member variable selectedPlatformToDevice → NO_COVERAGE

517

1.1
Location : postEvaluation
Killed by : none
removed call to net/bmahe/genetics4j/core/evaluation/FitnessEvaluator::postEvaluation → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.6