Page 1 of 2

Extract line from Sf bench command

Posted: Thu Jan 02, 2014 11:15 am
by quantum
I want to redirect the last line of Stockfish's bench output to a textfile on Ubuntu_64.

When I change line 155 in benchmark.cpp

Code: Select all

cerr << "\n==========================="
       << "\nTotal time (ms) : " << elapsed
       << "\nNodes searched  : " << nodes
       << "\nNodes/second    : " << 1000 * nodes / elapsed << endl;
to

Code: Select all

cout << "\n==========================="
       << "\nTotal time (ms) : " << elapsed
       << "\nNodes searched  : " << nodes
       << "\nNodes/second    : " << 1000 * nodes / elapsed << endl;
I can use
./stockfish bench > bench.txt && tail -1 bench.txt >> speed.csv
to do the job. When I run bench three times in a row my file looks as follows:

Code: Select all

Nodes/second    : 1074200
Nodes/second    : 1078206
Nodes/second    : 1065217
I now want to do the same with other compiles I find on the internet (e.g. abrok.eu) but I fail badly. Any idea on how to get there?

Re: Extract line from Sf bench command

Posted: Thu Jan 02, 2014 11:41 am
by Jeremy Bernstein
Why don't you just redirect stderr (and stdout) to the file and then filter the results?
./stockfish bench &> bench.txt && tail -1 bench.txt >> speed.csv
Should do what you want without requiring any source code changes.

jb

Re: Extract line from Sf bench command

Posted: Thu Jan 02, 2014 11:32 pm
by quantum
Hey, thanks for your quick reply. :)

atm I try to put it in a script to run 50 cycles automatically.Lets see if I get it right.

Re: Extract line from Sf bench command

Posted: Fri Jan 03, 2014 3:54 am
by lucasart
A couple of tips for you

1/ stdin, stdout, stderr

Every C programmer knows that stdin=0, stdout=1, stderr=2, right? You can use that in the shell. For example, if you want to run a program myProg and get it to read stdin from input.txt, write its stdout to output.txt and write its errors to error.txt:

Code: Select all

./myProg 0<./input.txt 1>./output.txt 2>./error.txt
2/ /dev/null

Sometimes, it can be useful to use /dev/null. Basically it's like a file from a programming point of view, but when you write into it, it's a no-operation for the operating system. For example, when you run Stockfish bench command, and you only want to see stderr output and discard stdout:

Code: Select all

./stockfish bench >/dev/null
Which is the same as

Code: Select all

./stockfish bench 1>/dev/null

Re: Extract line from Sf bench command

Posted: Fri Jan 03, 2014 12:01 pm
by quantum
Thanks for your explanation Lucas :)

I finally finished my little script which starts with bash coammand. Especially the part with the redirection was not straightforward for me.

Code: Select all

#!/bin/bash

for (( i = 1; i <= 50; i++ ))
do
    echo "$i. Iteration"
    ./stockfish_14010201_x64 bench > bench.txt 2>&1 && tail -1 bench.txt >> speed.csv
done  

Re: Extract line from Sf bench command

Posted: Fri Jan 03, 2014 1:58 pm
by lucasart
OK, I see you're becoming a shell guru now. Here is a more advanced version:

Code: Select all

