Let us parse the logs first:


In [1]:
%pylab inline


Populating the interactive namespace from numpy and matplotlib

In [2]:
! grep "multipv 1" log2.txt  | grep -v lowerbound | grep -v upperbound > log2_g.txt

In [3]:
def parse_info(l):
    D = {}
    k = l.split()
    i = 0
    assert k[i] == "info"
    i += 1
    while i < len(k):
        if k[i] == "depth":
            D[k[i]] = int(k[i+1])
            i += 2
        elif k[i] == "seldepth":
            D[k[i]] = int(k[i+1])
            i += 2
        elif k[i] == "multipv":
            D[k[i]] = int(k[i+1])
            i += 2
        elif k[i] == "score":
            if k[i+1] == "cp":
                D["score_p"] = int(k[i+2]) / 100. # score in pawns
            i += 3
        elif k[i] == "nodes":
            D[k[i]] = int(k[i+1])
            i += 2
        elif k[i] == "nps":
            D[k[i]] = int(k[i+1])
            i += 2
        elif k[i] == "hashfull":
            D[k[i]] = int(k[i+1]) / 1000. # between 0 and 1
            i += 2
        elif k[i] == "tbhits":
            D[k[i]] = int(k[i+1])
            i += 2
        elif k[i] == "time":
            D[k[i]] = int(k[i+1]) / 1000. # elapsed time in [s]
            i += 2
        elif k[i] == "pv":
            D[k[i]] = k[i+1:]
            return D
        else:
            raise Exception("Unknown kw")

In [4]:
# Convert to an array of lists
D = []
for l in open("log2_g.txt").readlines():
    D.append(parse_info(l))

# Convert to a list of arrays
data = {}
for key in D[-1].keys():
    d = []
    for x in D:
        if key in x:
            d.append(x[key])
        else:
            d.append(-1)
    if key != "pv":
        d = array(d)
    data[key] = d

The number of nodes searched depend linearly on time:


In [5]:
title("Number of nodes searched in time")
plot(data["time"] / 60., data["nodes"], "o")
xlabel("Time [min]")
ylabel("Nodes")
grid()
show()


So nodes per second is roughly constant:


In [6]:
title("Positions per second in time")
plot(data["time"] / 60., data["nps"], "o")
xlabel("Time [min]")
ylabel("Positions / s")
grid()
show()


The hashtable usage is at full capacity:


In [7]:
title("Hashtable usage")
hashfull = data["hashfull"]
hashfull[hashfull == -1] = 0
plot(data["time"] / 60., hashfull * 100, "o")
xlabel("Time [min]")
ylabel("Hashtable filled [%]")
grid()
show()


Number of nodes needed for the given depth grows exponentially, except for moves that are forced, which require very little nodes to search (those show as a horizontal plateau):


In [8]:
title("Number of nodes vs. depth")
semilogy(data["depth"], data["nodes"], "o")
xlabel("Depth [half moves]")
ylabel("Nodes")
grid()
show()


Convergence wrt. Depth


In [9]:
title("Score")
plot(data["depth"], data["score_p"], "o")
xlabel("Depth [half moves]")
ylabel("Score [pawns]")
grid()
show()


Convergence of the variations:


In [10]:
for i in range(len(data["depth"])):
    print "%2i %s" % (data["depth"][i], " ".join(data["pv"][i])[:100])


 1 d7a7
 2 d7a7 h6h5 a7a3
 3 f5f6 b5b6 d7d6 b6d6 e5d6
 4 f5f6 b5b6 d7d6 b6d6 e5d6 f8e8
 5 f5f6 b5b6 d7d6 b6d6 e5d6 f8e8 f2f3
 6 f2f4 b5b2 f5f6 b2b6 d7d6 b6d6 e5d6 f8e8
 7 f2f4 b5b2 f5f6 b2b6 d7d6 b6d6 e5d6 f8e8 f4f5
 8 d7a7 b5b2 f2f4 b2a2 f5f6 f8e8 a7e7 e8d8 e7f7 c5c4
 9 d7a7 b5b2 f2f4 b2a2 f5f6 f8e8 f4f5 a2f2 a7a3
10 d7a7 b5b2 f2f4 b2a2 f5f6 f8e8 f4f5 a2f2 a7a3 c5c4 a3c3 f2f4 h4h5
11 d7a7 b5b2 f2f4 b2a2 f5f6 f8e8 f4f5 a2e2 a7a3 c5c4 e5e6 f7e6 f5e6 e2f2 f6e5
12 d7a7 b5b2 f2f4 b2a2 f5f6 f8e8 a7a8 e8d7 f6f7 a2f2 e5e6 d7d6 a8a6 d6d5 e6e7 f2f4 f7e8 c5c4 a6a3
13 d7a7 b5b2 f2f4 b2a2 f5f6 f8g8 f4f5 c5c4 a7a8 g8h7 f6f7 a2f2 f5f6 c4c3 a8a3 c3c2 a3c3
14 d7a7 b5b2 f2f4 b2a2 f5f6 f8g8 a7a8 g8h7 f4f5 c5c4 f6f7 c4c3 e5e6 a2f2 e6e7 f2f5 f7e6 f5f2 a8h8 h7h8
15 d7a7 b5b2 f2f4 f8e8 a7a3 c5c4 a3c3 b2b4 a2a3 b4a4 f5f6 a4a6 f6g7 a6g6 g7h7 g6c6 f4f5 e8e7 a3a4 c6c5
16 d7a7 c5c4 a7a3 f8e7 f2f4 b5b4 h4h5 b4b2 f5e4 b2e2 e4d4 e2f2 a3a7 e7e8 d4c4 f2f4 c4d5 f4h4 d5d6 e8f8
17 d7a7 c5c4 a7a3 b5b2 f2f4 f8e7 f5e4 b2e2 e4d4 h6h5 f4f5 c4c3 a3c3 e2a2 c3c4 a2f2 d4e4 f7f6 c4c7 e7d8
18 d7a7 c5c4 a7a3 b5b2 f2f4 f8e7 f5e4 b2e2 e4d4 h6h5 f4f5 c4c3 a3c3 e2a2 c3c4 a2f2 d4e4 f7f6 c4c7 e7d8 
19 d7a7 c5c4 a7a3 b5b2 f2f4 f8e7 a3c3 b2b4 a2a3 b4a4 h4h5 f7f6 c3g3 f6e5 f4e5 a4a5 f5e4 a5a4 e4d5 e7d7 
20 d7a7 c5c4 a7a3 f8e7 a3c3 b5b4 h4h5 b4a4 a2a3 e7f8 f2f4 f8e7 c3f3 a4a8 f5e4 e7e6 f4f5 e6e7 f3g3 a8a4 
21 d7a7 c5c4 a7a3 f8e7 a3c3 b5b4 h4h5 b4a4 a2a3 e7f8 f2f4 f8e7 c3f3 a4a8 f5e4 e7e6 f4f5 e6e7 f3g3 a8a4 
22 d7a7 c5c4 a7a3 f8e7 f2f4 b5c5 a3c3 h6h5 f5e4 c5a5 c3c4 a5a2 f4f5 f7f6 e5e6 e7d6 c4d4 d6e7 d4d7 e7e8 
23 d7a7 c5c4 a7a3 f8e7 f2f4 b5c5 a3c3 h6h5 f5e4 c5a5 c3c4 a5a2 f4f5 f7f6 e5e6 a2a7 c4b4 e7d6 b4d4 d6e7 
24 d7a7 b5b2 f2f4 c5c4 a7a3 f8g7 a3g3 g7f8 g3c3 b2a2 c3c4 f8g7 c4c7 g7f8 c7c8 f8g7 h4h5 a2a4 c8c2 g7g8 
25 d7a7 b5b2 f2f4 c5c4 a7a3 f8g7 a3g3 g7f8 g3c3 b2a2 c3c4 f8g7 c4c7 g7f8 c7c8 f8g7 h4h5 a2a4 c8c2 g7g8 
26 d7a7 b5b2 f2f4 c5c4 a7a3 f8g7 a3g3 g7f8 g3c3 b2a2 c3c4 f8g7 c4c7 g7f8 c7c8 f8g7 h4h5 a2a4 c8c2 g7g8 
27 d7a7 b5b2 f2f4 c5c4 a7a3 f8g7 a3g3 g7f8 g3c3 b2a2 c3c4 f8g7 c4c7 g7f8 c7c8 f8g7 h4h5 a2a4 c8c2 g7g8 
28 d7a7 b5b2 f2f4 c5c4 a7a3 f8g7 a3g3 g7f8 g3c3 b2a2 c3c4 f8g7 c4c7 g7f8 c7c8 f8g7 h4h5 a2a4 c8c2 g7g8 
29 f5f6 b5b6 d7d6 b6d6 e5d6 f8e8 f6e5 e8d7 e5d5 c5c4 d5c4 d7d6 c4b4 f7f5 b4a3 f5f4 a3b4 d6d7 b4c5 f4f3 
30 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8e8 f7g7 c3c2 g7g8 e8d7 e5e6 d7c7 g8c8 c7c8 
31 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
32 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8e8 f7h7 e8d8 h7h8 d8c7 h8c8 c7c8 e5e6 c3c2 
33 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
34 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
35 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
36 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
37 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
38 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 f8g8 d7f7 c4c3 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
39 f5f6 b5b6 d7d6 b6b8 f2f4 f8e8 d6c6 b8b2 c6c8 e8d7 c8c5 b2f2 f4f5 d7d8 c5a5 d8c7 a5a3 c7b6 a3a8 f2f4 
40 f5f6 b5b6 d7d6 b6b8 f2f4 f8e8 d6c6 b8b2 c6c8 e8d7 c8c5 b2f2 f4f5 h6h5 c5c3 f2f4 c3a3 d7c6 a3a7 c6d5 
41 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
42 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
43 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
44 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
45 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
46 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
47 f5f6 b5b6 d7d6 b6b8 f2f4 c5c4 f4f5 b8c8 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
48 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
49 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
50 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
51 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8e8 e5e6 c3c2 f7h7 e8d8 h7h8 d8c7 h8c8 c7c8 
52 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
53 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8
54 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8e8 e5e6 c3c2 f7h7 e8d8 h7h8 d8c7 h8c8 c7c8 
55 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8e8 e5e6 c3c2 f7h7 e8d8 h7h8 d8c7 h8c8 c7c8 
56 f5f6 b5b6 d7d6 b6b8 f2f4 b8c8 f4f5 c5c4 d6d7 c4c3 d7f7 f8g8 e5e6 c8c6 f6g6 c3c2 f5f6 c2c1q f7g7 g8h8