Logo ROOT   6.16/01
Reference Guide
CpuBuffer.cxx
Go to the documentation of this file.
1// @(#)root/tmva/tmva/dnn:$Id$
2// Author: Simon Pfreundschuh 12/08/16
3
4/*************************************************************************
5 * Copyright (C) 2016, Simon Pfreundschuh *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/////////////////////////////////////////////////////////////
13// CPU Buffer interface class for the generic data loader. //
14/////////////////////////////////////////////////////////////
15
16#include <vector>
17#include <memory>
18#include "TMVA/DataSetInfo.h"
19#include "TMVA/DNN/DataLoader.h"
22#include "Rtypes.h"
23#include <iostream>
24
25namespace TMVA {
26namespace DNN {
27
28//______________________________________________________________________________
29template <typename AReal>
31{
32 delete[] * pointer;
33 delete[] pointer;
34}
35
36//______________________________________________________________________________
37template <typename AReal>
39{
40 AReal **pointer = new AReal *[1];
41 *pointer = new AReal[size];
42 fBuffer = std::shared_ptr<AReal *>(pointer, fDestructor);
43}
44
45//______________________________________________________________________________
46template <typename AReal>
48{
49 TCpuBuffer buffer = *this;
50 buffer.fOffset = offset;
51 buffer.fSize = size;
52 return buffer;
53}
54
55//______________________________________________________________________________
56template <typename AReal>
58{
59 std::swap(*this->fBuffer, *other.fBuffer);
60}
61
62//______________________________________________________________________________
63template <typename AReal>
65{
66 std::swap(*this->fBuffer, *other.fBuffer);
67}
68
69//______________________________________________________________________________
70template <>
72 size_t batchSize)
73{
74 const TMatrixT<Real_t> &inputMatrix = std::get<0>(fData);
75 size_t n = inputMatrix.GetNcols();
76
77 for (size_t i = 0; i < batchSize; i++) {
78 size_t sampleIndex = *sampleIterator;
79 for (size_t j = 0; j < n; j++) {
80 size_t bufferIndex = j * batchSize + i;
81 buffer[bufferIndex] = static_cast<Real_t>(inputMatrix(sampleIndex, j));
82 }
83 sampleIterator++;
84 }
85}
86
87//______________________________________________________________________________
88template <>
90 size_t batchSize)
91{
92 const TMatrixT<Real_t> &outputMatrix = std::get<1>(fData);
93 size_t n = outputMatrix.GetNcols();
94
95 for (size_t i = 0; i < batchSize; i++) {
96 size_t sampleIndex = *sampleIterator;
97 for (size_t j = 0; j < n; j++) {
98 size_t bufferIndex = j * batchSize + i;
99 buffer[bufferIndex] = static_cast<Real_t>(outputMatrix(sampleIndex, j));
100 }
101 sampleIterator++;
102 }
103}
104
105//______________________________________________________________________________
106template <>
108 size_t batchSize)
109{
110 const TMatrixT<Real_t> &outputMatrix = std::get<2>(fData);
111
112 for (size_t i = 0; i < batchSize; i++) {
113 size_t sampleIndex = *sampleIterator;
114 buffer[i] = static_cast<Real_t>(outputMatrix(sampleIndex, 0));
115 sampleIterator++;
116 }
117}
118
119//______________________________________________________________________________
120template <>
122 size_t batchSize)
123{
124 const TMatrixT<Double_t> &inputMatrix = std::get<0>(fData);
125 size_t n = inputMatrix.GetNcols();
126
127 for (size_t i = 0; i < batchSize; i++) {
128 size_t sampleIndex = *sampleIterator;
129 for (size_t j = 0; j < n; j++) {
130 size_t bufferIndex = j * batchSize + i;
131 buffer[bufferIndex] = inputMatrix(sampleIndex, j);
132 }
133 sampleIterator++;
134 }
135}
136
137//______________________________________________________________________________
138template <>
140 IndexIterator_t sampleIterator, size_t batchSize)
141{
142 const TMatrixT<Double_t> &outputMatrix = std::get<1>(fData);
143 size_t n = outputMatrix.GetNcols();
144
145 for (size_t i = 0; i < batchSize; i++) {
146 size_t sampleIndex = *sampleIterator;
147 for (size_t j = 0; j < n; j++) {
148 size_t bufferIndex = j * batchSize + i;
149 buffer[bufferIndex] = outputMatrix(sampleIndex, j);
150 }
151 sampleIterator++;
152 }
153}
154
155//______________________________________________________________________________
156template <>
158 IndexIterator_t sampleIterator, size_t batchSize)
159{
160 const TMatrixT<Double_t> &outputMatrix = std::get<2>(fData);
161
162 for (size_t i = 0; i < batchSize; i++) {
163 size_t sampleIndex = *sampleIterator;
164 buffer[i] = static_cast<Double_t>(outputMatrix(sampleIndex, 0));
165 sampleIterator++;
166 }
167}
168
169//______________________________________________________________________________
170template <>
172 size_t batchSize)
173{
174 Event *event = std::get<0>(fData)[0];
175 size_t n = event->GetNVariables();
176 for (size_t i = 0; i < batchSize; i++) {
177 size_t sampleIndex = * sampleIterator++;
178 event = std::get<0>(fData)[sampleIndex];
179 for (size_t j = 0; j < n; j++) {
180 size_t bufferIndex = j * batchSize + i;
181 buffer[bufferIndex] = event->GetValue(j);
182 }
183 }
184}
185
186//______________________________________________________________________________
187template <>
189 size_t batchSize)
190{
191 const DataSetInfo &info = std::get<1>(fData);
192 size_t n = buffer.GetSize() / batchSize;
193
194 // Copy target(s).
195
196 for (size_t i = 0; i < batchSize; i++) {
197 size_t sampleIndex = *sampleIterator++;
198 Event *event = std::get<0>(fData)[sampleIndex];
199 for (size_t j = 0; j < n; j++) {
200 // Copy output matrices.
201 size_t bufferIndex = j * batchSize + i;
202 // Classification
203 if (event->GetNTargets() == 0) {
204 if (n == 1) {
205 // Binary.
206 buffer[bufferIndex] = (info.IsSignal(event)) ? 1.0 : 0.0;
207 } else {
208 // Multiclass.
209 buffer[bufferIndex] = 0.0;
210 if (j == event->GetClass()) {
211 buffer[bufferIndex] = 1.0;
212 }
213 }
214 } else {
215 buffer[bufferIndex] = static_cast<Real_t>(event->GetTarget(j));
216 }
217 }
218 }
219}
220
221//______________________________________________________________________________
222template <>
224 size_t batchSize)
225{
226 for (size_t i = 0; i < batchSize; i++) {
227 size_t sampleIndex = *sampleIterator++;
228 Event *event = std::get<0>(fData)[sampleIndex];
229 buffer[i] = event->GetWeight();
230 }
231}
232
233//______________________________________________________________________________
234template <>
236 size_t batchSize)
237{
238 Event *event = std::get<0>(fData)[0];
239 size_t n = event->GetNVariables();
240 for (size_t i = 0; i < batchSize; i++) {
241 size_t sampleIndex = * sampleIterator++;
242 event = std::get<0>(fData)[sampleIndex];
243 for (size_t j = 0; j < n; j++) {
244 size_t bufferIndex = j * batchSize + i;
245 buffer[bufferIndex] = static_cast<Real_t>(event->GetValue(j));
246 }
247 }
248}
249
250//______________________________________________________________________________
251template <>
253 size_t batchSize)
254{
255 const DataSetInfo &info = std::get<1>(fData);
256 size_t n = buffer.GetSize() / batchSize;
257
258 // Copy target(s).
259
260 for (size_t i = 0; i < batchSize; i++) {
261 size_t sampleIndex = *sampleIterator++;
262 Event *event = std::get<0>(fData)[sampleIndex];
263 for (size_t j = 0; j < n; j++) {
264 // Copy output matrices.
265 size_t bufferIndex = j * batchSize + i;
266 // Classification
267 if (event->GetNTargets() == 0) {
268 if (n == 1) {
269 // Binary.
270 buffer[bufferIndex] = (info.IsSignal(event)) ? 1.0 : 0.0;
271 } else {
272 // Multiclass.
273 buffer[bufferIndex] = 0.0;
274 if (j == event->GetClass()) {
275 buffer[bufferIndex] = 1.0;
276 }
277 }
278 } else {
279 buffer[bufferIndex] = static_cast<Real_t>(event->GetTarget(j));
280 }
281 }
282 }
283}
284
285//______________________________________________________________________________
286template <>
288 size_t batchSize)
289{
290 for (size_t i = 0; i < batchSize; i++) {
291 size_t sampleIndex = *sampleIterator++;
292 Event *event = std::get<0>(fData)[sampleIndex];
293 buffer[i] = static_cast<Real_t>(event->GetWeight());
294 }
295}
296
297//______________________________________________________________________________
298template <>
300 IndexIterator_t sampleIterator)
301{
302 const std::vector<TMatrixT<Double_t>> &inputTensor = std::get<0>(fData);
303
304 if (fBatchDepth == 1) {
305 for (size_t i = 0; i < fBatchHeight; i++) {
306 size_t sampleIndex = *sampleIterator;
307 for (size_t j = 0; j < fBatchWidth; j++) {
308 size_t bufferIndex = j * fBatchHeight + i;
309 buffer[bufferIndex] = static_cast<Real_t>(inputTensor[0](sampleIndex, j));
310 }
311 sampleIterator++;
312 }
313 } else {
314 for (size_t i = 0; i < fBatchDepth; i++) {
315 size_t sampleIndex = *sampleIterator;
316 for (size_t j = 0; j < fBatchHeight; j++) {
317 for (size_t k = 0; k < fBatchWidth; k++) {
318 size_t bufferIndex = i * fBatchHeight * fBatchWidth + k * fBatchHeight + j;
319 buffer[bufferIndex] = static_cast<Real_t>(inputTensor[sampleIndex](j, k));
320 }
321 }
322 sampleIterator++;
323 }
324 }
325}
326
327//______________________________________________________________________________
328template <>
330 IndexIterator_t sampleIterator)
331{
332 const TMatrixT<Double_t> &outputMatrix = std::get<1>(fData);
333 size_t n = outputMatrix.GetNcols();
334
335 for (size_t i = 0; i < fBatchSize; i++) {
336 size_t sampleIndex = *sampleIterator;
337 for (size_t j = 0; j < n; j++) {
338 size_t bufferIndex = j * fBatchSize + i;
339 buffer[bufferIndex] = static_cast<Real_t>(outputMatrix(sampleIndex, j));
340 }
341 sampleIterator++;
342 }
343}
344
345//______________________________________________________________________________
346template <>
348 IndexIterator_t sampleIterator)
349{
350 const TMatrixT<Double_t> &outputMatrix = std::get<2>(fData);
351
352 for (size_t i = 0; i < fBatchSize; i++) {
353 size_t sampleIndex = *sampleIterator;
354 buffer[i] = static_cast<Real_t>(outputMatrix(sampleIndex, 0));
355 sampleIterator++;
356 }
357}
358
359//______________________________________________________________________________
360template <>
362 IndexIterator_t sampleIterator)
363{
364 const std::vector<TMatrixT<Double_t>> &inputTensor = std::get<0>(fData);
365
366 if (fBatchDepth == 1) {
367 for (size_t i = 0; i < fBatchHeight; i++) {
368 size_t sampleIndex = *sampleIterator;
369 for (size_t j = 0; j < fBatchWidth; j++) {
370 size_t bufferIndex = j * fBatchHeight + i;
371 buffer[bufferIndex] = inputTensor[0](sampleIndex, j);
372 }
373 sampleIterator++;
374 }
375 } else {
376 for (size_t i = 0; i < fBatchDepth; i++) {
377 size_t sampleIndex = *sampleIterator;
378 for (size_t j = 0; j < fBatchHeight; j++) {
379 for (size_t k = 0; k < fBatchWidth; k++) {
380 size_t bufferIndex = i * fBatchHeight * fBatchWidth + k * fBatchHeight + j;
381 buffer[bufferIndex] = inputTensor[sampleIndex](j, k);
382 }
383 }
384 sampleIterator++;
385 }
386 }
387}
388
389//______________________________________________________________________________
390template <>
392 IndexIterator_t sampleIterator)
393{
394 const TMatrixT<Double_t> &outputMatrix = std::get<1>(fData);
395 size_t n = outputMatrix.GetNcols();
396
397 for (size_t i = 0; i < fBatchSize; i++) {
398 size_t sampleIndex = *sampleIterator;
399 for (size_t j = 0; j < n; j++) {
400 size_t bufferIndex = j * fBatchSize + i;
401 buffer[bufferIndex] = outputMatrix(sampleIndex, j);
402 }
403 sampleIterator++;
404 }
405}
406
407//______________________________________________________________________________
408template <>
410 IndexIterator_t sampleIterator)
411{
412 const TMatrixT<Double_t> &outputMatrix = std::get<2>(fData);
413
414 for (size_t i = 0; i < fBatchSize; i++) {
415 size_t sampleIndex = *sampleIterator;
416 buffer[i] = static_cast<Double_t>(outputMatrix(sampleIndex, 0));
417 sampleIterator++;
418 }
419}
420
421///- re-implement specialization for Double_t
422//______________________________________________________________________________
423template <>
425 IndexIterator_t sampleIterator)
426{
427 // one event, one example in the batch
428
429 if (fBatchDepth == 1 && fBatchHeight == fBatchSize) {
430 for (size_t i = 0; i < fBatchHeight; i++) {
431 size_t sampleIndex = *sampleIterator;
432 Event * event = std::get<0>(fData)[sampleIndex];
433 for (size_t j = 0; j < fBatchWidth; j++) {
434 size_t bufferIndex = j * fBatchHeight + i;
435 buffer[bufferIndex] = event->GetValue(j);
436 }
437 sampleIterator++;
438 }
439 } else if (fBatchDepth == fBatchSize) {
440 // batchDepth is batch size
441 for (size_t i = 0; i < fBatchDepth; i++) {
442 size_t sampleIndex = *sampleIterator;
443 Event * event = std::get<0>(fData)[sampleIndex];
444 for (size_t j = 0; j < fBatchHeight; j++) {
445 for (size_t k = 0; k < fBatchWidth; k++) {
446 // because of the column-major ordering
447 size_t bufferIndex = i * fBatchHeight * fBatchWidth + k * fBatchHeight + j;
448 buffer[bufferIndex] = event->GetValue(j * fBatchWidth + k);
449 }
450 }
451 sampleIterator++;
452 }
453 }
454 else {
455 Error("TTensorDataLoader","Inconsistency between batch depth and batch size");
456 R__ASSERT(0); // one event, one example in the batch
457 }
458}
459
460//______________________________________________________________________________
461template <>
463 IndexIterator_t sampleIterator)
464{
465 const DataSetInfo &info = std::get<1>(fData);
466 size_t n = buffer.GetSize() / fBatchSize;
467
468 // Copy target(s).
469
470 for (size_t i = 0; i < fBatchSize; i++) {
471 size_t sampleIndex = *sampleIterator++;
472 Event *event = std::get<0>(fData)[sampleIndex];
473 for (size_t j = 0; j < n; j++) {
474 // Copy output matrices.
475 size_t bufferIndex = j * fBatchSize + i;
476 // Classification
477 if (event->GetNTargets() == 0) {
478 if (n == 1) {
479 // Binary.
480 buffer[bufferIndex] = (info.IsSignal(event)) ? 1.0 : 0.0;
481 } else {
482 // Multiclass.
483 buffer[bufferIndex] = 0.0;
484 if (j == event->GetClass()) {
485 buffer[bufferIndex] = 1.0;
486 }
487 }
488 } else {
489 buffer[bufferIndex] = static_cast<Real_t>(event->GetTarget(j));
490 }
491 }
492 }
493}
494
495//______________________________________________________________________________
496template <>
498 IndexIterator_t sampleIterator)
499{
500 for (size_t i = 0; i < fBatchSize; i++) {
501 size_t sampleIndex = *sampleIterator++;
502 Event *event = std::get<0>(fData)[sampleIndex];
503 buffer[i] = event->GetWeight();
504 }
505}
506
507///- re-implement specialization for Real_t
508//______________________________________________________________________________
509template <>
511 IndexIterator_t sampleIterator)
512{
513 // one event, one example in the batch
514
515 if (fBatchDepth == 1 && fBatchHeight == fBatchSize) {
516 for (size_t i = 0; i < fBatchHeight; i++) {
517 size_t sampleIndex = *sampleIterator;
518 Event * event = std::get<0>(fData)[sampleIndex];
519 for (size_t j = 0; j < fBatchWidth; j++) {
520 size_t bufferIndex = j * fBatchHeight + i;
521 buffer[bufferIndex] = event->GetValue(j);
522 }
523 sampleIterator++;
524 }
525 } else if (fBatchDepth == fBatchSize) {
526 // batchDepth is batch size
527 for (size_t i = 0; i < fBatchDepth; i++) {
528 size_t sampleIndex = *sampleIterator;
529 Event * event = std::get<0>(fData)[sampleIndex];
530 for (size_t j = 0; j < fBatchHeight; j++) {
531 for (size_t k = 0; k < fBatchWidth; k++) {
532 // because of the column-major ordering
533 size_t bufferIndex = i * fBatchHeight * fBatchWidth + k * fBatchHeight + j;
534 buffer[bufferIndex] = event->GetValue(j * fBatchWidth + k);
535 }
536 }
537 sampleIterator++;
538 }
539 }
540 else {
541 Error("TTensorDataLoader","Inconsistency between batch depth and batch size");
542 R__ASSERT(0);
543 }
544}
545
546//______________________________________________________________________________
547template <>
549 IndexIterator_t sampleIterator)
550{
551 const DataSetInfo &info = std::get<1>(fData);
552 size_t n = buffer.GetSize() / fBatchSize;
553
554 // Copy target(s).
555
556 for (size_t i = 0; i < fBatchSize; i++) {
557 size_t sampleIndex = *sampleIterator++;
558 Event *event = std::get<0>(fData)[sampleIndex];
559 for (size_t j = 0; j < n; j++) {
560 // Copy output matrices.
561 size_t bufferIndex = j * fBatchSize + i;
562 // Classification
563 if (event->GetNTargets() == 0) {
564 if (n == 1) {
565 // Binary.
566 buffer[bufferIndex] = (info.IsSignal(event)) ? 1.0 : 0.0;
567 } else {
568 // Multiclass.
569 buffer[bufferIndex] = 0.0;
570 if (j == event->GetClass()) {
571 buffer[bufferIndex] = 1.0;
572 }
573 }
574 } else {
575 buffer[bufferIndex] = static_cast<Real_t>(event->GetTarget(j));
576 }
577 }
578 }
579}
580
581//______________________________________________________________________________
582template <>
584 IndexIterator_t sampleIterator)
585{
586 for (size_t i = 0; i < fBatchSize; i++) {
587 size_t sampleIndex = *sampleIterator++;
588 Event *event = std::get<0>(fData)[sampleIndex];
589 buffer[i] = event->GetWeight();
590 }
591}
592
593
594// Explicit instantiations.
595template class TCpuBuffer<Double_t>;
596template class TCpuBuffer<Real_t>;
597
598} // namespace DNN
599} // namespace TMVA
float Real_t
Definition: RtypesCore.h:64
double Double_t
Definition: RtypesCore.h:55
#define R__ASSERT(e)
Definition: TError.h:96
void Error(const char *location, const char *msgfmt,...)
size_t GetSize() const
Definition: CpuBuffer.h:81
void CopyFrom(TCpuBuffer &)
Copy data from another buffer.
Definition: CpuBuffer.cxx:57
TCpuBuffer(size_t size)
Construct buffer to hold size numbers of type AFloat.
Definition: CpuBuffer.cxx:38
TCpuBuffer GetSubBuffer(size_t offset, size_t start)
Return subbuffer of siez start starting at element offset.
Definition: CpuBuffer.cxx:47
std::shared_ptr< AFloat * > fBuffer
Definition: CpuBuffer.h:49
void CopyTo(TCpuBuffer &)
Copy data to another buffer.
Definition: CpuBuffer.cxx:64
struct TMVA::DNN::TCpuBuffer::TDestructor fDestructor
Class that contains all the data information.
Definition: DataSetInfo.h:60
Bool_t IsSignal(const Event *ev) const
Int_t GetNcols() const
Definition: TMatrixTBase.h:127
TMatrixT.
Definition: TMatrixT.h:39
const Int_t n
Definition: legend1.C:16
typename std::vector< size_t >::iterator IndexIterator_t
Definition: DataLoader.h:42
Abstract ClassifierFactory template that handles arbitrary types.
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value and is_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Definition: json.hpp:12929
void operator()(AFloat **pointer)
Definition: CpuBuffer.cxx:30