dfpnParallel.cc
Go to the documentation of this file.
1 /* dfpnParallel.cc
2  */
5 #include <boost/ptr_container/ptr_vector.hpp>
6 #include <thread>
7 
8 #ifdef OSL_DFPN_SMP
9 osl::checkmate::
10 DfpnParallel::DfpnParallel(size_t threads)
11  : table(0), num_threads(threads), state(0)
12 {
13  if (threads == 0)
14  num_threads = OslConfig::concurrency();
15  workers.reset(new Dfpn[num_threads]);
16  for (size_t i=0; i<num_threads; ++i)
17  workers[i].setParallel(i, &shared);
18 }
19 
20 osl::checkmate::
21 DfpnParallel::~DfpnParallel()
22 {
23 #ifdef DFPN_DEBUG
24  table->testTable();
25 #endif
26 }
27 
28 void osl::checkmate::
29 DfpnParallel::setTable(DfpnTable *new_table)
30 {
31  table = new_table;
32  for (size_t i=0; i<num_threads; ++i)
33  workers[i].setTable(table);
34 }
35 
37 osl::checkmate::
38 DfpnParallel::hasCheckmateMove(const NumEffectState& state, const HashKey& key,
39  const PathEncoding& path, size_t limit, Move& best_move,
40  Move last_move, std::vector<Move> *pv)
41 {
42  PieceStand proof;
43  return hasCheckmateMove(state, key, path, limit, best_move, proof, last_move, pv);
44 }
45 
46 struct osl::checkmate::DfpnParallel::AttackWorker
47 {
48  DfpnParallel *parent;
49  int thread_id;
50 
51  AttackWorker(DfpnParallel *p, int id)
52  : parent(p), thread_id(id)
53  {
54  }
55  void operator()() const
56  {
57  assert(! parent->shared.data[thread_id].restart);
58  WorkerData& work = parent->worker_data[thread_id];
59  work.result = parent->workers[thread_id].hasCheckmateMove
60  (*(parent->state), parent->key, parent->path,
61  parent->limit, work.best_move, work.proof, parent->last_move);
62  parent->workers[thread_id].clear();
63  }
64 };
65 
67 osl::checkmate::
68 DfpnParallel::hasCheckmateMove(const NumEffectState& state, const HashKey& key,
69  const PathEncoding& path, size_t limit, Move& best_move, PieceStand& proof,
70  Move last_move, std::vector<Move> *pv)
71 {
72  this->state = &state;
73  this->key = key;
74  this->path = path;
75  this->last_move = last_move;
76  this->limit = limit;
77  shared.clear();
78  worker_data.reset(new WorkerData[num_threads]);
79  boost::ptr_vector<std::thread> threads;
80  for (size_t i=0; i<num_threads; ++i)
81  threads.push_back(new std::thread(AttackWorker(this, i)));
82  ProofDisproof ret;
83  unsigned int min_proof = ProofDisproof::PROOF_MAX;
84  for (size_t i=0; i<num_threads; ++i) {
85  threads[i].join();
86  if (ret.isFinal()
87  || (worker_data[i].result.proof() >= min_proof
88  && ! worker_data[i].result.isFinal()))
89  continue;
90  ret = worker_data[i].result;
91  min_proof = ret.proof();
92  best_move = worker_data[i].best_move;
93  proof = worker_data[i].proof;
94  }
95  if (pv && ret.isCheckmateSuccess()) {
96  ProofTreeDepthDfpn analyzer(*table);
97  analyzer.retrievePV(state, true, *pv);
98  }
99  return ret;
100 }
101 
102 struct osl::checkmate::DfpnParallel::DefenseWorker
103 {
104  DfpnParallel *parent;
105  int thread_id;
106 
107  DefenseWorker(DfpnParallel *p, int id)
108  : parent(p), thread_id(id)
109  {
110  }
111  void operator()() const
112  {
113  WorkerData& work = parent->worker_data[thread_id];
114  work.result = parent->workers[thread_id].hasEscapeMove
115  (*(parent->state), parent->key, parent->path,
116  parent->limit, parent->last_move);
117  }
118 };
119 
121 osl::checkmate::
122 DfpnParallel::hasEscapeMove(const NumEffectState& state,
123  const HashKey& key, const PathEncoding& path,
124  size_t limit, Move last_move)
125 {
126  this->state = &state;
127  this->key = key;
128  this->path = path;
129  this->last_move = last_move;
130  this->limit = limit;
131  shared.clear();
132  worker_data.reset(new WorkerData[num_threads]);
133  boost::ptr_vector<std::thread> threads;
134  for (size_t i=0; i<num_threads; ++i)
135  threads.push_back(new std::thread(DefenseWorker(this, i)));
136  ProofDisproof ret;
137  unsigned int min_disproof = ProofDisproof::DISPROOF_MAX;
138  for (size_t i=0; i<num_threads; ++i) {
139  threads[i].join();
140  if (worker_data[i].result.disproof() >= min_disproof)
141  continue;
142  ret = worker_data[i].result;
143  min_disproof = ret.disproof();
144  }
145  return ret;
146 }
147 
148 size_t osl::checkmate::
149 DfpnParallel::nodeCount() const
150 {
151  size_t sum = 0;
152  for (size_t i=0; i<num_threads; ++i)
153  sum += workers[i].nodeCount();
154  return sum;
155 }
156 
157 #ifndef MINIMAL
158 void osl::checkmate::
159 DfpnParallel::analyze(const PathEncoding& path,
160  const NumEffectState& src, const std::vector<Move>& moves) const
161 {
162  if (num_threads > 0)
163  workers[0].analyze(path, src, moves);
164 }
165 #endif
166 #endif
167 
168 /* ------------------------------------------------------------------------- */
169 // ;;; Local Variables:
170 // ;;; mode:c++
171 // ;;; c-basic-offset:2
172 // ;;; End:
void setTable(DfpnTable *new_table)
Definition: dfpn.cc:1296
void setParallel(int id, DfpnShared *s)
Definition: dfpn.h:132
const ProofDisproof hasCheckmateMove(const NumEffectState &state, const HashKey &key, const PathEncoding &path, size_t limit, Move &best_move, Move last_move=Move::INVALID(), std::vector< Move > *pv=0)
Definition: dfpn.cc:1329
size_t nodeCount() const
Definition: dfpn.h:152
DfpnTable * table
Definition: dfpn.h:115
static int concurrency()
Definition: oslConfig.cc:133
証明数(proof number)と反証数(disproof number).
Definition: proofDisproof.h:16