@@ -55,6 +55,7 @@ def __init__(
5555 pad_file = None ,
5656 additional_files = None ,
5757 additional_files_list_add = None ,
58+ circuit_constraint_list_add = None
5859 ):
5960 self .task_name = task_name
6061 self .config_dir = config_dir
@@ -81,6 +82,9 @@ def __init__(
8182 self .pad_file = pad_file
8283 self .additional_files = additional_files
8384 self .additional_files_list_add = additional_files_list_add
85+ self .circuit_constraints = parse_circuit_constraint_list (circuit_constraint_list_add ,
86+ self .circuits ,
87+ self .archs )
8488
8589
8690# pylint: enable=too-few-public-methods
@@ -225,7 +229,9 @@ def load_task_config(config_file) -> TaskConfig:
225229 # Interpret the file
226230 key_values = {}
227231 for line in values :
228- key , value = line .split ("=" )
232+ # Split the key and value using only the first equal sign. This allows
233+ # the value to have an equal sign.
234+ key , value = line .split ("=" , 1 )
229235
230236 # Trim whitespace
231237 key = key .strip ()
@@ -300,6 +306,73 @@ def check_include_fields(config_file, key_values):
300306 )
301307 )
302308
309+ def parse_circuit_constraint_list (
310+ circuit_constraint_list , circuits_list , arch_list
311+ ) -> dict :
312+ """
313+ Parse the circuit constraints passed in via the config file.
314+ Circuit constraints are expected to have the following syntax:
315+ (<circuit>, <constr_key>=<constr_val>)
316+ This function generates a dictionary which can be accessed:
317+ circuit_constraints[circuit][constr_key]
318+ If this dictionary returns "None", then the circuit is unconstrained for
319+ that key.
320+ """
321+
322+ # Constraint keys that can be specified.
323+ circuit_constraint_keys = set (
324+ [
325+ "arch" ,
326+ "device" ,
327+ "constraints" ,
328+ ]
329+ )
330+
331+ # Initialize the dictionary to be unconstrained for all circuits and keys.
332+ res_circuit_constraints = {
333+ circuit : {constraint_key : None for constraint_key in circuit_constraint_keys }
334+ for circuit in circuits_list
335+ }
336+
337+ # If there were no circuit constraints passed by the user, return dictionary
338+ # of Nones.
339+ if circuit_constraint_list is None :
340+ return res_circuit_constraints
341+
342+ # Parse the circuit constraint list
343+ for circuit_constraint in circuit_constraint_list :
344+ # Remove the round brackets.
345+ if circuit_constraint [0 ] != '(' or circuit_constraint [- 1 ] != ')' :
346+ raise VtrError (f"Circuit constraint syntax error: \" { circuit_constraint } \" " )
347+ circuit_constraint = circuit_constraint [1 :- 1 ]
348+ # Split the circuit and the constraint
349+ split_constraint_line = circuit_constraint .split (',' )
350+ if len (split_constraint_line ) != 2 :
351+ raise VtrError (f"Circuit constraint has too many arguments: \" { circuit_constraint } \" " )
352+ circuit = split_constraint_line [0 ].strip ()
353+ constraint = split_constraint_line [1 ].strip ()
354+ # Check that the circuit actually exists.
355+ if circuit not in circuits_list :
356+ raise VtrError (f"Cannot constrain circuit \" { circuit } \" , circuit has not been added" )
357+ # Parse the constraint
358+ split_constraint = constraint .split ("=" )
359+ if len (split_constraint ) != 2 :
360+ raise VtrError (f"Circuit constraint syntax error: \" { circuit_constraint } \" " )
361+ constr_key = split_constraint [0 ].strip ()
362+ constr_val = split_constraint [1 ].strip ()
363+ # Check that the constr_key is valid.
364+ if constr_key not in circuit_constraint_keys :
365+ raise VtrError (f"Invalid constraint \" { constr_key } \" used on circuit \" { circuit } \" " )
366+ # In the case of arch constraints, make sure this arch exists.
367+ if constr_key == "arch" and constr_val not in arch_list :
368+ raise VtrError (f"Cannot constrain arch \" { constr_key } \" , arch has not been added" )
369+ # Make sure this circuit is not already constrained with this constr_arg
370+ if res_circuit_constraints [circuit ][constr_key ] is not None :
371+ raise VtrError (f"Circuit \" { circuit } \" cannot be constrained more than once" )
372+ # Add the constraint for this circuit
373+ res_circuit_constraints [circuit ][constr_key ] = constr_val
374+
375+ return res_circuit_constraints
303376
304377def shorten_task_names (configs , common_task_prefix ):
305378 """
@@ -496,6 +569,11 @@ def create_jobs(args, configs, after_run=False) -> List[Job]:
496569 ]
497570
498571 for arch , circuit , noc_traffic in combinations :
572+ # If the circuit is constrained to only run on a specific arch, and
573+ # this arch is not that arch, skip this combination.
574+ circuit_arch_constraint = config .circuit_constraints [circuit ]["arch" ]
575+ if circuit_arch_constraint is not None and circuit_arch_constraint != arch :
576+ continue
499577 golden_results = load_parse_results (
500578 str (PurePath (config .config_dir ).joinpath ("golden_results.txt" ))
501579 )
@@ -613,6 +691,10 @@ def create_job(
613691 cmd += ["-expect_fail" , expected_vpr_status ]
614692 current_parse_cmd = parse_cmd .copy ()
615693
694+ # Apply the command-line circuit constraints provided by the circuit
695+ # constraint list in the config file.
696+ apply_cmd_line_circuit_constraints (cmd , circuit , config )
697+
616698 if config .parse_file :
617699 current_parse_cmd += [
618700 "arch={}" .format (arch ),
@@ -697,6 +779,19 @@ def ret_expected_vpr_status(arch, circuit, golden_results, script_params=None):
697779
698780 return golden_metrics ["vpr_status" ]
699781
782+ def apply_cmd_line_circuit_constraints (cmd , circuit , config ):
783+ """
784+ Apply the circuit constraints to the command line. If the circuit is not
785+ constrained for any key, this method will not do anything.
786+ """
787+ # Check if this circuit is constrained to a specific device.
788+ constrained_device = config .circuit_constraints [circuit ]["device" ]
789+ if constrained_device is not None :
790+ cmd += ["--device" , constrained_device ]
791+ # Check if the circuit has constrained atom locations.
792+ circuit_vpr_constraints = config .circuit_constraints [circuit ]["constraints" ]
793+ if circuit_vpr_constraints is not None :
794+ cmd += ["--read_vpr_constraints" , circuit_vpr_constraints ]
700795
701796def resolve_vtr_source_file (config , filename , base_dir = "" ):
702797 """
0 commit comments