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