Skip to content

Commit 6aa9e51

Browse files
authored
Add class name to region (#162)
Add class name to region Fixes #161
2 parents 6cad26e + d6e846d commit 6aa9e51

10 files changed

Lines changed: 101 additions & 85 deletions

File tree

scorep/_instrumenters/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from scorep._bindings import abspath
2+
from scorep.instrumenter import has_c_instrumenter
23

34

45
def get_module_name(frame):
@@ -11,6 +12,12 @@ def get_module_name(frame):
1112
modulename = "numpy.__array_function__"
1213
else:
1314
modulename = "unkown"
15+
typeobject = frame.f_locals.get("self", None)
16+
if typeobject is not None:
17+
if has_c_instrumenter():
18+
return ".".join([modulename, type(typeobject).__name__])
19+
else:
20+
return ".".join([modulename, typeobject.__class__.__name__])
1421
return modulename
1522

1623

src/methods.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,20 @@ extern "C"
6969
return NULL;
7070
}
7171

72-
std::string_view module(module_cstr, module_len);
72+
std::string module(module_cstr, module_len);
7373
std::string_view function_name(function_name_cstr, function_name_len);
74-
std::string_view file_name(file_name_cstr, file_name_len);
74+
auto const file_name_abs =
75+
scorepy::abspath(std::string_view(file_name_cstr, file_name_len));
7576

76-
std::string file_name_abs = scorepy::abspath(file_name);
77-
78-
if (identifier == nullptr or identifier == Py_None)
77+
if (identifier == nullptr || identifier == Py_None)
7978
{
80-
scorepy::region_begin(function_name, module, file_name_abs, line_number);
79+
scorepy::region_begin(function_name, std::move(module), std::move(file_name_abs),
80+
line_number);
8181
}
8282
else
8383
{
84-
scorepy::region_begin(function_name, module, file_name_abs, line_number,
85-
reinterpret_cast<PyCodeObject*>(identifier));
84+
scorepy::region_begin(function_name, std::move(module), std::move(file_name_abs),
85+
line_number, reinterpret_cast<PyCodeObject*>(identifier));
8686
}
8787

8888
Py_RETURN_NONE;
@@ -124,16 +124,17 @@ extern "C"
124124
return NULL;
125125
}
126126

127-
std::string_view module(module_cstr, module_len);
127+
std::string module(module_cstr, module_len);
128128
std::string_view function_name(function_name_cstr, function_name_len);
129129

130-
if (identifier == nullptr or identifier == Py_None)
130+
if (identifier == nullptr || identifier == Py_None)
131131
{
132-
scorepy::region_end(function_name, module);
132+
scorepy::region_end(function_name, std::move(module));
133133
}
134134
else
135135
{
136-
scorepy::region_end(function_name, module, reinterpret_cast<PyCodeObject*>(identifier));
136+
scorepy::region_end(function_name, std::move(module),
137+
reinterpret_cast<PyCodeObject*>(identifier));
137138
}
138139

139140
Py_RETURN_NONE;
@@ -253,7 +254,7 @@ extern "C"
253254
{ "abspath", abspath, METH_VARARGS, "Estimates the absolute Path." },
254255
{ "force_finalize", force_finalize, METH_VARARGS, "triggers a finalize" },
255256
{ "reregister_exit_handler", reregister_exit_handler, METH_VARARGS,
256-
"register an new atexit handler" },
257+
"register a new atexit handler" },
257258
{ NULL, NULL, 0, NULL } /* Sentinel */
258259
};
259260
}

