mf=cl.mem_flags#specifie comment la mémoire doit être gérée et utilisée
#print(mf.to_string(1))
a_g=cl.Buffer(ctx,mf.READ_ONLY|mf.COPY_HOST_PTR,hostbuf=a_np)#espace de mémoire temporaire. Ce sera une allocation de mémoire sur un periph (gpu) pour stocker les données qui seront utilisées dans des calculs parallèles
knl=prg.sum# Use this Kernel object for repeated calls
knl(queue,a_np.shape,None,a_g,b_g,res_g)
res_g=cl.Buffer(ctx,mf.WRITE_ONLY,a_np.nbytes)#Crée un buffer dans le contexte allouant de la mémoire sur le gpu pour stocker les resultats du calcul. Comme "WRITE-ONLY", il est destiné à stocker les données de sortie du noyau OpenCl
knl=prg.sum#On defini knl afin d'appeler le noyau sum du programme qu'on a créé précédement
knl(queue,a_np.shape,None,a_g,b_g,res_g)#execute le noyau sum sur le GPU à l'aide de la queue
res_np=np.empty_like(a_np)
cl.enqueue_copy(queue,res_np,res_g)
res_np=np.empty_like(a_np)#Crée un tableau numpy de même dimension que a_np mais vide afin de stocker les résultats du calcul
cl.enqueue_copy(queue,res_np,res_g)#Copie les données depuis le buffer sur le petipherique (GPU) vers le tableau res_np
# Check on CPU with Numpy:
print(res_np-(a_np+b_np))
print(np.linalg.norm(res_np-(a_np+b_np)))
assertnp.allclose(res_np,a_np+b_np)
print(res_np-(a_np+b_np))#Permet de voir si les donées ont été exportées correctement dans le tableau res_np en checkant la difference entre le tableau et les deux variables du départ. Ca doit etre egal à 0.
print(np.linalg.norm(res_np-(a_np+b_np)))#Calcul la norme L2 de la difference entre res_np et (a_np + b_np). Si les deux vecteurs sont identique, ça devrait etre egal à 0. Ca nous donne une mesure de l'erreur entre les resultats du noyau OpenCl et les resultats attendus
assertnp.allclose(res_np,a_np+b_np)#Compare les tableaux et verifie s'ils sont suffisament proches les uns des autres. S'ils le sont, le programme tourne normalement sinon, l'assertion renvoie un message d'echec.