DeviceFilters.java

1
package net.bmahe.genetics4j.gpu.spec;
2
3
import java.util.Arrays;
4
import java.util.Collection;
5
import java.util.function.Predicate;
6
7
import org.apache.commons.lang3.Validate;
8
9
import net.bmahe.genetics4j.gpu.opencl.model.Device;
10
import net.bmahe.genetics4j.gpu.opencl.model.DeviceType;
11
12
/**
13
 * Utility class providing predicate-based filters for selecting OpenCL devices in GPU-accelerated evolutionary algorithms.
14
 * 
15
 * <p>DeviceFilters offers a fluent API for creating device selection criteria based on device characteristics
16
 * such as type, capabilities, and performance metrics. These filters are used to automatically select
17
 * appropriate OpenCL devices for GPU-accelerated evolutionary algorithm execution.
18
 * 
19
 * <p>Key functionality includes:
20
 * <ul>
21
 * <li><strong>Type-based filtering</strong>: Select devices by type (GPU, CPU, accelerator)</li>
22
 * <li><strong>Logical combinations</strong>: Combine filters using AND and OR operations</li>
23
 * <li><strong>Performance filtering</strong>: Filter devices based on computational capabilities</li>
24
 * <li><strong>Predicate composition</strong>: Build complex selection criteria from simple predicates</li>
25
 * </ul>
26
 * 
27
 * <p>Common usage patterns:
28
 * <pre>{@code
29
 * // Select GPU devices only
30
 * Predicate<Device> gpuFilter = DeviceFilters.ofGPU();
31
 * 
32
 * // Select CPU devices only
33
 * Predicate<Device> cpuFilter = DeviceFilters.ofCPU();
34
 * 
35
 * // Select GPU or accelerator devices
36
 * Predicate<Device> computeFilter = DeviceFilters.or(
37
 *     DeviceFilters.ofGPU(),
38
 *     DeviceFilters.ofType(DeviceType.ACCELERATOR)
39
 * );
40
 * 
41
 * // Select high-performance GPU devices
42
 * Predicate<Device> highPerformanceGPU = DeviceFilters.and(
43
 *     DeviceFilters.ofGPU(),
44
 *     device -> device.maxComputeUnits() >= 8,
45
 *     device -> device.maxWorkGroupSize() >= 256
46
 * );
47
 * 
48
 * // Apply filter to device selection
49
 * GPUEAExecutionContext context = GPUEAExecutionContext.builder()
50
 *     .deviceFilters(gpuFilter)
51
 *     .build();
52
 * }</pre>
53
 * 
54
 * <p>Device selection workflow:
55
 * <ol>
56
 * <li><strong>Platform discovery</strong>: Enumerate available OpenCL platforms</li>
57
 * <li><strong>Device enumeration</strong>: Discover devices on selected platforms</li>
58
 * <li><strong>Filter application</strong>: Apply device filters to candidate devices</li>
59
 * <li><strong>Device selection</strong>: Select filtered devices for EA execution</li>
60
 * </ol>
61
 * 
62
 * <p>Filter composition patterns:
63
 * <ul>
64
 * <li><strong>Type filtering</strong>: Select devices by computational type</li>
65
 * <li><strong>Capability filtering</strong>: Filter by device computational capabilities</li>
66
 * <li><strong>Performance filtering</strong>: Select devices meeting performance criteria</li>
67
 * <li><strong>Logical combinations</strong>: Combine multiple criteria using boolean logic</li>
68
 * </ul>
69
 * 
70
 * <p>Performance considerations:
71
 * <ul>
72
 * <li><strong>Device enumeration overhead</strong>: Filters are applied during device discovery</li>
73
 * <li><strong>Capability validation</strong>: Ensure selected devices meet algorithm requirements</li>
74
 * <li><strong>Load balancing</strong>: Consider device performance when selecting multiple devices</li>
75
 * <li><strong>Fallback strategies</strong>: Implement fallback filters for systems with limited devices</li>
76
 * </ul>
77
 * 
78
 * @see Device
79
 * @see DeviceType
80
 * @see GPUEAExecutionContext
81
 */
