/ / Comment corriger correctement les résultats de la mémoire locale à la mémoire globale dans OpenCL - opencl, réduire

Comment corriger correctement les résultats de la mémoire locale à la mémoire globale dans OpenCL - opencl, réduire

J'ai un noyau OpenCL dans lequel chaque groupe de travail produit un vecteur de résultats en mémoire locale. Je dois ensuite faire la somme de tous ces résultats dans la mémoire globale pour une récupération ultérieure sur l'hôte.
Pour tester cela, j'ai créé le code de noyau suivant:

//1st thread in each workgroup initializes local buffer
if(get_local_id(0) == 0){
for(i=0; i<HYD_DIM; i++){
pressure_Local[i] = (float2){1.0f, 0.0f};
}
}

//wait for all workgroups to finish accessing any memory
barrier(CLK_GLOBAL_MEM_FENCE | CLK_LOCAL_MEM_FENCE);

/// sum all the results into global storage
for(i=0; i<get_num_groups(0); i++){

//1st thread in each workgroup writes the group"s local buffer to global memory
if(i == get_group_id(0) && get_local_id(0) == 0){
for(j=0; j<HYD_DIM; j++){
pressure_Global[j] += pressure_Local[j];
// barrier(CLK_GLOBAL_MEM_FENCE);
}
}

//flush global memory buffers:
barrier(CLK_GLOBAL_MEM_FENCE);
}

En substance, je m'attendais à tous les éléments de lavecteur dans la mémoire globale soit égal au nombre de groupes de travail (128 dans mon cas). En réalité, ils varient généralement entre 60 et 70, et les résultats changent d’une course à l’autre.
Quelqu'un peut-il me dire ce qui me manque ou comment le faire correctement?

Réponses:

2 pour la réponse № 1

Vous ne pouvez pas "synchroniser entre différents travauxgroupes avec opencl. CLK_GLOBAL_MEM_FENCE ne fonctionne pas de cette façon. Cela garantit uniquement que l'ordre des opérations de la mémoire (auquel le groupe de travail a accès) sera maintenu. Voir la section "6.12.8 Fonctions de synchronisation" du OCL 1.2 spec.

Je voudrais résoudre votre problème en utilisant un autrebloc de mémoire globale pour chaque groupe de travail. Vous écrivez les données dans global et votre noyau est terminé. Ensuite, si vous souhaitez réduire les données à un seul bloc, vous pouvez faire en sorte qu'un autre noyau lise les données de Global et les fusionne avec les autres blocs de résultats. Vous pouvez créer autant de couches de fusion que vous le souhaitez, mais la fusion finale doit être effectuée par un seul groupe de travail.

Rechercher autour des algorithmes de réduction gpu / opencl. Voici un bon début. Étude de cas: Réductions simples