Krnl_LS7.cl 7.85 KB
Newer Older
1
2
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
lvs's avatar
lvs committed
3
__kernel __attribute__ ((reqd_work_group_size(1,1,1)))
4
5
6
7
8
9
10
void Krnl_LS7(
		unsigned short            DockConst_max_num_of_iters,		
		float                     DockConst_rho_lower_bound,
		float                     DockConst_base_dmov_mul_sqrt3,
		unsigned char             DockConst_num_of_genes,
   		float                     DockConst_base_dang_mul_sqrt3,
		unsigned char             DockConst_cons_limit
11
12

#if !defined(SW_EMU)
13
14
		// IMPORTANT: enable this dummy global argument only for "hw" build.
		// Check ../common_xilinx/utility/boards.mk
15
16
17
18
		// https://forums.xilinx.com/t5/SDAccel/ERROR-KernelCheck-83-114-in-sdx-2017-4/td-p/818135
		,
		__global int *dummy
#endif
19
20
)
{
21
22
23
24
25
26
27
28
29
	#if 0
	printf("\nLS7: DockConst_max_num_of_iters: %u\n",   DockConst_max_num_of_iters);
	printf("LS7: DockConst_rho_lower_bound: %f\n",      DockConst_rho_lower_bound);
	printf("LS7: DockConst_base_dmov_mul_sqrt3: %f\n",  DockConst_base_dmov_mul_sqrt3);
	printf("LS7: DockConst_num_of_genes: %u\n",  	    DockConst_num_of_genes);
	printf("LS7: DockConst_base_dang_mul_sqrt3: %f\n",  DockConst_base_dang_mul_sqrt3);
	printf("LS7: DockConst_cons_limit: %u\n",           DockConst_cons_limit);
	#endif

30
31
	/*bool valid = true;*/
	char valid = 0x01;
32

33
34
__attribute__((xcl_pipeline_loop))
LOOP_WHILE_LS7_MAIN:
35
while(valid) {
36

37
	int active;
38
	nb_pipe_status valid_active = PIPE_STATUS_FAILURE;
39
40

	float current_energy;
41
	nb_pipe_status valid_energy = PIPE_STATUS_FAILURE;
42

43
	__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
44
	LOOP_WHILE_LS7_ACTIVE:
45
	while( (valid_active != PIPE_STATUS_SUCCESS) && (valid_energy != PIPE_STATUS_SUCCESS)) {
lvs's avatar
lvs committed
46
47
		valid_active = read_pipe(chan_GA2LS_Off7_active, &active);
		valid_energy = read_pipe(chan_GA2LS_LS7_energy,  &current_energy);
48
	}
49

50
	// (active == 1) means stop LS
51
52
53
54
55
	/*valid = (active != 1) || (valid_energy == PIPE_STATUS_SUCCESS);*/

	// Received something on pipe: chan_GA2LS_Off_active?
	// If so, then turn this kernel off
	valid = (valid_active == PIPE_STATUS_SUCCESS)? 0x00:0x01;
56
57
58
59
60

	if (valid) {

		float   genotype [ACTUAL_GENOTYPE_LENGTH];

61
		__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
62
		LOOP_FOR_LS7_READ_INPUT_GENOTYPE:
63
		for (uchar i=0; i<DockConst_num_of_genes; i++) {
lvs's avatar
lvs committed
64
			read_pipe_block(chan_GA2LS_LS7_genotype, &genotype [i] );
65
66
67
68
69
70
71
72
73
74
75
76
77
78
		}
	
		#if defined (DEBUG_KRNL_LS7)
		printf("In of while iter LS7\n");
		#endif

		float rho = 1.0f;
		ushort iteration_cnt = 0;
		uchar  cons_succ     = 0;
		uchar  cons_fail     = 0;
		uint   LS_eval       = 0;
		bool   positive_direction = true;

		// performing local search
79
		__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
80
		LOOP_WHILE_LS7_ITERATION_RHO:
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
		while ((iteration_cnt < DockConst_max_num_of_iters) && (rho > DockConst_rho_lower_bound)) {	
			// -----------------------------------------------
			// Exit condition is groups here. It allows pipelining
			if (positive_direction == true) { 
				if (cons_succ >= DockConst_cons_limit) {
					rho = LS_EXP_FACTOR*rho;
					cons_fail = 0;
					cons_succ = 0;
				}
				else if (cons_fail >= DockConst_cons_limit) {
					rho = LS_CONT_FACTOR*rho;
					cons_fail = 0;
					cons_succ = 0;
				}
				iteration_cnt++;
			}

			#if defined (DEBUG_KRNL_LS7)
			printf("LS7 positive?: %u, iteration_cnt: %u, rho: %f, limit rho: %f\n", positive_direction, iteration_cnt, rho, DockConst_rho_lower_bound);
			#endif
			// -----------------------------------------------

			float entity_possible_new_genotype   [ACTUAL_GENOTYPE_LENGTH];
			float genotype_bias                  [ACTUAL_GENOTYPE_LENGTH];
			float deviate_plus_bias              [ACTUAL_GENOTYPE_LENGTH];
			float deviate_minus_bias             [ACTUAL_GENOTYPE_LENGTH];

			// Tell Krnl_Conf_Arbiter, LS7 is done
			// Not completely strict as the (iteration_cnt < DockConst_max_num_of_iters) is ignored
			// In practice, rho condition dominates most of the cases
111
112
			int tmp_int = (rho < DockConst_rho_lower_bound)?0:1;
			write_pipe_block(chan_LS2Arbiter_LS7_end, &tmp_int);
lvs's avatar
lvs committed
113
/*
114
			mem_fence(CLK_CHANNEL_MEM_FENCE);
lvs's avatar
lvs committed
115
*/
116
117
118
		
			// new random deviate
			// rho is the deviation of the uniform distribution
119
			__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
120
			LOOP_FOR_LS7_WRITE_GENOTYPE:
121
			for (uchar i=0; i<DockConst_num_of_genes; i++) {
lvs's avatar
lvs committed
122
				float tmp_prng;
Leonardo Solis's avatar
Leonardo Solis committed
123
				read_pipe_block(chan_PRNG2LS7_float_prng, &tmp_prng);
lvs's avatar
lvs committed
124
/*
125
				mem_fence(CLK_CHANNEL_MEM_FENCE);
lvs's avatar
lvs committed
126
*/
127
128
129
130
131
132
133
134
135
136
137
				// tmp1 is genotype_deviate
				float tmp1 = rho * (2.0f*tmp_prng - 1.0f);

				if (i<3) { tmp1 = tmp1 * DockConst_base_dmov_mul_sqrt3; }
				else 	 { tmp1 = tmp1 * DockConst_base_dang_mul_sqrt3; }

				float deviate = 0.4f*tmp1;

				// tmp2 is the addition: genotype_deviate + genotype_bias
				// tmp3 is entity_possible_new_genotype
				float tmp_bias = (iteration_cnt == 1)? 0.0f:genotype_bias [i];
lvs's avatar
lvs committed
138
				float bias = 0.6f * tmp_bias;
139
140
141
142
143
144
145

				deviate_plus_bias  [i] = deviate + bias;
				deviate_minus_bias [i] = deviate - bias;

				float tmp2 = tmp1 + tmp_bias;
				float tmp3 = (positive_direction == true)? (genotype [i] + tmp2): (genotype [i] - tmp2);

146
				if (i>2) {if (i==4) { tmp3 = map_angle_180(tmp3);}
147
148
149
					  else      { tmp3 = map_angle_360(tmp3);}}

				entity_possible_new_genotype [i] = tmp3;
lvs's avatar
lvs committed
150
				write_pipe_block(chan_LS2Conf_LS7_genotype, &tmp3);
151
152
153
154
155
156
157
158
159
160

				#if defined (DEBUG_KRNL_LS7)
				printf("LS7_genotype sent: %u\n", i);
				#endif
			}

			//printf("Energy to calculate sent from LS7 ... ");

			float energyIA_LS_rx;
			float energyIE_LS_rx;
lvs's avatar
lvs committed
161

162
163
164
			nb_pipe_status intra_valid = PIPE_STATUS_FAILURE;
			nb_pipe_status inter_valid = PIPE_STATUS_FAILURE;

165
			__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
166
			LOOP_WHILE_LS7_READ_ENERGIES:
167
168
169
			while( (intra_valid != PIPE_STATUS_SUCCESS) || (inter_valid != PIPE_STATUS_SUCCESS)) {

				if (intra_valid != PIPE_STATUS_SUCCESS) {
lvs's avatar
lvs committed
170
					intra_valid = read_pipe(chan_Intrae2StoreLS_LS7_intrae, &energyIA_LS_rx );
171
				}
172
				else if (inter_valid != PIPE_STATUS_SUCCESS) {
lvs's avatar
lvs committed
173
					inter_valid = read_pipe(chan_Intere2StoreLS_LS7_intere, &energyIE_LS_rx);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
				}
			}

			float candidate_energy = energyIA_LS_rx + energyIE_LS_rx;

			// update LS energy-evaluation count
			LS_eval++;

			#if defined (DEBUG_KRNL_LS7)
			printf("INTERE received in LS7: %u\n", LS_eval);
			#endif

			if (candidate_energy < current_energy) {
				// updating offspring_genotype
				// updating genotype_bias
189
				__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
190
				LOOP_FOR_LS7_FLOATPT_UPDATE_POS_GENOTYPE:
191
192
193
194
195
196
197
198
199
200
201
202
203
				for (uchar i=0; i<DockConst_num_of_genes; i++) {
					genotype_bias [i] = (positive_direction == true) ?  deviate_plus_bias  [i] : 
											    deviate_minus_bias [i] ;
					genotype [i] = entity_possible_new_genotype [i];
				}	

				current_energy = candidate_energy;
				cons_succ++;
				cons_fail = 0;
				positive_direction = true;				
			}
			else {
				// updating (halving) genotype_bias
204
				__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
205
				LOOP_FOR_LS7_FLOATPT_UPDATE_NEG_GENOTYPE:
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
				for (uchar i=0; i<DockConst_num_of_genes; i++) {
					genotype_bias [i] = (iteration_cnt == 1)? 0.0f: (0.5f*genotype_bias [i]);
				}

				if (positive_direction == false) {
					cons_fail++;
					cons_succ = 0;
				}
				positive_direction = !positive_direction;
			}

		} // end of while (iteration_cnt) && (rho)
	
		#if defined (DEBUG_KRNL_LS7)
		printf("Out of while iter LS7\n");
		#endif

		// write back data to GA
224
		__attribute__((xcl_pipeline_loop))
Leonardo Solis's avatar
Leonardo Solis committed
225
		LOOP_FOR_LS7_WRITEBACK2GA:
226
227
228
		for (uchar i=0; i<DockConst_num_of_genes; i++) {
			if (i == 0) {
				float2 evalenergy  = {*(float*)&LS_eval, current_energy};
lvs's avatar
lvs committed
229
				write_pipe_block(chan_LS2GA_LS7_evalenergy, &evalenergy);
230
			}
lvs's avatar
lvs committed
231
/*
232
			mem_fence(CLK_CHANNEL_MEM_FENCE);
lvs's avatar
lvs committed
233
234
*/
			write_pipe_block(chan_LS2GA_LS7_genotype, &genotype [i]);
235
236
237
238
239
240
241
242
243
244
245
246
247
248
		}

	} // End of if (valid)
	
} // End of while (valid)		

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

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