Could not serialize dali.fn.python_function
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
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.
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 ?
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?
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]
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 !
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.