View Javadoc
1   package net.bmahe.genetics4j.gpu.spec.fitness.cldata;
2   
3   import org.apache.commons.lang3.Validate;
4   import org.jocl.CL;
5   import org.jocl.Pointer;
6   import org.jocl.Sizeof;
7   import org.jocl.cl_image_desc;
8   import org.jocl.cl_image_format;
9   import org.jocl.cl_mem;
10  
11  public class StaticDataLoaders {
12  
13  	private StaticDataLoaders() {
14  	}
15  
16  	public static StaticDataLoader of(final boolean readOnly, final int dataType, final Pointer dataPtr,
17  			final int dataLength) {
18  
19  		long bufferFlags = CL.CL_MEM_COPY_HOST_PTR;
20  
21  		if (readOnly) {
22  			bufferFlags |= CL.CL_MEM_READ_ONLY;
23  		}
24  		final long fBufferFlags = bufferFlags;
25  
26  		return (openCLExecutionContext) -> {
27  			final var clContext = openCLExecutionContext.clContext();
28  
29  			final cl_mem dataMem = CL.clCreateBuffer(clContext, fBufferFlags, dataType * dataLength, dataPtr, null);
30  
31  			return CLData.of(dataMem, dataType, dataLength);
32  		};
33  	}
34  
35  	public static StaticDataLoader of(final int[] data, final boolean readOnly) {
36  		return of(readOnly, Sizeof.cl_int, Pointer.to(data), data.length);
37  	}
38  
39  	public static StaticDataLoader of(final int... data) {
40  		return of(data, true);
41  	}
42  
43  	public static StaticDataLoader of(final float[] data, final boolean readOnly) {
44  		return of(readOnly, Sizeof.cl_float, Pointer.to(data), data.length);
45  	}
46  
47  	public static StaticDataLoader of(final float... data) {
48  		return of(data, true);
49  	}
50  
51  	public static StaticDataLoader of(final long[] data, final boolean readOnly) {
52  		return of(readOnly, Sizeof.cl_long, Pointer.to(data), data.length);
53  	}
54  
55  	public static StaticDataLoader of(final long... data) {
56  		return of(data, true);
57  	}
58  
59  	public static StaticDataLoader of(final double[] data, final boolean readOnly) {
60  		return of(readOnly, Sizeof.cl_double, Pointer.to(data), data.length);
61  	}
62  
63  	public static StaticDataLoader of(final double... data) {
64  		return of(data, true);
65  	}
66  
67  	/**
68  	 * Expect an evenly shaped data
69  	 * 
70  	 * @param data
71  	 * @param readOnly
72  	 * @return
73  	 */
74  	public static StaticDataLoader ofLinearize(final double[][] data, final boolean readOnly) {
75  		Validate.isTrue(data.length > 0);
76  		Validate.isTrue(data[0].length > 0);
77  
78  		final int numColumns = data[0].length;
79  		final double[] dataLinear = new double[data.length * numColumns];
80  		for (int i = 0; i < data.length; i++) {
81  			if (data[i].length != numColumns) {
82  				throw new IllegalArgumentException(
83  						String.format("Got %d columns for index %d. Should have been %d", data[i].length, i, numColumns));
84  			}
85  
86  			final int baseIndex = i * numColumns;
87  			for (int j = 0; j < numColumns; j++) {
88  				dataLinear[baseIndex + j] = data[i][j];
89  			}
90  		}
91  
92  		return of(dataLinear, readOnly);
93  	}
94  
95  	/**
96  	 * Expect an evenly shaped data
97  	 * 
98  	 * @param data
99  	 * @param readOnly
100 	 * @return
101 	 */
102 	public static StaticDataLoader ofLinearize(final float[][] data, final boolean readOnly) {
103 		Validate.isTrue(data.length > 0);
104 		Validate.isTrue(data[0].length > 0);
105 
106 		final int numColumns = data[0].length;
107 		final float[] dataLinear = new float[data.length * numColumns];
108 		for (int i = 0; i < data.length; i++) {
109 			if (data[i].length != numColumns) {
110 				throw new IllegalArgumentException(
111 						String.format("Got %d columns for index %d. Should have been %d", data[i].length, i, numColumns));
112 			}
113 
114 			final int baseIndex = i * numColumns;
115 			for (int j = 0; j < numColumns; j++) {
116 				dataLinear[baseIndex + j] = data[i][j];
117 			}
118 		}
119 
120 		return of(dataLinear, readOnly);
121 	}
122 
123 	/**
124 	 * Expect an evenly shaped data
125 	 * 
126 	 * @param data
127 	 * @return
128 	 */
129 	public static StaticDataLoader ofLinearize(final float[][] data) {
130 		return ofLinearize(data, true);
131 	}
132 
133 	/**
134 	 * Expect an evenly shaped data
135 	 * 
136 	 * @param data
137 	 * @param readOnly
138 	 * @return
139 	 */
140 	public static StaticDataLoader ofLinearize(final int[][] data, final boolean readOnly) {
141 		Validate.isTrue(data.length > 0);
142 		Validate.isTrue(data[0].length > 0);
143 
144 		final int numColumns = data[0].length;
145 		final int[] dataLinear = new int[data.length * numColumns];
146 		for (int i = 0; i < data.length; i++) {
147 			if (data[i].length != numColumns) {
148 				throw new IllegalArgumentException(
149 						String.format("Got %d columns for index %d. Should have been %d", data[i].length, i, numColumns));
150 			}
151 
152 			final int baseIndex = i * numColumns;
153 			for (int j = 0; j < numColumns; j++) {
154 				dataLinear[baseIndex + j] = data[i][j];
155 			}
156 		}
157 
158 		return of(dataLinear, readOnly);
159 	}
160 
161 	/**
162 	 * Expect an evenly shaped data
163 	 * 
164 	 * @param data
165 	 * @param readOnly
166 	 * @return
167 	 */
168 	public static StaticDataLoader ofLinearize(final long[][] data, final boolean readOnly) {
169 		Validate.isTrue(data.length > 0);
170 		Validate.isTrue(data[0].length > 0);
171 
172 		final int numColumns = data[0].length;
173 		final long[] dataLinear = new long[data.length * numColumns];
174 		for (int i = 0; i < data.length; i++) {
175 			if (data[i].length != numColumns) {
176 				throw new IllegalArgumentException(
177 						String.format("Got %d columns for index %d. Should have been %d", data[i].length, i, numColumns));
178 			}
179 
180 			final int baseIndex = i * numColumns;
181 			for (int j = 0; j < numColumns; j++) {
182 				dataLinear[baseIndex + j] = data[i][j];
183 			}
184 		}
185 
186 		return of(dataLinear, readOnly);
187 	}
188 
189 	public static StaticDataLoader ofImage(final byte[] data, final int width, final int height, final int channelOrder,
190 			final int channelDataType, final boolean readOnly) {
191 		Validate.isTrue(data.length > 0);
192 
193 		long bufferFlags = CL.CL_MEM_COPY_HOST_PTR;
194 
195 		if (readOnly) {
196 			bufferFlags |= CL.CL_MEM_READ_ONLY;
197 		}
198 		final long fBufferFlags = bufferFlags;
199 
200 		return (openCLExecutionContext) -> {
201 			final var clContext = openCLExecutionContext.clContext();
202 			final var clCommandQueue = openCLExecutionContext.clCommandQueue();
203 
204 			final var imageDesc = new cl_image_desc();
205 			imageDesc.image_type = CL.CL_MEM_OBJECT_IMAGE2D;
206 			imageDesc.image_width = width;
207 			imageDesc.image_height = height;
208 
209 			final var imageFormat = new cl_image_format();
210 			imageFormat.image_channel_order = channelOrder;
211 			imageFormat.image_channel_data_type = channelDataType;
212 
213 			final var clMem = CL.clCreateImage(clContext, fBufferFlags, imageFormat, imageDesc, Pointer.to(data), null);
214 
215 			CL.clEnqueueWriteImage(clCommandQueue,
216 					clMem,
217 					true,
218 					new long[] { 0, 0, 0 },
219 					new long[] { width, height, 1 },
220 					0,
221 					0,
222 					Pointer.to(data),
223 					0,
224 					null,
225 					null);
226 
227 			return CLData.of(clMem, 1, data.length);
228 		};
229 	}
230 
231 	public static StaticDataLoader ofImage(final byte[] data, final int width, final int height, final int channelOrder,
232 			final int channelDataType) {
233 		return ofImage(data, width, height, channelOrder, channelDataType, true);
234 	}
235 }