Line data Source code
1 : #pragma once
2 :
3 : #include "definition.hpp"
4 :
5 : #ifdef WITH_NNUE
6 :
7 : #include "quantization.hpp"
8 : #include "stackVector.hpp"
9 : #include "weightReader.hpp"
10 :
11 : constexpr size_t inputLayerSize = FeatureIdx::major * FeatureIdx::minor;
12 : constexpr size_t firstInnerLayerSize = 384;
13 :
14 : template<typename NT, size_t dim0, size_t dim1, bool Q>
15 : struct InputLayer {
16 : static constexpr size_t nbW = dim0 * dim1;
17 : static constexpr size_t nbB = dim1;
18 :
19 : using BIT = typename Quantization<Q>::BIT;
20 : using WIT = typename Quantization<Q>::WIT;
21 :
22 : // often too big to be statically allocated (see CTOR/DTOR for dynamic alloc)
23 : typename Quantization<Q>::WIT* W {nullptr};
24 :
25 : // bias can be statically allocated
26 : alignas(NNUEALIGNMENT) BIT b[nbB];
27 :
28 : FORCE_FINLINE void insertIdx(const size_t idx, StackVector<BIT, nbB, Q>& x) const {
29 324993060 : const WIT* wPtr = W + idx * dim1;
30 517499686 : x.add_(wPtr);
31 : }
32 :
33 : FORCE_FINLINE void eraseIdx(const size_t idx, StackVector<BIT, nbB, Q>& x) const {
34 17744168 : const WIT* wPtr = W + idx * dim1;
35 342737228 : x.sub_(wPtr);
36 : }
37 :
38 44 : InputLayer<NT, dim0, dim1, Q>& load_(WeightsReader<NT>& ws) {
39 44 : ws.template streamWI<WIT, Q>(W, nbW)
40 44 : .template streamBI<BIT, Q>(b, nbB);
41 44 : return *this;
42 : }
43 :
44 : // non copyable
45 : InputLayer<NT, dim0, dim1, Q>& operator=(const InputLayer<NT, dim0, dim1, Q>& other) = delete;
46 : InputLayer<NT, dim0, dim1, Q>& operator=(InputLayer<NT, dim0, dim1, Q>&& other) = delete;
47 : InputLayer(const InputLayer<NT, dim0, dim1, Q>& other) = delete;
48 : InputLayer(InputLayer<NT, dim0, dim1, Q>&& other) = delete;
49 :
50 : InputLayer() {
51 : W = static_cast<WIT*>(operator new[](sizeof(WIT) * nbW, NNUEALIGNMENT_STD));
52 : }
53 :
54 : ~InputLayer() {
55 : ::operator delete(W, NNUEALIGNMENT_STD);
56 : }
57 : };
58 :
59 : #endif // WITH_NNUE
|