2011-06-14 2 views
4

Je veux définir une fonction dans une fonction de noyau pour faire mon code d'indexation plus claire:Comment déclarer une fonction dans une fonction noyau dans OpenCL?

kernel void do_something (const int some_offset, 
          const int other_offset, 
          global float* buffer) 
{ 
    int index(int x, int y) 
    { 
     return some_offset+other_offset*x+y; 
    } 

    float value = buffer[index(1,2)]; 
    ... 
} 

Sinon, je dois déclarer la fonction d'index en dehors de mon noyau et l'index comme

float value = buffer[index(1,2,some_offset,other_offset)]; 

ce qui le rendrait plus laid etc. Y at-il un moyen de le faire? Le compilateur me donne une erreur, en disant:

OpenCL Compile Error: clBuildProgram failed (CL_BUILD_PROGRAM_FAILURE). 
Line 5: error: expected a ";" 

Est-il possible de faire ce que je veux ou est-il une autre façon d'obtenir le même? Merci!

+1

C ne possède aucune sorte de fermeture. Je suppose que OpenCL non plus, mais puisque c'est (à l'origine) une chose Apple, vérifiez si vous pouvez utiliser [blocks] (http://en.wikipedia.org/wiki/Blocks_%28C_language_extension%29). A défaut, dans ce cas, il semble que vous puissiez * utiliser * une macro, puisque votre 'some_offset' reste dans la portée. –

Répondre

5

C ne prend pas en charge les fonctions imbriquées. Cependant, votre cas est assez simple à mettre en œuvre avec une macro:

#define index(x,y) some_offset+other_offset*(x)+(y) 

Les parenthèses autour de x et y sont cruciales pour faire de la macro faire ce que vous voulez si vous passez des expressions plus complexes, par exemple, index(a+b,c).

+0

Ça a l'air génial. Dois-je définir la macro dans la fonction noyau ou est-ce que cela ne me dérange pas? –

+1

En C, le pré-traitement est une phase de compilation séparée qui se produit avant la compilation. Vous pouvez donc le définir n'importe où avant la première utilisation. (Peut-être que OpenCL a plus de restrictions.) – zvrba

+3

Vous devriez également mettre les parens autour de l'expression entière: '(some_offset + other_offset * (x) + (y))'. Sinon 'index (x, y) * 2' fait quelque chose de surprenant. –

Questions connexes