1
votes

OpenCL: comment éviter les fonctions scalaires / vectorielles dupliquées?

Les fonctions mathématiques intégrées d'OpenCL acceptent le gentype abstrait comme type d'argument, vous n'avez donc qu'un seul exp (x) ou log (x) et le compilateur bascule automatiquement vers le bon en fonction du type d'arguments réel lorsque vous les appelez.

J'ai besoin de programmer d'autres fonctions mathématiques qui effectueront un ensemble d'opérations algébriques de base comme (log (a / b) - c) / d (pas d'algèbre vectorielle verticale), mais parfois sur < code> float scalaires, parfois sur des vecteurs float4 . Existe-t-il un moyen propre de ne les coder qu'une seule fois et de faire basculer le compilateur de la même manière en fonction du type d'argument?

Alternativement, si j'écris uniquement le code scalaire float et que je boucle sur un float4 pour l'appliquer, le compilateur est-il capable de le vectoriser?


0 commentaires

3 Réponses :


1
votes

OpenCL est basé sur le langage de programmation C et je pense que le seul moyen d'éviter la duplication de code pour chaque type serait d'utiliser des macros de style C.

Une des façons de les utiliser serait d'avoir une macro pour le type, par exemple comme ceci:

#define vt(t,s) t##s
#define vector_type(t,s) vt(t,s)

typedef vector_type(float, VECTOR_SIZE) vfloat;

Et puis par exemple VECTOR_SIZE = 4 pourrait être passé au compilateur pour utiliser float4 . Mais cela ne fonctionnerait que pour les types de vecteurs. Pour utiliser si float ou float4 nécessite une macro légèrement différente.

Alternativement, si j'écris uniquement le code scalaire flottant et boucle sur un float4 pour l'appliquer, le compilateur est-il capable de le vectoriser?

Cela peut ou non, cela dépend de beaucoup de choses. De plus, les compilateurs OpenCL ne sont pas aussi avancés que par exemple gcc et peuvent ne pas générer de code vectorisé lorsque vous vous attendez à ce qu'ils le fassent. Le seul moyen de le savoir est d'essayer.


0 commentaires

0
votes

Utiliser uniquement une fonction scalaire et la dérouler sur chaque élément vectoriel si nécessaire ne semble produire aucun ralentissement, par rapport au chemin vectoriel complet, sur Intel Neo et Nvidia OpenCL, avec LLVM 10 et Clang 10 (je ne sais pas qui compile quoi ).

Il semblerait donc que le code scalaire soit correctement vectorisé en cas de besoin, et je n'ai pas besoin de maintenir manuellement un chemin vectorisé spécifique.


0 commentaires

0
votes

Vous pouvez utiliser "C ++ pour OpenCL" (qui n'est pas OpenCL C ++) et utiliser un modèle C ++ dans le code de votre noyau. La plupart des implémentations modernes basées sur LLVM le prennent en charge, mais vous devrez vérifier votre ou vos plates-formes spécifiques.


0 commentaires