// 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)
// 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)
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];
&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*>(
#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;
#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
}
#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
}
#endif
accumulator.computed_accumulation = true;
- accumulator.computed_score = false;
}
using BiasType = std::int16_t;