我正在尝试使用Metal作为我在iOS上使用的提前(AOT)Halide管道的目标。
我已经成功创建了一个使用Metal生成静态二进制文件的Halide生成器。我可以在我的iOS应用程序中链接并调用此二进制文件。
然而,当我将Buffer<uint8_t> input_
传递给函数时,Buffer
中的数据在GPU端似乎总是为零。请注意,这仅在iOS上的GPU上运行时才会发生。
发电机
#include "Halide.h"
using namespace Halide;
class MyHalideTest : public Halide::Generator<MyHalideTest> {
public:
Input<Buffer<uint8_t>> input{"input", 3};
Input<int32_t> width{"width"};
Input<int32_t> height{"height"};
Output<Buffer<uint8_t>> output{"output", 3};
void generate() {
output(x,y,c) = cast<uint8_t>(input(x,y,c)+25);
}
void schedule() {
input
.dim(0).set_stride(4)
.dim(2).set_stride(1).set_bounds(0, 4);
output
.dim(0).set_stride(4)
.dim(2).set_stride(1).set_bounds(0, 4);
if (get_target().has_gpu_feature()) {
output
.reorder(c, x, y)
.bound(c, 0, 4)
.unroll(c);
output.gpu_tile(x, y, xo, yo, xi, yi, 16, 16);
}
else {
output
.reorder(c, x, y)
.unroll(c)
.split(y, yo, yi, 16)
.parallel(yo)
.vectorize(x, 8);
}
}
private:
Var x{"x"}, y{"y"}, c{"c"}, xi{"xi"}, xo{"xo"}, yi{"yi"}, yo{"yo"};
};
HALIDE_REGISTER_GENERATOR(MyHalideTest, "halide_test")
生成生成器的命令行
./MyHalideTest_generator -g halide_test \
-f halide_test_ARM64_metal \
-n halide_test_ARM64_metal \
-o "${DERIVED_FILE_DIR}" \
target=arm-64-ios-metal-debug-user_context
iOS代码调用Halide功能
Buffer<uint8_t> input_;
Buffer<uint8_t> output_;
// Other setup
- (void)initBuffersWithWidth:(int)w height:(int)h using_metal:(bool)using_metal
{
// We really only need to pad this for the use_metal case,
// but it doesn't really hurt to always do it.
const int c = 4;
const int pad_pixels = (64 / sizeof(int32_t));
const int row_stride = (w + pad_pixels - 1) & ~(pad_pixels - 1);
const halide_dimension_t pixelBufShape[] = {
{0, w, c},
{0, h, c * row_stride},
{0, c, 1}
};
input_ = Buffer<uint8_t>(nullptr, 3, pixelBufShape);
input_.allocate();
auto buf = input_.raw_buffer()->host;
memset(buf, 200, input_.size_in_bytes());
// This allows us to make a Buffer with an arbitrary shape
// and memory managed by Buffer itself
output_ = Buffer<uint8_t>(nullptr, 3, pixelBufShape);
output_.allocate();
}
...
/** Calling Halide function here **/
halide_test((__bridge void *)self, input_, width, height, output_);
output_.copy_to_host();
// Display output image...
因此,代码将input_
缓冲区设置为值200.返回的output_
缓冲区应为225,但事实并非如此。所有值都只有25。
我应该注意,当我的笔记本电脑的GPU和手机的CPU上运行时,它正常 。唯一的区别是Halide生成器target
。
运行Halide函数时,Input<Buffer<uint8_t>> input
为什么似乎设置为全零的任何想法?
调试语句似乎是设备端的malloc内存,但我没有看到halide_copy_to_device
的明确声明。
答案 0 :(得分:3)
如果您在Buffer
中设置值,则需要将其标记为脏:input_.set_host_dirty()