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

llnl / dftracer-utils / 28356348514

29 Jun 2026 07:40AM UTC coverage: 52.174% (-0.1%) from 52.278%
28356348514

Pull #83

github

web-flow
Merge 278203630 into 2efed6649
Pull Request #83: refactor and improve code QoL

37276 of 92891 branches covered (40.13%)

Branch coverage included in aggregate %.

671 of 1173 new or added lines in 58 files covered. (57.2%)

66 existing lines in 30 files now uncovered.

33619 of 42991 relevant lines covered (78.2%)

20387.45 hits per line

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

62.19
/src/dftracer/utils/python/utilities/statistics_aggregator.cpp
1
#define PY_SSIZE_T_CLEAN
2
#include <dftracer/utils/core/coro/task.h>
3
#include <dftracer/utils/core/runtime.h>
4
#include <dftracer/utils/python/py_dict_helpers.h>
5
#include <dftracer/utils/python/py_runtime_mixin.h>
6
#include <dftracer/utils/python/py_type_helpers.h>
7
#include <dftracer/utils/python/runtime.h>
8
#include <dftracer/utils/python/utilities/statistics_aggregator.h>
9
#include <dftracer/utils/utilities/composites/dft/internal/utils.h>
10
#include <dftracer/utils/utilities/composites/dft/statistics/statistics_aggregator_utility.h>
11
#include <dftracer/utils/utilities/composites/dft/statistics/trace_statistics.h>
12

13
#include <string>
14

15
using dftracer::utils::Runtime;
16
using dftracer::utils::coro::CoroTask;
17
using namespace dftracer::utils::utilities::composites::dft::statistics;
18

19
static Runtime *get_runtime(StatisticsAggregatorObject *self) {
14✔
20
    return resolve_runtime(self);
14✔
21
}
22

23
static void StatisticsAggregator_dealloc(StatisticsAggregatorObject *self) {
14✔
24
    runtime_backed_dealloc(self);
14✔
25
}
14✔
26

27
static PyObject *StatisticsAggregator_new(PyTypeObject *type, PyObject *args,
14✔
28
                                          PyObject *kwds) {
29
    return runtime_backed_new<StatisticsAggregatorObject>(type, args, kwds);
14✔
30
}
31

32
static int StatisticsAggregator_init(StatisticsAggregatorObject *self,
14✔
33
                                     PyObject *args, PyObject *kwds) {
34
    return runtime_backed_init(self, args, kwds);
14✔
35
}
36

37
static PyObject *StatisticsAggregator_compute(StatisticsAggregatorObject *self,
14✔
38
                                              PyObject *args, PyObject *kwds) {
39
    static const char *kwlist[] = {"file_path", "index_dir", NULL};
40
    const char *file_path;
41
    const char *index_dir = "";
14✔
42
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s", (char **)kwlist,
14!
43
                                     &file_path, &index_dir))
44
        return NULL;
×
45

46
    std::string file_path_str(file_path);
14!
47
    std::string index_dir_str(index_dir);
14!
48
    TraceStatistics stats;
14!
49

50
    if (!run_blocking([&] {
21!
51
            Runtime *rt = get_runtime(self);
14!
52

53
            StatisticsAggregatorInput input;
14✔
54
            input.file_path = file_path_str;
14!
55
            input.index_dir = index_dir_str;
14!
56
            input.index_path = dftracer::utils::utilities::composites::dft::
7!
57
                internal::determine_index_path(file_path_str, index_dir_str);
14!
58

59
            auto *stats_p = &stats;
14✔
60
            auto input_copy = input;
14!
61
            auto task = [stats_p, input_copy]() -> CoroTask<void> {
63!
62
                StatisticsAggregatorUtility util;
21!
63
                *stats_p = co_await util.process(input_copy);
28!
64
            };
42!
65
            rt->submit(task(), "stats-aggregator").get();
14!
66
        })) {
14✔
UNCOV
67
        return NULL;
×
68
    }
69

70
    PyObject *d = PyDict_New();
14!
71
    if (!d) return NULL;
14✔
72

73
    int rc = 0;
14✔
74
    rc |= dict_set_str(d, "file_path", stats.file_path.c_str());
14!
75
    rc |= dict_set_u64(d, "total_events", stats.total_events());
14!
76
    rc |= dict_set_u64(d, "num_chunks", stats.num_chunks);
14!
77
    rc |= dict_set_bool(d, "success", stats.success);
14!
78
    rc |= dict_set_str(d, "error_message", stats.error_message.c_str());
