Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : /**
3 : * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
4 : *
5 : * @file data_iteration.cpp
6 : * @date 11 Aug 2021
7 : * @brief This file contains iteration and sample class
8 : * @see https://github.com/nnstreamer/nntrainer
9 : * @author Jihoon Lee <jhoon.it.lee@samsung.com>
10 : * @bug No known bugs except for NYI items
11 : *
12 : */
13 : #include <data_iteration.h>
14 :
15 : #include <algorithm>
16 :
17 : #include <nntrainer_error.h>
18 : #include <tensor.h>
19 : #include <tensor_dim.h>
20 :
21 : namespace nntrainer {
22 :
23 : namespace {
24 :
25 : /**
26 : * @brief check if all the dimension has the same batch, this is required
27 : * assumption for the creation of Iteration
28 : *
29 : */
30 5707 : bool isBatchSame(const std::vector<ml::train::TensorDim> &input_dims,
31 : const std::vector<ml::train::TensorDim> &label_dims) {
32 5707 : if (input_dims.empty()) {
33 : /// requires at least one input
34 : return false;
35 : }
36 :
37 5705 : unsigned int reference_batch = input_dims.front().batch();
38 : auto pred = [reference_batch](const TensorDim &dim) {
39 11729 : return dim.batch() == reference_batch;
40 : };
41 :
42 5705 : return std::all_of(input_dims.begin(), input_dims.end(), pred) &&
43 5703 : std::all_of(label_dims.begin(), label_dims.end(), pred);
44 : }
45 :
46 : /**
47 : * @brief slice vectors of tensors in to batch direction
48 : *
49 : * @param batched_tensors batched tensor
50 : * @param b batch
51 : * @return std::vector<Tensor> sliced tensor
52 : */
53 183052 : std::vector<Tensor> sliceTensor(const std::vector<Tensor> &batched_tensors,
54 : unsigned int b) {
55 : std::vector<Tensor> sliced_tensor;
56 183052 : sliced_tensor.reserve(batched_tensors.size());
57 183052 : std::transform(batched_tensors.begin(), batched_tensors.end(),
58 : std::back_inserter(sliced_tensor),
59 183734 : [b](const Tensor &t) { return t.getBatchSlice(b, 1); });
60 183050 : return sliced_tensor;
61 2 : };
62 :
63 5701 : std::vector<Sample> unpackIteration(Iteration &iter, unsigned int batch) {
64 : std::vector<Sample> samples;
65 5701 : samples.reserve(batch);
66 :
67 97223 : for (decltype(batch) i = 0; i < batch; ++i) {
68 91522 : samples.emplace_back(iter, i);
69 : }
70 :
71 5701 : return samples;
72 0 : }
73 :
74 : } // namespace
75 :
76 5707 : Iteration::Iteration(const std::vector<ml::train::TensorDim> &input_dims,
77 5707 : const std::vector<ml::train::TensorDim> &label_dims) :
78 5707 : inputs(input_dims.begin(), input_dims.end()),
79 5707 : labels(label_dims.begin(), label_dims.end()) {
80 :
81 5713 : NNTR_THROW_IF(!isBatchSame(input_dims, label_dims), std::invalid_argument)
82 : << "check batch size is all the same for all the input and label";
83 :
84 5701 : samples = unpackIteration(*this, input_dims.front().batch());
85 5701 : end_iterator = samples.end();
86 5719 : }
87 :
88 118708 : unsigned int Iteration::batch() { return std::distance(begin(), end()); }
89 :
90 1266 : void Iteration::setEndSample(std::vector<Sample>::iterator sample_iterator) {
91 1266 : end_iterator = sample_iterator;
92 1266 : }
93 :
94 12135 : void Iteration::setEndSample() { end_iterator = samples.end(); }
95 :
96 91527 : Sample::Sample(const Iteration &iter, unsigned int batch) :
97 91527 : inputs(sliceTensor(iter.getInputsRef(), batch)),
98 91525 : labels(sliceTensor(iter.getLabelsRef(), batch)) {}
99 :
100 : } // namespace nntrainer
|