]> AND Private Git Repository - snake_gpu.git/blob - src/lib_gpu.cu~
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
added rectangle generation for initialization
[snake_gpu.git] / src / lib_gpu.cu~
1
2 #include <stdio.h>
3
4
5 extern "C"{
6 #include "structures.h"
7 #include "lib_math.h"
8 #include "defines.h"
9 #include "lib_gpu.h"
10 #include "lib_snake_2_gpu.h"
11 }
12 #include "lib_test_gpu.h"
13 #include "lib_kernels_cumuls.cu"
14 #include "lib_kernel_snake_2_gpu.cu"
15
16 #define DEBUG_IMG_CUMUL 1
17 bool DISPLAY_ERR_IMG_CUMUL = 1;
18 //#define DEBUG_POSITIONS
19 //#define DEBUG_MOVE
20 //#define DEBUG_CRST
21 //#define DEBUG_MV
22 //#define DEBUG_SOMSOM
23 //#define DEBUG_SOMBLOCS
24 //#define DEBUG_LISTES
25 //#define DEBUG_STATS_REF
26
27
28 inline unsigned int nextPow2( unsigned int x ) {
29   --x;
30   x |= x >> 1;
31   x |= x >> 2;
32   x |= x >> 4;
33   x |= x >> 8;
34   x |= x >> 16;
35   return ++x;
36 }
37
38
39 void cuda_init_img_cumul(unsigned short ** img_in, int H, int L, int nb_nodes,
40                                                  unsigned short ** d_img, t_cumul_x ** d_img_x, t_cumul_x2 ** d_img_x2,
41                                                  int ** d_freemanDiDj, int ** d_codeNoeud,
42                                                  snake_node_gpu ** d_snake, uint32 ** d_nb_pix_max,
43                                                  uint4 ** d_positions, uint64 ** d_contribs_segments, uint4 ** d_freemans_centres,
44                                                  int ** d_codes_segments, int64 ** d_stats_snake,
45                                                  int64 ** d_stats, int64 ** d_stats_ref, double ** d_vrais, double ** d_vrais_snake,
46                                                  uint2 ** d_liste_pixels, uint64 ** d_contribs_segments_blocs,
47                                                  bool ** d_move
48                                                  )
49 {
50   unsigned int taille = H*L;
51   timeval chrono;
52
53   
54   //allocation cumuls en memoire GPU
55   tic(&chrono, NULL);
56   /*
57         MAX_PIX 20000
58         MAX_NODES 10000
59         MAX_LISTE_PIX 10000000
60    */
61   cudaMalloc( (void**) d_snake, MAX_NODES*sizeof(snake_node_gpu) );
62   
63   cudaMalloc( (void**) d_img, taille*sizeof(unsigned short) );
64   cudaMalloc( (void**) d_img_x, taille*sizeof(t_cumul_x) );
65   cudaMalloc( (void**) d_img_x2, taille*sizeof(t_cumul_x2) );
66  
67   cudaMalloc( (void**) d_freemanDiDj, 9*sizeof(int) );
68   cudaMalloc( (void**) d_codeNoeud, 64*sizeof(int) );
69   
70   cudaMalloc( (void**) d_stats_snake, 6*sizeof(int64)) ;
71   cudaMalloc( (void**) d_positions, 8*MAX_NODES*sizeof(uint4)) ;
72   cudaMalloc( (void**) d_contribs_segments, 3*16*MAX_NODES*sizeof(uint64)) ;
73   cudaMalloc( (void**) d_contribs_segments_blocs, (3*MAX_LISTE_PIX/32)*sizeof(uint64)) ;
74   cudaMalloc( (void**) d_freemans_centres, 16*MAX_NODES*sizeof(uint4)) ;
75   cudaMalloc( (void**) d_codes_segments, 16*MAX_NODES*sizeof(int)) ;
76   cudaMalloc( (void**) d_stats, 3*8*MAX_NODES*sizeof(int64)) ;
77   cudaMalloc( (void**) d_stats_ref, 3*MAX_NODES*sizeof(int64)) ;
78   cudaMalloc( (void**) d_vrais, 8*MAX_NODES*sizeof(double)) ;
79   cudaMalloc( (void**) d_move, MAX_NODES*sizeof(bool)) ;
80   cudaMalloc( (void**) d_nb_pix_max, sizeof(uint32)) ;
81   cudaMalloc( (void**) d_vrais_snake, sizeof(double)) ;
82   
83   cudaMalloc( (void**) d_liste_pixels, 16*5*(MAX_NODES)*sizeof(uint2) );
84   
85   printf("TOTAL MEM = %ld octets\n",
86                  (2*MAX_NODES*(sizeof(snake_node_gpu)+(8+16)*sizeof(uint4)+3*16*8+16*4+24*8+3*8+8*sizeof(double)+sizeof(bool))
87                  +(MAX_LISTE_PIX)*(sizeof(uint2)+1)
88                  +taille*(8+sizeof(t_cumul_x)+sizeof(t_cumul_x2))
89                   +9*4+64*4+6*8+4+sizeof(double)) );
90             
91   int64 * h_stats_snake = new int64[6];
92   
93   toc(chrono, "temps alloc mem GPU");
94
95   /*detection-choix-initialisation de la carte GPU*/
96   tic(&chrono, NULL) ;
97   cudaDeviceProp deviceProp;
98   deviceProp.major = 1;
99   deviceProp.minor = 0;
100   int desiredMinorRevision = 3;
101   int dev;
102   cudaChooseDevice(&dev, &deviceProp);
103   cudaGetDeviceProperties(&deviceProp, dev);
104   if(deviceProp.major > 1 || deviceProp.minor >= desiredMinorRevision)
105         {
106           printf("Using Device %d: \"%s\"\n", dev, deviceProp.name);
107           cudaSetDevice(dev);
108         }
109   toc(chrono, "temps acces GPU") ;
110   
111   //copie tables correspondances freeman en mem GPU
112   tic(&chrono, NULL) ;
113   cudaMemcpy( *d_freemanDiDj, CORRESPONDANCE_Di_Dj_FREEMAN , 9*sizeof(int), cudaMemcpyHostToDevice);
114   cudaMemcpy( *d_codeNoeud, TABLE_CODAGE , 64*sizeof(unsigned int), cudaMemcpyHostToDevice);
115   toc(chrono, "temps transfert tables de codage") ;
116   
117   /*transfert image en global mem GPU*/
118   tic(&chrono, NULL);
119   cudaMemcpy( *d_img, img_in[0], taille*sizeof(unsigned short), cudaMemcpyHostToDevice);
120   toc(chrono, "transfert image vers GPU");
121
122   //calculs images cumulees sur GPU
123   int blocs_max = 65536 ;
124   int bs = 256 ; //arbitraire, d'apres les observations c'est souvent l'optimu
125   unsigned int base = 0 ;
126   unsigned int bl_l  = (L+bs-1)/bs ;
127   unsigned int nb_lines =  blocs_max / bl_l ;
128   unsigned int lines ;
129   unsigned int tranches = ( 1 + H / nb_lines ) ;
130   nb_lines = (H +tranches -1)/ tranches ; // equilibre la taille des tranches
131   unsigned blocs = bl_l*nb_lines ;
132   dim3 threads(bs,1,1);
133   int smem = nextPow2(bl_l)*2; //smem pour le prefixscan des sommes de blocs (etape 2)
134   smem += smem >> DEC;
135   smem += smem >> DEC;
136   int smem_size = smem*sizeof(uint64);
137   uint64 * d_somblocs ; // sommes des cumuls par bloc de calcul
138   
139
140   if(DEBUG_IMG_CUMUL)
141         {
142           printf("--- CALCULS IMAGES CUMULEES+STATS GPU  ----\n");
143           printf("\t%d threads par bloc  -- %u blocs par ligne -- %u tranches -- %u lignes par tranche \n",bs, bl_l, tranches,nb_lines);
144           printf(" Smem totale pour cumuls : %d\n", CFI(bs)*(sizeof(t_cumul_x)+sizeof(t_cumul_x2)) );
145           tic(&chrono, NULL);
146         }
147   //calculs cumuls generiques : necessitent 3 etapes / 3 kernels  
148   cudaMalloc( (void**) &d_somblocs, 2*bl_l*nb_lines*sizeof(uint64) );
149   cudaFuncSetCacheConfig(calcul_cumuls_gpu, cudaFuncCachePreferShared);
150   do
151         {
152           if  ( H-base < nb_lines ) lines = H - base ; else lines = nb_lines ;
153           printf("base = ligne %d -- traitement de %d lignes \n", base, lines) ;
154           dim3 grid(bl_l*lines,1,1) ;
155           calcul_cumuls_gpu<<<grid, threads, CFI(bs)*sizeof(tcumuls)>>>(*d_img, *d_img_x, *d_img_x2, H, L, d_somblocs, bl_l, base, lines) ;
156           scan_somblocs<<<2*lines, nextPow2(bl_l)/2, smem_size>>>(d_somblocs, bl_l) ;
157           add_soms_to_cumuls<<<grid, threads>>>(*d_img_x, *d_img_x2, H, L, d_somblocs, bl_l, base, lines) ;
158           base += lines ;
159         }
160   while (base < H) ;
161   cudaFree(d_somblocs) ;
162   
163   //calcul des sommes totales N, sigX et sigX2 sur l'image
164   calcul_stats_image<<<1, 1>>>( *d_img_x, *d_img_x2, H, L, (uint64*)*d_stats_snake);
165   
166   
167           cudaThreadSynchronize()   ;
168           toc(chrono, "\tTemps GPU");
169          if(DEBUG_IMG_CUMUL)
170         { 
171           
172           //allocation memoire CPU
173           t_cumul_x  * img_x = new t_cumul_x [H*L];
174           t_cumul_x2 *  img_x2 = new t_cumul_x2 [H*L];
175           
176           /*pour test comparaison*/
177           t_cumul_x * img_xb = new t_cumul_x [H*L];
178           t_cumul_x2 * img_x2b = new t_cumul_x2 [H*L];
179           
180           cudaMemcpy( img_xb, *d_img_x, taille*sizeof(t_cumul_x), cudaMemcpyDeviceToHost);
181           cudaMemcpy( img_x2b, *d_img_x2, taille*sizeof(t_cumul_x2), cudaMemcpyDeviceToHost);
182           
183           //cumuls : etape 1 CPU
184           /*      
185                 for (int i=0; i<H; i++)
186                 {
187                         for (int b=0; b<bl_l; b++)
188                         {
189                                 int offset = b*bs ;
190                                 img_x[i*L+offset] = img_in[i][offset] ;
191                                 img_x2[i*L+offset]= img_in[i][offset]*img_in[i][offset] ;
192                                 for (int p=1; p<bs; p++)
193                                 {
194                                         int j = p+offset ;
195                                         if (j<L)
196                                         {
197                                                 img_x[i*L+j] = img_x[i*L+j-1] + img_in[i][j];
198                                                 img_x2[i*L+j] = img_x2[i*L+j-1] + img_in[i][j]*img_in[i][j] ;
199                                         }
200                                 }
201                         }
202                 }
203           */
204           //cumuls complets CPU
205           
206           for (int i=0; i<H; i++)
207                 {
208                   img_x[i*L+0] = img_in[i][0] ;
209                   img_x2[i*L+0]= img_in[i][0]*img_in[i][0] ;
210                   for (int j=1; j<L; j++)
211                         {
212                           img_x[i*L+j]  = img_x[i*L+j-1]  + img_in[i][j] ;
213                           img_x2[i*L+j] = img_x2[i*L+j-1] + img_in[i][j]*img_in[i][j] ;
214                         }
215                 }
216           
217           int cpt = 0;
218           int cpt_err1=0, cpt_errx=0, cpt_errx2 = 0;
219           for (int i=0; i< H; i++){
220                 for (int j=0; j< L; j++){
221                   if ( (img_x[i*L+j] !=  img_xb[i*L+j]) ) cpt_errx++ ;
222                   if ( (img_x2[i*L+j] !=  img_x2b[i*L+j]) ) cpt_errx2++ ;
223                   if ( (img_x[i*L+j] !=  img_xb[i*L+j]) || (img_x2[i*L+j] !=  img_x2b[i*L+j]))
224                   {
225                         //printf("(%d,%d)sxCPU=%lu  sxGPU=%lu -- sx2CPU=%lu  sx2GPU=%lu\n",i,j,img_x[i*L+j], img_xb[i*L+j], img_x2[i*L+j], img_x2b[i*L+j]);
226                   }
227                   cpt++;
228                 }
229           }
230           printf("%d erreurs sur CX / %d points\n", cpt_errx, cpt );
231           printf("%d erreurs sur CX2 / %d points\n", cpt_errx2, cpt );
232           uint64 sigX = 0, sigX2 = 0 ;
233           for (int i=0; i<H; i++)
234                 {
235                   sigX += img_x[i*L+L-1] ;
236                   sigX2+= img_x2[i*L+L-1];
237                 }
238           printf("STATS IMAGE  N = %d - sigX = %lu - sigX2 = %lu\n",  H*L, sigX, sigX2 );
239         }
240   
241   /*
242    * generation snake en mem GPU
243    */
244   int dist = 140 ;
245   
246   tic(&chrono, NULL);
247   if (nb_nodes == 4)  genere_snake_rectangle_4nodes_gpu<<< 1, 1>>>(*d_snake, 140, H, L) ;
248   else if (nb_nodes == 40) genere_snake_rectangle_Nnodes_gpu<<< 1, 1>>>(*d_snake, (H+L)/20, H, L) ;
249
250   int nnodes = nb_nodes ;
251   snake_node_gpu * h_snake = new snake_node_gpu[nnodes];
252   snake_node * h_snake_ll = new snake_node[nnodes] ;
253   uint4 * h_liste_positions = new uint4[nnodes*8]; 
254   double * h_vrais_snake = new double ;
255   //init les stats du snake
256   uint2 * d_liste_temp  ;
257   t_sum_x2 * d_sompart  ;
258   int tpb, bps, npixmax ;
259  
260   //calcul nb threads par bloc
261   npixmax = 2*(H+L-4*dist)/(nnodes-1) ;
262   tpb = nextPow2(npixmax) ;
263   if (tpb >= 256) tpb = 256 ;//  /!\ le kernel <<< calcul_contrib...>>> ne supporte pas un bs>256 a cause de la shared-mem nécessaire
264   if (tpb < 32 ) tpb = 32 ;
265   tpb=128 ; 
266   bps = (npixmax+tpb-1)/tpb ;
267   printf("PARAMS EXEC INIT : %d pix max, %d threads/bloc, %d blocs/seg, %d blocs/grille\n", npixmax, tpb, bps, nnodes*bps);
268  
269   //alloc
270   cudaMalloc((void**) &d_liste_temp, nnodes*bps*tpb*sizeof(uint2));
271   cudaMalloc((void**) &d_sompart, 3*nnodes*bps*sizeof(t_sum_x2));
272   cudaMalloc((void**) &d_stats_ref, 3*nnodes*sizeof(int64));
273
274   //DEBUG : pour forcer la mise à zero du tableau intermediaire d_stats_ref
275   int64 h_stats_ref[3*nnodes] ;
276   for (int a=0; a<3*nnodes ; a++) h_stats_ref[a] = 0 ;
277   cudaMemcpy( h_stats_ref, d_stats_ref, sizeof(int64), cudaMemcpyHostToDevice) ;
278   //fin forçage a 0
279   
280   //DEBUG : pour forcer la mise à zero du tableau intermediaire d_sompart
281      t_sum_x2 h_sompart[ 3*nnodes*bps ] ;
282      for (int a=0; a<3*nnodes*bps ; a++) h_sompart[a] = 0 ;
283      cudaMemcpy( h_sompart, d_sompart, sizeof(t_sum_x2), cudaMemcpyHostToDevice) ;
284   //fin forçage a 0
285   
286   calcul_contribs_segments_snake<<< nnodes*bps, tpb, (CFI(tpb))*(3*sizeof(t_sum_x2))>>>
287         (*d_snake, nnodes, 
288          *d_img_x, *d_img_x2, 
289          L, d_liste_temp, d_sompart, *d_freemanDiDj );
290
291   //TODO
292   //parametrer pour ne pas appeler qd tpb=1
293   //oblige a modifier le kernel <<< calcul_contrib...>>> pour ecrire directement ds d_snake
294   // au lieu de d_sompart
295   somsom_snake<<< nnodes , 1 >>>(d_sompart, nnodes, bps, *d_snake);
296   
297   
298   calcul_stats_snake<<< 1 , 1 >>>(*d_snake, nnodes, *d_stats_snake, *d_vrais_snake,
299                                                                   *d_img_x, *d_img_x2,
300                                                                   *d_codeNoeud, L
301                                                                   );
302   cudaThreadSynchronize() ;
303   toc(chrono, "\tTemps") ;
304   
305   /*
306         verif stats initiales du snake
307   */
308   cudaMemcpy( h_vrais_snake, *d_vrais_snake, sizeof(double), cudaMemcpyDeviceToHost) ;  
309   cudaMemcpy( h_stats_snake, *d_stats_snake, 6*sizeof(int64), cudaMemcpyDeviceToHost) ;
310   
311   printf("STATS SNAKE log vrais=%lf : c1=%lu - cx=%lu - cx2=%lu - N=%lu - SUMX=%lu - SUMX2=%lu\n",
312                  *h_vrais_snake,
313                  h_stats_snake[0],  h_stats_snake[1],  h_stats_snake[2],
314                  h_stats_snake[3],  h_stats_snake[4],  h_stats_snake[5] );
315   
316   /*
317         verif stats diminuees des contribs des 2 segments associes a chaque noeud
318   */  
319 #ifdef DEBUG_STATS_REF
320   cudaMemcpy( h_stats_ref, d_stats_ref, 3*nnodes*sizeof(int64), cudaMemcpyDeviceToHost) ;
321   cudaMemcpy( h_snake, *d_snake, nnodes*sizeof(snake_node_gpu), cudaMemcpyDeviceToHost) ;
322   
323         
324   printf("******* STATS DIMINUEES\n");
325   for(int n=0; n<nnodes;n++)
326         {
327           int i = h_snake[n].posi, j = h_snake[n].posj ;
328           printf("node %d (%d,%d) : %ld - %ld - %ld - img1= %lu - imgx= %lu - imgx2= %lu \n", n, i, j,
329                          h_stats_ref[3*n], h_stats_ref[3*n +1], h_stats_ref[3*n +2],
330                          img_1[i][j], img_x[i][j], img_x2[i][j]);
331         }
332 #endif //DEBUG_STATS_REF
333   
334   //snake2gpu(d_snake, snake, nb_nodes);
335   //gpu2snake(*d_snake, &h_snake_ll, nnodes);
336
337  
338 #ifdef DEBUG_POSITIONS
339   for (int n=0; n<nnodes; n++)
340         {
341           printf("Node %d :\n", n);
342           for (int pos=0; pos<8; pos++)
343                 {
344                   printf("(%d , %d):%d:%d | ", h_liste_positions[8*n + pos].x, h_liste_positions[8*n + pos].y,
345                                  h_liste_positions[8*n + pos].z, h_liste_positions[8*n + pos].w);
346                 }
347           printf("\n");
348         }
349 #endif //DEBUG_POSITIONS
350
351 //verif liste pixels noeuds pairs/impairs selon
352
353 #ifdef DEBUG_LISTES
354   printf("NOMBRE PIXELS pour LISTE = %d\n", *h_nb_pix_max) ;
355   printf("bs = %d - grid = %d - nblocs_seg = %d - npix_max = %d - taille mem = %d\n",
356                  bs, grid.x, nblocs_seg, *h_nb_pix_max, taille_mem);
357
358   cudaMemcpy( h_liste_pix, d_liste_pix, taille_mem*sizeof(uint2), cudaMemcpyDeviceToHost ) ;
359   cudaMemcpy( h_snake, *d_snake, nnodes*sizeof(snake_node_gpu), cudaMemcpyDeviceToHost );
360   uint32 * h_liste_pixels_segment = new uint32[2*(*h_nb_pix_max)] ;
361   int idx_n, idx_nprec, idx_nsuiv ;
362
363   printf("********* LISTE PIX  ***********\n");
364   printf("bs = %d - grid = %d - nblocs_seg = %d - npix_max = %d - taille mem = %d\n",
365                  bs, grid.x, nblocs_seg, *h_nb_pix_max, taille_mem);
366   
367   for (int n=0; n<(nnodes/2 + (nnodes%2)*pairs); n++)
368         {
369           idx_n = 2*n + !pairs ;
370           if (idx_n == 0) idx_nprec = nnodes - 1;
371           else idx_nprec = idx_n - 1;
372           if (idx_n == nnodes-1) idx_nsuiv = 0;
373           else idx_nsuiv = idx_n + 1 ;
374                 
375           for (int pos=0; pos < 8 ; pos++) //test des segments avant le noeud
376                 {
377                   
378                   int nb_pix = calcul_liste_pixel_segment(h_snake[idx_nprec].posi,h_snake[idx_nprec].posj,
379                                                                                                   h_liste_positions[8*idx_n+pos].x, h_liste_positions[8*idx_n+pos].y,
380                                                                                                   h_liste_pixels_segment, 0);
381                   
382                   for (int pix=0; pix < nb_pix; pix++)
383                         {
384                           
385                           if ( (h_liste_pix[(16*n + pos)*nblocs_seg*bs + pix].x != h_liste_pixels_segment[2*pix] )
386                                    || ( h_liste_pix[(16*n + pos)*nblocs_seg*bs + pix].y != h_liste_pixels_segment[2*pix+1] ) )
387                                 printf("erreur avant n=%d pix %d/%d segment %d noeuds[ %d-%d-%d ] , CPU (%d,%d) - GPU (%d, %d)\n", n, pix, nb_pix, pos,
388                                            idx_nprec, idx_n, idx_nsuiv,
389                                            h_liste_pixels_segment[2*pix], h_liste_pixels_segment[2*pix+1],
390                                            h_liste_pix[(16*n + pos)*nblocs_seg*bs + pix].x,  h_liste_pix[(16*n + pos)*nblocs_seg*bs + pix].y);
391                           
392                         }
393                   
394                 }
395           for (int pos=0; pos < 8 ; pos++) //test des segments apres le noeud
396                 {
397                   
398                   int nb_pix = calcul_liste_pixel_segment(h_liste_positions[8*idx_n+pos].x, h_liste_positions[8*idx_n+pos].y,
399                                                                                                   h_snake[idx_nsuiv].posi,h_snake[idx_nsuiv].posj,
400                                                                                                   h_liste_pixels_segment, 0);
401                   
402                   for (int pix=0; pix < nb_pix; pix++)
403                         {
404                           
405                           if ( (h_liste_pix[(16*n + pos + 8)*nblocs_seg*bs + pix].x != h_liste_pixels_segment[2*pix] )
406                              || ( h_liste_pix[(16*n + pos + 8)*nblocs_seg*bs + pix].y != h_liste_pixels_segment[2*pix+1] ) )
407                                 printf("erreur apres n=%d pix %d/%d segment %d noeuds[ %d-%d-%d ] , CPU (%d,%d) - GPU (%d, %d)\n", n, pix, nb_pix, pos+8,
408                                            idx_nprec, idx_n, idx_nsuiv,
409                                            h_liste_pixels_segment[2*pix], h_liste_pixels_segment[2*pix+1],
410                                            h_liste_pix[(16*n + pos + 8)*nblocs_seg*bs + pix].x,  h_liste_pix[(16*n + pos + 8)*nblocs_seg*bs + pix].y);
411                           
412                         }
413                   
414                 }
415  
416                 }
417   
418 #endif //DEBUG_LISTES
419   
420   /*
421         
422         Test du calcul des sommes partielles 'somblocs' faites par le kernel 'calcul_contribs_segments_blocs_full'
423
424    */
425  
426 #ifdef DEBUG_SOMBLOCS
427   printf("********* SOMMES PARTIELLES  ***********\n");
428   printf("bs = %d - grid = %d -  intervalles = %d - nblocs_seg = %d - pairs = %d \n", bs, grid.x, n_interval, nblocs_seg, pairs);
429   for (int n=0; n< n_interval; n++)
430         {
431           idx_n = 2*n + !pairs ;
432           if (idx_n == 0) idx_nprec = nnodes - 1 ;
433           else idx_nprec = idx_n - 1 ;
434           if (idx_n == nnodes-1) idx_nsuiv = 0 ;
435           else idx_nsuiv = idx_n + 1 ;
436           printf("******** node %d\n", idx_n) ;
437           for(int s=0; s<8; s++)
438                 {
439                   int nb_pix = calcul_liste_pixel_segment(h_snake[idx_nprec].posi,h_snake[idx_nprec].posj,
440                                                                                                   h_liste_positions[8*idx_n+s].x, h_liste_positions[8*idx_n+s].y,
441                                                                                                   h_liste_pixels_segment, 0);
442                   for (int b=0; b<nblocs_seg; b++)
443                         {
444                           uint64 c1=0, cx=0, cx2=0 ;
445                           int i,j;
446                           for (int p=0; p<bs; p++)
447                                 {
448                                   if ( ((b*bs+p) < (nb_pix-1)) && ((b*bs+p)>0) )
449                                         {
450                                           //  /!\ penser a oter le test de prise en
451                                           // compte pour les pix sur la même ligne dans
452                                           // le kernel, sinon les comparaisons des
453                                           // sommes par colonne seront fausses
454                                           i = h_liste_pixels_segment[2*(b*bs + p)] ;
455                                           j = h_liste_pixels_segment[2*(b*bs + p) + 1] ;
456                                           c1 += img_1[i][j] ;
457                                           cx += img_x[i][j] ;
458                                           cx2+= img_x2[i][j];
459                                         }
460                                 }
461                           if ( ( c1 != h_sombloc[(16*n + s)*nblocs_seg + b ] ) || ( cx != h_sombloc[(16*n + s)*nblocs_seg + b + grid.x] )
462                                    ||  ( cx2 != h_sombloc[ (16*n + s)*nblocs_seg + b + 2*grid.x] ) )
463                                 printf("seg %d - %d pix : bloc %d -> CPU : %lu - %lu - %lu \t|| GPU : %lu - %lu - %lu \n", s, nb_pix, b,
464                                            c1, cx, cx2, h_sombloc[(16*n+s)*nblocs_seg + b], h_sombloc[(16*n+s)*nblocs_seg + b + grid.x],
465                                            h_sombloc[(16*n+s)*nblocs_seg + b + 2*grid.x]) ;    
466                         }
467                  
468                 }
469            for(int s=0; s<8; s++)
470                 {
471                   int nb_pix = calcul_liste_pixel_segment( h_liste_positions[8*idx_n+s].x, h_liste_positions[8*idx_n+s].y,
472                                                                                                   h_snake[idx_nsuiv].posi,h_snake[idx_nsuiv].posj,
473                                                                                                   h_liste_pixels_segment, 0);
474                   for (int b=0; b<nblocs_seg; b++)
475                         {
476                           uint64 c1=0, cx=0, cx2=0 ;
477                           int i,j;
478                           for (int p=0; p<bs; p++)
479                                 {
480                                   if ( ((b*bs+p) < (nb_pix-1)) && ((b*bs+p)>0) )
481                                         {
482                                           //  /!\ penser a oter le test de prise en
483                                           // compte pour les pix sur la même ligne dans
484                                           // le kernel, sinon les comparaisons des
485                                           // sommes par colonne seront fausses
486                                           i = h_liste_pixels_segment[2*(b*bs + p)] ;
487                                           j = h_liste_pixels_segment[2*(b*bs + p) + 1] ;
488                                           c1 += img_1[i][j] ;
489                                           cx += img_x[i][j] ;
490                                           cx2+= img_x2[i][j];
491                                         }
492                                 }
493                           if ( ( c1 != h_sombloc[(16*n + s + 8)*nblocs_seg + b ] ) || ( cx != h_sombloc[(16*n + s + 8)*nblocs_seg + b + grid.x] )
494                                    ||  ( cx2 != h_sombloc[ (16*n + s + 8)*nblocs_seg + b + 2*grid.x] ) )
495                                 printf("seg %d - %d pix : bloc %d -> CPU : %lu - %lu - %lu \t|| GPU : %lu - %lu - %lu \n", s, nb_pix, b,
496                                            c1, cx, cx2, h_sombloc[(16*n+s+8)*nblocs_seg + b], h_sombloc[(16*n+s+8)*nblocs_seg + b + grid.x],
497                                            h_sombloc[(16*n+s+8)*nblocs_seg + b + 2*grid.x]) ;    
498                         }
499                  
500                 }
501           
502         }
503 #endif //DEBUG_SOMBLOCS
504
505  
506  /*
507         
508         Test du calcul des sommes totales 'somsom' faites par le kernel 'somsom_full'
509
510    */
511
512 #ifdef DEBUG_SOMSOM
513  printf("********* SOMMES TOTALES  ***********\n");
514   printf("bs = %d - grid = %d -  intervalles = %d - nblocs_seg = %d - pairs = %d \n", bs, grid.x, n_interval, nblocs_seg, pairs);
515   for (int n=0; n< n_interval; n++)
516         {
517           idx_n = 2*n + !pairs ;
518           if (idx_n == 0) idx_nprec = nnodes - 1 ;
519           else idx_nprec = idx_n - 1 ;
520           if (idx_n == nnodes-1) idx_nsuiv = 0 ;
521           else idx_nsuiv = idx_n + 1 ;
522           printf("******** node %d\n", idx_n) ;
523           for(int s=0; s<8; s++)
524                 {
525                   int nb_pix = calcul_liste_pixel_segment(h_snake[idx_nprec].posi,h_snake[idx_nprec].posj,
526                                                                                                   h_liste_positions[8*idx_n+s].x, h_liste_positions[8*idx_n+s].y,
527                                                                                                   h_liste_pixels_segment, 0);
528                   uint64 c1=0, cx=0, cx2=0 ;
529                   for (int b=0; b<nblocs_seg; b++)
530                         {
531                           int i,j;
532                           for (int p=0; p<bs; p++)
533                                 {
534                                   if ( ((b*bs+p) < (nb_pix-1)) && ((b*bs+p)>0) )
535                                         {
536                                           //  /!\ penser a oter le test de prise en
537                                           // compte pour les pix sur la même ligne dans
538                                           // le kernel, sinon les comparaisons des
539                                           // sommes par colonne seront fausses
540                                           i = h_liste_pixels_segment[2*(b*bs + p)] ;
541                                           j = h_liste_pixels_segment[2*(b*bs + p) + 1] ;
542                                           c1 += img_1[i][j] ;
543                                           cx += img_x[i][j] ;
544                                           cx2+= img_x2[i][j];
545                                         }
546                                 }    
547                         }
548                   if ( ( c1 != h_somsom[3*(16*n + s)] ) || ( cx != h_somsom[3*(16*n + s) + 1] )
549                            ||  ( cx2 != h_somsom[3*(16*n + s) + 2] ) )
550                                 printf("seg %d - %d pix -> CPU : %lu - %lu - %lu \t|| GPU : %lu - %lu - %lu \n", s, nb_pix, 
551                                            c1, cx, cx2, h_somsom[3*(16*n + s)], h_somsom[3*(16*n + s) + 1],
552                                            h_somsom[3*(16*n + s) + 2]) ;
553                  
554                 }
555           
556            for(int s=0; s<8; s++)
557                 {
558                   int nb_pix = calcul_liste_pixel_segment( h_liste_positions[8*idx_n+s].x, h_liste_positions[8*idx_n+s].y,
559                                                                                                   h_snake[idx_nsuiv].posi,h_snake[idx_nsuiv].posj,
560                                                                                                    h_liste_pixels_segment, 0);
561                   uint64 c1=0, cx=0, cx2=0 ;
562                   for (int b=0; b<nblocs_seg; b++)
563                         {
564                           
565                           int i,j;
566                           for (int p=0; p<bs; p++)
567                                 {
568                                   if ( ((b*bs+p) < (nb_pix-1)) && ((b*bs+p)>0) )
569                                         {
570                                           //  /!\ penser a oter le test de prise en
571                                           // compte pour les pix sur la même ligne dans
572                                           // le kernel, sinon les comparaisons des
573                                           // sommes par colonne seront fausses
574                                           i = h_liste_pixels_segment[2*(b*bs + p)] ;
575                                           j = h_liste_pixels_segment[2*(b*bs + p) + 1] ;
576                                           c1 += img_1[i][j] ;
577                                           cx += img_x[i][j] ;
578                                           cx2+= img_x2[i][j];
579                                         }
580                                 }
581                         }
582                   if ( ( c1 != h_somsom[3*(16*n + s + 8)]  ) || ( cx != h_somsom[3*(16*n + s + 8) + 1] )
583                            ||  ( cx2 != h_somsom[3*(16*n + s + 8) + 2] ) )
584                         printf("seg %d - %d pix -> CPU : %lu - %lu - %lu \t|| GPU : %lu - %lu - %lu \n", s, nb_pix,
585                                    c1, cx, cx2, h_somsom[3*(16*n + s + 8)], h_somsom[3*(16*n + s + 8) + 1],
586                                    h_somsom[3*(16*n + s + 8)  + 2]) ;      
587                   
588                 }
589           
590         }
591   
592 #endif
593   
594  
595 #ifdef DEBUG_MV
596   printf("**** STATS - REF : %lf \n", *h_vrais_snake);
597   for(int n=0; n<n_interval; n++)
598         {
599           for(int p=0; p<8; p++)
600                 {
601                   printf("test %d du node %d : %lu - %lu - %lu - - log_vrais = %lf\n", p, (2*n + !pairs),
602                                  h_stats[3*(8*n+p)], h_stats[3*(8*n+p)+1], h_stats[3*(8*n+p)+2], h_vrais[8*n+p]);
603                 }
604         }
605 #endif //DEBUG_MV
606
607  
608 #ifdef DEBUG_CRST
609   printf("**** CROISEMENTS \n");
610   for(int n=0; n<nnodes; n++)
611         {
612           printf("test du seg %d : ",  n);
613           if ( h_croist[n] ) printf("CROISEMENT\n"); else printf("\n");
614         }
615 #endif //DEBUG_CRST
616
617  
618 #ifdef DEBUG_MOVE
619   printf("**** MOUVEMENTS \n");
620   for(int n=0; n<nnodes; n++)
621         {
622           printf("Node %d : (%s) ",n, (h_move[n])? "yes":"no");
623         }
624 #endif //DEBUG_MOVE
625   
626   delete h_liste_positions ;
627   delete h_snake;
628                                                                          
629   /*
630    * fin generation snake GPU
631    */ 
632 }
633
634