33#include < algorithm>
44#include < cstddef>
55#include < cstring>
6- #include < functional>
76#include < numeric>
87#include < utility>
98
1413
1514namespace infini_train {
1615namespace {
17- size_t CheckedCeilDiv (size_t numerator, size_t denominator) {
18- CHECK_GT (denominator, 0 );
19- return (numerator + denominator - 1 ) / denominator;
20- }
21-
2216// TODO(dcj): Use official stack implementation later.
2317std::shared_ptr<Tensor> Stack (const std::vector<std::shared_ptr<Tensor>> &tensors) {
24- CHECK (!tensors.empty ()) << " Cannot stack an empty batch. Check DataLoader iterator end handling." ;
2518 const int batch_size = tensors.size ();
2619 const auto &dims = tensors[0 ]->Dims ();
2720 const int stacked_dim = std::accumulate (dims.begin (), dims.end (), 1 , std::multiplies<int64_t >());
@@ -42,31 +35,21 @@ std::shared_ptr<Tensor> Stack(const std::vector<std::shared_ptr<Tensor>> &tensor
4235}
4336} // namespace
4437
45- DataLoaderIterator::DataLoaderIterator (const Dataset &dataset, size_t batch_size, size_t global_batch_idx ,
46- size_t num_global_batches , size_t ddp_rank, size_t ddp_world_size)
47- : dataset_(&dataset), batch_size_(batch_size), global_batch_idx_(global_batch_idx ),
48- num_global_batches_ (num_global_batches), ddp_rank_(ddp_rank), ddp_world_size_(ddp_world_size){};
38+ DataLoaderIterator::DataLoaderIterator (const Dataset &dataset, size_t batch_size, size_t batch_idx ,
39+ size_t max_batch_idx , size_t ddp_rank, size_t ddp_world_size)
40+ : dataset_(&dataset), batch_size_(batch_size), batch_idx_(batch_idx), max_batch_idx_(max_batch_idx ),
41+ ddp_rank_ (ddp_rank), ddp_world_size_(ddp_world_size){};
4942
5043std::pair<std::shared_ptr<Tensor>, std::shared_ptr<Tensor>> DataLoaderIterator::operator *() const {
5144 /*
5245 0, 1, ..., x, ...
5346 [0, bs-1], [bs, 2*bs-1], ..., [x*bs, (x+1)*bs-1], ...
5447 ^
55- global_batch_idx
48+ batch_idx
5649 */
5750 std::vector<std::shared_ptr<Tensor>> data_vec;
5851 std::vector<std::shared_ptr<Tensor>> label_vec;
59- CHECK_LT (global_batch_idx_, num_global_batches_)
60- << " Cannot dereference DataLoader end iterator. global_batch_idx=" << global_batch_idx_
61- << " , num_global_batches=" << num_global_batches_ << " , ddp_rank=" << ddp_rank_
62- << " , ddp_world_size=" << ddp_world_size_;
63- const size_t start_idx = (global_batch_idx_ * ddp_world_size_ + ddp_rank_) * batch_size_;
64- CHECK_LT (start_idx, dataset_->Size ())
65- << " DataLoader batch starts past dataset end. global_batch_idx=" << global_batch_idx_
66- << " , start_idx=" << start_idx << " , dataset_size=" << dataset_->Size () << " , batch_size=" << batch_size_
67- << " , ddp_rank=" << ddp_rank_ << " , ddp_world_size=" << ddp_world_size_;
68- const size_t end_idx = std::min (start_idx + batch_size_, dataset_->Size ());
69- for (size_t idx = start_idx; idx < end_idx; ++idx) {
52+ for (int idx = batch_idx_ * batch_size_; idx < (batch_idx_ + 1 ) * batch_size_ && idx < dataset_->Size (); ++idx) {
7053 auto &&[data, label] = dataset_->operator [](idx);
7154 data_vec.push_back (std::move (data));
7255 label_vec.push_back (std::move (label));
@@ -75,7 +58,7 @@ std::pair<std::shared_ptr<Tensor>, std::shared_ptr<Tensor>> DataLoaderIterator::
7558}
7659
7760DataLoaderIterator &DataLoaderIterator::operator ++() {
78- global_batch_idx_ = std::min (global_batch_idx_ + 1 , num_global_batches_ );
61+ batch_idx_ = std::min (batch_idx_ + ddp_world_size_, max_batch_idx_ );
7962 return *this ;
8063}
8164
@@ -85,60 +68,36 @@ DataLoaderIterator DataLoaderIterator::operator++(int) {
8568 return tmp;
8669}
8770
88- bool operator <(const DataLoaderIterator &lhs, const DataLoaderIterator &rhs) {
89- return lhs.global_batch_idx_ < rhs.global_batch_idx_ ;
90- }
71+ bool operator <(const DataLoaderIterator &lhs, const DataLoaderIterator &rhs) { return lhs.batch_idx_ < rhs.batch_idx_ ; }
9172
9273bool operator !=(const DataLoaderIterator &lhs, const DataLoaderIterator &rhs) {
93- return lhs.global_batch_idx_ != rhs.global_batch_idx_ ;
74+ return lhs.batch_idx_ != rhs.batch_idx_ ;
9475}
9576
9677bool operator ==(const DataLoaderIterator &lhs, const DataLoaderIterator &rhs) {
97- return lhs.global_batch_idx_ == rhs.global_batch_idx_ ;
78+ return lhs.batch_idx_ == rhs.batch_idx_ ;
9879}
9980
100- size_t DataLoaderIterator::GlobalBatchIndex () const { return global_batch_idx_; }
101-
102- DataLoaderIterator &DataLoaderIterator::SeekGlobalBatch (size_t global_batch_idx) {
103- CHECK_LE (global_batch_idx, num_global_batches_)
104- << " Cannot seek past DataLoader end. global_batch_idx=" << global_batch_idx
105- << " , num_global_batches=" << num_global_batches_;
106- global_batch_idx_ = global_batch_idx;
107- return *this ;
108- }
81+ size_t DataLoaderIterator::BatchIndex () const { return batch_idx_; }
10982
11083DataLoader::DataLoader (const std::shared_ptr<Dataset> &dataset, size_t batch_size)
111- : dataset_(dataset), batch_size_(batch_size), num_global_batches_(CheckedCeilDiv (dataset_->Size (), batch_size_) ) {}
84+ : dataset_(dataset), batch_size_(batch_size), max_batch_idx_( (dataset_->Size () + batch_size_ - 1) / batch_size_ ) {}
11285
113- DataLoaderIterator DataLoader::begin () const {
114- return DataLoaderIterator (*dataset_, batch_size_, 0 , num_global_batches_);
115- }
86+ DataLoaderIterator DataLoader::begin () const { return DataLoaderIterator (*dataset_, batch_size_, 0 , max_batch_idx_); }
11687
11788DataLoaderIterator DataLoader::end () const {
118- return DataLoaderIterator (*dataset_, batch_size_, num_global_batches_, num_global_batches_ );
89+ return DataLoaderIterator (*dataset_, batch_size_, max_batch_idx_, max_batch_idx_ );
11990}
12091
121- size_t DataLoader::NumGlobalBatches () const { return num_global_batches_; }
122-
12392DistributedDataLoader::DistributedDataLoader (const std::shared_ptr<Dataset> &dataset, size_t batch_size,
12493 size_t ddp_rank, size_t ddp_world_size)
125- : DataLoader(dataset, batch_size), ddp_rank_(ddp_rank), ddp_world_size_(ddp_world_size) {
126- CHECK_GT (ddp_world_size_, 0 );
127- CHECK_LT (ddp_rank_, ddp_world_size_);
128- const size_t global_batch_size = ddp_world_size_ * batch_size_;
129- CHECK_GE (dataset_->Size (), global_batch_size)
130- << " DistributedDataLoader needs at least one full global batch. dataset_size=" << dataset_->Size ()
131- << " , global_batch_size=" << global_batch_size << " (" << batch_size_ << " per rank * " << ddp_world_size_
132- << " ranks). Reduce batch size/world size or use a larger dataset." ;
133- num_global_batches_ = dataset_->Size () / global_batch_size;
134- }
94+ : DataLoader(dataset, batch_size), ddp_rank_(ddp_rank), ddp_world_size_(ddp_world_size) {}
13595
13696DataLoaderIterator DistributedDataLoader::begin () const {
137- return DataLoaderIterator (*dataset_, batch_size_, 0 , num_global_batches_ , ddp_rank_, ddp_world_size_);
97+ return DataLoaderIterator (*dataset_, batch_size_, ddp_rank_, max_batch_idx_ , ddp_rank_, ddp_world_size_);
13898}
13999
140100DataLoaderIterator DistributedDataLoader::end () const {
141- return DataLoaderIterator (*dataset_, batch_size_, num_global_batches_, num_global_batches_, ddp_rank_,
142- ddp_world_size_);
101+ return DataLoaderIterator (*dataset_, batch_size_, max_batch_idx_, max_batch_idx_, ddp_rank_, ddp_world_size_);
143102}
144103} // namespace infini_train
0 commit comments