:github_url: https://github.com/pytorch/pytorch .. _program_listing_file_torch_csrc_api_include_torch_data_detail_sequencers.h: Program Listing for File sequencers.h ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``torch/csrc/api/include/torch/data/detail/sequencers.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include #include #include #include namespace torch::data::detail::sequencers { namespace detail { template bool buffer_contains_result(const std::vector>& buffer) { return std::any_of( buffer.begin(), buffer.end(), [](const std::optional& result) { return result.has_value(); }); } } // namespace detail template struct Sequencer { using ResultProducer = std::function()>; virtual ~Sequencer() = default; virtual std::optional next(ResultProducer next_result) = 0; }; template struct NoSequencer final : public Sequencer { using typename Sequencer::ResultProducer; std::optional next(ResultProducer next_result) override { return next_result(); } }; template struct OrderedSequencer : public Sequencer { using typename Sequencer::ResultProducer; explicit OrderedSequencer(size_t max_jobs) : buffer_(max_jobs) {} std::optional next(ResultProducer next_result) override { // If we already have the result for the next sqn, return it. if (auto& maybe_result = buffer(next_sequence_number_)) { auto result = std::move(*maybe_result); buffer(next_sequence_number_++).reset(); return result; } // Otherwise wait for the next result. while (true) { auto result = next_result(); if (!result) { AT_ASSERT(!detail::buffer_contains_result(buffer_)); break; } // If it was not nullopt and the sequence numbers match, return it // directly and bump the sequence number. if (result->sequence_number == next_sequence_number_) { ++next_sequence_number_; return result; } // Stash the result for later. AT_ASSERT(!buffer(result->sequence_number).has_value()); buffer(result->sequence_number) = std::move(result); } // The result was an empty optional, so we are done with this epoch. return std::nullopt; } std::optional& buffer(size_t index) { return buffer_.at(index % buffer_.size()); } size_t next_sequence_number_ = 0; std::vector> buffer_; }; } // namespace torch::data::detail::sequencers