Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend external source operator capacity #1127

Merged
merged 1 commit into from
Aug 20, 2019
Merged

Extend external source operator capacity #1127

merged 1 commit into from
Aug 20, 2019

Conversation

JanuszL
Copy link
Contributor

@JanuszL JanuszL commented Jul 30, 2019

  • makes external source to be able to hold more than one sample
    at the time so the user can feed more data ahead before it is consumed
    by RunCPU/RunGPU

Signed-off-by: Janusz Lisiecki jlisiecki@nvidia.com

Why we need this PR?

  • makes external source to be able to hold more than one sample
    at the time so the user can feed more data ahead before it is consumed

What happened in this PR?

  • so far ExternalSource was able to keep only one piece of data and every try to provide it with more was waiting for pipeline to consume what is already there
  • adds queue with data to ExternalSource which caches already consumed tensors to avoid expensive allocations when new piece is provided
  • test is added, tested on CI

JIRA TASK: DALI-954

@JanuszL
Copy link
Contributor Author

JanuszL commented Jul 30, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [834670]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [834670]: BUILD FAILED

@JanuszL
Copy link
Contributor Author

JanuszL commented Jul 30, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [834754]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [834754]: BUILD FAILED

@JanuszL
Copy link
Contributor Author

JanuszL commented Jul 30, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [835080]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [835080]: BUILD FAILED

@JanuszL
Copy link
Contributor Author

JanuszL commented Jul 31, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [835829]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [835829]: BUILD FAILED

dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/util/backend2workspace_map.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.cc Outdated Show resolved Hide resolved
@dali-automaton
Copy link
Collaborator

CI MESSAGE: [836294]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [836294]: BUILD FAILED

@JanuszL
Copy link
Contributor Author

JanuszL commented Aug 1, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [837881]: BUILD FAILED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [837896]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [837896]: BUILD FAILED

@JanuszL
Copy link
Contributor Author

JanuszL commented Aug 1, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [837981]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [837981]: BUILD PASSED

@JanuszL JanuszL requested a review from mzient August 2, 2019 07:17
}
cv_.notify_all();
output.Copy(*data, (ws->has_stream() ? ws->stream() : 0));
busy_lock.lock();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as I wrote before, but not really strong opinion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

template <typename T>
class CachingList {
public:
CachingList() {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CachingList() {}
CachingList() = default;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

std::unique_ptr<T> GetEmpty() {
if (!empty_data_.size()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!empty_data_.size()) {
if (empty_data_.empty()) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -0,0 +1,254 @@
// Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2019

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [848584]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [848584]: BUILD FAILED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [848665]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [848665]: BUILD FAILED

@JanuszL
Copy link
Contributor Author

JanuszL commented Aug 9, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [849861]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [849861]: BUILD FAILED

if (cuda_event) {
cuda_events_.Recycle(std::move(cuda_event));
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the RecycleHelper more complicated than it should be

Why not:

private:
  void RecycleHelper(std::unique_ptr<std::vector<Tensor<CPUBackend>>>> data) {
    t_data_.Recycle(std::move(data));
  }

  void RecycleHelper(std::unique_ptr<TensorList<CPUBackend>> data) {
    tl_data_.Recycle(std::move(data));
  }

and then in RecycleBuffer you just call

RecycleHelper(std::move(data));

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

};

template <typename DataType>
std::enable_if_t<std::is_same<DataType, std::unique_ptr<TensorList<CPUBackend>>>::value>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my comment below about this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [850380]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [850380]: BUILD FAILED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [851002]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [851002]: BUILD FAILED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [851002]: BUILD PASSED

DALI_ENFORCE(!tl_data_.IsEmpty(), "ExternalSource is empty. Need to feed data first.");
tl_data = tl_data_.PopFront();
DALI_ENFORCE(OperatorBase::batch_size_ == static_cast<int>(tl_data.front()->ntensor()),
"Data list provided to ExternalSource needs to have batch_size length.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing indent

DALI_ENFORCE(!t_data_.IsEmpty(), "ExternalSource is empty. Need to feed data first.");
t_data = t_data_.PopFront();
DALI_ENFORCE(OperatorBase::batch_size_ == static_cast<int>(t_data.front()->size()),
"Data list provided to ExternalSource needs to have batch_size length.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing indent

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

cv_.notify_all();

auto &output = ws->Output<GPUBackend>(0);
output.Copy(*(data.front()), (ws->has_stream() ? ws->stream() : 0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have (ws->has_stream() ? ws->stream() : 0) twice. Consider using a variable instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.cc Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
// HostWorkspace doesn't have any stream
cudaStream_t stream = 0;
if (is_tl_data) {
output.Copy(*(tl_data.front()), data_idx, stream);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this copy the TensorList batch_size_ times? I guess it shouldn't be in a loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. output is a tensor, Copy(*(tl_data.front()), data_idx, stream); extracts the data_idx tensor from tl_data and copies to the output.
I think we don't have a fast way to copy TensorList to a vector of Tensors other than go one by one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed the data_idx argument. Everything's ok.

return full_data_.empty();
}

ListT PopFront() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment describing how the CachingList works and that it always operates on single elements wrapped in a list? I misread the doc for splice and was wandering why you don't handle a case with more than 1 element.

BTW is this really that much better than references + moves?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description added. The idea with one element list was provided by @mzient as it saves the allocation for the new element in the list. I don't think it gives us much but on the other hand it doesn't cost much (regarding the code itself) to make it this way either.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The small allocations can be painful, esp. if there is a lot of them.

dali/pipeline/operators/util/external_source.cc Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.h Outdated Show resolved Hide resolved
dali/pipeline/operators/util/external_source.cu Outdated Show resolved Hide resolved
@JanuszL
Copy link
Contributor Author

JanuszL commented Aug 16, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [859754]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [859754]: BUILD PASSED

@JanuszL JanuszL requested a review from klecki August 17, 2019 22:05
@JanuszL
Copy link
Contributor Author

JanuszL commented Aug 19, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [863164]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [863164]: BUILD FAILED

- makes external source to be able to hold more than one sample
  at the time so the user can feed more data ahead before it is consumed
  by RunCPU/RunGPU

Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
@JanuszL
Copy link
Contributor Author

JanuszL commented Aug 19, 2019

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [863215]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [863215]: BUILD PASSED

@JanuszL JanuszL merged commit bee78ee into NVIDIA:master Aug 20, 2019
@JanuszL JanuszL deleted the external_source_upd branch August 20, 2019 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants