View Javadoc
1   package net.bmahe.genetics4j.gpu.spec.fitness.cldata;
2   
3   import org.apache.logging.log4j.LogManager;
4   import org.apache.logging.log4j.Logger;
5   import org.jocl.CL;
6   import org.jocl.Pointer;
7   import org.jocl.Sizeof;
8   import org.jocl.cl_mem;
9   
10  import net.bmahe.genetics4j.core.Genotype;
11  import net.bmahe.genetics4j.core.chromosomes.DoubleChromosome;
12  import net.bmahe.genetics4j.core.chromosomes.FloatChromosome;
13  
14  public class DataLoaders {
15  	public static final Logger logger = LogManager.getLogger(DataLoaders.class);
16  
17  	private DataLoaders() {
18  	}
19  
20  	public static DataLoader ofFloatSupplier(final DataSupplier<float[]> floatSupplier) {
21  		return (openCLExecutionContext, generation, genotypes) -> {
22  			final var clContext = openCLExecutionContext.clContext();
23  
24  			final float[] data = floatSupplier.get(openCLExecutionContext, generation, genotypes);
25  			logger.trace("Allocating memory on GPU for float[] of {} elements", data.length);
26  
27  			final Pointer dataPtr = Pointer.to(data);
28  			final cl_mem inputMem = CL.clCreateBuffer(
29  					clContext,
30  					CL.CL_MEM_COPY_HOST_PTR | CL.CL_MEM_READ_ONLY,
31  					Sizeof.cl_float * data.length,
32  					dataPtr,
33  					null);
34  
35  			return CLData.of(inputMem, Sizeof.cl_float, data.length);
36  		};
37  	}
38  
39  	public static DataLoader ofIntSupplier(final DataSupplier<int[]> intSupplier) {
40  		return (openCLExecutionContext, generation, genotypes) -> {
41  			final var clContext = openCLExecutionContext.clContext();
42  
43  			final int[] data = intSupplier.get(openCLExecutionContext, generation, genotypes);
44  			logger.trace("Allocating memory on GPU for int[] of {} elements", data.length);
45  
46  			final Pointer dataPtr = Pointer.to(data);
47  			final cl_mem inputMem = CL.clCreateBuffer(
48  					clContext,
49  					CL.CL_MEM_COPY_HOST_PTR | CL.CL_MEM_READ_ONLY,
50  					Sizeof.cl_int * data.length,
51  					dataPtr,
52  					null);
53  
54  			return CLData.of(inputMem, Sizeof.cl_int, data.length);
55  		};
56  	}
57  
58  	public static DataLoader ofGenerationAndPopulationSize(final boolean readOnly) {
59  		long bufferFlags = CL.CL_MEM_COPY_HOST_PTR;
60  
61  		if (readOnly) {
62  			bufferFlags |= CL.CL_MEM_READ_ONLY;
63  		}
64  		final long fBufferFlags = bufferFlags;
65  
66  		return (openCLExecutionContext, generation, genotypes) -> {
67  			final var clContext = openCLExecutionContext.clContext();
68  
69  			int[] data = new int[2];
70  			data[0] = (int) generation;
71  			data[1] = genotypes.size();
72  
73  			final Pointer dataPtr = Pointer.to(data);
74  			final cl_mem inputMem = CL.clCreateBuffer(clContext, fBufferFlags, Sizeof.cl_int * data.length, dataPtr, null);
75  
76  			return CLData.of(inputMem, Sizeof.cl_int, data.length);
77  		};
78  	}
79  
80  	public static DataLoader ofGenerationAndPopulationSize() {
81  		return ofGenerationAndPopulationSize(true);
82  	}
83  
84  	public static DataLoader ofLinearizeFloatChromosome(final int chromosomeIndex, final boolean readOnly) {
85  
86  		long bufferFlags = CL.CL_MEM_COPY_HOST_PTR;
87  
88  		if (readOnly) {
89  			bufferFlags |= CL.CL_MEM_READ_ONLY;
90  		}
91  		final long fBufferFlags = bufferFlags;
92  
93  		return (openCLExecutionContext, generation, genotypes) -> {
94  			final var clContext = openCLExecutionContext.clContext();
95  
96  			final var firstchromosome = genotypes.getFirst().getChromosome(chromosomeIndex, FloatChromosome.class);
97  			final int chromosomeSize = firstchromosome.getSize();
98  
99  			final float[] data = new float[genotypes.size() * chromosomeSize];
100 
101 			for (int i = 0; i < genotypes.size(); i++) {
102 				final Genotype genotype = genotypes.get(i);
103 				final var chromosome = genotype.getChromosome(chromosomeIndex, FloatChromosome.class);
104 
105 				for (int j = 0; j < chromosome.getNumAlleles(); j++) {
106 					data[i * chromosomeSize + j] = (float) chromosome.getAllele(j);
107 				}
108 
109 			}
110 
111 			final Pointer inputPtr = Pointer.to(data);
112 			final cl_mem inputMem = CL
113 					.clCreateBuffer(clContext, fBufferFlags, Sizeof.cl_float * data.length, inputPtr, null);
114 
115 			return CLData.of(inputMem, Sizeof.cl_float, data.length);
116 		};
117 	}
118 
119 	public static DataLoader ofLinearizeFloatChromosome(final int chromosomeIndex) {
120 		return ofLinearizeFloatChromosome(chromosomeIndex, true);
121 	}
122 
123 	public static DataLoader ofLinearizeDoubleChromosome(final int chromosomeIndex, final boolean readOnly) {
124 
125 		long bufferFlags = CL.CL_MEM_COPY_HOST_PTR;
126 
127 		if (readOnly) {
128 			bufferFlags |= CL.CL_MEM_READ_ONLY;
129 		}
130 		final long fBufferFlags = bufferFlags;
131 
132 		return (openCLExecutionContext, generation, genotypes) -> {
133 			final var clContext = openCLExecutionContext.clContext();
134 
135 			final var firstchromosome = genotypes.getFirst().getChromosome(chromosomeIndex, DoubleChromosome.class);
136 			final int chromosomeSize = firstchromosome.getSize();
137 
138 			final double[] data = new double[genotypes.size() * chromosomeSize];
139 
140 			for (int i = 0; i < genotypes.size(); i++) {
141 				final Genotype genotype = genotypes.get(i);
142 				final var chromosome = genotype.getChromosome(0, DoubleChromosome.class);
143 
144 				for (int j = 0; j < chromosome.getNumAlleles(); j++) {
145 					data[i * chromosomeSize + j] = chromosome.getAllele(j);
146 				}
147 
148 			}
149 
150 			final Pointer dataPtr = Pointer.to(data);
151 			final cl_mem dataMem = CL
152 					.clCreateBuffer(clContext, fBufferFlags, Sizeof.cl_double * data.length, dataPtr, null);
153 
154 			return CLData.of(dataMem, Sizeof.cl_double, data.length);
155 		};
156 	}
157 
158 	public static DataLoader ofLinearizeDoubleChromosome(final int chromosomeIndex) {
159 		return ofLinearizeDoubleChromosome(chromosomeIndex, true);
160 	}
161 }