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 2.2 3.3 4.4 |
|
99 |
1.1 |
|
110 |
1.1 2.2 |
|
121 |
1.1 2.2 |
|
135 |
1.1 2.2 3.3 4.4 |
|
136 |
1.1 2.2 3.3 4.4 |
|
150 |
1.1 2.2 3.3 4.4 |
|
151 |
1.1 2.2 3.3 4.4 |
|
166 |
1.1 2.2 3.3 4.4 |
|
167 |
1.1 2.2 3.3 4.4 |
|
181 |
1.1 2.2 3.3 4.4 |
|
182 |
1.1 2.2 3.3 4.4 |