My Project
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
9osl::checkmate::
10DfpnParallel::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
20osl::checkmate::
21DfpnParallel::~DfpnParallel()
22{
23#ifdef DFPN_DEBUG
24 table->testTable();
25#endif
26}
27
28void osl::checkmate::
29DfpnParallel::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
37osl::checkmate::
38DfpnParallel::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
46struct 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
67osl::checkmate::
68DfpnParallel::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
102struct 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
121osl::checkmate::
122DfpnParallel::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
148size_t osl::checkmate::
149DfpnParallel::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
158void osl::checkmate::
159DfpnParallel::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:
証明数(proof number)と反証数(disproof number).
unsigned int disproof() const
unsigned int proof() const