1 package net.bmahe.genetics4j.gpu.spec.fitness.cldata;
2
3 import java.util.List;
4
5 import net.bmahe.genetics4j.core.Genotype;
6 import net.bmahe.genetics4j.gpu.opencl.OpenCLExecutionContext;
7
8 /**
9 * Functional interface for loading genotype data into OpenCL device memory for GPU-accelerated fitness evaluation.
10 *
11 * <p>DataLoader defines the contract for converting evolutionary algorithm genotypes into OpenCL memory buffers that
12 * can be processed by GPU kernels. This abstraction allows different chromosome types and data formats to be
13 * efficiently transferred to GPU memory for parallel fitness evaluation.
14 *
15 * <p>Key responsibilities:
16 * <ul>
17 * <li><strong>Data conversion</strong>: Transform genotypes into OpenCL-compatible data formats</li>
18 * <li><strong>Memory allocation</strong>: Allocate appropriate device memory for the data</li>
19 * <li><strong>Data transfer</strong>: Copy converted data to GPU memory buffers</li>
20 * <li><strong>Lifecycle management</strong>: Handle generation-specific data loading patterns</li>
21 * </ul>
22 *
23 * <p>Common implementation patterns:
24 *
25 * <pre>{@code
26 * // DataLoader for floating-point chromosomes
27 * DataLoader floatLoader = (context, generation, genotypes) -> {
28 * // Convert genotypes to float array
29 * float[] data = genotypes.stream()
30 * .flatMap(
31 * genotype -> genotype.getChromosome(FloatChromosome.class)
32 * .stream()
33 * .mapToDouble(FloatChromosome::getValue)
34 * .mapToObj(d -> (float) d))
35 * .toArray(float[]::new);
36 *
37 * // Allocate and populate GPU memory
38 * cl_mem buffer = clCreateBuffer(
39 * context.context(),
40 * CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
41 * data.length * Sizeof.cl_float,
42 * Pointer.to(data),
43 * null);
44 *
45 * return CLData.of(buffer, CL_FLOAT, data.length);
46 * };
47 *
48 * // DataLoader for integer chromosomes with generation-specific logic
49 * DataLoader intLoader = (context, generation, genotypes) -> {
50 * int[] data = convertIntGenotypes(genotypes, generation);
51 * cl_mem buffer = allocateIntBuffer(context, data);
52 * return CLData.of(buffer, CL_INT, data.length);
53 * };
54 *
55 * // DataLoader using static data (parameters)
56 * DataLoader paramLoader = DataLoaders.staticFloatArray(new float[] { 0.1f, 0.2f, 0.5f });
57 * }</pre>
58 *
59 * <p>Memory management considerations:
60 * <ul>
61 * <li><strong>Buffer allocation</strong>: Use appropriate OpenCL memory flags (READ_ONLY, READ_WRITE, etc.)</li>
62 * <li><strong>Data copying</strong>: Consider using CL_MEM_COPY_HOST_PTR for immediate data transfer</li>
63 * <li><strong>Memory alignment</strong>: Ensure data is properly aligned for GPU access patterns</li>
64 * <li><strong>Resource cleanup</strong>: Returned CLData objects should be properly released after use</li>
65 * </ul>
66 *
67 * <p>Performance optimization strategies:
68 * <ul>
69 * <li><strong>Batch processing</strong>: Process multiple genotypes efficiently in single operations</li>
70 * <li><strong>Memory reuse</strong>: Reuse memory buffers across generations when possible</li>
71 * <li><strong>Data layout</strong>: Optimize data layout for coalesced GPU memory access</li>
72 * <li><strong>Transfer minimization</strong>: Minimize host-to-device data transfers</li>
73 * </ul>
74 *
75 * <p>Generation-aware loading:
76 * <ul>
77 * <li><strong>Generation tracking</strong>: Use generation parameter for evolution-dependent data</li>
78 * <li><strong>Adaptive parameters</strong>: Modify algorithm parameters based on generation number</li>
79 * <li><strong>Dynamic sizing</strong>: Adjust data sizes based on population evolution</li>
80 * <li><strong>Caching strategies</strong>: Cache expensive computations across generations</li>
81 * </ul>
82 *
83 * @see CLData
84 * @see DataLoaders
85 * @see StaticDataLoader
86 * @see net.bmahe.genetics4j.gpu.spec.fitness.OpenCLFitness
87 */
88 @FunctionalInterface
89 public interface DataLoader {
90
91 /**
92 * Loads genotype data into OpenCL device memory for GPU processing.
93 *
94 * <p>This method converts the provided genotypes into an appropriate data format, allocates OpenCL device memory,
95 * and transfers the converted data to the GPU. The resulting CLData object can be used as input for OpenCL kernels.
96 *
97 * @param openCLExecutionContext the OpenCL execution context providing device access
98 * @param generation the current generation number for generation-aware loading
99 * @param genotypes the list of genotypes to convert and load into device memory
100 * @return CLData object containing the loaded data in device memory
101 * @throws IllegalArgumentException if any parameter is null
102 * @throws RuntimeException if OpenCL memory allocation or data transfer fails
103 */
104 CLData load(final OpenCLExecutionContext openCLExecutionContext, final long generation,
105 final List<Genotype> genotypes);
106 }