Skip to content

Commit 4976d5d

Browse files
some heuristics to limit code repair from generating many candidates
1 parent cc9ad56 commit 4976d5d

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

codeflash/code_utils/config_consts.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
TOTAL_LOOPING_TIME_LSP = 10.0 # Kept same timing for LSP mode to avoid in increase in performance reporting
2121
N_CANDIDATES_LP_LSP = 3
2222

23+
# Code repair
24+
REPAIR_UNMATCHED_PERCENTAGE_LIMIT = 0.35 # if the percentage of unmatched tests is greater than this, we won't fix it
25+
MAX_REPAIRS_PER_TRACE = 3 # maximum number of repairs we will do for each function
26+
2327
MAX_N_CANDIDATES = 5
2428
MAX_N_CANDIDATES_LP = 6
2529

codeflash/optimization/function_optimizer.py

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@
4343
from codeflash.code_utils.config_consts import (
4444
COVERAGE_THRESHOLD,
4545
INDIVIDUAL_TESTCASE_TIMEOUT,
46+
MAX_REPAIRS_PER_TRACE,
4647
N_CANDIDATES_EFFECTIVE,
4748
N_CANDIDATES_LP_EFFECTIVE,
4849
N_TESTS_TO_GENERATE_EFFECTIVE,
50+
REPAIR_UNMATCHED_PERCENTAGE_LIMIT,
4951
REPEAT_OPTIMIZATION_PROBABILITY,
5052
TOTAL_LOOPING_TIME_EFFECTIVE,
5153
)
@@ -282,6 +284,7 @@ def __init__(
282284
self.ast_code_to_id = {}
283285
self.future_all_refinements: list[concurrent.futures.Future] = []
284286
self.future_all_code_repair: list[concurrent.futures.Future] = []
287+
self.repair_counter = 0 # track how many repairs we did for each function
285288

286289
def can_be_optimized(self) -> Result[tuple[bool, CodeOptimizationContext, dict[Path, str]], str]:
287290
should_run_experiment = self.experiment_id is not None
@@ -553,6 +556,7 @@ def determine_best_candidate(
553556
optimized_runtimes: dict[str, float | None] = {}
554557
is_correct = {}
555558
optimized_line_profiler_results: dict[str, str] = {}
559+
self.repair_counter = 0
556560

557561
logger.info(
558562
f"Determining best optimization candidate (out of {len(candidates)}) for "
@@ -1915,27 +1919,36 @@ def run_optimized_candidate(
19151919
logger.info("h3|Test results matched ✅")
19161920
console.rule()
19171921
else:
1918-
result_unmatched_perc = len(diffs) / len(candidate_behavior_results)
1919-
if candidate.source == OptimizedCandidateSource.REPAIR or result_unmatched_perc > 0.5:
1920-
# if the test unmatched percentage is greater than 50%, we can't fix it
1921-
return self.get_results_not_matched_error()
1922-
1923-
ai_service_client = self.aiservice_client if exp_type == "EXP0" else self.local_aiservice_client
1924-
logger.info("Adding this to the repair queue")
1925-
self.future_all_code_repair.append(
1926-
self.repair_optimization(
1927-
original_source_code=code_context.read_writable_code.markdown,
1928-
modified_source_code=candidate.source_code.markdown,
1929-
test_diffs=diffs,
1930-
trace_id=self.function_trace_id[:-4] + exp_type
1931-
if self.experiment_id
1932-
else self.function_trace_id,
1933-
ai_service_client=ai_service_client,
1934-
optimization_id=candidate.optimization_id,
1935-
executor=self.executor,
1922+
1923+
def repair_if_possible() -> None:
1924+
if self.repair_counter >= MAX_REPAIRS_PER_TRACE:
1925+
return
1926+
1927+
result_unmatched_perc = len(diffs) / len(candidate_behavior_results)
1928+
if (
1929+
candidate.source == OptimizedCandidateSource.REPAIR
1930+
or result_unmatched_perc > REPAIR_UNMATCHED_PERCENTAGE_LIMIT
1931+
):
1932+
return
1933+
1934+
ai_service_client = self.aiservice_client if exp_type == "EXP0" else self.local_aiservice_client
1935+
logger.info("Adding this to the repair queue")
1936+
self.repair_counter += 1
1937+
self.future_all_code_repair.append(
1938+
self.repair_optimization(
1939+
original_source_code=code_context.read_writable_code.markdown,
1940+
modified_source_code=candidate.source_code.markdown,
1941+
test_diffs=diffs,
1942+
trace_id=self.function_trace_id[:-4] + exp_type
1943+
if self.experiment_id
1944+
else self.function_trace_id,
1945+
ai_service_client=ai_service_client,
1946+
optimization_id=candidate.optimization_id,
1947+
executor=self.executor,
1948+
)
19361949
)
1937-
)
19381950

1951+
repair_if_possible()
19391952
return self.get_results_not_matched_error()
19401953

19411954
logger.info(f"loading|Running performance tests for candidate {optimization_candidate_index}...")

0 commit comments

Comments
 (0)