2013-07-27 2 views
0

Je suis en train d'écrire un noyau openCL pour effectuer une IA à force brute pour un jeu de réflexion, mais j'ai un problème avec mon code noyau et/ou la fonction auxiliaire qu'il appelle. Voici mon code de noyau (je suis sûr que les entrées sont passées correctement ici): 60 est la taille de travail globale définie par clEnqueueNDRangeKernel.auxiliaire openCL L'appel de fonction ne fonctionne pas

Les entrées du noyau sont les suivantes:

Est devenu char * en // entrée factice à des fins de test

Est devenu char * de board_in, // un grand tableau de caractères contenant 60 planches

int * recherche Est devenu, // un tableau j'utiliser pour obtenir rapidement le score de notation se déplace

Sorties:

char * out Est devenu, // sortie factice pour tester

int * score_out Est devenu, // un tableau de 60 scores: un pour chaque conseil

int * row_out Est devenu, // un tableau de 60 lignes: une pour chaque conseil évalué

int * col_out Est devenu // un tableau de 60 Col.: ...

__kernel void helloworld(__global char* in, 
        __global char* board_in, 
        __global int* lookup, 
        __global char* out, 
        __global int * score_out, 
        __global int * row_out, 
        __global int * col_out) 
{ 

    int num = get_global_id(0); 
    char workingBoard[72]; 
    int scoreMat[64]; 
//set up the array for each thread to use 
    for(int k=0; k< 72; k++) 
    { 
     workingBoard[k] = board_in[num*BOARDSIZE+k]; 
    } 
// Make a copy of the score matrix for each thread to use 
    for(int j=0; j<64; j++) 
    { 
     scoreMat[j] = lookup[j]; 
    } 
    int s=0; 
    int r=0; 
    int c=0; 
    findBestMove(workingBoard,scoreMat,&s,1,&r,&c); 
    col_out[num] = ????????? 
    score_out[num] = ??????????? 
    row_out[num] = ??????????????? 
} 

La fonction findBestMove fonctionne comme ceci (son assez bien testé. Je l'ai utilisé dans une implémentation de CPU pendant un moment): Il prend un tableau (tableau de char), un tableau de recherche de score, un pointeur vers ce que le mouvement marque, la profondeur actuelle et un pointeur vers la ligne et la colonne . Il est censé définir le score, la ligne et la colonne. Il appelle d'autres fonctions que je définis dans le même document.

Si je lance cet extrait de code sur la CPU, je reçois la sortie correcte:

// workerBoard and lookuparr are set previous to this to be the same as what 
//the kernel thread is supposed to have 
int s=0; 
int r=0; 
int c=0; 
findBestMove(workerBoard,lookuparr,&s,1,&r,&c); 
cout<<s<<","<<r<<","<<c<<endl; 

Quand je lance mon code du noyau, je ne fais pas passé l'appel de fonction. La fonction est définie dans le même document que le noyau et n'utilise pas de mémoire dynamique, de pointeurs de fonction, de récursion ou de mémoire globale (en dehors des arguments du noyau). J'utilise certaines déclarations #define.

Je veux définir le ???? sections de mon noyau pour être r, c et s, mais comme mentionné, je ne comprends pas. Est-ce que je fais des erreurs critiques (note: le noyau passe mon vérificateur de code et l'analyseur de noyau d'AMD). En outre, je suis assez nouveau pour openCL, donc tous les conseils sont les bienvenus. Si je peux fournir plus d'informations pour aider à répondre à cette question, faites le moi savoir!

+0

Pourriez-vous également poster le code de votre fonction'findBestMove'? – CaptainObvious

+0

Il plus les autres fonctions qu'il utilise est d'environ 500 lignes. Cela pourrait aider, mais je ne suis pas sûr si coller autant de code ici est utile. – user2503981

+0

OK, alors qu'est-ce que cela signifie "Je ne le fais pas passé l'appel de la fonction"? Avez-vous une erreur qui est retournée? Si oui, quel est le numéro d'erreur? Si ce n'est pas le cas, que se passe-t-il? – CaptainObvious

Répondre

0

Basé sur vos commentaires Il semble que le problème soit quelque part dans votre fonction findBestMove. BTW si vous aviez une boucle infinie, dans un point le chien de garde se déclencherait et le plus probablement votre conducteur se bloquerait avec un écran noir ou gelé. Donc je vous suggère de commenter tout votre code dans votre fonction et d'attribuer aux variables r, s, c une valeur choisie comme l'identifiant de travail qui a manipulé ces variables spécifiques en utilisant la fonction get_global_id. Bien sûr, en remplaçant le ??? avec:

col_out[num] = c; 
    score_out[num] = s; 
    row_out[num] = r; 

Si vous obtenez la bonne valeur, commencez à déboguer votre fonction, vous saurez avec certitude que votre problème est dans la fonction.Comme vous avez demandé quelques conseils ici, c'est celui qui, je pense, va améliorer les performances (une fois que vous avez corrigé votre bug :)): au lieu d'utiliser la mémoire privée pour votre tableau scoreMat utiliser la mémoire locale. Vous éviterez ainsi que chaque thread accède aux mêmes données dans la mémoire globale à plusieurs reprises (ce qui est lent). Pour extraire les données de la mémoire globale vers la mémoire locale, vous pouvez utiliser la fonction async_work_group_copy.

Donc, dans votre cas, vous auriez quelque chose comme ceci:

local int scoreMat[64]; 
event_t ev = async_work_group_copy(lookup, scoreMat, 64, 0); 
// Wait to make sure everything is copied 
wait_group_events (1, &ev); 

Vous devrez peut-être changer un peu plus de code pour prendre en compte que vous utilisez la mémoire locale maintenant. Fondamentalement, il fonctionne de la même manière que le global (du point de vue de l'accès) mais il est beaucoup plus rapide. Notez que la différence avec ce que vous avez est qu'une seule copie sera faite pas 60 (le nombre de postes de travail). En outre, cette fois, les données que vous avez extraites de sont accessibles à partir de tous les work items d'un groupe de travail. Avant chaque travail avait sa propre copie. Il est également important de souligner le fait qu'il est dans un groupe de travail. Mais puisque vous n'utilisez que 60 work items, vous n'avez probablement qu'un seul groupe de travail.

Questions connexes