Marco Costalba [Tue, 15 Aug 2017 08:05:22 +0000 (01:05 -0700)]
Restore perft
Rewrite perft to be placed naturally inside new
bench code. In particular we don't have special
custom code to run perft anymore but perft is
just a new parameter of 'go' command.
Marco Costalba [Wed, 16 Aug 2017 09:28:54 +0000 (02:28 -0700)]
Speed up Trevis CI
Avoid a couple of redundant rebuilds and compile
with 2 threads since travis gives 2vCPUs.
Also enable -O1 optimization for valgrind and
sanitizers, it should be safe withouth false
positives and it gives a very sensible speed
up, especially with valgrind.
The spee dup allow us to increase testing to
depth 10, useful for thread sanitizer.
This time management handles base time and movestogo cases separatelly. One can test one case without affecting the other. Also, increment usage can be tested separately without (necessarily) affecting sudden death or x moves in y seconds performance.
On stable machines there are no time losses on 0.1+0.001 time control (tested on i7 + Windows 10 platform).
Marco Costalba [Mon, 14 Aug 2017 16:12:16 +0000 (09:12 -0700)]
Fix incorrect StateInfo
We use Position::set() to set root position across
threads. But there are some StateInfo fields (previous,
pliesFromNull, capturedPiece) that cannot be deduced
from a fen string, so set() clears them and to not lose
the info we need to backup and later restore setupStates->back().
Note that setupStates is shared by threads but is accessed
in read-only mode.
I have not fixed all suggestions, for instance I still prefer
to declare the type instead of a spread use of 'auto'. I also
perfer good old 'typedef' to the new 'using' form.
I have not fixed some warnings in the last functions of
syzygy code because those are still the original functions
and need to be completely rewritten anyhow.
tthsqe12 [Sat, 12 Aug 2017 08:50:38 +0000 (10:50 +0200)]
Fix the handling of opposite bishops in KXK endgame evaluation
The case of three or more bishops against a long king must look at all of the
bishops and not just the first two in the piece lists. This patch makes sure
that the position is treated as a win when there are bishops on opposite
colors. This functional change is very small because bench remains the same.
Marco Costalba [Thu, 10 Aug 2017 19:32:50 +0000 (12:32 -0700)]
Re-apply the fix for Limits::ponder race
But this time correctly set Threads.ponder
We avoid using 'limits' for passing pondering
flag because we don't want to have 2 ponder
variables in search scope: Search::Limits.ponder
and Threads.ponder. This would be confusing also
because limits.ponder is set at the beginning of
the search and never changes, instead Threads.ponder
can change value asynchronously during search.
Limits::ponder was used as a signal between uci and search threads,
but is not an atomic variable, leading to the following race as
flagged by a sanitized binary.
Marco Costalba [Sun, 6 Aug 2017 11:43:02 +0000 (04:43 -0700)]
Fix some races and clarify the code
Better split code that should be run at
startup from code run at ucinewgame. Also
fix several races when 'bench', 'perft' and
'ucinewgame' are sent just after 'bestomve'
from the engine threads are still running.
Also use a specific UI thread instead of
main thread when setting up the Position
object used by UI uci loop. This fixes a
race when sending 'eval' command while searching.
We accept a race on 'setoption' to allow the
GUI to change an option while engine is searching
withouth stalling the pipe. Note that changing an
option while searchingg is anyhow not mandated by
UCI protocol.
as a lower level routine, movepicker should not depend on the
search stack or the thread class, removing a circular dependency.
Instead of copying the search stack into the movepicker object,
as well as accessing the thread class for one of the histories,
pass the required fields explicitly to the constructor (removing
the need for thread.h and implicitly search.h in movepick.cpp).
The signature is thus longer, but more explicit:
Also some renaming of histories structures while there.
Rocky640 [Wed, 2 Aug 2017 01:36:33 +0000 (18:36 -0700)]
Rework the "unsupported" penalty into a "supported" bonus
A pawn (according to all the searched positions of a bench run) is not supported 85% of the time,
(in current master it is either isolated, backward or "unsupported").
So it made sense to try moving the S(17, 8) "unsupported" penalty value into the base pawn value hoping for a more representative pawn value, and accordingly
a) adjust backward and isolated so that they stay more or less the same as master
b) increase the mg connected bonus in the supported case by S(17, 0) and let the Connected formula find a suitable eg value according to rank.
in the last month a couple of timeouts have been seen in travis valgrind testing, leading to undesired false positives. The precise cause of this is unclear: a normal valgrind instrumented run is about 6min, the timeout is 10min. Either there are rare hangs (not reproduced locally), or maybe the actual runtime fluctuates on the travis infrastructure (which uses VMs on AWS as far as I know). This patch leads to roughly a 2x speedup of the instrumented testing by reducing the depth from 10 to 9. If timeouts persist, it needs further analysis.
Instead of having Signals in the search namespace,
make the stop variables part of the Threads structure.
This moves more of the shared (atomic) variables towards
the thread-related structures, making their role more clear.
Marco Costalba [Sun, 2 Jul 2017 10:10:50 +0000 (03:10 -0700)]
Don't uselessy share rootDepth
It is not needed becuase the only case is a real special
one (bench on depth with many threads) and can be easily
rewritten to avoid sharing rootDepth.
Marco Costalba [Sun, 2 Jul 2017 11:39:58 +0000 (13:39 +0200)]
Fix some warnings with clang static analyzer
Only one remains (also in tbprobe.cpp), but is bougus.
As a side note, tbprobe.cpp is almost clean, only the last 3
functions probe_wdl(), root_probe() and root_probe_wdl()
are still the original ones and are quite hacky.
Somewhere in the future we will reformat also the last 3
ones. The reason why has not been done before it is because
these functions are really wrong by design and should be
rewritten entirely, not only reformatted.
Marco Costalba [Sat, 24 Jun 2017 05:15:46 +0000 (07:15 +0200)]
Only main thread checks time
The main change of the patch is that now time check
is done only by main thread. In the past, before lazy
SMP, we needed all the threds to check for available
time because main thread could have been blocked on
a split point, now this is no more the case and main
thread can do the job alone, greatly simplifying the logic.
Verified for regression testing on STC with 7 threads:
LLR: 2.96 (-2.94,2.94) [-3.00,1.00]
Total: 11895 W: 1741 L: 1608 D: 8546
snicolet [Wed, 21 Jun 2017 21:01:59 +0000 (14:01 -0700)]
Improve readability of evaluation functions
This patch puts the evaluation helper functions inside EvalInfo struct, which simplifies a bit their signature and (most importantly, IMHO) makes their C++ code much cleaner and simpler to read (by removing the "ei." qualifiers all around in evaluate.cpp).
Also rename the EvalInfo struct into Evaluation class to get a natural invocation v = Evaluation(p).value() to evaluation position p.
The downside is an increase of 20 lines in evaluate.cpp (for the prototypes of the helper functions). The upsides are better readability and a speed-up of 0.6% (by generating all the helpers for the NO_TRACE case together, which helps the instruction cache).
the nodes, tbHits, rootDepth and lastInfoTime variables are read by multiple threads, but not declared atomic, leading to data races as found by -fsanitize=thread. This patch fixes this issue. It is based on top of the CI-threading branch (PR #1129), and should fix the corresponding CI error messages.
Whereas rootDepth and lastInfoTime are not performance critical, nodes and tbHits are. Indeed, an earlier version using relaxed atomic updates on the latter two variables failed STC testing (http://tests.stockfishchess.org/tests/view/592001700ebc59035df34924), which can be shown to be due to x86-32 (http://tests.stockfishchess.org/tests/view/592330ac0ebc59035df34a89). Indeed, the latter have no instruction to atomically update a 64bit variable. The proposed solution thus uses a variable in Position that is accessed only by one thread, which is copied every few thousand nodes to the shared variable in Thread.
TT.new_search() was being called by mainThread in Thread::search(). However, mainThread is the last to start searching, and helper threads could reach a measured rootDepth 10 (on 64 cores) before mainThread increments the TT generation. Fixed by moving the call to MaintThread::search() before helper threads start searching.
atumanian [Tue, 6 Jun 2017 17:13:10 +0000 (10:13 -0700)]
Don't score as an immediate draw 2-fold repetitions of the root position
In the current version a search stops when the current position is the same as
any position earlier in the search stack,
including the root position but excluding positions before the root.
The new version makes an exception for repeating the root position.
This gives correct scores for moves in the MultiPV > 1 mode.
Fixes #948 (see it for the detailed description of the bug).
Marco Costalba [Fri, 26 May 2017 06:42:50 +0000 (08:42 +0200)]
History code rewrite (#1122)
Rearrange and rename all history heuristic code. Naming
is now based on chessprogramming.wikispaces.com conventions
and the relations among the various heuristics are now more
clear and consistent.
snicolet [Thu, 18 May 2017 01:23:07 +0000 (18:23 -0700)]
Do check analysis later in the game
The previous patch has added a fraction of the king danger score to the
endgame score of the tapered eval, so it seems natural to perform the
king danger computation later in the endgame.
With this patch we extend the limit of such check analysis down to the
material of Rook+Knight, when we have at least two pieces attacking the
opponent king zone.
snicolet [Thu, 18 May 2017 01:19:47 +0000 (18:19 -0700)]
Use a fraction of king danger in endgame score
When SF has an attack on the opponent king in one flank, the huge
midgame -> endgame gradient of the tapered eval prevents us to properly
evaluate neutral exchanges on the other flank as the current king
danger score is a pure midgame term. This may affect SF's ability to
switch to defense in some positions. We add a small contribution
of the king danger to the endgame score to limit this
effect.
Again suggested in the following forum thread:
https://groups.google.com/forum/?fromgroups=#!topic/fishcooking/xrUCQ7b0ObE
Fixes a bug in Search::clear, where the filling of CounterMoveStats&, overwrote (currently presumably unused) memory because sizeof(cm) returns the size in bytes, whereas elements was needed.
snicolet [Tue, 16 May 2017 02:26:27 +0000 (19:26 -0700)]
Limit king ring to eight squares
In current master the size of the king ring varies abruptly from eight
squares when the king is in g8, to 12 squares when it is in g7. Because
the king ring is used for estimating attack strength, this may lead to
an overestimation of king danger in some positions. This patch limits
the king ring to eight squares in all cases.
Inspired by the following forum thread:
https://groups.google.com/forum/?fromgroups=#!topic/fishcooking/xrUCQ7b0ObE
execute an implied ucinewgame upon entering the UCI::loop,
to make sure that searches starting with and without an (optional) ucinewgame
command yield the same search.
This is needed now that seach::clear() initializes tables to non-zero default values.
mstembera [Mon, 8 May 2017 03:14:23 +0000 (20:14 -0700)]
Avoid *begin always being included in the sorted list regardless of its value.
This was a minor criticism by @zamar in the original pull request
https://github.com/official-stockfish/Stockfish/pull/1065
necessitating a comment explanation.
joergoster [Thu, 4 May 2017 02:46:40 +0000 (19:46 -0700)]
Fix multiPV issue #502
In general, this patch handles the cases where we don't have a valid score for each PV line in a multiPV search. This can happen if the search has been stopped in an unfortunate moment while still in the aspiration loop. The patch consists of two parts.
Part 1: The new PVIdx was already part of the k-best pv's in the last iteration, and we therefore have a valid pv and score to output from the last iteration. This is taken care of with:
bool updated = (i <= PVIdx && rootMoves[i].score != -VALUE_INFINITE);
Case 2: The new PVIdx was NOT part of the k-best pv's in the last iteration, and we have no valid pv and score to output. Not from the current nor from the previous iteration. To avoid this, we are now also considering the previous score when sorting, so that the PV lines with no actual but with a valid previous score are pushed up again, and the previous score can be displayed.
Testing the release candidate revealed only one minor issue, namely a new warning -Wimplicit-fallthrough (part of -Wextra) triggers in the movepicker. This can be silenced by adding a comment, and once we move to c++17 by adding a standard annotation [[fallthrough]];.
Marco Costalba [Sat, 29 Apr 2017 03:33:30 +0000 (20:33 -0700)]
Retire the misdesigned StepAttacks[] array.
StepAttacks[] is misdesigned, the color dependance is specific
to pawns, and trying to generalise to king and knights, proves
neither useful nor convinient in practice.
So this patch reformats the code with the following changes:
- Use PieceType instead of Piece in attacks_() functions
ss->killers can change while the movepicker is active.
The reason ss->killers changes is related to the singular
extension search in the moves loop that calls search<>
recursively with ss instead of ss+1,
effectively using the same stack entry for caller and callee.
By making a copy of the killers,
the movepicker does the right thing nevertheless.
Use int instead of Value for history related stats.
history related scores are not related to evaluation based scores.
For example, can easily exceed the range -VALUE_INFINITE,VALUE_INFINITE.
As such the current type is confusing, and a plain int is a better match.
the order of elements returned by std::partition is implementation defined (since not stable) and could depend on the version of libstdc++ linked.
As std::stable_partition was tested to be too slow (http://tests.stockfishchess.org/tests/view/585cdfd00ebc5903140c6082).
Instead combine partition with our custom implementation of insert_sort, which fixes this issue.
Implementation based on a patch by mstembera (http://tests.stockfishchess.org/tests/view/58d4d3460ebc59035df3315c), which suggests some benefit by itself.
Higher depth moves are all sorted (INT_MIN version), as in current master.
It is worth noting that an attempt to only increase the bonus passed STC but failed LTC, and
an attempt to remove the cap without increasing the bonus is still running at STC, but will probably fail after more than 100k.
By adding pos.non_pawn_material(pos.side_to_move()) as a precondition in step 13,
which is already in use in Futility Pruning (child node) and Null Move Pruning for similar reasons.
Pawn endgames, especially those with only 1 or 2 pawns, are simply heavily influenced by zugzwang situations.
Since we are using a bitbase for KPK endgames, I see no reason to accept buggy evals as shown in #760
a single Xeon Phi can present itself as a single numa node with up to 288 threads (4 threads per hardware core).
Tested to work as expected with a Xeon Phi CPU 7230 up to 256 threads.