DALI icon indicating copy to clipboard operation
DALI copied to clipboard

Could not serialize dali.fn.python_function

Open omair18 opened this issue 2 years ago • 6 comments

Describe the question.

I am trying to serialize a pipeline which uses dali.fn.python_function but I'm getting the following error.

RuntimeError: [/opt/dali/dali/pipeline/pipeline.cc:776] Assert on "spec.GetSchema().IsSerializable()" failed: Could not serialize the operator: DLTensorPythonFunctionImpl 

Here's my pipeline

def rectangular_pad(image, canvas, pad_x, pad_y):
        h, w, c = image.shape
        paste_x = int(pad_x/2)
        paste_y = int(pad_y/2)
        canvas[paste_y: paste_y + h, 
            paste_x: paste_x + w] = image
        return canvas
@dali.pipeline_def(batch_size=256, num_threads=4, device_id=0, exec_async=False, exec_pipelined=False)
def pipe():
    images = dali.fn.external_source(device="cpu", name="DALI_INPUT_0")
    images = dali.fn.decoders.image(images, device="cpu", output_type=types.BGR)
    orig_shape = dali.fn.shapes(images)
    orig_width = orig_shape[1]
    orig_height = orig_shape[0]

    scale_x = target_width / orig_width
    scale_y = target_height / orig_height
    scale_min = dali.math.min(left=scale_x, right=scale_y)

    new_width = orig_width * scale_min
    new_height = orig_height * scale_min

    pad_x = target_width - new_width
    pad_y = target_height - new_height
    resized_images = dali.fn.resize(images, resize_x=new_width, resize_y=new_height, 
                            dtype=types.FLOAT, interp_type=types.INTERP_LINEAR, antialias=False)
    canvas = dali.fn.constant(idata=128, shape=[target_height, target_width, 3])
    out_images = dali.fn.python_function(images, canvas, pad_x, pad_y, function=rectangular_pad, num_outputs=1, batch_processing=False)
        
    return out_images, images

Check for duplicates

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

omair18 avatar Sep 25 '23 16:09 omair18

Hi @omair18,

Thank you for reaching out. I'm sorry but by design python operator cannot be serialized as we cannot save the Python code and for now together with the test of the DALI pipeline representation. What you can do is use crop or slice operators with out_of_bounds_policy set.

JanuszL avatar Sep 25 '23 17:09 JanuszL

Hi @JanuszL ,

Thank you for your quick response. Can you guide me how to implement rectangular padding on images using dali.fn like I did using python_function ?

omair18 avatar Sep 25 '23 17:09 omair18

Hi @JanuszL . I have implemented rectangular padding via dali.fn.crop but if I try to use device="mixed" in dali.fn.decoders I'm getting

Named arguments inputs to operators must be CPU data nodes. However, a GPU data node was provided (op: 'Resize', input: '__ArithmeticGenericOp_9')

Can you please help?

omair18 avatar Sep 25 '23 18:09 omair18

Hi,

This is one of the DALI limitations, that data once lands on the GPU cannot be moved back. In this case please use peek image shape operator to obtain the image shape before the decoding:

@dali.pipeline_def(batch_size=256, num_threads=4, device_id=0, exec_async=False, exec_pipelined=False)
def pipe():
    images = dali.fn.external_source(device="cpu", name="DALI_INPUT_0")
    orig_shape = dali.fn.peek_image_shape(images)
    images = dali.fn.decoders.image(images, device="cpu", output_type=types.BGR)
    orig_width = orig_shape[1]
    orig_height = orig_shape[0]

JanuszL avatar Sep 25 '23 18:09 JanuszL

This doesn't really answer the original question which was that python function cannot be serialized. DALI support torch_python_function which is great, but cannot be serialized... Any help is welcome !

Vincouux avatar Jul 22 '24 13:07 Vincouux

Hi @Vincouux,

This doesn't really answer the original question which was that python function cannot be serialized.

As I mentioned by design Python operator cannot be serialized as we cannot save the Python code and I proposed a way to express the needed operations using the native DALI operators. The serialization of the Python code imposes multiple challenges and limitations we haven't figured out how to overcome yet. For now please try to express your flow using the DALI native operators.

JanuszL avatar Aug 05 '24 18:08 JanuszL