Closed lewis-carson closed 2 months ago
Hello, thanks for sharing the issue in detail. After having gone through each of the code samples, I have only been able to replicate the crash in the last case which is expected.
What pos.reset()
does is set the NNUE's "root position" to the current position meaning you will not be able to unmake any further than that position. This is poor naming on my end and I will be looking to refactor the engine code in the following days.
I replicated your examples by pasting the pieces of code you shared into the main function in the main.rs file and adding the proper imports. These are the results I am getting:
Evaluation { score: -168 }
Evaluation { score: 241 }
thread 'main' panicked at src/bm/nnue/mod.rs:408:47:
called `Option::unwrap()` on a `None` value
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
With the third one being expected for the previously mentioned reason.
I have a few guesses as to why the issue could be occuring:
50f28079
if you would like to confirm this regardless. If this is the issue, it is probably related to git lfs not having pulled the latest file and is resolvable by git lfs pull
.All the issues aside, if you would like to be able to separate the NNUE component without doing any extra work yourself or any other component for that matter, please let me know via another issue and I will work on making the engine more modular and also more exhaustively document the code.
This is very odd! Thanks for such a quick and thorough reply. I really don't mean to give you any more work and I am not suggesting you change the engine at all on my behalf. Compiling the original blackmarlin repo (from which I extracted the NNUE) works flawlessly (with the default.bin) the same. build.rs
is also the same. Confirming, the sha256 hash is:
50f280793f71370e6330c768bdf431b51676def4b2b0a7ee21ee07f6d1d4ed1f
Here's what my folder structure looks like for my own, seperated module:
nnue
├── eval.rs
├── include.rs
├── layers.rs
├── mod.rs
├── position.rs
├── threats.rs
└── zobrist.rs
With the relevant exports adjusted. No file within this has been modified otherwise.
This is very curious!
I've created a repo which contains a minimally reproducible example.
Hello, I have tracked down the issue. It occurs because Black Marlin NNUE relies on search max ply. This is done as the NNUE keeps track of a relatively large accumulator for every search ply and the engine normally guarantees that the search won't get deeper than the given ply.
Applying the following patch will fix the issue however you will probably want to modify the code in a way that either extends the accumulator stack as more is needed or have it as a parameter.
diff --git a/src/nnue/mod.rs b/src/nnue/mod.rs
index 1b42255..53f50e8 100644
--- a/src/nnue/mod.rs
+++ b/src/nnue/mod.rs
@@ -136,7 +136,7 @@ impl Nnue {
Accumulator {
w_acc: incremental_bias,
b_acc: incremental_bias
- }
+ }; 128
],
w_input_layer: input_layer.clone(),
b_input_layer: input_layer,
You can also remove zobrist.rs
and everywhere it is used. It will not affect the evaluation or position's functionality in any way.
I've got it fixed on my end! Thanks for having a look. How does blackmarlin increase the size of the accumulator stack? I can't find it anywhere.
It does not increase the size of the stack because it's guaranteed to never search deeper than the specified amount within search. I can provide a version where this is done if it is going to prove useful for your use case of the NNUE.
Hi, I'm experimenting with the NNUE portion of blackmarlin. To do so, I've isolated the file involved with pure evaluation and removed the search component of the engine. I'm running into a few issues calling the eval function after making/unmaking moves. Maybe you could shed some light on this because I am completely lost here.
The following works:
The following does not work:
Producing the following error:
However, this does work when
reset()
is called aftermake_move
which, to my understanding, recalculates the accumulators. This seems counterintuitive in that a NNUE should not have to be reset after eachmake_move
which defeats the purpose of being efficiently updatable.With respect to
unmake_move
, the following does not work:Resulting in the following error:
Perhaps you could shed some light on this. Thank you for your time!
Lewis