Hacking around CFish NNUE

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
maksimKorzh
Posts: 775
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: Hacking around CFish NNUE

Post by maksimKorzh »

Daniel Shawul wrote: Fri Oct 16, 2020 2:49 am
maksimKorzh wrote: Fri Oct 16, 2020 2:22 am
Daniel Shawul wrote: Fri Oct 16, 2020 12:56 am I just finished implementing the library without incremental updates.

https://github.com/dshawul/nnue-probe.git

It has a FEN interface and a pieces[],squares[] interface as well

Code: Select all

DLLExport void _CDECL nnue_init(const char * evalFile);
DLLExport int _CDECL nnue_evaluate(int player, int* pieces, int* squares);
DLLExport int _CDECL nnue_evaluate_fen(const char* fen);
Funny thing is that incremental updates gives only 4.5% speedup on the start position that it may not be worth it at all.
The "NNUE" implementation below was directly implemented in my engine with all the incremental update etc.
The "NNUE without increment" is through the library.

Code: Select all

No NNUE                         = 2100 knps
NNUE                            = 1400 knps
NNUE without increment          = 1337 knps
NNUE without increment + memcpy = 1100 knps
NNUE is about 65% of the speed of classic.
NNUE without incremntal evaluation is just 4.5% slower on the start position.
When I added the updates in makemove with memcpy for Accumulator/DirtyPiece it was 14-18% slower.
But without it, it is so small not to worry about at all.
I've retrieved the score via FEN:

Code: Select all

