Blame view

Debug/src/kernels/cl_explore.cl 33.7 KB
0c8ce2b0   Pedro Roque   missing files
1
2
3
4
/*
 * cl_explore.cl
 *
 *  Created on: 19/03/2015
4d26a735   Pedro Roque   Increased recogni...
5
 *      Author: Pedro
0c8ce2b0   Pedro Roque   missing files
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 */

#if CUDA_VERSION
#include "../utils/cu_syntax.h"
#endif

#ifndef __OPENCL_VERSION__

#include <stdbool.h>
#include <sys/types.h>
#include <stdio.h>
#include <stddef.h>
#include "cl_explore.h"
#include "cl_aux_functions.h"
#include "cl_propagators.h"
#include "../utils/cl_syntax.h"
0c8ce2b0   Pedro Roque   missing files
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

#else

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
//#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable		// not supported by some devices
//#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable	// not supported by some devices

#include "cl_aux_functions.c"
#include "cl_propagators.c"

#endif

#include "../config.h"
#include "../domains.h"
#include "cl_constraints.h"
#include "cl_variables.h"
#include "cl_ttl.h"

#if CL_D_TYPE == CL_BITMAP
#include "cl_bitmaps.h"
#elif CL_D_TYPE == CL_INTERVAL
#include  "cl_intervals.h"
#endif

