Skip to content

Cannot couple RandomBBoxCrop and Slice #855

@kometa-triatlon

Description

@kometa-triatlon

I have a detection pipeline similar to the COCO example pipeline:

import nvidia.dali.ops as ops
import nvidia.dali.types as types
import nvidia.dali.tfrecord as tfrecord
from nvidia.dali.pipeline import Pipeline
from nvidia.dali import plugin_manager

plugin_manager.load_library('./ConcatOp/build/libconcat.so')


class DetectionPipeline(Pipeline):
    def __init__(self,
                 tfrecords,
                 tfrecords_idx,
                 batch_size,
                 num_workers,
                 device_id,
                 shard_id,
                 is_training=True):

        super(DetectionPipeline, self).__init__(batch_size, num_workers, device_id)

        self.is_training = is_training

        features = {
            'image/encoded': tfrecord.FixedLenFeature((), tfrecord.string, ''),
            # Object boxes and classes.
            'image/object/bbox/xmin': tfrecord.VarLenFeature(tfrecord.float32, 0.0),
            'image/object/bbox/ymin': tfrecord.VarLenFeature(tfrecord.float32, 0.0),
            'image/object/bbox/xmax': tfrecord.VarLenFeature(tfrecord.float32, 0.0),
            'image/object/bbox/ymax': tfrecord.VarLenFeature(tfrecord.float32, 0.0),
            'image/object/class/label': tfrecord.VarLenFeature(tfrecord.int64, -1),
        }

        self.input = ops.TFRecordReader(path=tfrecords,
                                        index_path=tfrecords_idx,
                                        features=features,
                                        shard_id=shard_id,
                                        num_shards=num_workers,
                                        random_shuffle=False)

        self.decode = ops.nvJPEGDecoder(device="mixed", output_type=types.RGB)
        self.concat = ops.Concat(device="cpu")
        self.cast_to_int32 = ops.Cast(device="cpu", dtype=types.INT32)

        self.paste = ops.Paste(device='gpu', fill_value=0.)
        self.bbox_paste = ops.BBoxPaste(device='cpu', ltrb=True)
        self.paste_ratio = ops.Uniform(range=[1.0, 4.0])
        self.paste_pos = ops.Uniform(range=[0.0, 1.0])

        # Augumentation techniques
        self.crop = ops.RandomBBoxCrop(
            device="cpu",
            aspect_ratio=[0.5, 2.0],
            thresholds=[0, 0.1, 0.3, 0.5, 0.7, 0.9],
            scaling=[0.3, 1.0],
            ltrb=True,
            allow_no_crop=True,
            num_attempts=10)

        self.slice = ops.Slice(device="gpu")

        self.resize = ops.Resize(
            device="gpu",
            resize_x=512,
            resize_y=512,
            min_filter=types.DALIInterpType.INTERP_TRIANGULAR)

    def define_graph(self):
        # Read images and labels
        inputs = self.input(name="Reader")
        images = inputs["image/encoded"]
        xmin = inputs["image/object/bbox/xmin"]
        ymin = inputs["image/object/bbox/ymin"]
        xmax = inputs["image/object/bbox/xmax"]
        ymax = inputs["image/object/bbox/ymax"]
        labels = inputs["image/object/class/label"]

        images = self.decode(images)
        boxes = self.concat(xmin, ymin, xmax, ymax)
        labels = self.cast_to_int32(labels)

        paste_ratio = self.paste_ratio()
        paste_pos_x = self.paste_pos()
        paste_pos_y = self.paste_pos()

        images = self.paste(images, ratio=paste_ratio, paste_x=paste_pos_x, paste_y=paste_pos_y)
        boxes = self.bbox_paste(boxes, ratio=paste_ratio, paste_x=paste_pos_x, paste_y=paste_pos_y)

        crop_begin, crop_size, boxes, labels = self.crop(boxes, labels)
        images = self.slice(images, crop_begin, crop_size)
        images = self.resize(images)

        return images.gpu(), boxes.gpu(), labels.gpu()

Trying to run it, I am getting an error:

DALI daliCreatePipeline(&pipe_handle_, serialized_pipeline.c_str(), serialized_pipeline.length(), batch_size, num_threads, device_id, prefetch_queue_depth_) failed: [/opt/dali/dali/pipeline/pipeline.cc:160] Assert on "it != edge_names_.end()" failed: Input 'contiguous_RandomBBoxCrop_id_9_output_0' to op 'Slice' is not known to the pipeline.

However, if I comment out the cropping/slicing code:

        crop_begin, crop_size, boxes, labels = self.crop(boxes, labels)
        images = self.slice(images, crop_begin, crop_size)

it works just fine.
I think this is due to the fact that RandomBBoxCrop is CPU op, and Slice is the GPU one.
If I move Slice to CPU, it understands the output from RandomBBoxCrop pretty well.

But how to couple the CPU RandomBBoxCrop and GPU Slice?

Thanks in advance.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingquestionFurther information is requested

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions