NDRange Nombre d’éléments de travail

J’essaie de copier une image en utilisant OpenCL:

std::ssortingng kernelCode = "void kernel copy(global const int* image, global int* result)" "{" "result[get_global_id(0)] = image[get_global_id(0)];" "}"; 

L’image contient 200 * 300 pixels.

Le nombre maximal d’éléments de travail est 4100 selon CL_DEVICE_MAX_WORK_GROUP_SIZE

Dans la queue:

 int size = _originalImage.width() * _originalImage.height(); //... queue.enqueueNDRangeKernel(imgProcess, cl::NullRange, cl::NDRange(size), cl::NullRange); 

Donne segfault.

 queue.enqueueNDRangeKernel(imgProcess, cl::NullRange, cl::NDRange(10000), cl::NullRange); 

Fonctionne bien, mais ne restitue qu’une partie de l’image.

Qu’est-ce que j’oublie ici?

Comme vous l’avez déjà indiqué correctement, votre CL_DEVICE_MAX_WORK_GROUP_SIZE est inférieur au nombre de threads que vous souhaitez démarrer. Le segfault indique une erreur dans le runtime. Vous pouvez obtenir des erreurs C ++ à partir d’OpenCL si vous ajoutez la définition suivante au début de votre fichier de code (avant d’inclure des en-têtes OpenCL).

 #define __CL_ENABLE_EXCEPTIONS 

La deuxième ligne de code ne copie clairement que les 10000 premiers pixels de votre image au lieu de la totalité des 60000. Si vous souhaitez utiliser uniquement 10 000 threads, vous devez effectuer cet appel six fois avec un décalage NDRange ajusté à chaque fois.

En général, je vous conseillerais soit d’utiliser cl :: copy pour copier une image, soit de modifier votre kernel pour copier plusieurs pixels par thread.

De plus, je ne suis pas sûr de l’effet de définir la taille du groupe de travail local sur NullRange. Comme la taille du groupe de travail local n’a pas d’importance dans votre cas, je pense qu’il est préférable de laisser ce paramètre de côté et d’utiliser la version de enqueueNDRangeKernel avec seulement 3 arguments (en omettant le dernier).