Skip to content

Commit 692b9f6

Browse files
authored
Merge pull request The-OpenROAD-Project#3424 from jeffng-or/at-enable-string-choice-list
enable string choice lists in AutoTuner
2 parents ad13f2d + da72052 commit 692b9f6

File tree

2 files changed

+82
-62
lines changed

2 files changed

+82
-62
lines changed

flow/scripts/variables.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ PLACE_SITE:
320320
Placement site for core cells defined in the technology LEF file.
321321
stages:
322322
- floorplan
323+
type: string
324+
tunable: 1
323325
TAPCELL_TCL:
324326
description: |
325327
Path to Endcap and Welltie cells file.

tools/AutoTuner/src/autotuner/utils.py

Lines changed: 80 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -450,40 +450,48 @@ def apply_condition(config, data):
450450
# algorithms should take different methods (will be added)
451451
if algorithm != "random":
452452
return config
453-
dp_pad_min = data["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"]["minmax"][0]
454-
dp_pad_step = data["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"]["step"]
455-
if dp_pad_step == 1:
456-
config["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"] = tune.sample_from(
457-
lambda spec: np.random.randint(
458-
dp_pad_min, spec.config.CELL_PAD_IN_SITES_GLOBAL_PLACEMENT + 1
453+
if "CELL_PAD_IN_SITES_DETAIL_PLACEMENT" in data:
454+
dp_pad_min = data["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"]["minmax"][0]
455+
dp_pad_step = data["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"]["step"]
456+
if dp_pad_step == 1:
457+
config["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"] = tune.sample_from(
458+
lambda spec: np.random.randint(
459+
dp_pad_min, spec.config.CELL_PAD_IN_SITES_GLOBAL_PLACEMENT + 1
460+
)
459461
)
460-
)
461-
if dp_pad_step > 1:
462-
config["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"] = tune.sample_from(
463-
lambda spec: random.randrange(
464-
dp_pad_min,
465-
spec.config.CELL_PAD_IN_SITES_GLOBAL_PLACEMENT + 1,
466-
dp_pad_step,
462+
if dp_pad_step > 1:
463+
config["CELL_PAD_IN_SITES_DETAIL_PLACEMENT"] = tune.sample_from(
464+
lambda spec: random.randrange(
465+
dp_pad_min,
466+
spec.config.CELL_PAD_IN_SITES_GLOBAL_PLACEMENT + 1,
467+
dp_pad_step,
468+
)
467469
)
468-
)
469470
return config
470471

471472
def read_tune(this):
472473
from ray import tune
473474

474-
min_, max_ = this["minmax"]
475-
if min_ == max_:
476-
# Returning a choice of a single element allow pbt algorithm to
477-
# work. pbt does not accept single values as tunable.
478-
return tune.choice([min_, max_])
479-
if this["type"] == "int":
480-
if this["step"] == 1:
481-
return tune.randint(min_, max_)
482-
return tune.choice(np.ndarray.tolist(np.arange(min_, max_, this["step"])))
483-
if this["type"] == "float":
484-
if this["step"] == 0:
485-
return tune.uniform(min_, max_)
486-
return tune.choice(np.ndarray.tolist(np.arange(min_, max_, this["step"])))
475+
if "minmax" in this:
476+
min_, max_ = this["minmax"]
477+
if min_ == max_:
478+
# Returning a choice of a single element allow pbt algorithm to
479+
# work. pbt does not accept single values as tunable.
480+
return tune.choice([min_, max_])
481+
if this["type"] == "int":
482+
if this["step"] == 1:
483+
return tune.randint(min_, max_)
484+
return tune.choice(
485+
np.ndarray.tolist(np.arange(min_, max_, this["step"]))
486+
)
487+
if this["type"] == "float":
488+
if this["step"] == 0:
489+
return tune.uniform(min_, max_)
490+
return tune.choice(
491+
np.ndarray.tolist(np.arange(min_, max_, this["step"]))
492+
)
493+
if this["type"] == "string":
494+
return tune.choice(this["values"])
487495
return None
488496

489497
def read_tune_ax(name, this):
@@ -493,33 +501,41 @@ def read_tune_ax(name, this):
493501
from ray import tune
494502

495503
dict_ = dict(name=name)
496-
if "minmax" not in this:
497-
return None
498-
min_, max_ = this["minmax"]
499-
if min_ == max_:
500-
dict_["type"] = "fixed"
501-
dict_["value"] = min_
502-
elif this["type"] == "int":
503-
if this["step"] == 1:
504-
dict_["type"] = "range"
505-
dict_["bounds"] = [min_, max_]
506-
dict_["value_type"] = "int"
504+
if "minmax" in this:
505+
min_, max_ = this["minmax"]
506+
if min_ == max_:
507+
dict_["type"] = "fixed"
508+
dict_["value"] = min_
509+
elif this["type"] == "int":
510+
if this["step"] == 1:
511+
dict_["type"] = "range"
512+
dict_["bounds"] = [min_, max_]
513+
dict_["value_type"] = "int"
514+
else:
515+
dict_["type"] = "choice"
516+
dict_["values"] = tune.randint(min_, max_, this["step"])
517+
dict_["value_type"] = "int"
518+
elif this["type"] == "float":
519+
if this["step"] == 1:
520+
dict_["type"] = "choice"
521+
dict_["values"] = tune.choice(
522+
np.ndarray.tolist(np.arange(min_, max_, this["step"]))
523+
)
524+
dict_["value_type"] = "float"
525+
else:
526+
dict_["type"] = "range"
527+
dict_["bounds"] = [min_, max_]
528+
dict_["value_type"] = "float"
529+
return dict_
530+
if "values" in this:
531+
dict_["type"] = "choice"
532+
dict_["values"] = this["values"]
533+
if this["type"] == "string":
534+
dict_["value_type"] = "str"
507535
else:
508-
dict_["type"] = "choice"
509-
dict_["values"] = tune.randint(min_, max_, this["step"])
510-
dict_["value_type"] = "int"
511-
elif this["type"] == "float":
512-
if this["step"] == 1:
513-
dict_["type"] = "choice"
514-
dict_["values"] = tune.choice(
515-
np.ndarray.tolist(np.arange(min_, max_, this["step"]))
516-
)
517-
dict_["value_type"] = "float"
518-
else:
519-
dict_["type"] = "range"
520-
dict_["bounds"] = [min_, max_]
521-
dict_["value_type"] = "float"
522-
return dict_
536+
dict_["value_type"] = this["type"]
537+
return dict_
538+
return None
523539

524540
def read_tune_pbt(name, this):
525541
"""
@@ -528,15 +544,17 @@ def read_tune_pbt(name, this):
528544
"""
529545
from ray import tune
530546

531-
if "minmax" not in this:
532-
return None
533-
min_, max_ = this["minmax"]
534-
if min_ == max_:
535-
return tune.choice([min_, max_])
536-
if this["type"] == "int":
537-
return tune.randint(min_, max_)
538-
if this["type"] == "float":
539-
return tune.uniform(min_, max_)
547+
if "minmax" in this:
548+
min_, max_ = this["minmax"]
549+
if min_ == max_:
550+
return tune.choice([min_, max_])
551+
if this["type"] == "int":
552+
return tune.randint(min_, max_)
553+
if this["type"] == "float":
554+
return tune.uniform(min_, max_)
555+
if "values" in this:
556+
return tune.choice(this["values"])
557+
return None
540558

541559
# Check file exists and whether it is a valid JSON file.
542560
assert os.path.isfile(file_name), f"File {file_name} not found."

0 commit comments

Comments
 (0)