| 52 | } |
| 53 | |
| 54 | void NumpyReaderGPU::Prefetch() { |
| 55 | // We actually prepare the next batch |
| 56 | DomainTimeRange tr("[DALI][NumpyReaderGPU] Prefetch #" + to_string(curr_batch_producer_), |
| 57 | DomainTimeRange::kRed); |
| 58 | DataReader<GPUBackend, NumpyFileWrapperGPU, NumpyFileWrapperGPU, true>::Prefetch(); |
| 59 | auto &curr_batch = prefetched_batch_queue_[curr_batch_producer_]; |
| 60 | auto &curr_tensor_list = prefetched_batch_tensors_[curr_batch_producer_]; |
| 61 | |
| 62 | // get shapes |
| 63 | for (size_t data_idx = 0; data_idx < curr_batch.size(); ++data_idx) { |
| 64 | // when padding, the last sample is duplicated so no need to redo the same work |
| 65 | if (data_idx > 0 && curr_batch[data_idx -1 ] == curr_batch[data_idx]) continue; |
| 66 | thread_pool_.AddWork([this, &curr_batch, data_idx](int tid) { |
| 67 | curr_batch[data_idx]->Reopen(); |
| 68 | curr_batch[data_idx]->ReadHeader(header_cache_); |
| 69 | }); |
| 70 | } |
| 71 | thread_pool_.RunAll(); |
| 72 | |
| 73 | // resize the current batch |
| 74 | auto ref_type = curr_batch[0]->get_type(); |
| 75 | auto ref_shape = curr_batch[0]->get_shape(); |
| 76 | TensorListShape<> tmp_shapes(curr_batch.size(), ref_shape.sample_dim()); |
| 77 | for (size_t data_idx = 0; data_idx < curr_batch.size(); ++data_idx) { |
| 78 | auto &sample = curr_batch[data_idx]; |
| 79 | DALI_ENFORCE(ref_type == sample->get_type(), make_string("Inconsistent data! " |
| 80 | "The data produced by the reader has inconsistent type:\n" |
| 81 | "type of [", data_idx, "] is ", sample->get_type(), " whereas\n" |
| 82 | "type of [0] is ", ref_type)); |
| 83 | |
| 84 | DALI_ENFORCE( |
| 85 | ref_shape.sample_dim() == sample->get_shape().sample_dim(), |
| 86 | make_string( |
| 87 | "Inconsistent data! The data produced by the reader has inconsistent dimensionality:\n" |
| 88 | "[", |
| 89 | data_idx, "] has ", sample->get_shape().sample_dim(), |
| 90 | " dimensions whereas\n" |
| 91 | "[0] has ", |
| 92 | ref_shape.sample_dim(), " dimensions.")); |
| 93 | tmp_shapes.set_tensor_shape(data_idx, sample->get_shape()); |
| 94 | } |
| 95 | |
| 96 | curr_tensor_list.Resize(tmp_shapes, ref_type); |
| 97 | |
| 98 | // read the data |
| 99 | int first_padded = -1; |
| 100 | for (int data_idx = 0; data_idx < curr_tensor_list.num_samples(); ++data_idx) { |
| 101 | curr_tensor_list.SetMeta(data_idx, curr_batch[data_idx]->meta); |
| 102 | SampleView<GPUBackend> sample(curr_tensor_list.raw_mutable_tensor(data_idx), |
| 103 | curr_tensor_list.tensor_shape(data_idx), |
| 104 | curr_tensor_list.type()); |
| 105 | // when padding, the last sample is duplicated so no need to redo the same work |
| 106 | if (data_idx > 0 && curr_batch[data_idx - 1] == curr_batch[data_idx]) { |
| 107 | if (first_padded < 0) { |
| 108 | first_padded = data_idx; |
| 109 | } |
| 110 | curr_batch[data_idx]->source_sample_idx = first_padded - 1; |
| 111 | } else { |
nothing calls this directly
no test coverage detected