A set of benchmarks to compare a new prototype MiniZinc implementation
1#!/usr/bin/env python3
2import minizinc
3import sys
4import csv
5import os
6import time
7import subprocess
8import re
9from tqdm import tqdm
10from pathlib import Path
11from datetime import timedelta
12
13MZNCC = "../build/mzncc"
14MZNASM = "../build/mznasm"
15REPEATS = 10
16
17# Instances Selection (File location)
18if len(sys.argv) < 3:
19 print("Usage: new_flatstats.py <instances> <library>")
20 exit(1)
21
22instances_location = sys.argv[1]
23library = sys.argv[2]
24
25
26def parse_statistics(stdout: bytes, stderr: bytes):
27 statistics: Dict[str, StatisticsType] = {}
28 matches = re.findall(rb"%%%mzn-stat:? (\w*)=([^\r\n]*)", stdout)
29 for m in matches:
30 minizinc.result.set_stat(statistics, m[0].decode(), m[1].decode())
31
32 matches = re.findall(rb"([A-Z].*): (.*)\n", stderr)
33 for m in matches:
34 statistics[m[0].decode()] = m[1].decode()
35 return statistics
36
37
38writer = None
39num_lines = sum(1 for line in open(instances_location)) - 1
40with open(instances_location) as instances_file:
41 with tqdm(total=num_lines*REPEATS, file=sys.stderr) as pbar:
42 reader = csv.reader(instances_file, dialect="unix")
43 next(reader, None) # Skip the header line
44 mem = ""
45 for row in reader:
46 assert len(row) == 3
47 pbar.set_description(
48 "Flattening %s - %s"
49 % (row[1].split(os.sep)[-1], row[2].split(os.sep)[-1])
50 )
51
52 # Compile model
53 if mem != row[1]:
54 clock = time.perf_counter()
55 os.system(f"{MZNCC} -G{library} {row[1]} > _temp.uzn")
56 clock = timedelta(
57 microseconds=int((time.perf_counter() - clock) * 1000000)
58 )
59 mem = row[1]
60
61 # Flatten instance
62 cmd = [
63 '/usr/bin/time',
64 '-v',
65 MZNASM,
66 "--solver",
67 "org.minizinc.mzn-fzn",
68 "-c",
69 "-s",
70 "_temp.uzn",
71 ]
72 if row[2]:
73 cmd.append(row[2])
74 for i in range(REPEATS):
75 output = subprocess.run(cmd, capture_output=True,)
76
77 if output.returncode != 0:
78 print(
79 f"mznasm ERROR {output.returncode}: {row[1].split(os.sep)[-1]} - {row[2].split(os.sep)[-1]}:\n{output.stderr}",
80 file=sys.stderr,
81 )
82 break
83 else:
84 stats = parse_statistics(output.stdout, output.stderr)
85 stats["problem"] = row[0]
86 stats["model"] = row[1]
87 stats["data_file"] = row[2]
88 stats["compileTime"] = clock
89 stats["iteration"] = i + 1
90 if writer is None:
91 keys = list(
92 set(
93 ["problem", "model", "data_file", "status"]
94 + list(minizinc.result.StdStatisticTypes.keys())
95 + list(stats.keys())
96 )
97 )
98 writer = csv.DictWriter(
99 sys.stdout, keys, dialect="unix", extrasaction="ignore"
100 )
101 writer.writeheader()
102 writer.writerow(stats)
103 pbar.update(1)
104 sys.stdout.flush()