Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 154 Rev 169
Line 4... Line 4...
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
5
  Copyright (C) 2015-2016 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
5
  Copyright (C) 2015-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
6
 
6
 
7
  Stockfish is free software: you can redistribute it and/or modify
7
  Stockfish is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU General Public License as published by
8
  it under the terms of the GNU General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
10
  (at your option) any later version.
Line 21... Line 21...
21
#include <fstream>
21
#include <fstream>
22
#include <iostream>
22
#include <iostream>
23
#include <istream>
23
#include <istream>
24
#include <vector>
24
#include <vector>
25
 
25
 
26
#include "misc.h"
-
 
27
#include "position.h"
26
#include "position.h"
28
#include "search.h"
-
 
29
#include "thread.h"
-
 
30
#include "uci.h"
-
 
31
 
27
 
32
using namespace std;
28
using namespace std;
33
 
29
 
34
namespace {
30
namespace {
35
 
31
 
36
const vector<string> Defaults = {
32
const vector<string> Defaults = {
-
 
33
  "setoption name UCI_Chess960 value false",
37
  "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
34
  "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
38
  "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 10",
35
  "r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 10",
39
  "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 11",
36
  "8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 11",
40
  "4rrk1/pp1n3p/3q2pQ/2p1pb2/2PP4/2P3N1/P2B2PP/4RRK1 b - - 7 19",
37
  "4rrk1/pp1n3p/3q2pQ/2p1pb2/2PP4/2P3N1/P2B2PP/4RRK1 b - - 7 19",
41
  "rq3rk1/ppp2ppp/1bnpb3/3N2B1/3NP3/7P/PPPQ1PP1/2KR3R w - - 7 14",
38
  "rq3rk1/ppp2ppp/1bnpb3/3N2B1/3NP3/7P/PPPQ1PP1/2KR3R w - - 7 14 moves d4e6",
42
  "r1bq1r1k/1pp1n1pp/1p1p4/4p2Q/4Pp2/1BNP4/PPP2PPP/3R1RK1 w - - 2 14",
39
  "r1bq1r1k/1pp1n1pp/1p1p4/4p2Q/4Pp2/1BNP4/PPP2PPP/3R1RK1 w - - 2 14 moves g2g4",
43
  "r3r1k1/2p2ppp/p1p1bn2/8/1q2P3/2NPQN2/PPP3PP/R4RK1 b - - 2 15",
40
  "r3r1k1/2p2ppp/p1p1bn2/8/1q2P3/2NPQN2/PPP3PP/R4RK1 b - - 2 15",
44
  "r1bbk1nr/pp3p1p/2n5/1N4p1/2Np1B2/8/PPP2PPP/2KR1B1R w kq - 0 13",
41
  "r1bbk1nr/pp3p1p/2n5/1N4p1/2Np1B2/8/PPP2PPP/2KR1B1R w kq - 0 13",
45
  "r1bq1rk1/ppp1nppp/4n3/3p3Q/3P4/1BP1B3/PP1N2PP/R4RK1 w - - 1 16",
42
  "r1bq1rk1/ppp1nppp/4n3/3p3Q/3P4/1BP1B3/PP1N2PP/R4RK1 w - - 1 16",
46
  "4r1k1/r1q2ppp/ppp2n2/4P3/5Rb1/1N1BQ3/PPP3PP/R5K1 w - - 1 17",
43
  "4r1k1/r1q2ppp/ppp2n2/4P3/5Rb1/1N1BQ3/PPP3PP/R5K1 w - - 1 17",
47
  "2rqkb1r/ppp2p2/2npb1p1/1N1Nn2p/2P1PP2/8/PP2B1PP/R1BQK2R b KQ - 0 11",
44
  "2rqkb1r/ppp2p2/2npb1p1/1N1Nn2p/2P1PP2/8/PP2B1PP/R1BQK2R b KQ - 0 11",
Line 50... Line 47...
50
  "r1q2rk1/2p1bppp/2Pp4/p6b/Q1PNp3/4B3/PP1R1PPP/2K4R w - - 2 18",
47
  "r1q2rk1/2p1bppp/2Pp4/p6b/Q1PNp3/4B3/PP1R1PPP/2K4R w - - 2 18",
51
  "4k2r/1pb2ppp/1p2p3/1R1p4/3P4/2r1PN2/P4PPP/1R4K1 b - - 3 22",
48
  "4k2r/1pb2ppp/1p2p3/1R1p4/3P4/2r1PN2/P4PPP/1R4K1 b - - 3 22",
52
  "3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - 4 26",
49
  "3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - 4 26",
53
  "6k1/6p1/6Pp/ppp5/3pn2P/1P3K2/1PP2P2/3N4 b - - 0 1",
50
  "6k1/6p1/6Pp/ppp5/3pn2P/1P3K2/1PP2P2/3N4 b - - 0 1",
54
  "3b4/5kp1/1p1p1p1p/pP1PpP1P/P1P1P3/3KN3/8/8 w - - 0 1",
51
  "3b4/5kp1/1p1p1p1p/pP1PpP1P/P1P1P3/3KN3/8/8 w - - 0 1",
55
  "2K5/p7/7P/5pR1/8/5k2/r7/8 w - - 0 1",
52
  "2K5/p7/7P/5pR1/8/5k2/r7/8 w - - 0 1 moves g5g6 f3e3 g6g5 e3f3",
56
  "8/6pk/1p6/8/PP3p1p/5P2/4KP1q/3Q4 w - - 0 1",
53
  "8/6pk/1p6/8/PP3p1p/5P2/4KP1q/3Q4 w - - 0 1",
57
  "7k/3p2pp/4q3/8/4Q3/5Kp1/P6b/8 w - - 0 1",
54
  "7k/3p2pp/4q3/8/4Q3/5Kp1/P6b/8 w - - 0 1",
58
  "8/2p5/8/2kPKp1p/2p4P/2P5/3P4/8 w - - 0 1",
55
  "8/2p5/8/2kPKp1p/2p4P/2P5/3P4/8 w - - 0 1",
59
  "8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - 0 1",
56
  "8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - 0 1",
60
  "8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - 0 1",
57
  "8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - 0 1",
Line 77... Line 74...
77
 
74
 
78
  // 7-man positions
75
  // 7-man positions
79
  "8/R7/2q5/8/6k1/8/1P5p/K6R w - - 0 124", // Draw
76
  "8/R7/2q5/8/6k1/8/1P5p/K6R w - - 0 124", // Draw
80
 
77
 
81
  // Mate and stalemate positions
78
  // Mate and stalemate positions
-
 
79
  "6k1/3b3r/1p1p4/p1n2p2/1PPNpP1q/P3Q1p1/1R1RB1P1/5K2 b - - 0 1",
-
 
80
  "r2r1n2/pp2bk2/2p1p2p/3q4/3PN1QP/2P3R1/P4PP1/5RK1 w - - 0 1",
82
  "8/8/8/8/8/6k1/6p1/6K1 w - -",
81
  "8/8/8/8/8/6k1/6p1/6K1 w - -",
83
  "5k2/5P2/5K2/8/8/8/8/8 b - -",
82
  "7k/7P/6K1/8/3B4/8/8/8 b - -",
-
 
83
 
84
  "8/8/8/8/8/4k3/4p3/4K3 w - -",
84
  // Chess 960
85
  "8/8/8/8/8/5K2/8/3Q1k2 b - -",
85
  "setoption name UCI_Chess960 value true",
-
 
86
  "bbqnnrkr/pppppppp/8/8/8/8/PPPPPPPP/BBQNNRKR w KQkq - 0 1 moves g2g3 d7d5 d2d4 c8h3 c1g5 e8d6 g5e7 f7f6",
86
  "7k/7P/6K1/8/3B4/8/8/8 b - -"
87
  "setoption name UCI_Chess960 value false"
87
};
88
};
88
 
89
 
89
} // namespace
90
} // namespace
90
 