int main()
{
    nnue_init("nn-04cf2b4ed1da.nnue");
    int score = nnue_evaluate_fen("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1");
    printf("score: %d\n", score);
    return 0;
}
But what confuses me slightly a bit is the output score (probably I'm doing something wrong)
e.g. above code gives output: 108
while same network in JS interface gives: 57 (0.28)

to try it yourself you can navigate here: file:///home/maksim/Desktop/nnue.html -> go to NNUE tab, download network (I used nn-04cf2b4ed1da.nnue from https://tests.stockfishchess.org/nns)

Is this the matter of different implementations or I did something horribly wrong?
There was a bug that I just fixed with decoding FEN.
Here is how you probe it from FEN

Code: Select all

from ctypes import *
nnue = cdll.LoadLibrary("libnnueprobe.so")
nnue.nnue_init("/home/daniel/Scorpio/nets-scorpio/nn-baeb9ef2d183.nnue")
score = nnue.nnue_evaluate_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
print "Score = ", score
I'm a bit confused with following error when compiling test.c wilt libnnue.so:

Code: Select all

In file included from nnue.h:4:0,
                 from test.c:1:
misc.h:52:41: error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
 void decode_fen(const char* fen_str, int& player, int& castle,
                                         ^
In file included from test.c:1:0:
nnue.h:44:3: error: expected specifier-qualifier-list before ‘alignas’
   alignas(64) int16_t accumulation[2][256];
   ^~~~~~~
nnue.h:59:19: error: unknown type name ‘Position’
 int nnue_evaluate(Position* pos);
                   ^~~~~~~~
nnue.h:15:29: error: expected identifier or ‘(’ before string constant
 #   define DLLExport extern "C"
                             ^
nnue.h:64:1: note: in expansion of macro ‘DLLExport’
 DLLExport void _CDECL nnue_init(
 ^~~~~~~~~
nnue.h:15:29: error: expected identifier or ‘(’ before string constant
 #   define DLLExport extern "C"
                             ^
nnue.h:71:1: note: in expansion of macro ‘DLLExport’
 DLLExport int _CDECL nnue_evaluate_fen(
 ^~~~~~~~~
nnue.h:15:29: error: expected identifier or ‘(’ before string constant
 #   define DLLExport extern "C"
                             ^
nnue.h:91:1: note: in expansion of macro ‘DLLExport’
 DLLExport int _CDECL nnue_evaluate(
 ^~~~~~~~~
test.c: In function ‘main’:
test.c:5:5: warning: implicit declaration of function ‘nnue_init’ [-Wimplicit-function-declaration]
     nnue_init("nn-04cf2b4ed1da.nnue");
comiling command:

Code: Select all

gcc -L/home/maksim/Desktop/nnue-probe/src test.c -lnnueprobe -o test
source of test.c

Code: Select all

#include "nnue.h"

int main()
{
    nnue_init("nn-04cf2b4ed1da.nnue");

    return 0;
}
User avatar
maksimKorzh
Posts: 775
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: Hacking around CFish NNUE

Post by maksimKorzh »

maksimKorzh wrote: Fri Oct 16, 2020 12:23 pm
Daniel Shawul wrote: Fri Oct 16, 2020 2:49 am
maksimKorzh wrote: Fri Oct 16, 2020 2:22 am
Daniel Shawul wrote: Fri Oct 16, 2020 12:56 am I just finished implementing the library without incremental updates.

https://github.com/dshawul/nnue-probe.git

It has a FEN interface and a pieces[],squares[] interface as well

Code: Select all

DLLExport void _CDECL nnue_init(const char * evalFile);
DLLExport int _CDECL nnue_evaluate(int player, int* pieces, int* squares);
DLLExport int _CDECL nnue_evaluate_fen(const char* fen);
Funny thing is that incremental updates gives only 4.5% speedup on the start position that it may not be worth it at all.
The "NNUE" implementation below was directly implemented in my engine with all the incremental update etc.
The "NNUE without increment" is through the library.

Code: Select all

No NNUE                         = 2100 knps
NNUE                            = 1400 knps
NNUE without increment          = 1337 knps
NNUE without increment + memcpy = 1100 knps
NNUE is about 65% of the speed of classic.
NNUE without incremntal evaluation is just 4.5% slower on the start position.
When I added the updates in makemove with memcpy for Accumulator/DirtyPiece it was 14-18% slower.
But without it, it is so small not to worry about at all.
I've retrieved the score via FEN:

Code: Select all

int main()
{
    nnue_init("nn-04cf2b4ed1da.nnue");
    int score = nnue_evaluate_fen("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1");
    printf("score: %d\n", score);
    return 0;
}
But what confuses me slightly a bit is the output score (probably I'm doing something wrong)
e.g. above code gives output: 108
while same network in JS interface gives: 57 (0.28)

to try it yourself you can navigate here: file:///home/maksim/Desktop/nnue.html -> go to NNUE tab, download network (I used nn-04cf2b4ed1da.nnue from https://tests.stockfishchess.org/nns)

Is this the matter of different implementations or I did something horribly wrong?
There was a bug that I just fixed with decoding FEN.
Here is how you probe it from FEN

Code: Select all

from ctypes import *
nnue = cdll.LoadLibrary("libnnueprobe.so")
nnue.nnue_init("/home/daniel/Scorpio/nets-scorpio/nn-baeb9ef2d183.nnue")
score = nnue.nnue_evaluate_fen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
print "Score = ", score
I'm a bit confused with following error when compiling test.c wilt libnnue.so:

Code: Select all

In file included from nnue.h:4:0,
                 from test.c:1:
misc.h:52:41: error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
 void decode_fen(const char* fen_str, int& player, int& castle,
                                         ^
In file included from test.c:1:0:
nnue.h:44:3: error: expected specifier-qualifier-list before ‘alignas’
   alignas(64) int16_t accumulation[2][256];
   ^~~~~~~
nnue.h:59:19: error: unknown type name ‘Position’
 int nnue_evaluate(Position* pos);
                   ^~~~~~~~
nnue.h:15:29: error: expected identifier or ‘(’ before string constant
 #   define DLLExport extern "C"
                             ^
nnue.h:64:1: note: in expansion of macro ‘DLLExport’
 DLLExport void _CDECL nnue_init(
 ^~~~~~~~~
nnue.h:15:29: error: expected identifier or ‘(’ before string constant
 #   define DLLExport extern "C"
                             ^
nnue.h:71:1: note: in expansion of macro ‘DLLExport’
 DLLExport int _CDECL nnue_evaluate_fen(
 ^~~~~~~~~
nnue.h:15:29: error: expected identifier or ‘(’ before string constant
 #   define DLLExport extern "C"
                             ^
nnue.h:91:1: note: in expansion of macro ‘DLLExport’
 DLLExport int _CDECL nnue_evaluate(
 ^~~~~~~~~
test.c: In function ‘main’:
test.c:5:5: warning: implicit declaration of function ‘nnue_init’ [-Wimplicit-function-declaration]
     nnue_init("nn-04cf2b4ed1da.nnue");
comiling command:

Code: Select all

gcc -L/home/maksim/Desktop/nnue-probe/src test.c -lnnueprobe -o test
source of test.c

Code: Select all

#include "nnue.h"

int main()
{
    nnue_init("nn-04cf2b4ed1da.nnue");

    return 0;
}
Above errors are fixed by using g++ instead of gcc
User avatar
Andres Valverde
Posts: 565
Joined: Sun Feb 18, 2007 11:07 pm
Location: Almeria. SPAIN
Full name: Andres Valverde Toresano

Re: Hacking around CFish NNUE

Post by Andres Valverde »

Hi all,

Anyone has comiled the 32 bit DLL from :

https://github.com/dshawul/nnue-probe

Thanks in advance
Saludos, Andres
User avatar
Andres Valverde
Posts: 565
Joined: Sun Feb 18, 2007 11:07 pm
Location: Almeria. SPAIN
Full name: Andres Valverde Toresano

Re: Hacking around CFish NNUE

Post by Andres Valverde »

Andres Valverde wrote: Mon Sep 23, 2024 3:38 pm Hi all,

Anyone has comiled the 32 bit DLL from :

https://github.com/dshawul/nnue-probe

Thanks in advance
Managed to do it myself. Thanks
Saludos, Andres