Hitmap 1.3
 All Data Structures Namespaces Files Functions Variables Typedefs Friends Macros Groups Pages
is.c
Go to the documentation of this file.
1 
11 /*
12  * <license>
13  *
14  * Hitmap v1.2
15  *
16  * This software is provided to enhance knowledge and encourage progress in the scientific
17  * community. It should be used only for research and educational purposes. Any reproduction
18  * or use for commercial purpose, public redistribution, in source or binary forms, with or
19  * without modifications, is NOT ALLOWED without the previous authorization of the copyright
20  * holder. The origin of this software must not be misrepresented; you must not claim that you
21  * wrote the original software. If you use this software for any purpose (e.g. publication),
22  * a reference to the software package and the authors must be included.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY
25  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
27  * THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Copyright (c) 2007-2015, Trasgo Group, Universidad de Valladolid.
35  * All rights reserved.
36  *
37  * More information on http://trasgo.infor.uva.es/
38  *
39  * </license>
40 */
41 
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <hitmap.h>
45 #include "prototypes.h"
46 
47 /******************/
48 /* default values */
49 /******************/
50 #ifndef CLASS
51 #define CLASS 'S'
52 #endif
53 #define MIN_PROCS 1
54 
55 
56 /*************/
57 /* CLASS S */
58 /*************/
59 #if CLASS == 'S'
60 #define TOTAL_KEYS_LOG_2 16
61 #define MAX_KEY_LOG_2 11
62 #define NUM_BUCKETS_LOG_2 9
63 #endif
64 
65 
66 /*************/
67 /* CLASS W */
68 /*************/
69 #if CLASS == 'W'
70 #define TOTAL_KEYS_LOG_2 20
71 #define MAX_KEY_LOG_2 16
72 #define NUM_BUCKETS_LOG_2 10
73 #endif
74 
75 /*************/
76 /* CLASS A */
77 /*************/
78 #if CLASS == 'A'
79 #define TOTAL_KEYS_LOG_2 23
80 #define MAX_KEY_LOG_2 19
81 #define NUM_BUCKETS_LOG_2 10
82 #endif
83 
84 
85 /*************/
86 /* CLASS B */
87 /*************/
88 #if CLASS == 'B'
89 #define TOTAL_KEYS_LOG_2 25
90 #define MAX_KEY_LOG_2 21
91 #define NUM_BUCKETS_LOG_2 10
92 #endif
93 
94 
95 /*************/
96 /* CLASS C */
97 /*************/
98 #if CLASS == 'C'
99 #define TOTAL_KEYS_LOG_2 27
100 #define MAX_KEY_LOG_2 23
101 #define NUM_BUCKETS_LOG_2 10
102 #endif
103 
104 
105 /*************/
106 /* CLASS D */
107 /*************/
108 #if CLASS == 'D'
109 #define TOTAL_KEYS_LOG_2 29
110 #define MAX_KEY_LOG_2 27
111 #define NUM_BUCKETS_LOG_2 10
112 #undef MIN_PROCS
113 #define MIN_PROCS 4
114 #endif
115 
116 
117 #define TOTAL_KEYS (1 << TOTAL_KEYS_LOG_2)
118 #define MAX_KEY (1 << MAX_KEY_LOG_2)
119 #define NUM_BUCKETS (1 << NUM_BUCKETS_LOG_2)
120 //#define NUM_KEYS (TOTAL_KEYS/(numProcs)*MIN_PROCS)
121 
122 /*****************************************************************/
123 /* On larger number of processors, since the keys are (roughly) */
124 /* gaussian distributed, the first and last processor sort keys */
125 /* in a large interval, requiring array sizes to be larger. Note */
126 /* that for large NUM_PROCS, NUM_KEYS is, however, a small number*/
127 /* The required array size also depends on the bucket size used. */
128 /* The following values are validated for the 1024-bucket setup. */
129 /*****************************************************************/
130 
131 // This is now set dynamically.
132 /*
133 #if NUM_PROCS < 256
134 #define SIZE_OF_BUFFERS 3*NUM_KEYS/2
135 #elif NUM_PROCS < 512
136 #define SIZE_OF_BUFFERS 5*NUM_KEYS/2
137 #elif NUM_PROCS < 1024
138 #define SIZE_OF_BUFFERS 4*NUM_KEYS
139 #else
140 #define SIZE_OF_BUFFERS 13*NUM_KEYS/2
141 #endif
142 */
143 
144 
145 /*****************************************************************/
146 /* NOTE: THIS CODE CANNOT BE RUN ON ARBITRARILY LARGE NUMBERS OF */
147 /* PROCESSORS. THE LARGEST VERIFIED NUMBER IS 1024. INCREASE */
148 /* MAX_PROCS AT YOUR PERIL */
149 /*****************************************************************/
150 #if CLASS == 'S'
151 #define MAX_PROCS 128
152 #else
153 #define MAX_PROCS 1024
154 #endif
155 
156 #define MAX_ITERATIONS 10
157 #define TEST_ARRAY_SIZE 5
158 
159 
160 
162 
163 /***********************************/
164 /* Enable separate communication, */
165 /* computation timing and printout */
166 /***********************************/
167 /* #define TIMING_ENABLED */
168 #ifdef TIMING_ENABLED
169 HitClock timers[3];
170 #endif
171 
172 
173 /*************************************/
174 /* Typedef: if necessary, change the */
175 /* size of int here by changing the */
176 /* int type to, say, long */
177 /*************************************/
178 typedef int INT_TYPE;
179 typedef long INT_TYPE2;
180 
181 
182 /********************/
183 /* Some global info */
184 /********************/
186 
187 
188 /************************************/
189 /* These are the three main arrays. */
190 /* See SIZE_OF_BUFFERS def above */
191 /************************************/
192 
195 
196 hit_tileNewType(int);
197 hit_tileNewType(double);
198 hit_tileNewType(HitTile_int);
199 typedef HitTile_int KEY_TYPE;
200 
201 KEY_TYPE key_array, key_buff1, key_buff2 = HIT_TILE_NULL_STATIC, key_buff3 = HIT_TILE_NULL_STATIC,
204 
205 
206 #define hit_key_array(a) hit_tileElemAtNoStride1(key_array,a)
207 #define hit_key_buff1(a) hit_tileElemAtNoStride1(key_buff1,a)
208 #define hit_key_buff2(a) hit_tileElemAtNoStride1(key_buff2,a)
209 #define hit_key_buff3(a) hit_tileElemAtNoStride1(key_buff3,a)
210 
211 #define hit_bucket_size(a) hit_tileElemAtNoStride1(bucket_size,(a))
212 #define hit_bucket_size_totals(a) hit_tileElemAtNoStride1(bucket_size_totals,(a))
213 #define hit_test_keys(a) hit_tileElemAtNoStride1(test_keys,(a))
214 #define hit_test_keys_all(a) hit_tileElemAtNoStride1(test_keys_all,(a))
215 
217 
219 
220 
221 
222 /**********************/
223 /* Partial verif info */
224 /**********************/
227 
229  {48427,17148,23627,62548,4431},
231  {0,18,346,64917,65463},
232 
234  {357773,934767,875723,898999,404505},
236  {1249,11698,1039987,1043896,1048018},
237 
239  {2112377,662041,5336171,3642833,4250760},
241  {104,17523,123928,8288932,8388264},
242 
244  {41869,812306,5102857,18232239,26860214},
246  {33422937,10244,59149,33135281,99},
247 
249  {44172927,72999161,74326391,129606274,21736814},
251  {61147,882988,266290,133997595,133525895},
252 
254  {1317351170,995930646,1157283250,1503301535,1453734525},
256  {1,36538729,1978098519,2145192618,2147425337};
257 
258 
259 
260 
261 /*****************************************************************/
262 /************ F I N D _ M Y _ S E E D ************/
263 /************ ************/
264 /************ returns parallel random number seq seed ************/
265 /*****************************************************************/
266 
267 /*
268  * Create a random number sequence of total length nn residing
269  * on np number of processors. Each processor will therefore have a
270  * subsequence of length nn/np. This routine returns that random
271  * number which is the first random number for the subsequence belonging
272  * to processor rank kn, and which is used as seed for proc kn ran # gen.
273  */
274 
275 double find_my_seed( int kn, /* my processor rank, 0<=kn<=num procs */
276  int np, /* np = num procs */
277  long nn, /* total num of ran numbers, all procs */
278  double s, /* Ran num seed, for ex.: 314159265.00 */
279  double a ) /* Ran num gen mult, try 1220703125.00 */
280 {
281 
282  long i, mq,nq,kk,ik;
283  double t1,t2,t3,an;
284 
285 
286 
287  nq = nn / np;
288 
289  for( mq=0; nq>1; mq++,nq/=2 )
290  ;
291 
292  t1 = a;
293 
294  for( i=1; i<=mq; i++ )
295  t2 = randlc( &t1, &t1 );
296 
297  an = t1;
298 
299  kk = kn;
300  t1 = s;
301  t2 = an;
302 
303  for( i=1; i<=100; i++ )
304  {
305  ik = kk / 2;
306  if( 2 * ik != kk )
307  t3 = randlc( &t1, &t2 );
308  if( ik == 0 )
309  break;
310  t3 = randlc( &t2, &t2 );
311  kk = ik;
312  }
313  // @arturo Ago 2015: Avoid a warning of variable initialized but not used
314  (void)t3;
315 
316  return( t1 );
317 
318 }
319 
320 
321 
322 
323 /*****************************************************************/
324 /************* C R E A T E _ S E Q ************/
325 /*****************************************************************/
326 
327 void create_seq( double seed, double a, int num_keys )
328 {
329  double x;
330  int i, k;
331 
332  k = MAX_KEY/4;
333 
334  for (i=0; i<num_keys; i++)
335  {
336  x = randlc(&seed, &a);
337  x += randlc(&seed, &a);
338  x += randlc(&seed, &a);
339  x += randlc(&seed, &a);
340 
341  hit_key_array(i) = (int) (k*x);
342  }
343 }
344 
345 
346 
347 /*****************************************************************/
348 /************* R A N K ****************/
349 /*****************************************************************/
350 
351 
352 void rank( int iteration )
353 {
354  INT_TYPE i, k, key, min_key_val, max_key_val, zero = 0, *key_buff_ptr;
357  double weights[NUM_BUCKETS];
358 
359  /* Iteration alteration of keys */
360  if ( hit_layImLeader( layout_keys ) )
361  {
362  hit_key_array(iteration) = iteration;
363  hit_key_array(iteration+MAX_ITERATIONS) = MAX_KEY - iteration;
364  }
365 
366  /* Initialize */
369 
370  /* Determine where the partial verify test keys are, load into */
371  /* their own tile */
374  hit_test_keys(i) =
375  hit_tileElemAtArrayCoords1( key_array, test_index_array[i] );
376 
377  /* Determine the number of local keys in each bucket */
379  hit_bucket_size( hit_key_array(i) >> shift )++;
380 
381  /* Accumulative bucket sizes are the bucket pointers */
382  bucket_ptrs[0] = 0;
383  for( i=1; i< hit_tileCard( bucket_size ); i++ )
384  bucket_ptrs[i] = bucket_ptrs[i-1] + hit_bucket_size(i-1);
385 
386  /* Sort into appropriate bucket */
387  hit_tileDomainAlloc( &key_buff1, int, 1, hit_layCard( layout_keys ) );
389  {
390  key = hit_key_array(i);
391  hit_key_buff1(bucket_ptrs[key >> shift]++) = key;
392  }
393 
394 #ifdef TIMING_ENABLED
395  hit_clockStop( timers[1] );
396  hit_clockContinue( timers[2] );
397 #endif
398 
399  /* Get the bucket size totals for the entire problem. These */
400  /* will be used to determine the redistribution of keys */
401  /* All processes get all the hidden test keys, in case they need them */
402  /* for the partial verification stage */
403  hit_comDo( &commBucketSizes );
404 
405 #ifdef TIMING_ENABLED
406  hit_clockStop( timers[2] );
407  hit_clockContinue( timers[1] );
408 #endif
409 
410  /* Transform bucket population in weigths for distribution calculations */
412  weights[i] = (double) hit_bucket_size_totals(i);
413 
414  /* Layout with the redistribution of buckets */
415  layout = hit_layout( plug_layContiguous, topology, hit_tileShape( bucket_size ), weights );
416 
417  /* Extract information used by IS from the layout */
418 /*
419  INT_TYPE2 total_lesser_keys = 0;
420  INT_TYPE2 total_local_keys = 0;
421  INT_TYPE num_local_buckets = 0;
422  INT_TYPE num_previous_buckets = 0;
423  for(i=0;i<NUM_BUCKETS;i++) {
424  int elementAssignedTo = hit_lgr_elementGroup( layout, i );
425  if ( elementAssignedTo < hit_layGroup( layout ) ) {
426  total_lesser_keys += hit_bucket_size_totals(i);
427  num_previous_buckets ++;
428  }
429  else if ( elementAssignedTo == hit_layGroup( layout ) ) {
430  total_local_keys += hit_bucket_size_totals(i);
431  num_local_buckets ++;
432  }
433  else break;
434  }
435 */
436 
437 /* DEBUG: SHOW LOADS AND BUCKETS FOR ALL PROCESSORS IN iteration 1 */
438 #ifdef DEBUG
439 if ( iteration == 1 ) {
440 //printf("[%d] total keys: %ld,%ld,%d,%d\n", hit_Rank, total_local_keys, total_lesser_keys, num_local_buckets, num_previous_buckets );
441 printf("[%d] total KEYS: %ld,%ld,%d,%d\n", hit_Rank, (long)hit_layLoad( layout ),
442  (long)hit_layPredLoad( layout, 0 ), hit_lgr_card( layout ), hit_lgr_cardPred( layout ) );
443 }
444 #endif
445 
446  /* Dynamically reallocate the buffer for the number of keys to be received */
448  hit_tileDomainAlloc( &key_buff2, INT_TYPE, 1, (long)hit_layLoad( layout ) );
449 
450 #ifdef TIMING_ENABLED
451  hit_clockStop( timers[1] );
452  hit_clockContinue( timers[2] );
453 #endif
454 
455  /* Redistribute keys */
457  hit_layFree( layout );
459 
460 #ifdef TIMING_ENABLED
461  hit_clockStop( timers[2] );
462  hit_clockContinue( timers[1] );
463 #endif
464 
465 
466  /* The starting and ending bucket numbers on each processor are
467  multiplied by the interval size of the buckets to obtain the
468  smallest possible min and greatest possible max value of any
469  key on each processor */
470  min_key_val = ( hit_lgr_cardPred( layout ) ) << shift;
471  max_key_val = (( hit_lgr_cardPred( layout ) + hit_lgr_card( layout ) ) << shift) -1;
472 
473  /* Reallocate and clear the buffer to compute the local keys population */
475  hit_tileDomainShapeAlloc( &key_buff3, int, hit_shape(1, hit_sig( min_key_val, max_key_val, 1 ) ) );
476  hit_tileFill( &key_buff3, &zero );
477 
478  /* Ranking of all keys occurs in this section: */
479  /* shift it backwards so no subtractions are necessary in loop */
480  key_buff_ptr = & hit_tileElemAtArrayCoords1( key_buff3, 0 );
481 
482  /* In this section, the keys themselves are used as their
483  own indexes to determine how many of each there are: their
484  individual population */
486  key_buff_ptr[hit_key_buff2(i)]++; /* Now they have individual key */
487  /* population */
488 
489  /* To obtain ranks of each key, successively add the individual key
490  population, not forgetting the total of lesser keys, m.
491  NOTE: Since the total of lesser keys would be subtracted later
492  in verification, it is no longer added to the first key population
493  here, but still needed during the partial verify test. This is to
494  ensure that 32-bit key_buff can still be used for class D. */
495  for( i=1; i<hit_tileCard( key_buff3 ); i++ )
496  hit_key_buff3( i ) += hit_key_buff3( i-1 );
497 
498  /* This is the partial verify test section */
499  /* Observe that test_rank_array vals are */
500  /* shifted differently for different cases */
501 
503  {
504  k = hit_test_keys_all(i);
505  if( hit_tileHasArrayCoords1( key_buff3, k ) )
506  {
507  /* Add the total of lesser keys, m, here */
508  // @arturo: POTENTIAL BUG IN THE ORIGINAL CODE:
509  // IF k == min_key_val, OUT OF BUFFER ACCESING key_buff_ptr[ k-1 ]
510  INT_TYPE2 key_rank = hit_tileElemAtArrayCoords1( key_buff3, k-1 ) + (long)hit_layPredLoad( layout, 0 );
511  int failed = 0;
512 
513  switch( CLASS )
514  {
515  case 'S':
516  if( i <= 2 )
517  {
518  if( key_rank != test_rank_array[i]+iteration )
519  failed = 1;
520  else
521  hit_counterInc( passed_verification );
522  }
523  else
524  {
525  if( key_rank != test_rank_array[i]-iteration )
526  failed = 1;
527  else
528  hit_counterInc( passed_verification );
529  }
530  break;
531  case 'W':
532  if( i < 2 )
533  {
534  if( key_rank != test_rank_array[i]+(iteration-2) )
535  failed = 1;
536  else
537  hit_counterInc( passed_verification );
538  }
539  else
540  {
541  if( key_rank != test_rank_array[i]-iteration )
542  failed = 1;
543  else
544  hit_counterInc( passed_verification );
545  }
546  break;
547  case 'A':
548  if( i <= 2 )
549  {
550  if( key_rank != test_rank_array[i]+(iteration-1) )
551  failed = 1;
552  else
553  hit_counterInc( passed_verification );
554  }
555  else
556  {
557  if( key_rank != test_rank_array[i]-(iteration-1) )
558  failed = 1;
559  else
560  hit_counterInc( passed_verification );
561  }
562  break;
563  case 'B':
564  if( i == 1 || i == 2 || i == 4 )
565  {
566  if( key_rank != test_rank_array[i]+iteration )
567  failed = 1;
568  else
569  hit_counterInc( passed_verification );
570  }
571  else
572  {
573  if( key_rank != test_rank_array[i]-iteration )
574  failed = 1;
575  else
576  hit_counterInc( passed_verification );
577  }
578  break;
579  case 'C':
580  if( i <= 2 )
581  {
582  if( key_rank != test_rank_array[i]+iteration )
583  failed = 1;
584  else
585  hit_counterInc( passed_verification );
586  }
587  else
588  {
589  if( key_rank != test_rank_array[i]-iteration )
590  failed = 1;
591  else
592  hit_counterInc( passed_verification );
593  }
594  break;
595  case 'D':
596  if( i < 2 )
597  {
598  if( key_rank != test_rank_array[i]+iteration )
599  failed = 1;
600  else
601  hit_counterInc( passed_verification );
602  }
603  else
604  {
605  if( key_rank != test_rank_array[i]-iteration )
606  failed = 1;
607  else
608  hit_counterInc( passed_verification );
609  }
610  break;
611  }
612  if( failed == 1 )
613  printf( "Failed partial verification: "
614  "iteration %d, processor %d, test key %d\n",
615  iteration, hit_laySelfRanksDim( layout_keys, 0 ), (int)i );
616  }
617  }
618 }
619 
620 
621 
622 
623 /*****************************************************************/
624 /************* M A I N ****************/
625 /*****************************************************************/
626 
627 int main( int argc, char **argv )
628 {
629  int i, iteration;
630 
631  /* Initialize Hitmap */
632  hit_comInit(&argc,&argv);
633 
634  /* Initialize the verification arrays if a valid class */
635  for( i=0; i<TEST_ARRAY_SIZE; i++ )
636  switch( CLASS )
637  {
638  case 'S':
641  break;
642  case 'A':
645  break;
646  case 'W':
649  break;
650  case 'B':
653  break;
654  case 'C':
657  break;
658  case 'D':
661  break;
662  };
663 
664 
665  /* Create a topology: Restrict to a number of processes which is power of 2 */
666  topology = hit_topology( plug_topPlainPower2 );
667 
668  /* Printout initial NPB info */
669  if ( hit_topImLeader( topology ) )
670  {
671  printf( "\n\n NAS Parallel Benchmarks 3.3 -- IS Benchmark\n\n" );
672  printf( " Size: %ld (class %c)\n", (long)TOTAL_KEYS*MIN_PROCS, CLASS );
673  printf( " Iterations: %d\n", MAX_ITERATIONS );
674  printf( " Number of processes: %d\n", hit_topCard( topology ) );
675  }
676 
677  /* Check to see whether total number of processes is within bounds.
678  This could in principle be checked in setparams.c, but it is more
679  convenient to do it here */
680  if( hit_topCard( topology ) < MIN_PROCS || hit_topCard( topology ) > MAX_PROCS)
681  {
682  if ( hit_topImLeader( topology ) )
683  printf( "\n ERROR: number of processes %d not within range %d-%d"
684  "\n Exiting program!\n\n", hit_topCard( topology ), MIN_PROCS, MAX_PROCS);
685  hit_comFinalize();
686  exit( 1 );
687  }
688 
689  /* Create non-allocated global array of keys */
690  KEY_TYPE global_keys;
691  hit_tileDomain( &global_keys, INT_TYPE, 1, TOTAL_KEYS*MIN_PROCS );
692 
693  /* Build layout for keys */
694  layout_keys = hit_layout( plug_layBlocks, topology, hit_tileShape( global_keys ) );
695 
696  if ( hit_layImActive( layout_keys ) ) {
697 
698  int numProcs = hit_layNumActives( layout_keys );
699 
700  /* Create allocated array for bucket sizes + hidden test keys
701  * and prepare tile selections for easy access */
706  hit_tileSelect( &test_keys, &full_buckets_plus_test, hit_shape(1, hit_sig( NUM_BUCKETS, NUM_BUCKETS+TEST_ARRAY_SIZE-1, 1 )) );
707  hit_tileSelect( &test_keys_all, &full_buckets_plus_test2, hit_shape(1, hit_sig( NUM_BUCKETS, NUM_BUCKETS+TEST_ARRAY_SIZE-1, 1 )) );
708 
709  /* Select and allocate ancillary tiles and buffers */
710  hit_tileSelect( &key_array, &global_keys, hit_layShape( layout_keys ) );
712 
713  /* Create communication object for the bucket sizes and test keys */
715 
716  /* Generate random number sequence and subsequent keys on all procs */
717  create_seq( find_my_seed( hit_laySelfRanksDim( layout_keys, 0 ),
718  numProcs,
719  4*(long)TOTAL_KEYS*MIN_PROCS,
720  314159265.00, /* Random number gen seed */
721  1220703125.00 ), /* Random number gen mult */
722  1220703125.00, /* Random number gen mult */
723  hit_layCard( layout_keys ) ); /* Number of keys in each process */
724 
725  /* Do one interation for free (i.e., untimed) to guarantee initialization of
726  all data and code pages and respective tables */
727  rank( 1 );
728 
729  /* Start verification counter */
730  hit_counterReset( passed_verification );
731 
732 #ifdef TIMING_ENABLED
733  /* Initialize separate communication, computation timing */
734  hit_clockReset( timers[2] );
735 #endif
736 
737  /* Start timer */
738  hit_clockStart( mainTimer );
739 
740 #ifdef TIMING_ENABLED
741  hit_clockStart( timers[0] );
742  hit_clockStart( timers[1] );
743 #endif
744 
745  /* This is the main iteration */
746  for( iteration=1; iteration<=MAX_ITERATIONS; iteration++ )
747  {
748  if ( CLASS != 'S' && hit_layImLeader( layout_keys ) )
749  printf( "\tIteration %d\n", iteration );
750  rank( iteration );
751  }
752 
753  /* End of timing, obtain maximum time of all processors */
754  hit_clockStop( mainTimer );
755  hit_clockReduce( layout_keys, mainTimer );
756 
757  /* Free tiles not needed in full verification */
761 
762 #ifdef TIMING_ENABLED
763  /* Show timers */
764  hit_clockStop( timers[1] );
765  hit_clockStop( timers[0] );
766  if ( hit_topImLeader( topology ) )
767  printf( "\nTimers 0/1/2 = total/computation/communication times\n");
768  hit_clockReduce( layout_keys, timers[0] );
769  hit_clockPrintMax( timers[0] );
770  hit_clockPrintMin( timers[0] );
771  hit_clockPrintAvg( timers[0] );
772  hit_clockReduce( layout_keys, timers[1] );
773  hit_clockPrintMax( timers[1] );
774  hit_clockPrintMin( timers[1] );
775  hit_clockPrintAvg( timers[1] );
776  hit_clockReduce( layout_keys, timers[2] );
777  hit_clockPrintMax( timers[2] );
778  hit_clockPrintMin( timers[2] );
779  hit_clockPrintAvg( timers[2] );
780 #endif
781 
782  /* Tests that keys are in sequence: sorting of last ranked key seq
783  occurs here, but is an untimed operation */
784  full_verify();
785 
786  /* Free tiles used for full verification */
789 
790  /* Obtain verification counter sum */
791  hit_counterReduce( layout_keys, passed_verification );
792  int verificationSum = hit_counterSum( passed_verification );
793 
794  /* The final printout */
795  if ( hit_layImLeader( layout_keys ) ) {
796  if( verificationSum != 5*MAX_ITERATIONS + numProcs )
797  verificationSum = 0;
798  c_print_results( "IS",
799  CLASS,
800  (int)(TOTAL_KEYS),
801  MIN_PROCS,
802  0,
804  -1,
805  numProcs,
806  hit_clockGetMaxSeconds( mainTimer ),
807  ((double) (MAX_ITERATIONS)*TOTAL_KEYS*MIN_PROCS)
808  /hit_clockGetMaxSeconds( mainTimer)/1000000.0,
809  "keys ranked",
810  verificationSum,
811  "", // NPBVERSION
812  "", // COMPILETIME
813  "", // MPICC
814  "", // CLINK
815  "", // CMPI_LIB
816  "", // CMPI_INC
817  "", // CFLAGS
818  ""); // CLINKFLAGS
819  }
820  } // END hit_layImActive
821 
822  /* Free communication objects, layouts, and topology */
823  hit_comFree( commBucketSizes );
824  hit_layFree( layout_keys );
825  hit_topFree( topology );
826  hit_comFinalize();
827 
828  return 0;
829  /**************************/
830 } /* E N D P R O G R A M */
831  /**************************/
832 
833 
834 
835 /*****************************************************************/
836 /************* F U L L _ V E R I F Y ************/
837 /*****************************************************************/
838 
839 void full_verify( void )
840 {
841 
842  INT_TYPE i;
843  KEY_TYPE largest_key;
844 
845  /* Allocate the key array to sort the keys in buff2 */
847 
848  /* Now, finally, sort the keys: */
849  INT_TYPE *key_buff_ptr = & hit_tileElemAtArrayCoords1( key_buff3, 0 );
851  hit_key_array( --key_buff_ptr[hit_key_buff2(i)] ) = hit_key_buff2(i);
852 
853  /* Get the largest key */
854  hit_tileDomainAlloc( &largest_key, int, 1, 1 );
855  hit_tileElemAt( largest_key, 1, 0 ) = (hit_tileCard( key_buff2 ) > 0) ? hit_key_array( hit_tileDimEnd( key_buff2, 0 ) ) : 0;
856 
857  /* Communication: Shift largest key value to next processor */
858  hit_comDoOnce( hit_comShiftDim( layout_keys, 0, +1, &largest_key, HIT_INT ) );
859 
860  /* Confirm that neighbor's greatest key value
861  is not greater than my least key value */
862  int j = 0;
863  if( ! hit_layImLeader( layout_keys ) && hit_tileCard( key_buff2 ) > 0 )
864  if( hit_tileElemAt( largest_key, 1 , 0 ) > hit_key_array(0) )
865  j++;
866 
867 #ifdef DEBUG
868  if( j != 0 )
869  {
870  printf( "Processor %d: Full_verify: Before: %d, first: %d!!!: %d\n", hit_laySelfRanksDim( layout_keys, 0 ), j, hit_tileElemAt( largest_key, 1, 0 ), hit_key_array(0) );
871  }
872 #endif
873 
874  /* Confirm keys correctly sorted: count incorrectly sorted keys, if any */
875  for( i=1; i<hit_tileCard( key_buff2 ); i++ )
876  if( hit_key_array(i-1) > hit_key_array(i) )
877  j++;
878 
879  if( j != 0 )
880  {
881  printf( "Processor %d: Full_verify: number of keys out of sort: %d\n", hit_laySelfRanksDim( layout_keys, 0 ), j );
882  }
883  else
884  hit_counterInc( passed_verification );
885 
886  /* Free resources */
888  hit_tileFree( largest_key );
889 }
890 
INT_TYPE2 W_test_rank_array[TEST_ARRAY_SIZE]
Definition: is.c:235
INT_TYPE2 B_test_rank_array[TEST_ARRAY_SIZE]
Definition: is.c:245
#define hit_counterInc(c)
Definition: hit_utils.h:233
KEY_TYPE bucket_size
Definition: is.c:201
#define hit_shape(nd,...)
Definition: hit_sshape.h:175
#define hit_layShape(lay)
Definition: hit_layout.h:650
#define hit_key_buff1(a)
Definition: is.c:207
#define MAX_KEY_LOG_2
Definition: is.c:110
#define hit_tileNewType(baseType)
Definition: hit_tile.h:163
INT_TYPE2 S_test_rank_array[TEST_ARRAY_SIZE]
Definition: is.c:230
HitOp HIT_OP_SUM_INT
Definition: hit_com.c:63
#define hit_tileFill(var, value)
Definition: hit_tile.h:390
#define HIT_INT
Definition: hit_com.h:74
void create_seq(double seed, double a, int num_keys)
Definition: is.c:327
#define hit_Rank
Definition: hit_com.h:140
#define hit_tileElemAt(var, ndims,...)
Definition: hit_tile.h:519
#define hit_layCard(lay)
Definition: hit_layout.h:690
void hit_comFree(HitCom issue)
Definition: hit_com.c:1995
void full_verify(void)
Definition: is.c:839
#define hit_layImLeader(lay)
Definition: hit_layout.h:817
#define hit_topImLeader(topo)
Definition: hit_topology.h:486
void hit_comDo(HitCom *issue)
Definition: hit_com.c:2408
KEY_TYPE full_buckets_plus_test2
Definition: is.c:201
#define hit_clockContinue(c)
Definition: hit_utils.h:121
#define hit_tileDomainAlloc(newVarP, baseType, numDims,...)
Definition: hit_tile.h:336
HitLayout layout_keys
Definition: is.c:193
#define MIN_PROCS
Definition: is.c:113
HitLayout layout[k_num]
Definition: mg.c:150
#define hit_tileAlloc(var)
Definition: hit_tile.h:319
#define hit_key_buff2(a)
Definition: is.c:208
HitCom hit_comAllDistribute(HitLayout lay, const void *tilePSend, int *count, const void *tilePRecv, HitType baseType)
Definition: hit_com.c:1651
#define hit_topology(name,...)
Definition: hit_topology.h:308
#define NUM_BUCKETS
Definition: is.c:119
HitRanks HIT_RANKS_NULL
Definition: hit_topology.c:68
#define MAX_PROCS
Definition: is.c:151
INT_TYPE2 C_test_rank_array[TEST_ARRAY_SIZE]
Definition: is.c:250
KEY_TYPE key_buff1
Definition: is.c:201
#define hit_clockGetMaxSeconds(c)
Definition: hit_utils.h:191
INT_TYPE2 W_test_index_array[TEST_ARRAY_SIZE]
Definition: is.c:233
int rank
Definition: SWpar_ref.c:181
KEY_TYPE key_buff2
Definition: is.c:201
#define hit_layPredLoad(lay, dim)
Definition: hit_layout.h:631
#define hit_tileCard(var)
Definition: hit_tile.h:763
#define hit_lgr_cardPred(lay)
Definition: hit_layout.h:911
#define hit_test_keys(a)
Definition: is.c:213
#define hit_laySelfRanksDim(lay, dim)
Definition: hit_layout.h:857
#define hit_tileSelect(newVar, oldVar, shape)
Definition: hit_tile.h:453
#define hit_clockPrintMax(c)
Definition: hit_utils.h:175
#define MAX_ITERATIONS
Definition: is.c:156
#define hit_counterReduce(lay, c)
Definition: hit_utils.h:248
void c_print_results(char *name, char class, int n1, int n2, int n3, int niter, int nprocs_compiled, int nprocs_total, double t, double mops, char *optype, int passed_verification, char *npbversion, char *compiletime, char *mpicc, char *clink, char *cmpi_lib, char *cmpi_inc, char *cflags, char *clinkflags)
int INT_TYPE
Definition: is.c:178
#define hit_lgr_card(lay)
Definition: hit_layout.h:909
#define hit_tileDomainShapeAlloc(newVarP, baseType, shape)
Definition: hit_tile.h:354
#define x
#define hit_key_array(a)
Definition: is.c:206
#define hit_clockReset(c)
Definition: hit_utils.h:78
void hit_topFree(HitTopology topo)
Definition: hit_topology.c:129
INT_TYPE2 A_test_rank_array[TEST_ARRAY_SIZE]
Definition: is.c:240
#define TOTAL_KEYS
Definition: is.c:117
#define hit_tileDimHasArrayCoord(var, dim, pos)
Definition: hit_tile.h:836
void hit_comInit(int *pargc, char **pargv[])
Definition: hit_com.c:111
#define hit_comDoOnce(com)
Definition: hit_com.h:1003
HitClock mainTimer
Definition: is.c:161
INT_TYPE2 C_test_index_array[TEST_ARRAY_SIZE]
Definition: is.c:248
#define hit_layImActive(lay)
Definition: hit_layout.h:797
INT_TYPE2 test_rank_array[TEST_ARRAY_SIZE]
Definition: is.c:225
#define hit_comShiftDim(lay, dim, shift, tileP, baseType)
Definition: hit_com.h:646
#define hit_bucket_size(a)
Definition: is.c:211
#define hit_counterReset(c)
Definition: hit_utils.h:220
#define hit_tileDomain(newVarP, baseType, numDims,...)
Definition: hit_tile.h:286
INT_TYPE2 B_test_index_array[TEST_ARRAY_SIZE]
Definition: is.c:243
KEY_TYPE bucket_size_totals
Definition: is.c:201
int hit_topCard(HitTopology topo)
Definition: hit_topology.c:361
#define hit_key_buff3(a)
Definition: is.c:209
#define hit_tileDimEnd(var, dim)
Definition: hit_tile.h:796
KEY_TYPE key_array
Definition: is.c:201
#define hit_clockPrintMin(c)
Definition: hit_utils.h:178
HitCom commBucketSizes
Definition: is.c:218
INT_TYPE bucket_ptrs[NUM_BUCKETS]
Definition: is.c:216
INT_TYPE2 A_test_index_array[TEST_ARRAY_SIZE]
Definition: is.c:238
void hit_layFree(HitLayout lay)
Definition: hit_layout.c:2251
#define hit_clockStop(c)
Definition: hit_utils.h:109
#define s
int main(int argc, char *argv[])
Definition: cannonAsync.c:62
double find_my_seed(int kn, int np, long nn, double s, double a)
Definition: is.c:275
#define hit_comReduce(lay, root, tilePSend, tilePRecv, baseType, operation)
Definition: hit_com.h:725
HitTile_int KEY_TYPE
Definition: is.c:199
#define hit_counterSum(c)
Definition: hit_utils.h:306
KEY_TYPE key_buff3
Definition: is.c:201
#define NUM_BUCKETS_LOG_2
Definition: is.c:111
#define hit_layLoad(lay)
Definition: hit_layout.h:630
#define TEST_ARRAY_SIZE
Definition: is.c:157
#define hit_clockPrintAvg(c)
Definition: hit_utils.h:181
INT_TYPE2 test_index_array[TEST_ARRAY_SIZE]
Definition: is.c:225
#define hit_test_keys_all(a)
Definition: is.c:214
int hit_layNumActives(HitLayout lay)
Definition: hit_layout.c:2213
double randlc(double *X, double *A)
Definition: c_randlc.c:40
#define hit_tileForDimDomain(tile, dim, index)
Definition: hit_tile.h:587
KEY_TYPE test_keys
Definition: is.c:201
#define hit_layout(name, topo,...)
Definition: hit_layout.h:415
#define MAX_KEY
Definition: is.c:118
INT_TYPE2 D_test_index_array[TEST_ARRAY_SIZE]
Definition: is.c:253
long INT_TYPE2
Definition: is.c:179
#define hit_tileFree(var)
Definition: hit_tile.h:369
KEY_TYPE full_buckets_plus_test
Definition: is.c:201
INT_TYPE2 D_test_rank_array[TEST_ARRAY_SIZE]
Definition: is.c:255
HitTopology topology
Definition: is.c:194
#define hit_tileShape(var)
Definition: hit_tile.h:723
INT_TYPE2 S_test_index_array[TEST_ARRAY_SIZE]
Definition: is.c:228
void hit_comFinalize()
Definition: hit_com.c:159
HitCounter passed_verification
Definition: is.c:185
#define hit_clockReduce(lay, c)
Definition: hit_utils.h:139
#define hit_bucket_size_totals(a)
Definition: is.c:212
#define hit_clockStart(c)
Definition: hit_utils.h:87
#define CLASS
Definition: is.c:51
KEY_TYPE test_keys_all
Definition: is.c:201