LargePagePtr<FeatureTransformer> featureTransformer;
// Evaluation function
- AlignedPtr<Network> network;
+ AlignedPtr<Network> network[LayerStacks];
// Evaluation function file name
std::string fileName;
void initialize() {
Detail::initialize(featureTransformer);
- Detail::initialize(network);
+ for (std::size_t i = 0; i < LayerStacks; ++i)
+ Detail::initialize(network[i]);
}
// Read network header
std::uint32_t version, size;
version = read_little_endian<std::uint32_t>(stream);
- *hashValue = read_little_endian<std::uint32_t>(stream);
+ *hashValue = read_little_endian<std::uint32_t>(stream);
size = read_little_endian<std::uint32_t>(stream);
if (!stream || version != Version) return false;
desc->resize(size);
if (!read_header(stream, &hashValue, &netDescription)) return false;
if (hashValue != HashValue) return false;
if (!Detail::read_parameters(stream, *featureTransformer)) return false;
- if (!Detail::read_parameters(stream, *network)) return false;
+ for (std::size_t i = 0; i < LayerStacks; ++i)
+ if (!Detail::read_parameters(stream, *(network[i]))) return false;
return stream && stream.peek() == std::ios::traits_type::eof();
}
if (!write_header(stream, HashValue, netDescription)) return false;
if (!Detail::write_parameters(stream, *featureTransformer)) return false;
- if (!Detail::write_parameters(stream, *network)) return false;
+ for (std::size_t i = 0; i < LayerStacks; ++i)
+ if (!Detail::write_parameters(stream, *(network[i]))) return false;
return (bool)stream;
}
// Evaluation function. Perform differential calculation.
- Value evaluate(const Position& pos) {
+ Value evaluate(const Position& pos, bool adjusted) {
// We manually align the arrays on the stack because with gcc < 9.3
// overaligning stack variables with alignas() doesn't work correctly.
ASSERT_ALIGNED(transformedFeatures, alignment);
ASSERT_ALIGNED(buffer, alignment);
- featureTransformer->transform(pos, transformedFeatures);
- const auto output = network->propagate(transformedFeatures, buffer);
+ const std::size_t bucket = (pos.count<ALL_PIECES>() - 1) / 4;
+ const auto psqt = featureTransformer->transform(pos, transformedFeatures, bucket);
+ const auto output = network[bucket]->propagate(transformedFeatures, buffer);
- return static_cast<Value>(output[0] / OutputScale);
+ int materialist = psqt;
+ int positional = output[0];
+
+ int delta_npm = abs(pos.non_pawn_material(WHITE) - pos.non_pawn_material(BLACK));
+ int entertainment = (adjusted && delta_npm <= BishopValueMg - KnightValueMg ? 7 : 0);
+
+ int A = 128 - entertainment;
+ int B = 128 + entertainment;
+
+ int sum = (A * materialist + B * positional) / 128;
+
+ return static_cast<Value>( sum / OutputScale );
}
// Load eval, from a file stream or a memory stream