Skip to content

Commit d7cf1c7

Browse files
committed
Merge branch 'master' of github.com:score-p/scorep_binding_python
2 parents 4cece8b + 19bf80d commit d7cf1c7

12 files changed

Lines changed: 111 additions & 45 deletions

File tree

.github/workflows/unit_tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
python: [2.7, 3.5, 3.6, 3.7, 3.8]
12+
python: [2.7, 3.5, 3.6, 3.7, 3.8, 'pypy-2.7', 'pypy-3.6', 'pypy-3.7']
1313
fail-fast: false
1414

1515
steps:
@@ -41,4 +41,4 @@ jobs:
4141
run: pip install .
4242
- name: Run tests
4343
working-directory: test
44-
run: pytest
44+
run: pytest

CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ find_package(Python REQUIRED COMPONENTS Interpreter Development)
1919
Python_add_library(_bindings
2020
src/methods.cpp src/scorep_bindings.cpp src/scorepy/events.cpp
2121
)
22-
if(Python_VERSION_MAJOR GREATER_EQUAL 3)
22+
if(Python_VERSION_MAJOR GREATER_EQUAL 3 AND NOT Python_INTERPRETER_ID STREQUAL "PyPy")
2323
target_sources(_bindings PRIVATE
2424
src/classes.cpp
2525
src/scorepy/cInstrumenter.cpp
2626
src/scorepy/pathUtils.cpp
2727
src/scorepy/pythonHelpers.cpp
2828
)
29+
target_compile_definitions(_bindings PRIVATE SCOREPY_ENABLE_CINSTRUMENTER=1)
30+
else()
31+
target_compile_definitions(_bindings PRIVATE SCOREPY_ENABLE_CINSTRUMENTER=0)
2932
endif()
3033
target_link_libraries(_bindings PRIVATE Scorep::Plugin)
3134
target_compile_features(_bindings PRIVATE cxx_std_11)

scorep/__main__.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33

44
import scorep.instrumenter
55
import scorep.subsystem
6+
from scorep.helper import print_err
67

78

89
def _err_exit(msg):
9-
sys.stderr.write("%s: %s\n" % ("scorep", msg))
10+
print_err("scorep: " + msg)
1011
sys.exit(1)
1112

1213

@@ -19,17 +20,25 @@ def scorep_main(argv=None):
1920
parse_scorep_commands = True
2021

2122
keep_files = False
23+
verbose = False
2224
no_default_threads = False
2325
no_default_compiler = False
2426
no_instrumenter = False
25-
instrumenter_type = "profile"
27+
if scorep.instrumenter.has_c_instrumenter():
28+
instrumenter_type = "cProfile"
29+
else:
30+
instrumenter_type = "profile"
2631

2732
for elem in argv[1:]:
2833
if parse_scorep_commands:
29-
if elem == "--mpi":
34+
if elem == "--":
35+
parse_scorep_commands = False
36+
elif elem == "--mpi":
3037
scorep_config.append("--mpp=mpi")
3138
elif elem == "--keep-files":
3239
keep_files = True
40+
elif elem == "--verbose" or elem == '-v':
41+
verbose = True
3342
elif "--thread=" in elem:
3443
scorep_config.append(elem)
3544
no_default_threads = True
@@ -61,7 +70,7 @@ def scorep_main(argv=None):
6170
_err_exit("Did not find a script to run")
6271

6372
if os.environ.get("SCOREP_PYTHON_BINDINGS_INITIALISED") != "true":
64-
scorep.subsystem.init_environment(scorep_config, keep_files)
73+
scorep.subsystem.init_environment(scorep_config, keep_files, verbose)
6574
os.environ["SCOREP_PYTHON_BINDINGS_INITIALISED"] = "true"
6675
"""
6776
python -m starts the module as skript. i.e. sys.argv will loke like:

scorep/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.2.0"
1+
__version__ = "3.3.0"

scorep/helper.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
import re
55

66

7+
def print_err(*args):
8+
"""Print to stderr"""
9+
sys.stderr.write(' '.join(map(str, args)) + '\n')
10+
11+
712
def call(arguments):
813
"""
914
return a triple with (returncode, stdout, stderr) from the call to subprocess
1015
"""
11-
result = ()
1216
if sys.version_info > (3, 5):
1317
out = subprocess.run(
1418
arguments,
@@ -74,15 +78,15 @@ def add_to_ld_library_path(path):
7478
os.environ["LD_LIBRARY_PATH"] = ':'.join([path] + library_paths)
7579

7680

77-
def generate_compile_deps(config=[]):
81+
def generate_compile_deps(config):
7882
"""
7983
Generates the data needed for compilation.
8084
"""
8185

82-
scorep_config = ["scorep-config"] + config + ["--user"]
86+
scorep_config = ["scorep-config"] + config
8387

84-
(retrun_code, _, _) = call(scorep_config)
85-
if retrun_code != 0:
88+
(return_code, _, _) = call(scorep_config)
89+
if return_code != 0:
8690
raise ValueError(
8791
"given config {} is not supported".format(config))
8892

scorep/instrumenter.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import inspect
22
import os
3+
import platform
4+
import sys
35

46
global_instrumenter = None
57

68

9+
def has_c_instrumenter():
10+
"""Return true if the C instrumenter(s) are available"""
11+
# We are using the UTF-8 string features from Python 3
12+
# The C Instrumenter functions are not available on PyPy
13+
return sys.version_info.major >= 3 and platform.python_implementation() != 'PyPy'
14+
15+
716
def get_instrumenter(enable_instrumenter=False,
817
instrumenter_type="dummy"):
918
"""

