prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Profiler: Automatically fill `tag` in `record`?
  Maybe we can use the caller's function name (`inspect.stack()`) if tag is not given.
  
  TODO: Need to measure overhead.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pytorch_pfn_extras/profiler/_record.py`
  Content:
  ```
  1 from contextlib import contextmanager
  2 from typing import Any, Callable, Generator, Iterable, Optional, TypeVar
  3 
  4 import torch
  5 
  6 from pytorch_pfn_extras.profiler._time_summary import time_summary, _ReportNotification
  7 
  8 
  9 @contextmanager
  10 def record(
  11         tag: str,
  12         metric: Optional[str] = None,
  13         use_cuda: bool = False,
  14 ) -> Generator[_ReportNotification, None, None]:
  15     if metric is None:
  16         metric = tag
  17 
  18     if use_cuda:
  19         torch.cuda.nvtx.range_push(tag)  # type: ignore[no-untyped-call]
  20     try:
  21         with torch.autograd.profiler.record_function(tag):
  22             with time_summary.report(metric, use_cuda) as ntf:
  23                 yield ntf
  24     finally:
  25         if use_cuda:
  26             torch.cuda.nvtx.range_pop()  # type: ignore[no-untyped-call]
  27 
  28 
  29 _T = TypeVar('_T')
  30 
  31 
  32 def record_function(
  33         tag: str,
  34         use_cuda: bool = False,
  35 ) -> Callable[[Callable[..., _T]], Callable[..., _T]]:
  36     def wrapper(f: Callable[..., _T]) -> Callable[..., _T]:
  37         def wrapped(*args: Any, **kwargs: Any) -> _T:
  38             with record(tag, use_cuda=use_cuda):
  39                 return f(*args, **kwargs)
  40 
  41         return wrapped
  42 
  43     return wrapper
  44 
  45 
  46 def record_iterable(
  47     tag: str,
  48     iter: Iterable[_T],
  49     divide_metric: bool = False,
  50     use_cuda: bool = False,
  51 ) -> Iterable[_T]:
  52     def wrapped() -> Iterable[_T]:
  53         for i, x in enumerate(iter):
  54             name = f"{tag}-{i}"
  55             metric = name if divide_metric else tag
  56             with record(name, metric, use_cuda=use_cuda):
  57                 yield x
  58 
  59     return wrapped()
  60
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pytorch_pfn_extras/profiler/_record.py b/pytorch_pfn_extras/profiler/_record.py
  --- a/pytorch_pfn_extras/profiler/_record.py
  +++ b/pytorch_pfn_extras/profiler/_record.py
  @@ -1,17 +1,35 @@
   from contextlib import contextmanager
  +import inspect
   from typing import Any, Callable, Generator, Iterable, Optional, TypeVar
  +import types
   
   import torch
   
   from pytorch_pfn_extras.profiler._time_summary import time_summary, _ReportNotification
   
   
  +def _infer_tag_name(frame: Optional[types.FrameType], depth: int) -> str:
  +    for _ in range(depth):
  +        assert frame is not None
  +        frame = frame.f_back
  +    assert frame is not None
  +    frame_info = inspect.getframeinfo(frame, context=0)
  +    return '{}:{}:{}'.format(
  +        inspect.getmodulename(frame_info.filename),
  +        frame_info.lineno,
  +        frame_info.function,
  +    )
  +
  +
   @contextmanager
   def record(
  -        tag: str,
  +        tag: Optional[str],
           metric: Optional[str] = None,
           use_cuda: bool = False,
   ) -> Generator[_ReportNotification, None, None]:
  +    if tag is None:
  +        tag = _infer_tag_name(inspect.currentframe(), depth=2)
  +
       if metric is None:
           metric = tag
   
  @@ -30,12 +48,12 @@
   
   
   def record_function(
  -        tag: str,
  +        tag: Optional[str],
           use_cuda: bool = False,
   ) -> Callable[[Callable[..., _T]], Callable[..., _T]]:
       def wrapper(f: Callable[..., _T]) -> Callable[..., _T]:
           def wrapped(*args: Any, **kwargs: Any) -> _T:
  -            with record(tag, use_cuda=use_cuda):
  +            with record(tag or f.__name__, use_cuda=use_cuda):
                   return f(*args, **kwargs)
   
           return wrapped
  @@ -44,11 +62,14 @@
   
   
   def record_iterable(
  -    tag: str,
  -    iter: Iterable[_T],
  -    divide_metric: bool = False,
  -    use_cuda: bool = False,
  +        tag: Optional[str],
  +        iter: Iterable[_T],
  +        divide_metric: bool = False,
  +        use_cuda: bool = False,
   ) -> Iterable[_T]:
  +    if tag is None:
  +        tag = _infer_tag_name(inspect.currentframe(), depth=1)
  +
       def wrapped() -> Iterable[_T]:
           for i, x in enumerate(iter):
               name = f"{tag}-{i}"
  
verification_info: {"golden_diff": "diff --git a/pytorch_pfn_extras/profiler/_record.py b/pytorch_pfn_extras/profiler/_record.py\n--- a/pytorch_pfn_extras/profiler/_record.py\n+++ b/pytorch_pfn_extras/profiler/_record.py\n@@ -1,17 +1,35 @@\n from contextlib import contextmanager\n+import inspect\n from typing import Any, Callable, Generator, Iterable, Optional, TypeVar\n+import types\n \n import torch\n \n from pytorch_pfn_extras.profiler._time_summary import time_summary, _ReportNotification\n \n \n+def _infer_tag_name(frame: Optional[types.FrameType], depth: int) -> str:\n+    for _ in range(depth):\n+        assert frame is not None\n+        frame = frame.f_back\n+    assert frame is not None\n+    frame_info = inspect.getframeinfo(frame, context=0)\n+    return '{}:{}:{}'.format(\n+        inspect.getmodulename(frame_info.filename),\n+        frame_info.lineno,\n+        frame_info.function,\n+    )\n+\n+\n @contextmanager\n def record(\n-        tag: str,\n+        tag: Optional[str],\n         metric: Optional[str] = None,\n         use_cuda: bool = False,\n ) -> Generator[_ReportNotification, None, None]:\n+    if tag is None:\n+        tag = _infer_tag_name(inspect.currentframe(), depth=2)\n+\n     if metric is None:\n         metric = tag\n \n@@ -30,12 +48,12 @@\n \n \n def record_function(\n-        tag: str,\n+        tag: Optional[str],\n         use_cuda: bool = False,\n ) -> Callable[[Callable[..., _T]], Callable[..., _T]]:\n     def wrapper(f: Callable[..., _T]) -> Callable[..., _T]:\n         def wrapped(*args: Any, **kwargs: Any) -> _T:\n-            with record(tag, use_cuda=use_cuda):\n+            with record(tag or f.__name__, use_cuda=use_cuda):\n                 return f(*args, **kwargs)\n \n         return wrapped\n@@ -44,11 +62,14 @@\n \n \n def record_iterable(\n-    tag: str,\n-    iter: Iterable[_T],\n-    divide_metric: bool = False,\n-    use_cuda: bool = False,\n+        tag: Optional[str],\n+        iter: Iterable[_T],\n+        divide_metric: bool = False,\n+        use_cuda: bool = False,\n ) -> Iterable[_T]:\n+    if tag is None:\n+        tag = _infer_tag_name(inspect.currentframe(), depth=1)\n+\n     def wrapped() -> Iterable[_T]:\n         for i, x in enumerate(iter):\n             name = f\"{tag}-{i}\"\n", "issue": "Profiler: Automatically fill `tag` in `record`?\nMaybe we can use the caller's function name (`inspect.stack()`) if tag is not given.\r\n\r\nTODO: Need to measure overhead.\n", "before_files": [{"content": "from contextlib import contextmanager\nfrom typing import Any, Callable, Generator, Iterable, Optional, TypeVar\n\nimport torch\n\nfrom pytorch_pfn_extras.profiler._time_summary import time_summary, _ReportNotification\n\n\n@contextmanager\ndef record(\n        tag: str,\n        metric: Optional[str] = None,\n        use_cuda: bool = False,\n) -> Generator[_ReportNotification, None, None]:\n    if metric is None:\n        metric = tag\n\n    if use_cuda:\n        torch.cuda.nvtx.range_push(tag)  # type: ignore[no-untyped-call]\n    try:\n        with torch.autograd.profiler.record_function(tag):\n            with time_summary.report(metric, use_cuda) as ntf:\n                yield ntf\n    finally:\n        if use_cuda:\n            torch.cuda.nvtx.range_pop()  # type: ignore[no-untyped-call]\n\n\n_T = TypeVar('_T')\n\n\ndef record_function(\n        tag: str,\n        use_cuda: bool = False,\n) -> Callable[[Callable[..., _T]], Callable[..., _T]]:\n    def wrapper(f: Callable[..., _T]) -> Callable[..., _T]:\n        def wrapped(*args: Any, **kwargs: Any) -> _T:\n            with record(tag, use_cuda=use_cuda):\n                return f(*args, **kwargs)\n\n        return wrapped\n\n    return wrapper\n\n\ndef record_iterable(\n    tag: str,\n    iter: Iterable[_T],\n    divide_metric: bool = False,\n    use_cuda: bool = False,\n) -> Iterable[_T]:\n    def wrapped() -> Iterable[_T]:\n        for i, x in enumerate(iter):\n            name = f\"{tag}-{i}\"\n            metric = name if divide_metric else tag\n            with record(name, metric, use_cuda=use_cuda):\n                yield x\n\n    return wrapped()\n", "path": "pytorch_pfn_extras/profiler/_record.py"}], "after_files": [{"content": "from contextlib import contextmanager\nimport inspect\nfrom typing import Any, Callable, Generator, Iterable, Optional, TypeVar\nimport types\n\nimport torch\n\nfrom pytorch_pfn_extras.profiler._time_summary import time_summary, _ReportNotification\n\n\ndef _infer_tag_name(frame: Optional[types.FrameType], depth: int) -> str:\n    for _ in range(depth):\n        assert frame is not None\n        frame = frame.f_back\n    assert frame is not None\n    frame_info = inspect.getframeinfo(frame, context=0)\n    return '{}:{}:{}'.format(\n        inspect.getmodulename(frame_info.filename),\n        frame_info.lineno,\n        frame_info.function,\n    )\n\n\n@contextmanager\ndef record(\n        tag: Optional[str],\n        metric: Optional[str] = None,\n        use_cuda: bool = False,\n) -> Generator[_ReportNotification, None, None]:\n    if tag is None:\n        tag = _infer_tag_name(inspect.currentframe(), depth=2)\n\n    if metric is None:\n        metric = tag\n\n    if use_cuda:\n        torch.cuda.nvtx.range_push(tag)  # type: ignore[no-untyped-call]\n    try:\n        with torch.autograd.profiler.record_function(tag):\n            with time_summary.report(metric, use_cuda) as ntf:\n                yield ntf\n    finally:\n        if use_cuda:\n            torch.cuda.nvtx.range_pop()  # type: ignore[no-untyped-call]\n\n\n_T = TypeVar('_T')\n\n\ndef record_function(\n        tag: Optional[str],\n        use_cuda: bool = False,\n) -> Callable[[Callable[..., _T]], Callable[..., _T]]:\n    def wrapper(f: Callable[..., _T]) -> Callable[..., _T]:\n        def wrapped(*args: Any, **kwargs: Any) -> _T:\n            with record(tag or f.__name__, use_cuda=use_cuda):\n                return f(*args, **kwargs)\n\n        return wrapped\n\n    return wrapper\n\n\ndef record_iterable(\n        tag: Optional[str],\n        iter: Iterable[_T],\n        divide_metric: bool = False,\n        use_cuda: bool = False,\n) -> Iterable[_T]:\n    if tag is None:\n        tag = _infer_tag_name(inspect.currentframe(), depth=1)\n\n    def wrapped() -> Iterable[_T]:\n        for i, x in enumerate(iter):\n            name = f\"{tag}-{i}\"\n            metric = name if divide_metric else tag\n            with record(name, metric, use_cuda=use_cuda):\n                yield x\n\n    return wrapped()\n", "path": "pytorch_pfn_extras/profiler/_record.py"}]}