82
public class DeviceFilters {
83
84
	private DeviceFilters() {
85
86
	}
87
88
	/**
89
	 * Creates a predicate that filters devices by the specified device type.
90
	 * 
91
	 * @param deviceType the OpenCL device type to filter for
92
	 * @return predicate that returns true for devices of the specified type
93
	 * @throws IllegalArgumentException if deviceType is null
94
	 */
95
	public static Predicate<Device> ofType(final DeviceType deviceType) {
96
		Validate.notNull(deviceType);
97
98 4 1. lambda$ofType$0 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$ofType$0 → NO_COVERAGE
2. lambda$ofType$0 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$ofType$0 → NO_COVERAGE
3. ofType : replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofType → NO_COVERAGE
4. lambda$ofType$0 : removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceType → NO_COVERAGE
		return (device) -> device.deviceType()
99 1 1. lambda$ofType$0 : removed call to java/util/Set::contains → NO_COVERAGE
				.contains(deviceType);
100
	}
101
102
	/**
103
	 * Creates a predicate that filters for GPU devices only.
104
	 * 
105
	 * <p>This is a convenience method equivalent to {@code ofType(DeviceType.GPU)}.
106
	 * 
107
	 * @return predicate that returns true for GPU devices
108
	 */
109
	public static Predicate<Device> ofGPU() {
110 2 1. ofGPU : replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofGPU → NO_COVERAGE
2. ofGPU : removed call to net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofType → NO_COVERAGE
		return ofType(DeviceType.GPU);
111
	}
112
113
	/**
114
	 * Creates a predicate that filters for CPU devices only.
115
	 * 
116
	 * <p>This is a convenience method equivalent to {@code ofType(DeviceType.CPU)}.
117
	 * 
118
	 * @return predicate that returns true for CPU devices
119
	 */
120
	public static Predicate<Device> ofCPU() {
121 2 1. ofCPU : removed call to net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofType → NO_COVERAGE
2. ofCPU : replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofCPU → NO_COVERAGE
		return ofType(DeviceType.CPU);
122
	}
123
124
	/**
125
	 * Creates a predicate that returns true if any of the provided predicates return true (logical OR).
126
	 * 
127
	 * @param predicates array of device predicates to combine with OR logic
128
	 * @return predicate that returns true if any input predicate returns true
129
	 * @throws IllegalArgumentException if predicates is null or empty
130
	 */
131
	public static Predicate<Device> or(@SuppressWarnings("unchecked") final Predicate<Device>... predicates) {
132
		Validate.notNull(predicates);
133
		Validate.isTrue(predicates.length > 0);
134
135 4 1. lambda$or$2 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$2 → NO_COVERAGE
2. lambda$or$2 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$2 → NO_COVERAGE
3. lambda$or$2 : removed call to java/util/Arrays::stream → NO_COVERAGE
4. or : replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::or → NO_COVERAGE
		return device -> Arrays.stream(predicates)
136 4 1. lambda$or$2 : removed call to java/util/stream/Stream::anyMatch → NO_COVERAGE
2. lambda$or$1 : removed call to java/util/function/Predicate::test → NO_COVERAGE
3. lambda$or$1 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$1 → NO_COVERAGE
4. lambda$or$1 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$1 → NO_COVERAGE
				.anyMatch(predicate -> predicate.test(device));
137
	}
138
139
	/**
140
	 * Creates a predicate that returns true if any of the provided predicates return true (logical OR).
141
	 * 
142
	 * @param predicates collection of device predicates to combine with OR logic
143
	 * @return predicate that returns true if any input predicate returns true
144
	 * @throws IllegalArgumentException if predicates is null or empty
145
	 */
146
	public static Predicate<Device> or(final Collection<Predicate<Device>> predicates) {
147
		Validate.notNull(predicates);
148
		Validate.isTrue(predicates.size() > 0);
149
150 4 1. lambda$or$4 : removed call to java/util/Collection::stream → NO_COVERAGE
2. lambda$or$4 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$4 → NO_COVERAGE
3. lambda$or$4 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$4 → NO_COVERAGE
4. or : replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::or → NO_COVERAGE
		return device -> predicates.stream()
151 4 1. lambda$or$3 : removed call to java/util/function/Predicate::test → NO_COVERAGE
2. lambda$or$3 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$3 → NO_COVERAGE
3. lambda$or$3 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$3 → NO_COVERAGE
4. lambda$or$4 : removed call to java/util/stream/Stream::anyMatch → NO_COVERAGE
				.anyMatch(predicate -> predicate.test(device));
152
	}
153
154
	/**
155
	 * Creates a predicate that returns true only if all provided predicates return true (logical AND).
156
	 * 
157
	 * @param predicates array of device predicates to combine with AND logic
158
	 * @return predicate that returns true only if all input predicates return true
159
	 * @throws IllegalArgumentException if predicates is null or empty
160
	 */
161
	@SafeVarargs
162
	public static Predicate<Device> and(final Predicate<Device>... predicates) {
163
		Validate.notNull(predicates);
164
		Validate.isTrue(predicates.length > 0);
165
166 4 1. lambda$and$6 : removed call to java/util/Arrays::stream → NO_COVERAGE
2. and : replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::and → NO_COVERAGE
3. lambda$and$6 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$6 → NO_COVERAGE
4. lambda$and$6 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$6 → NO_COVERAGE
		return device -> Arrays.stream(predicates)
167 4 1. lambda$and$5 : removed call to java/util/function/Predicate::test → NO_COVERAGE
2. lambda$and$5 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$5 → NO_COVERAGE
3. lambda$and$5 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$5 → NO_COVERAGE
4. lambda$and$6 : removed call to java/util/stream/Stream::allMatch → NO_COVERAGE
				.allMatch(predicate -> predicate.test(device));
168
	}
169
170
	/**
171
	 * Creates a predicate that returns true only if all provided predicates return true (logical AND).
172
	 * 
173
	 * @param predicates collection of device predicates to combine with AND logic
174
	 * @return predicate that returns true only if all input predicates return true
175
	 * @throws IllegalArgumentException if predicates is null or empty
176
	 */
177
	public static Predicate<Device> and(final Collection<Predicate<Device>> predicates) {
178
		Validate.notNull(predicates);
179
		Validate.isTrue(predicates.size() > 0);
180
181 4 1. and : replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::and → NO_COVERAGE
2. lambda$and$8 : removed call to java/util/Collection::stream → NO_COVERAGE
3. lambda$and$8 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$8 → NO_COVERAGE
4. lambda$and$8 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$8 → NO_COVERAGE
		return device -> predicates.stream()
182 4 1. lambda$and$8 : removed call to java/util/stream/Stream::allMatch → NO_COVERAGE
2. lambda$and$7 : removed call to java/util/function/Predicate::test → NO_COVERAGE
3. lambda$and$7 : replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$7 → NO_COVERAGE
4. lambda$and$7 : replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$7 → NO_COVERAGE
				.allMatch(predicate -> predicate.test(device));
183
	}
184
185
}

Mutations

98

1.1
Location : lambda$ofType$0
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$ofType$0 → NO_COVERAGE

2.2
Location : lambda$ofType$0
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$ofType$0 → NO_COVERAGE

3.3
Location : ofType
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofType → NO_COVERAGE

4.4
Location : lambda$ofType$0
Killed by : none
removed call to net/bmahe/genetics4j/gpu/opencl/model/Device::deviceType → NO_COVERAGE

99

1.1
Location : lambda$ofType$0
Killed by : none
removed call to java/util/Set::contains → NO_COVERAGE

110

1.1
Location : ofGPU
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofGPU → NO_COVERAGE

2.2
Location : ofGPU
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofType → NO_COVERAGE

121

1.1
Location : ofCPU
Killed by : none
removed call to net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofType → NO_COVERAGE

2.2
Location : ofCPU
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::ofCPU → NO_COVERAGE

135

1.1
Location : lambda$or$2
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$2 → NO_COVERAGE

2.2
Location : lambda$or$2
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$2 → NO_COVERAGE

3.3
Location : lambda$or$2
Killed by : none
removed call to java/util/Arrays::stream → NO_COVERAGE

4.4
Location : or
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::or → NO_COVERAGE

136

1.1
Location : lambda$or$2
Killed by : none
removed call to java/util/stream/Stream::anyMatch → NO_COVERAGE

2.2
Location : lambda$or$1
Killed by : none
removed call to java/util/function/Predicate::test → NO_COVERAGE

3.3
Location : lambda$or$1
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$1 → NO_COVERAGE

4.4
Location : lambda$or$1
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$1 → NO_COVERAGE

150

1.1
Location : lambda$or$4
Killed by : none
removed call to java/util/Collection::stream → NO_COVERAGE

2.2
Location : lambda$or$4
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$4 → NO_COVERAGE

3.3
Location : lambda$or$4
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$4 → NO_COVERAGE

4.4
Location : or
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::or → NO_COVERAGE

151

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

2.2
Location : lambda$or$3
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$3 → NO_COVERAGE

3.3
Location : lambda$or$3
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$or$3 → NO_COVERAGE

4.4
Location : lambda$or$4
Killed by : none
removed call to java/util/stream/Stream::anyMatch → NO_COVERAGE

166

1.1
Location : lambda$and$6
Killed by : none
removed call to java/util/Arrays::stream → NO_COVERAGE

2.2
Location : and
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::and → NO_COVERAGE

3.3
Location : lambda$and$6
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$6 → NO_COVERAGE

4.4
Location : lambda$and$6
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$6 → NO_COVERAGE

167

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

2.2
Location : lambda$and$5
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$5 → NO_COVERAGE

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

4.4
Location : lambda$and$6
Killed by : none
removed call to java/util/stream/Stream::allMatch → NO_COVERAGE

181

1.1
Location : and
Killed by : none
replaced return value with null for net/bmahe/genetics4j/gpu/spec/DeviceFilters::and → NO_COVERAGE

2.2
Location : lambda$and$8
Killed by : none
removed call to java/util/Collection::stream → NO_COVERAGE

3.3
Location : lambda$and$8
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$8 → NO_COVERAGE

4.4
Location : lambda$and$8
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$8 → NO_COVERAGE

182

1.1
Location : lambda$and$8
Killed by : none
removed call to java/util/stream/Stream::allMatch → NO_COVERAGE

2.2
Location : lambda$and$7
Killed by : none
removed call to java/util/function/Predicate::test → NO_COVERAGE

3.3
Location : lambda$and$7
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$7 → NO_COVERAGE

4.4
Location : lambda$and$7
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/gpu/spec/DeviceFilters::lambda$and$7 → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.6