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

paulmthompson / WhiskerToolbox / 18389801194

09 Oct 2025 09:35PM UTC coverage: 71.943% (+0.1%) from 71.826%
18389801194

push

github

paulmthompson
add correlation matrix to filtering interface

207 of 337 new or added lines in 5 files covered. (61.42%)

867 existing lines in 31 files now uncovered.

49964 of 69449 relevant lines covered (71.94%)

1103.53 hits per line

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

0.0
/src/DataManager/Tensors/Tensor_Data_LibTorch.cpp
1
#include "Tensor_Data.hpp"
2
#include "Tensor_Data_Impl.hpp"
3
#include <algorithm>
4

5
#ifdef TENSOR_BACKEND_LIBTORCH
6
#include <torch/torch.h>
7

8
// ========== TensorData PIMPL Implementation ==========
9

10
// ========== Constructors ==========
11

UNCOV
12
TensorData::TensorData() : _pimpl(std::make_unique<TensorDataImpl>()) {}
×
13

UNCOV
14
TensorData::~TensorData() = default;
×
15

UNCOV
16
TensorData::TensorData(const TensorData& other) 
×
17
    : ObserverData(other)
UNCOV
18
    , _pimpl(std::make_unique<TensorDataImpl>(*other._pimpl))
×
UNCOV
19
    , _time_frame(other._time_frame) {}
×
20

UNCOV
21
TensorData::TensorData(TensorData&& other) noexcept 
×
22
    : ObserverData(std::move(other))
×
23
    , _pimpl(std::move(other._pimpl))
×
24
    , _time_frame(std::move(other._time_frame)) {}
×
25

UNCOV
26
TensorData& TensorData::operator=(const TensorData& other) {
×
27
    if (this != &other) {
×
28
        _pimpl = std::make_unique<TensorDataImpl>(*other._pimpl);
×
29
        _time_frame = other._time_frame;
×
30
    }
UNCOV
31
    return *this;
×
32
}
33

34
TensorData& TensorData::operator=(TensorData&& other) noexcept {
×
35
    if (this != &other) {
×
36
        _pimpl = std::move(other._pimpl);
×
37
        _time_frame = std::move(other._time_frame);
×
38
    }
UNCOV
39
    return *this;
×
40
}
41

42
#ifdef TENSOR_BACKEND_LIBTORCH
43
template<typename T>
44
TensorData::TensorData(std::map<TimeFrameIndex, void*> data, std::vector<T> shape) {
×
45
    // Convert void* back to torch::Tensor for internal storage
UNCOV
46
    std::map<TimeFrameIndex, torch::Tensor> tensor_data;
×
UNCOV
47
    for (const auto& [time, tensor_ptr] : data) {
×
48
        tensor_data[time] = *static_cast<torch::Tensor*>(tensor_ptr);
×
49
    }
50
    _pimpl = std::make_unique<TensorDataImpl>(std::move(tensor_data), shape);
×
UNCOV
51
}
×
52

53
// Explicit instantiation for common types
54
template TensorData::TensorData(std::map<TimeFrameIndex, void*>, std::vector<int>);
55
template TensorData::TensorData(std::map<TimeFrameIndex, void*>, std::vector<std::size_t>);
56
template TensorData::TensorData(std::map<TimeFrameIndex, void*>, std::vector<long>);
57
#endif
58

59
// ========== Setters ==========
60

61
#ifdef TENSOR_BACKEND_LIBTORCH
62
void TensorData::addTensorAtTime(TimeFrameIndex time, void* tensor) {
×
63
    _pimpl->addTensorAtTime(time, *static_cast<torch::Tensor*>(tensor));
×
UNCOV
64
    notifyObservers();
×
65
}
×
66

UNCOV
67
void TensorData::overwriteTensorAtTime(TimeFrameIndex time, void* tensor) {
×
68
    _pimpl->overwriteTensorAtTime(time, *static_cast<torch::Tensor*>(tensor));
×
69
    notifyObservers();
×
70
}
×
71
#endif
72

73
void TensorData::addTensorAtTime(TimeFrameIndex time, const std::vector<float>& data, const std::vector<std::size_t>& shape) {
×
UNCOV
74
    _pimpl->addTensorAtTime(time, data, shape);
×
75
    notifyObservers();
×
76
}
×
77

UNCOV
78
void TensorData::overwriteTensorAtTime(TimeFrameIndex time, const std::vector<float>& data, const std::vector<std::size_t>& shape) {
×
UNCOV
79
    _pimpl->overwriteTensorAtTime(time, data, shape);
×
80
    notifyObservers();
×
81
}
×
82

83
// ========== Getters ==========
84

85
#ifdef TENSOR_BACKEND_LIBTORCH
86
void* TensorData::getTensorAtTime(TimeFrameIndex time) const {
×
87
    auto tensor = _pimpl->getTensorAtTime(time);
×
UNCOV
88
    if (!tensor.defined()) {
×
89
        return nullptr;
×
90
    }
91
    // Return a pointer to the tensor (caller must manage lifetime)
92
    return new torch::Tensor(tensor);
×
93
}
×
94

