Commit c6b0796d authored by Bowen Wu's avatar Bowen Wu
Browse files

Switch from stdout to stderr

parent d665e705
......@@ -4,6 +4,9 @@ from pysmps.pysmps.smps_loader import load_mps, MPSParseError
from generator import MPSProgram
import glob
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
# A simple wrapper to suppress talkative APIs from printing
# Inspired from https://stackoverflow.com/a/45669280
class VerbosePrint:
......
......@@ -11,8 +11,8 @@ from queue import Queue
from generator import MPSProgram
from mps_mut import DenseMatMut, FlipObjSense, ScaleMut, SparseMatMut, FlipSignMut, NoOpMut, MoreIntMut
from mps_util import load_mps_dict
from optimizer import OPTIMAL, CplexSolver, GurobiSolver
from mps_util import load_mps_dict, eprint
from optimizer import OPTIMAL, CBCSolver, CplexSolver, GurobiSolver
# TODO
# 1. Make this class checkpoint-able
......@@ -53,7 +53,7 @@ class OptFuzzer(object):
else:
self.queue = []
self.next_id = 0 # id assigned to the next mutant
print("Initializing seeds")
eprint("Initializing seeds")
for s in self.seed:
mutant = {
"id" : self.next_id,
......@@ -68,7 +68,7 @@ class OptFuzzer(object):
heapq.heappush(self.queue, ((-1, self.next_id, 1), mutant))
self.next_id += 1
self.mut_cnt_per_seed = [0] * len(self.seed)
print("Seeds initialized")
eprint("Seeds initialized")
def get_mutant(self, mut_choice : str, nr_mutations: int = 3) -> Tuple[dict, dict]:
if self.schedule == 'fifo':
......@@ -77,7 +77,7 @@ class OptFuzzer(object):
else:
parent_ent = heapq.heappop(self.queue)
parent = parent_ent[1]
# print(parent_ent[0])
# eprint(parent_ent[0])
self.mut_cnt_per_seed[parent["root"]] += 1
mps = deepcopy(parent["mps"])
......@@ -91,17 +91,17 @@ class OptFuzzer(object):
elif mut_choice == "random":
idx = random.randint(0, self.n_mut - 1)
else:
print(f"Unsupported mutant choice {mut_choice}")
eprint(f"Unsupported mutant choice {mut_choice}")
os.abort()
#print("========== GOING TO MUTATE ============")
#eprint("========== GOING TO MUTATE ============")
if mut_choice == 'random':
mps_prime = mps
for _ct in range(nr_mutations):
idx = random.randint(0, self.n_mut - 1)
mut_method = self.no_op_mut_method if (random.random() < 0.5) else self.mut_method[idx]
# print(self.mut_method)
# print('idx = ', idx, ' Mutating using ', mut_method)
# eprint(self.mut_method)
# eprint('idx = ', idx, ' Mutating using ', mut_method)
mps_prime = mut_method(mps_prime)
else:
mps_prime = self.mut_method[idx](mps)
......@@ -124,13 +124,13 @@ class OptFuzzer(object):
def sol_equal(self, sol1 : dict, sol2 : dict, check_var = False) -> bool:
if sol1['status'] != sol2['status']:
print("Diff ", len(self.diff), " produces different status, ", sol1["status"], " vs. ", sol2["status"])
eprint("Diff ", len(self.diff), " produces different status, ", sol1["status"], " vs. ", sol2["status"])
return False
if sol1['status'] == OPTIMAL:
# check if the obj value is the same
if not math.isclose(sol1['obj_val'], sol2['obj_val'], abs_tol=self.abs_tol):
print("Diff ", len(self.diff), " produces different obj_val, ", sol1['obj_val'], " vs. ", sol2["obj_val"])
eprint("Diff ", len(self.diff), " produces different obj_val, ", sol1['obj_val'], " vs. ", sol2["obj_val"])
return False
# check if the variable values are the same
......@@ -175,7 +175,7 @@ class OptFuzzer(object):
g_time = time.time() - g_start
if cplex_sol is None or gurobi_sol is None:
print("[Fatal] Cannot load the solution")
eprint("[Fatal] Cannot load the solution")
self.checkpoint()
os.abort()
......@@ -188,7 +188,7 @@ class OptFuzzer(object):
new_key = scaled_time_diff * 1.0 + math.fabs(scaled_time_diff - p[0][2]) * 0
new_key = self.get_perturbed_time_diff(new_key)
heapq.heappush(self.queue, ((-new_key, p[1]["id"], scaled_time_diff), p[1]))
# print("time-diff = ", self.get_perturbed_time_diff(scaled_time_diff))
# eprint("time-diff = ", self.get_perturbed_time_diff(scaled_time_diff))
if not are_equal:
dfname = os.path.join(self.diff_path, f"diff_{len(self.diff)}.mps")
......@@ -199,20 +199,20 @@ class OptFuzzer(object):
# print_ind_stats = False
# if(print_ind_stats):
# #Id, Name, Equal, Cplex time, Gurobi time
# print('{},{},{},{},{},{}'.format(mut['id']-203, mut['seed_name'].replace('seed/',''), are_equal, c_time, g_time,scaled_time_diff))
# eprint('{},{},{},{},{},{}'.format(mut['id']-203, mut['seed_name'].replace('seed/',''), are_equal, c_time, g_time,scaled_time_diff))
# self.all_mutant.append(mut)
def print_stats(self):
print(f"Seeds: {self.seed}")
print("Mutation methods used: ", self.mut_method)
print("# Mutations: ", self.next_id - len(self.seed))
print("# Mutants that caused a difference: ", len(self.diff))
eprint(f"Seeds: {self.seed}")
eprint("Mutation methods used: ", self.mut_method)
eprint("# Mutations: ", self.next_id - len(self.seed))
eprint("# Mutants that caused a difference: ", len(self.diff))
for i, s in enumerate(self.seed):
print(i, " ", s, "\t", self.mut_cnt_per_seed[i])
eprint(i, " ", s, "\t", self.mut_cnt_per_seed[i])
for i, d in enumerate(self.diff):
print("Difference ", i, " is derived from ", d["root"], " at round ", d["mut_no"])
eprint("Difference ", i, " is derived from ", d["root"], " at round ", d["mut_no"])
def checkpoint(self):
pass
......@@ -247,7 +247,7 @@ class OptFuzzer(object):
def main():
from config import parser
args = parser.parse_args()
print(args)
eprint(args)
mut_method = []
for m in args.mut_methods:
......@@ -275,7 +275,7 @@ def main():
grb = GurobiSolver(timeout=False)
ts = str(time.time())
print("Timestamp = ", ts)
eprint("Timestamp = ", ts)
save_path = os.path.join(args.save_path, ts)
checkpoint_freq = args.ckpt_freq
checkpoint_path = os.path.join(args.ckpt_path, ts)
......
......@@ -2,7 +2,7 @@ from time import time
import xml.etree.ElementTree as ET
from cplex import Cplex
import gurobipy as gp
from mps_util import VerbosePrint
from mps_util import VerbosePrint, eprint
import mip
# Solver status
......@@ -34,9 +34,9 @@ class Solver(object):
self.stats[k] = 0
def print_solver_stats(self) -> None:
print("\n", self.__class__.__name__, " Stats:")
eprint("\n", self.__class__.__name__, " Stats:")
for k in self.stats:
print(status_text[k], " = ", self.stats[k], " times")
eprint(status_text[k], " = ", self.stats[k], " times")
class CplexSolver(Solver):
# https://www.tu-chemnitz.de/mathematik/discrete/manuals/cplex/doc/refman/html/appendixB.html
......@@ -210,7 +210,8 @@ class CBCSolver(Solver):
def __call__(self, mps_file: str) -> dict:
with VerbosePrint(False):
model = mip.Model()
model = mip.Model(solver_name=mip.CBC)
model.verbose = 0
model.read(mps_file)
status = model.optimize()
......@@ -227,6 +228,8 @@ class CBCSolver(Solver):
ret['status'] = UNBOUNDED
else:
ret["status"] = UNKNOWN
self.stats[ret["status"]] += 1
return ret
......@@ -235,7 +238,11 @@ if __name__ == "__main__":
mps_file = "mps/testprob_int.mps"
cpx = CplexSolver()
grb = GurobiSolver()
print(cpx(mps_file))
print(grb(mps_file))
cbc = CBCSolver()
eprint(cpx(mps_file))
eprint(grb(mps_file))
eprint(cbc(mps_file))
cpx.print_solver_stats()
grb.print_solver_stats()
cbc.print_solver_stats()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment