• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

llnl / dftracer-utils / 30069185152

24 Jul 2026 05:20AM UTC coverage: 50.687% (-2.0%) from 52.66%
30069185152

Pull #99

github

web-flow
Merge 47af36077 into 06bc84ec9
Pull Request #99: Support CM time_metric (NS/MS/SEC/US) across reader and viz

18062 of 48203 branches covered (37.47%)

Branch coverage included in aggregate %.

1510 of 2205 new or added lines in 59 files covered. (68.48%)

742 existing lines in 114 files now uncovered.

23711 of 34210 relevant lines covered (69.31%)

39853.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

29.61
/src/dftracer/utils/python/py_runtime_mixin.h
1
#ifndef DFTRACER_UTILS_PYTHON_PY_RUNTIME_MIXIN_H
2
#define DFTRACER_UTILS_PYTHON_PY_RUNTIME_MIXIN_H
3

4
#include <Python.h>
5
#include <dftracer/utils/core/common/error.h>
6
#include <dftracer/utils/python/py_errors.h>
7
#include <dftracer/utils/python/runtime.h>
8

9
#include <exception>
10
#include <stdexcept>
11
#include <string>
12

13
// Shared implementation for utility objects whose layout is exactly:
14
//     typedef struct { PyObject_HEAD PyObject *runtime_obj; } XObject;
15
// Each binding kept re-rolling an identical runtime-resolution / tp_new /
16
// tp_dealloc / tp_init quartet; these templates single-source it.
17

18
// Resolve the backing Runtime: the explicitly-bound one, else the default.
19
template <typename T>
20
dftracer::utils::Runtime *resolve_runtime(T *self) {
54✔
21
    if (self->runtime_obj)
54!
22
        return ((RuntimeObject *)self->runtime_obj)->runtime.get();
×
23
    return get_default_runtime();
54✔
24
}
25

26
template <typename T>
27
PyObject *runtime_backed_new(PyTypeObject *type, PyObject *, PyObject *) {
54✔
28
    T *self = (T *)type->tp_alloc(type, 0);
54✔
29
    if (self) self->runtime_obj = NULL;
54!
30
    return (PyObject *)self;
54✔
31
}
32

33
template <typename T>
34
void runtime_backed_dealloc(T *self) {
54✔
35
    Py_XDECREF(self->runtime_obj);
54✔
36
    Py_TYPE(self)->tp_free((PyObject *)self);
54✔
37
}
54✔
38

39
// Parse an optional `runtime=` kwarg (a Runtime instance, an object exposing a
40
// `_native` Runtime, or None) and bind it into self->runtime_obj.
41
template <typename T>
42
int runtime_backed_init(T *self, PyObject *args, PyObject *kwds) {
54✔
43
    static const char *kwlist[] = {"runtime", NULL};
44
    PyObject *runtime_arg = NULL;
54✔
45
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", (char **)kwlist,
54!
46
                                     &runtime_arg)) {
47
        return -1;
×
48
    }
49
    if (runtime_arg && runtime_arg != Py_None) {
54!
50
        if (PyObject_TypeCheck(runtime_arg, &RuntimeType)) {
×
51
            Py_INCREF(runtime_arg);
×
52
            self->runtime_obj = runtime_arg;
×
53
        } else {
54
            PyObject *native = PyObject_GetAttrString(runtime_arg, "_native");
×
55
            if (native && PyObject_TypeCheck(native, &RuntimeType)) {
×
56
                self->runtime_obj = native;
×
57
            } else {
58
                Py_XDECREF(native);
×
59
                PyErr_SetString(PyExc_TypeError,
×
60
                                "runtime must be a Runtime instance or None");
61
                return -1;
×
62
            }
63
        }
64
    }
65
    return 0;
54✔
66
}
67

68
// Run a blocking C++ body with the GIL released
69
template <typename F>
70
bool run_blocking(F &&body) {
312✔
71
    bool failed = false;
312✔
72
    std::string error_msg;
312✔
73
    PyObject *exc_type = nullptr;  // pointer read only; no Python API off-GIL
312✔
74
    Py_BEGIN_ALLOW_THREADS try {
312!
75
        body();
312!
UNCOV
76
    } catch (const dftracer::utils::DFTUtilsException &e) {
×
77
        failed = true;
×
78
        error_msg = e.what();
×
79
        exc_type = py_error_type_for(e.code());
×
80
    } catch (const std::invalid_argument &e) {
×
81
        failed = true;
×
82
        error_msg = e.what();
×
83
        exc_type = g_dft_value_error;
×
84
    } catch (const std::exception &e) {
×
85
        failed = true;
×
86
        error_msg = e.what();
×
87
    } catch (...) {
×
88
        failed = true;
×
89
        error_msg = "unknown C++ exception";
×
90
    }
91
    Py_END_ALLOW_THREADS if (failed) {
312!
92
        if (exc_type == nullptr) exc_type = g_dft_error;
×
93
        PyErr_SetString(exc_type ? exc_type : PyExc_RuntimeError,
×
94
                        error_msg.c_str());
95
        return false;
×
96
    }
97
    return true;
312✔
98
}
312✔
99

100
// Like run_blocking, but for a body that produces a value. Runs `body` with
101
// the GIL released, assigning its result into `out`. On a thrown exception the
102
// exception is captured off-GIL, the GIL is re-acquired, the typed Python error
103
// is raised, and false is returned. `out` is only modified on success.
104
template <typename F, typename T>
105
bool run_blocking_r(F &&body, T &out) {
40✔
106
    std::exception_ptr eptr;
40✔
107
    Py_BEGIN_ALLOW_THREADS try { out = body(); } catch (...) {
40!
108
        eptr = std::current_exception();
×
109
    }
110
    Py_END_ALLOW_THREADS if (eptr) {
40!
111
        try {
112
            std::rethrow_exception(eptr);
×
113
        } catch (const std::exception &e) {
×
114
            set_typed_py_error(e);
×
115
        } catch (...) {
×
116
            PyErr_SetString(g_dft_error ? g_dft_error : PyExc_RuntimeError,
×
117
                            "unknown C++ exception");
118
        }
119
        return false;
×
120
    }
121
    return true;
40✔
122
}
40✔
123

124
// Generate the tp_dealloc / tp_new / tp_init shims for a utility object whose
125
// layout is `struct { PyObject_HEAD PyObject *runtime_obj; }`. PREFIX is the
126
// type's function-name prefix (e.g. Aggregator); OBJ is its object struct.
127
#define DFTRACER_UTILS_RUNTIME_BACKED_SLOTS(PREFIX, OBJ)                      \
128
    static void PREFIX##_dealloc(OBJ *self) { runtime_backed_dealloc(self); } \
129
    static PyObject *PREFIX##_new(PyTypeObject *type, PyObject *args,         \
130
                                  PyObject *kwds) {                           \
131
        return runtime_backed_new<OBJ>(type, args, kwds);                     \
132
    }                                                                         \
133
    static int PREFIX##_init(OBJ *self, PyObject *args, PyObject *kwds) {     \
134
        return runtime_backed_init(self, args, kwds);                         \
135
    }
136

137
#endif  // DFTRACER_UTILS_PYTHON_PY_RUNTIME_MIXIN_H
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc