Skip to content

Commit d02b59c

Browse files
committed
add user rewind support
1 parent c8bd9e6 commit d02b59c

5 files changed

Lines changed: 151 additions & 0 deletions

File tree

scorep/trace.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,34 @@ def user_region_begin(self, name, file_name=None, line_number=None):
135135

136136
def user_region_end(self, name):
137137
self.scorep_bindings.region_end("user", name)
138+
139+
def rewind_begin(self, name, file_name=None, line_number=None):
140+
"""
141+
Begin of an Rewind region. If file_name or line_number is None, both will
142+
bet determined automatically
143+
@param name name of the user region
144+
@param file_name file name of the user region
145+
@param line_number line number of the user region
146+
"""
147+
if file_name is None or line_number is None:
148+
frame = inspect.currentframe().f_back
149+
file_name = frame.f_globals.get('__file__', None)
150+
line_number = frame.f_lineno
151+
if file_name is not None:
152+
full_file_name = os.path.abspath(file_name)
153+
else:
154+
full_file_name = "None"
155+
156+
self.scorep_bindings.rewind_begin(name, full_file_name, line_number)
157+
158+
def rewind_end(self, name, value):
159+
"""
160+
End of an Rewind region.
161+
@param name name of the user region
162+
@param value True or False, whenether the region shall be rewinded or not.
163+
"""
164+
self.scorep_bindings.rewind_end(name, value)
165+
138166

