c++ Halide-जबकि लूप समकक्ष



opencv image-processing (1)

आप यह ध्यान देने योग्य हैं कि यह स्पष्ट नहीं है कि गतिशील रूप से समापन (कब) लूप को व्यक्त करने के लिए-अभी वे शुद्ध हॉलिडे में व्यक्त करना संभव नहीं हैं! यह भविष्य (अनिश्चित, दीर्घकालिक) में बदल सकता है, लेकिन इन्हें जोड़ने से Halide प्रोग्राम ट्यूरिंग-पूर्ण हो जाएगा; उनके बिना, हम हमेशा अपने लूप की सीमाओं का विश्लेषण कर सकते हैं, लेकिन हम उन्हें, हम थकावट की समस्या का सामना करेंगे।

वास्तव में इस तरह की चीज़ के लिए एक एस्केप हैच है, हालांकि: आप हाइड पाइपलाइन के अंदर से बाहरी कार्य (सी या कुछ और में लागू) कॉल कर सकते हैं। एक बाहरी फ़ंक्शन के लिए इंटरफ़ेस एक संकलित पाइपलाइन के इंटरफ़ेस के समान दिखता है (अंतिम बफर आउटपुट के साथ, यह स्केलर और बफर तर्क लेता है, और अगर नल बफ़र्स से बुलाया जाता है तो उसे सीमाओं के अनुसार इसकी इनपुट की सीमा की गणना करना चाहिए इसके उत्पादन का अनुरोध)। कुछ उदाहरणों के लिए extern_* परीक्षा कार्यक्रम देखें , जैसे, https://github.com/halide/Halide/blob/master/test/correctness/extern_stage.cpp । आपके कोड पर जल्दी से ग्लेंसिंग, मेरा मानना ​​है कि यह आपके पास पहले से मौजूद सी कोड का उपयोग करते हुए एक बाहरी चरण में आसानी से लागू होना चाहिए।

मैं Halide में Meijster दूरी परिवर्तन एल्गोरिथ्म को लागू करने की कोशिश कर रहा हूँ। मैंने पहले से ही इस कोड को सी ++ (ओपनसीवी) के द्वारा पुनः लिखा है और यह ठीक काम कर रहा है। इस एल्गोरिथम के बारे में पेपर यहाँ है अभी मेरे हलाइड कोड 50% पूर्ण है - पहला चरण ठीक काम कर रहा है, अब मुझे चरण 2 (लिंक कोड में 3 स्कैन) के साथ समस्या है जो (सरलीकृत) इस तरह दिखती है:

//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
}

क्या इस समय के लूप को बदलने के लिए कोई हलाइड-अनुकूल तरीका है? अभी एकमात्र उपाय है जो मैंने अभी तक आया है, इस तरह से (अभी तक परीक्षण नहीं हुआ):

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);
}

लेकिन यह काम करेगा, भले ही हलाइड स्थिति की जांच करने से पहले चयन के दोनों मूल्यों का मूल्यांकन करने की कोशिश करे और पुनर्यन करने से यह बहुत धीमा हो जाएगा

अगर Halide में लूप को लागू करने का कोई तरीका नहीं है, तो क्या आपके पास केवल Halide के अंदर के कुछ कोड का उपयोग करने का कोई तरीका है? कोई अन्य विचार?





halide