scorep/subsystem.py

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import os
2-
import sys
32
import distutils.ccompiler
43
import tempfile
54
import shutil
65

76
import scorep.helper
7+
from scorep.helper import print_err
8+
9+
10+
def _print_info(msg):
11+
"""Print an info message with a prefix"""
12+
print_err("scorep: " + msg)
813

914

1015
def generate_subsystem_lib_name():
@@ -24,20 +29,19 @@ def generate_ld_preload(scorep_config):
2429
@return ld_preload string which needs to be passed to LD_PRELOAD
2530
"""
2631

27-
(_, preload, _) = scorep.helper.call(
28-
["scorep-config"] + scorep_config + ["--user", "--preload-libs"])
29-
return preload
32+
(_, preload, _) = scorep.helper.call(["scorep-config"] + scorep_config + ["--preload-libs"])
33+
return preload.strip()
3034

3135

32-
def generate_subsystem_code(config=[]):
36+
def generate_subsystem_code(config):
3337
"""
3438
Generates the data needed to be preloaded.
3539
"""
3640

37-
scorep_config = ["scorep-config"] + config + ["--user"]
41+
scorep_config = ["scorep-config"] + config
3842

39-
(retrun_code, _, _) = scorep.helper.call(scorep_config)
40-
if retrun_code != 0:
43+
(return_code, _, _) = scorep.helper.call(scorep_config)
44+
if return_code != 0:
4145
raise ValueError(
4246
"given config {} is not supported".format(scorep_config))
4347
(_, scorep_adapter_init, _) = scorep.helper.call(
@@ -75,9 +79,7 @@ def generate(scorep_config, keep_files=False):
7579

7680
temp_dir = tempfile.mkdtemp(prefix="scorep.")
7781
if keep_files:
78-
sys.stderr.write(
79-
"Score-P files are keept at: {}\n".format(temp_dir))
80-
sys.stderr.flush()
82+
_print_info("Score-P files are kept at: " + temp_dir)
8183

8284
with open(temp_dir + "/scorep_init.c", "w") as f:
8385
f.write(scorep_adapter_init)
@@ -99,35 +101,50 @@ def generate(scorep_config, keep_files=False):
99101
return(subsystem_lib_name, temp_dir)
100102

101103

102-
def init_environment(scorep_config=[], keep_files=False):
104+
def init_environment(scorep_config, keep_files=False, verbose=False):
103105
"""
104-
Set the inital needed environmet variables, to get everythin up an running.
105-
As a few variables interact with LD env vars, the programms needs to be restarted after this.
106+
Set the inital needed environment variables, to get everything up an running.
107+
As a few variables interact with LD env vars, the program needs to be restarted after this.
106108
107109
@param scorep_config configuration flags for score-p
108110
@param keep_files whether to keep the generated files, or not.
111+
@param verbose Set to True to output information about config used and environment variables set.
109112
"""
110113

111114
if "libscorep" in os.environ.get("LD_PRELOAD", ""):
112-
raise RuntimeError(
113-
"Score-P is already loaded. This should not happen at this point")
115+
raise RuntimeError("Score-P is already loaded. This should not happen at this point")
116+
117+
if "--user" not in scorep_config:
118+
scorep_config.append("--user")
114119

115-
subsystem_lib_name, temp_dir = scorep.subsystem.generate(
116-
scorep_config, keep_files)
120+
if verbose:
121+
_print_info("Score-P config: %s" % scorep_config)
122+
123+
old_env = os.environ.copy()
124+
125+
subsystem_lib_name, temp_dir = generate(scorep_config, keep_files)
117126
scorep_ld_preload = generate_ld_preload(scorep_config)
118127

119128
scorep.helper.add_to_ld_library_path(temp_dir)
120129

121130
preload_str = scorep_ld_preload + " " + subsystem_lib_name
122-
if "LD_PRELOAD" in os.environ:
123-
sys.stderr.write(
124-
"LD_PRELOAD is already specified. If Score-P is already loaded this might lead to errors.")
131+
if os.environ.get("LD_PRELOAD"):
132+
print_err("LD_PRELOAD is already specified. If Score-P is already loaded this might lead to errors.")
125133
preload_str = os.environ["LD_PRELOAD"] + " " + preload_str
126134
os.environ["SCOREP_LD_PRELOAD_BACKUP"] = os.environ["LD_PRELOAD"]
127135
else:
128136
os.environ["SCOREP_LD_PRELOAD_BACKUP"] = ""
129137
os.environ["LD_PRELOAD"] = preload_str
130138

139+
if verbose:
140+
for var in ("LD_LIBRARY_PATH", "LD_PRELOAD"):
141+
# Shorten the setting to e.g.: FOO=new:$FOO
142+
old_val = old_env.get(var)
143+
new_val = os.environ[var]
144+
if old_val:
145+
new_val = new_val.replace(old_val, '$' + var)
146+
_print_info('%s="%s"' % (var, new_val))
147+
131148

132149
def reset_preload():
133150
"""

