View Javadoc
1   package net.bmahe.genetics4j.gpu.spec.fitness.cldata;
2   
3   import org.apache.commons.lang3.Validate;
4   import org.immutables.value.Value;
5   import org.jocl.cl_mem;
6   
7   /**
8    * Container representing data stored in OpenCL device memory for GPU-accelerated evolutionary algorithm processing.
9    * 
10   * <p>CLData encapsulates the information needed to reference and manage data that has been allocated and stored on an
11   * OpenCL device (GPU). This includes the OpenCL memory object, the data type, and the number of elements, providing a
12   * type-safe way to work with GPU memory buffers in evolutionary algorithm fitness evaluation.
13   * 
14   * <p>Key characteristics:
15   * <ul>
16   * <li><strong>Memory reference</strong>: OpenCL memory object (cl_mem) pointing to device memory</li>
17   * <li><strong>Type information</strong>: OpenCL data type for proper kernel parameter binding</li>
18   * <li><strong>Size tracking</strong>: Number of elements for bounds checking and memory management</li>
19   * <li><strong>Resource management</strong>: Facilitates proper cleanup of OpenCL memory objects</li>
20   * </ul>
21   * 
22   * <p>Common usage patterns:
23   * 
24   * <pre>{@code
25   * // Create CLData for population chromosomes
26   * CLData populationData = CLData.of(chromosomeBuffer, CL.CL_FLOAT, populationSize * chromosomeLength);
27   * 
28   * // Create CLData for fitness results
29   * CLData fitnessData = CLData.of(fitnessBuffer, CL.CL_DOUBLE, populationSize);
30   * 
31   * // Create CLData for algorithm parameters
32   * CLData parameterData = CLData.of(paramBuffer, CL.CL_INT, parameterCount);
33   * 
34   * // Use in kernel execution
35   * clSetKernelArg(kernel, 0, Sizeof.cl_mem, Pointer.to(populationData.clMem()));
36   * clSetKernelArg(kernel, 1, Sizeof.cl_mem, Pointer.to(fitnessData.clMem()));
37   * }</pre>
38   * 
39   * <p>Memory lifecycle management:
40   * <ol>
41   * <li><strong>Allocation</strong>: Memory is allocated using clCreateBuffer or similar OpenCL functions</li>
42   * <li><strong>Wrapping</strong>: CLData object is created to wrap the allocated memory</li>
43   * <li><strong>Usage</strong>: Memory is used in kernel execution through CLData references</li>
44   * <li><strong>Cleanup</strong>: Memory is released using clReleaseMemObject when no longer needed</li>
45   * </ol>
46   * 
47   * <p>Data type mapping:
48   * <ul>
49   * <li><strong>CL_FLOAT</strong>: Single-precision floating-point data</li>
50   * <li><strong>CL_DOUBLE</strong>: Double-precision floating-point data</li>
51   * <li><strong>CL_INT</strong>: 32-bit integer data</li>
52   * <li><strong>CL_CHAR</strong>: 8-bit character data</li>
53   * </ul>
54   * 
55   * <p>Error handling considerations:
56   * <ul>
57   * <li><strong>Memory validation</strong>: Ensures cl_mem objects are valid before use</li>
58   * <li><strong>Type safety</strong>: Validates OpenCL data types are positive</li>
59   * <li><strong>Size validation</strong>: Ensures element counts are positive</li>
60   * <li><strong>Resource tracking</strong>: Facilitates proper memory cleanup</li>
61   * </ul>
62   * 
63   * @see DataLoader
64   * @see ResultExtractor
65   * @see net.bmahe.genetics4j.gpu.spec.fitness.OpenCLFitness
66   */
67  @Value.Immutable
68  public interface CLData {
69  
70  	/**
71  	 * Returns the OpenCL memory object that references the data stored on the device.
72  	 * 
73  	 * @return the OpenCL memory object (cl_mem) containing the device data
74  	 */
75  	@Value.Parameter
76  	cl_mem clMem();
77  
78  	/**
79  	 * Returns the OpenCL data type of the elements stored in the memory buffer.
80  	 * 
81  	 * <p>Common OpenCL types include CL_FLOAT, CL_DOUBLE, CL_INT, and CL_CHAR. This information is used for proper
82  	 * kernel parameter binding and type checking.
83  	 * 
84  	 * @return the OpenCL data type constant (e.g., CL_FLOAT, CL_DOUBLE)
85  	 */
86  	@Value.Parameter
87  	int clType();
88  
89  	/**
90  	 * Returns the number of elements stored in the OpenCL memory buffer.
91  	 * 
92  	 * <p>This represents the count of individual data elements (not bytes) contained in the memory object. For example,
93  	 * a buffer containing 1000 floating-point values would have a size of 1000, regardless of the actual byte size.
94  	 * 
95  	 * @return the number of elements in the memory buffer
96  	 */
97  	@Value.Parameter
98  	int size();
99  
100 	/**
101 	 * Creates a new CLData instance with the specified OpenCL memory object, data type, and size.
102 	 * 
103 	 * @param clMem  the OpenCL memory object containing the device data
104 	 * @param clType the OpenCL data type constant (e.g., CL_FLOAT, CL_DOUBLE)
105 	 * @param size   the number of elements in the memory buffer
106 	 * @return a new CLData instance
107 	 * @throws IllegalArgumentException if clMem is null, clType is not positive, or size is not positive
108 	 */
109 	static CLData of(final cl_mem clMem, final int clType, final int size) {
110 		Validate.notNull(clMem);
111 		Validate.isTrue(clType > 0);
112 		Validate.isTrue(size > 0);
113 
114 		return ImmutableCLData.of(clMem, clType, size);
115 	}
116 }