91
 
91
/// benchmark() runs a simple benchmark by letting Stockfish analyze a set
92
/// setup_bench() builds a list of UCI commands to be run by bench. There
-
 
93
/// are five parameters: TT size in MB, number of search threads that
92
/// of positions for a given limit each. There are five parameters: the
94
/// should be used, the limit value spent for each position, a file name
93
/// transposition table size, the number of search threads that should
95
/// where to look for positions in FEN format and the type of the limit:
-
 
96
/// depth, perft, nodes and movetime (in millisecs).
-
 
97
///
94
/// be used, the limit value spent for each position (optional, default is
98
/// bench -> search default positions up to depth 13
-
 
99
/// bench 64 1 15 -> search default positions up to depth 15 (TT = 64MB)
95
/// depth 13), an optional file name where to look for positions in FEN
100
/// bench 64 4 5000 current movetime -> search current position with 4 threads for 5 sec
96
/// format (defaults are the positions defined above) and the type of the
101
/// bench 64 1 100000 default nodes -> search default positions for 100K nodes each
97
/// limit value: depth (default), time in millisecs or number of nodes.
102
/// bench 16 1 5 default perft -> run a perft 5 on default positions
98
 
103
 
99
void benchmark(const Position& current, istream& is) {
104
vector<string> setup_bench(const Position& current, istream& is) {
100
 
105
 
101
  string token;
-
 
102
  vector<string> fens;
106
  vector<string> fens, list;
103
  Search::LimitsType limits;
107
  string go, token;
104
 
108
 
105
  // Assign default values to missing arguments
109
  // Assign default values to missing arguments
106
  string ttSize    = (is >> token) ? token : "16";
110
  string ttSize    = (is >> token) ? token : "16";
107
  string threads   = (is >> token) ? token : "1";
111
  string threads   = (is >> token) ? token : "1";
108
  string limit     = (is >> token) ? token : "13";
112
  string limit     = (is >> token) ? token : "13";
109
  string fenFile   = (is >> token) ? token : "default";
113
  string fenFile   = (is >> token) ? token : "default";
110
  string limitType = (is >> token) ? token : "depth";
114
  string limitType = (is >> token) ? token : "depth";
111
 
115
 
112
  Options["Hash"]    = ttSize;
-
 
113
  Options["Threads"] = threads;
-
 
114
  Search::clear();
-
 
115
 
-
 
116
  if (limitType == "time")
-
 
117
      limits.movetime = stoi(limit); // movetime is in millisecs
-
 
118
 
-
 
119
  else if (limitType == "nodes")
-
 
120
      limits.nodes = stoi(limit);
-
 
121
 
-
 
122
  else if (limitType == "mate")
-
 
123
      limits.mate = stoi(limit);
-
 
124
 
-
 
125
  else
-
 
126
      limits.depth = stoi(limit);
116
  go = "go " + limitType + " " + limit;
127
 
117
 
128
  if (fenFile == "default")
118
  if (fenFile == "default")
129
      fens = Defaults;
119
      fens = Defaults;
130
 
120
 
131
  else if (fenFile == "current")
121
  else if (fenFile == "current")
Line 137... Line 127...
137
      ifstream file(fenFile);
127
      ifstream file(fenFile);
138
 
128
 
139
      if (!file.is_open())
129
      if (!file.is_open())
140
      {
130
      {
141
          cerr << "Unable to open file " << fenFile << endl;
131
          cerr << "Unable to open file " << fenFile << endl;
142
          return;
132
          exit(EXIT_FAILURE);
143
      }
133
      }
144
 
134
 
145
      while (getline(file, fen))
135
      while (getline(file, fen))
146
          if (!fen.empty())
136
          if (!fen.empty())
147
              fens.push_back(fen);
137
              fens.push_back(fen);
148
 
138
 
149
      file.close();
139
      file.close();
150
  }
140
  }