src/scorepy/cInstrumenter.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,13 @@ bool CInstrumenter::on_event(PyFrameObject& frame, int what, PyObject*)
119119
bool success = try_region_begin(code);
120120
if (!success)
121121
{
122-
std::string_view name = compat::get_string_as_utf_8(code->co_name);
123-
std::string_view module_name = get_module_name(frame);
122+
const auto name = compat::get_string_as_utf_8(code->co_name);
123+
const auto module_name = get_module_name(frame);
124124
if (name.compare("_unsetprofile") != 0 && module_name.compare(0, 6, "scorep") != 0)
125125
{
126126
const int line_number = code->co_firstlineno;
127-
const std::string file_name = get_file_name(frame);
128-
region_begin(name, module_name, file_name, line_number, code);
127+
const auto file_name = get_file_name(frame);
128+
region_begin(name, std::move(module_name), std::move(file_name), line_number, code);
129129
}
130130
}
131131
Py_DECREF(code);
@@ -137,12 +137,12 @@ bool CInstrumenter::on_event(PyFrameObject& frame, int what, PyObject*)
137137
bool success = try_region_end(code);
138138
if (!success)
139139
{
140-
std::string_view name = compat::get_string_as_utf_8(code->co_name);
141-
std::string_view module_name = get_module_name(frame);
140+
const auto name = compat::get_string_as_utf_8(code->co_name);
141+
const auto module_name = get_module_name(frame);
142142
// TODO: Use string_view/CString comparison?
143-
if (std::string(name) != "_unsetprofile" && std::string(module_name, 0, 6) != "scorep")
143+
if (name.compare("_unsetprofile") != 0 && module_name.compare(0, 6, "scorep") != 0)
144144
{
145-
region_end(name, module_name, code);
145+
region_end(name, std::move(module_name), code);
146146
}
147147
}
148148
Py_DECREF(code);

