Krnl_GA.cl 20.7 KB
Newer Older
1
2
3
// Enable the channels extension
#pragma OPENCL EXTENSION cl_altera_channels : enable

4
5
6
//IC:  initial calculation of energy of populations
//GG:  genetic generation 
//LS:  local search
7
//OFF: turn off 
Leonardo Solis's avatar
Leonardo Solis committed
8
9

#include "../defines.h"
Leonardo Solis's avatar
Leonardo Solis committed
10
11

#define CHAN_DEPTH_ATOMXYZ   (MAX_NUM_OF_ATOMS/2)
12
//#define CHAN_DEPTH_ATOMXYZ   MAX_NUM_OF_ATOMS
Leonardo Solis's avatar
Leonardo Solis committed
13
14
#define CHAN_DEPTH_GENOTYPE  ACTUAL_GENOTYPE_LENGTH

15
16
17
#define CHAN_NEW_DEPTH_GENOTYPE (MAX_POPSIZE*CHAN_DEPTH_GENOTYPE)
#define CHAN_NEW_DEPTH_ATOMXYZ  (MAX_POPSIZE*CHAN_DEPTH_ATOMXYZ)

18
19
20
// Send active signal to IGL_Arbiter
channel bool    chan_GA2IGL_IC_active;
channel bool    chan_GA2IGL_GG_active;
21

Leonardo Solis's avatar
Leonardo Solis committed
22
// Send genotypes from producers (IC, GG) to Conform
23
#if 0
Leonardo Solis's avatar
Leonardo Solis committed
24
25
channel float  	chan_IC2Conf_genotype          __attribute__((depth(CHAN_DEPTH_GENOTYPE)));
channel float  	chan_GG2Conf_genotype          __attribute__((depth(CHAN_DEPTH_GENOTYPE)));
26
27
28
29
#endif
channel float  	chan_IC2Conf_genotype          __attribute__((depth(CHAN_NEW_DEPTH_GENOTYPE)));
channel float  	chan_GG2Conf_genotype          __attribute__((depth(CHAN_NEW_DEPTH_GENOTYPE)));

Leonardo Solis's avatar
Leonardo Solis committed
30

31
// Send ligand-atom positions from Conform to InterE & IntraE
32
#if 0
Leonardo Solis's avatar
Leonardo Solis committed
33
channel float8  chan_Conf2Intere_xyz           __attribute__((depth(CHAN_DEPTH_ATOMXYZ)));
34
35
36
#endif
channel float8  chan_Conf2Intere_xyz           __attribute__((depth(CHAN_NEW_DEPTH_ATOMXYZ)));

37
channel char  	chan_Conf2Intere_actmode;
Leonardo Solis's avatar
Leonardo Solis committed
38

39
#if 0
Leonardo Solis's avatar
Leonardo Solis committed
40
channel float8	chan_Conf2Intrae_xyz           __attribute__((depth(CHAN_DEPTH_ATOMXYZ)));
41
42
43
#endif
channel float8	chan_Conf2Intrae_xyz           __attribute__((depth(CHAN_NEW_DEPTH_ATOMXYZ)));

44
channel char  	chan_Conf2Intrae_actmode;	
45

Leonardo Solis's avatar
Leonardo Solis committed
46
// Send energy values from InterE & IntraE to genotype-senders (IC, GG)
Leonardo Solis's avatar
Leonardo Solis committed
47
#if 1
48
channel float 	chan_Intere2StoreGG_intere     __attribute__((depth(MAX_POPSIZE)));
49
#endif
50
#if 1
51
52
channel float 	chan_Intere2StoreIC_intere     __attribute__((depth(MAX_POPSIZE)));
#endif
Leonardo Solis's avatar
Leonardo Solis committed
53

Leonardo Solis's avatar
Leonardo Solis committed
54
#if 1
55
channel float 	chan_Intrae2StoreGG_intrae     __attribute__((depth(MAX_POPSIZE)));
56
#endif
57
#if 1
58
59
channel float 	chan_Intrae2StoreIC_intrae     __attribute__((depth(MAX_POPSIZE)));
#endif
Leonardo Solis's avatar
Leonardo Solis committed
60

