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