View Javadoc
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 }