/*
4d26a735   Pedro Roque   Increased recogni...
48
 * Explore the received sub-search spaces and return the number of solutions found or the solution found
0c8ce2b0   Pedro Roque   missing files
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 */
// atoms: (for finding all solutions)
// buffer for atomics data (Most devices only have atomics for 32 bits variables)
// 0 - first sub-search to explore
// 1 - last sub-search to explore
// 2 - n_ss
// 3 - depth
// 4 - WIs still working for work-sharing
// 5 - 5+N_VS - n_repeat per variable
// 5+N_VS...5+N_VS+N_WG*N_WI_WG - number of solutions found per work-item
//
// atoms: (for finding one solution)
// buffer for atomics data (Most devices only have atomics for 32 bits variables)
// 0 - first sub-search to explore
// 1 - last sub-search to explore
// 2 - n_ss
// 3 - depth
// 4 - WIs still working for work-sharing
// 5 - 5+N_VS - n_repeat per variable
// 5+N_VS - solution found flag
//
// atoms: (optimization)
// buffer for atomics data (Most devices only have atomics for 32 bits variables)
// 0 - first sub-search to explore
// 1 - last sub-search to explore
// 2 - n_ss
// 3 - depth
// 4 - WIs still working for work-sharing
// 5 - 5+N_VS - n_repeat per variable
// 5+N_VS - solution found flag
// 6+N_VS - Value to optimize
// 7+N_VS - WIs still working for saving the best solution
//
// ints:
// 0...+cs_vs_idx	- each constraint list of constrained variables ids placed per constraint order
// cs_vs_idx...cs_vs_idx+vs_cs_idx	- each variable list of constraints ids placed per variable order
// cs_vs_idx+vs_cs_idx...cs_vs_idx+vs_cs_idx+n_const_cs	- each constraint list of constants placed per constraint order
//
// backtrack:
4d26a735   Pedro Roque   Increased recogni...
88
// 0...(n_vs_to_label+2)*CL_N_VS*CL_SPLIT_VALUES_EXT*wi_total - backtracking history
0c8ce2b0   Pedro Roque   missing files
89
90
//
// generic:
4d26a735   Pedro Roque   Increased recogni...
91
// (dev_args->n_vs_to_label + 2) * dev_args->split_values_ext) * 2 - to use in kernel (hist_labeleds_id and hist_labeleds_n_vals)
0c8ce2b0   Pedro Roque   missing files
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// n_terms * dev_args->wi_total - to use in propagators
// CL_D_MAX+1 - for ss generation
//
// cs_ignore
// CL_N_CS*wi_total - Buffer for storing the flags that indicate if a constraint can prune more on device
//
// domains: (for finding one solution)
// 0...N_VS - solution domains
//
// domains: (optimization)
// 0...N_VS*(CL_D_MAX+1) - (CL_D_MAX+1) solution stores because concurrency control
//
// vs_id_to_prop:
// 0 - first index of the vector that contains an variable ID to propagate
// 1 - index of the vector where next variable ID to propagate should be added
// 2...2+CL_N_VS+3 - variables ID to propagate
//
// stats:
// 0 - (*nodes_fail)
// 1 - (*nodes_expl)
// 2 - (*backtracks)
// 3 - (*labels)
// 4 - (*pruning)
// 5 - (*props_ok)
// 6 - (*max_depth)
// ... repeat per work-item
//
// flags for signaling the state of each work-sharing store
// 0 - next shared SS to be picked
// 1 - next shared SS to be filled
// 2...number of SS already filled
// 3..3+CL_N_SHARED_SS - V_ID that was labeled to generate this SS
//
// filt_domains:
// 0...N_VS - size of domains_mem buffer for the filtering result
//
// filt_cs:
// 0...N_CS - size of filt_cs_size buffer for the filtering
4d26a735   Pedro Roque   Increased recogni...
130
131
132
133
__kernel void explore(
		__global unsigned int *atoms,	// read/write to all work-items
		CL_INTS_MEM int *ints,			// read to all work-items
		__global DOMAIN_ *backtrack1,	// to store backtracking history
0c8ce2b0   Pedro Roque   missing files
134
135

#if CL_USE_N_BUFFERS > 1
4d26a735   Pedro Roque   Increased recogni...
136
		__global DOMAIN_* backtrack2,	// to store backtracking history
0c8ce2b0   Pedro Roque   missing files
137
138
#endif
#if CL_USE_N_BUFFERS > 2
4d26a735   Pedro Roque   Increased recogni...
139
		__global DOMAIN_* backtrack3,	// to store backtracking history
0c8ce2b0   Pedro Roque   missing files
140
141
#endif
#if CL_USE_N_BUFFERS > 3
4d26a735   Pedro Roque   Increased recogni...
142
		__global DOMAIN_* backtrack4,	// to store backtracking history
0c8ce2b0   Pedro Roque   missing files
143
144
#endif

4d26a735   Pedro Roque   Increased recogni...
145
		__global int *generic_mem,		// multiple purposes buffer
0c8ce2b0   Pedro Roque   missing files
146
#if CL_CS_IGNORE
4d26a735   Pedro Roque   Increased recogni...
147
		__global char *cs_ignore_,		// for cs_ignore flags
0c8ce2b0   Pedro Roque   missing files
148
149
150
#endif

#if CL_WORK == CL_ONE || CL_WORK == CL_OPT
4d26a735   Pedro Roque   Increased recogni...
151
		__global DOMAIN_ *domains,		// to store the solution
0c8ce2b0   Pedro Roque   missing files
152
153
#endif

4d26a735   Pedro Roque   Increased recogni...
154
155
		CL_VS_MEM VARS *vs,				// variables structure common to all work-items
		CL_CS_MEM cl_constr *cs			// constraints structure common to all work-items
0c8ce2b0   Pedro Roque   missing files
156
157

#if (CUDA_VERSION == 1 && CL_MEM != CL_USE_LOCAL_MEM) || CUDA_VERSION == 0
4d26a735   Pedro Roque   Increased recogni...
158
159
		, CL_MEMORY VARS_PROP *vs_prop,				// variable structures per work-item
		CL_MEMORY unsigned short *vs_id_to_prop		// list of variables marked for propagation
0c8ce2b0   Pedro Roque   missing files
160
161
162
#endif

#if CL_D_TYPE == CL_BITMAP
4d26a735   Pedro Roque   Increased recogni...
163
		, CL_B_DS_MEM cl_bitmap *b_ds		// when using bitmaps, this array contains the original domains of all the CSP variables
0c8ce2b0   Pedro Roque   missing files
164
165
166
#endif

#if CL_STATS == 1
4d26a735   Pedro Roque   Increased recogni...
167
		, __global unsigned long *stats		// to count statistics
0c8ce2b0   Pedro Roque   missing files
168
169
170
#endif

#if CL_N_DEVS > 1
4d26a735   Pedro Roque   Increased recogni...
171
		, __global unsigned long *props		// 1 per work-item for counting the number of propagations made by each work-item
0c8ce2b0   Pedro Roque   missing files
172
173
174
#endif

#if CL_N_SHARED_SS > 0
4d26a735   Pedro Roque   Increased recogni...
175
176
		, __global DOMAIN_* shared_ss		// stores for work-sharing
		, __global int* shared_ss_flags		// flags for atomic operations between work-items
0c8ce2b0   Pedro Roque   missing files
177
178
179
180
#endif

#if CL_FILTERING
		,
4d26a735   Pedro Roque   Increased recogni...
181
		__global DOMAIN_ *filt_domains	// for the domains of the variables
0c8ce2b0   Pedro Roque   missing files
182
#if CL_CS_IGNORE
4d26a735   Pedro Roque   Increased recogni...
183
		, __global char *filt_cs		// for the flag of ignoring constraints
0c8ce2b0   Pedro Roque   missing files
184
185
#endif
#endif
4d26a735   Pedro Roque   Increased recogni...
186
		) {
0c8ce2b0   Pedro Roque   missing files
187

4d26a735   Pedro Roque   Increased recogni...
188
189
190
191
	CL_INTS_MEM int *vs_per_c_idx = ints;		// each constraint list of constrained variables ids placed per constraint order
	CL_INTS_MEM int *cs_per_v_idx = vs_per_c_idx + CL_N_VS_CS; 		// each variable list of constraints ids placed per variable order
#if CS_AT_LEAST == 1 || CS_AT_MOST == 1 || CS_AT_MOST_ONE == 1 || CS_EXACTLY == 1 || CS_INT_LIN_EQ == 1 || CS_INT_LIN_LE == 1 || CS_INT_LIN_NE == 1 || CS_INT_LIN_VAR == 1 || CS_ARRAY_INT_ELEMENT == 1  || CS_BOOL_LIN_EQ == 1 || CS_BOOL_LIN_LE == 1
	CL_INTS_MEM int *c_consts = cs_per_v_idx + CL_N_CS_VS; 		// each constraint list of constants placed per constraint order
0c8ce2b0   Pedro Roque   missing files
192
193
194
195
196
197
#endif

	int wi_glob_id = get_global_id(0);	// this global work item id
	int wi_total = get_global_size(0);	// total number of work-items

#if CL_N_DEVS > 1
4d26a735   Pedro Roque   Increased recogni...
198
	unsigned long props_count = 0;	// to calculate this device performance for work-distribution between devices
0c8ce2b0   Pedro Roque   missing files
199
200
201
#endif
	int hist_tree_level = 0;	// current backtracking level on the tree
	// ID of the variable that was labeled from one level of the backtracking tree to the next one
4d26a735   Pedro Roque   Increased recogni...
202
	__global int *hist_labeleds_id = &generic_mem[(CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * 2 * wi_glob_id];
0c8ce2b0   Pedro Roque   missing files
203
	// Number of values on the variable that was labeled from one level of the backtracking tree to the next one
4d26a735   Pedro Roque   Increased recogni...
204
205
206
	__global int *hist_labeleds_n_vals = hist_labeleds_id + ((CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT);
	// auxiliary memory to use on propagators
	__global int *terms_mem = &generic_mem[(CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * 2 * wi_total + CL_N_TERMS * wi_glob_id];
0c8ce2b0   Pedro Roque   missing files
207
	// to use when generating each ss
4d26a735   Pedro Roque   Increased recogni...
208
209
210
211
212
213
214
	__global int *ss_aux_mem = &generic_mem[((CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * 2 * wi_total + CL_N_TERMS * wi_total) + (CL_D_MAX + 1) * wi_glob_id];

#if CL_FZN_SEQ && CL_FZN_SEQ_N_LABELS > 1
	// list of ordered labeling heuristics to use
	__global int *label_hs = &generic_mem[((CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * 2 * wi_total + CL_N_TERMS * wi_total) + (CL_D_MAX + 1) * wi_total];
	int last_label_h_idx = 0;	// index of labeling heuristic currently used
#endif
0c8ce2b0   Pedro Roque   missing files
215
216

#if CL_CS_IGNORE
4d26a735   Pedro Roque   Increased recogni...
217
	__global char *cs_ignore = cs_ignore_ + CL_N_CS * wi_glob_id;	// flags to signal if this work-item constrains can be ignored in the current ss
0c8ce2b0   Pedro Roque   missing files
218
219
220
221
	clear_cs_ignore(cs_ignore);
#endif

	unsigned int prop_v_id;	// Next variable to propagate
4d26a735   Pedro Roque   Increased recogni...
222
223
	bool prop_ok;			// flag for signaling if the last propagations was consistent
	bool labeled = 1;		// flag for signaling if the last attempt for labeling was successful
0c8ce2b0   Pedro Roque   missing files
224
225
226
	int i, j, k;

#if CL_PRE_LABELING == 1
4d26a735   Pedro Roque   Increased recogni...
227
#define PROP_NORMALLY 0		// 0 - propagate normally
0c8ce2b0   Pedro Roque   missing files
228
229
#define PROP_PRE_LABELING 1	// 1 - propagate revising
#define PRE_LABELED_OK 2	// 2 - revising propagated ok
4d26a735   Pedro Roque   Increased recogni...
230
#define PRE_LABELED_NOK 3	// 3 - revising propagated not ok
0c8ce2b0   Pedro Roque   missing files
231
232
233
234
235
	int revise = PROP_NORMALLY;
#endif

	// if statistics should be collected
#if CL_STATS == 1
4d26a735   Pedro Roque   Increased recogni...
236
237
238
239
240
241
242
	__global unsigned long *nodes_fail = stats + wi_glob_id * 7;
	__global unsigned long *nodes_expl = stats + wi_glob_id * 7 + 1;
	__global unsigned long *backtracks = stats + wi_glob_id * 7 + 2;
	__global unsigned long *labels = stats + wi_glob_id * 7 + 3;
	__global unsigned long *pruning = stats + wi_glob_id * 7 + 4;
	__global unsigned long *props_ok = stats + wi_glob_id * 7 + 5;
	__global unsigned long *max_depth = stats + wi_glob_id * 7 + 6;
0c8ce2b0   Pedro Roque   missing files
243
244
245
#endif

#if CL_MEM == CL_USE_LOCAL_MEM
4d26a735   Pedro Roque   Increased recogni...
246
247
	int wi_loc_id = get_local_id(0);		// number of this work item in its work-group
	int wi_local_size = get_local_size(0);	// number of work-items per work-group
0c8ce2b0   Pedro Roque   missing files
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

#if CUDA_VERSION == 1
	extern __shared__ ushort local_mem[];
	int vs_id_to_prop_size = CL_N_VS + 3;

	// due to shared memory alignment in CUDA
	if (CL_WORD == 32) {
		while ((vs_id_to_prop_size * 8) % 32 != 0) {
			vs_id_to_prop_size++;
		}
	} else { // 64
		while ((vs_id_to_prop_size * 8) % 64 != 0) {
			vs_id_to_prop_size++;
		}
	}

	ushort* vs_id_to_prop = local_mem;
	ushort* vs_prop_begin = &local_mem[wi_local_size * vs_id_to_prop_size];
	VARS_PROP* vs_prop = (VARS_PROP*)vs_prop_begin;

	ushort* vs_id_to_prop_ = &vs_id_to_prop[wi_loc_id * (CL_N_VS + 3)];
	VARS_PROP* vs_prop_ = &vs_prop[wi_loc_id * CL_N_VS];

#else

	//	vector with variables ID to propagate for this work-item
4d26a735   Pedro Roque   Increased recogni...
274
	CL_MEMORY unsigned short *vs_id_to_prop_ = vs_id_to_prop + wi_loc_id * (CL_N_VS + 3);
0c8ce2b0   Pedro Roque   missing files
275
	// CSP variables for propagation in local memory for this work-item
4d26a735   Pedro Roque   Increased recogni...
276
	CL_MEMORY VARS_PROP *vs_prop_ = vs_prop + wi_loc_id * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
277
278
279
280
281
282
283
284
285
#endif
#else
	//	vector with variables ID to propagate for this work-item
	CL_MEMORY unsigned short* vs_id_to_prop_ = vs_id_to_prop + wi_glob_id * (CL_N_VS + 3);
	// CSP variables for propagation in local memory for this work-item
	CL_MEMORY VARS_PROP* vs_prop_ = vs_prop + wi_glob_id * CL_N_VS;
#endif

#if CL_WORK == CL_OPT
4d26a735   Pedro Roque   Increased recogni...
286
	__global unsigned int *wis_working_opt = atoms + 7 + CL_N_VS;	// number of WIs still working for saving the best solution
0c8ce2b0   Pedro Roque   missing files
287
288
289
290
291
292
293
#endif

#if CL_N_SHARED_SS > 0
	__global unsigned int* wis_working = atoms + 4;	// number of WIs still working for work-sharing
#endif

	// backtracking history for this work-item
4d26a735   Pedro Roque   Increased recogni...
294
	__global DOMAIN_ *hist;
0c8ce2b0   Pedro Roque   missing files
295
#if CL_USE_N_BUFFERS == 1
4d26a735   Pedro Roque   Increased recogni...
296
	hist = backtrack1 + wi_glob_id * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
297
298
299

#elif CL_USE_N_BUFFERS == 2
	if (wi_glob_id < wi_total / 2) {
4d26a735   Pedro Roque   Increased recogni...
300
		hist = backtrack1 + wi_glob_id * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
301
302

	} else {
4d26a735   Pedro Roque   Increased recogni...
303
		hist = backtrack2 + (wi_glob_id - (wi_total / 2)) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
304
305
306
	}
#elif CL_USE_N_BUFFERS == 3
	if (wi_glob_id < wi_total / 3) {
4d26a735   Pedro Roque   Increased recogni...
307
		hist = backtrack1 + wi_glob_id * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
308
309

	} else if (wi_glob_id < wi_total * 2 / 3) {
4d26a735   Pedro Roque   Increased recogni...
310
		hist = backtrack2 + (wi_glob_id - (wi_total / 3)) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
311
312

	} else {
4d26a735   Pedro Roque   Increased recogni...
313
		hist = backtrack3 + (wi_glob_id - (wi_total * 2 / 3)) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
314
315
316
317
	}

#elif CL_USE_N_BUFFERS == 4
	if (wi_glob_id < wi_total / 4) {
4d26a735   Pedro Roque   Increased recogni...
318
		hist = backtrack1 + wi_glob_id * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
319
320

	} else if (wi_glob_id < wi_total * 2 / 4) {
4d26a735   Pedro Roque   Increased recogni...
321
		hist = backtrack2 + (wi_glob_id - (wi_total / 4)) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
322
323

	} else if (wi_glob_id < wi_total * 3 / 4) {
4d26a735   Pedro Roque   Increased recogni...
324
		hist = backtrack3 + (wi_glob_id - (wi_total * 2 / 4)) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
325
326

	} else {
4d26a735   Pedro Roque   Increased recogni...
327
		hist = backtrack4 + (wi_glob_id - (wi_total * 3 / 4)) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS;
0c8ce2b0   Pedro Roque   missing files
328
329
330
331
332
333
334
335
336
	}
#endif

	// domains (bitmap or interval only) of each variable per tree level
#if CL_WORK == CL_CNT
	unsigned int sols_count = 0;
	__global unsigned int* sols_fnd = atoms + 5 + CL_N_VS + wi_glob_id;	// solutions found counter
#elif CL_WORK == CL_ONE
	__global DOMAIN_* solution = domains;	// solution domains
4d26a735   Pedro Roque   Increased recogni...
337
	__global unsigned int* sol_fnd = atoms + 5 + CL_N_VS;	// solution found flag
0c8ce2b0   Pedro Roque   missing files
338
#elif CL_WORK == CL_OPT
4d26a735   Pedro Roque   Increased recogni...
339
340
341
	__global DOMAIN_ *solutions = domains;		// solutions domains
	__global unsigned int *sols_fnd = atoms + 5 + CL_N_VS;		// solution found flag
	__global unsigned int *val_to_opt_g = atoms + 6 + CL_N_VS;	// global value to optimize
0c8ce2b0   Pedro Roque   missing files
342
	unsigned int val_to_opt_found;	// local optimization value found on a solution
4d26a735   Pedro Roque   Increased recogni...
343
	unsigned int val_to_opt_new;	// local optimization value found on a solution to store atomically
0c8ce2b0   Pedro Roque   missing files
344
	unsigned int val_to_opt_tmp;	// to compare when updating global value to optimize
4d26a735   Pedro Roque   Increased recogni...
345
346
	bool val_to_opt_upd;			// to check if global value to optimize was updated
	unsigned int prev_tree_idx;		// first index of the previous backtracking history
0c8ce2b0   Pedro Roque   missing files
347
348
	bool changed;
#endif
4d26a735   Pedro Roque   Increased recogni...
349
350
	__global DOMAIN_ *hist_prev;	// previous level of the backtracking tree
	__global DOMAIN_ *hist_curr;	// current level of the backtracking tree
0c8ce2b0   Pedro Roque   missing files
351
352

#if USE_TTL == 1
4d26a735   Pedro Roque   Increased recogni...
353
354
	// when a time to live is used inside the kernel, this is the counter that will stop the kernel when it reaches a predefined value
	unsigned int ttl_ctr = 0;
0c8ce2b0   Pedro Roque   missing files
355
356
357
358
#endif

#if CL_N_SHARED_SS > 0
	bool get_shared;	// look for a shared search-space
4d26a735   Pedro Roque   Increased recogni...
359
	bool finished_block = false;	// if the block of search spaces is depleted
0c8ce2b0   Pedro Roque   missing files
360
361
362
363
364
365
#endif

	// print the CSP as received by the device
#if CL_PRINT_CSP
	if (wi_glob_id == 0) {
		print_CSP_device(vs, cs, cs_per_v_idx, vs_per_c_idx
4d26a735   Pedro Roque   Increased recogni...
366
#if CS_AT_LEAST == 1 || CS_AT_MOST == 1 || CS_AT_MOST_ONE == 1 || CS_EXACTLY == 1 || CS_INT_LIN_EQ == 1 || CS_INT_LIN_LE == 1 || CS_INT_LIN_NE == 1 || CS_INT_LIN_VAR == 1 || CS_ARRAY_INT_ELEMENT == 1  || CS_BOOL_LIN_EQ == 1 || CS_BOOL_LIN_LE == 1
0c8ce2b0   Pedro Roque   missing files
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
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
				, c_consts
#endif
#if CL_D_TYPE == CL_BITMAP
				, b_ds
#endif
		);
	} else {
		return;
	}
#endif

	// get a new store from the block of search-spaces
	get_new_str(atoms, vs, hist, vs_prop_, vs_id_to_prop_, &hist_tree_level, hist_labeleds_id, hist_labeleds_n_vals, &prop_v_id
#if CL_D_TYPE == CL_BITMAP
			, b_ds
#endif
#if (CS_MAXIMIZE == 1 || CS_MINIMIZE == 1) && CL_WORK == CL_OPT
			, val_to_opt_g
#endif
			, ss_aux_mem TTL_CTR_E);

#if CL_N_SHARED_SS > 0
	// if this work-item doesn't find a ss to explore, check shared ss
	if (prop_v_id == CL_N_VS && wi_total > 1) {
		get_shared = false;

		if (!finished_block) {
			atomic_dec(wis_working);
			finished_block = true;
		}

		if (atomic_add(&shared_ss_flags[0], 0) < CL_N_SHARED_SS && atomic_add(&shared_ss_flags[2], 0) == CL_N_SHARED_SS) {
			get_shared = true;
		} else if (finished_block && atomic_add(wis_working, 0) == 0) {
			get_shared = true;
		}

		if (get_shared) {
			get_shared_store(shared_ss, shared_ss_flags, vs_id_to_prop_, vs_prop_, hist, &hist_tree_level, hist_labeleds_id, hist_labeleds_n_vals, &prop_v_id TTL_CTR_E);
		}
	}
#endif
	if (prop_v_id != CL_N_VS) {
		labeled = true;

#if CL_STATS == 1
		if (hist_labeleds_n_vals[0] == 0) {
			(*labels)++;
			(*nodes_expl)++;
		}
#endif
		// while there are variables to explore
		for (j = 0; j < CL_N_VS; j++) {
			CHECK_TTL_V(ttl_ctr, 12)

#if CL_WORK == CL_ONE
			if (atomic_add(sol_fnd, 0) == 1) {
#if CL_N_DEVS > 1
				props[wi_glob_id] = props_count;
#endif
				return;
			}
#endif
			prop_ok = 1;

			// while there are variables to propagate and propagation succeed
			for (k = 0; k < CL_N_VS; k++) {
				CHECK_TTL_V(ttl_ctr, 13)

				// run the propagators
				propagate(vs, cs, cs_per_v_idx, vs_per_c_idx,
4d26a735   Pedro Roque   Increased recogni...
438
#if CS_AT_LEAST == 1 || CS_AT_MOST == 1 || CS_AT_MOST_ONE == 1 || CS_EXACTLY == 1 || CS_INT_LIN_EQ == 1 || CS_INT_LIN_LE == 1 || CS_INT_LIN_NE == 1 || CS_INT_LIN_VAR == 1 || CS_ARRAY_INT_ELEMENT == 1  || CS_BOOL_LIN_EQ == 1 || CS_BOOL_LIN_LE == 1
0c8ce2b0   Pedro Roque   missing files
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
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
						c_consts,
#endif
#if (CS_MAXIMIZE == 1 || CS_MINIMIZE == 1) && CL_WORK == CL_OPT
						val_to_opt_g,
#endif
#if CL_STATS == 1
						nodes_fail, nodes_expl, pruning, props_ok,
#endif
						vs_prop_, prop_v_id, vs_id_to_prop_ TTL_CTR_E
#if CL_N_DEVS > 1
						, &props_count
#endif
						CS_IGNORE_CALL, &prop_ok, terms_mem);

				k = 0;

				// reset the array of variables to propagate
				if (!prop_ok) {
					vs_id_to_prop_[0] = 2;
					vs_id_to_prop_[1] = 2;

					prop_v_id = CL_N_VS;
					k = CL_N_VS;

				} else {

					v_get_id_to_prop(vs_id_to_prop_, vs_prop_, &prop_v_id TTL_CTR_E);

					// reset the array of variables to propagate
					if (prop_v_id == CL_N_VS) {
						k = CL_N_VS;
					}
				}
			}

			j = 0;

#if CL_WORK == CL_ONE
			if (atomic_add(sol_fnd, 0) == 1) {
#if CL_N_DEVS > 1
				props[wi_glob_id] = props_count;
#endif
				return;
			}
#endif

			// If propagation ok, label next variable
			if (prop_ok) {

#if CL_FILTERING
				// no more variables to propagate without labeling, so the filtering is complete
				for (i = 0; i < CL_N_VS; i++) {
					CHECK_TTL_V(ttl_ctr, 15)
					cl_d_copy_gm(&filt_domains[i], &vs_prop_[i].prop_d TTL_CTR_E);
				}
#if CL_CS_IGNORE
				// send to host the constraints that may be ignored
				for (i = 0; i < CL_N_CS; i++) {
					filt_cs[i] = cs_ignore[i];
				}
				i = CL_N_VS;
#endif

				// to avoid unreachable code warning
				if (i == CL_N_VS) {
					return;
				}
#endif

#if CL_PRE_LABELING == 1
				if (revise == PROP_PRE_LABELING) {
					// update backtracking history
					hist_curr = &hist[GET_PREV_TREE_LEVEL_IDX(hist_tree_level)];

					for (i = 0; i < CL_N_VS; i++) {
						CHECK_TTL_V(ttl_ctr, 14)
4d26a735   Pedro Roque   Increased recogni...
515
								cl_d_copy_gm(&hist_curr[i], &vs_prop_[i].prop_d TTL_CTR_E);
0c8ce2b0   Pedro Roque   missing files
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
					}

					hist_labeleds_n_vals[hist_tree_level - 1] = V_N_VALS(vs_prop_[hist_labeleds_id[hist_tree_level - 1]]);

#if CL_CHECK_ERRORS
					if (hist_tree_level - 1 < 0) {
						printf((__constant char *)"\n###error 51\n");
					}
#endif

					labeled = false;
					revise = PRE_LABELED_OK;

				} else {
#endif

4d26a735   Pedro Roque   Increased recogni...
532
533
534
535
				// get next variable to label ID
#if CL_FZN_SEQ && CL_FZN_SEQ_N_LABELS > 1
				v_get_id_to_label(vs_prop_, vs, &prop_v_id, &last_label_h_idx, label_hs TTL_CTR_E);
#else
0c8ce2b0   Pedro Roque   missing files
536
					v_get_id_to_label(vs_prop_, vs, &prop_v_id TTL_CTR_E);
4d26a735   Pedro Roque   Increased recogni...
537
538
539
540
#endif

				// if a new variable to label was found do the labeling and remove the labeled value from the backtracking previous level
				if (prop_v_id != CL_N_VS) {
0c8ce2b0   Pedro Roque   missing files
541
#if CL_STATS == 1
4d26a735   Pedro Roque   Increased recogni...
542
543
					(*labels)++;
					(*nodes_expl)++;
0c8ce2b0   Pedro Roque   missing files
544
#endif
4d26a735   Pedro Roque   Increased recogni...
545
546
					// save backtracking history state
					hist_curr = &hist[GET_CURR_TREE_LEVEL_IDX(hist_tree_level)];
0c8ce2b0   Pedro Roque   missing files
547

4d26a735   Pedro Roque   Increased recogni...
548
					hist_labeleds_id[hist_tree_level] = prop_v_id;
0c8ce2b0   Pedro Roque   missing files
549

4d26a735   Pedro Roque   Increased recogni...
550
551
552
553
					for (i = 0; i < CL_N_VS; i++) {
						CHECK_TTL_V(ttl_ctr, 14)
						cl_d_copy_gm(&hist_curr[i], &vs_prop_[i].prop_d TTL_CTR_E);
					}
0c8ce2b0   Pedro Roque   missing files
554

4d26a735   Pedro Roque   Increased recogni...
555
556
557
558
559
560
					// assign a value to the variable, according to the selected heuristic
#if CL_FZN_SEQ && CL_FZN_SEQ_N_LABELS > 1
					v_assign(&vs_prop_[prop_v_id], &hist_curr[prop_v_id], &hist_labeleds_n_vals[hist_tree_level], &vs[prop_v_id]);
#else
						v_assign(&vs_prop_[prop_v_id], &hist_curr[prop_v_id], &hist_labeleds_n_vals[hist_tree_level]);
#endif
0c8ce2b0   Pedro Roque   missing files
561
562
563
564
565
566
567

#if CL_N_SHARED_SS > 0
						// set a new shared search-space
						if (atomic_add(&shared_ss_flags[1], 0) < CL_N_SHARED_SS && atomic_add(wis_working, 0) > 1 && wi_total > 1) {
							set_shared_store(shared_ss, shared_ss_flags, vs_prop_, prop_v_id, &hist_curr[prop_v_id], &hist_labeleds_n_vals[hist_tree_level] TTL_CTR_E);
						}
#endif
4d26a735   Pedro Roque   Increased recogni...
568
569
					// update current history level
					hist_tree_level++;
0c8ce2b0   Pedro Roque   missing files
570
571

#if CL_CHECK_ERRORS
4d26a735   Pedro Roque   Increased recogni...
572
						if (hist_tree_level > (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT) {
0c8ce2b0   Pedro Roque   missing files
573
574
575
576
577
							printf((__constant char *)"\n###error 55\n");
						}
#endif

#if CL_STATS == 1
4d26a735   Pedro Roque   Increased recogni...
578
579
580
					if (hist_tree_level > convert_int (*max_depth)) {
						*max_depth = hist_tree_level;
					}
0c8ce2b0   Pedro Roque   missing files
581
#endif
4d26a735   Pedro Roque   Increased recogni...
582
					labeled = true;
0c8ce2b0   Pedro Roque   missing files
583
584

#if CL_WORK == CL_OPT
4d26a735   Pedro Roque   Increased recogni...
585
					val_to_opt_tmp = convert_int (atomic_add(val_to_opt_g, 0));
0c8ce2b0   Pedro Roque   missing files
586
587

#if CL_OPT_M == CL_DECREASE
4d26a735   Pedro Roque   Increased recogni...
588
589
					// if optimal value is better then the last one
					if (val_to_opt_tmp < V_MAX(vs_prop_[CL_VAR_ID_TO_OPT]))
0c8ce2b0   Pedro Roque   missing files
590
#elif CL_OPT_M == CL_INCREASE
4d26a735   Pedro Roque   Increased recogni...
591
							if (val_to_opt_tmp > V_MIN(vs_prop_[CL_VAR_ID_TO_OPT]))
0c8ce2b0   Pedro Roque   missing files
592
#endif
4d26a735   Pedro Roque   Increased recogni...
593
					{
0c8ce2b0   Pedro Roque   missing files
594
#if CL_OPT_M == CL_DECREASE
4d26a735   Pedro Roque   Increased recogni...
595
						cl_v_del_gt_m(&changed, &vs_prop_[CL_VAR_ID_TO_OPT], val_to_opt_tmp);
0c8ce2b0   Pedro Roque   missing files
596
#elif CL_OPT_M == CL_INCREASE
4d26a735   Pedro Roque   Increased recogni...
597
								cl_v_del_lt_m(&changed, &vs_prop_[CL_VAR_ID_TO_OPT], val_to_opt_tmp);
0c8ce2b0   Pedro Roque   missing files
598
#endif
4d26a735   Pedro Roque   Increased recogni...
599
600
601
602
						if (changed) {
							if (V_N_VALS(vs_prop_[CL_VAR_ID_TO_OPT]) == 0) {
								labeled = false;
								prop_ok = 0;
0c8ce2b0   Pedro Roque   missing files
603

4d26a735   Pedro Roque   Increased recogni...
604
605
							} else {
								v_add_to_prop(vs_id_to_prop_, vs_prop_, CL_VAR_ID_TO_OPT);
0c8ce2b0   Pedro Roque   missing files
606
607
							}
						}
4d26a735   Pedro Roque   Increased recogni...
608
					}
0c8ce2b0   Pedro Roque   missing files
609
610
#endif

4d26a735   Pedro Roque   Increased recogni...
611
612
					// if there are no more variables to label, a solution was found
				} else {
0c8ce2b0   Pedro Roque   missing files
613
614
615
616
617
618

#if CL_WORK == CL_ONE
						if (atomic_cmpxchg(sol_fnd, 0, 1) == 0) {

							for (i = 0; i < CL_N_VS; i++) {
								CHECK_TTL_V(ttl_ctr, 15)
4d26a735   Pedro Roque   Increased recogni...
619
										cl_d_copy_gm(&solution[i], &vs_prop_[i].prop_d TTL_CTR_E);
0c8ce2b0   Pedro Roque   missing files
620
621
622
623
624
625
626
627
628
629
630
631
632
							}
						}
#if CL_STATS == 1
						(*nodes_expl)++;
#endif

#if CL_N_DEVS > 1
						props[wi_glob_id] = props_count;
#endif

#if PRINT_SOLS
						for (i = 0; i < CL_N_VS - 1; i++) {
							CHECK_TTL_V(ttl_ctr, 184)
4d26a735   Pedro Roque   Increased recogni...
633
									printf((__constant char *)"%u,", V_MIN(vs_prop_[i]));
0c8ce2b0   Pedro Roque   missing files
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
						}
						printf((__constant char *)"%u\n", V_MIN(vs_prop_[i]));
#endif
#if CL_VERIFY_SOLS
						for (i = 0; i < CL_N_VS; i++) {
							int n_vals;
							cl_d_cnt_vals_m(&vs_prop_[i].prop_d, &n_vals);
							if (V_N_VALS(vs_prop_[i]) != 1 || V_MIN(vs_prop_[i]) != V_MAX(vs_prop_[i]) || n_vals != 1) {
								printf((__constant char *)"ERROR: variable %d have more than one value in a solution (N_VALS=%d, min=%u, max=%u, n_vals=%d)\n",
										i, V_N_VALS(vs_prop_[i]), V_MIN(vs_prop_[i]), V_MAX(vs_prop_[i]), n_vals);
								return;
							}
						}
#endif
						return;
#elif CL_WORK == CL_CNT
						sols_count++;
						labeled = false;

#if PRINT_SOLS
						for (i = 0; i < CL_N_VS - 1; i++) {
							CHECK_TTL_V(ttl_ctr, 185)
4d26a735   Pedro Roque   Increased recogni...
656
									printf((__constant char *)"%u,", V_MIN(vs_prop_[i]));
0c8ce2b0   Pedro Roque   missing files
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
						}
						printf((__constant char *)"%u\n", V_MIN(vs_prop_[i]));
#endif
#if CL_VERIFY_SOLS
						for (i = 0; i < CL_N_VS; i++) {
							int n_vals;
							cl_d_cnt_vals_m(&vs_prop_[i].prop_d, &n_vals);
							if (V_N_VALS(vs_prop_[i]) != 1 || V_MIN(vs_prop_[i]) != V_MAX(vs_prop_[i]) || n_vals != 1) {
								printf((__constant char *)"ERROR: variable %d have more than one value in a solution (N_VALS=%d, min=%u, max=%u, n_vals=%d)\n",
										i, V_N_VALS(vs_prop_[i]), V_MIN(vs_prop_[i]), V_MAX(vs_prop_[i]), n_vals);
								return;
							}
						}
#endif

#if CL_STATS == 1
						(*nodes_expl)++;
#endif

#else	// if optimizing

#if PRINT_SOLS
#if CL_OPT_M == CL_DECREASE
						printf((__constant char *)"%u->", V_MAX(vs_prop_[CL_VAR_ID_TO_OPT]));
#elif CL_OPT_M == CL_INCREASE
						printf((__constant char *)"%u->", V_MIN(vs_prop_[CL_VAR_ID_TO_OPT]));
#endif
						for (i = 0; i < CL_N_VS - 1; i++) {
							CHECK_TTL_V(ttl_ctr, 186)
4d26a735   Pedro Roque   Increased recogni...
686
									printf((__constant char *)"%u,", V_MIN(vs_prop_[i]));
0c8ce2b0   Pedro Roque   missing files
687
688
689
690
691
692
693
694
695
696
						}
						printf((__constant char *)"%u\n", V_MIN(vs_prop_[i]));
#endif
#if CL_VERIFY_SOLS
						for (i = 0; i < CL_N_VS; i++) {
							int n_vals;
							cl_d_cnt_vals_m(&vs_prop_[i].prop_d, &n_vals);
							if (V_N_VALS(vs_prop_[i]) != 1 || V_MIN(vs_prop_[i]) != V_MAX(vs_prop_[i]) || n_vals != 1) {
								printf((__constant char *)"ERROR: variable %d have more than one value in a solution (N_VALS=%d, min=%u, max=%u, n_vals=%d)\n",
										i, V_N_VALS(vs_prop_[i]), V_MIN(vs_prop_[i]), V_MAX(vs_prop_[i]), n_vals);
4d26a735   Pedro Roque   Increased recogni...
697

0c8ce2b0   Pedro Roque   missing files
698
699
700
701
702
								return;
							}
						}
#endif

4d26a735   Pedro Roque   Increased recogni...
703
					val_to_opt_found = V_MIN(vs_prop_[CL_VAR_ID_TO_OPT]);
0c8ce2b0   Pedro Roque   missing files
704
705

#if CL_OPT_M == CL_DECREASE
4d26a735   Pedro Roque   Increased recogni...
706
					val_to_opt_new = val_to_opt_found - 1;
0c8ce2b0   Pedro Roque   missing files
707
#elif CL_OPT_M == CL_INCREASE
4d26a735   Pedro Roque   Increased recogni...
708
					val_to_opt_new = val_to_opt_found + 1;
0c8ce2b0   Pedro Roque   missing files
709
#endif
4d26a735   Pedro Roque   Increased recogni...
710
					val_to_opt_upd = 0;
0c8ce2b0   Pedro Roque   missing files
711

4d26a735   Pedro Roque   Increased recogni...
712
713
714
					// while new optimal value not updated, keep trying
					while (!val_to_opt_upd) {
						CHECK_TTL_V(ttl_ctr, 16)
0c8ce2b0   Pedro Roque   missing files
715

4d26a735   Pedro Roque   Increased recogni...
716
						val_to_opt_tmp = convert_int (atomic_add(val_to_opt_g, 0));
0c8ce2b0   Pedro Roque   missing files
717
#if CL_OPT_M == CL_DECREASE
4d26a735   Pedro Roque   Increased recogni...
718
719
						// if optimal value is better then the last one
						if (val_to_opt_found <= val_to_opt_tmp)
0c8ce2b0   Pedro Roque   missing files
720
#elif CL_OPT_M == CL_INCREASE
4d26a735   Pedro Roque   Increased recogni...
721
						if (val_to_opt_found >= val_to_opt_tmp)
0c8ce2b0   Pedro Roque   missing files
722
723
#endif
								{
4d26a735   Pedro Roque   Increased recogni...
724
725
							// update new optimal value and writes the solution
							if (atomic_cmpxchg(val_to_opt_g, val_to_opt_tmp, val_to_opt_new) == val_to_opt_tmp) {
0c8ce2b0   Pedro Roque   missing files
726

4d26a735   Pedro Roque   Increased recogni...
727
728
729
								for (i = 0; i < CL_N_VS; i++) {
									CHECK_TTL_V(ttl_ctr, 17)
									cl_d_copy_gm(&solutions[CL_N_VS * (val_to_opt_found) + i], &vs_prop_[i].prop_d TTL_CTR_E);
0c8ce2b0   Pedro Roque   missing files
730
								}
4d26a735   Pedro Roque   Increased recogni...
731
732
733
734
735
736
737

								val_to_opt_upd = 1;
							}
							atomic_xchg(sols_fnd, 1);

						} else {
							val_to_opt_upd = 1;
0c8ce2b0   Pedro Roque   missing files
738
						}
0c8ce2b0   Pedro Roque   missing files
739
					}
4d26a735   Pedro Roque   Increased recogni...
740
741
742
					labeled = false;
#endif
				}
0c8ce2b0   Pedro Roque   missing files
743
744
745
746
747
#if CL_PRE_LABELING == 1
				}
#endif
			}

4d26a735   Pedro Roque   Increased recogni...
748
			// If propagation not ok, or ok but was a solution, and all or the best solution must be found, do backtracking
0c8ce2b0   Pedro Roque   missing files
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
			if (!prop_ok || !labeled) {
#if CL_FILTERING
				// the filtering resulted in an inconsistent CSP
				cl_d_clear_g(filt_domains);
				// to avoid unreachable code warning
				bool empty_aux;
				cl_d_is_empty_g(&empty_aux, filt_domains);
				if (empty_aux) {
					return;
				}
#endif

#if CL_PRE_LABELING == 1
				if (revise == PROP_PRE_LABELING) {
					prop_v_id = hist_labeleds_id[hist_tree_level - 1];
					cl_d_clear_g(&hist[GET_PREV_TREE_LEVEL_IDX(hist_tree_level) + prop_v_id] TTL_CTR_E);

#if CL_CHECK_ERRORS
					if (hist_tree_level - 1 < 0) {
						printf((__constant char *)"\n###error 56\n");
					}
#endif

#if CL_CHECK_ERRORS
#if CL_WORK == CL_CNT
4d26a735   Pedro Roque   Increased recogni...
774
					if (GET_PREV_TREE_LEVEL_IDX(hist_tree_level) > (wi_glob_id + 1) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS) {
0c8ce2b0   Pedro Roque   missing files
775
776
777
						printf((__constant char *)"\n###error 57\n");
					}
#elif CL_WORK == CL_ONE
4d26a735   Pedro Roque   Increased recogni...
778
					if (GET_PREV_TREE_LEVEL_IDX(hist_tree_level) > CL_N_VS + (wi_glob_id + 1) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT
0c8ce2b0   Pedro Roque   missing files
779
780
781
782
							* CL_N_VS) {
						printf((__constant char *)"\n###error 58\n");
					}
#else
4d26a735   Pedro Roque   Increased recogni...
783
					if (GET_PREV_TREE_LEVEL_IDX(hist_tree_level) > CL_N_VS * (CL_D_MAX + 1) + (wi_glob_id + 1) * (CL_N_VS_TO_LABEL + 2) *
0c8ce2b0   Pedro Roque   missing files
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
							CL_SPLIT_VALUES_EXT * CL_N_VS) {
						printf((__constant char *)"\n###error 59\n");
					}
#endif
#endif

					hist_labeleds_n_vals[hist_tree_level - 1] = 0;
					revise = PRE_LABELED_NOK;
				}
#endif

#if CL_WORK == CL_OPT
				bool empty;

				// get a labeled variable from the backtracking levels with values yet to be assigned
				for (k = 0; k < CL_N_VS; k++) {
					CHECK_TTL_V(ttl_ctr, 18)

					if (hist_tree_level > 0) {
						if (hist_labeleds_n_vals[hist_tree_level - 1] == 0) {
							hist_tree_level--;
						} else {
							prev_tree_idx = GET_PREV_TREE_LEVEL_IDX(hist_tree_level);

#if CL_CHECK_ERRORS
4d26a735   Pedro Roque   Increased recogni...
809
810
811
812
									if (prev_tree_idx + CL_VAR_ID_TO_OPT > CL_N_VS * (CL_D_MAX + 1) + (wi_glob_id + 1) * (CL_N_VS_TO_LABEL + 2)
											* CL_SPLIT_VALUES_EXT * CL_N_VS) {
										printf((__constant char *)"\n###error 60\n");
									}
0c8ce2b0   Pedro Roque   missing files
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
#endif
							// update the domain of the variable to optimize
							upd_opt_var_hist_g(&hist[prev_tree_idx + CL_VAR_ID_TO_OPT], val_to_opt_g TTL_CTR_E);
							cl_d_is_empty_g(&empty, &hist[prev_tree_idx + CL_VAR_ID_TO_OPT] TTL_CTR_E);

							if (empty) {
								hist_tree_level--;

							} else {
								k = CL_N_VS;
							}
						}

					} else {
						k = CL_N_VS;
					}
				}
#else
				// get a labeled variable from the backtracking levels with values yet to be assigned
				for (k = 0; k < CL_N_VS; k++) {
					CHECK_TTL_V(ttl_ctr, 19)

4d26a735   Pedro Roque   Increased recogni...
835
836
837
838
839
							if (hist_tree_level > 0 && hist_labeleds_n_vals[hist_tree_level - 1] == 0) {
								hist_tree_level--;
							} else {
								k = CL_N_VS;
							}
0c8ce2b0   Pedro Roque   missing files
840
841
842
843
844
845
846
847
848
849
				}

#endif
				// If not all the sub-tree was explored
				if (hist_tree_level > 0) {

					hist_prev = &hist[GET_PREV_TREE_LEVEL_IDX(hist_tree_level)];

#if CL_CHECK_ERRORS
#if CL_WORK == CL_CNT
4d26a735   Pedro Roque   Increased recogni...
850
					if (GET_PREV_TREE_LEVEL_IDX(hist_tree_level) > (wi_glob_id + 1) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT * CL_N_VS) {
0c8ce2b0   Pedro Roque   missing files
851
852
853
						printf((__constant char *)"\n###error 61\n");
					}
#elif CL_WORK == CL_ONE
4d26a735   Pedro Roque   Increased recogni...
854
					if (GET_PREV_TREE_LEVEL_IDX(hist_tree_level) > CL_N_VS + (wi_glob_id + 1) * (CL_N_VS_TO_LABEL + 2) * CL_SPLIT_VALUES_EXT
0c8ce2b0   Pedro Roque   missing files
855
856
857
858
							* CL_N_VS) {
						printf((__constant char *)"\n###error 62\n");
					}
#else
4d26a735   Pedro Roque   Increased recogni...
859
					if (GET_PREV_TREE_LEVEL_IDX(hist_tree_level) > CL_N_VS * (CL_D_MAX + 1) + (wi_glob_id + 1) * (CL_N_VS_TO_LABEL + 2) *
0c8ce2b0   Pedro Roque   missing files
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
							CL_SPLIT_VALUES_EXT * CL_N_VS) {
						printf((__constant char *)"\n###error 63\n");
					}
#endif
#endif
					// update current variables data
					for (i = 0; i < CL_N_VS; i++) {
						CHECK_TTL_V(ttl_ctr, 20)
						cl_d_copy_mg(&vs_prop_[i].prop_d, &hist_prev[i] TTL_CTR_E);
						vs_prop_[i].to_prop = 0;

						cl_v_calc_min_val_m(&vs_prop_[i] TTL_CTR_E);
						cl_v_calc_max_val_m(&vs_prop_[i] TTL_CTR_E);
						cl_v_cnt_vals_m(&vs_prop_[i] TTL_CTR_E);
					}

					prop_v_id = hist_labeleds_id[hist_tree_level - 1];

4d26a735   Pedro Roque   Increased recogni...
878
879
880
881
882
883
884
885
886
887
#if CL_FZN_SEQ && CL_FZN_SEQ_N_LABELS > 1
					for (i = last_label_h_idx; i >= 0; i--) {

						if (vs[prop_v_id].label_h == label_hs[i]) {
							last_label_h_idx = i;
							break;
						}
					}
#endif

0c8ce2b0   Pedro Roque   missing files
888
889
890
891
892
893
894
895
896
897
898
899
#if CL_CHECK_ERRORS
					if (hist_tree_level - 1 < 0) {
						printf((__constant char *)"\n###error 64\n");
					}
#if CL_WORK == CL_OPT
					if (V_IS_EMPTY(vs_prop_[CL_VAR_ID_TO_OPT])) {
						printf((__constant char *)"\n###error 69\n");
					}
#endif
#endif

#if CL_WORK == CL_OPT
4d26a735   Pedro Roque   Increased recogni...
900
					val_to_opt_tmp = convert_int (atomic_add(val_to_opt_g, 0));
0c8ce2b0   Pedro Roque   missing files
901
902
903
904
905
#if CL_OPT_M == CL_DECREASE
					// if optimal value is better then the last one
					if (val_to_opt_tmp < V_MAX(vs_prop_[CL_VAR_ID_TO_OPT]))

#elif CL_OPT_M == CL_INCREASE
4d26a735   Pedro Roque   Increased recogni...
906
						if (val_to_opt_tmp > V_MIN(vs_prop_[CL_VAR_ID_TO_OPT]))
0c8ce2b0   Pedro Roque   missing files
907
908
909
910
911
912
913
914
915
916
917
#endif

					{
						v_add_to_prop(vs_id_to_prop_, vs_prop_, CL_VAR_ID_TO_OPT);
					}
#endif

#if CL_PRE_LABELING == 1
					if (revise == PRE_LABELED_OK || revise == PRE_LABELED_NOK || hist_labeleds_n_vals[hist_tree_level - 1] == 1) {
						revise = PROP_NORMALLY;
#endif
4d26a735   Pedro Roque   Increased recogni...
918
919
920
921
922
923
924

					// assign a value to the variable according to the selected heuristic
#if CL_FZN_SEQ && CL_FZN_SEQ_N_LABELS > 1
					v_assign(&vs_prop_[prop_v_id], &hist_prev[prop_v_id], &hist_labeleds_n_vals[hist_tree_level - 1], &vs[prop_v_id]);
#else
						v_assign(&vs_prop_[prop_v_id], &hist_prev[prop_v_id], &hist_labeleds_n_vals[hist_tree_level - 1]);
#endif
0c8ce2b0   Pedro Roque   missing files
925
926

#if CL_STATS == 1
4d26a735   Pedro Roque   Increased recogni...
927
					(*backtracks)++;
0c8ce2b0   Pedro Roque   missing files
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
#endif

#if CL_PRE_LABELING == 1
					} else {
						revise = PROP_PRE_LABELING;
					}
#endif

#if CL_STATS == 1
					if (V_N_VALS(vs_prop_[prop_v_id]) > 0) {
						(*labels)++;
						(*nodes_expl)++;
					}
#endif
					labeled = true;

#if CL_CS_IGNORE
					clear_cs_ignore(cs_ignore);
#endif

#if CL_CHECK_ERRORS
					int l;
					for (l = 0; l < CL_N_VS; l++) {

						bool empty;
#if CL_N_WORDS == 1
						empty = (vs_prop_[l].prop_d == 0);
#else
						int m;
						empty = 1;
						for (m = 0; m < CL_N_WORDS; m++) {
							CHECK_TTL(ttl_ctr, 115)
4d26a735   Pedro Roque   Increased recogni...
960
961
962
963
									if (vs_prop_[l].prop_d[m] != 0) {
										empty = 0;
										m = CL_N_WORDS;
									}
0c8ce2b0   Pedro Roque   missing files
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
						}
#endif
						if (empty || vs_prop_[l].n_vals == 0 || vs_prop_[l].n_vals > vs_prop_[l].max + 1 || vs_prop_[l].min > vs_prop_[l].max || vs_prop_[l].max > CL_D_MAX) {
							printf((__constant char *)"\n###error 72\n");
						}
					}
#endif

				} else {
					labeled = false;
				}
			}

			// try to get a new search space to explore
			if (!labeled) {

#if CL_CS_IGNORE
				clear_cs_ignore(cs_ignore);
#endif

4d26a735   Pedro Roque   Increased recogni...
984
985
986
#if CL_FZN_SEQ && CL_FZN_SEQ_N_LABELS > 1
				last_label_h_idx = 0;
#endif
0c8ce2b0   Pedro Roque   missing files
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
				get_new_str(atoms, vs, hist, vs_prop_, vs_id_to_prop_, &hist_tree_level, hist_labeleds_id, hist_labeleds_n_vals, &prop_v_id
#if CL_D_TYPE == CL_BITMAP
						, b_ds
#endif
#if (CS_MAXIMIZE == 1 || CS_MINIMIZE == 1) && CL_WORK == CL_OPT
						, val_to_opt_g
#endif
						, ss_aux_mem TTL_CTR_E);

#if CL_N_SHARED_SS > 0
				// if this work-item doesn't find a ss to explore, check shared ss
				if (atomic_add(&shared_ss_flags[0], 0) < CL_N_SHARED_SS && atomic_add(&shared_ss_flags[2], 0) == CL_N_SHARED_SS) {

					get_shared = false;

					if (!finished_block) {
						atomic_dec(wis_working);
						finished_block = true;
					}

					if (atomic_add(&shared_ss_flags[0], 0) <= atomic_add(&shared_ss_flags[2], 0)) {
						get_shared = true;
					} else if (finished_block && atomic_add(wis_working, 0) == 0) {
						get_shared = true;
					}

					if (get_shared) {
						get_shared_store(shared_ss, shared_ss_flags, vs_id_to_prop_, vs_prop_, hist, &hist_tree_level, hist_labeleds_id, hist_labeleds_n_vals,
								&prop_v_id TTL_CTR_E);
					}
				}
#endif
			}

			if (prop_v_id == CL_N_VS) {
				labeled = false;
				j = CL_N_VS;
			} else {
				labeled = true;

#if CL_CHECK_ERRORS
				int l;
				for (l = 0; l < CL_N_VS; l++) {

					bool empty;
#if CL_N_WORDS == 1
					empty = (vs_prop_[l].prop_d == 0);
#else
					int m;
					empty = 1;
					for (m = 0; m < CL_N_WORDS; m++) {
						CHECK_TTL(ttl_ctr, 115)
4d26a735   Pedro Roque   Increased recogni...
1039
1040
1041
1042
								if (vs_prop_[l].prop_d[m] != 0) {
									empty = 0;
									m = CL_N_WORDS;
								}
0c8ce2b0   Pedro Roque   missing files
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
					}
#endif
					if (empty || vs_prop_[l].n_vals > vs_prop_[l].max + 1 || vs_prop_[l].min > vs_prop_[l].max || vs_prop_[l].max > CL_D_MAX) {
						printf((__constant char *)"\n###error 73\n");
					}
				}
#endif
			}

#if CL_STATS == 1
			if (hist_labeleds_n_vals[0] == 0) {
				(*labels)++;
				(*nodes_expl)++;
			}
#endif
		}
	}

#if CL_WORK == CL_CNT
	(*sols_fnd) = sols_count;
#endif

#if CL_N_DEVS > 1
	// to calculate this device performance for work-dsitribution between devices
	props[wi_glob_id] = props_count;
#endif

	// if optimization and this is the last work-item running, update the optimal cost to the buffer
#if CL_WORK == CL_OPT
	if (atomic_dec(wis_working_opt) == 1 && atomic_add(sols_fnd, 0) >= 1) {

#if CL_OPT_M == CL_DECREASE
		val_to_opt_found = atomic_add(val_to_opt_g, 0) + 1;
#elif CL_OPT_M == CL_INCREASE
		val_to_opt_found = atomic_add(val_to_opt_g, 0) - 1;
#endif

		for (i = 0; i < CL_N_VS; i++) {
			CHECK_TTL_V(ttl_ctr, 250)
			cl_d_copy_g(&solutions[i], &solutions[CL_N_VS * (val_to_opt_found) + i] TTL_CTR_E);
		}
	}
#endif
}