UNCOV
95
std::map<TimeFrameIndex, void*> TensorData::getData() const {
×
96
    std::map<TimeFrameIndex, void*> result;
×
97
    auto times = _pimpl->getTimesWithTensors();
×
98
    for (const auto& time : times) {
×
UNCOV
99
        auto tensor = _pimpl->getTensorAtTime(time);
×
100
        if (tensor.defined()) {
×
UNCOV
101
            result[time] = new torch::Tensor(tensor);
×
102
        }
103
    }
×
UNCOV
104
    return result;
×
105
}
×
106
#endif
107

108
std::vector<float> TensorData::getTensorDataAtTime(TimeFrameIndex time) const {
×
109
    return _pimpl->getTensorDataAtTime(time);
×
110
}
111

112
std::vector<std::size_t> TensorData::getTensorShapeAtTime(TimeFrameIndex time) const {
×
UNCOV
113
    return _pimpl->getTensorShapeAtTime(time);
×
114
}
115

116
std::vector<TimeFrameIndex> TensorData::getTimesWithTensors() const {
×
UNCOV
117
    return _pimpl->getTimesWithTensors();
×
118
}
119

120
std::vector<float> TensorData::getChannelSlice(TimeFrameIndex time, int channel) const {
×
121
    return _pimpl->getChannelSlice(time, channel);
×
122
}
123

UNCOV
124
std::size_t TensorData::size() const {
×
125
    return _pimpl->size();
×
126
}
127

128
std::vector<std::size_t> TensorData::getFeatureShape() const {
×
129
    return _pimpl->getFeatureShape();
×
130
}
131

UNCOV
132
void TensorData::setFeatureShape(const std::vector<std::size_t>& shape) {
×
UNCOV
133
    _pimpl->setFeatureShape(shape);
×
134
}
×
135

136
// ========== TensorDataImpl Implementation ==========
137

138
// ========== Constructors ==========
139

140
TensorDataImpl::TensorDataImpl(const TensorDataImpl& other) = default;
×
141

UNCOV
142
TensorDataImpl::TensorDataImpl(TensorDataImpl&& other) noexcept = default;
×
143

144
TensorDataImpl& TensorDataImpl::operator=(const TensorDataImpl& other) = default;
×
145

UNCOV
146
TensorDataImpl& TensorDataImpl::operator=(TensorDataImpl&& other) noexcept = default;
×
147

148
// ========== Template Constructor Implementation ==========
149
template<typename T>
UNCOV
150
TensorDataImpl::TensorDataImpl(std::map<TimeFrameIndex, torch::Tensor> data, std::vector<T> shape)
×
151
    : _data(std::move(data)) {
×
152
    for (auto s : shape) {
×
153
        _feature_shape.push_back(static_cast<std::size_t>(s));
×
154
    }
UNCOV
155
}
×
156

157
// Explicit instantiation for common types
158
template TensorDataImpl::TensorDataImpl(std::map<TimeFrameIndex, torch::Tensor>, std::vector<int>);
159
template TensorDataImpl::TensorDataImpl(std::map<TimeFrameIndex, torch::Tensor>, std::vector<std::size_t>);
160
template TensorDataImpl::TensorDataImpl(std::map<TimeFrameIndex, torch::Tensor>, std::vector<long>);
161

162
// ========== LibTorch-specific Setters ==========
163

UNCOV
164
void TensorDataImpl::addTensorAtTime(TimeFrameIndex time, torch::Tensor const & tensor) {
×
UNCOV
165
    _data[time] = tensor;
×
UNCOV
166
}
×
167

UNCOV
168
void TensorDataImpl::overwriteTensorAtTime(TimeFrameIndex time, torch::Tensor const & tensor) {
×
UNCOV
169
    _data[time] = tensor;
×
UNCOV
170
}
×
171

172
// ========== Generic Setters ==========
173

UNCOV
174
void TensorDataImpl::addTensorAtTime(TimeFrameIndex time, const std::vector<float>& data, const std::vector<std::size_t>& shape) {
×
UNCOV
175
    torch::Tensor tensor = vectorToTensor(data, shape);
×
UNCOV
176
    _data[time] = tensor;
×
UNCOV
177
}
×
178

UNCOV
179
void TensorDataImpl::overwriteTensorAtTime(TimeFrameIndex time, const std::vector<float>& data, const std::vector<std::size_t>& shape) {
×
UNCOV
180
    torch::Tensor tensor = vectorToTensor(data, shape);
×
UNCOV
181
    _data[time] = tensor;
×
UNCOV
182
}
×
183

184
// ========== LibTorch-specific Getters ==========
185

UNCOV
186
torch::Tensor TensorDataImpl::getTensorAtTime(TimeFrameIndex time) const {
×
UNCOV
187
    if (_data.find(time) != _data.end()) {
×
UNCOV
188
        return _data.at(time);
×
189
    }
UNCOV
190
    return torch::Tensor{};
×
191
}
192

