Esempio n. 1
0
static void calc_checksum(char *name)
{
  long64 orig_size;

  if (!work) work = alloc_work(total_work);

  data = map_file(name, 0, &size);
  orig_size = size;
  if ((size & 0x3f) == 0x10) {
    size &= ~0x3fULL;
    memcpy(checksum1, data + size, 16);
    checksum_found = 1;
  } else {
    if (size & 0x3f) {
      printf("Size of %s is not a multiple of 64.\n", name);
      exit(1);
    }
    checksum_found = 0;
  }

  int chunks = (size + CHUNK - 1) / CHUNK;
  results = (uint64 *)malloc(32 * chunks);
  fill_work(total_work, chunks, 0, work);
  run_threaded(checksum_worker, work, 0);
  CityHashCrc128((char *)results, 32 * chunks, checksum2);
  unmap_file(data, orig_size);
  free(results);

  if (checksum_found)
    checksum_match = (checksum1[0] == checksum2[0]
			&& checksum1[1] == checksum2[1]);
}
Esempio n. 2
0
void verify_stats(ubyte *table, long64 *tot_stats, struct dtz_map *map)
{
  long64 stats[256];
  long64 stats2[256];
  int i, j;
  ubyte (*inv_map)[256] = map->inv_map;

  for (i = 0; i < 256; i++)
    stats[i] = stats2[i] = 0;

  for (i = 0; i < 256 * numthreads; i++)
    thread_stats[i] = 0;
  count_stats_table = table;
  run_threaded(count_stats, work_g, 0);
  for (i = 0; i < numthreads; i++)
    for (j = 0; j < 256; j++)
      stats[j] += thread_data[i].stats[j];

  stats2[inv_map[0][0]] = tot_stats[0];
  stats2[inv_map[1][0]] = tot_stats[STAT_MATE];
  if (map->ply_accurate_win)
    for (i = 0; i < DRAW_RULE; i++)
      stats2[inv_map[0][i]] += tot_stats[i + 1];
  else
    for (i = 0; i < DRAW_RULE; i++)
      stats2[inv_map[0][i / 2]] += tot_stats[i + 1];
  if (map->ply_accurate_loss)
    for (i = 0; i < DRAW_RULE; i++)
      stats2[inv_map[1][i]] += tot_stats[STAT_MATE - 1 - i];
  else
    for (i = 0; i < DRAW_RULE; i++)
      stats2[inv_map[1][i / 2]] += tot_stats[STAT_MATE - 1 - i];
  for (i = DRAW_RULE + 1; i < MAX_PLY; i++) {
    stats2[inv_map[2][(i - DRAW_RULE - 1) / 2]] += tot_stats[i];
    stats2[inv_map[3][(i - DRAW_RULE - 1) / 2]] += tot_stats[STAT_MATE - i];
  }

  int verify_ok = 1;
  for (i = 0; i < 256; i++)
    if (stats[i] != stats2[i] && i != map->max_num) {
      printf("stats[%d] = %"PRIu64"; stats2[%d] = %"PRIu64"\n",
		    i, stats[i], i, stats2[i]);
      int j;
      for (j = 0; j < 4; j++)
	printf("map[%d][%d]=%d\n", j, i, map->map[j][i]);
      verify_ok = 0;
    }

  if (!verify_ok) {
    fprintf(stderr, "Verification of reconstructed table failed.\n");
    exit(1);
  }
}
Esempio n. 3
0
long64 find_val(ubyte *table, ubyte v, long64 *work)
{
  found_idx = 0xffffffffffffffffULL;
  find_val_table = table;
  find_val_v = v;

  run_threaded(find_loop, work, 0);

  if (found_idx == 0xffffffffffffffffULL)
    fprintf(stderr, "find_val: not found!\n");

  return found_idx;
}
Esempio n. 4
0
int main(int argc, const char * argv[])
{
    // Too few arguments specified.
    if (argc < 2) {
        print_usage();
        return 0;
    }
    
    // One argument specified, should only be the interactive mode.
    if (argc == 2) {
        if (!strcmp("-i", argv[1])) {
            run_interactive();
            return 0;
        }
        
        print_usage();
        return 0;
    }
    
    // Two arguments. The first should either be the demonstration or worker flag.
    // The second is assumed to be a file path; errors with that are handled further down.
    if (argc == 3) {
        if (!strcmp("-d", argv[1])) {
            run_multiprocess(argv);
            return 0;
        }
        
        if (!strcmp("-w", argv[1])) {
            run_worker(argv);
            return 0;
        }
        
        if (!strcmp("-t", argv[1])) {
            run_threaded(argv[2]);
            return 0;
        }
        
        print_usage();
        return 0;
    }
    
    // Anything more and it was used wrong.
    print_usage();
    return 0;
}
Esempio n. 5
0
File: reduce.c Progetto: Albitex/tb
void reduce_tables(void)
{
  int i;
  ubyte v[256];

  if (!copybuf)
    copybuf = malloc(COPYSIZE);

  collect_stats(0);

  if (generate_dtz) {
    save_table(table_w, 'w');
    if (!symmetric)
      save_table(table_b, 'b');
  }

  for (i = 0; i < 256; i++)
    v[i] = 0;

#ifndef SUICIDE
  v[BROKEN] = BROKEN;
  v[UNKNOWN] = UNKNOWN;
  v[CHANGED] = CHANGED;
  v[CAPT_DRAW] = CAPT_DRAW;
  v[MATE] = MATE;
  v[ILLEGAL] = ILLEGAL;
  v[CAPT_WIN] = CAPT_WIN;
  if (num_saves == 0) {
    for (i = 0; i < DRAW_RULE; i++) {
      v[WIN_IN_ONE + i] = WIN_IN_ONE;
      v[LOSS_IN_ONE - i] = MATE;
    }
    v[CAPT_CWIN] = CAPT_CWIN_RED;
    for (; i < REDUCE_PLY - 2; i++) {
      v[WIN_IN_ONE + i + 1] = CAPT_CWIN_RED + 1;
      v[LOSS_IN_ONE - i] = LOSS_IN_ONE;
    }
    v[LOSS_IN_ONE - i] = LOSS_IN_ONE;
    v[WIN_IN_ONE + REDUCE_PLY - 1] = CAPT_CWIN_RED + 2;
    v[WIN_IN_ONE + REDUCE_PLY] = CAPT_CWIN_RED + 3;
    v[WIN_IN_ONE + REDUCE_PLY + 1] = CAPT_CWIN_RED + 4;
    v[LOSS_IN_ONE - REDUCE_PLY + 1] = LOSS_IN_ONE - 1;
  } else {
    v[WIN_IN_ONE] = WIN_IN_ONE;
    v[LOSS_IN_ONE] = LOSS_IN_ONE;
    v[CAPT_CWIN_RED] = CAPT_CWIN_RED;
    v[CAPT_CWIN_RED + 1] = CAPT_CWIN_RED + 1;
    for (i = 0; i < REDUCE_PLY_RED; i++) {
      v[CAPT_CWIN_RED + i + 2] = CAPT_CWIN_RED + 1;
      v[LOSS_IN_ONE - i - 1] = LOSS_IN_ONE;
    }
    v[CAPT_CWIN_RED + REDUCE_PLY_RED + 2] = CAPT_CWIN_RED + 2;
    v[CAPT_CWIN_RED + REDUCE_PLY_RED + 3] = CAPT_CWIN_RED + 3;
    v[CAPT_CWIN_RED + REDUCE_PLY_RED + 4] = CAPT_CWIN_RED + 4;
    v[LOSS_IN_ONE - REDUCE_PLY_RED - 1] = LOSS_IN_ONE - 1;
  }
#else
  v[BROKEN] = BROKEN;
  v[UNKNOWN] = UNKNOWN;
  v[CHANGED] = CHANGED;
  v[CAPT_WIN] = CAPT_WIN;
  v[CAPT_CWIN] = CAPT_CWIN;
  v[CAPT_DRAW] = CAPT_DRAW;
  v[CAPT_CLOSS] = CAPT_CLOSS;
  v[CAPT_LOSS] = CAPT_LOSS;
  v[THREAT_WIN] = THREAT_WIN;
  if (num_saves == 0) {
    for (i = 3; i <= DRAW_RULE; i++)
      v[BASE_WIN + i] = BASE_WIN + 3;
    v[THREAT_CWIN1] = BASE_WIN + 4;
    v[THREAT_CWIN2] = BASE_WIN + 4;
    v[BASE_WIN + DRAW_RULE + 1] = BASE_WIN + 5;
    for (i = DRAW_RULE + 2; i < REDUCE_PLY; i++)
      v[BASE_WIN + i + 2] = BASE_WIN + 5;
    for (i = 2; i <= DRAW_RULE; i++)
      v[BASE_LOSS - i] = BASE_LOSS - 2;
    for (; i < REDUCE_PLY; i++)
      v[BASE_LOSS - i] = BASE_LOSS - 3;
    v[BASE_WIN + REDUCE_PLY + 2] = BASE_WIN + 6;
    v[BASE_WIN + REDUCE_PLY + 3] = BASE_WIN + 7;
    v[BASE_LOSS - REDUCE_PLY] = BASE_LOSS - 4;
  } else {
    v[BASE_WIN + 3] = BASE_WIN + 3;
    v[BASE_WIN + 4] = BASE_WIN + 4;
    v[BASE_WIN + 5] = BASE_WIN + 5;
    v[BASE_LOSS - 2] = BASE_LOSS - 2;
    v[BASE_LOSS - 3] = BASE_LOSS - 3;
    for (i = 0; i < REDUCE_PLY_RED; i++) {
      v[BASE_WIN + i + 6] = BASE_WIN + 5;
      v[BASE_LOSS - i - 4] = BASE_LOSS - 3;
    }
    v[BASE_WIN + REDUCE_PLY_RED + 6] = BASE_WIN + 6;
    v[BASE_WIN + REDUCE_PLY_RED + 7] = BASE_WIN + 7;
    v[BASE_LOSS - REDUCE_PLY_RED - 4] = BASE_LOSS - 4;
  }
#endif

  transform_v = v;
  run_threaded(transform, work_g, 1);

  if (num_saves == 0)
    reduce_cnt = REDUCE_PLY - DRAW_RULE - 2;
  else
    reduce_cnt += REDUCE_PLY_RED;
}
Esempio n. 6
0
File: reduce.c Progetto: Albitex/tb
void reconstruct_table(ubyte *table, char color, struct dtz_map *map)
{
  int i, k;
  int num = map->max_num;
  ubyte (*inv_map)[256] = map->inv_map;
  ubyte v[256];

  for (i = 0; i < 256; i++)
    v[i] = 0;

#ifndef SUICIDE
  v[ILLEGAL] = num;
  v[BROKEN] = num;
  v[UNKNOWN] = num;
  v[CAPT_DRAW] = num;
  v[CAPT_CWIN_RED] = num;
  v[CAPT_WIN] = num;
  for (i = 0; i <= REDUCE_PLY_RED; i++) {
    v[CAPT_CWIN_RED + i + 2] = inv_map[2][(reduce_cnt + i) / 2];
    v[LOSS_IN_ONE - i - 1] = inv_map[3][(reduce_cnt + i + 1) / 2];
  }
  v[CAPT_CWIN_RED + i + 2] = inv_map[2][(reduce_cnt + i) / 2];
#else
  v[BROKEN] = num;
  v[UNKNOWN] = num;
  v[CAPT_WIN] = v[CAPT_CWIN] = v[CAPT_DRAW] = num;
  v[CAPT_CLOSS] = v[CAPT_LOSS] = num;
  v[THREAT_WIN] = v[BASE_WIN + 4] = v[THREAT_DRAW] = num;
  for (i = 0; i <= REDUCE_PLY_RED; i++) {
    v[BASE_WIN + i + 6] = inv_map[2][(reduce_cnt + i) / 2];
    v[BASE_LOSS - i - 4] = inv_map[3][(reduce_cnt + i) / 2];
  }
#endif

  transform_v = v;
  transform_tbl = table;
  run_threaded(transform_table, work_g, 0);

  v[0] = 0;
  int red_cnt = 0;
#ifndef SUICIDE
  for (k = 0; k < num_saves; k++) {
    if (k == 0) {
      v[255] = inv_map[1][0];
      if (map->ply_accurate_win)
	for (i = 0; i < DRAW_RULE; i++)
	  v[i + 1] = inv_map[0][i];
      else
	for (i = 0; i < DRAW_RULE; i++)
	  v[i + 1] = inv_map[0][i / 2];
      if (map->ply_accurate_loss)
	for (i = 0; i < DRAW_RULE; i++)
	  v[254 - i] = inv_map[1][i];
      else
	for (i = 0; i < DRAW_RULE; i++)
	  v[254 - i] = inv_map[1][i / 2];
      for (; i <= REDUCE_PLY; i += 2) {
	v[1 + DRAW_RULE + (i - DRAW_RULE) / 2] = inv_map[2][(i - DRAW_RULE) / 2];
	v[254 - DRAW_RULE - (i - DRAW_RULE) / 2] = inv_map[3][(i - DRAW_RULE) / 2];
      }
      red_cnt = REDUCE_PLY - DRAW_RULE - 2;
    } else {
      for (i = 0; i <= REDUCE_PLY_RED + 1; i += 2) {
	v[1 + ((red_cnt & 1) + i) / 2] = inv_map[2][(red_cnt + i) / 2];
	v[255 - ((red_cnt & 1) + i + 1) / 2] = inv_map[3][(red_cnt + i + 1) / 2];
      }
      red_cnt += REDUCE_PLY_RED;
    }
    reconstruct_table_pass(table, color, k, v);
  }
#else
  for (k = 0; k < num_saves; k++) {
    if (k == 0) {
      if (map->ply_accurate_win)
	for (i = 3; i <= DRAW_RULE; i++)
	  v[1 + (i - 3)] = inv_map[0][i - 1];
      else
	for (i = 3; i <= DRAW_RULE; i++)
	  v[1 + (i - 3)] = inv_map[0][(i - 1) / 2];
      if (map->ply_accurate_loss)
	for (i = 2; i <= DRAW_RULE; i++)
	  v[255 - (i - 2)] = inv_map[1][i - 1];
      else
	for (i = 2; i <= DRAW_RULE; i++)
	  v[255 - (i - 2)] = inv_map[1][(i - 1) / 2];
      for (i = DRAW_RULE + 1; i < REDUCE_PLY; i++) {
	v[DRAW_RULE - 1 + (i - DRAW_RULE - 1) / 2] = inv_map[2][(i - DRAW_RULE - 1) / 2];
	v[254 - (DRAW_RULE - 2) - (i - DRAW_RULE - 1) / 2] = inv_map[3][(i - DRAW_RULE - 1) / 2];
      }
      red_cnt = REDUCE_PLY - 1 - DRAW_RULE;
    } else {
      for (i = 0; i < REDUCE_PLY_RED; i += 2) {
	v[1 + ((red_cnt & 1) + i) / 2] = inv_map[2][(red_cnt + i) / 2];
	v[255 - ((red_cnt & 1) + i) / 2] = inv_map[3][(red_cnt + i) / 2];
      }
      red_cnt += REDUCE_PLY_RED;
    }
    reconstruct_table_pass(table, color, k, v);
  }
#endif

  if (color == 'w') {
    printf("Verifying reconstructed table_w based on collected statistics.\n");
    verify_stats(table_w, total_stats_w, map);
  } else {
    printf("Verifying reconstructed table_b based on collected statistics.\n");
    verify_stats(table_b, total_stats_b, map);
  }
}
Esempio n. 7
0
void collect_stats_table(long64 *total_stats, ubyte *table, int wtm, int phase, int local, long64 *work)
{
  int i, j;
  int n;
  int sval;

  sval = (local == 0) ? 0 : stats_val[local - 1];

  for (i = 0; i < 256 * numthreads; i++)
    thread_stats[i] = 0;

  count_stats_table = table;
  run_threaded(count_stats, work, 0);

  if (local == 0)
    n = REDUCE_PLY - 2;
  else
    n = REDUCE_PLY_RED;
  if (phase == 1) n += 2;

#ifndef SUICIDE
  for (i = 0; i < numthreads; i++) {
    long64 *stats = thread_data[i].stats;
    if (local == 0) {
      total_stats[STAT_CAPT_WIN] += stats[CAPT_WIN];
      total_stats[STAT_CAPT_CWIN] += stats[CAPT_CWIN];
      total_stats[STAT_PAWN_WIN] += stats[PAWN_WIN];
      total_stats[STAT_PAWN_CWIN] += stats[PAWN_CWIN];
      total_stats[STAT_MATE] += stats[MATE];
      for (j = 0; j < DRAW_RULE; j++) {
	total_stats[1 + j] += stats[WIN_IN_ONE + j];
	total_stats[STAT_MATE - 1 - j] += stats[LOSS_IN_ONE - j];
      }
      for (; j < n; j++) {
	total_stats[1 + j] += stats[WIN_IN_ONE + j + 2];
	total_stats[STAT_MATE - 1 - j] += stats[LOSS_IN_ONE - j];
      }
      total_stats[STAT_MATE - 1 - j] += stats[LOSS_IN_ONE - j];
    } else {
      for (j = 0; j < n; j++) {
	total_stats[1 + sval + j] += stats[CAPT_CWIN_RED + j + 2];
	total_stats[STAT_MATE - 1 - sval - j - 1] += stats[LOSS_IN_ONE - j - 1];
      }
    }
  }
#else
  for (i = 0; i < numthreads; i++) {
    long64 *stats = thread_data[i].stats;
    if (local == 0) {
      total_stats[0] += stats[STALE_WIN];
      total_stats[1] += stats[STALE_WIN + 1];
      for (j = 2; j <= DRAW_RULE + 1; j++)
	total_stats[j] += stats[BASE_WIN + j];
      for (; j < REDUCE_PLY; j++)
	total_stats[j] += stats[BASE_WIN + j + 2];
      for (j = 0; j < REDUCE_PLY; j++)
	total_stats[STAT_MATE - j] += stats[BASE_LOSS - j];
      total_stats[STAT_CAPT_WIN] += stats[CAPT_WIN];
      total_stats[STAT_CAPT_CWIN] += stats[CAPT_CWIN];
      total_stats[STAT_CAPT_DRAW] += stats[CAPT_DRAW];
      total_stats[STAT_CAPT_LOSS] += stats[CAPT_LOSS];
      total_stats[STAT_CAPT_CLOSS] += stats[CAPT_CLOSS];
      total_stats[STAT_THREAT_WIN2] += stats[THREAT_WIN2];
      total_stats[STAT_THREAT_WIN1] += stats[THREAT_WIN1];
      total_stats[STAT_THREAT_CWIN2] += stats[THREAT_CWIN2];
      total_stats[STAT_THREAT_CWIN1] += stats[THREAT_CWIN1];
    } else {
      for (j = 0; j < n; j++) {
	total_stats[sval + j] += stats[BASE_CWIN_RED + 1 + j];
	total_stats[STAT_MATE - sval - j] += stats[BASE_CLOSS_RED -1 - j];
      }
    }
  }
#endif

  if (local == 0) {
    for (i = DRAW_RULE; i >= 0; i--)
      if (total_stats[i]) break;
    if (i >= 0) {
#ifndef SUICIDE
      j = WIN_IN_ONE + i - 1;
#else
      j = (i < 2) ? STALE_WIN + i : BASE_WIN + i;
#endif
      if (wtm) {
	if (i > lw_ply) {
	  lw_ply = i;
	  lw_clr = 1;
	  lw_idx = find_val(table, j, work);
	}
      } else {
	if (i > lb_ply) {
	  lb_ply = i;
	  lb_clr = 0;
	  lb_idx = find_val(table, j, work);
	}
      }
    }
    for (i = DRAW_RULE; i >= 0; i--)
      if (total_stats[STAT_MATE - i]) break;
    if (i >= 0) {
#ifndef SUICIDE
      j = MATE - i;
#else
      j = BASE_LOSS - i;
#endif
      if (wtm) {
	if (i > lb_ply) {
	  lb_ply = i;
	  lb_clr = 1;
	  lb_idx = find_val(table, j, work);
	}
      } else {
	if (i > lw_ply) {
	  lw_ply = i;
	  lw_clr = 0;
	  lw_idx = find_val(table, j, work);
	}
      }
    }
  }

  for (i = MAX_PLY; i > DRAW_RULE; i--)
    if (total_stats[i]) break;
  if (i > DRAW_RULE) {
#ifndef SUICIDE
    if (local == 0)
      j = WIN_IN_ONE + i + 1;
    else
      j = CAPT_CWIN_RED + 1 + i - sval;
#else
    if (local == 0)
      j = (i == DRAW_RULE + 1) ? BASE_WIN + i : BASE_WIN + i + 2;
    else
      j = BASE_CWIN_RED + i + 1 - sval;
#endif
    if (wtm) {
      if (i > lcw_ply) {
	lcw_ply = i;
	lcw_clr = 1;
	lcw_idx = find_val(table, j, work);
      }
    } else {
      if (i > lcb_ply) {
	lcb_ply = i;
	lcb_clr = 0;
	lcb_idx = find_val(table, j, work);
      }
    }
  }

  for (i = MAX_PLY; i > DRAW_RULE; i--)
    if (total_stats[STAT_MATE - i]) break;
  if (i > DRAW_RULE) {
#ifndef SUICIDE
    j = MATE - i + sval;
#else
    if (local == 0)
      j = BASE_LOSS - i;
    else
      j = BASE_CLOSS_RED - 1 - i + sval;
#endif
    if (wtm) {
      if (i > lcb_ply) {
	lcb_ply = i;
	lcb_clr = 1;
	lcb_idx = find_val(table, j, work);
      }
    } else {
      if (i > lcw_ply) {
	lcw_ply = i;
	lcw_clr = 0;
	lcw_idx = find_val(table, j, work);
      }
    }
  }

#ifndef SUICIDE
  if (phase == 1)
    for (i = 0; i < numthreads; i++) {
      total_stats[STAT_DRAW] += thread_data[i].stats[UNKNOWN];
      total_stats[STAT_DRAW] += thread_data[i].stats[PAWN_DRAW];
      total_stats[STAT_CAPT_DRAW] += thread_data[i].stats[CAPT_DRAW];
    }
#else
  if (phase == 1)
    for (i = 0; i < numthreads; i++) {
      total_stats[STAT_DRAW] += thread_data[i].stats[UNKNOWN];
      total_stats[STAT_DRAW] += thread_data[i].stats[PAWN_DRAW];
      total_stats[STAT_THREAT_DRAW] += thread_data[i].stats[THREAT_DRAW];
    }
#endif
}
Esempio n. 8
0
void reduce_tables(int local)
{
  int i;
  ubyte v[256];
  long64 *work;
  long64 save_begin = begin;

  if (!copybuf)
    copybuf = malloc(COPYSIZE);

  if (local == num_saves) {
    work = work_part;
    fill_work(total_work, begin + (1ULL << shift[numpawns - 1]), 0, work);
    begin = 0;
    reduce_val[local] = ply;
    work = work_part;
  } else
    work = work_p;

  collect_stats(work, 0, local);

  if (generate_dtz) {
    save_table(table_w, 'w', local, begin, work[total_work]);
    if (!symmetric)
      save_table(table_b, 'b', local, begin, work[total_work]);
  }

  for (i = 0; i < 256; i++)
    v[i] = 0;

#ifndef SUICIDE
  v[BROKEN] = BROKEN;
  v[UNKNOWN] = UNKNOWN;
  v[CHANGED] = CHANGED;
  v[CAPT_DRAW] = CAPT_DRAW;
  v[PAWN_DRAW] = PAWN_DRAW;
  v[MATE] = MATE;
  v[ILLEGAL] = ILLEGAL;
  v[CAPT_WIN] = CAPT_WIN;
  if (local == 0) {
    v[PAWN_WIN] = WIN_RED;
    for (i = 0; i < DRAW_RULE; i++) {
      v[WIN_IN_ONE + i] = WIN_RED;
      v[LOSS_IN_ONE - i] = MATE;
    }
    v[CAPT_CWIN] = CAPT_CWIN_RED;
    v[PAWN_CWIN] = CAPT_CWIN_RED + 1;
    for (; i < REDUCE_PLY - 2; i++) {
      v[WIN_IN_ONE + i + 2] = CAPT_CWIN_RED + 1;
      v[LOSS_IN_ONE - i] = LOSS_IN_ONE;
    }
    v[LOSS_IN_ONE - i] = LOSS_IN_ONE;
    v[WIN_IN_ONE + REDUCE_PLY] = CAPT_CWIN_RED + 2;
    v[WIN_IN_ONE + REDUCE_PLY + 1] = CAPT_CWIN_RED + 3;
    v[WIN_IN_ONE + REDUCE_PLY + 2] = CAPT_CWIN_RED + 4;
    v[LOSS_IN_ONE - REDUCE_PLY + 1] = LOSS_IN_ONE - 1;
  } else {
    v[WIN_RED] = WIN_RED;
    v[LOSS_IN_ONE] = LOSS_IN_ONE;
    v[CAPT_CWIN_RED] = CAPT_CWIN_RED;
    v[CAPT_CWIN_RED + 1] = CAPT_CWIN_RED + 1;
    for (i = 0; i < REDUCE_PLY_RED; i++) {
      v[CAPT_CWIN_RED + i + 2] = CAPT_CWIN_RED + 1;
      v[LOSS_IN_ONE - i - 1] = LOSS_IN_ONE;
    }
    v[CAPT_CWIN_RED + REDUCE_PLY_RED + 2] = CAPT_CWIN_RED + 2;
    v[CAPT_CWIN_RED + REDUCE_PLY_RED + 3] = CAPT_CWIN_RED + 3;
    v[CAPT_CWIN_RED + REDUCE_PLY_RED + 4] = CAPT_CWIN_RED + 4;
    v[LOSS_IN_ONE - REDUCE_PLY_RED - 1] = LOSS_IN_ONE - 1;
  }
#else
  v[BROKEN] = BROKEN;
  v[UNKNOWN] = UNKNOWN;
  v[CHANGED] = CHANGED;
  v[CAPT_WIN] = CAPT_WIN;
  v[CAPT_CWIN] = CAPT_CWIN;
  v[CAPT_DRAW] = CAPT_DRAW;
  v[CAPT_CLOSS] = CAPT_CLOSS;
  v[CAPT_LOSS] = CAPT_LOSS;
  v[PAWN_DRAW] = PAWN_DRAW;
  if (local == 0) {
    v[THREAT_WIN1] = THREAT_WIN_RED;
    v[THREAT_WIN2] = THREAT_WIN_RED;
    v[STALE_WIN] = BASE_WIN_RED;
    v[STALE_WIN + 1] = BASE_WIN_RED;
    for (i = 2; i <= DRAW_RULE; i++)
      v[BASE_WIN + i] = BASE_WIN_RED;
    v[THREAT_CWIN1] = THREAT_CWIN_RED;
    v[THREAT_CWIN2] = THREAT_CWIN_RED;
    v[BASE_WIN + DRAW_RULE + 1] = BASE_CWIN_RED;
    for (i = DRAW_RULE + 2; i < REDUCE_PLY; i++)
      v[BASE_WIN + i + 2] = BASE_CWIN_RED;
    for (i = 0; i <= DRAW_RULE; i++)
      v[BASE_LOSS - i] = BASE_LOSS_RED;
    for (; i < REDUCE_PLY; i++)
      v[BASE_LOSS - i] = BASE_CLOSS_RED;
    v[BASE_WIN + REDUCE_PLY + 2] = BASE_CWIN_RED + 1;
    v[BASE_WIN + REDUCE_PLY + 3] = BASE_CWIN_RED + 2;
    v[BASE_LOSS - REDUCE_PLY] = BASE_CLOSS_RED - 1;
  } else {
    v[THREAT_WIN_RED] = THREAT_WIN_RED;
    v[BASE_WIN_RED] = BASE_WIN_RED;
    v[THREAT_CWIN_RED] = THREAT_CWIN_RED;
    v[BASE_CWIN_RED] = BASE_CWIN_RED;
    v[BASE_LOSS_RED] = BASE_LOSS_RED;
    v[BASE_CLOSS_RED] = BASE_CLOSS_RED;
    for (i = 0; i < REDUCE_PLY_RED; i++) {
      v[BASE_CWIN_RED + i + 1] = BASE_CWIN_RED;
      v[BASE_CLOSS_RED - i - 1] = BASE_CLOSS_RED;
    }
    v[BASE_CWIN_RED + REDUCE_PLY_RED + 1] = BASE_CWIN_RED + 1;
    v[BASE_CWIN_RED + REDUCE_PLY_RED + 2] = BASE_CWIN_RED + 2;
    v[BASE_CLOSS_RED - REDUCE_PLY_RED - 1] = BASE_CLOSS_RED - 1;
  }
#endif

  transform_v = v;
  run_threaded(transform, work, 0);

  if (local == num_saves) {
    if (num_saves == 0)
      reduce_cnt[0] = ply - DRAW_RULE - 2;
    else
      reduce_cnt[num_saves] = reduce_cnt[num_saves - 1] + ply;
    begin = save_begin;
    num_saves++;
  }
}
Esempio n. 9
0
File: tbver.c Progetto: prvn16/tb
int main(int argc, char **argv)
{
    int i, j;
    int color;
    int val, longindex;
    int pcs[16];
    int wdl_only = 0;
#ifdef SUICIDE
    int switched = 0;
#endif

    numthreads = 1;

    do {
//    val = getopt_long(argc, argv, "t:lwc", options, &longindex);
        val = getopt_long(argc, argv, "t:ld", options, &longindex);
        switch (val) {
        case 't':
            numthreads = atoi(optarg);
            break;
        case 'l':
            log = 1;
            break;
        case 'w':
            wdl_only = 1;
            break;
        case 'd':
            use_envdirs = 1;
            break;
        }
    } while (val != EOF);

    if (optind >= argc) {
        fprintf(stderr, "No tablebase specified.\n");
        exit(1);
    }
    tablename = argv[optind];

    init_tablebases();

    for (i = 0; i < 16; i++)
        pcs[i] = 0;

    numpcs = strlen(tablename) - 1;
    color = 0;
    j = 0;
    for (i = 0; i < strlen(tablename); i++)
        switch (tablename[i]) {
        case 'P':
            pcs[PAWN | color]++;
            pt[j++] = PAWN | color;
            break;
        case 'N':
            pcs[KNIGHT | color]++;
            pt[j++] = KNIGHT | color;
            break;
        case 'B':
            pcs[BISHOP | color]++;
            pt[j++] = BISHOP | color;
            break;
        case 'R':
            pcs[ROOK | color]++;
            pt[j++] = ROOK | color;
            break;
        case 'Q':
            pcs[QUEEN | color]++;
            pt[j++] = QUEEN | color;
            break;
        case 'K':
            pcs[KING | color]++;
            pt[j++] = KING | color;
            break;
        case 'v':
            if (color) exit(1);
            color = 0x08;
            break;
        default:
            exit(1);
        }
    if (!color) exit(1);

    if (pcs[WPAWN] || pcs[BPAWN]) {
        fprintf(stderr, "Can't handle pawns.\n");
        exit(1);
    }

    if (numthreads < 1) numthreads = 1;
    else if (numthreads > MAX_THREADS) numthreads = MAX_THREADS;

    printf("number of threads = %d\n", numthreads);

    if (numthreads == 1)
        total_work = 1;
    else
        total_work = 100 + 10 * numthreads;

    for (i = 0; i < numpcs; i++) {
        shift[i] = (numpcs - i - 1) * 6;
        mask[i] = 0x3fULL << shift[i];
    }

#ifndef SMALL
    size = 10ULL << (6 * (numpcs-1));
#else
    size = 462ULL << (6 * (numpcs-2));

    mask[0] = 0x1ffULL << shift[1];
#endif

    work_g = create_work(total_work, size, 0x3f);
#ifndef SMALL
    work_piv = create_work(total_work, 1ULL << shift[0], 0);
#else
    work_piv0 = create_work(total_work, 1ULL << shift[0], 0);
    work_piv1 = create_work(total_work, 10ULL << shift[1], 0);
#endif

    static int piece_order[16] = {
        0, 0, 3, 5, 7, 9, 1, 0,
        0, 0, 4, 6, 8, 10, 2, 0
    };

#ifdef SUICIDE
    j = pt[0];
    for (i = 1; i < numpcs; i++)
        if (piece_order[pt[i]] < piece_order[j])
            j = pt[i];
    if (j & 0x08) {
        for (i = 0; i < numpcs; i++)
            pt[i] ^= 0x08;
        for (i = 0; i < 8; i++) {
            int tmp = pcs[i];
            pcs[i] = pcs[i + 8];
            pcs[i + 8] = tmp;
        }
        switched = 1;
    }
#endif

    for (i = 0; i < numpcs; i++)
        for (j = i + 1; j < numpcs; j++)
            if (piece_order[pt[i]] > piece_order[pt[j]]) {
                int tmp = pt[i];
                pt[i] = pt[j];
                pt[j] = tmp;
            }

    for (i = 0, j = 0; i < numpcs; i++)
        if (!(pt[i] & 0x08))
            white_pcs[j++] = i;
    white_pcs[j] = -1;

    for (i = 0, j = 0; i < numpcs; i++)
        if (pt[i] & 0x08)
            black_pcs[j++] = i;
    black_pcs[j] = -1;

    idx_mask1[numpcs - 1] = 0xffffffffffffffc0ULL;
    idx_mask2[numpcs - 1] = 0;
    for (i = numpcs - 2; i >= 0; i--) {
        idx_mask1[i] = idx_mask1[i + 1] << 6;
        idx_mask2[i] = (idx_mask2[i + 1] << 6) | 0x3f;
    }

#ifndef SUICIDE
    for (i = 0; i < numpcs; i++)
        if (pt[i] == WKING)
            white_king = i;

    for (i = 0; i < numpcs; i++)
        if (pt[i] == BKING)
            black_king = i;
#endif

    table_w = alloc_huge(2 * size);
    table_b = table_w + size;

    printf("Verifying %s.\n", tablename);
    if (log) {
        L = fopen(LOGFILE, "a");
        fprintf(L, "Verifying %s...", tablename);
        fflush(L);
    }

    init_threads(0);
    init_tables();

    gettimeofday(&start_time, NULL);
    cur_time = start_time;

    printf("Initialising broken positions.\n");
    run_threaded(calc_broken, work_g, 1);
    printf("Calculating white captures.\n");
    calc_captures_w();
    printf("Calculating black captures.\n");
    calc_captures_b();
#ifndef SUICIDE
    printf("Calculating mate positions.\n");
    run_threaded(calc_mates, work_g, 1);
#else
    init_capt_threat();
    printf("Calculating white threats.\n");
    iter_table = table_b;
    iter_table_opp = table_w;
    iter_pcs_opp = white_pcs;
    run_threaded(calc_threats, work_g, 1);
    printf("Calculating black threats.\n");
    iter_table = table_w;
    iter_table_opp = table_b;
    iter_pcs_opp = black_pcs;
    run_threaded(calc_threats, work_g, 1);
#endif

    decomp_init_piece(pcs);

    // open wdl table
    struct tb_handle *H = open_tb(tablename, 1);
    decomp_init_table(H);
    load_entry = (struct TBEntry_piece *)get_entry(H);

    if (!wdl_only) {
        // white, wdl
        printf("Loading wdl, white.\n");
        tb_table = decompress_table(H, 0, 0);
        set_perm(H, 0, 0, tb_perm, pt);
        load_table = table_w;
        load_bside = 0;
        run_threaded(load_wdl, work_g, 1);

        // black, wdl
        printf("Loading wdl, black.\n");
        tb_table = decompress_table(H, 1, 0);
        set_perm(H, 1, 0, tb_perm, pt);
        load_table = table_b;
        load_bside = 1;
        run_threaded(load_wdl, work_g, 1);
        close_tb(H);

        // open dtz table
        H = open_tb(tablename, 0);
        decomp_init_table(H);
        load_entry = (struct TBEntry_piece *)get_entry(H);
        ply_accurate_win = get_ply_accurate_win(H, 0);
        ply_accurate_loss = get_ply_accurate_loss(H, 0);
        load_map = get_dtz_map(H, 0);
        int dtz_side = get_dtz_side(H, 0);
        init_wdl_dtz();

        // dtz
        printf("Loading dtz, %s.\n" , dtz_side == 0 ? "white" : "black");
        tb_table = decompress_table(H, 0, 0);
        set_perm(H, 0, 0, tb_perm, pt);
        load_table = dtz_side == 0 ? table_w : table_b;
        load_bside = 0;
        if (load_map)
            run_threaded(load_dtz_mapped, work_g, 1);
        else
            run_threaded(load_dtz, work_g, 1);
        close_tb(H);

        if (dtz_side == 0) {
            load_table = table_w;
            load_opp_table = table_b;
            load_pieces = white_pcs;
            load_opp_pieces = black_pcs;
        } else {
            load_table = table_b;
            load_opp_table = table_w;
            load_pieces = black_pcs;
            load_opp_pieces = white_pcs;
        }

        printf("Verifying %s.\n", dtz_side ? "white" : "black");
        run_threaded(verify_opp, work_g, 1);
        printf("Verifying %s.\n", dtz_side ? "black" : "white");
        run_threaded(verify_dtz, work_g, 1);
    } else { // currently broken (and disabled)
        // white, wdl
        printf("Loading wdl, white.\n");
        tb_table = decompress_table(H, 0, 0);
        set_perm(H, 0, 0, tb_perm, pt);
        load_table = table_w;
        load_bside = 0;
        run_threaded(wdl_load_wdl, work_g, 1);

        // black, wdl
        printf("Loading wdl, black.\n");
        tb_table = decompress_table(H, 1, 0);
        set_perm(H, 1, 0, tb_perm, pt);
        load_table = table_b;
        load_bside = 1;
        run_threaded(wdl_load_wdl, work_g, 1);
        close_tb(H);

        ply_accurate_win = get_ply_accurate_win(H, 0);
        ply_accurate_loss = get_ply_accurate_loss(H, 0);
        init_wdl();
        load_table = table_w;
        load_opp_table = table_b;
        load_pieces = white_pcs;
        printf("Verifying white.\n");
        run_threaded(verify_wdl, work_g, 1);

        ply_accurate_win = get_ply_accurate_loss(H, 0);
        ply_accurate_loss = get_ply_accurate_win(H, 0);
        init_wdl();
        load_table = table_b;
        load_opp_table = table_w;
        load_pieces = black_pcs;
        printf("Verifying black.\n");
        run_threaded(verify_wdl, work_g, 1);
    }

    if (num_errors == 0) {
        printf("No errors.\n");
        if (log) fprintf(L, " No errors.\n");
    }
    if (log) fclose(L);

    return 0;
}