-
Notifications
You must be signed in to change notification settings - Fork 1
/
generate.py
146 lines (113 loc) · 4.36 KB
/
generate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from pprint import pprint
import sys, getopt
from prepare_problem import get_problem_data
import json
from dimod import cqm_to_bqm, Binary, Integer, ConstrainedQuadraticModel
from dwave.system import LeapHybridBQMSampler, LeapHybridCQMSampler
import numpy as np
from parse import parse
import time
import pickle
import os
from os import walk
def generate_histogram(inputfile, machinefile, deadline, output_name):
with open(inputfile) as f:
input = json.loads(f.read())
machines = None
if machinefile is not None:
with open(machinefile) as f:
machines = json.loads(f.read())
# def cqm_solution(cost_df, jobs, runtimes, paths, deadline, debug = False):
cost_df, runtimes, jobs, paths = get_problem_data(input, machines)
cqm = ConstrainedQuadraticModel()
xs = []
job_count = len(jobs)
for machines in range(len(cost_df.columns)):
x = [Binary(f'm{machines}_x{i}') for i in range(job_count)]
xs.extend(x)
# Problem definition
model = None
for cost, variable in zip(np.array(cost_df).flatten(), xs):
if model:
model = model + cost * variable
else:
model = cost * variable
cqm.set_objective(model)
# Must use exactly one machine
for i in range(job_count):
one_machine = None
for j in range(i, len(xs), job_count):
if one_machine:
one_machine = one_machine + xs[j]
else:
one_machine = xs[j]
cqm.add_constraint( one_machine == 1)
# All paths finish before dedline
flat_runtimes = [(runtime, name) for n, machine_runtimes in runtimes.items() for runtime, name in zip(machine_runtimes, [j.name for j in jobs])]
for path in paths:
path_runtime = None
for var, (runtime, name) in zip(xs, flat_runtimes):
if name not in path:
continue
if path_runtime:
path_runtime = path_runtime + runtime * var
else:path_runtime = runtime * var
cqm.add_constraint(path_runtime <= deadline)
sampler_cqm = LeapHybridCQMSampler()
start = time.time()
solution = sampler_cqm.sample_cqm(cqm,time_limit=5)
end = time.time()
# if debug:
# pprint(solution.info)
def is_correct_solution(cqm, sol):
return len(cqm.violations(sol, skip_satisfied = True)) == 0
correct_solutions = [ s for s in solution if is_correct_solution(cqm, s)]
# if debug:
# pprint(solution.info)
best_solution = correct_solutions[0]
machine_names = cost_df.columns
job_names = cost_df.index
actual_solution = {}
for k, is_used in best_solution.items():
machine, var = parse('m{}_x{}', k)
if is_used:
actual_solution[jobs[int(var)].name] = machine_names[int(machine)]
# for s in solution:
# print(solution.data_vectors.keys())
print(solution.data_vectors["energy"])
print(actual_solution)
# print(solution.data_vectors["num_occurrences"])
# print(solution.data_vectors["is_feasible"])
# print(solution.data_vectors["is_satisfied"])
# print(solution.info.keys())
# print(solution.info['qpu_access_time'])
solved_cqm = {
"input" : inputfile,
"machines" : machines,
"deadline" : deadline,
"solution" : {
"info" : solution.info,
"data_vectors" : solution.data_vectors,
"solutions" : [s for s in solution],
},
"machine_names" : machine_names,
"job_names" : job_names
}
with open(output_name, 'wb') as out_file:
pickle.dump(solved_cqm, out_file)
# deadlines = [20, 130, 260, 300]
deadlines = [10000]
# ['Jobs_492.json'] #
workflows = next(walk("workflows"), (None, None, []))[2] # [] if no file
machines = ['basic_test.json', 'cyfronet.json'] #next(walk("machines"), (None, None, []))[2] # [] if no file
print(machines)
print(workflows)
for deadline in deadlines:
for workflow in workflows:
for machine in machines:
output_name = f"pickled_cqm_results/{os.path.splitext(workflow)[0]}_{os.path.splitext(machine)[0]}_{deadline}.pkl"
if not os.path.exists(output_name):
print(f"RUNNING: {output_name}")
generate_histogram(f"workflows/{workflow}", f"machines/{machine}", deadline, output_name)
else:
print(f"CACHED: {output_name}")