Skip to content

Commit de3db13

Browse files
committed
Fixed gray-box result output bugs
1 parent 115c979 commit de3db13

89 files changed

Lines changed: 644 additions & 457 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@ __pycache__/
77
*.so
88

99
# Folders
10-
rtac/logs/Cadical_ReACTR
11-
rtac/logs/TSP_Q_ReACTR
12-
rtac/logs/TSP_RT_ReACTR
1310
rtac/logs/Cadical_CPPL
11+
rtac/logs/Cadicalpp_CPPL
1412
rtac/logs/Cadicalpp_CPPL_gb
13+
rtac/logs/Cadicalpp_ReACTR
14+
rtac/logs/Cadicalpp_ReACTRpp
15+
rtac/logs/Cadicalpp_ReACTR_gb
16+
rtac/logs/Cadicalpp_ReACTRpp_gb
17+
rtac/logs/Cadical_ReACTR
1518
rtac/logs/TSP_Qpp_ReACTRpp
19+
rtac/logs/TSP_Q_ReACTR
1620
rtac/logs/TSP_RT_CPPL
1721
rtac/logs/TSP_RTpp_ReACTRpp
18-
rtac/logs/Cadicalpp_ReACTR_gb
19-
rtac/logs/Cadicalpp_ReACTRpp_gb
22+
rtac/logs/TSP_RT_ReACTR
2023
rtac/data/instances/power_law_easy
2124
rtac/data/solvers/cadical
2225

.idea/.name

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rtac/ac_functionalities/ranking/cppl.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,9 @@ def insert_in_pool(self, configs):
466466

467467
for c, d in zip(configs.values(), self.discard):
468468
disc_id = list(self.pool.keys())[d]
469-
print('Replaced cotender', disc_id,
470-
'by contender generated via', c.gen, '\n')
469+
if self.scenario.verbosity == 2:
470+
print('Replaced contender', disc_id,
471+
'by contender generated via', c.gen, '\n')
471472

472473
def skill_and_confidence(self):
473474
with threadpool_limits(limits=1):

rtac/ac_functionalities/ranking/gray_box.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,15 +254,16 @@ def term_list(self, pred, cores, verbosity):
254254
worse_than_avg = \
255255
[core for core, rank in ranks.items() if rank >= avg_rank]
256256

257-
if verbosity == 2:
258-
print("Better counts:", dict(better_counts))
259-
print("Ranks:", ranks)
260-
print("Average rank:", avg_rank)
261-
print("Worse than average:", worse_than_avg)
262-
263-
if avg_rank != 1.0:
257+
if len(set(better_counts.values())) == 1:
264258
return []
265259
else:
260+
if verbosity == 2:
261+
print('\n\n')
262+
print('GRAY BOX PAIRWSE COMPARISON STATS:')
263+
print("Better counts:", dict(better_counts))
264+
print("Ranks:", ranks)
265+
print("Average rank:", avg_rank)
266+
print("Worse than average:", worse_than_avg)
266267
return worse_than_avg
267268

268269

rtac/ac_functionalities/result_processing.py

Lines changed: 77 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ def manage_pool(self) -> None:
106106
def select_contenders(self) -> None:
107107
"""Select contenders for next tournament/problem instance."""
108108