UNCOV
193
std::map<TimeFrameIndex, torch::Tensor> const & TensorDataImpl::getData() const {
×
UNCOV
194
    return _data;
×
195
}
196

197
// ========== Generic Getters ==========
198

UNCOV
199
std::vector<float> TensorDataImpl::getTensorDataAtTime(TimeFrameIndex time) const {
×
UNCOV
200
    if (_data.find(time) != _data.end()) {
×
UNCOV
201
        return tensorToVector(_data.at(time));
×
202
    }
UNCOV
203
    return {};
×
204
}
205

UNCOV
206
std::vector<std::size_t> TensorDataImpl::getTensorShapeAtTime(TimeFrameIndex time) const {
×
UNCOV
207
    if (_data.find(time) != _data.end()) {
×
UNCOV
208
        const auto& tensor = _data.at(time);
×
UNCOV
209
        std::vector<std::size_t> shape;
×
UNCOV
210
        for (int i = 0; i < tensor.dim(); ++i) {
×
UNCOV
211
            shape.push_back(static_cast<std::size_t>(tensor.size(i)));
×
212
        }
UNCOV
213
        return shape;
×
UNCOV
214
    }
×
UNCOV
215
    return {};
×
216
}
217

UNCOV
218
std::vector<TimeFrameIndex> TensorDataImpl::getTimesWithTensors() const {
×
UNCOV
219
    std::vector<TimeFrameIndex> times;
×
UNCOV
220
    times.reserve(_data.size());
×
UNCOV
221
    for (const auto& [time, tensor] : _data) {
×
UNCOV
222
        times.push_back(time);
×
223
    }
UNCOV
224
    return times;
×
UNCOV
225
}
×
226

UNCOV
227
std::vector<float> TensorDataImpl::getChannelSlice(TimeFrameIndex time, int channel) const {
×
UNCOV
228
    torch::Tensor const tensor = getTensorAtTime(time);
×
229
    
UNCOV
230
    if (!tensor.defined() || tensor.numel() == 0) {
×
UNCOV
231
        return {};
×
232
    }
233

UNCOV
234
    auto sub_tensor = tensor.index({
×
UNCOV
235
        torch::indexing::Slice(),
×
UNCOV
236
        torch::indexing::Slice(),
×
237
        channel
UNCOV
238
    });
×
239

240
    // Apply sigmoid
UNCOV
241
    sub_tensor = torch::sigmoid(sub_tensor);
×
242

UNCOV
243
    std::vector<float> vec(sub_tensor.data_ptr<float>(), 
×
UNCOV
244
                          sub_tensor.data_ptr<float>() + sub_tensor.numel());
×
245

UNCOV
246
    return vec;
×
UNCOV
247
}
×
248

UNCOV
249
std::size_t TensorDataImpl::size() const {
×
UNCOV
250
    return _data.size();
×
251
}
252

UNCOV
253
std::vector<std::size_t> TensorDataImpl::getFeatureShape() const {
×
UNCOV
254
    return _feature_shape;
×
255
}
256

UNCOV
257
void TensorDataImpl::setFeatureShape(const std::vector<std::size_t>& shape) {
×
UNCOV
258
    _feature_shape = shape;
×
UNCOV
259
}
×
260

261
// ========== Private Helper Methods ==========
262

UNCOV
263
torch::Tensor TensorDataImpl::vectorToTensor(const std::vector<float>& data, const std::vector<std::size_t>& shape) const {
×
264
    // Convert shape to torch IntArrayRef
UNCOV
265
    std::vector<int64_t> torch_shape;
×
UNCOV
266
    torch_shape.reserve(shape.size());
×
UNCOV
267
    for (std::size_t dim : shape) {
×
UNCOV
268
        torch_shape.push_back(static_cast<int64_t>(dim));
×
269
    }
270
    
271
    // Create tensor from data
UNCOV
272
    torch::Tensor tensor = torch::from_blob(
×
UNCOV
273
        const_cast<float*>(data.data()), 
×
274
        torch_shape, 
275
        torch::kFloat32
UNCOV
276
    ).clone(); // Clone to ensure data ownership
×
277
    
UNCOV
278
    return tensor;
×
UNCOV
279
}
×
280

UNCOV
281
std::vector<float> TensorDataImpl::tensorToVector(const torch::Tensor& tensor) const {
×
UNCOV
282
    if (!tensor.defined() || tensor.numel() == 0) {
×
UNCOV
283
        return {};
×
284
    }
285
    
286
    // Ensure tensor is contiguous and on CPU
UNCOV
287
    torch::Tensor cpu_tensor = tensor.contiguous().to(torch::kCPU);
×
288
    
UNCOV
289
    std::vector<float> vec(cpu_tensor.data_ptr<float>(), 
×
UNCOV
290
                          cpu_tensor.data_ptr<float>() + cpu_tensor.numel());
×
UNCOV
291
    return vec;
×
UNCOV
292
}
×
293

294
#endif // TENSOR_BACKEND_LIBTORCH
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