Skip to content

Commit 8a0e90c

Browse files
Merge branch 'main' into automated-pypi-publishing
2 parents 67b91d3 + 534cf7d commit 8a0e90c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+3226
-657
lines changed

.github/workflows/unit-tests.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ jobs:
2828
- name: install dependencies
2929
run: uv sync
3030

31-
- name: Install test-only dependencies (Python 3.13)
32-
if: matrix.python-version == '3.13'
31+
- name: Install test-only dependencies (Python 3.9 and 3.13)
32+
if: matrix.python-version == '3.9' || matrix.python-version == '3.13'
3333
run: uv sync --group tests
3434

3535
- name: Unit tests

code_to_optimize/bubble_sort_method.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,27 @@ def sorter(self, arr):
1515
arr[j + 1] = temp
1616
print("stderr test", file=sys.stderr)
1717
return arr
18+
19+
@classmethod
20+
def sorter_classmethod(cls, arr):
21+
print("codeflash stdout : BubbleSorter.sorter_classmethod() called")
22+
for i in range(len(arr)):
23+
for j in range(len(arr) - 1):
24+
if arr[j] > arr[j + 1]:
25+
temp = arr[j]
26+
arr[j] = arr[j + 1]
27+
arr[j + 1] = temp
28+
print("stderr test classmethod", file=sys.stderr)
29+
return arr
30+
31+
@staticmethod
32+
def sorter_staticmethod(arr):
33+
print("codeflash stdout : BubbleSorter.sorter_staticmethod() called")
34+
for i in range(len(arr)):
35+
for j in range(len(arr) - 1):
36+
if arr[j] > arr[j + 1]:
37+
temp = arr[j]
38+
arr[j] = arr[j + 1]
39+
arr[j + 1] = temp
40+
print("stderr test staticmethod", file=sys.stderr)
41+
return arr

code_to_optimize/tests/pytest/test_topological_sort.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def test_topological_sort():
1010
g.addEdge(2, 3)
1111
g.addEdge(3, 1)
1212

13-
assert g.topologicalSort() == [5, 4, 2, 3, 1, 0]
13+
assert g.topologicalSort()[0] == [5, 4, 2, 3, 1, 0]
1414

1515

1616
def test_topological_sort_2():
@@ -20,15 +20,15 @@ def test_topological_sort_2():
2020
for j in range(i + 1, 10):
2121
g.addEdge(i, j)
2222

23-
assert g.topologicalSort() == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
23+
assert g.topologicalSort()[0] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2424

2525
g = Graph(10)
2626

2727
for i in range(10):
2828
for j in range(i + 1, 10):
2929
g.addEdge(i, j)
3030

31-
assert g.topologicalSort() == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
31+
assert g.topologicalSort()[0] == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3232

3333

3434
def test_topological_sort_3():
@@ -38,4 +38,4 @@ def test_topological_sort_3():
3838
for j in range(i + 1, 1000):
3939
g.addEdge(j, i)
4040

41-
assert g.topologicalSort() == list(reversed(range(1000)))
41+
assert g.topologicalSort()[0] == list(reversed(range(1000)))

codeflash-benchmark/codeflash_benchmark/plugin.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ def pytest_addoption(parser: pytest.Parser) -> None:
5252
parser.addoption(
5353
"--codeflash-trace", action="store_true", default=False, help="Enable CodeFlash tracing for benchmarks"
5454
)
55-
# These options are ignored when --codeflash-trace is used
56-
for option, action, default, help_text in benchmark_options:
57-
help_suffix = " (ignored when --codeflash-trace is used)"
58-
parser.addoption(option, action=action, default=default, help=help_text + help_suffix)
55+
# Only add benchmark options if pytest-benchmark is not installed for backward compatibility with existing pytest-benchmark setup
56+
if not PYTEST_BENCHMARK_INSTALLED:
57+
for option, action, default, help_text in benchmark_options:
58+
help_suffix = " (ignored when --codeflash-trace is used)"
59+
parser.addoption(option, action=action, default=default, help=help_text + help_suffix)
5960

6061

6162
@pytest.fixture

codeflash/LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Business Source License 1.1
33
Parameters
44

55
Licensor: CodeFlash Inc.
6-
Licensed Work: Codeflash Client version 0.17.x
6+
Licensed Work: Codeflash Client version 0.18.x
77
The Licensed Work is (c) 2024 CodeFlash Inc.
88

99
Additional Use Grant: None. Production use of the Licensed Work is only permitted
@@ -13,7 +13,7 @@ Additional Use Grant: None. Production use of the Licensed Work is only permitte
1313
Platform. Please visit codeflash.ai for further
1414
information.
1515

16-
Change Date: 2029-09-23
16+
Change Date: 2029-10-21
1717

1818
Change License: MIT
1919

codeflash/api/aiservice.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def optimize_python_code( # noqa: D417
144144
logger.info("!lsp|Generating optimized candidates…")
145145
console.rule()
146146
try:
147-
response = self.make_ai_service_request("/optimize", payload=payload, timeout=600)
147+
response = self.make_ai_service_request("/optimize", payload=payload, timeout=60)
148148
except requests.exceptions.RequestException as e:
149149
logger.exception(f"Error generating optimized candidates: {e}")
150150
ph("cli-optimize-error-caught", {"error": str(e)})
@@ -209,7 +209,7 @@ def optimize_python_code_line_profiler( # noqa: D417
209209
console.rule()
210210
return []
211211
try:
212-
response = self.make_ai_service_request("/optimize-line-profiler", payload=payload, timeout=600)
212+
response = self.make_ai_service_request("/optimize-line-profiler", payload=payload, timeout=60)
213213
except requests.exceptions.RequestException as e:
214214
logger.exception(f"Error generating optimized candidates: {e}")
215215
ph("cli-optimize-error-caught", {"error": str(e)})
@@ -255,13 +255,15 @@ def optimize_python_code_refinement(self, request: list[AIServiceRefinerRequest]
255255
"optimized_code_runtime": opt.optimized_code_runtime,
256256
"speedup": opt.speedup,
257257
"trace_id": opt.trace_id,
258+
"function_references": opt.function_references,
259+
"python_version": platform.python_version(),
258260
}
259261
for opt in request
260262
]
261263
logger.debug(f"Refining {len(request)} optimizations…")
262264
console.rule()
263265
try:
264-
response = self.make_ai_service_request("/refinement", payload=payload, timeout=600)
266+
response = self.make_ai_service_request("/refinement", payload=payload, timeout=120)
265267
except requests.exceptions.RequestException as e:
266268
logger.exception(f"Error generating optimization refinements: {e}")
267269
ph("cli-optimize-error-caught", {"error": str(e)})
@@ -308,6 +310,8 @@ def get_new_explanation( # noqa: D417
308310
original_throughput: str | None = None,
309311
optimized_throughput: str | None = None,
310312
throughput_improvement: str | None = None,
313+
function_references: str | None = None,
314+
codeflash_version: str = codeflash_version,
311315
) -> str:
312316
"""Optimize the given python code for performance by making a request to the Django endpoint.
313317
@@ -327,6 +331,8 @@ def get_new_explanation( # noqa: D417
327331
- original_throughput: str | None - throughput for the baseline code (operations per second)
328332
- optimized_throughput: str | None - throughput for the optimized code (operations per second)
329333
- throughput_improvement: str | None - throughput improvement percentage
334+
- current codeflash version
335+
- function_references: str | None - where the function is called in the codebase
330336
331337
Returns
332338
-------
@@ -349,6 +355,8 @@ def get_new_explanation( # noqa: D417
349355
"original_throughput": original_throughput,
350356
"optimized_throughput": optimized_throughput,
351357
"throughput_improvement": throughput_improvement,
358+
"function_references": function_references,
359+
"codeflash_version": codeflash_version,
352360
}
353361
logger.info("loading|Generating explanation")
354362
console.rule()
@@ -373,7 +381,12 @@ def get_new_explanation( # noqa: D417
373381
return ""
374382

375383
def generate_ranking( # noqa: D417
376-
self, trace_id: str, diffs: list[str], optimization_ids: list[str], speedups: list[float]
384+
self,
385+
trace_id: str,
386+
diffs: list[str],
387+
optimization_ids: list[str],
388+
speedups: list[float],
389+
function_references: str | None = None,
377390
) -> list[int] | None:
378391
"""Optimize the given python code for performance by making a request to the Django endpoint.
379392
@@ -382,6 +395,7 @@ def generate_ranking( # noqa: D417
382395
- trace_id : unique uuid of function
383396
- diffs : list of unified diff strings of opt candidates
384397
- speedups : list of speedups of opt candidates
398+
- function_references : where the function is called in the codebase
385399
386400
Returns
387401
-------
@@ -394,6 +408,7 @@ def generate_ranking( # noqa: D417
394408
"speedups": speedups,
395409
"optimization_ids": optimization_ids,
396410
"python_version": platform.python_version(),
411+
"function_references": function_references,
397412
}
398413
logger.info("loading|Generating ranking")
399414
console.rule()
@@ -506,7 +521,7 @@ def generate_regression_tests( # noqa: D417
506521
"is_async": function_to_optimize.is_async,
507522
}
508523
try:
509-
response = self.make_ai_service_request("/testgen", payload=payload, timeout=600)
524+
response = self.make_ai_service_request("/testgen", payload=payload, timeout=90)
510525
except requests.exceptions.RequestException as e:
511526
logger.exception(f"Error generating tests: {e}")
512527
ph("cli-testgen-error-caught", {"error": str(e)})
@@ -532,7 +547,7 @@ def generate_regression_tests( # noqa: D417
532547
ph("cli-testgen-error-response", {"response_status_code": response.status_code, "error": response.text})
533548
return None
534549

535-
def get_optimization_impact(
550+
def get_optimization_review(
536551
self,
537552
original_code: dict[Path, str],
538553
new_code: dict[Path, str],
@@ -544,8 +559,9 @@ def get_optimization_impact(
544559
replay_tests: str,
545560
root_dir: Path,
546561
concolic_tests: str, # noqa: ARG002
562+
calling_fn_details: str,
547563
) -> str:
548-
"""Compute the optimization impact of current Pull Request.
564+
"""Compute the optimization review of current Pull Request.
549565
550566
Args:
551567
original_code: dict -> data structure mapping file paths to function definition for original code
@@ -558,10 +574,11 @@ def get_optimization_impact(
558574
replay_tests: str -> replay test table
559575
root_dir: Path -> path of git directory
560576
concolic_tests: str -> concolic_tests (not used)
577+
calling_fn_details: str -> filenames and definitions of functions which call the function_to_optimize
561578
562579
Returns:
563580
-------
564-
- 'high' or 'low' optimization impact
581+
- 'high', 'medium' or 'low' optimization review
565582
566583
"""
567584
diff_str = "\n".join(
@@ -577,7 +594,7 @@ def get_optimization_impact(
577594
]
578595
)
579596
code_diff = f"```diff\n{diff_str}\n```"
580-
logger.info("!lsp|Computing Optimization Impact…")
597+
logger.info("!lsp|Computing Optimization Review…")
581598
payload = {
582599
"code_diff": code_diff,
583600
"explanation": explanation.raw_explanation_message,
@@ -591,22 +608,25 @@ def get_optimization_impact(
591608
"benchmark_details": explanation.benchmark_details if explanation.benchmark_details else None,
592609
"optimized_runtime": humanize_runtime(explanation.best_runtime_ns),
593610
"original_runtime": humanize_runtime(explanation.original_runtime_ns),
611+
"codeflash_version": codeflash_version,
612+
"calling_fn_details": calling_fn_details,
613+
"python_version": platform.python_version(),
594614
}
595615
console.rule()
596616
try:
597-
response = self.make_ai_service_request("/optimization_impact", payload=payload, timeout=600)
617+
response = self.make_ai_service_request("/optimization_review", payload=payload, timeout=120)
598618
except requests.exceptions.RequestException as e:
599619
logger.exception(f"Error generating optimization refinements: {e}")
600620
ph("cli-optimize-error-caught", {"error": str(e)})
601621
return ""
602622

603623
if response.status_code == 200:
604-
return cast("str", response.json()["impact"])
624+
return cast("str", response.json()["review"])
605625
try:
606626
error = cast("str", response.json()["error"])
607627
except Exception:
608628
error = response.text
609-
logger.error(f"Error generating impact candidates: {response.status_code} - {error}")
629+
logger.error(f"Error generating optimization review: {response.status_code} - {error}")
610630
ph("cli-optimize-error-response", {"response_status_code": response.status_code, "error": error})
611631
console.rule()
612632
return ""

0 commit comments

Comments
 (0)