在具有相同输入/输出缓冲区

时间:2017-05-15 23:29:40

标签: halide

使用下面的代码,我注意到同一输入有一些意想不到的差异。有时,while循环执行不同的迭代次数,即使使用相同的代码和输入数据也是如此。我在调试CPU和GPU时遇到了同样的问题。

int main() {

    int dx, dy;
    Buffer<uint8_t> output;
    Buffer<int> count = Buffer<int>::make_scalar();
    ImageParam param(UInt(8), 2);

    update_func = build_hysteresis_update(param);
    count_func = build_hysteresis_count(param);

    output = ini_func.realize(dx, dy); // ini_func always returns the same output.
    do {

        param.set(output);
        update_func.realize(output); // --> same input/output. I use this way because performance get really better.

        param.set(output);
        count_func.realize(count);

    } while (count(0) > 0); // --> Different quantities of iterations happens here.

}

Func build_hysteresis_update(ImageParam input) {

    RDom rh(-1, 3, -1, 3);
    Func inb, update;
    Var x, y;

    inb = BoundaryConditions::repeat_edge(input);

    update(x, y) = cast<uint8_t>(select(inb(x, y) == 1 && sum(cast<uint16_t>(inb(x+rh.x, y+rh.y))) > 9, 254, inb(x, y) == 254, 255, inb(x, y)));

    Var xi, yi;
    update.tile(x, y, xi, yi, 32, 8).parallel(y).vectorize(xi, 8);

    return update;
}

Func build_hysteresis_count(ImageParam input) {

    RDom rc(0, input.width(), 0, input.height());
    Func count;

    count() = sum(select(input(rc.x, rc.y) == 254, 1, 0));

    return count;
}

我尝试过这些解决方案,但是性能不是很好。有没有更好的方法来避免这个问题(这似乎是一个竞争条件问题)保持第一个表现?我也试图使用“device_sync”而没有成功解决问题。

// Solution 1:
Func build_hysteresis_update(ImageParam input) {
    ...
    // Adding "aux" and replace "inb" inside "update" func.
    aux(x, y) = inb(x, y);
    update(x, y) = cast<uint8_t>(select(aux(x, y) == 1 && sum(cast<uint16_t>(aux(x+rh.x, y+rh.y))) > 9, 254, aux(x, y) == 254, 255, aux(x, y)));
    ...
    // Also adding scheduling "compute_root" for "aux" func.
    aux.compute_root();
    ...
}

// Solution 2:
int main() {
    ...
    do {
        // Don't pass the allocated "output" to the "realize" method.
        param.set(output);
        output = func_update.realize(dx, dy);
        ...
    } while (count(0) > 0);
    ...
}

1 个答案:

答案 0 :(得分:0)

虽然存在竞争条件,但这不是真正的问题。您正在做一个小模糊,如果输入和输出是相同的缓冲区,则具有非常不同的含义。模糊就地需要不同类型的算法。一种解决方案是双缓冲:

do {
    param.set(output1);
    func_update.realize(output2);
    param.set(output2);
    func_update.realize(output1);
    ...
} while (count(0) > 0);