You also wrote "The reason why it is there is to handle the case where DTZ is not available and the root position is in the TBs and winning."syzygy wrote:Contrary to what you think, this is not speculation.
Isn't this the same case...
Moderators: hgm, Rebel, chrisw
You also wrote "The reason why it is there is to handle the case where DTZ is not available and the root position is in the TBs and winning."syzygy wrote:Contrary to what you think, this is not speculation.
There is the case where DTZ is available. SF then uses DTZ at the root only to filter out the non-winning moves (or the losing moves if the root is a draw). This code looks at the 50-move counter and tries to be a bit smart (e.g. it will go for losing moves will high DTZ if the root position is lost but the opponent has not too much 50-move margin). In this case, TB probing within the tree is disabled.mcostalba wrote:You also wrote "The reason why it is there is to handle the case where DTZ is not available and the root position is in the TBs and winning."syzygy wrote:Contrary to what you think, this is not speculation.
Isn't this the same case...
I still use the rule50 count, I just did not post the entirety of the code (only the relevant changes). Here is the complete code block:This is also very interesting. I see you don't use pos.rule50_count() == 0 condition to probe TB.
Code: Select all
// Step 4a. Tablebase probe
if (!rootNode && TB::Cardinality)
{
int piecesCount = popcount(pos.pieces());
if ( piecesCount <= TB::Cardinality
&& (piecesCount < TB::Cardinality || depth >= TB::ProbeDepth)
&& pos.rule50_count() == 0
&& !pos.can_castle(ANY_CASTLING))
{
TB::ProbeState err;
TB::WDLScore v = Tablebases::probe_wdl(pos, &err);
if (err != TB::ProbeState::FAIL)
{
thisThread->tbHits.fetch_add(1, std::memory_order_relaxed);
int drawScore = TB::UseRule50 ? 1 : 0;
if ( abs(v) <= drawScore
|| !ttHit
|| (v < -drawScore && ttValue > -VALUE_KNOWN_WIN)
|| (v > drawScore && ttValue < VALUE_KNOWN_WIN))
{
value = v < -drawScore ? -VALUE_MATE_IN_MAX_PLY + ss->ply + (pos.non_pawn_material(pos.side_to_move()) - pos.non_pawn_material(~pos.side_to_move())) / 256
: v > drawScore ? VALUE_MATE_IN_MAX_PLY - ss->ply + (pos.non_pawn_material(pos.side_to_move()) - pos.non_pawn_material(~pos.side_to_move())) / 256
: VALUE_DRAW + v * drawScore;
tte->save(posKey, value_to_tt(value, ss->ply),
v > drawScore ? BOUND_LOWER : v < -drawScore ? BOUND_UPPER : BOUND_EXACT,
depth, MOVE_NONE, VALUE_NONE, TT.generation());
if (abs(v) <= drawScore)
return value;
}
}
}
}
Thanks for sharing. Another interesting thing that you do is to save with LOWER / BOUND_UPPER instead of always BOUND_EXACT as it is usually done. Can you pelase elaborate on that?jhellis3 wrote: I still use the rule50 count, I just did not post the entirety of the code (only the relevant changes). Here is the complete code block:
Code: Select all
<cut> tte->save(posKey, value_to_tt(value, ss->ply), v > drawScore ? BOUND_LOWER : v < -drawScore ? BOUND_UPPER : BOUND_EXACT, depth, MOVE_NONE, VALUE_NONE, TT.generation()); if (abs(v) <= drawScore) return value; <cut>
The generation time is ultimately based the size of the TB's. Using a 12 core Mac Pro with slightly older CPUs (x5690) was able to generate syzygy all 6 Man EGTB's in less than 72 hours - let's call it 60 hours . This is about 150 GB. The Syzygy 5 Man EGTB takes up about 1 GB. Should not take more than an hour or so to generate using all 8 cores on your machine - maybe even 45 minutes or faster It will take you more time to read the documentation and to make sure one is using the right commands Don't attempt to generate the 6 Man unless you have 32 GB of RAM. It can take advantage of multiple CPUs - just read the fine print.Nordlandia wrote:Ronald:
How long will it take to generate 5-men syzygy in DTM format on high-end hardware (in my case i7-5960X 8-core) and estimated volume with good compression technique?
The TB scores are saved as bounds because they are bounds.... as has been pointed out time and time again. This is not rocket science.Another interesting thing that you do is to save with LOWER / BOUND_UPPER instead of always BOUND_EXACT as it is usually done. Can you pelase elaborate on that?
Well, Bound Exact is only correct for draws, the result will never be greater than or less than a draw. But in the case of a TB win, that DTZ result implies mate eventually. To me, it certainly makes sense to treat a mate in X number of moves as greater value than mate eventually (and indeed this is the way they are actually scored in the engine), so use Bound Lower. Same principle applies to being mated.Thanks for sharing. Another interesting thing that you do is to save with LOWER / BOUND_UPPER instead of always BOUND_EXACT as it is usually done. Can you pelase elaborate on that?