Skip to content

Commit

Permalink
refine auto-parts logic (#1098)
Browse files Browse the repository at this point in the history
Co-authored-by: Pyifan <[email protected]>
  • Loading branch information
Pyifan and Pyifan authored Jun 6, 2024
1 parent 79a3c29 commit 5a1e45e
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 7 deletions.
2 changes: 2 additions & 0 deletions doc/newsfragments/2991_changed.auto_parts_refine.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Refine Auto-Part feature to handle corner cases when zero/negative/overly large number of parts are calculated.

41 changes: 34 additions & 7 deletions testplan/runnable/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -592,19 +592,46 @@ def _get_tasks(
)
num_of_parts = 1
else:
num_of_parts = math.ceil(
# the setup time shall take no more than 50% of runtime
cap = math.ceil(
time_info["execution_time"]
/ (
self.cfg.auto_part_runtime_limit
- time_info["setup_time"]
)
/ self.cfg.auto_part_runtime_limit
* 2
)
formula = f"""
num_of_parts = math.ceil(
time_info["execution_time"] {time_info["execution_time"]}
/ (
self.cfg.auto_part_runtime_limit {self.cfg.auto_part_runtime_limit}
- time_info["setup_time"] {time_info["setup_time"]}
)
)
"""
try:
num_of_parts = math.ceil(
time_info["execution_time"]
/ (
self.cfg.auto_part_runtime_limit
- time_info["setup_time"]
)
)
except ZeroDivisionError:
self.logger.error(
f"ZeroDivisionError occurred when calculating num_of_parts for {uid}, set to 1. {formula}"
)
num_of_parts = 1

if num_of_parts < 1:
self.logger.error(
f"Calculated num_of_parts for {uid} is {num_of_parts}, set to 1. {formula}"
)
num_of_parts = 1

if num_of_parts > cap:
self.logger.error(
f"Calculated num_of_parts for {uid} is {num_of_parts},"
" check the input runtime_data and auto_part_runtime_limit"
f"Calculated num_of_parts for {uid} is {num_of_parts} > cap {cap}, set to {cap}. {formula}"
)
num_of_parts = cap
if "weight" not in _task_arguments:
_task_arguments["weight"] = (
math.ceil(
Expand Down
60 changes: 60 additions & 0 deletions tests/functional/testplan/runners/pools/test_auto_part.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,63 @@ def test_auto_weight_discover():
assert task.weight == 140
mockplan.run()
assert pool.size == 1


def test_auto_parts_zero_neg_parts():
with tempfile.TemporaryDirectory() as runpath:
mockplan = TestplanMock(
"plan",
runpath=runpath,
merge_scheduled_parts=True,
auto_part_runtime_limit=45,
plan_runtime_target=200,
runtime_data={
"Proj1-suite": {
"execution_time": 50,
"setup_time": 50, # setup_time > runtime_limit -> negtive num_of_parts
}
},
)
pool = ProcessPool(name="MyPool", size="auto")
mockplan.add_resource(pool)
current_folder = os.path.dirname(os.path.realpath(__file__))
mockplan.schedule_all(
path=f"{current_folder}/discover_tasks",
name_pattern=r".*auto_parts_tasks\.py$",
resource="MyPool",
)
assert len(pool.added_items) == 1
for task in pool.added_items.values():
assert task.weight == 100
mockplan.run()
assert pool.size == 1


def test_auto_parts_cap_parts():
with tempfile.TemporaryDirectory() as runpath:
mockplan = TestplanMock(
"plan",
runpath=runpath,
merge_scheduled_parts=True,
auto_part_runtime_limit=45,
plan_runtime_target=200,
runtime_data={
"Proj1-suite": {
"execution_time": 60,
"setup_time": 44,
}
},
)
pool = ProcessPool(name="MyPool", size="auto")
mockplan.add_resource(pool)
current_folder = os.path.dirname(os.path.realpath(__file__))
mockplan.schedule_all(
path=f"{current_folder}/discover_tasks",
name_pattern=r".*auto_parts_tasks\.py$",
resource="MyPool",
)
assert len(pool.added_items) == 3
for task in pool.added_items.values():
assert task.weight == 64
mockplan.run()
assert pool.size == 1

0 comments on commit 5a1e45e

Please sign in to comment.