Halogen cycle equivalent

I am trying to implement the Maidster distance conversion algorithm in Halide. I have already rewritten this code in C ++ (using openCV) and it works great. An article about this algorithm is here . Currently, my halide code is 50% complete - the first phase is working fine, now I have a problem with phase 2 (scan 3 in the linked code), which (simplified) look like this:

//g is 2 dimensional cv::Mat (something like array) - result of previous stage // m is g.width and n is g.height int(*functionF)(int x, int i, int g_i) = EDT_f; int(*functionSep)(int i, int u, int g_i, int g_u, int max_value) = EDT_Sep; cv::Mat dt = cv::Mat(n, m, CV_32SC1); int* s = new int[m]; int* t = new int[m]; int q = 0, w; for (int y = 0; y<n; y++) { q = 0; s[0] = 0; t[0] = 0; // Scan 3 for (int u = 1; u<m; u++) { //how can i replace this loop: while (q >= 0 && functionF(t[q], s[q], g.at<int>(y, s[q])) > functionF(t[q], u, g.at<int>(y, u))) q--; //some operations which might change value of q, s[] and t[] } // Scan 4 - not important here } 

Is there any halogen way to replace this cycle? Right now, the only solution I came up with looks like this (not yet tested):

 Expr calculateQ(Expr currentQValue, Expr y, Func t, Func s, Func g) { //while (q >= 0 && functionF(t[q], s[q], g.at<int>(y, s[q])) > functionF(t[q], u, g.at<int>(y, u))) //q--; return select(currentQValue >= 0 && functionF(t[q], s[q], g[s[q], y]) > functionF(t[q], u, g[u, y]), calculateQ(currentQValue - 1, y, t, s, g), currentQValue); } 

but even if this works, most likely the halogen will try to evaluate both select values ​​before checking the state, and recursion will make it very slow.

If there is no way to implement while loop in Halide, is there a way to use part of the code inside Halide? Any other ideas?

+5
source share
1 answer

You correctly noted that it is unclear how to express a dynamically terminating (while) loop - they cannot be expressed in pure halide right now! This may change into the (uncertain, long-term) future, but adding that this will make the Halide Turing-complete program cycle; without them, we can always analyze the boundaries of your cycles, but we, they, are faced with the problem of stopping.

There is an exit hatch for this kind of thing: you can call external functions (implemented in C or something else) from the Halide pipeline. The interface to the extern function looks like the interface to the compiled pipeline (it takes scalar and buffer arguments, the output being the final buffer, and if it is called with zero buffers, it must calculate the estimates required from its inputs taking into account the boundaries with the request for its output). Check out extern_* test programs for some examples, for example https://github.com/halide/Halide/blob/master/test/correctness/extern_stage.cpp . Having a quick look at your code, I believe that it should be easily implemented externally using the C code that you already have.

+3
source

Source: https://habr.com/ru/post/1234913/


All Articles