61
62
63
64
65
66
67
68
69
70
71
// Send PRNG outputs from generators to consumers
channel float8   chan_PRNG2GA_BT_ushort_float_prng;
channel uchar2   chan_PRNG2GA_GG_uchar_prng;
channel float    chan_PRNG2GA_GG_float_prng     __attribute__((depth(CHAN_DEPTH_GENOTYPE)));

// Turn-off signals to PRNG generators

// FIXME: these channels don't go anymore through IGL_Arbiter.
// That was initially the case, but was fixed.
// Name should be changed accordingly (GA instead of Arbiter)
// to avoid misleading data-flow information
72
73
74
channel bool 	chan_Arbiter_BT_ushort_float_off;
channel bool    chan_Arbiter_GG_uchar_off;
channel bool    chan_Arbiter_GG_float_off;
Leonardo Solis's avatar
Leonardo Solis committed
75

76
77
// Send genotype-producer-channel selector and genotype 
// from IGL_Arbiter to Conform
78
79
channel char  chan_IGL2Conform_actmode	       __attribute__((depth(3))); // mode

80
// Turn-off signal to IGL_Arbiter, Conform, InterE, IntraE
Leonardo Solis's avatar
Leonardo Solis committed
81
channel bool   chan_IGLArbiter_Off;
Leonardo Solis's avatar
Leonardo Solis committed
82

Leonardo Solis's avatar
Leonardo Solis committed
83
#if defined (FIXED_POINT_CONFORM) 
84
85
#include "../defines_fixedpt.h"
typedef int3          fixedpt3;
86
typedef int4	      fixedpt4;
87
88
#endif

Leonardo Solis's avatar
Leonardo Solis committed
89
#if defined (FIXED_POINT_INTERE) || defined (FIXED_POINT_INTRAE)
90
91
92
#include "../defines_fixedpt_64.h"
#endif

Leonardo Solis's avatar
Leonardo Solis committed
93
// --------------------------------------------------------------------------
94
// Map the argument into the interval 0 - 180, or 0 - 360
Leonardo Solis's avatar
Leonardo Solis committed
95
96
97
98
99
100
101
// by adding/subtracting n*ang_max to/from it.
// Originally from: searchoptimum.c
// --------------------------------------------------------------------------

float map_angle_180(float angle)
{
	float x = angle;
102
103
104
105
106
107
	//while (x < 0.0f)
	if (x < 0.0f)   
	{ x += 180.0f; }
	//while (x > 180.0f)
	if (x > 180.0f) 
	{ x -= 180.0f; }
Leonardo Solis's avatar
Leonardo Solis committed
108
109
110
111
112
113
	return x;
}

float map_angle_360(float angle)
{
	float x = angle;
114
115
116
117
118
119
	//while (x < 0.0f)
	if (x < 0.0f)
	{ x += 360.0f; }
	//while (x > 360.0f)
	if (x > 360.0f)
	{ x -= 360.0f;}
Leonardo Solis's avatar
Leonardo Solis committed
120
121
122
	return x;
}

123
124
// Shift register sizes
// Such registers are used to reduce Initiation Interval (II)
Leonardo Solis's avatar
Leonardo Solis committed
125
126
127
#define SHIFT_REG_SIZE 10
#define SHIFT_REG_SIZE_MINUS_ONE (SHIFT_REG_SIZE-1)

128
// --------------------------------------------------------------------------
129
// Lamarckian Genetic-Algorithm (GA): GA + LS (Local Search) 
130
131
// Originally from: searchoptimum.c
// --------------------------------------------------------------------------
132
__kernel __attribute__ ((max_global_work_dim(0)))
133
134
void Krnl_GA(__global       float*           restrict GlobPopulationCurrent,
	     __global       float*           restrict GlobEnergyCurrent,
135
136
137
138
	     #if defined(SINGLE_COPY_POP_ENE)
   	     __global       unsigned int*    restrict GlobEvals_performed,
             __global       unsigned int*    restrict GlobGens_performed,
	     #else
Leonardo Solis's avatar
Leonardo Solis committed
139
	     __global       unsigned int*    restrict GlobEvalsGenerations_performed,
140
	     #endif
Leonardo Solis's avatar
Leonardo Solis committed
141
142
143
144
145
146
147
			    unsigned int              DockConst_pop_size,
		     	    unsigned int              DockConst_num_of_energy_evals,
			    unsigned int              DockConst_num_of_generations,
		      	    float                     DockConst_tournament_rate,
			    float                     DockConst_mutation_rate,
		    	    float                     DockConst_abs_max_dmov,
			    float                     DockConst_abs_max_dang,
Leonardo Solis's avatar
Leonardo Solis committed
148
149
		    	    float                     Host_two_absmaxdmov,
			    float                     Host_two_absmaxdang,
Leonardo Solis's avatar
Leonardo Solis committed
150
			    float                     DockConst_crossover_rate,
Leonardo Solis's avatar
Leonardo Solis committed
151
#if 0
Leonardo Solis's avatar
Leonardo Solis committed
152
			    unsigned int              DockConst_num_of_lsentities,
Leonardo Solis's avatar
Leonardo Solis committed
153
#endif
154
155
156
157
158
159
160
161
			    unsigned char             DockConst_num_of_genes
	     #if defined(SINGLE_COPY_POP_ENE)
	     					      ,
	                    unsigned short            Host_RunId,
			    unsigned int 	      Host_Offset_Pop,
			    unsigned int	      Host_Offset_Ene
	     #endif
	     )