14!
79
    rc |= dict_set_f64(d, "time_span_seconds", stats.time_span_seconds());
14!
80
    rc |= dict_set_f64(d, "duration_mean_us", stats.duration_mean_us());
14!
81
    rc |= dict_set_f64(d, "duration_stddev_us", stats.duration_stddev_us());
14!
82
    rc |= dict_set_size(d, "num_categories", stats.num_categories());
14!
83
    rc |= dict_set_size(d, "num_unique_names", stats.num_unique_names());
14!
84
    rc |= dict_set_size(d, "num_pid_tids", stats.num_pid_tids());
14!
85
    rc |= dict_set_u64(d, "min_timestamp_us", stats.merged.min_timestamp_us);
14!
86
    rc |= dict_set_u64(d, "max_timestamp_us", stats.merged.max_timestamp_us);
14!
87

88
    if (rc != 0) {
14!
89
        Py_DECREF(d);
×
NEW
90
        return NULL;
×
91
    }
92

93
    return d;
14✔
94
}
14✔
95

96
static PyObject *StatisticsAggregator_call(PyObject *self, PyObject *args,
2✔
97
                                           PyObject *kwds) {
98
    return StatisticsAggregator_compute((StatisticsAggregatorObject *)self,
3✔
99
                                        args, kwds);
2✔
100
}
101

102
static PyMethodDef StatisticsAggregator_methods[] = {
103
    {"process", (PyCFunction)StatisticsAggregator_compute,
104
     METH_VARARGS | METH_KEYWORDS,
105
     "process(file_path, index_dir='')\n"
106
     "--\n"
107
     "\n"
108
     "Compute aggregated statistics from a trace file.\n"
109
     "\n"
110
     "Args:\n"
111
     "    file_path (str): Path to the trace file.\n"
112
     "    index_dir (str): Directory for .dftindex stores (default '').\n"
113
     "\n"
114
     "Returns:\n"
115
     "    dict: Aggregated statistics.\n"},
116
    {NULL}};
117

118
PyTypeObject StatisticsAggregatorType = {
119
    PyVarObject_HEAD_INIT(
120
        NULL, 0) "dftracer_utils_ext.StatisticsAggregatorUtility", /* tp_name */
121
    sizeof(StatisticsAggregatorObject),       /* tp_basicsize */
122
    0,                                        /* tp_itemsize */
123
    (destructor)StatisticsAggregator_dealloc, /* tp_dealloc */
124
    0,                                        /* tp_vectorcall_offset */
125
    0,                                        /* tp_getattr */
126
    0,                                        /* tp_setattr */
127
    0,                                        /* tp_as_async */
128
    0,                                        /* tp_repr */
129
    0,                                        /* tp_as_number */
130
    0,                                        /* tp_as_sequence */
131
    0,                                        /* tp_as_mapping */
132
    0,                                        /* tp_hash */
133
    StatisticsAggregator_call,                /* tp_call */
134
    0,                                        /* tp_str */
135
    0,                                        /* tp_getattro */
136
    0,                                        /* tp_setattro */
137
    0,                                        /* tp_as_buffer */
138
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
139
    "StatisticsAggregatorUtility(runtime: Runtime | None = None)\n"
140
    "--\n\n"
141
    "Aggregate statistics from an indexed trace file.\n\n"
142
    "Args:\n"
143
    "    runtime (Runtime or None): Runtime for thread pool control.\n",
144
    0,                                   /* tp_traverse */
145
    0,                                   /* tp_clear */
146
    0,                                   /* tp_richcompare */
147
    0,                                   /* tp_weaklistoffset */
148
    0,                                   /* tp_iter */
149
    0,                                   /* tp_iternext */
150
    StatisticsAggregator_methods,        /* tp_methods */
151
    0,                                   /* tp_members */
152
    0,                                   /* tp_getset */
153
    0,                                   /* tp_base */
154
    0,                                   /* tp_dict */
155
    0,                                   /* tp_descr_get */
156
    0,                                   /* tp_descr_set */
157
    0,                                   /* tp_dictoffset */
158
    (initproc)StatisticsAggregator_init, /* tp_init */
159
    0,                                   /* tp_alloc */
160
    StatisticsAggregator_new,            /* tp_new */
161
};
162

163
int init_statistics_aggregator(PyObject *m) {
2✔
164
    if (register_type(m, &StatisticsAggregatorType,
2✔
165
                      "StatisticsAggregatorUtility") < 0)
2✔
UNCOV
166
        return -1;
×
167

168
    return 0;
2✔
169
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc