Exemplo n.º 1
0
static void smix_classic(void)
{
	uint64_t X = B;
	uint32_t i, j;

	puts("classic");

	t_cost = 0;

	for (i = 0; i < N; i++) {
		hits[i] = 0;

		V[i] = X;
		X = H(X);
	}

	at_cost1 = N * sqrt(N); /* sqrt(N) parallel cores attack with extreme recursion */
	at_cost2 = 0;

	for (i = 0; i < N; i++) {
		j = X % N;
		X = H(X ^ V[j]);

		hits[j]++;
		at_cost2 += N; /* 1 time * N area */
	}

	count_hits();

	at_cost2 /= 2; /* extreme TMTO */

	print_costs(X);
	print_hits("total");
	puts("");
}
Exemplo n.º 2
0
static void smix_loop1_pow2(uint32_t N2div)
{
	uint64_t X = B;
	uint32_t i, j, n, N2;

	printf("loop1_pow2(N2 = N/%u)\n", N2div);

	t_cost = 0;
	at_cost1 = at_cost2 = 0;

	n = 1;
	for (i = 0; i < N; i++) {
		V[i] = X;

		hits[i] = 0;
		if (i > 1) {
			if ((i & (i - 1)) == 0)
				n <<= 1;
			j = (X & (n - 1)) + (i - n);
			if (j >= i)
				fprintf(stderr, "Bad j = %08x\n", j);
			hits[j]++;

			X ^= V[j];
		}

		X = H(X);

		at_cost1 += n; /* 1 time * n area */
	}

	count_hits();
	print_hits("loop1");

	N2 = N / N2div;
	for (i = 0; i < N2; i++) {
		j = X % N;
		X = H(X ^ V[j]);

		hits[j]++;
		at_cost2 += N; /* 1 time * N area */
	}

	count_hits();

	at_cost1 /= 2; /* extreme TMTO, probably impossible */
	at_cost2 /= 2; /* extreme TMTO, probably impossible */

	print_costs(X);
	print_hits("total");
	puts("");
}
Exemplo n.º 3
0
static void smix_loop1_mod(uint32_t N2div)
{
	uint64_t X = B;
	uint32_t i, j, N2;

	printf("loop1_mod(N2 = N/%u)\n", N2div);

	t_cost = 0;
	at_cost1 = at_cost2 = 0;

	for (i = 0; i < N; i++) {
		V[i] = X;

		hits[i] = 0;
		if (i > 1) {
			j = X % i; /* drawbacks: depends on chosen size of X (beyond bits in N-1), somewhat slow, not constant time, slightly non-uniform when size of X is not a lot larger than log2(N) */
			if (j >= i)
				fprintf(stderr, "Bad j = %08x\n", j);
			hits[j]++;

			X ^= V[j];
		}

		X = H(X);

		at_cost1 += i; /* 1 time * i area */
	}

	count_hits();
	print_hits("loop1");

	N2 = N / N2div;
	for (i = 0; i < N2; i++) {
		j = X % N;
		X = H(X ^ V[j]);

		hits[j]++;
		at_cost2 += N; /* 1 time * N area */
	}

	count_hits();

	at_cost1 /= 2; /* extreme TMTO, probably impossible */
	at_cost2 /= 2; /* extreme TMTO, probably impossible */

	print_costs(X);
	print_hits("total");
	puts("");
}
Exemplo n.º 4
0
static void smix_loop1_wrap(uint32_t N2div)
{
	uint64_t X = B;
	uint32_t i, j, N2;

	printf("loop1_wrap(N2 = N/%u)\n", N2div);

	t_cost = 0;
	at_cost1 = at_cost2 = 0;

	for (i = 0; i < N; i++) {
		V[i] = X;

		hits[i] = 0;
		if (i > 1) {
			j = wrap(X, i);
			if (j >= i)
				fprintf(stderr, "Bad j = %08x\n", j);
			hits[j]++;

			X ^= V[j];
		}

		X = H(X);

		at_cost1 += i; /* 1 time * i area (although not all j's in [0,i-1] are possible for a given i) */
	}

	count_hits();
	print_hits("loop1");

	N2 = N / N2div;
	for (i = 0; i < N2; i++) {
		j = X % N;
		X = H(X ^ V[j]);

		hits[j]++;
		at_cost2 += N; /* 1 time * N area */
	}

	count_hits();

	at_cost1 /= 2; /* extreme TMTO, probably impossible */
	at_cost2 /= 2; /* extreme TMTO, probably impossible */

	print_costs(X);
	print_hits("total");
	puts("");
}
Exemplo n.º 5
0
void
dump_callgrind(calltree_node *root, FILE *ofile)
{
  int i;
  call_summary summary;
  summary.fns_usemask = calloc(1, g_nfndescr);
  assert(summary.fns_usemask);

  collect_summary(root, &summary);
  fprintf(ofile, "events: Instructions\n"
          "summary: %" PRIu64"\n\n\n", summary.total_cost);
  
  for (i = 0; i < g_nfndescr; i++) {
    if (summary.fns_usemask[i])
      fprintf(ofile, "fn=(%d) %s\n", i, g_fndescr[i].name);
  }
  free(summary.fns_usemask);

  print_costs(&summary, root, ofile);
  fprintf(ofile, "\n\n");
}
Exemplo n.º 6
0
static void
print_costs(const call_summary *summary, 
            const calltree_node *node, FILE *ofile)
{
    int i;

    fprintf(ofile, "fn=(%d)\n", fn2id(node->pfn));
    fprintf(ofile, "1 %" PRIu64 "\n", node->nself);

    for (i = 0; i < node->nchilds; i++) {
        const calltree_node *child = &node->childs[i];

        fprintf(ofile, "cfn=(%d)\n", fn2id(child->pfn));
        fprintf(ofile, "calls=%" PRIu64 " 1\n", child->nself + child->nintermediate);
        fprintf(ofile, "1 %" PRIu64 "\n", child->nself + child->nintermediate);
    }

    for (i = 0; i < node->nchilds; i++) {
        fprintf(ofile, "\n");
        print_costs(summary, &node->childs[i], ofile);
    }
}
Exemplo n.º 7
0
int
main(int argc, char *argv[])
{
  static AdData data;		/* to be init with 0 (debug only) */
  AdData *p_ad = &data;
  int i, user_stat = 0;

  double time_one0, time_one;
  double nb_same_var_by_iter, nb_same_var_by_iter_tot;

  int    nb_iter_cum;
  int    nb_local_min_cum;
  int    nb_swap_cum;
  int    nb_reset_cum;
  double nb_same_var_by_iter_cum;


  int    nb_restart_cum,           nb_restart_min,              nb_restart_max;
  double time_cum,                    time_min,                    time_max;

  int    nb_iter_tot_cum,          nb_iter_tot_min,             nb_iter_tot_max;
  int    nb_local_min_tot_cum,     nb_local_min_tot_min,   nb_local_min_tot_max;
  int    nb_swap_tot_cum,          nb_swap_tot_min,             nb_swap_tot_max;
  int    nb_reset_tot_cum,         nb_reset_tot_min,          nb_reset_tot_max;
  double nb_same_var_by_iter_tot_cum, nb_same_var_by_iter_tot_min, nb_same_var_by_iter_tot_max;

  int    user_stat_cum,             user_stat_min,               user_stat_max;
  char buff[256], str[32];

  /* Seeds generation */
  int last_value;	/* last value generated by the linear chaotic map */
  int param_a;		/* parameter 'a' for the linear chaotic map */
  int param_c;		/* parameter 'c' for the linear chaotic map */
  long int print_seed ;
  struct timeval tv ;
#if defined PRINT_COSTS
  char * tmp_filename=NULL ;
#endif /* PRINT_COSTS */
#if defined MPI
  Main_MPIData mpi_data ;
#endif

  Parse_Cmd_Line(argc, argv, p_ad);

  /************************ Initialize chaotic function **********************/
  param_a = 5;                      /* Values by default from research paper */
  param_c = 1;
  gettimeofday(&tv, NULL);

  /*********************** MPI & SEQ code Initialization *********************/
#if defined MPI
  mpi_data.param_a_ptr = &param_a ;
  mpi_data.param_c_ptr = &param_c ;
  mpi_data.last_value_ptr = &last_value ;
  mpi_data.p_ad = p_ad ;
  mpi_data.p_ad->main_mpi_data_ptr = &mpi_data ;
  mpi_data.print_seed_ptr = &print_seed ;
  mpi_data.tv_sec = tv.tv_sec ;
  mpi_data.count_ptr = &count ;

#if defined STATS
  Gmpi_stats.nb_sent_messages = 0 ;
  Gmpi_stats.nb_sent_mymessages = 0 ;
#endif

#if defined PRINT_COSTS
  mpi_data.nb_digits_nbprocs_ptr = &nb_digits_nbprocs ;
#endif
  MPI_Init( &argc , &argv ) ;
  MPI_Comm_rank(MPI_COMM_WORLD, &my_num) ;
  MPI_Comm_size(MPI_COMM_WORLD, &mpi_size) ;
  TPRINT0("Program: %s", argv[0]) ;
  for( i=1 ; i< argc ; ++i )
    PRINT0(" %s", argv[i]) ;
  PRINT0("\n") ;
  AS_MPI_initialization( &mpi_data ) ;
#else /****************************** MPI -> SEQ *****************************/
  TPRINT0("Program: %s", argv[0]) ;
  for( i=1 ; i< argc ; i++ )
    PRINT0(" %s", argv[i]) ;
  PRINT0("\n") ;
#if defined PRINT_COSTS
  nb_digits_nbprocs = 0 ;
#endif /* PRINT_COSTS */
  if (p_ad->seed < 0) {
    srandom((unsigned int)tv.tv_sec);
    /* INT_MAX / 6 (= 357.913.941) is a reasonable value to start with... 
       I think... */
    last_value = (int) Random(INT_MAX / 6);
    /* INT_MAX (= 2.147.483.647) is the max value for a signed 32-bit int */
    p_ad->seed = randChaos(INT_MAX, &last_value, &param_a, &param_c);
  }
  print_seed = p_ad->seed;
#endif /**************************** MPI */

#if defined PRINT_COSTS
  if( filename_pattern_print_cost==NULL ) {
    PRINT0("Please give a pattern for filename in which to save costs\n\n") ;
    exit(-1) ;
  }
  tmp_filename=(char*)
    malloc(sizeof(char)*strlen(filename_pattern_print_cost) 
	   + 2
	   + nb_digits_nbprocs ) ;
  if( nb_digits_nbprocs > 3 ) {
    PRINT0("You use a number of procs sup to 999. "
	   "You must modify the code to adjust next line\n") ;
    exit(-1) ;
  }
#if defined MPI
  /* TODO: How can we bypass the static char to format output in nxt line? */
  sprintf(tmp_filename,"%s_p%03d", filename_pattern_print_cost,my_num) ;
#else
  sprintf(tmp_filename,"%s_seq", filename_pattern_print_cost) ;
#endif
  file_descriptor_print_cost = open(tmp_filename,
				    O_WRONLY | O_EXCL | O_CREAT,
				    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) ;
  if( file_descriptor_print_cost == -1 ) {
    PRINTF("Cannot create file to print costs: file already exists?\n") ;
    return -1 ;
  }
#endif /* PRINT_COSTS */

  /********* Initialization of the pseudo-random generator with the seed ******/
  srandom((unsigned)p_ad->seed);

  p_ad->nb_var_to_reset = -1;
  p_ad->do_not_init = 0;
  p_ad->actual_value = NULL;
  p_ad->base_value = 0;
  p_ad->break_nl = 0;
  /* defaults */

  Init_Parameters(p_ad);

  if (p_ad->reset_limit >= p_ad->size)
    p_ad->reset_limit = p_ad->size - 1;

  setvbuf(stdout, NULL, _IOLBF, 0);
  //setlinebuf(stdout);

  if (p_ad->debug > 0 && !ad_has_debug)
    DPRINT0("Warning ad_solver is not compiled with debugging support\n") ;

  if (p_ad->log_file && !ad_has_log_file)
    DPRINT0("Warning ad_solver is not compiled with log file support\n") ;

  p_ad->size_in_bytes = p_ad->size * sizeof(int);
  p_ad->sol = malloc(p_ad->size_in_bytes);

  if (p_ad->nb_var_to_reset == -1) {
    p_ad->nb_var_to_reset = Div_Round_Up(p_ad->size * p_ad->reset_percent, 100);
    if (p_ad->nb_var_to_reset < 2) {
      p_ad->nb_var_to_reset = 2;
      PRINT0("increasing nb var to reset since too small, now = %d\n",
	     p_ad->nb_var_to_reset);
    }
  }

#if defined MPI
  AS_MPI_initialization_epilogue( &mpi_data ) ;
#endif

  /********** Print configuration information + specific initialization *****/  
  PRINT0("current random seed used: %u (seed_0 %u) \n",
	 (unsigned int)p_ad->seed, (unsigned int)print_seed) ;
  PRINT0("variables of loc min are frozen for: %d swaps\n",
	 p_ad->freeze_loc_min) ;
  PRINT0("variables swapped are frozen for: %d swaps\n", p_ad->freeze_swap) ;
  if (p_ad->reset_percent >= 0)
    PRINT0("%d %% = ", p_ad->reset_percent) ;
  PRINT0("%d variables are reset when %d variables are frozen\n", 
	 p_ad->nb_var_to_reset, p_ad->reset_limit) ;
  PRINT0("probability to select a local min (instead of "
	 "staying on a plateau): ") ;
  if (p_ad->prob_select_loc_min >=0 && p_ad->prob_select_loc_min <= 100)
    PRINT0("%d %%\n", p_ad->prob_select_loc_min) ;
  else PRINT0("not used\n") ;
  PRINT0("abort when %d iterations are reached "
	 "and restart at most %d times\n",
	 p_ad->restart_limit, p_ad->restart_max) ;

  PrintAllCompilationOptions() ;

#if defined BACKTRACK
  /* Note: This has to be done after p_ad initialization! */
  /* Gbacktrack_array_begin = 0 ; */
  /* Gbacktrack_array_end = 0 ; */
  /* Gconfiguration_size_in_bytes = p_ad->size_in_bytes ; */
  /* for( i=0 ; i<SIZE_BACKTRACK ; i++ ) */
  /*   Gbacktrack_array[i].configuration = (unsigned int*) */
  /*     malloc(Gconfiguration_size_in_bytes) ; */
  /* YC->all: do the rest of initilization */

  gl_elitePool.config_list_begin		= NULL;
  gl_elitePool.config_list_end			= NULL;
  gl_elitePool.config_list_size			= 0;
  gl_elitePool.nb_backtrack			= 0;
  gl_elitePool.nb_variable_backtrack		= 0;
  gl_elitePool.nb_value_backtrack		= 0;

  gl_stockPool.config_list_begin		= NULL;
  gl_stockPool.config_list_end			= NULL;
  gl_stockPool.config_list_size			= 0;

  backtrack_configuration *item;
  for (i = 0; i < SIZE_BACKTRACK; i++)
    {
      item			= malloc(sizeof(backtrack_configuration));
      item->configuration	= malloc(p_ad->size_in_bytes);
      pushStock(item);
    }

#endif

  TPRINT0("%d begins its resolution!\n", my_num) ;
  TPRINT0("count = %d\n", count);


  if (count <= 0) /* Note: MPI => count=1 */
    {
      Set_Initial(p_ad);

      time_one0 = (double) User_Time();
      Solve(p_ad);
      time_one = ((double) User_Time() - time_one0) / 1000;

      if (p_ad->exhaustive)
	DPRINTF("exhaustive search\n") ;
      
      if (count < 0)
	Display_Solution(p_ad);

      Verify_Sol(p_ad);

      if (p_ad->total_cost)
	PRINTF("*** NOT SOLVED (cost of this pseudo-solution: %d) ***\n", p_ad->total_cost) ;

      if (count == 0)
	{
	  nb_same_var_by_iter = (double) p_ad->nb_same_var / p_ad->nb_iter;
	  nb_same_var_by_iter_tot = (double) p_ad->nb_same_var_tot / p_ad->nb_iter_tot;

	  PRINTF("%5d %8.2f %8d %8d %8d %8d %8.1f %8d %8d %8d %8d %8.1f", 
		 p_ad->nb_restart, time_one, 
		 p_ad->nb_iter, p_ad->nb_local_min, p_ad->nb_swap, 
		 p_ad->nb_reset, nb_same_var_by_iter,
		 p_ad->nb_iter_tot, p_ad->nb_local_min_tot, p_ad->nb_swap_tot, 
		 p_ad->nb_reset_tot, nb_same_var_by_iter_tot);
	  if (user_stat_fct)
	    PRINTF(" %8d", (*user_stat_fct)(p_ad));
	  PRINTF("\n");
	}
      else
	{
	  PRINTF("in %.2f secs (%d restarts, %d iters, %d loc min, %d swaps, %d resets)\n", 
		 time_one, p_ad->nb_restart, p_ad->nb_iter_tot, p_ad->nb_local_min_tot, 
		 p_ad->nb_swap_tot, p_ad->nb_reset_tot);
	}
#if defined BACKTRACK
      PRINTF("BACKTRACK STATS:\n");
      PRINTF("Total number of performed backtracks: %d\n", gl_elitePool.nb_backtrack);
      PRINTF("Total number of performed backtracks starting from another variable: %d\n", gl_elitePool.nb_variable_backtrack);
      PRINTF("Total number of performed backtracks starting from another value: %d\n", gl_elitePool.nb_value_backtrack);
#endif
#if defined STATS
      print_stats() ;
#endif
      return 0 ;
    } /* (count <= 0) */

  if (user_stat_name)
    sprintf(str, " %8s |", user_stat_name);
  else
    *str = '\0';

  snprintf(buff, 255,
	   "|Count|restart|     time |    iters |  loc min |    swaps "
	   "|   resets | same/iter|%s\n", str);

  if (param_needed > 0)
    PRINT0("%*d\n", (int) strlen(buff)/2, p_ad->param) ;
  else if (param_needed < 0)
    PRINT0("%*s\n", (int) strlen(buff)/2, p_ad->param_file) ;

  PRINT0("%s", buff) ;
  for(i = 0; buff[i] != '\n'; ++i)
    if (buff[i] != '|')
      buff[i] = '-';
  PRINT0("%s\n", buff) ;

  nb_restart_cum = time_cum = user_stat_cum = 0;

  nb_iter_cum = nb_local_min_cum = nb_swap_cum = nb_reset_cum = 0;
  nb_same_var_by_iter_cum = user_stat_cum = 0;


  nb_iter_tot_cum = nb_local_min_tot_cum = nb_swap_tot_cum = nb_reset_tot_cum = 0;
  nb_same_var_by_iter_tot_cum = 0;

  nb_restart_min = user_stat_min = (1 << 30);
  time_min = 1e100;
  
  nb_iter_tot_min = nb_local_min_tot_min = nb_swap_tot_min = nb_reset_tot_min = (1 << 30);
  nb_same_var_by_iter_tot_min = 1e100;

  nb_restart_max = user_stat_max = 0;
  time_max = 0;
 
  nb_iter_tot_max = nb_local_min_tot_max = nb_swap_tot_max = nb_reset_tot_max = 0;
  nb_same_var_by_iter_tot_max = 0;


  for(i = 1; i <= count; i++)
    {
      Set_Initial(p_ad);

      time_one0 = (double) User_Time();
      Solve(p_ad);
      time_one = ((double) User_Time() - time_one0) / 1000;

#if !defined MPI /* Slashes MPI output! */
      if (disp_mode == 2 && nb_restart_cum > 0)
	PRINTF("\033[A\033[K");
      PRINTF("\033[A\033[K\033[A\033[256D");
#endif

      Verify_Sol(p_ad);

      if (user_stat_fct)
	user_stat = (*user_stat_fct)(p_ad);


      nb_same_var_by_iter = (double) p_ad->nb_same_var / p_ad->nb_iter;
      nb_same_var_by_iter_tot = (double) p_ad->nb_same_var_tot / p_ad->nb_iter_tot;

      nb_restart_cum += p_ad->nb_restart;
      time_cum += time_one;
      nb_iter_cum += p_ad->nb_iter;
      nb_local_min_cum += p_ad->nb_local_min;
      nb_swap_cum += p_ad->nb_swap;
      nb_reset_cum += p_ad->nb_reset;
      nb_same_var_by_iter_cum += nb_same_var_by_iter;
      user_stat_cum += user_stat;

      nb_iter_tot_cum += p_ad->nb_iter_tot;
      nb_local_min_tot_cum += p_ad->nb_local_min_tot;
      nb_swap_tot_cum += p_ad->nb_swap_tot;
      nb_reset_tot_cum += p_ad->nb_reset_tot;
      nb_same_var_by_iter_tot_cum += nb_same_var_by_iter_tot;

      if (nb_restart_min > p_ad->nb_restart)
	nb_restart_min = p_ad->nb_restart;
      if (time_min > time_one)
	time_min = time_one;
      if (nb_iter_tot_min > p_ad->nb_iter_tot)
	nb_iter_tot_min = p_ad->nb_iter_tot;
      if (nb_local_min_tot_min > p_ad->nb_local_min_tot)
	nb_local_min_tot_min = p_ad->nb_local_min_tot;
      if (nb_swap_tot_min > p_ad->nb_swap_tot)
	nb_swap_tot_min = p_ad->nb_swap_tot;
      if (nb_reset_tot_min > p_ad->nb_reset_tot)
	nb_reset_tot_min = p_ad->nb_reset_tot;
      if (nb_same_var_by_iter_tot_min > nb_same_var_by_iter_tot)
	nb_same_var_by_iter_tot_min = nb_same_var_by_iter_tot;
      if (user_stat_min > user_stat)
	user_stat_min = user_stat;

      if (nb_restart_max < p_ad->nb_restart)
	nb_restart_max = p_ad->nb_restart;
      if (time_max < time_one)
	time_max = time_one;
      if (nb_iter_tot_max < p_ad->nb_iter_tot)
	nb_iter_tot_max = p_ad->nb_iter_tot;
      if (nb_local_min_tot_max < p_ad->nb_local_min_tot)
	nb_local_min_tot_max = p_ad->nb_local_min_tot;
      if (nb_swap_tot_max < p_ad->nb_swap_tot)
	nb_swap_tot_max = p_ad->nb_swap_tot;
      if (nb_reset_tot_max < p_ad->nb_reset_tot)
	nb_reset_tot_max = p_ad->nb_reset_tot;
      if (nb_same_var_by_iter_tot_max < nb_same_var_by_iter_tot)
	nb_same_var_by_iter_tot_max = nb_same_var_by_iter_tot;
      if (user_stat_max < user_stat)
	user_stat_max = user_stat;
  
#if !defined(MPI)
      switch(disp_mode)
	{
	case 0:			/* only last iter counters */
	case 2:			/* last iter followed by restart if needed */
	  PRINTF("|%4d | %5d%c| %8.2f | %8d | %8d | %8d | %8d | %8.1f |",
		 i, p_ad->nb_restart, (p_ad->total_cost == 0) ? ' ' : 'N',
		 time_one,
		 p_ad->nb_iter, p_ad->nb_local_min, p_ad->nb_swap,
		 p_ad->nb_reset, nb_same_var_by_iter);
	  if (user_stat_fct)
	    PRINTF(" %8d |", user_stat);
	  PRINTF("\n");

	  if (disp_mode == 2 && p_ad->nb_restart > 0) 
	    {
	      PRINTF("|     |       |          |"
		     " %8d | %8d | %8d | %8d | %8.1f |",
		     p_ad->nb_iter_tot, p_ad->nb_local_min_tot,
		     p_ad->nb_swap_tot,
		     p_ad->nb_reset_tot, nb_same_var_by_iter_tot);
	      if (user_stat_fct)
		PRINTF("          |");
	      PRINTF("\n");
	    }

	  PRINTF("%s", buff);

	  PRINTF("| avg | %5d | %8.2f | %8d | %8d | %8d | %8d | %8.1f |",
		 nb_restart_cum / i, time_cum / i,
		 nb_iter_cum / i, nb_local_min_cum / i, nb_swap_cum / i,
		 nb_reset_cum / i, nb_same_var_by_iter_cum / i);
	  if (user_stat_fct)
	    PRINTF(" %8.2f |", (double) user_stat_cum / i);
	  PRINTF("\n");


	  if (disp_mode == 2 && nb_restart_cum > 0) 
	    {
	      PRINTF("|     |       |          |"
		     " %8d | %8d | %8d | %8d | %8.1f |",
		     nb_iter_tot_cum / i, nb_local_min_tot_cum / i,
		     nb_swap_tot_cum / i,
		     nb_reset_tot_cum / i, nb_same_var_by_iter_tot_cum / i);
	      if (user_stat_fct)
		PRINTF("          |");
	      PRINTF("\n");
	    }
	  break;

	case 1:			/* only total (restart + last iter) counters */
	  PRINTF("|%4d | %5d%c| %8.2f | %8d | %8d | %8d | %8d | %8.1f |",
		 i, p_ad->nb_restart, (p_ad->total_cost == 0) ? ' ' : 'N',
		 time_one,
		 p_ad->nb_iter_tot, p_ad->nb_local_min_tot, p_ad->nb_swap_tot,
		 p_ad->nb_reset_tot, nb_same_var_by_iter_tot);
	  if (user_stat_fct)
	    PRINTF(" %8d |", user_stat);
	  PRINTF("\n");

	  PRINTF("%s", buff);

	  PRINTF("| avg | %5d | %8.2f | %8d | %8d | %8d | %8d | %8.1f |",
		 nb_restart_cum / i, time_cum / i,
		 nb_iter_tot_cum / i, nb_local_min_tot_cum / i,
		 nb_swap_tot_cum / i,
		 nb_reset_tot_cum / i, nb_same_var_by_iter_tot_cum / i);
	  if (user_stat_fct)
	    PRINTF(" %8.2f |", (double) user_stat_cum / i);
	  PRINTF("\n");
	  break;
	}
#else /* MPI */
      /* disp_mode equals 1 by default */
      /* Prepare what will be sent to 0, and/or printed by 0 */
      snprintf(mpi_data.results, RESULTS_CHAR_MSG_SIZE - 1,
	       "|* %ld/(%d/%d) | %5d | %8.2f | %8d | %8d | %8d | %8d | %8.1f |",
	       print_seed,
	       my_num,
	       mpi_size,
	       nb_restart_cum / i, time_cum / i,
	       nb_iter_tot_cum / i, nb_local_min_tot_cum / i,
	       nb_swap_tot_cum / i,
	       nb_reset_tot_cum / i, nb_same_var_by_iter_tot_cum / i);
      /* TODO: use if(user_stat_fct)? What is that? */
#endif /* MPI */
    } /* for(i = 1; i <= count; i++) */

  if (count <= 0) /* YC->DD: is it really possible here? return 0 before.*/
    return 0;

  if( count > 1 ) { /* YC->DD: why this test has been removed? */
    PRINTF("| min | %5d | %8.2f | %8d | %8d | %8d | %8d | %8.1f |",
	   nb_restart_min, time_min,
	   nb_iter_tot_min, nb_local_min_tot_min, nb_swap_tot_min,
	   nb_reset_tot_min, nb_same_var_by_iter_tot_min);
    if (user_stat_fct)
      PRINTF(" %8d |", user_stat_min);
    PRINTF("\n");

    PRINTF("| max | %5d | %8.2f | %8d | %8d | %8d | %8d | %8.1f |",
	   nb_restart_max, time_max,
	   nb_iter_tot_max, nb_local_min_tot_max, nb_swap_tot_max,
	   nb_reset_tot_max, nb_same_var_by_iter_tot_max);
    if (user_stat_fct)
      PRINTF(" %8d |", user_stat_max);
    PRINTF("\n");
  }

#if defined BACKTRACK
  PRINTF("BACKTRACK STATS:\n");
  PRINTF("Total number of performed backtracks: %d\n", gl_elitePool.nb_backtrack);
  PRINTF("Total number of performed backtracks starting from another variable: %d\n", gl_elitePool.nb_variable_backtrack);
  PRINTF("Total number of performed backtracks starting from another value: %d\n", gl_elitePool.nb_value_backtrack);

  /* flush pools */
  while(gl_elitePool.config_list_size > 0)
    {
      item = popElite();
      free(item->configuration);
      free(item);
    }
  while(gl_stockPool.config_list_size > 0)
    {
      item = popStock();
      free(item->configuration);
      free(item);
    }
#endif /* BACKTRACK */

#if defined STATS
  print_stats() ;
#endif

#if !( defined MPI )
#if defined PRINT_COSTS
  print_costs() ;
#endif
  TDPRINTF("Processus ends now.\n") ;   /* Seq code is now ending */
#else /* !( defined MPI) */
  AS_MPI_completion( &mpi_data ) ;
#endif /* MPI */
}