Logo ROOT   6.16/01
Reference Guide
DataLoader.h
Go to the documentation of this file.
1// @(#)root/tmva/tmva/dnn:$Id$
2// Author: Simon Pfreundschuh 08/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// Generic data loader for neural network input data. Provides a //
14// high level abstraction for the transfer of training data to the //
15// device. //
16/////////////////////////////////////////////////////////////////////
17
18#ifndef TMVA_DNN_DATALOADER
19#define TMVA_DNN_DATALOADER
20
21#include "TMatrix.h"
22#include "TMVA/Event.h"
23
24#include <algorithm>
25#include <iostream>
26#include <random>
27#include <vector>
28
29namespace TMVA {
30
31class DataSetInfo;
32
33namespace DNN {
34
35//
36// Input Data Types
37//______________________________________________________________________________
38using MatrixInput_t = std::tuple<const TMatrixT<Double_t> &, const TMatrixT<Double_t> &, const TMatrixT<Double_t> &>;
40 std::tuple<const std::vector<Event *> &, const DataSetInfo &>;
41
42using IndexIterator_t = typename std::vector<size_t>::iterator;
43
44/** TBatch
45 *
46 * Class representing training batches consisting of a matrix of input data
47 * and a matrix of output data. The input and output data can be accessed using
48 * the GetInput() and GetOutput() member functions.
49 *
50 * \tparam AArchitecture The underlying architecture.
51 */
52//______________________________________________________________________________
53template <typename AArchitecture>
54class TBatch
55{
56private:
57
58 using Matrix_t = typename AArchitecture::Matrix_t;
59
63
64public:
66 TBatch(const TBatch &) = default;
67 TBatch( TBatch &&) = default;
68 TBatch & operator=(const TBatch &) = default;
69 TBatch & operator=( TBatch &&) = default;
70
71 /** Return the matrix representing the input data. */
73 /** Return the matrix representing the output data. */
75 /** Return the matrix holding the event weights. */
77};
78
79template<typename Data_t, typename AArchitecture> class TDataLoader;
80
81/** TBatchIterator
82 *
83 * Simple iterator class for the iterations over the training batches in
84 * a given data set represented by a TDataLoader object.
85 *
86 * \tparam AData The input data type.
87 * \tparam AArchitecture The underlying architecture type.
88 */
89template<typename Data_t, typename AArchitecture>
91{
92private:
93
96
97public:
98
100: fDataLoader(dataLoader), fBatchIndex(index)
101{
102 // Nothing to do here.
103}
104
107 bool operator!=(const TBatchIterator & other) {
108 return fBatchIndex != other.fBatchIndex;
109 }
110};
111
112/** TDataLoader
113 *
114 * Service class managing the streaming of the training data from the input data
115 * type to the accelerator device or the CPU. A TDataLoader object manages a number
116 * of host and device buffer pairs that are used in a round-robin manner for the
117 * transfer of batches to the device.
118 *
119 * Each TDataLoader object has an associated batch size and a number of total
120 * samples in the dataset. One epoch is the number of buffers required to transfer
121 * the complete training set. Using the begin() and end() member functions allows
122 * the user to iterate over the batches in one epoch.
123 *
124 * \tparam AData The input data type.
125 * \tparam AArchitecture The achitecture class of the underlying architecture.
126 */
127template<typename Data_t, typename AArchitecture>
129{
130private:
131
132 using HostBuffer_t = typename AArchitecture::HostBuffer_t;
133 using DeviceBuffer_t = typename AArchitecture::DeviceBuffer_t;
134 using Matrix_t = typename AArchitecture::Matrix_t;
136
137 const Data_t &fData;
138
139 size_t fNSamples;
144
145 size_t fNStreams; ///< Number of buffer pairs.
146 std::vector<DeviceBuffer_t> fDeviceBuffers;
147 std::vector<HostBuffer_t> fHostBuffers;
148
149 std::vector<size_t> fSampleIndices; ///< Ordering of the samples in the epoch.
150
151public:
152
153 TDataLoader(const Data_t & data, size_t nSamples, size_t batchSize,
154 size_t nInputFeatures, size_t nOutputFeatures, size_t nStreams = 1);
155 TDataLoader(const TDataLoader &) = default;
156 TDataLoader( TDataLoader &&) = default;
157 TDataLoader & operator=(const TDataLoader &) = default;
159
160 /** Copy input matrix into the given host buffer. Function to be specialized by
161 * the architecture-specific backend. */
162 void CopyInput(HostBuffer_t &buffer, IndexIterator_t begin, size_t batchSize);
163 /** Copy output matrix into the given host buffer. Function to be specialized
164 * by the architecture-spcific backend. */
165 void CopyOutput(HostBuffer_t &buffer, IndexIterator_t begin, size_t batchSize);
166 /** Copy weight matrix into the given host buffer. Function to be specialized
167 * by the architecture-spcific backend. */
168 void CopyWeights(HostBuffer_t &buffer, IndexIterator_t begin, size_t batchSize);
169
172 {
174 }
175
176 /** Shuffle the order of the samples in the batch. The shuffling is indirect,
177 * i.e. only the indices are shuffled. No input data is moved by this
178 * routine. */
179 void Shuffle();
180
181 /** Return the next batch from the training set. The TDataLoader object
182 * keeps an internal counter that cycles over the batches in the training
183 * set. */
185
186};
187
188//
189// TBatch Class.
190//______________________________________________________________________________
191template <typename AArchitecture>
192TBatch<AArchitecture>::TBatch(Matrix_t &inputMatrix, Matrix_t &outputMatrix, Matrix_t &weightMatrix)
193 : fInputMatrix(inputMatrix), fOutputMatrix(outputMatrix), fWeightMatrix(weightMatrix)
194{
195 // Nothing to do here.
196}
197
198//
199// TDataLoader Class.
200//______________________________________________________________________________
201template<typename Data_t, typename AArchitecture>
203 const Data_t & data, size_t nSamples, size_t batchSize,
204 size_t nInputFeatures, size_t nOutputFeatures, size_t nStreams)
205 : fData(data), fNSamples(nSamples), fBatchSize(batchSize),
206 fNInputFeatures(nInputFeatures), fNOutputFeatures(nOutputFeatures),
207 fBatchIndex(0), fNStreams(nStreams), fDeviceBuffers(), fHostBuffers(),
208 fSampleIndices()
209{
210 size_t inputMatrixSize = fBatchSize * fNInputFeatures;
211 size_t outputMatrixSize = fBatchSize * fNOutputFeatures;
212 size_t weightMatrixSize = fBatchSize;
213
214 for (size_t i = 0; i < fNStreams; i++)
215 {
216 fHostBuffers.push_back(HostBuffer_t(inputMatrixSize + outputMatrixSize + weightMatrixSize));
217 fDeviceBuffers.push_back(DeviceBuffer_t(inputMatrixSize + outputMatrixSize + weightMatrixSize));
218 }
219
220 fSampleIndices.reserve(fNSamples);
221 for (size_t i = 0; i < fNSamples; i++) {
222 fSampleIndices.push_back(i);
223 }
224}
225
226//______________________________________________________________________________
227template<typename Data_t, typename AArchitecture>
229{
230 fBatchIndex %= (fNSamples / fBatchSize); // Cycle through samples.
231
232
233 size_t inputMatrixSize = fBatchSize * fNInputFeatures;
234 size_t outputMatrixSize = fBatchSize * fNOutputFeatures;
235 size_t weightMatrixSize = fBatchSize;
236
237 size_t streamIndex = fBatchIndex % fNStreams;
238 HostBuffer_t & hostBuffer = fHostBuffers[streamIndex];
239 DeviceBuffer_t & deviceBuffer = fDeviceBuffers[streamIndex];
240
241 HostBuffer_t inputHostBuffer = hostBuffer.GetSubBuffer(0, inputMatrixSize);
242 HostBuffer_t outputHostBuffer = hostBuffer.GetSubBuffer(inputMatrixSize,
243 outputMatrixSize);
244 HostBuffer_t weightHostBuffer = hostBuffer.GetSubBuffer(inputMatrixSize + outputMatrixSize, weightMatrixSize);
245
246 DeviceBuffer_t inputDeviceBuffer = deviceBuffer.GetSubBuffer(0, inputMatrixSize);
247 DeviceBuffer_t outputDeviceBuffer = deviceBuffer.GetSubBuffer(inputMatrixSize,
248 outputMatrixSize);
249 DeviceBuffer_t weightDeviceBuffer = deviceBuffer.GetSubBuffer(inputMatrixSize + outputMatrixSize, weightMatrixSize);
250
251 size_t sampleIndex = fBatchIndex * fBatchSize;
252 IndexIterator_t sampleIndexIterator = fSampleIndices.begin() + sampleIndex;
253
254 CopyInput(inputHostBuffer, sampleIndexIterator, fBatchSize);
255 CopyOutput(outputHostBuffer, sampleIndexIterator, fBatchSize);
256 CopyWeights(weightHostBuffer, sampleIndexIterator, fBatchSize);
257
258 deviceBuffer.CopyFrom(hostBuffer);
259 Matrix_t inputMatrix(inputDeviceBuffer, fBatchSize, fNInputFeatures);
260 Matrix_t outputMatrix(outputDeviceBuffer, fBatchSize, fNOutputFeatures);
261 Matrix_t weightMatrix(weightDeviceBuffer, fBatchSize, fNOutputFeatures);
262
263 fBatchIndex++;
264 return TBatch<AArchitecture>(inputMatrix, outputMatrix, weightMatrix);
265}
266
267//______________________________________________________________________________
268template<typename Data_t, typename AArchitecture>
270{
271 std::shuffle(fSampleIndices.begin(), fSampleIndices.end(), std::default_random_engine{});
272}
273
274} // namespace DNN
275} // namespace TMVA
276
277#endif
TBatchIterator.
Definition: DataLoader.h:91
TDataLoader< Data_t, AArchitecture > & fDataLoader
Definition: DataLoader.h:94
TBatch< AArchitecture > operator*()
Definition: DataLoader.h:105
bool operator!=(const TBatchIterator &other)
Definition: DataLoader.h:107
TBatchIterator(TDataLoader< Data_t, AArchitecture > &dataLoader, size_t index=0)
Definition: DataLoader.h:99
TBatchIterator operator++()
Definition: DataLoader.h:106
Matrix_t fInputMatrix
Definition: DataLoader.h:60
TBatch(const TBatch &)=default
Matrix_t fOutputMatrix
Definition: DataLoader.h:61
TBatch(Matrix_t &, Matrix_t &, Matrix_t &)
Definition: DataLoader.h:192
Matrix_t fWeightMatrix
Definition: DataLoader.h:62
Matrix_t & GetInput()
Return the matrix representing the input data.
Definition: DataLoader.h:72
Matrix_t & GetOutput()
Return the matrix representing the output data.
Definition: DataLoader.h:74
TBatch & operator=(const TBatch &)=default
Matrix_t & GetWeights()
Return the matrix holding the event weights.
Definition: DataLoader.h:76
TBatch(TBatch &&)=default
TBatch & operator=(TBatch &&)=default
typename AArchitecture::Matrix_t Matrix_t
Definition: DataLoader.h:58
BatchIterator_t end()
Definition: DataLoader.h:171
const Data_t & fData
Definition: DataLoader.h:137
TDataLoader(TDataLoader &&)=default
void CopyInput(HostBuffer_t &buffer, IndexIterator_t begin, size_t batchSize)
Copy input matrix into the given host buffer.
BatchIterator_t begin()
Definition: DataLoader.h:170
std::vector< size_t > fSampleIndices
Ordering of the samples in the epoch.
Definition: DataLoader.h:149
std::vector< HostBuffer_t > fHostBuffers
Definition: DataLoader.h:147
TBatch< AArchitecture > GetBatch()
Return the next batch from the training set.
Definition: DataLoader.h:228
typename AArchitecture::DeviceBuffer_t DeviceBuffer_t
Definition: DataLoader.h:133
void CopyOutput(HostBuffer_t &buffer, IndexIterator_t begin, size_t batchSize)
Copy output matrix into the given host buffer.
TDataLoader & operator=(TDataLoader &&)=default
std::vector< DeviceBuffer_t > fDeviceBuffers
Definition: DataLoader.h:146
TDataLoader & operator=(const TDataLoader &)=default
typename AArchitecture::Matrix_t Matrix_t
Definition: DataLoader.h:134
size_t fNStreams
Number of buffer pairs.
Definition: DataLoader.h:145
TDataLoader(const Data_t &data, size_t nSamples, size_t batchSize, size_t nInputFeatures, size_t nOutputFeatures, size_t nStreams=1)
Definition: DataLoader.h:202
typename AArchitecture::HostBuffer_t HostBuffer_t
Definition: DataLoader.h:132
void Shuffle()
Shuffle the order of the samples in the batch.
Definition: DataLoader.h:269
void CopyWeights(HostBuffer_t &buffer, IndexIterator_t begin, size_t batchSize)
Copy weight matrix into the given host buffer.
TDataLoader(const TDataLoader &)=default
Class that contains all the data information.
Definition: DataSetInfo.h:60
typename std::vector< size_t >::iterator IndexIterator_t
Definition: DataLoader.h:42
std::tuple< const std::vector< Event * > &, const DataSetInfo & > TMVAInput_t
Definition: DataLoader.h:40
std::tuple< const TMatrixT< Double_t > &, const TMatrixT< Double_t > &, const TMatrixT< Double_t > & > MatrixInput_t
Definition: DataLoader.h:38
Abstract ClassifierFactory template that handles arbitrary types.