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

llnl / dftracer-utils / 27739884676

18 Jun 2026 05:57AM UTC coverage: 52.155% (+0.04%) from 52.111%
27739884676

Pull #79

github

web-flow
Merge 93a88987f into 53ad1e86c
Pull Request #79: Add Valgrind memory checking (C++, Python, MPI) and fix the bugs it found

37169 of 92677 branches covered (40.11%)

Branch coverage included in aggregate %.

129 of 144 new or added lines in 11 files covered. (89.58%)

7 existing lines in 3 files now uncovered.

33450 of 42726 relevant lines covered (78.29%)

20413.17 hits per line

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

62.64
/src/dftracer/utils/python/memoryview_batch.cpp
1
#define PY_SSIZE_T_CLEAN
2
#include <dftracer/utils/python/memoryview_batch.h>
3

4
#include <cstring>
5

6
namespace dftracer::utils::python {
7

8
static void MemoryViewBatch_dealloc(MemoryViewBatchObject *self) {
504✔
9
    delete self->data;
504✔
10
    Py_TYPE(self)->tp_free((PyObject *)self);
504✔
11
}
504✔
12

13
static int MemoryViewBatch_getbuffer(MemoryViewBatchObject *self,
2,302✔
14
                                     Py_buffer *view, int flags) {
15
    if (!self->data || self->data->buffer.empty()) {
2,302!
16
        PyErr_SetString(PyExc_BufferError, "MemoryViewBatch has no data");
×
17
        return -1;
×
18
    }
19
    return PyBuffer_FillInfo(view, (PyObject *)self, self->data->buffer.data(),
3,453✔
20
                             static_cast<Py_ssize_t>(self->data->buffer.size()),
2,302✔
21
                             1, flags);
2,302✔
22
}
1,151✔
23

24
static Py_ssize_t MemoryViewBatch_length(MemoryViewBatchObject *self) {
×
25
    if (!self->data) return 0;
×
26
    return static_cast<Py_ssize_t>(self->data->num_entries());
×
27
}
28

29
PyObject *MemoryViewBatch_item(MemoryViewBatchObject *self, Py_ssize_t i) {
2,302✔
30
    if (!self->data) {
2,302✔
31
        PyErr_SetString(PyExc_IndexError, "MemoryViewBatch has no data");
×
32
        return NULL;
×
33
    }
34
    Py_ssize_t n = static_cast<Py_ssize_t>(self->data->num_entries());
2,302✔
35
    if (i < 0 || i >= n) {
2,302!
36
        PyErr_SetString(PyExc_IndexError, "MemoryViewBatch index out of range");
×
37
        return NULL;
×
38
    }
39

40
    PyObject *full = PyMemoryView_FromObject((PyObject *)self);
2,302✔
41
    if (!full) return NULL;
2,302✔
42

43
    Py_ssize_t start = static_cast<Py_ssize_t>(self->data->offsets[i]);
2,302✔
44
    Py_ssize_t stop = start + static_cast<Py_ssize_t>(self->data->lengths[i]);
2,302✔
45
    PyObject *lo = PyLong_FromSsize_t(start);
2,302✔
46
    PyObject *hi = PyLong_FromSsize_t(stop);
2,302✔
47
    PyObject *slice = (lo && hi) ? PySlice_New(lo, hi, NULL) : NULL;
2,302!
48
    Py_XDECREF(lo);
2,302✔
49
    Py_XDECREF(hi);
2,302✔
50
    if (!slice) {
2,302✔
51
        Py_DECREF(full);
NEW
52
        return NULL;
×
53
    }
54
    PyObject *entry = PyObject_GetItem(full, slice);  // sub-view, shares buffer
2,302✔
55
    Py_DECREF(slice);
1,151✔
56
    Py_DECREF(full);
1,151✔
57
    return entry;
2,302✔
58
}
1,151✔
59

60
static PyBufferProcs MemoryViewBatch_as_buffer = {
61
    (getbufferproc)MemoryViewBatch_getbuffer,
62
    NULL,
63
};
64

65
static PySequenceMethods MemoryViewBatch_as_sequence = {
66
    (lenfunc)MemoryViewBatch_length,
67
    NULL,
68
    NULL,
69
    (ssizeargfunc)MemoryViewBatch_item,
70
};
71

72
static PyObject *MemoryViewBatch_get_num_entries(MemoryViewBatchObject *self,
×
73
                                                 void *) {
74
    if (!self->data) return PyLong_FromLong(0);
×
75
    return PyLong_FromSsize_t(
×
76
        static_cast<Py_ssize_t>(self->data->num_entries()));
×
77
}
78

79
static PyObject *MemoryViewBatch_get_num_bytes(MemoryViewBatchObject *self,
×
80
                                               void *) {
81
    if (!self->data) return PyLong_FromLong(0);
×
82
    return PyLong_FromSsize_t(
×
83
        static_cast<Py_ssize_t>(self->data->buffer.size()));
×
84
}
85

86
static PyGetSetDef MemoryViewBatch_getsetters[] = {
87
    {"num_entries", (getter)MemoryViewBatch_get_num_entries, NULL,
88
     "Number of entries", NULL},
89
    {"num_bytes", (getter)MemoryViewBatch_get_num_bytes, NULL,
90
     "Total buffer size in bytes", NULL},
91
    {NULL}};
92

93
PyTypeObject MemoryViewBatchType = {
94
    .ob_base = PyVarObject_HEAD_INIT(NULL, 0).tp_name =
95
        "dftracer_utils_ext._MemoryViewBatch",
96
    .tp_basicsize = sizeof(MemoryViewBatchObject),
97
    .tp_itemsize = 0,
98
    .tp_dealloc = (destructor)MemoryViewBatch_dealloc,
99
    .tp_as_sequence = &MemoryViewBatch_as_sequence,
100
    .tp_as_buffer = &MemoryViewBatch_as_buffer,
101
    .tp_flags = Py_TPFLAGS_DEFAULT,
102
    .tp_doc = "Zero-copy batch of byte entries backed by a contiguous buffer",
103
    .tp_getset = MemoryViewBatch_getsetters,
104
};
105

106
int init_memoryview_batch(PyObject *m) {
2✔
107
    if (PyType_Ready(&MemoryViewBatchType) < 0) return -1;
2✔
108
    Py_INCREF(&MemoryViewBatchType);
1✔
109
    if (PyModule_AddObject(m, "_MemoryViewBatch",
3!
110
                           (PyObject *)&MemoryViewBatchType) < 0) {
2!
111
        Py_DECREF(&MemoryViewBatchType);
112
        return -1;
×
113
    }
114
    return 0;
2✔
115
}
1✔
116

117
}  // namespace dftracer::utils::python
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