-
Notifications
You must be signed in to change notification settings - Fork 21
Granular async instrumentation #687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
KRRT7
wants to merge
40
commits into
standalone-fto-async
Choose a base branch
from
granular-async-instrumentation
base: standalone-fto-async
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
0a57afa
first pass at wrapper deco behavioral
KRRT7 c9aaaad
don't reapply too early
KRRT7 ad1d085
feedback
KRRT7 14353d4
Update codeflash_wrap_decorator.py
KRRT7 3c05f97
Update function_optimizer.py
KRRT7 bafad49
Update codeflash_wrap_decorator.py
KRRT7 745a3f7
test gen for async too
KRRT7 5a47237
Update aiservice.py
KRRT7 1ab1886
create path object once
KRRT7 af96274
use sqlite vs pickle
KRRT7 4dfda09
no dependencies on codeflash
KRRT7 2a2a3a3
add tests for async wrapper
KRRT7 b569d44
linting
KRRT7 4514dd6
address feedback re: using existing logic from tracer & cf capture
KRRT7 fb9555e
test
KRRT7 66f7a84
add unit tests
KRRT7 aa872b5
be consistent
KRRT7 0319803
Update codeflash_wrap_decorator.py
KRRT7 9bbe988
some async changes
KRRT7 1fe7c04
Update test_add_runtime_comments.py
KRRT7 91b8902
Update codeflash/code_utils/codeflash_wrap_decorator.py
misrasaurabh1 0f066c0
Merge branch 'granular-async-instrumentation' of https://github.com/c…
KRRT7 69fa701
mirror tests
KRRT7 862415e
add support for async tests in edit_generated_tests
KRRT7 febf2b6
add tests with run_and_parse_tests
KRRT7 61aade1
Update test_async_run_and_parse_tests.py
KRRT7 5bf5c20
⚡️ Speed up method `CommentMapper.visit_ClassDef` by 197% in PR #687 …
codeflash-ai[bot] b2bf9fa
add missing imports
KRRT7 ef74bb5
Update edit_generated_tests.py
KRRT7 e119085
Merge pull request #706 from codeflash-ai/codeflash/optimize-pr687-20…
KRRT7 600dafc
⚡️ Speed up method `CommentMapper.visit_FunctionDef` by 84% in PR #68…
codeflash-ai[bot] 1142de5
linting / formatting
KRRT7 14280fa
Merge pull request #709 from codeflash-ai/codeflash/optimize-pr687-20…
KRRT7 3ca6fad
linter
KRRT7 73d03ae
add E2E
KRRT7 0af669f
Update workload.py
KRRT7 1ebc616
Update workload.py
KRRT7 d8a6ab2
temp
KRRT7 7bcd136
go
KRRT7 2429801
restore original code if not found for async
KRRT7 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
from __future__ import annotations | ||
|
||
import gc | ||
import inspect | ||
import os | ||
import pickle | ||
import time | ||
from functools import wraps | ||
from pathlib import Path | ||
from typing import Any, Callable, TypeVar | ||
|
||
from codeflash.code_utils.code_utils import get_run_tmp_file | ||
|
||
F = TypeVar("F", bound=Callable[..., Any]) | ||
|
||
|
||
def extract_test_context_from_frame() -> tuple[str, str | None, str]: | ||
frame = inspect.currentframe() | ||
try: | ||
while frame: | ||
frame = frame.f_back | ||
if frame and frame.f_code.co_name.startswith("test_"): | ||
test_name = frame.f_code.co_name | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
test_module_name = frame.f_globals.get("__name__", "unknown_module") | ||
test_class_name = None | ||
if "self" in frame.f_locals: | ||
test_class_name = frame.f_locals["self"].__class__.__name__ | ||
|
||
return test_module_name, test_class_name, test_name | ||
raise RuntimeError("No test function found in call stack") | ||
finally: | ||
del frame | ||
|
||
|
||
def codeflash_behavior_async(func: F) -> F: | ||
function_name = func.__name__ | ||
line_id = f"{func.__name__}_{func.__code__.co_firstlineno}" | ||
loop_index = int(os.environ.get("CODEFLASH_LOOP_INDEX", "1")) | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@wraps(func) | ||
async def async_wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401 | ||
test_module_name, test_class_name, test_name = extract_test_context_from_frame() | ||
|
||
test_id = f"{test_module_name}:{test_class_name}:{test_name}:{line_id}:{loop_index}" | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if not hasattr(async_wrapper, "index"): | ||
async_wrapper.index = {} | ||
if test_id in async_wrapper.index: | ||
async_wrapper.index[test_id] += 1 | ||
else: | ||
async_wrapper.index[test_id] = 0 | ||
|
||
codeflash_test_index = async_wrapper.index[test_id] | ||
invocation_id = f"{line_id}_{codeflash_test_index}" | ||
test_stdout_tag = f"{test_module_name}:{(test_class_name + '.' if test_class_name else '')}{test_name}:{function_name}:{loop_index}:{invocation_id}" | ||
|
||
print(f"!$######{test_stdout_tag}######$!") | ||
|
||
exception = None | ||
gc.disable() | ||
try: | ||
counter = time.perf_counter_ns() | ||
ret = func(*args, **kwargs) | ||
|
||
if inspect.isawaitable(ret): | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
counter = time.perf_counter_ns() | ||
return_value = await ret | ||
else: | ||
return_value = ret | ||
|
||
codeflash_duration = time.perf_counter_ns() - counter | ||
except Exception as e: | ||
codeflash_duration = time.perf_counter_ns() - counter | ||
exception = e | ||
finally: | ||
gc.enable() | ||
|
||
print(f"!######{test_stdout_tag}######!") | ||
|
||
iteration = os.environ.get("CODEFLASH_TEST_ITERATION", "0") | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
codeflash_run_tmp_dir = get_run_tmp_file(Path()).as_posix() | ||
|
||
output_file = Path(codeflash_run_tmp_dir) / f"test_return_values_{iteration}.bin" | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
with output_file.open("ab") as f: | ||
pickled_values = ( | ||
pickle.dumps((args, kwargs, exception)) if exception else pickle.dumps((args, kwargs, return_value)) | ||
) | ||
_test_name = f"{test_module_name}:{(test_class_name + '.' if test_class_name else '')}{test_name}:{function_name}:{line_id}".encode( | ||
"ascii" | ||
) | ||
|
||
f.write(len(_test_name).to_bytes(4, byteorder="big")) | ||
f.write(_test_name) | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
f.write(codeflash_duration.to_bytes(8, byteorder="big")) | ||
f.write(len(pickled_values).to_bytes(4, byteorder="big")) | ||
f.write(pickled_values) | ||
f.write(loop_index.to_bytes(8, byteorder="big")) | ||
f.write(len(invocation_id).to_bytes(4, byteorder="big")) | ||
f.write(invocation_id.encode("ascii")) | ||
|
||
if exception: | ||
raise exception | ||
return return_value | ||
|
||
return async_wrapper | ||
|
||
|
||
def codeflash_performance_async(func: F) -> F: | ||
function_name = func.__name__ | ||
line_id = f"{func.__name__}_{func.__code__.co_firstlineno}" | ||
loop_index = int(os.environ.get("CODEFLASH_LOOP_INDEX", "1")) | ||
KRRT7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@wraps(func) | ||
async def async_wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401 | ||
test_module_name, test_class_name, test_name = extract_test_context_from_frame() | ||
|
||
test_id = f"{test_module_name}:{test_class_name}:{test_name}:{line_id}:{loop_index}" | ||
|
||
if not hasattr(async_wrapper, "index"): | ||
async_wrapper.index = {} | ||
if test_id in async_wrapper.index: | ||
async_wrapper.index[test_id] += 1 | ||
else: | ||
async_wrapper.index[test_id] = 0 | ||
|
||
codeflash_test_index = async_wrapper.index[test_id] | ||
invocation_id = f"{line_id}_{codeflash_test_index}" | ||
test_stdout_tag = f"{test_module_name}:{(test_class_name + '.' if test_class_name else '')}{test_name}:{function_name}:{loop_index}:{invocation_id}" | ||
|
||
print(f"!$######{test_stdout_tag}######$!") | ||
|
||
exception = None | ||
gc.disable() | ||
try: | ||
counter = time.perf_counter_ns() | ||
ret = func(*args, **kwargs) | ||
|
||
if inspect.isawaitable(ret): | ||
counter = time.perf_counter_ns() | ||
return_value = await ret | ||
else: | ||
return_value = ret | ||
|
||
codeflash_duration = time.perf_counter_ns() - counter | ||
except Exception as e: | ||
codeflash_duration = time.perf_counter_ns() - counter | ||
exception = e | ||
finally: | ||
gc.enable() | ||
|
||
print(f"!######{test_stdout_tag}:{codeflash_duration}######!") | ||
|
||
if exception: | ||
raise exception | ||
return return_value | ||
|
||
return async_wrapper |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.