162
{
163
	#if defined (DEBUG_KRNL_GA)
164
	printf("\n");
Leonardo Solis's avatar
Leonardo Solis committed
165
	printf("%-40s %u\n", "DockConst_pop_size: ",        		DockConst_pop_size);
Leonardo Solis's avatar
Leonardo Solis committed
166
167
168
169
170
171
	printf("%-40s %u\n", "DockConst_num_of_energy_evals: ",  	DockConst_num_of_energy_evals);
	printf("%-40s %u\n", "DockConst_num_of_generations: ",  	DockConst_num_of_generations);
	printf("%-40s %f\n", "DockConst_tournament_rate: ", 		DockConst_tournament_rate);
	printf("%-40s %f\n", "DockConst_mutation_rate: ", 		DockConst_mutation_rate);
	printf("%-40s +/-%fA\n", "DockConst_abs_max_dmov: ",		DockConst_abs_max_dmov);
	printf("%-40s +/-%f°\n", "DockConst_abs_max_dang: ",  		DockConst_abs_max_dang);
Leonardo Solis's avatar
Leonardo Solis committed
172
173
	printf("%-40s +/-%fA\n", "Host_two_absmaxdmov: ",		Host_two_absmaxdmov);
	printf("%-40s +/-%f°\n", "Host_two_absmaxdang: ",  		Host_two_absmaxdang);
Leonardo Solis's avatar
Leonardo Solis committed
174
	printf("%-40s %f\n", "DockConst_crossover_rate: ", 		DockConst_crossover_rate);
Leonardo Solis's avatar
Leonardo Solis committed
175
#if 0
Leonardo Solis's avatar
Leonardo Solis committed
176
	printf("%-40s %u\n", "DockConst_num_of_lsentities: ",   	DockConst_num_of_lsentities);
Leonardo Solis's avatar
Leonardo Solis committed
177
#endif
Leonardo Solis's avatar
Leonardo Solis committed
178
	printf("%-40s %u\n", "DockConst_num_of_genes: ",        	DockConst_num_of_genes);
179
180
	#endif

181
	// Other banking configuration (see PopNext, eneNext) might reduce logic
182
	// but makes PopCurr stallable
Leonardo Solis's avatar
Leonardo Solis committed
183
184
185
	__local float LocalPopCurr[MAX_POPSIZE][ACTUAL_GENOTYPE_LENGTH];
	__local float LocalEneCurr[MAX_POPSIZE];

Leonardo Solis's avatar
Leonardo Solis committed
186
187
188
189
190
	#if defined(SINGLE_COPY_POP_ENE)
	__global float* GlobPopCurr = & GlobPopulationCurrent [Host_Offset_Pop];
	__global float* GlobEneCurr = & GlobEnergyCurrent     [Host_Offset_Ene];
	#endif

191
192
193
194
195
	bool main_loop_enable = false;
	bool exit_enable = false;
	uint eval_cnt;
	uint generation_cnt;

196
	// ------------------------------------------------------------------
197
	// Initial Calculation (IC) of scores
198
	// ------------------------------------------------------------------
199
200
	bool rx_IC_enable = false;

Leonardo Solis's avatar
Leonardo Solis committed
201
	for (ushort pop_cnt = 0; pop_cnt < DockConst_pop_size; pop_cnt++) {
202
		// Calculate energy
203
		write_channel_altera(chan_GA2IGL_IC_active, true);
204
205
		mem_fence(CLK_CHANNEL_MEM_FENCE);

Leonardo Solis's avatar
Leonardo Solis committed
206
		for (uchar pipe_cnt=0; pipe_cnt<DockConst_num_of_genes; pipe_cnt++) {
207
208

#if 0
209
			#if defined(SINGLE_COPY_POP_ENE)
Leonardo Solis's avatar
Leonardo Solis committed
210
			LocalPopCurr[pop_cnt][pipe_cnt & MASK_GENOTYPE] = GlobPopCurr[pop_cnt*ACTUAL_GENOTYPE_LENGTH + pipe_cnt];
211
			#else
Leonardo Solis's avatar
Leonardo Solis committed
212
			LocalPopCurr[pop_cnt][pipe_cnt & MASK_GENOTYPE] = GlobPopulationCurrent[pop_cnt*ACTUAL_GENOTYPE_LENGTH + pipe_cnt];
213
			#endif
214

Leonardo Solis's avatar
Leonardo Solis committed
215
			write_channel_altera(chan_IC2Conf_genotype, LocalPopCurr[pop_cnt][pipe_cnt & MASK_GENOTYPE]);	
216
217
218
219
220
221
222
223
224
225
226
227
228
#endif

#if 1
			float tmp_ic;
			#if defined(SINGLE_COPY_POP_ENE)
			tmp_ic = GlobPopCurr[pop_cnt*ACTUAL_GENOTYPE_LENGTH + pipe_cnt];
			#else
			tmp_ic = GlobPopulationCurrent[pop_cnt*ACTUAL_GENOTYPE_LENGTH + pipe_cnt];
			#endif
		
			LocalPopCurr[pop_cnt][pipe_cnt & MASK_GENOTYPE] = tmp_ic;
			write_channel_altera(chan_IC2Conf_genotype, tmp_ic);
#endif
229
		}
230

Leonardo Solis's avatar
Leonardo Solis committed
231
		#if defined (DEBUG_KRNL_IC)
Leonardo Solis's avatar
Leonardo Solis committed
232
		printf("\nIC - tx pop: %u", pop_cnt); 		
Leonardo Solis's avatar
Leonardo Solis committed
233
		#endif
234

235
236
		if (pop_cnt == (DockConst_pop_size-1)) {
			rx_IC_enable = true;
237
		}
Leonardo Solis's avatar
Leonardo Solis committed
238
	}
239

240
241
242
243
244
245
246
	// Read energy
	if (rx_IC_enable == true) {
		for (ushort pop_cnt = 0; pop_cnt < DockConst_pop_size; pop_cnt++) {
			float energyIA_IC_rx = read_channel_altera(chan_Intrae2StoreIC_intrae);
			float energyIE_IC_rx = read_channel_altera(chan_Intere2StoreIC_intere);
			mem_fence(CLK_CHANNEL_MEM_FENCE);
			LocalEneCurr[pop_cnt] = energyIA_IC_rx + energyIE_IC_rx;
Leonardo Solis's avatar
Leonardo Solis committed
247

248
249
250
			#if defined (DEBUG_KRNL_IC)
			printf(", IC - rx pop: %u\n", pop_cnt); 		
			#endif
Leonardo Solis's avatar
Leonardo Solis committed
251

252
253
254
255
256
			if (pop_cnt == (DockConst_pop_size - 1)){
				main_loop_enable = true;
				eval_cnt = DockConst_pop_size; // takes into account the IC evals
				generation_cnt = 0;
			}
Leonardo Solis's avatar
Leonardo Solis committed
257
		}
258
259
260
	}
	mem_fence(CLK_LOCAL_MEM_FENCE);
	// ------------------------------------------------------------------
Leonardo Solis's avatar
Leonardo Solis committed
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	//printf("\nIC loop finished!"); 	

	if (main_loop_enable == true) {
		while ((eval_cnt < DockConst_num_of_energy_evals) && (generation_cnt < DockConst_num_of_generations)) {

			//float LocalPopNext[MAX_POPSIZE][ACTUAL_GENOTYPE_LENGTH];
			//float LocalEneNext[MAX_POPSIZE];

			// This configuration reduces logic and does not increase block RAM usage
			float __attribute__ ((
					       memory,
			   		       numbanks(4),
					       bankwidth(32),
					      )) LocalPopNext[MAX_POPSIZE][ACTUAL_GENOTYPE_LENGTH];

			float __attribute__ ((
					       memory,
			   		       numbanks(4),
					       bankwidth(4),
					      )) LocalEneNext[MAX_POPSIZE];

			// ------------------------------------------------------------------
			// Genetic Generation (GG)
			// ------------------------------------------------------------------
			float __attribute__ ((
					       memory,
			   		       numbanks(1),
					       bankwidth(64),
					       singlepump,
	 			               numreadports(6),
					       numwriteports(1)
					      )) loc_energies[MAX_POPSIZE];
		
			bool GG_gen_enable = false;
Leonardo Solis's avatar
Leonardo Solis committed
296

297
298
			// Shift register to reduce II (initially II=6) of best entity for-loop 
			float shift_reg[SHIFT_REG_SIZE];
Leonardo Solis's avatar
Leonardo Solis committed
299

Leonardo Solis's avatar
Leonardo Solis committed
300
			#pragma unroll
301
302
			for (uchar i=0; i<SHIFT_REG_SIZE; i++) {
				shift_reg[i] = 0.0f;
Leonardo Solis's avatar
Leonardo Solis committed
303
			}
304

305
			ushort best_entity = 0;
306

307
308
309
310
	//		for (ushort pop_cnt=1; pop_cnt<DockConst_pop_size; pop_cnt++) {
			for (ushort pop_cnt=0; pop_cnt<DockConst_pop_size; pop_cnt++) {
				// copy energy to local memory
				loc_energies[pop_cnt] = LocalEneCurr[pop_cnt];
311

312
313
314
315
316
317
318
				// Identifying best entity
				// The enclosing "if (pop_cnt>0) {}" should not be commented
				// but it is removed in order to improve performance.
				// It does not affect functionality as it performs 
				// an unnecessary evaluation when pop_cnt=0 
				//if (pop_cnt>0) {
				shift_reg[SHIFT_REG_SIZE_MINUS_ONE] = loc_energies[best_entity];
Leonardo Solis's avatar
Leonardo Solis committed
319

320
321
322
323
324
325
326
327
328
				#pragma unroll
				for (uchar j=0; j<SHIFT_REG_SIZE_MINUS_ONE; j++) {
					shift_reg[j] = shift_reg[j+1];
				}
			
				if (loc_energies[pop_cnt] < shift_reg[0]) {
					best_entity = pop_cnt;
				}
				//}
Leonardo Solis's avatar
Leonardo Solis committed
329

330
331
332
				if (pop_cnt == (DockConst_pop_size-1)) {
					GG_gen_enable = true;
				}
Leonardo Solis's avatar
Leonardo Solis committed
333
			}
334

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
			bool rx_GG_enable = false;

			if (GG_gen_enable ==  true) {
				#pragma ivdep array (LocalPopNext)
				#pragma ivdep array (LocalEneNext)
				for (ushort new_pop_cnt = 1; new_pop_cnt < DockConst_pop_size; new_pop_cnt++) {

					// ---------------------------------------------------
					// Elitism: copying the best entity to new population
					// ---------------------------------------------------
					if (new_pop_cnt == 1) {
						#pragma unroll
						for (uchar gene_cnt=0; gene_cnt<ACTUAL_GENOTYPE_LENGTH; gene_cnt++) { 		
							LocalPopNext[0][gene_cnt & MASK_GENOTYPE] = LocalPopCurr[best_entity][gene_cnt & MASK_GENOTYPE]; 	
						} 		
						LocalEneNext[0] = loc_energies[best_entity];
					}
Leonardo Solis's avatar
Leonardo Solis committed
352

353
354
355
					#if defined (DEBUG_KRNL_GA)
					printf("Krnl_GA: %u\n", new_pop_cnt);
					#endif
Leonardo Solis's avatar
Leonardo Solis committed
356

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
					float local_entity_1 [ACTUAL_GENOTYPE_LENGTH];
					float local_entity_2 [ACTUAL_GENOTYPE_LENGTH]; 
		
					// ---------------------------------------------------
					// Binary-Tournament (BT) selection
					// ---------------------------------------------------

					// Get ushort binary_tournament selection prngs (parent index)
					// Get float binary_tournament selection prngs (tournament rate)
					float8 bt_tmp = read_channel_altera(chan_PRNG2GA_BT_ushort_float_prng);
					mem_fence(CLK_CHANNEL_MEM_FENCE);

					// Convert: float prng that must be still converted to short
					float bt_tmp_uf0 = bt_tmp.s0; 
					float bt_tmp_uf1 = bt_tmp.s2;
					float bt_tmp_uf2 = bt_tmp.s4;
					float bt_tmp_uf3 = bt_tmp.s6;

					// short prng ready to be used, replace ushort prng_BT_U[4];
					ushort bt_tmp_u0 = *(uint*)&bt_tmp_uf0;
					ushort bt_tmp_u1 = *(uint*)&bt_tmp_uf1;
					ushort bt_tmp_u2 = *(uint*)&bt_tmp_uf2;
					ushort bt_tmp_u3 = *(uint*)&bt_tmp_uf3;

					// float prng ready to used, replace float prng_BT_F[4];
					float bt_tmp_f0 = bt_tmp.s1;
					float bt_tmp_f1 = bt_tmp.s3;
					float bt_tmp_f2 = bt_tmp.s5;
					float bt_tmp_f3 = bt_tmp.s7;

					ushort parent1;
					ushort parent2; 

					// First parent
					if (loc_energies[bt_tmp_u0] < loc_energies[bt_tmp_u1]) {
						if (bt_tmp_f0 < DockConst_tournament_rate) {parent1 = bt_tmp_u0;}
						else				           {parent1 = bt_tmp_u1;}}
					else {
						if (bt_tmp_f1 < DockConst_tournament_rate) {parent1 = bt_tmp_u1;}
						else				           {parent1 = bt_tmp_u0;}}
Leonardo Solis's avatar
Leonardo Solis committed
397

398
399
400
401
402
403
404
					// The better will be the second parent
					if (loc_energies[bt_tmp_u2] < loc_energies[bt_tmp_u3]) {
						if (bt_tmp_f2 < DockConst_tournament_rate) {parent2 = bt_tmp_u2;}
						else		          	           {parent2 = bt_tmp_u3;}}
					else {
						if (bt_tmp_f3 < DockConst_tournament_rate) {parent2 = bt_tmp_u3;}
						else			                   {parent2 = bt_tmp_u2;}}
Leonardo Solis's avatar
Leonardo Solis committed
405

406
407
408
409
410
					// local_entity_1 and local_entity_2 are population-parent1, population-parent2
					for (uchar gene_cnt=0; gene_cnt<DockConst_num_of_genes; gene_cnt++) {
						local_entity_1[gene_cnt & MASK_GENOTYPE] = LocalPopCurr[parent1][gene_cnt & MASK_GENOTYPE];
						local_entity_2[gene_cnt & MASK_GENOTYPE] = LocalPopCurr[parent2][gene_cnt & MASK_GENOTYPE];
					}
Leonardo Solis's avatar
Leonardo Solis committed
411

412
413
414
					// ---------------------------------------------------
					// Mating parents
					// ---------------------------------------------------	
Leonardo Solis's avatar
Leonardo Solis committed
415

416
417
418
419
					// get uchar genetic_generation prngs (gene index)
					// get float genetic_generation prngs (mutation rate)
					uchar2 prng_GG_C = read_channel_altera(chan_PRNG2GA_GG_uchar_prng);
					mem_fence(CLK_CHANNEL_MEM_FENCE);
Leonardo Solis's avatar
Leonardo Solis committed
420

421
422
423
					uchar covr_point_low;
					uchar covr_point_high;
					bool twopoint_cross_yes = false;
Leonardo Solis's avatar
Leonardo Solis committed
424

425
					if (prng_GG_C.x == prng_GG_C.y) {covr_point_low = prng_GG_C.x;}
Leonardo Solis's avatar
Leonardo Solis committed
426
					else {
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
						twopoint_cross_yes = true;
						if (prng_GG_C.x < prng_GG_C.y) { covr_point_low  = prng_GG_C.x;
									         covr_point_high = prng_GG_C.y; }
						else {		      		 covr_point_low  = prng_GG_C.y;
		   								 covr_point_high = prng_GG_C.x; }
					}
			
					// Reuse of bt prng float as crossover-rate
					bool crossover_yes = (DockConst_crossover_rate > bt_tmp_f0);

					write_channel_altera(chan_GA2IGL_GG_active, true);
					mem_fence(CLK_CHANNEL_MEM_FENCE);

					for (uchar gene_cnt=0; gene_cnt<DockConst_num_of_genes; gene_cnt++) {

						float prngGG = read_channel_altera(chan_PRNG2GA_GG_float_prng);
						mem_fence(CLK_CHANNEL_MEM_FENCE);

						float tmp_offspring;

						// Performing crossover
						if (   	(
							crossover_yes && (										// crossover
							( (twopoint_cross_yes == true)  && ((gene_cnt <= covr_point_low) || (gene_cnt > covr_point_high)) )  ||	// two-point crossover 			 		
							( (twopoint_cross_yes == false) && (gene_cnt <= covr_point_low))  					// one-point crossover
							)) || 
							(!crossover_yes)	// no crossover
						   ) {
							tmp_offspring = local_entity_1[gene_cnt & MASK_GENOTYPE];
						}
						else {
							tmp_offspring = local_entity_2[gene_cnt & MASK_GENOTYPE];
						}

						// Performing mutation
						if (DockConst_mutation_rate > prngGG) {
							if(gene_cnt<3) {
								tmp_offspring = tmp_offspring + Host_two_absmaxdmov*prngGG-DockConst_abs_max_dmov;
							}
							else {
								float tmp;
								tmp = tmp_offspring + Host_two_absmaxdang*prngGG-DockConst_abs_max_dang;
								if (gene_cnt==4) { tmp_offspring = map_angle_180(tmp); }
								else             { tmp_offspring = map_angle_360(tmp); }
							}
						}

						// Calculate energy
						LocalPopNext [new_pop_cnt][gene_cnt & MASK_GENOTYPE] = tmp_offspring;
						write_channel_altera(chan_GG2Conf_genotype, tmp_offspring);
Leonardo Solis's avatar
Leonardo Solis committed
477
478
					}

479
480
481
482
483
484
485
486
					#if defined (DEBUG_KRNL_GG)
					printf("GG - tx pop: %u", new_pop_cnt); 		
					#endif	

					if (new_pop_cnt == (DockConst_pop_size-1)) {
						rx_GG_enable = true;
					}
				}
Leonardo Solis's avatar
Leonardo Solis committed
487
			}
488

489
490
491
492
			// No channel nor global/local fence would be useful for synchronization here
			// as theres no such dependency between blocks in question,
			// update_pop_ene_enable is added
			bool update_pop_ene_enable = false;
493

494
			// Read energy
495
496
497
498
499
500
501
502
503
504
505
506
507
508
			if (rx_GG_enable == true) {
				for (ushort new_pop_cnt = 1; new_pop_cnt < DockConst_pop_size; new_pop_cnt++) {
					float energyIA_GG_rx = read_channel_altera(chan_Intrae2StoreGG_intrae);
					float energyIE_GG_rx = read_channel_altera(chan_Intere2StoreGG_intere);
					mem_fence(CLK_CHANNEL_MEM_FENCE);
					LocalEneNext[new_pop_cnt] = energyIA_GG_rx + energyIE_GG_rx;

					#if defined (DEBUG_KRNL_GG)
					printf(", GG - rx pop: %u\n", new_pop_cnt); 		
					#endif

					if (new_pop_cnt == (DockConst_pop_size-1)) {
						update_pop_ene_enable = true;
					}
509
510
				}
			}
511
512
		
			// TODO: check that pop en curr is correctly updated!
Leonardo Solis's avatar
Leonardo Solis committed
513

514
515
516
517
518
519
			// Update current pops & energies
			if (update_pop_ene_enable == true) {
				for (ushort pop_cnt=0; pop_cnt<DockConst_pop_size; pop_cnt++) {
					for (uchar gene_cnt=0; gene_cnt<DockConst_num_of_genes; gene_cnt++) {
						LocalPopCurr[pop_cnt][gene_cnt & MASK_GENOTYPE] = LocalPopNext[pop_cnt][gene_cnt & MASK_GENOTYPE];
					}
Leonardo Solis's avatar
Leonardo Solis committed
520

521
522
					LocalEneCurr[pop_cnt] = LocalEneNext[pop_cnt];
				}
Leonardo Solis's avatar
Leonardo Solis committed
523
			}
524
			mem_fence(CLK_LOCAL_MEM_FENCE);
Leonardo Solis's avatar
Leonardo Solis committed
525

526
527
			// Update energy evaluations count: GG evals
			eval_cnt += DockConst_pop_size; 
Leonardo Solis's avatar
Leonardo Solis committed
528

529
530
			// Update generation count
			generation_cnt++;
Leonardo Solis's avatar
Leonardo Solis committed
531

532
533
534
535
			#if defined (DEBUG_KRNL_GA)
			printf("eval_cnt: %u, generation_cnt: %u\n", eval_cnt, generation_cnt);
			#endif
		} // End while eval_cnt & generation_cnt
Leonardo Solis's avatar
Leonardo Solis committed
536

537
538
539
540
		if ((eval_cnt > DockConst_num_of_energy_evals) || (generation_cnt > DockConst_num_of_generations)) {
			exit_enable = true;
		}
	} // End if (main_loop_enable == true)
541

542
	// ------------------------------------------------------------------
543
	// Off: turn off all other kernels
544
	// ------------------------------------------------------------------
Leonardo Solis's avatar
Leonardo Solis committed
545

546
547
548
549
550
551
	if (exit_enable == true) {
		// Turn off PRNG kernels
		write_channel_altera(chan_Arbiter_BT_ushort_float_off,  false);
		write_channel_altera(chan_Arbiter_GG_uchar_off, 	false);
		write_channel_altera(chan_Arbiter_GG_float_off, 	false);
		mem_fence(CLK_CHANNEL_MEM_FENCE);
552

553
554
555
		// Turn off IGL_Arbiter, Conform, InterE, IntraE kernerls
		write_channel_altera(chan_IGLArbiter_Off,     		false);
		mem_fence(CLK_CHANNEL_MEM_FENCE);
Leonardo Solis's avatar
Leonardo Solis committed
556

557
558
559
560
561
562
563
564
565
566
		// Write final pop & energies back to FPGA-board DDRs
		for (ushort pop_cnt=0;pop_cnt<DockConst_pop_size; pop_cnt++) { 	

			for (uchar gene_cnt=0; gene_cnt<DockConst_num_of_genes; gene_cnt++) {
				#if defined(SINGLE_COPY_POP_ENE)
				GlobPopCurr[pop_cnt*ACTUAL_GENOTYPE_LENGTH + gene_cnt] = LocalPopCurr[pop_cnt][gene_cnt & MASK_GENOTYPE];
				#else
				GlobPopulationCurrent[pop_cnt*ACTUAL_GENOTYPE_LENGTH + gene_cnt] = LocalPopCurr[pop_cnt][gene_cnt & MASK_GENOTYPE];
				#endif
			}
Leonardo Solis's avatar
Leonardo Solis committed
567

568
			#if defined(SINGLE_COPY_POP_ENE)
569
			GlobEneCurr[pop_cnt] = LocalEneCurr[pop_cnt];
570
			#else
571
			GlobEnergyCurrent[pop_cnt] = LocalEneCurr[pop_cnt];
572
			#endif
Leonardo Solis's avatar
Leonardo Solis committed
573
		}
574

575
576
577
578
579
580
581
582
583
		#if defined (DEBUG_KRNL_GA)
		printf("GA: %u %u\n", active, DockConst_pop_size -1);
		#endif

		#if defined (DEBUG_ACTIVE_KERNEL)
		printf("	%-20s: %s\n", "Krnl_GA", "disabled");
		#endif

		// Write final evals & generation counts to FPGA-board DDRs
584
		#if defined(SINGLE_COPY_POP_ENE)
585
586
		GlobEvals_performed[Host_RunId] = eval_cnt;
		GlobGens_performed [Host_RunId] = generation_cnt;
587
		#else
588
589
		GlobEvalsGenerations_performed[0] = eval_cnt;
		GlobEvalsGenerations_performed[1] = generation_cnt;
590
		#endif
Leonardo Solis's avatar
Leonardo Solis committed
591
	}
592
593
594
595
596
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------

Leonardo Solis's avatar
Leonardo Solis committed
597
#include "Krnl_PRNG.cl"
598

599
#include "Krnl_IGL_Arbiter.cl"
600
601
#include "Krnl_Conform.cl"
#include "Krnl_InterE.cl"
602
#include "Krnl_IntraE.cl"
603