dfpnParallel.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
dfpnParallel.cc
Go to the documentation of this file.
1 /* dfpnParallel.cc
2 */
3 #include "osl/checkmate/dfpnParallel.h"
4 #include "osl/checkmate/proofTreeDepthDfpn.h"
5 #include <boost/ptr_container/ptr_vector.hpp>
6 #include <boost/thread/thread.hpp>
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::numCPUs();
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
36 const osl::checkmate::ProofDisproof
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, 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
66 const osl::checkmate::ProofDisproof
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, 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<boost::thread> threads;
80 for (size_t i=0; i<num_threads; ++i)
81 threads.push_back(new boost::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
120 const osl::checkmate::ProofDisproof
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<boost::thread> threads;
134 for (size_t i=0; i<num_threads; ++i)
135 threads.push_back(new boost::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 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: