Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 4 additions & 34 deletions src/nnue/evaluate_nnue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,31 +115,16 @@ namespace Eval::NNUE {
return stream && stream.peek() == std::ios::traits_type::eof();
}

// Proceed with the difference calculation if possible
static void UpdateAccumulatorIfPossible(const Position& pos) {

feature_transformer->UpdateAccumulatorIfPossible(pos);
}

// Calculate the evaluation value
static Value ComputeScore(const Position& pos, bool refresh) {

auto& accumulator = pos.state()->accumulator;
if (!refresh && accumulator.computed_score) {
return accumulator.score;
}
// Evaluation function. Perform differential calculation.
Value evaluate(const Position& pos) {

alignas(kCacheLineSize) TransformedFeatureType
transformed_features[FeatureTransformer::kBufferSize];
feature_transformer->Transform(pos, transformed_features, refresh);
feature_transformer->Transform(pos, transformed_features);
alignas(kCacheLineSize) char buffer[Network::kBufferSize];
const auto output = network->Propagate(transformed_features, buffer);

auto score = static_cast<Value>(output[0] / FV_SCALE);

accumulator.score = score;
accumulator.computed_score = true;
return accumulator.score;
return static_cast<Value>(output[0] / FV_SCALE);
}

// Load eval, from a file stream or a memory stream
Expand All @@ -150,19 +135,4 @@ namespace Eval::NNUE {
return ReadParameters(stream);
}

// Evaluation function. Perform differential calculation.
Value evaluate(const Position& pos) {
return ComputeScore(pos, false);
}

// Evaluation function. Perform full calculation.
Value compute_eval(const Position& pos) {
return ComputeScore(pos, true);
}

// Proceed with the difference calculation if possible
void update_eval(const Position& pos) {
UpdateAccumulatorIfPossible(pos);
}

} // namespace Eval::NNUE
2 changes: 0 additions & 2 deletions src/nnue/nnue_accumulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ namespace Eval::NNUE {
struct alignas(kCacheLineSize) Accumulator {
std::int16_t
accumulation[2][kRefreshTriggers.size()][kTransformedFeatureDimensions];
Value score;
bool computed_accumulation;
bool computed_score;
};

} // namespace Eval::NNUE
Expand Down
58 changes: 25 additions & 33 deletions src/nnue/nnue_feature_transformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ namespace Eval::NNUE {

// Hash value embedded in the evaluation file
static constexpr std::uint32_t GetHashValue() {

return RawFeatures::kHashValue ^ kOutputDimensions;
}

// Read network parameters
bool ReadParameters(std::istream& stream) {

for (std::size_t i = 0; i < kHalfDimensions; ++i)
biases_[i] = read_little_endian<BiasType>(stream);
for (std::size_t i = 0; i < kHalfDimensions * kInputDimensions; ++i)
Expand All @@ -64,23 +66,26 @@ namespace Eval::NNUE {

// Proceed with the difference calculation if possible
bool UpdateAccumulatorIfPossible(const Position& pos) const {

const auto now = pos.state();
if (now->accumulator.computed_accumulation) {
if (now->accumulator.computed_accumulation)
return true;
}

const auto prev = now->previous;
if (prev && prev->accumulator.computed_accumulation) {
UpdateAccumulator(pos);
return true;
}

return false;
}

// Convert input features
void Transform(const Position& pos, OutputType* output, bool refresh) const {
if (refresh || !UpdateAccumulatorIfPossible(pos)) {
void Transform(const Position& pos, OutputType* output) const {

if (!UpdateAccumulatorIfPossible(pos))
RefreshAccumulator(pos);
}

const auto& accumulation = pos.state()->accumulator.accumulation;

#if defined(USE_AVX2)
Expand Down Expand Up @@ -177,6 +182,7 @@ namespace Eval::NNUE {
private:
// Calculate cumulative value without using difference calculation
void RefreshAccumulator(const Position& pos) const {

auto& accumulator = pos.state()->accumulator;
IndexType i = 0;
Features::IndexList active_indices[2];
Expand Down Expand Up @@ -216,9 +222,8 @@ namespace Eval::NNUE {
&accumulator.accumulation[perspective][i][0]);
auto column = reinterpret_cast<const __m64*>(&weights_[offset]);
constexpr IndexType kNumChunks = kHalfDimensions / (kSimdWidth / 2);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = _mm_add_pi16(accumulation[j], column[j]);
}

#elif defined(USE_NEON)
auto accumulation = reinterpret_cast<int16x8_t*>(
Expand All @@ -240,11 +245,11 @@ namespace Eval::NNUE {
#endif

accumulator.computed_accumulation = true;
accumulator.computed_score = false;
}

// Calculate cumulative value using difference calculation
void UpdateAccumulator(const Position& pos) const {

const auto prev_accumulator = pos.state()->previous->accumulator;
auto& accumulator = pos.state()->accumulator;
IndexType i = 0;
Expand Down Expand Up @@ -288,33 +293,27 @@ namespace Eval::NNUE {

#if defined(USE_AVX2)
auto column = reinterpret_cast<const __m256i*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = _mm256_sub_epi16(accumulation[j], column[j]);
}

#elif defined(USE_SSE2)
auto column = reinterpret_cast<const __m128i*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = _mm_sub_epi16(accumulation[j], column[j]);
}

#elif defined(USE_MMX)
auto column = reinterpret_cast<const __m64*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = _mm_sub_pi16(accumulation[j], column[j]);
}

#elif defined(USE_NEON)
auto column = reinterpret_cast<const int16x8_t*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = vsubq_s16(accumulation[j], column[j]);
}

#else
for (IndexType j = 0; j < kHalfDimensions; ++j) {
accumulator.accumulation[perspective][i][j] -=
weights_[offset + j];
}
for (IndexType j = 0; j < kHalfDimensions; ++j)
accumulator.accumulation[perspective][i][j] -= weights_[offset + j];
#endif

}
Expand All @@ -325,33 +324,27 @@ namespace Eval::NNUE {

#if defined(USE_AVX2)
auto column = reinterpret_cast<const __m256i*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = _mm256_add_epi16(accumulation[j], column[j]);
}

#elif defined(USE_SSE2)
auto column = reinterpret_cast<const __m128i*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = _mm_add_epi16(accumulation[j], column[j]);
}

#elif defined(USE_MMX)
auto column = reinterpret_cast<const __m64*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = _mm_add_pi16(accumulation[j], column[j]);
}

#elif defined(USE_NEON)
auto column = reinterpret_cast<const int16x8_t*>(&weights_[offset]);
for (IndexType j = 0; j < kNumChunks; ++j) {
for (IndexType j = 0; j < kNumChunks; ++j)
accumulation[j] = vaddq_s16(accumulation[j], column[j]);
}

#else
for (IndexType j = 0; j < kHalfDimensions; ++j) {
accumulator.accumulation[perspective][i][j] +=
weights_[offset + j];
}
for (IndexType j = 0; j < kHalfDimensions; ++j)
accumulator.accumulation[perspective][i][j] += weights_[offset + j];
#endif

}
Expand All @@ -362,7 +355,6 @@ namespace Eval::NNUE {
#endif

accumulator.computed_accumulation = true;
accumulator.computed_score = false;
}

using BiasType = std::int16_t;
Expand Down
2 changes: 0 additions & 2 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,6 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {

// Used by NNUE
st->accumulator.computed_accumulation = false;
st->accumulator.computed_score = false;
auto& dp = st->dirtyPiece;
dp.dirty_num = 1;

Expand Down Expand Up @@ -1000,7 +999,6 @@ void Position::do_null_move(StateInfo& newSt) {
if (Eval::useNNUE)
{
std::memcpy(&newSt, st, sizeof(StateInfo));
st->accumulator.computed_score = false;
}
else
std::memcpy(&newSt, st, offsetof(StateInfo, accumulator));
Expand Down