139167
def oa_region_begin(self, name, file_name=None, line_number=None):
140168
"""

scorep/user.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,35 @@ def region_begin(name, file_name=None, line_number=None):
3030
def region_end(name):
3131
global_trace.user_region_end(name)
3232

33+
def rewind_begin(name, file_name=None, line_number=None):
34+
"""
35+
Begin of an User region. If file_name or line_number is None, both will
36+
bet determined automatically
37+
@param name name of the user region
38+
@param file_name file name of the user region
39+
@param line_number line number of the user region
40+
"""
41+
global_trace.unregister()
42+
if file_name is None or line_number is None:
43+
frame = inspect.currentframe().f_back
44+
file_name = frame.f_globals.get('__file__', None)
45+
line_number = frame.f_lineno
46+
if file_name is not None:
47+
full_file_name = os.path.abspath(file_name)
48+
else:
49+
full_file_name = "None"
50+
51+
global_trace.rewind_begin(name, full_file_name, line_number)
52+
global_trace.register()
53+
54+
55+
def rewind_end(name, value):
56+
"""
57+
End of an Rewind region.
58+
@param name name of the user region
59+
@param value True or False, whenether the region shall be rewinded or not.
60+
"""
61+
global_trace.rewind_end(name, value)
3362

3463
def oa_region_begin(name, file_name=None, line_number=None):
3564
global_trace.unregister()

src/scorep.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct region_handle
1818
};
1919

2020
static std::unordered_map<std::string, region_handle> regions;
21+
static std::unordered_map<std::string, region_handle> rewind_regions;
2122

2223
void region_begin(std::string region_name, std::string module, std::string file_name,
2324
std::uint64_t line_number)
@@ -41,6 +42,29 @@ void region_end(std::string region_name)
4142
SCOREP_User_RegionEnd(handle.value);
4243
}
4344

45+
void rewind_begin(std::string region_name, std::string file_name, std::uint64_t line_number)
46+
{
47+
auto pair = rewind_regions.emplace(make_pair(region_name, region_handle()));
48+
bool inserted_new = pair.second;
49+
auto& handle = pair.first->second;
50+
if (inserted_new)
51+
{
52+
SCOREP_User_RegionInit(&handle.value, NULL, &SCOREP_User_LastFileHandle,
53+
region_name.c_str(), SCOREP_USER_REGION_TYPE_FUNCTION,
54+
file_name.c_str(), line_number);
55+
}
56+
SCOREP_User_RewindRegionEnter(handle.value);
57+
}
58+
59+
void rewind_end(std::string region_name, bool value)
60+
{
61+
auto& handle = rewind_regions[region_name];
62+
/* don't call SCOREP_ExitRewindRegion, as
63+
* SCOREP_User_RewindRegionEnd does some additional magic
64+
* */
65+
SCOREP_User_RewindRegionEnd(handle.value, value);
66+
}
67+
4468
void parameter_int(std::string name, int64_t value)
4569
{
4670
static SCOREP_User_ParameterHandle scorep_param = SCOREP_USER_INVALID_PARAMETER;
@@ -140,6 +164,36 @@ extern "C"
140164
return Py_None;
141165
}
142166

167+
static PyObject* rewind_begin(PyObject* self, PyObject* args)
168+
{
169+
const char* region_name;
170+
const char* file_name;
171+
std::uint64_t line_number = 0;
172+
173+
if (!PyArg_ParseTuple(args, "ssK", &region_name, &file_name, &line_number))
174+
return NULL;
175+
176+
scorep::rewind_begin(region_name, file_name, line_number);
177+
178+
Py_INCREF(Py_None);
179+
return Py_None;
180+
}
181+
182+
static PyObject* rewind_end(PyObject* self, PyObject* args)
183+
{
184+
const char* region_name;
185+
PyObject* value; // false C-Style
186+
187+
if (!PyArg_ParseTuple(args, "sO", &region_name, &value))
188+
return NULL;
189+
190+
// TODO cover PyObject_IsTrue(value) == -1 (error case)
191+
scorep::rewind_end(region_name, PyObject_IsTrue(value) == 1);
192+
193+
Py_INCREF(Py_None);
194+
return Py_None;
195+
}
196+
143197
static PyObject* oa_region_begin(PyObject* self, PyObject* args)
144198
{
145199
const char* region;
@@ -219,6 +273,8 @@ extern "C"
219273
static PyMethodDef ScorePMethods[] = {
220274
{ "region_begin", region_begin, METH_VARARGS, "enter a region." },
221275
{ "region_end", region_end, METH_VARARGS, "exit a region." },
276+
{ "rewind_begin", rewind_begin, METH_VARARGS, "rewind begin." },
277+
{ "rewind_end", rewind_end, METH_VARARGS, "rewind end." },
222278
{ "oa_region_begin", oa_region_begin, METH_VARARGS, "enter an online access region." },
223279
{ "oa_region_end", oa_region_end, METH_VARARGS, "exit an online access region." },
224280
{ "enable_recording", enable_recording, METH_VARARGS, "disable scorep recording." },

test/test.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,32 @@ def test_user_regions(self):
8585
self.assertRegex(std_out,
8686
'LEAVE[ ]*[0-9 ]*[0-9 ]*Region: "user:test_region"')
8787

88+
def test_user_rewind(self):
89+
env = self.env
90+
env["SCOREP_EXPERIMENT_DIRECTORY"] += "/test_user_rewind"
91+
trace_path = env["SCOREP_EXPERIMENT_DIRECTORY"] + "/traces.otf2"
92+
93+
out = call([self.python,
94+
"-m",
95+
"scorep",
96+
"test_user_rewind.py"],
97+
env=env)
98+
std_out = out[1]
99+
std_err = out[2]
100+
101+
self.assertEqual(std_err, self.expected_std_err)
102+
self.assertEqual(std_out, "hello world\nhello world\n")
103+
104+
out = call(["otf2-print", trace_path])
105+
std_out = out[1]
106+
std_err = out[2]
107+
108+
self.assertRegex(std_out,
109+
'MEASUREMENT_ON_OFF[ ]*[0-9 ]*[0-9 ]*Mode: OFF')
110+
self.assertRegex(std_out,
111+
'MEASUREMENT_ON_OFF[ ]*[0-9 ]*[0-9 ]*Mode: ON')
112+
113+
88114
def test_oa_regions(self):
89115
env = self.env
90116
env["SCOREP_EXPERIMENT_DIRECTORY"] += "/test_oa_regions"

test/test_user_rewind.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import scorep.user
2+
3+
def bar():
4+
print("hello world")
5+
6+
def foo():
7+
bar()
8+
scorep.user.rewind_begin("test_region")
9+
bar()
10+
scorep.user.rewind_end("test_region",True)
11+
12+
foo()

0 commit comments

Comments
 (0)