Skip to content

First‐batch filenames misaligned by two frames when using ExternalSource + DALIGenericIterator (DALI 1.49) #5930

@aafaqin

Description

@aafaqin

Describe the question.

I’m trying to feed raw JPEG bytes and their corresponding frame‐indices into a DALI pipeline, then look up the real filenames on the Python side. My minimal repro looks like this (using DALI 1.49):

import os, numpy as np
import nvidia.dali.fn as fn
import nvidia.dali.types as types
from nvidia.dali.pipeline import Pipeline
from nvidia.dali.plugin.pytorch import DALIGenericIterator
from nvidia.dali.plugin.base_iterator import LastBatchPolicy

class ExternalInputIterator:
    def __init__(self, batch_size, image_dir):
        self.files = sorted(os.listdir(image_dir))
        self.batch_size = batch_size
        self.i = 0
    def __iter__(self):
        self.i = 0
        return self
    def __next__(self):
        if self.i >= len(self.files):
            raise StopIteration()
        bufs, idxs = [], []
        for _ in range(self.batch_size):
            if self.i >= len(self.files): break
            fname = self.files[self.i]
            with open(os.path.join(image_dir, fname), 'rb') as f:
                bufs.append(np.frombuffer(f.read(), dtype=np.uint8))
            idxs.append(np.int64(self.i))
            self.i += 1
        return bufs, idxs

class SimplePipeline(Pipeline):
    def __init__(self, bs, nthreads, devid, external_iter, W, H):
        super().__init__(bs, nthreads, devid,
                         exec_async=False, exec_pipelined=False,
                         prefetch_queue_depth=1, seed=123)
        self.jpegs, self.idxs = fn.external_source(
            source=external_iter,
            num_outputs=2,
            dtype=[types.UINT8, types.INT64],
            parallel=False
        )
        self.decode  = fn.decoders.image(self.jpegs, device="mixed", output_type=types.RGB)
        self.resized = fn.resize(self.decode, device="gpu", resize_x=W, resize_y=H)
        self.normed  = fn.crop_mirror_normalize(
            self.resized, device="gpu", dtype=types.FLOAT, output_layout="CHW",
            mean=[0,0,0], std=[255,255,255], shift=0
        )
    def define_graph(self):
        return self.normed, self.idxs

# … in infer_on_DALI() …
all_files = sorted(os.listdir(image_dir))
external_it = ExternalInputIterator(batch_size, image_dir)
pipe = SimplePipeline(batch_size, 4, 0, external_it, WIDTH, HEIGHT)
pipe.build()

dali_iter = DALIGenericIterator(
    pipe,
    ["data", "idx"],
    size=len(all_files),
    last_batch_policy=LastBatchPolicy.PARTIAL,
    auto_reset=True,
    prepare_first_batch=False  # or omitted
)

for batch in dali_iter:
    images = batch[0]["data"]
    idxs   = batch[0]["idx"].cpu().numpy().astype(int)
    frame_names = [all_files[i] for i in idxs]
    print("Processing", frame_names)
    # … do detection …

Observed behavior

Every frame_names printed inside the loop is consistently two frames behind what the ExternalInputIterator logs on its own print calls.

Adding or removing prepare_first_batch=False and/or manual next(dali_iter) flushes changes how many batches are skipped, but I can’t get a 1:1 alignment.

I’m on DALI 1.49.

Expected behavior

The first batch inside the for batch in dali_iter: should correspond to the first images and indices yielded by ExternalInputIterator, with no offset.

Questions

Am I misusing prepare_first_batch vs. DALI’s default priming?

Are there any internal queues or prefetching details in DALI 1.49 that introduce this two-frame lag?

What is the recommended pattern for keeping an ExternalSource -> DALIGenericIterator pipeline perfectly in sync, so my Python-side indices (and thus filenames) line up exactly with the tensors I receive?

Any pointers or example snippets to fix this alignment issue would be greatly appreciated!

Check for duplicates

  • I have searched the open bugs/issues and have found no duplicates for this bug report

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions