33from concurrent .futures import ThreadPoolExecutor , TimeoutError
44from multiprocessing import Process , Queue
55import signal
6+ import shutil
67
78# Add optiprofiler to the system path
89import os
4344# To store all the 'time out' problems
4445timeout_problems = []
4546
47+ # Helper function to append to txt files
48+ def append_to_txt (file_path , value ):
49+ try :
50+ if os .path .exists (file_path ):
51+ with open (file_path , 'r' ) as f :
52+ existing = [line .strip () for line in f .readlines ()]
53+ if value in existing :
54+ return
55+ with open (file_path , 'a' ) as f :
56+ f .write (value + '\n ' )
57+ except Exception as e :
58+ print (f"Error appending to { file_path } : { e } " )
59+
4660# Find problems that are parametric
4761filename = os .path .join (cwd , 'list_of_parametric_problems_with_parameters_python.txt' )
4862# Scan each line, each line only has one problem name, which ends before the first comma
@@ -80,7 +94,7 @@ def flush(self):
8094 self .log .flush ()
8195
8296# Record the log from terminal
83- log_file = open (os .path .join (saving_path , 'log_python .txt' ), 'w ' )
97+ log_file = open (os .path .join (saving_path , 'log_python_temp .txt' ), 'a ' )
8498sys .stdout = Logger (log_file )
8599sys .stderr = Logger (log_file )
86100
@@ -147,6 +161,7 @@ def get_problem_info(problem_name, known_feasibility, problem_argins=None):
147161 except TimeoutError :
148162 print (f"Timeout while loading problem { problem_name } ." )
149163 timeout_problems .append (problem_name )
164+ append_to_txt (os .path .join (saving_path , 'timeout_problems_python_temp.txt' ), problem_name )
150165 print (f"Skipping problem { problem_name } due to timeout." )
151166 return info_single
152167
@@ -176,6 +191,7 @@ def get_problem_info(problem_name, known_feasibility, problem_argins=None):
176191 elif np .size (f ) == 0 or np .isnan (f ) or problem_name in known_feasibility :
177192 info_single ['isfeasibility' ] = 1
178193 feasibility .append (problem_name )
194+ append_to_txt (os .path .join (saving_path , 'feasibility_python_temp.txt' ), problem_name )
179195 else :
180196 info_single ['isfeasibility' ] = 0
181197 if problem_name == 'LIN' :
@@ -189,6 +205,7 @@ def get_problem_info(problem_name, known_feasibility, problem_argins=None):
189205 info_single ['f0' ] = 0
190206 info_single ['isfeasibility' ] = 1
191207 feasibility .append (problem_name )
208+ append_to_txt (os .path .join (saving_path , 'feasibility_python_temp.txt' ), problem_name )
192209
193210 if problem_name in feasibility :
194211 info_single ['isgrad' ] = 1
@@ -349,6 +366,7 @@ def process_arg(problem_name, arg, fixed_argins):
349366 except TimeoutError :
350367 print (f"Timeout while processing problem { problem_name } with argument { arg } ." )
351368 timeout_problems .append (problem_name + f" with arg { arg } " )
369+ append_to_txt (os .path .join (saving_path , 'timeout_problems_python_temp.txt' ), problem_name + f" with arg { arg } " )
352370 continue
353371 except Exception as e :
354372 print (f"Error while processing problem { problem_name } with argument { arg } : { e } " )
@@ -379,45 +397,96 @@ def process_arg(problem_name, arg, fixed_argins):
379397 return info_single
380398
381399if __name__ == "__main__" :
382- # Save problem information into a csv file
383- results = []
400+ csv_file = os .path .join (saving_path , 'probinfo_python.csv' )
401+ csv_file_temp = os .path .join (saving_path , 'probinfo_python_temp.csv' )
402+ current_prob_file = os .path .join (saving_path , 'current_problem.txt' )
403+ exclude_file = os .path .join (saving_path , 'exclude_python.txt' )
404+
405+ # 1. Crash Detection: If current_problem.txt exists, the previous run crashed on that problem.
406+ if os .path .exists (current_prob_file ):
407+ with open (current_prob_file , 'r' ) as f :
408+ crashed_prob = f .read ().strip ()
409+ if crashed_prob :
410+ print (f"Detected crash during previous run on problem: { crashed_prob } . Adding to exclude list." )
411+ with open (exclude_file , 'a' ) as f :
412+ f .write (crashed_prob + '\n ' )
413+ try :
414+ os .remove (current_prob_file )
415+ except :
416+ pass
417+
418+ # 2. Load existing exclusions
419+ if os .path .exists (exclude_file ):
420+ with open (exclude_file , 'r' ) as f :
421+ for line in f :
422+ ex = line .strip ()
423+ if ex and ex not in problem_exclude :
424+ problem_exclude .append (ex )
425+
426+ # Update problem_names by removing excluded ones
427+ problem_names = [name for name in problem_names if name not in problem_exclude ]
428+
429+ # 3. Resume: Find which problems are already completed
430+ completed_problems = set ()
431+ if os .path .exists (csv_file_temp ):
432+ try :
433+ existing_df = pd .read_csv (csv_file_temp , usecols = ['problem_name' ])
434+ completed_problems = set (existing_df ['problem_name' ].tolist ())
435+ print (f"Found { len (completed_problems )} already completed problems in temp file. Resuming..." )
436+ except Exception as e :
437+ print (f"Could not read existing temp CSV for resumption: { e } " )
438+
439+ # 4. Processing loop
384440 for name in problem_names :
441+ if name in completed_problems :
442+ continue
443+
385444 if name in para_problem_names :
386445 index = para_problem_names .index (name )
387446 args = problem_argins [index ] if index < len (problem_argins ) else []
388447 else :
389448 args = None
449+
450+ # Write current problem name before processing it to detect crashes
451+ with open (current_prob_file , 'w' ) as f :
452+ f .write (name )
453+
390454 info = get_problem_info (name , known_feasibility , args )
391- results .append (info )
455+
456+ # Original logic to filter out 'unknown' values
457+ def has_unknown_values (info_dict ):
458+ for value in info_dict .values ():
459+ if str (value ).strip ().lower () == 'unknown' :
460+ return True
461+ return False
462+
463+ if not has_unknown_values (info ):
464+ df_single = pd .DataFrame ([info ])
465+ if not os .path .exists (csv_file_temp ):
466+ df_single .to_csv (csv_file_temp , index = False , na_rep = 'nan' )
467+ else :
468+ df_single .to_csv (csv_file_temp , mode = 'a' , header = False , index = False , na_rep = 'nan' )
469+ else :
470+ print (f"Filtered out problem { name } due to 'unknown' values." )
471+
472+ # Clear crash detection file after successful processing
473+ if os .path .exists (current_prob_file ):
474+ os .remove (current_prob_file )
475+
392476 sys .stdout .flush ()
393477 sys .stderr .flush ()
394478
395- df = pd .DataFrame (results )
396-
397- def has_unknown_values (row ):
398- for value in row :
399- if str (value ).strip ().lower () == 'unknown' :
400- return True
401- return False
402- unknown_mask = df .apply (has_unknown_values , axis = 1 )
403- if unknown_mask .any ():
404- filtered_problems = df .loc [unknown_mask , 'problem_name' ].tolist ()
405- print (f"Filtered out { len (filtered_problems )} problems with 'unknown' values:" )
406- for problem in filtered_problems :
407- print (f" - { problem } " )
408- df_clean = df [~ unknown_mask ]
409-
410- df_clean .to_csv (os .path .join (saving_path , 'probinfo_python.csv' ), index = False , na_rep = 'nan' )
411-
412- # Save 'feasibility' to txt file in the one line format with space separated values
413- feasibility_file = os .path .join (saving_path , 'feasibility_python.txt' )
414- with open (feasibility_file , 'w' ) as f :
415- f .write (' ' .join (feasibility ))
416-
417- # Save 'timeout_problems' to txt file in the one line format with space separated values
418- timeout_file = os .path .join (saving_path , 'timeout_problems_python.txt' )
419- with open (timeout_file , 'w' ) as f :
420- f .write (' ' .join (timeout_problems ))
479+ # 5. Finalize: If we reached here, all problems are processed successfully.
480+ print ("All problems processed. Finalizing output files..." )
481+ if os .path .exists (csv_file_temp ):
482+ shutil .move (csv_file_temp , csv_file )
483+
484+ # Handle txt files renaming
485+ for base_name in ['feasibility_python' , 'timeout_problems_python' , 'log_python' ]:
486+ temp_path = os .path .join (saving_path , base_name + '_temp.txt' )
487+ final_path = os .path .join (saving_path , base_name + '.txt' )
488+ if os .path .exists (temp_path ):
489+ shutil .move (temp_path , final_path )
421490
422491 print ("Script completed successfully." )
423492
0 commit comments