I would like to implement an image pipeline for various image data types. I am defining a Generator
class containing the build()
method describing the pipeline, a GeneratorParam<type>
to specify the data type parameter and an ImageParam
member to specify the input image. If I specify the type of the ImageParam
to be the GeneratorParam<Type>
that I have defined above, then no matter what type I specify when I execute the generator, the type of the input image is always the default type. If I copy the declaration of the ImageParam
inside the body of the build()
method, then it seems to be working fine. Is this the correct way to define a pipeline with an input image that can have different types?
Here is the class as I originally wrote it:
#include "Halide.h"
using namespace Halide;
class myGenerator : public Generator<myGenerator>
{
public:
// Image data type as a parameter of the generator; default: float
GeneratorParam<Type> datatype{"datatype", Float(32)};
// Input image to the pipeline
ImageParam input{datatype, 3, "input"}; // datatype=Float(32) always
// Pipeline
Func build()
{
// ...
}
};
If I compile the generator and run it to generate a pipeline for a datatype
different from the default:
$ ./myGenerator -f pipeline_uint8 -o . datatype=uint8
Then everything seems fine, but the pipeline crashes at runtime because the buffer that I pass to it is uint8, but it was expecting an image of type float (the default I have specified in the generator class):
Error: Input buffer input has type float32 but elem_size of the buffer passed in is 1 instead of 4
I have fixed the issue by copying the declaration of the ImageParam
inside the build()
block, but that seems a little bit dirty to me. Is there a better way? Here is the class now:
#include "Halide.h"
using namespace Halide;
class myGenerator : public Generator<myGenerator>
{
public:
// Image data type as a parameter of the generator; default: float
GeneratorParam<Type> datatype{"datatype", Float(32)};
// Input image to the pipeline
ImageParam input{datatype, 3, "input"};
// Pipeline
Func build()
{
// Copy declaration. This time, it picks up datatype
// as being the type inputted when executing the
// generator instead of using the default.
ImageParam input{datatype, 3, "input"};
// ...
}
};
Thanks.
It is indeed dirty. The current best known solution is reinitializing input with the correct type at the top of build, rather than shadowing it with another ImageParam with the same name:
Func build()
{
input = ImageParam{datatype, 3, "input"};
...
}