151
 
141
 
152
  uint64_t nodes = 0;
-
 
153
  TimePoint elapsed = now();
142
  list.emplace_back("ucinewgame");
154
  Position pos;
-
 
155
 
-
 
156
  for (size_t i = 0; i < fens.size(); ++i)
-
 
157
  {
-
 
158
      StateListPtr states(new std::deque<StateInfo>(1));
143
  list.emplace_back("setoption name Threads value " + threads);
159
      pos.set(fens[i], Options["UCI_Chess960"], &states->back(), Threads.main());
-
 
160
 
-
 
161
      cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl;
144
  list.emplace_back("setoption name Hash value " + ttSize);
162
 
-
 
163
      if (limitType == "perft")
-
 
164
          nodes += Search::perft(pos, limits.depth * ONE_PLY);
-
 
165
 
145
 
-
 
146
  for (const string& fen : fens)
-
 
147
      if (fen.find("setoption") != string::npos)
-
 
148
          list.emplace_back(fen);
166
      else
149
      else
167
      {
150
      {
168
          limits.startTime = now();
-
 
169
          Threads.start_thinking(pos, states, limits);
151
          list.emplace_back("position fen " + fen);
170
          Threads.main()->wait_for_search_finished();
-
 
171
          nodes += Threads.nodes_searched();
152
          list.emplace_back(go);
172
      }
153
      }
173
  }
-
 
174
 
-
 
175
  elapsed = now() - elapsed + 1; // Ensure positivity to avoid a 'divide by zero'
-
 
176
 
-
 
177
  dbg_print(); // Just before exiting
-
 
178
 
154
 
179
  cerr << "\n==========================="
-
 
180
       << "\nTotal time (ms) : " << elapsed
155
  return list;
181
       << "\nNodes searched  : " << nodes
-
 
182
       << "\nNodes/second    : " << 1000 * nodes / elapsed << endl;
-
 
183
}
156
}