109-
def process_tourn(self, rtac_data: RTACData, instance: str = None, tourn_nr: int = None) -> str:
109+
def process_tourn(self, rtac_data: RTACData, instance: str = None,
110+
tourn_nr: int = None) -> str:
110111
"""Manage result processing.
111112
112113
:param rtac_data: Object containing data and objects necessary
@@ -146,11 +147,12 @@ def get_contender_dict(self) -> dict[str: Configuration]:
146147
def result_summary_terminal(self, results, tourn_nr=None):
147148
if tourn_nr:
148149
self.tourn_nr = tourn_nr
149-
if self.scenario.verbosity == 2:
150+
if self.scenario.verbosity == 2 and self.scenario.experimental:
150151
if not self.scenario.objective_min:
151152
unit = 'seconds'
152153
else:
153154
unit = 'objective value'
155+
154156
self.time_sum += round(min(results), 3)
155157
len_str = len('Instance nr. ' + str(self.tourn_nr) + ' : ' + str(
156158
round(self.time_sum, 3)
@@ -233,7 +235,8 @@ def get_winner(self, times: list[float], res: list[float]) \
233235

234236
return winner, ranks
235237

236-
def process_results(self, rtac_data: RTACData, instance: str = None, tourn_nr: int = None) -> None:
238+
def process_results(self, rtac_data: RTACData, instance: str = None,
239+
tourn_nr: int = None) -> None:
237240
"""Perform tournament result processing necessary to replace contenders
238241
in pool and select contenders for next tournament/problem instance
239242
according to ReACTR implementation.
@@ -248,10 +251,15 @@ def process_results(self, rtac_data: RTACData, instance: str = None, tourn_nr: i
248251
if self.rtac_data.ta_res[core] == self.huge_float:
249252
self.rtac_data.ta_res_time[core] = self.scenario.timeout
250253

254+
if not self.scenario.objective_min:
255+
results = list(self.rtac_data.ta_res_time[:])
256+
else:
257+
results = list(self.rtac_data.ta_res[:])
258+
259+
self.result_summary_terminal(results)
260+
251261
times = list(self.rtac_data.ta_res_time[:])
252262

253-
self.result_summary_terminal(times)
254-
255263
self.rtac_data.newtime = min(times)
256264
res = list(self.rtac_data.ta_res[:])
257265
self.rtac_data.best_res = min(res)
@@ -457,57 +465,66 @@ def get_winner(self, times: list[float], res: list[float]) \
457465
else:
458466
winner = res.index(min(res))
459467

460-
interim_sorted = [[self.rtac_data.interim[j][i]
461-
for j in range(self.scenario.number_cores)]
462-
for i, _ in enumerate(self.rtac_data.interim[0])]
463-
464-
interim_sorted = np.array(interim_sorted)
465-
interim_sorted = interim_sorted.astype(float)
466-
467-
for i, isort in enumerate(interim_sorted):
468-
if self.rtac_data.interim_meaning[i] is \
469-
InterimMeaning.decrease:
470-
interim_sorted[i] = rankdata(isort,
471-
method='dense',
472-
nan_policy="propagate")
473-
elif self.rtac_data.interim_meaning[i] is \
474-
InterimMeaning.increase:
475-
interim_sorted[i] = rankdata([-1 * i if i is not None
476-
else None for i in isort],
477-
method='dense',
478-
nan_policy="propagate")
479-
480-
ranks = [0 for core in range(self.scenario.number_cores)]
481-
482-
for _, isort in enumerate(interim_sorted):
483-
for r, _ in enumerate(ranks):
484-
ranks[r] += isort[r]
485-
486-
if self.scenario.objective_min:
487-
res_ranks = rankdata(res, method='dense', nan_policy="propagate")
488-
489-
duplicates = []
490-
491-
for rank in sorted(set(res_ranks)):
492-
duplicates.append(self.duplicates(res_ranks, rank))
493-
494-
for duplicate in duplicates:
495-
if len(duplicate) > 1:
496-
interim_ranks = [ranks[dup] for dup in duplicate]
497-
tie_winner = \
498-
duplicate[interim_ranks.index(min(interim_ranks))]
499-
interim_ranks = rankdata(interim_ranks, method='dense')
500-
interim_ranks -= min(interim_ranks)
501-
for d, ir in zip(duplicate, interim_ranks):
502-
for r, _ in enumerate(res_ranks):
503-
if d == r and r != winner and r != tie_winner:
504-
res_ranks[r] += interim_ranks[ir]
505-
else:
506-
res_ranks[r] += max(interim_ranks)
507-
508-
ranks = res_ranks
509-
510-
ranks = rankdata(ranks, method='dense')
468+
if not any(elem is None for sublist in self.rtac_data.interim
469+
for elem in sublist):
470+
471+
ranks = [0 for core in range(self.scenario.number_cores)]
472+
473+
interim_sorted = [[self.rtac_data.interim[j][i]
474+
for j in range(self.scenario.number_cores)]
475+
for i, _ in enumerate(self.rtac_data.interim[0])]
476+
477+
interim_sorted = np.array(interim_sorted)
478+
interim_sorted = interim_sorted.astype(float)
479+
480+
for i, isort in enumerate(interim_sorted):
481+
if self.rtac_data.interim_meaning[i] is \
482+
InterimMeaning.decrease:
483+
interim_sorted[i] = rankdata(isort,
484+
method='dense',
485+
nan_policy="propagate")
486+
elif self.rtac_data.interim_meaning[i] is \
487+
InterimMeaning.increase:
488+
interim_sorted[i] = rankdata([-1 * i if i is not None
489+
else None for i in isort],
490+
method='dense',
491+
nan_policy="propagate")
492+
493+
for _, isort in enumerate(interim_sorted):
494+
for r, _ in enumerate(ranks):
495+
ranks[r] += isort[r]
496+
497+
if self.scenario.objective_min:
498+
res_ranks = rankdata(res, method='dense', nan_policy="propagate")
499+
500+
duplicates = []
501+
502+
for rank in sorted(set(res_ranks)):
503+
duplicates.append(self.duplicates(res_ranks, rank))
504+
505+
for duplicate in duplicates:
506+
if len(duplicate) > 1:
507+
interim_ranks = [ranks[dup] for dup in duplicate]
508+
if not all(np.isnan(ir) for ir in interim_ranks):
509+
tie_winner = \
510+
duplicate[interim_ranks.index(min(interim_ranks))]
511+
interim_ranks = rankdata(interim_ranks, method='dense')
512+
interim_ranks -= min(interim_ranks)
513+
for d, ir in zip(duplicate, interim_ranks):
514+
for r, _ in enumerate(res_ranks):
515+
if d == r and r != winner and r != tie_winner:
516+
res_ranks[r] += interim_ranks[ir]
517+
elif np.isnan(max(interim_ranks)):
518+
res_ranks[r] += self.scenario.number_cores
519+
else:
520+
res_ranks[r] += max(interim_ranks)
521+
522+
ranks = res_ranks
523+
524+
ranks = rankdata(ranks, method='dense')
525+
526+
else:
527+
ranks = [1 for core in range(self.scenario.number_cores)]
511528

512529
ranks[winner] = 0
513530

@@ -560,7 +577,8 @@ def init_cppl(self, scenario, pool, random_config_gen, contender_dict,
560577

561578
queue.put((bandit, bandit_models))
562579

563-
def process_tourn(self, rtac_data: RTACData, instance: str = None, tourn_nr: int = None) -> str:
580+
def process_tourn(self, rtac_data: RTACData, instance: str = None,
581+
tourn_nr: int = None) -> str:
564582
"""Manage result processing.
565583
566584
:param rtac_data: Object containing data and objects necessary
@@ -615,7 +633,8 @@ def cppl_process_results(self, contender_dict, scenario, rtac_data,
615633

616634
queue.put((bandit, bandit_models, results, times))
617635

618-
def process_results(self, rtac_data: RTACData, instance: str = None, tourn_nr: int = None) -> None:
636+
def process_results(self, rtac_data: RTACData, instance: str = None,
637+
tourn_nr: int = None) -> None:
619638
"""Perform tournament result processing necessary to replace contenders
620639
in pool and select contenders for next tournament/problem instance.
621640

rtac/ac_functionalities/rtac_data.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def __init__(self, scenario: argparse.Namespace, **kwargs) -> None:
176176
self.tournID = 0
177177
self.cores_start = Manager().list(
178178
[core for core in range(scenario.number_cores)])
179-
self.early_start_tournament = False
179+
self.early_start_tournament = Value('b', False) # False
180180
self.event = Value('i', 0)
181181
self.newtime = Value('d', float(scenario.timeout))
182182
self.best_res = Value('d', huge_res)
@@ -242,12 +242,57 @@ def __init__(self, scenario: argparse.Namespace, rtacdata_init, **kwargs) -> Non
242242
:param scenario: Namespace containing all settings for the RTAC.
243243
:type scenario: argparse.Namespace
244244
"""
245+
self.scenario = scenario
245246
self.rec_data = {core: Manager().dict()
246247
for core in range(scenario.number_cores)}
247248

248249
self.RuntimeFeatures = Manager().list(
249250
[[] for core in range(scenario.number_cores)])
250251

252+
def early_rtac_copy(self):
253+
early_rtac_data = self.__class__.__new__(self.__class__)
254+
255+
overrides = {
256+
'ev': Event(),
257+
'cores_start': self.cores_start,
258+
'early_start_tournament': Value('b', False),
259+
'event': Value('i', 0),
260+
'newtime': Value('d', float(self.scenario.timeout)),
261+
'best_res': Value('d', sys.float_info.max * 1e-100),
262+
'winner': Manager().Value('c', 0),
263+
'status': Array('i',
264+
[0 for core in range(self.scenario.number_cores)]),
265+
'pids': Array('i',
266+
[0 for core in range(self.scenario.number_cores)]),
267+
'substart':
268+
Array('d', [0.0 for core in range(self.scenario.number_cores)]),
269+
'substart_wall':
270+
Array('d', [0.0 for core in range(self.scenario.number_cores)]),
271+
'ta_res':
272+
Array('d', [sys.float_info.max * 1e-100
273+
for core in range(self.scenario.number_cores)]),
274+
'ta_res_time':
275+
Array('d', [self.scenario.timeout * self.scenario.runtimePAR
276+
for core in range(self.scenario.number_cores)]),
277+
'ta_rtac_time':
278+
Array('d', [self.scenario.timeout * self.scenario.runtimePAR
279+
for core in range(self.scenario.number_cores)]),
280+
'process':
281+
['process_{0}'.format(s)
282+
for s in range(self.scenario.number_cores)],
283+
'start': time.time()
284+
}
285+
286+
# Selectively deepcopy or shallow copy attributes
287+
for key, value in self.__dict__.items():
288+
if key in overrides:
289+
setattr(early_rtac_data, key, overrides[key])
290+
else:
291+
# Safe to deepcopy
292+
setattr(early_rtac_data, key, copy.deepcopy(value))
293+
294+
return early_rtac_data
295+
251296

252297
def rtacdata_factory(scenario: argparse.Namespace, **kwargs) \
253298
-> AbstractRTACData:
@@ -272,6 +317,7 @@ class rtacdata_copy(rtacdata):
272317

273318
rtacdata_init = rtacdata.__init__
274319
rtacdata_copy.__init__ = GBData.__init__
320+
rtacdata_copy.early_rtac_copy = GBData.early_rtac_copy
275321

276322
return rtacdata_copy(scenario, rtacdata_init, **kwargs)
277323

rtac/ac_functionalities/ta_runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ def run(self, instance: str, config: Configuration,
276276
while self.running:
277277
# Avoid checking output excessively often (causes too much
278278
# overhead)
279-
time.sleep(5e-6)
279+
time.sleep(0.005) # time.sleep(5e-6)
280280

281281
ta_output = non_block_read(self.proc.stdout, self.logs)
282282

0 commit comments

Comments
 (0)