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