Я использую Генератор для создания библиотеки c stati для моего модуля Halide. Я сравниваю расписание по умолчанию, AutoScheduler и расписание GPU, использующее простую мозаику. У меня есть два входа одинакового размера («источник» и «ссылка») и один выход.
Все работает нормально, пока я не выполню вход с размерами менее 64x64. И для версий с автоматическим планированием, и для запланированных GPU эта ошибка возникает на входе 63x63:
Error: Output buffer output is accessed at -1, which is before the min (0) in dimension 0
.
По мере уменьшения размера ввода ошибочный индекс также уменьшается (например, 62x62 производит output is accessed at -2
, 61x61 производит -3
, et c.)
Я запутался, потому что я не получайте эту ошибку, используя расписание по умолчанию, но каким-то образом поступайте с запланированными версиями auto и GPU. Я не знаю, почему эта проблема возникает ниже размера 64x64. Кто-нибудь может помочь, пожалуйста? Как мне заставить его работать для любого размера ввода?
# include Halide.h
using namespace Halide;
class MyGenerator : public Halide::Generator<MyGenerator> {
public:
// Input parameters
Input <Buffer<uint8_t>> source{"src", 2};
Input <Buffer<uint8_t>> reference{"ref", 2};
Output <Buffer<uint8_t>> output{"output", 2};
Input<int> radius{"radius"};
void generate(){
src_clamped = BoundaryConditions::constant_exterior(source, 0);
ref_clamped = BoundaryConditions::constant_exterior(reference, 0);
/* snipped for brevity; this part just shows I'm using padding
and calculating output only at (x, y) */
output(x, y) = ... ;
}
void schedule() {
if (auto_schedule) {
source.dim(0).set_estimate(0, 3000);
source.dim(1).set_estimate(0, 4000);
reference.dim(0).set_estimate(0, 3000);
reference.dim(1).set_estimate(0, 4000);
radius.set_estimate(5);
output.set_estimate(x, 0, 3000);
output.set_estimate(y, 0, 4000);
} else {
Var xo("xo"), yo("yo"), xi("xi"), yi("yi");
if (get_target().has_gpu_feature()){
std::cout << "Using GPU schedule\n";
const int EXPECTED_RADIUS = 5;
int kernel_w = EXPECTED_RADIUS * 2 + 1;
output.gpu_tile(x, y, xo, yo, xi, yi, kernel_w, kernel_w);
} else {
std::cout << "Using CPU schedule\n";
}
}
}
private:
// create variables to index our location
Var x{"x"}, y{"y"}, dx{"dx"}, dy{"dy"};
};