setup.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import sys
33
from distutils.core import setup, Extension
44
import scorep.helper
5+
from scorep.instrumenter import has_c_instrumenter
56

67
if scorep.helper.get_scorep_version() < 5.0:
78
raise RuntimeError(
@@ -16,33 +17,39 @@
1617
if "gcc" in check_compiler:
1718
gcc_plugin = scorep.helper.get_scorep_config("GCC plug-in support:")
1819
if not ("yes" in gcc_plugin):
19-
raise RuntimeError(
20-
"Score-P uses GCC but is not build with GCC Compiler Plugin. GCC plug-in support is:\n{}".format(gcc_plugin))
20+
raise RuntimeError("Score-P uses GCC but is not build with GCC Compiler Plugin. "
21+
"GCC plug-in support is:\n{}".format(gcc_plugin))
2122

2223

2324
cmodules = []
24-
(include, _, _, _, _) = scorep.helper.generate_compile_deps()
25+
(include, _, _, _, _) = scorep.helper.generate_compile_deps([])
2526
src_folder = os.path.abspath('src')
2627
include += [src_folder]
2728
sources = ['src/methods.cpp', 'src/scorep_bindings.cpp', 'src/scorepy/events.cpp']
28-
if sys.version_info.major >= 3:
29+
define_macros = [('PY_SSIZE_T_CLEAN', '1')]
30+
# We are using the UTF-8 string features from Python 3
31+
# The C Instrumenter functions are not available on PyPy
32+
if has_c_instrumenter():
2933
sources.extend([
3034
'src/classes.cpp',
3135
'src/scorepy/cInstrumenter.cpp',
3236
'src/scorepy/pythonHelpers.cpp',
3337
'src/scorepy/pathUtils.cpp',
3438
])
39+
define_macros.append(('SCOREPY_ENABLE_CINSTRUMENTER', '1'))
40+
else:
41+
define_macros.append(('SCOREPY_ENABLE_CINSTRUMENTER', '0'))
3542

3643
cmodules.append(Extension('scorep._bindings',
3744
include_dirs=include,
38-
define_macros=[('PY_SSIZE_T_CLEAN', '1')],
45+
define_macros=define_macros,
3946
extra_compile_args=["-std=c++11"],
4047
sources=sources))
4148

4249
setup(
4350
name='scorep',
4451
version=scorep._version.__version__,
45-
description='This is a scorep tracing package for python',
52+
description='This is a Score-P tracing package for python',
4653
author='Andreas Gocht',
4754
author_email='andreas.gocht@tu-dresden.de',
4855
url='https://github.com/score-p/scorep_binding_python',
@@ -70,6 +77,7 @@
7077
'Programming Language :: Python :: 3.8',
7178
'Programming Language :: Python :: 3.9',
7279
'Programming Language :: Python :: Implementation :: CPython',
80+
'Programming Language :: Python :: Implementation :: PyPy',
7381
'Operating System :: POSIX',
7482
'Operating System :: Unix',
7583
],

src/scorep_bindings.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ PyMODINIT_FUNC init_bindings(void)
77
{
88
(void)Py_InitModule("_bindings", scorepy::getMethodTable());
99
}
10-
#else /*python 3*/
10+
#else /*python 3*/
1111
static struct PyModuleDef scorepmodule = { PyModuleDef_HEAD_INIT, "_bindings", /* name of module */
1212
NULL, /* module documentation, may be NULL */
1313
-1, /* size of per-interpreter state of the module,
@@ -16,23 +16,27 @@ static struct PyModuleDef scorepmodule = { PyModuleDef_HEAD_INIT, "_bindings", /
1616
scorepy::getMethodTable() };
1717
PyMODINIT_FUNC PyInit__bindings(void)
1818
{
19+
#if SCOREPY_ENABLE_CINSTRUMENTER
1920
auto* ctracerType = &scorepy::getCInstrumenterType();
2021
if (PyType_Ready(ctracerType) < 0)
2122
return nullptr;
23+
#endif
2224

2325
auto* m = PyModule_Create(&scorepmodule);
2426
if (!m)
2527
{
2628
return nullptr;
2729
}
2830

31+
#if SCOREPY_ENABLE_CINSTRUMENTER
2932
Py_INCREF(ctracerType);
3033
if (PyModule_AddObject(m, "CInstrumenter", (PyObject*)ctracerType) < 0)
3134
{
3235
Py_DECREF(ctracerType);
3336
Py_DECREF(m);
3437
return nullptr;
3538
}
39+
#endif
3640

3741
return m;
3842
}
File renamed without changes.

0 commit comments

Comments
 (0)