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 }