Passing buffer as function arguments fails with: Eerror: cannot convert ‘Halide::Buffer<unsigned char, 2>’ to ‘halide_buffer_t*’
#8188
-
Hello, Thanks for this wonderful repo - it's a pleasure to work with it. I am trying to write a simple example which sums two values of an input buffer to an output buffer with twice the size. The example fails to compile with the error: /home/fabian/Documents/work/github/Halide/apps/resize_android/resize.cpp: In function ‘int main()’:
/home/fabian/Documents/work/github/Halide/apps/resize_android/resize.cpp:20:19: error: cannot convert ‘Halide::Buffer<unsigned char, 2>’ to ‘halide_buffer_t*’
20 | halide_resize(input, output);
| ^~~~~
| |
| Halide::Buffer<unsigned char, 2>
In file included from /home/fasc6540/Documents/work/github/Halide/apps/resize_android/resize.cpp:2:
/home/fabian/Documents/work/github/Halide/apps/resize_android/build_linux/halide_resize.h:44:43: note: initializing argument 1 of ‘int halide_resize(halide_buffer_t*, halide_buffer_t*)’
44 | int halide_resize(struct halide_buffer_t *_input_buffer, struct halide_buffer_t *_output_buffer);
| ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
make[2]: *** [CMakeFiles/resize.dir/build.make:76: CMakeFiles/resize.dir/resize.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:224: CMakeFiles/resize.dir/all] Error 2
make: *** [Makefile:101: all] Error 2 Why could that be? Consider the following main function: #include "Halide.h"
#include "halide_resize.h"
using namespace Halide;
int main() {
constexpr size_t width = 10;
constexpr size_t height = 10;
Buffer<uint8_t, 2> input(width, height);
for (int y = 0; y < input.height(); y++) {
for (int x = 0; x < input.width(); x++) {
input(x, y) = rand() & 0xfff;
}
}
constexpr int out_width = 2* 10;
constexpr int out_height =2 * 10;
Buffer<uint8_t, 2> output(out_height, out_width);
halide_resize(input, output);
} and the following generator: #include "Halide.h"
using namespace Halide;
class HalideResize : public Halide::Generator<HalideResize> {
public:
Input<Buffer<uint8_t, 2>> input{"input"};
Output<Buffer<uint8_t, 2>> output{"output"};
Var x{"x"};
Var y{"y"};
Var c{"c"};
Func intermediate{"intermediate"};
void generate() {
intermediate(x, y) = Halide::ConciseCasts::u16_sat(
input(x / 2, y / 2) + input(x / 2 + 1, y / 2 + 1));
output(x, y) = saturating_cast(input.type(), intermediate(x, y));
}
};
HALIDE_REGISTER_GENERATOR(HalideResize, halide_resize); and the cmake file is:
Apart from fixing the compilation error, I am trying to understand how the indices (x,y) get defined and how they handle the fact that the output size is twice the input size. I assume they get defined by backward-induction? The last usage of (x,y) is |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
If you're using Halide as an AOT compiler, the file with the main function shouldn't be including Halide.h - that's the compiler, which you probably don't want to deploy in your app (unless you're using it as a JIT compiler). Instead of Halide.h, include HalideRuntime.h and HalideBuffer.h, and use a Halide::Runtime::Buffer instead of a Halide::Buffer. Yes, the regions computed (and thus the range of the index values) get defined by starting from the size of the output buffer, which gives the size of the output Func. The compiler then works its way back up the pipeline, for each Func asking the question "to compute some region of this Func, how much of its input Funcs do I need?". This is a sort of reverse (demand-driven) shape inference. |
Beta Was this translation helpful? Give feedback.
If you're using Halide as an AOT compiler, the file with the main function shouldn't be including Halide.h - that's the compiler, which you probably don't want to deploy in your app (unless you're using it as a JIT compiler). Instead of Halide.h, include HalideRuntime.h and HalideBuffer.h, and use a Halide::Runtime::Buffer instead of a Halide::Buffer.
Yes, the regions computed (and thus the range of the index values) get defined by starting from the size of the output buffer, which gives the size of the output Func. The compiler then works its way back up the pipeline, for each Func asking the question "to compute some region of this Func, how much of its input Funcs do I need?". This is …