c++ - while - yolo opencv



Halide-tandis que l'équivalent de boucle (1)

Vous avez raison de noter qu'il n'est pas évident d'exprimer une boucle (while) à terminaison dynamique - il n'est pas possible d'exprimer en halogénure pure en ce moment! Cela peut changer dans le futur (indéfini, à long terme), mais l'ajout de ceux-ci ferait en boucle des programmes Halide Turing-complet; sans eux, nous pouvons toujours analyser les limites de vos boucles, mais nous, nous serions confrontés au problème de l'arrêt.

Cependant, il existe une échappatoire pour ce genre de chose: vous pouvez appeler des fonctions externes (implémentées en C ou n'importe quoi d'autre) depuis un pipeline Halide. L'interface à une fonction externe ressemble à l'interface d'un pipeline compilé (elle prend des arguments scalaires et tampons, le tampon final étant la sortie, et si elle est appelée avec des tampons NULL, elle doit calculer les limites requises de ses entrées étant donné les limites demandé de sa sortie). Consultez les programmes de test extern_* pour des exemples, par exemple, https://github.com/halide/Halide/blob/master/test/correctness/extern_stage.cpp . Jetant rapidement un coup d'œil sur votre code, je crois qu'il devrait être facilement applicable dans une étape externe en utilisant le code C que vous avez déjà.

J'essaye d'implémenter l'algorithme de transformation de distance de Meijster dans Halide. J'ai déjà réécrit ce code en C ++ (en utilisant openCV) et ça marche bien. Le papier sur cet algorithme est ici . En ce moment mon code aux halogénures est terminé à 50% - la première phase fonctionne bien, maintenant j'ai un problème avec la phase 2 (scan 3 dans le code lié) qui (simplifié) ressemble à ceci:

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

Existe-t-il un moyen convivial pour remplacer les halogénures ? En ce moment, la seule solution que j'ai trouvée jusqu'ici est quelque chose comme ça (pas encore testé):

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

mais même si cela fonctionne, la plupart des halogénures tenteront d'évaluer les deux valeurs de select avant de vérifier la condition et la récursivité la rendra très lente.

S'il n'y a aucun moyen d'implémenter la boucle en Halide, est-il possible d'utiliser une partie de votre code dans Halide? D'autres idées?





halide