Skip to content

Commit 89d79fe

Browse files
authored
Instrumenter region name (#62)
It is now possible to name parts of the code, where the instrumenter was enabled or disabled.
1 parent 70e11e2 commit 89d79fe

2 files changed

Lines changed: 91 additions & 6 deletions

File tree

README.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,53 @@ with scorep.instrumenter.enable():
119119
do_something()
120120
```
121121

122-
or during startup with `--noinstrumenter`. Please be aware that the function calls override the Flag.
122+
or during startup with `--noinstrumenter`. The given function calls override this flag.
123+
124+
The main idea is to reduce the instrumentation overhead for regions that are not of interest.
125+
Whenever the instrumenter is disabled, function enter or exits will not be trace.
126+
127+
As an example:
128+
129+
```
130+
import numpy as np
131+
132+
[...]
133+
c = np.dot(a,b)
134+
[...]
135+
```
136+
137+
You might not be interested, what happens during the import of numpy, but actually how long `dot` takes.
138+
If you change the code to
139+
140+
```
141+
import numpy as np
142+
import scorep
143+
144+
[...]
145+
with scorep.instrumenter.enable():
146+
c = np.dot(a,b)
147+
[...]
148+
```
149+
and run the code with `python -m scorep --noinstrumenter run.py` only the call to np.dot and everything below will be instrumented.
150+
Please be aware, that user instrumentation, using scorep.user will always be recorded.
151+
152+
153+
With version 3.1 the bindings support the annotation of regions where the instrumenter was explicit enabled or disabled.
154+
You can now pass a `region_name` to `scorep.instrumenter.enable("enabled_region_name")` and `scorep.instrumenter.disable("disabled_region_name")`.
155+
This might be useful if you do something expensive, and just want to know how long it takes, but you do not care what happens exactly e.g.:
156+
157+
```
158+
[...]
159+
def fun_calls(n):
160+
if (n>0):
161+
fun_calls(n-1)
162+
163+
with scorep.instrumenter.disable("my_fun_calls"):
164+
fun_calls(1000000)
165+
[...]
166+
```
167+
168+
`my_fun_calls` will be present in the trace or profile but `fun_calls` will not.
123169

124170
## Overview about Flags
125171

scorep/instrumenter.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import scorep.instrumenters.scorep_profile
33
import scorep.instrumenters.scorep_trace
44

5+
import inspect
6+
import os
7+
58
global_instrumenter = None
69

710

@@ -55,24 +58,42 @@ class enable():
5558
"""
5659
Context manager to enable tracing in a certain region:
5760
```
58-
with enable():
61+
with enable(region_name=None):
5962
do stuff
6063
```
6164
This overides --no-instrumenter (--nopython leagacy)
65+
@param region_name: if a region name is given, the region the contextmanager is active will be marked in the trace or profile
6266
"""
6367

64-
def __init__(self):
65-
pass
68+
def __init__(self, region_name=None):
69+
self.region_name = region_name
6670

6771
def __enter__(self):
6872
self.tracer_registered = scorep.instrumenter.get_instrumenter().get_registered()
6973
if not self.tracer_registered:
74+
if self.region_name:
75+
self.module_name = "user_instrumenter"
76+
frame = inspect.currentframe().f_back
77+
file_name = frame.f_globals.get('__file__', None)
78+
line_number = frame.f_lineno
79+
if file_name is not None:
80+
full_file_name = os.path.abspath(file_name)
81+
else:
82+
full_file_name = "None"
83+
84+
scorep.instrumenter.get_instrumenter().region_begin(
85+
self.module_name, self.region_name, full_file_name, line_number)
86+
7087
scorep.instrumenter.get_instrumenter().register()
7188

7289
def __exit__(self, exc_type, exc_value, traceback):
7390
if not self.tracer_registered:
7491
scorep.instrumenter.get_instrumenter().unregister()
7592

93+
if self.region_name is not None:
94+
scorep.instrumenter.get_instrumenter().region_end(
95+
self.module_name, self.region_name)
96+
7697

7798
class disable():
7899
"""
@@ -82,16 +103,34 @@ class disable():
82103
do stuff
83104
```
84105
This overides --no-instrumenter (--nopython leagacy)
106+
@param region_name: if a region name is given, the region the contextmanager is active will be marked in the trace or profile
85107
"""
86108

87-
def __init__(self):
88-
pass
109+
def __init__(self, region_name=None):
110+
self.region_name = region_name
89111

90112
def __enter__(self):
91113
self.tracer_registered = scorep.instrumenter.get_instrumenter().get_registered()
92114
if self.tracer_registered:
93115
scorep.instrumenter.get_instrumenter().unregister()
94116

117+
if self.region_name is not None:
118+
self.module_name = "user_instrumenter"
119+
frame = inspect.currentframe().f_back
120+
file_name = frame.f_globals.get('__file__', None)
121+
line_number = frame.f_lineno
122+
if file_name is not None:
123+
full_file_name = os.path.abspath(file_name)
124+
else:
125+
full_file_name = "None"
126+
127+
scorep.instrumenter.get_instrumenter().region_begin(
128+
self.module_name, self.region_name, full_file_name, line_number)
129+
95130
def __exit__(self, exc_type, exc_value, traceback):
96131
if self.tracer_registered:
132+
if self.region_name is not None:
133+
scorep.instrumenter.get_instrumenter().region_end(
134+
self.module_name, self.region_name)
135+
97136
scorep.instrumenter.get_instrumenter().register()

0 commit comments

Comments
 (0)