Besoin d'aide pour développement d'un rawKernel avec Python/Cupy
Bonjour à tous,
C'est mon 1er message sur le forum.
J'ai développé dans le cadre de mon travail un code de traitement d'hologrammes en C++/CUDA.
Comme mes collègues et étudiant de mon laboratoire ne sont pas à l'aise avec le C++, je recode toute mon application en Python + cupy.
Je m'en sort plutôt bien sauf dans un cas particulier: celui où je dois faire du calcul complex dans un raw kernel.
Voici mon raw kernel ainsi que la fonction qui l'appel et après voici mon code d'erreur (j'ai souligné la ligne qui provoque mon erreur):
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
@jit.rawkernel()
def clean_plan_cplx_device(d_plan_cplx, size_x, size_y, posX, posY, clean_radius_pix, replace_cplx_value):
index = jit.blockIdx.x * jit.blockDim.x + jit.threadIdx.x
sizeXY = size_x * size_y
jj = cp.int32(index) // cp.int32(size_x)
ii = cp.int32(index) - cp.int32(jj * size_x)
if (ii < size_x and jj < size_y):
#calcul distance
distance = cp.sqrt((posX - ii)**2 + (posY - jj)**2)
cplx = cp.complex64(d_plan_cplx[ii, jj])
mod = cp.sqrt(cp.real(cplx)**2 + cp.imag(cplx)**2)
if (distance < clean_radius_pix):
d_plan_cplx[ii, jj] = 0.0+0j
else:
d_plan_cplx[ii, jj] = mod + 0j
def clean_plan_cplx(d_plan_cplx, size_x, size_y, posX, posY, clean_radius_pix, replace_value):
nthread = 1024
nBlock = math.ceil(size_x * size_y // nthread)
clean_plan_cplx_device[nBlock, nthread](d_plan_cplx, size_x, size_y, posX, posY, clean_radius_pix, replace_value) |
d_plan_cplx est un cupy ndarray de complex64 2 dimensions
En fait je ne sais pas comment accéder à la partie imaginaire et réelle des valeurs.
Pourtant cela marche bien de cette façon en dehors de mon rawkernel.
Y aurait-il quelqu'un qui saurait m'aider?
Merci d'avance
Simon Becker
Précision de la question avec autre exemple
Rebonjour,
Je dépoussière mon message précédent en donnant un autre exemple où je n'arrive pas à accéder à la partie réelle de mon tableau cupy, puisque personnes n'a réussit à m'aider où s'est intérressé au problème.
Notez que c'est un exemple. Je sais qu'il est possible de passer par un autre moyen que par le décorateur @jit.rawkernel(), mais c'est important pour moi de réussir à le faire.
j'ai tout essayé:
r = cp.real(cplx)
r = cplx.real
r = cplx.real()
r = cp.real(d_plan_complex[ii, jj])
r = cp.real(d_plan_complex)[ii, jj]
rien ne marche
Notez que bizarrement chatGpt me dit que mon code doit marcher alors que ce n'est pas le cas.
Enfin, c'est plutôt une bonne nouvelle selon moi si chatGpt dit encore quelques bêtises ;)
Merci pour votre aide
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
import cupy as cp
import numpy as np
from cupyx import jit
@jit.rawkernel()
def d_calc_phase(d_plan_complex, d_phase, size_x, size_y):
index = jit.blockIdx.x * jit.blockDim.x + jit.threadIdx.x
sizeXY = size_x * size_y
jj = index // size_x
ii = index - jj * size_x
if (ii < size_x and jj < size_y):
cplx = d_plan_complex[ii, jj]
r = cp.real(cplx)
if (r == 0.0):
d_phase[ii, jj] = 0.0
elif(r > 0.0):
d_phase[ii, jj] = cp.arctan(cp.imag(cplx) / cp.real(cplx))
else:
d_phase[ii, jj] = cp.pi + cp.arctan(cp.imag(cplx) / cp.real(cplx))
if __name__ == '__main__':
# Définir les dimensions de la matrice
size_x = 10
size_y = 10
# Initialiser la matrice d_plan_complex avec des nombres complexes aléatoires
d_plan_complex = cp.random.rand(size_x, size_y) + 1j * cp.random.rand(size_x, size_y)
# Initialiser la matrice d_phase avec des zéros
d_phase = cp.zeros((size_x, size_y))
# Définir la taille des blocs et des grilles pour la fonction CUDA
block_size = 128
grid_size = (size_x * size_y + block_size - 1) // block_size
# Appeler la fonction CUDA pour calculer la phase
d_calc_phase[grid_size, block_size](d_plan_complex, d_phase, size_x, size_y)
# Afficher la matrice d_phase
print(d_phase) |