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 }