x=$(./stockfish bench 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/")
echo $x
Try to figure out how it works. Once you've done that, you can do a loop and use the shell to calculate the

Code: Select all

average=sum(x_i)/50
The shell is really a powerful scripting language, almost a programming language in a certain sense. I think there was a (crazy) guy who programmed a chess engine in shell.

That being said, I think the shell is best used for really simple scripts. Beyond that its cryptic syntax and archaism make it not the ideal choice. I prefer Python for non trivial scripts.

Re: Extract line from Sf bench command

Posted: Fri Jan 03, 2014 9:45 pm
by quantum
Here is my little script. This is some pretty cool stuff with sed. It is quite rewarding if you get your things working.
I wanted to save each run in an array and calculate the standard deviation but I mess up with the array stuff. Will take a look at this at a later time. I should rather study more serious than toying around with the bash :D

Do you think it is possible to change uci parameters in the bash and then run bench command? Maybe I will end up with something similar to Houdini's autotune command.

Code: Select all

#!/bin/bash
sum=0
average=0
for (( i = 1; i <= 50; i++ ))
do
    echo "$i. Iteration"
    x=$(./stockfish bench 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/")
let sum=$sum+$x
echo $x
done  

let average=$sum/50 ; echo average nps $average

Re: Extract line from Sf bench command

Posted: Sat Jan 04, 2014 3:11 am
by lucasart
Yes, regular expressions are pretty awesome. I use grep and sed all the time, and I can't imagine the world without them. Imagine going back to Windows and its pathetic DOS prompt :lol:

You can feed in stuff to the engine using the shell. The idea is that an UCI engine reads its UCI commands (from the GUI normally) from stdin, and outputs stuff (for the GUI to read) in its stdout.

Here's a sample session with an UCI engine, to search the starting position at depth 12:

Code: Select all

uci
isready
ucinewgame
position startpos
go depth 12
quit
If you fire up any UCI engine in command line and type these things, you should get the expected result.

What you can do in a script is put the commands you want to send the engine in a file, and frun:

Code: Select all

./engine <./commands_file >./output
and then parse the output, using grep for example.

The problem is that you can only do things in a static manner. You have to decide the commands you will send first, let the engine process them all and analyse the output after. With Python you can do an interactive script, that sends and receives them one by one, so it's a better choice than the shell for that kind of thing.

Re: Extract line from Sf bench command

Posted: Sat Mar 01, 2014 2:57 pm
by ChessDrone
quantum wrote:Here is my little script. This is some pretty cool stuff with sed. It is quite rewarding if you get your things working.
I wanted to save each run in an array and calculate the standard deviation but I mess up with the array stuff. Will take a look at this at a later time. I should rather study more serious than toying around with the bash :D

Do you think it is possible to change uci parameters in the bash and then run bench command? Maybe I will end up with something similar to Houdini's autotune command.

Code: Select all

#!/bin/bash
sum=0
average=0
for (( i = 1; i <= 50; i++ ))
do
    echo "$i. Iteration"
    x=$(./stockfish bench 2>&1|grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/")
let sum=$sum+$x
echo $x
done  

let average=$sum/50 ; echo average nps $average
Interesting script. Thank you
There are ways to adapt this script for several Stockfish?

Because I want to disable Threads Sleep before bench, may be this script can be mixed with this one?

Code: Select all

#!/bin/bash
cat << EOF | stockfish.exe
setoption name Idle Threads Sleep value false
bench

EOF
or this

Code: Select all

#!/bin/bash
cat < OPTIONS.INI << EOF | stockfish.exe
bench
EOF

Re: Extract line from Sf bench command

Posted: Sun Mar 02, 2014 11:26 am
by ChessDrone
modified by wmahan (fics)

Code: Select all

#!/bin/bash

# http://www.open-chess.org/viewtopic.php?f=5&t=2557#p20321 modified by wmahan

for engine in profile-build/stockfish* build/stockfish*; do
    echo -e "$engine\t">>results.txt
    sum=0
    average=0
    for (( i = 1; i <= 50; i++ ))
    do
        #echo "$i. Iteration"
        out=`cat <<END | $engine 2>&1 | tail
setoption name Idle Threads Sleep value false
isready
bench
END`
        nps=`echo "$out" | grep "Nodes\/second"|sed "s/.*: \([0-9]*\)/\1/"`
        nodes=`echo "$out" | grep "Nodes searched"| sed "s/.*: \([0-9]*\)/\1/"`
        let sum=$sum+$nps
    done
    echo -e "$nodes\t">>results.txt

    let average=$sum/50 ; echo -e "$average\r">>results.txt
done
Image