mirror of
https://github.com/sockspls/badfish
synced 2025-05-02 01:29:36 +00:00
[cluster] Fix oversight in TT key reuse
In the original code, the position key stored in the TT is used to probe&store TT entries after message passing. Since we only store part of the bits in the TT, this leads to incorrect rehashing. This is fixed in this patch storing also the full key in the send buffers, and using that for hashing after message arrival. Short testing with 4 ranks (old vs new) shows this is effective: Score of mpiold vs mpinew: 84 - 275 - 265 [0.347] 624 Elo difference: -109.87 +/- 20.88
This commit is contained in:
parent
2659c407c4
commit
2559c20c6e
4 changed files with 26 additions and 22 deletions
|
@ -357,7 +357,7 @@ ifeq ($(OS), Android)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
### 3.10 MPI
|
### 3.10 MPI
|
||||||
ifeq ($(CXX),$(filter $(CXX),mpicxx mpic++ mpiCC))
|
ifeq ($(CXX),$(filter $(CXX),mpicxx mpic++ mpiCC mpicxx.mpich))
|
||||||
mpi = yes
|
mpi = yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ static MPI_Comm MoveComm = MPI_COMM_NULL;
|
||||||
static MPI_Comm StopComm = MPI_COMM_NULL;
|
static MPI_Comm StopComm = MPI_COMM_NULL;
|
||||||
|
|
||||||
static MPI_Datatype TTEntryDatatype = MPI_DATATYPE_NULL;
|
static MPI_Datatype TTEntryDatatype = MPI_DATATYPE_NULL;
|
||||||
static std::vector<TTEntry> TTBuff;
|
static std::vector<KeyedTTEntry> TTBuff;
|
||||||
|
|
||||||
static MPI_Op BestMoveOp = MPI_OP_NULL;
|
static MPI_Op BestMoveOp = MPI_OP_NULL;
|
||||||
static MPI_Datatype MIDatatype = MPI_DATATYPE_NULL;
|
static MPI_Datatype MIDatatype = MPI_DATATYPE_NULL;
|
||||||
|
@ -65,14 +65,16 @@ static void BestMove(void* in, void* inout, int* len, MPI_Datatype* datatype) {
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
int thread_support;
|
int thread_support;
|
||||||
constexpr std::array<int, 6> TTblocklens = {1, 1, 1, 1, 1, 1};
|
constexpr std::array<int, 7> TTblocklens = {1, 1, 1, 1, 1, 1, 1};
|
||||||
const std::array<MPI_Aint, 6> TTdisps = {offsetof(TTEntry, key16),
|
const std::array<MPI_Aint, 7> TTdisps = {offsetof(KeyedTTEntry, first),
|
||||||
offsetof(TTEntry, move16),
|
offsetof(KeyedTTEntry, second) + offsetof(TTEntry, key16),
|
||||||
offsetof(TTEntry, value16),
|
offsetof(KeyedTTEntry, second) + offsetof(TTEntry, move16),
|
||||||
offsetof(TTEntry, eval16),
|
offsetof(KeyedTTEntry, second) + offsetof(TTEntry, value16),
|
||||||
offsetof(TTEntry, genBound8),
|
offsetof(KeyedTTEntry, second) + offsetof(TTEntry, eval16),
|
||||||
offsetof(TTEntry, depth8)};
|
offsetof(KeyedTTEntry, second) + offsetof(TTEntry, genBound8),
|
||||||
const std::array<MPI_Datatype, 6> TTtypes = {MPI_UINT16_T,
|
offsetof(KeyedTTEntry, second) + offsetof(TTEntry, depth8)};
|
||||||
|
const std::array<MPI_Datatype, 7> TTtypes = {MPI_UINT64_T,
|
||||||
|
MPI_UINT16_T,
|
||||||
MPI_UINT16_T,
|
MPI_UINT16_T,
|
||||||
MPI_INT16_T,
|
MPI_INT16_T,
|
||||||
MPI_INT16_T,
|
MPI_INT16_T,
|
||||||
|
@ -95,7 +97,7 @@ void init() {
|
||||||
|
|
||||||
TTBuff.resize(TTSendBufferSize * world_size);
|
TTBuff.resize(TTSendBufferSize * world_size);
|
||||||
|
|
||||||
MPI_Type_create_struct(6, TTblocklens.data(), TTdisps.data(), TTtypes.data(),
|
MPI_Type_create_struct(7, TTblocklens.data(), TTdisps.data(), TTtypes.data(),
|
||||||
&TTEntryDatatype);
|
&TTEntryDatatype);
|
||||||
MPI_Type_commit(&TTEntryDatatype);
|
MPI_Type_commit(&TTEntryDatatype);
|
||||||
|
|
||||||
|
@ -185,12 +187,13 @@ int rank() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void save(Thread* thread, TTEntry* tte,
|
void save(Thread* thread, TTEntry* tte,
|
||||||
Key k, Value v, Bound b, Depth d, Move m, Value ev, uint8_t g) {
|
Key k, Value v, Bound b, Depth d, Move m, Value ev) {
|
||||||
tte->save(k, v, b, d, m, ev, g);
|
tte->save(k, v, b, d, m, ev);
|
||||||
|
|
||||||
// Try to add to thread's send buffer
|
// Try to add to thread's send buffer
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lk(thread->ttBuffer.mutex);
|
std::lock_guard<Mutex> lk(thread->ttBuffer.mutex);
|
||||||
thread->ttBuffer.buffer.replace(*tte);
|
thread->ttBuffer.buffer.replace(KeyedTTEntry(k,*tte));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Communicate on main search thread
|
// Communicate on main search thread
|
||||||
|
@ -208,9 +211,9 @@ void save(Thread* thread, TTEntry* tte,
|
||||||
if (flag) {
|
if (flag) {
|
||||||
// Save all recieved entries
|
// Save all recieved entries
|
||||||
for (auto&& e : TTBuff) {
|
for (auto&& e : TTBuff) {
|
||||||
replace_tte = TT.probe(e.key(), found);
|
replace_tte = TT.probe(e.first, found);
|
||||||
replace_tte->save(e.key(), e.value(), e.bound(), e.depth(),
|
replace_tte->save(e.first, e.second.value(), e.second.bound(), e.second.depth(),
|
||||||
e.move(), e.eval(), e.gen());
|
e.second.move(), e.second.eval());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset send buffer
|
// Reset send buffer
|
||||||
|
|
|
@ -39,17 +39,19 @@ struct MoveInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef USE_MPI
|
#ifdef USE_MPI
|
||||||
|
using KeyedTTEntry = std::pair<Key, TTEntry>;
|
||||||
|
|
||||||
constexpr std::size_t TTSendBufferSize = 16;
|
constexpr std::size_t TTSendBufferSize = 16;
|
||||||
template <std::size_t N> class TTSendBuffer : public std::array<TTEntry, N> {
|
template <std::size_t N> class TTSendBuffer : public std::array<KeyedTTEntry, N> {
|
||||||
struct Compare {
|
struct Compare {
|
||||||
inline bool operator()(const TTEntry& lhs, const TTEntry& rhs) {
|
inline bool operator()(const KeyedTTEntry& lhs, const KeyedTTEntry& rhs) {
|
||||||
return lhs.depth() > rhs.depth();
|
return lhs.second.depth() > rhs.second.depth();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Compare compare;
|
Compare compare;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool replace(const TTEntry& value) {
|
bool replace(const KeyedTTEntry& value) {
|
||||||
if (compare(value, this->front())) {
|
if (compare(value, this->front())) {
|
||||||
std::pop_heap(this->begin(), this->end(), compare);
|
std::pop_heap(this->begin(), this->end(), compare);
|
||||||
this->back() = value;
|
this->back() = value;
|
||||||
|
|
1
src/tt.h
1
src/tt.h
|
@ -41,7 +41,6 @@ namespace Cluster {
|
||||||
|
|
||||||
struct TTEntry {
|
struct TTEntry {
|
||||||
|
|
||||||
Key key() const { return (Key )(key16) << 48; }
|
|
||||||
Move move() const { return (Move )move16; }
|
Move move() const { return (Move )move16; }
|
||||||
Value value() const { return (Value)value16; }
|
Value value() const { return (Value)value16; }
|
||||||
Value eval() const { return (Value)eval16; }
|
Value eval() const { return (Value)eval16; }
|
||||||
|
|
Loading…
Add table
Reference in a new issue