src/scorepy/compat.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ namespace compat
1414
{
1515
/// Region names that are known to have no region enter event and should not report an error
1616
/// on region exit
17-
static const std::array<std::string, 2> exit_region_whitelist = {
17+
static const std::array<std::string, 4> exit_region_whitelist = {
1818
#if PY_MAJOR_VERSION >= 3
19-
"threading:_bootstrap_inner", "threading:_bootstrap"
19+
"threading.Thread:_bootstrap_inner", "threading.Thread:_bootstrap",
20+
"threading.TMonitor:_bootstrap_inner", "threading.TMonitor:_bootstrap"
2021
#else
21-
"threading:__bootstrap_inner", "threading:__bootstrap"
22+
"threading.Thread:__bootstrap_inner", "threading.Thread:__bootstrap",
23+
"threading.TMonitor:__bootstrap_inner", "threading.TMonitor:__bootstrap"
2224
#endif
2325
};
2426

src/scorepy/events.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,44 +28,51 @@ static compat::RegisterCodeDealloc register_dealloc(on_dealloc);
2828

2929
// Used for regions, that have an identifier, aka a code object id. (instrumenter regions and
3030
// some decorated regions)
31-
void region_begin(std::string_view& function_name, std::string_view& module,
32-
const std::string& file_name, const std::uint64_t line_number,
33-
compat::PyCodeObject* identifier)
31+
void region_begin(std::string_view function_name, std::string module, std::string file_name,
32+
const std::uint64_t line_number, compat::PyCodeObject* identifier)
3433
{
3534
region_handle& region = regions[identifier];
3635

3736
if (region == uninitialised_region_handle)
3837
{
39-
auto& region_name = make_region_name(module, function_name);
38+
auto region_name = make_region_name(std::move(module), function_name);
4039
SCOREP_User_RegionInit(&region.value, NULL, NULL, region_name.c_str(),
4140
SCOREP_USER_REGION_TYPE_FUNCTION, file_name.c_str(), line_number);
4241

43-
SCOREP_User_RegionSetGroup(region.value, std::string(module, 0, module.find('.')).c_str());
42+
if (const auto pos = region_name.find(':'); pos != std::string::npos)
43+
{
44+
region_name.resize(pos);
45+
SCOREP_User_RegionSetGroup(region.value, region_name.c_str());
46+
}
4447
}
4548
SCOREP_User_RegionEnter(region.value);
4649
}
4750

4851
// Used for regions, that only have a function name, a module, a file and a line number (user
4952
// regions)
50-
void region_begin(std::string_view& function_name, std::string_view& module,
51-
const std::string& file_name, const std::uint64_t line_number)
53+
void region_begin(std::string_view function_name, std::string module, std::string file_name,
54+
const std::uint64_t line_number)
5255
{
53-
std::string region_name = make_region_name(module, function_name);
56+
auto region_name = make_region_name(std::move(module), function_name);
5457
region_handle& region = user_regions[region_name];
5558

5659
if (region == uninitialised_region_handle)
5760
{
5861
SCOREP_User_RegionInit(&region.value, NULL, NULL, region_name.c_str(),
5962
SCOREP_USER_REGION_TYPE_FUNCTION, file_name.c_str(), line_number);
6063

61-
SCOREP_User_RegionSetGroup(region.value, std::string(module, 0, module.find('.')).c_str());
64+
if (const auto pos = region_name.find(':'); pos != std::string::npos)
65+
{
66+
region_name.resize(pos);
67+
SCOREP_User_RegionSetGroup(region.value, region_name.c_str());
68+
}
6269
}
6370
SCOREP_User_RegionEnter(region.value);
6471
}
6572

6673
// Used for regions, that have an identifier, aka a code object id. (instrumenter regions and
6774
// some decorated regions)
68-
void region_end(std::string_view& function_name, std::string_view& module,
75+
void region_end(std::string_view function_name, std::string module,
6976
compat::PyCodeObject* identifier)
7077
{
7178
const auto it_region = regions.find(identifier);
@@ -75,27 +82,27 @@ void region_end(std::string_view& function_name, std::string_view& module,
7582
}
7683
else
7784
{
78-
std::string region_name = make_region_name(module, function_name);
79-
region_end_error_handling(region_name);
85+
const auto region_name = make_region_name(std::move(module), function_name);
86+
region_end_error_handling(std::move(region_name));
8087
}
8188
}
8289

8390
// Used for regions, that only have a function name, a module (user regions)
84-
void region_end(std::string_view& function_name, std::string_view& module)
91+
void region_end(std::string_view function_name, std::string module)
8592
{
86-
std::string region_name = make_region_name(module, function_name);
93+
const auto region_name = make_region_name(std::move(module), function_name);
8794
auto it_region = user_regions.find(region_name);
8895
if (it_region != user_regions.end())
8996
{
9097
SCOREP_User_RegionEnd(it_region->second.value);
9198
}
9299
else
93100
{
94-
region_end_error_handling(region_name);
101+
region_end_error_handling(std::move(region_name));
95102
}
96103
}
97104

98-
void region_end_error_handling(const std::string& region_name)
105+
void region_end_error_handling(std::string region_name)
99106
{
100107
static region_handle error_region;
101108
static SCOREP_User_ParameterHandle scorep_param = SCOREP_USER_INVALID_PARAMETER;

src/scorepy/events.hpp

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,11 @@ struct region_handle
3030
constexpr region_handle uninitialised_region_handle = region_handle();
3131

3232
/// Combine the arguments into a region name
33-
/// Return value is a statically allocated string to avoid memory (re)allocations
34-
inline const std::string& make_region_name(std::string_view& module_name, std::string_view& name)
33+
inline std::string make_region_name(std::string module_name, std::string_view name)
3534
{
36-
static std::string region;
37-
region = module_name;
38-
region += ":";
39-
region += name;
40-
return region;
35+
module_name += ':';
36+
module_name += name;
37+
return std::move(module_name);
4138
}
4239

4340
extern std::unordered_map<compat::PyCodeObject*, region_handle> regions;
@@ -59,11 +56,10 @@ inline bool try_region_begin(compat::PyCodeObject* identifier)
5956
}
6057
}
6158

62-
void region_begin(std::string_view& function_name, std::string_view& module,
63-
const std::string& file_name, const std::uint64_t line_number,
64-
compat::PyCodeObject* identifier);
65-
void region_begin(std::string_view& function_name, std::string_view& module,
66-
const std::string& file_name, const std::uint64_t line_number);
59+
void region_begin(std::string_view function_name, std::string module, std::string file_name,
60+
const std::uint64_t line_number, compat::PyCodeObject* identifier);
61+
void region_begin(std::string_view function_name, std::string module, std::string file_name,
62+
const std::uint64_t line_number);
6763

6864
/** tries to end a region. Return true on success
6965
*
@@ -82,11 +78,11 @@ inline bool try_region_end(compat::PyCodeObject* identifier)
8278
}
8379
}
8480

85-
void region_end(std::string_view& function_name, std::string_view& module,
81+
void region_end(std::string_view function_name, std::string module,
8682
compat::PyCodeObject* identifier);
87-
void region_end(std::string_view& function_name, std::string_view& module);
83+
void region_end(std::string_view function_name, std::string module);
8884

89-
void region_end_error_handling(const std::string& region_name);
85+
void region_end_error_handling(std::string region_name);
9086

9187
void rewind_begin(std::string region_name, std::string file_name, std::uint64_t line_number);
9288
void rewind_end(std::string region_name, bool value);

src/scorepy/pathUtils.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static std::string getcwd()
2525
result.resize(result.find('\0', result.size() - chunk_size));
2626
else
2727
result.clear();
28-
return result;
28+
return std::move(result);
2929
}
3030

3131
void normalize_path(std::string& path)
@@ -80,7 +80,7 @@ std::string abspath(std::string_view input_path)
8080
result = getcwd();
8181
// On error exit
8282
if (result.empty())
83-
return result;
83+
return {};
8484
// Prepend CWD
8585
result.append(1, '/').append(input_path);
8686
}
@@ -89,6 +89,6 @@ std::string abspath(std::string_view input_path)
8989
result = input_path;
9090
}
9191
normalize_path(result);
92-
return result;
92+
return std::move(result);
9393
}
9494
} // namespace scorepy

src/scorepy/pythonHelpers.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,46 @@
33
#include "pathUtils.hpp"
44
#include "pythoncapi_compat.h"
55

6+
#include <sstream>
67
#include <stdlib.h>
78

89
namespace scorepy
910
{
10-
std::string_view get_module_name(PyFrameObject& frame)
11+
std::string get_module_name(PyFrameObject& frame)
1112
{
13+
const char* self_name = nullptr;
14+
PyObject* locals = PyFrame_GetLocals(&frame);
15+
PyObject* self = PyDict_GetItemString(locals, "self");
16+
if (self)
17+
{
18+
Py_INCREF(self);
19+
PyTypeObject* type = Py_TYPE(self);
20+
self_name = _PyType_Name(type);
21+
Py_DECREF(self);
22+
}
23+
Py_DECREF(locals);
24+
1225
PyObject* globals = PyFrame_GetGlobals(&frame);
1326
PyObject* module_name = PyDict_GetItemString(globals, "__name__");
1427
Py_DECREF(globals);
1528
if (module_name)
16-
return compat::get_string_as_utf_8(module_name);
29+
{
30+
std::stringstream result;
31+
result << compat::get_string_as_utf_8(module_name);
32+
if (self_name)
33+
result << '.' << self_name;
34+
return std::move(result).str();
35+
}
1736

1837
// this is a NUMPY special situation, see NEP-18, and Score-P issue #63
1938
// TODO: Use string_view/C-String to avoid creating 2 std::strings
2039
PyCodeObject* code = PyFrame_GetCode(&frame);
2140
std::string_view filename = compat::get_string_as_utf_8(code->co_filename);
2241
Py_DECREF(code);
2342
if ((filename.size() > 0) && (filename == "<__array_function__ internals>"))
24-
return std::string_view("numpy.__array_function__");
43+
return std::move(std::string("numpy.__array_function__"));
2544
else
26-
return std::string_view("unkown");
45+
return std::move(std::string("unkown"));
2746
}
2847

2948
std::string get_file_name(PyFrameObject& frame)
@@ -33,9 +52,9 @@ std::string get_file_name(PyFrameObject& frame)
3352
Py_DECREF(code);
3453
if (filename == Py_None)
3554
{
36-
return "None";
55+
return std::move(std::string("None"));
3756
}
38-
const std::string full_file_name = abspath(compat::get_string_as_utf_8(filename));
39-
return !full_file_name.empty() ? full_file_name : "ErrorPath";
57+
const auto full_file_name = abspath(compat::get_string_as_utf_8(filename));
58+
return !full_file_name.empty() ? std::move(full_file_name) : "ErrorPath";
4059
}
4160
} // namespace scorepy

src/scorepy/pythonHelpers.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ auto cast_to_PyFunc(TFunc* func) -> detail::ReplaceArgsToPyObject_t<TFunc>*
7373

7474
/// Return the module name the frame belongs to.
7575
/// The pointer is valid for the lifetime of the frame
76-
std::string_view get_module_name(PyFrameObject& frame);
76+
std::string get_module_name(PyFrameObject& frame);
7777
/// Return the file name the frame belongs to
7878
std::string get_file_name(PyFrameObject& frame);
7979

0 commit comments

Comments
 (0)