1 | package net.bmahe.genetics4j.gpu.spec; | |
2 | ||
3 | import java.util.List; | |
4 | import java.util.Optional; | |
5 | import java.util.Set; | |
6 | ||
7 | import org.apache.commons.lang3.Validate; | |
8 | import org.immutables.value.Value; | |
9 | ||
10 | /** | |
11 | * Specification for OpenCL programs containing kernel source code, build options, and compilation settings. | |
12 | * | |
13 | * <p>Program represents a complete OpenCL program specification that includes kernel source code | |
14 | * (either as direct content or resource references), kernel definitions, and compilation options. | |
15 | * This specification is used by the GPU EA system to compile and execute OpenCL kernels for | |
16 | * fitness evaluation on GPU devices. | |
17 | * | |
18 | * <p>A program can contain: | |
19 | * <ul> | |
20 | * <li><strong>Source content</strong>: Direct OpenCL C code as strings</li> | |
21 | * <li><strong>Resource references</strong>: Paths to OpenCL source files in the classpath</li> | |
22 | * <li><strong>Kernel definitions</strong>: Names of kernels to be compiled and made available</li> | |
23 | * <li><strong>Build options</strong>: Compiler flags and preprocessor definitions</li> | |
24 | * </ul> | |
25 | * | |
26 | * <p>Program compilation workflow: | |
27 | * <ol> | |
28 | * <li><strong>Source loading</strong>: Load content from strings and resource files</li> | |
29 | * <li><strong>Source concatenation</strong>: Combine all sources into a single compilation unit</li> | |
30 | * <li><strong>Compilation</strong>: Compile with specified build options for target devices</li> | |
31 | * <li><strong>Kernel extraction</strong>: Create kernel objects for specified kernel names</li> | |
32 | * <li><strong>Validation</strong>: Verify all kernels were successfully created</li> | |
33 | * </ol> | |
34 | * | |
35 | * <p>Common usage patterns: | |
36 | * <pre>{@code | |
37 | * // Simple single-kernel program from resource | |
38 | * Program basicProgram = Program.ofResource("/kernels/fitness.cl", "evaluate_fitness"); | |
39 | * | |
40 | * // Program with build options for optimization | |
41 | * Program optimizedProgram = Program.ofResource( | |
42 | * "/kernels/optimization.cl", | |
43 | * "fitness_kernel", | |
44 | * "-O3 -DPOPULATION_SIZE=1000 -DUSE_FAST_MATH" | |
45 | * ); | |
46 | * | |
47 | * // Complex program with multiple sources and kernels | |
48 | * Program complexProgram = Program.builder() | |
49 | * .addContent("#define PROBLEM_SIZE 256") // Direct content | |
50 | * .addResources("/kernels/common.cl") // Common utilities | |
51 | * .addResources("/kernels/fitness.cl") // Main fitness logic | |
52 | * .addKernelNames("fitness_eval") // Primary kernel | |
53 | * .addKernelNames("data_preparation") // Helper kernel | |
54 | * .buildOptions("-cl-fast-relaxed-math -DLOCAL_SIZE=64") | |
55 | * .build(); | |
56 | * }</pre> | |
57 | * | |
58 | * <p>Build options support: | |
59 | * <ul> | |
60 | * <li><strong>Optimization flags</strong>: -O0, -O1, -O2, -O3 for performance tuning</li> | |
61 | * <li><strong>Math optimizations</strong>: -cl-fast-relaxed-math for numerical performance</li> | |
62 | * <li><strong>Preprocessor definitions</strong>: -DMACRO=value for compile-time configuration</li> | |
63 | * <li><strong>Warning control</strong>: -w to disable warnings, -Werror to treat warnings as errors</li> | |
64 | * <li><strong>Standards compliance</strong>: -cl-std=CL1.2 for specific OpenCL version targeting</li> | |
65 | * </ul> | |
66 | * | |
67 | * <p>Resource loading considerations: | |
68 | * <ul> | |
69 | * <li><strong>Classpath resolution</strong>: Resources loaded relative to classpath</li> | |
70 | * <li><strong>Encoding</strong>: Source files assumed to be UTF-8 encoded</li> | |
71 | * <li><strong>Include simulation</strong>: Manual concatenation instead of OpenCL #include</li> | |
72 | * <li><strong>Error handling</strong>: Resource loading failures result in compilation errors</li> | |
73 | * </ul> | |
74 | * | |
75 | * <p>Validation and constraints: | |
76 | * <ul> | |
77 | * <li><strong>Kernel names required</strong>: At least one kernel name must be specified</li> | |
78 | * <li><strong>Source availability</strong>: Either content or resources must provide source code</li> | |
79 | * <li><strong>Name uniqueness</strong>: Kernel names must be unique within the program</li> | |
80 | * <li><strong>Compilation validity</strong>: Source code must compile successfully for target devices</li> | |
81 | * </ul> | |
82 | * | |
83 | * @see net.bmahe.genetics4j.gpu.GPUFitnessEvaluator | |
84 | * @see net.bmahe.genetics4j.gpu.spec.GPUEAConfiguration | |
85 | * @see net.bmahe.genetics4j.gpu.opencl.OpenCLExecutionContext | |
86 | */ | |
87 | @Value.Immutable | |
88 | public abstract class Program { | |
89 | ||
90 | /** | |
91 | * Returns the direct OpenCL source code content as strings. | |
92 | * | |
93 | * <p>Content represents OpenCL C source code provided directly as strings | |
94 | * rather than loaded from resources. Multiple content strings are concatenated | |
95 | * during compilation to form a single compilation unit. | |
96 | * | |
97 | * @return list of OpenCL source code strings | |
98 | */ | |
99 | @Value.Parameter | |
100 | public abstract List<String> content(); | |
101 | ||
102 | /** | |
103 | * Returns the classpath resource paths containing OpenCL source code. | |
104 | * | |
105 | * <p>Resources are loaded from the classpath at compilation time and | |
106 | * concatenated with any direct content to form the complete program source. | |
107 | * Resource paths should be relative to the classpath root. | |
108 | * | |
109 | * @return set of classpath resource paths for OpenCL source files | |
110 | */ | |
111 | @Value.Parameter | |
112 | public abstract Set<String> resources(); | |
113 | ||
114 | /** | |
115 | * Returns the names of kernels to be extracted from the compiled program. | |
116 | * | |
117 | * <p>Kernel names specify which functions in the OpenCL source should be | |
118 | * made available as executable kernels. These names must correspond to | |
119 | * functions declared with the {@code __kernel} qualifier in the source code. | |
120 | * | |
121 | * @return set of kernel function names to extract after compilation | |
122 | */ | |
123 | @Value.Parameter | |
124 | public abstract Set<String> kernelNames(); | |
125 | ||
126 | /** | |
127 | * Returns the OpenCL compiler build options for program compilation. | |
128 | * | |
129 | * <p>Build options are passed to the OpenCL compiler to control optimization, | |
130 | * define preprocessor macros, and configure compilation behavior. Common options | |
131 | * include optimization levels, math optimizations, and macro definitions. | |
132 | * | |
133 | * @return optional build options string for OpenCL compilation | |
134 | */ | |
135 | public abstract Optional<String> buildOptions(); | |
136 | ||
137 | @Value.Check | |
138 | protected void check() { | |
139 | Validate.notNull(kernelNames()); | |
140 | Validate.isTrue(kernelNames().isEmpty() == false); | |
141 | } | |
142 | ||
143 | /** | |
144 | * Creates a program from direct OpenCL source content with a single kernel. | |
145 | * | |
146 | * <p>This factory method creates a simple program specification with source code | |
147 | * provided directly as a string and a single kernel to be extracted. | |
148 | * | |
149 | * @param content the OpenCL source code as a string | |
150 | * @param kernelName the name of the kernel function to extract | |
151 | * @return a new program specification with the given content and kernel | |
152 | * @throws IllegalArgumentException if content or kernelName is null or blank | |
153 | */ | |
154 | public static Program ofContent(final String content, final String kernelName) { | |
155 | Validate.notBlank(content); | |
156 | Validate.notBlank(kernelName); | |
157 | ||
158 |
2
1. ofContent : replaced return value with null for net/bmahe/genetics4j/gpu/spec/Program::ofContent → NO_COVERAGE 2. ofContent : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram::builder → NO_COVERAGE |
return ImmutableProgram.builder() |
159 |
2
1. ofContent : replaced call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addContent with receiver → NO_COVERAGE 2. ofContent : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addContent → NO_COVERAGE |
.addContent(content) |
160 |
2
1. ofContent : replaced call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addKernelNames with receiver → NO_COVERAGE 2. ofContent : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addKernelNames → NO_COVERAGE |
.addKernelNames(kernelName) |
161 |
1
1. ofContent : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::build → NO_COVERAGE |
.build(); |
162 | } | |
163 | ||
164 | /** | |
165 | * Creates a program from a classpath resource with a single kernel. | |
166 | * | |
167 | * <p>This factory method creates a program specification that loads OpenCL source | |
168 | * code from a classpath resource and extracts a single named kernel. | |
169 | * | |
170 | * @param resource the classpath path to the OpenCL source file | |
171 | * @param kernelName the name of the kernel function to extract | |
172 | * @return a new program specification with the given resource and kernel | |
173 | * @throws IllegalArgumentException if resource or kernelName is null or blank | |
174 | */ | |
175 | public static Program ofResource(final String resource, final String kernelName) { | |
176 | Validate.notBlank(resource); | |
177 | Validate.notBlank(kernelName); | |
178 | ||
179 |
2
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram::builder → NO_COVERAGE 2. ofResource : replaced return value with null for net/bmahe/genetics4j/gpu/spec/Program::ofResource → NO_COVERAGE |
return ImmutableProgram.builder() |
180 |
2
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addResources → NO_COVERAGE 2. ofResource : replaced call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addResources with receiver → NO_COVERAGE |
.addResources(resource) |
181 |
2
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addKernelNames → NO_COVERAGE 2. ofResource : replaced call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addKernelNames with receiver → NO_COVERAGE |
.addKernelNames(kernelName) |
182 |
1
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::build → NO_COVERAGE |
.build(); |
183 | } | |
184 | ||
185 | /** | |
186 | * Creates a program from a classpath resource with a single kernel and build options. | |
187 | * | |
188 | * <p>This factory method creates a program specification that loads OpenCL source | |
189 | * code from a classpath resource, extracts a single named kernel, and applies | |
190 | * the specified build options during compilation. | |
191 | * | |
192 | * @param resource the classpath path to the OpenCL source file | |
193 | * @param kernelName the name of the kernel function to extract | |
194 | * @param buildOptions the build options for OpenCL compilation | |
195 | * @return a new program specification with the given resource, kernel, and build options | |
196 | * @throws IllegalArgumentException if resource or kernelName is null or blank | |
197 | */ | |
198 | public static Program ofResource(final String resource, final String kernelName, final String buildOptions) { | |
199 | Validate.notBlank(resource); | |
200 | Validate.notBlank(kernelName); | |
201 | ||
202 |
2
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram::builder → NO_COVERAGE 2. ofResource : replaced return value with null for net/bmahe/genetics4j/gpu/spec/Program::ofResource → NO_COVERAGE |
return ImmutableProgram.builder() |
203 |
2
1. ofResource : replaced call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addResources with receiver → NO_COVERAGE 2. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addResources → NO_COVERAGE |
.addResources(resource) |
204 |
2
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addKernelNames → NO_COVERAGE 2. ofResource : replaced call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::addKernelNames with receiver → NO_COVERAGE |
.addKernelNames(kernelName) |
205 |
2
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::buildOptions → NO_COVERAGE 2. ofResource : replaced call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::buildOptions with receiver → NO_COVERAGE |
.buildOptions(buildOptions) |
206 |
1
1. ofResource : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram$Builder::build → NO_COVERAGE |
.build(); |
207 | } | |
208 | ||
209 | /** | |
210 | * Creates a new builder for constructing complex program specifications. | |
211 | * | |
212 | * <p>The builder provides a fluent interface for creating programs with multiple | |
213 | * source files, kernels, and advanced configuration options. | |
214 | * | |
215 | * @return a new builder instance for creating program specifications | |
216 | */ | |
217 | public static ImmutableProgram.Builder builder() { | |
218 |
2
1. builder : replaced return value with null for net/bmahe/genetics4j/gpu/spec/Program::builder → NO_COVERAGE 2. builder : removed call to net/bmahe/genetics4j/gpu/spec/ImmutableProgram::builder → NO_COVERAGE |
return ImmutableProgram.builder(); |
219 | } | |
220 | } | |
Mutations | ||
158 |
1.1 2.2 |
|
159 |
1.1 2.2 |
|
160 |
1.1 2.2 |
|
161 |
1.1 |
|
179 |
1.1 2.2 |
|
180 |
1.1 2.2 |
|
181 |
1.1 2.2 |
|
182 |
1.1 |
|
202 |
1.1 2.2 |
|
203 |
1.1 2.2 |
|
204 |
1.1 2.2 |
|
205 |
1.1 2.2 |
|
206 |
1.1 |
|
218 |
1.1 2.2 |