gpuArray related memory issue
Mostrar comentarios más antiguos
Hello, i am trying to do some calculations on the GPU but unfortunately possibly due to size of matrix (1010x1010x1601) I get GPU memory run out error (4gb Nvidia), and without GPU this calculation takes days. Is there any way to modify gpuArray for separate it subArrays to overcome this memory problem?
Thank you for your assistance.
function proj2d = projection(data3d,param, iview)
angle_rad = param.deg(iview)/360*2*pi;
proj2d = (zeros(param.nu,param.nv,'single'));
[uu,vv] = meshgrid(param.us,param.vs);
[xx,yy] = meshgrid(param.xs,param.ys);
if param.gpu == 1
data3d = gpuArray(single(data3d));
rx = gpuArray(((xx.*cos(angle_rad) - yy.*sin(angle_rad)) - xx(1,1))/param.dx + 1);
ry = gpuArray(((xx.*sin(angle_rad) + yy.*cos(angle_rad)) - yy(1,1))/param.dy + 1);
else
rx = (((xx.*cos(angle_rad) - yy.*sin(angle_rad)) - xx(1,1))/param.dx + 1);
ry = (((xx.*sin(angle_rad) + yy.*cos(angle_rad)) - yy(1,1))/param.dy + 1);
end
for iz = 1:param.nz
data3d(:,:,iz) = interp2(data3d(:,:,iz),rx,ry, param.interptype);
end
data3d(isnan(data3d))=0;
data3d = permute(data3d,[1 3 2]);
[xx,zz] = meshgrid(param.xs,param.zs);
for iy = 1:param.ny
Ratio = (param.ys(iy)+param.DSO)/(param.DSD);
pu = uu*Ratio;
pv = vv*Ratio;
pu = (pu - xx(1,1))/(param.dx)+1;
pv = (pv - zz(1,1))/(param.dz)+1;
if param.gpu == 1
tmp = gather(interp2(gpuArray(single(data3d(:,:,iy))),gpuArray(single(pv)),gpuArray(single(pu)),param.interptype));
else
tmp = (interp2((single(data3d(:,:,iy))),(single(pv)),(single(pu)),param.interptype));
end
tmp(isnan(tmp))=0;
proj2d = proj2d + tmp';
end
dist = sqrt((param.DSD)^2 + uu.^2 + vv.^2)./(param.DSD)*param.dy;
proj2d = proj2d .* dist';
1 comentario
Joss Knight
el 20 de Feb. de 2017
It looks to me like a single call to interpn is what you need, not multiple calls to interp2 with a permute in the middle. And your second loop is summing over the y-axis, so why not use sum?
Respuestas (1)
Joss Knight
el 20 de Feb. de 2017
1 voto
Your first chunk of operations are element-wise, so you can divide the arrays up however you like (perhaps along the z-axis?) and process it in chunks, gathering each result to free up GPU memory.
Your two loops are over the 3rd dimension of your data, so you could move each slice of data to the GPU, process it, and gather it back.
4 comentarios
Emre Topal
el 21 de Feb. de 2017
Joss Knight
el 21 de Feb. de 2017
Well, I mean, just don't put data3d on the GPU and then go
for iz = 1:param.nz
slice = gpuArray(data3d(:,:,iz));
data3d(:,:,iz) = gather(interp2(slice,rx,ry, param.interptype));
end
But really you should be using interpn.
Emre Topal
el 22 de Feb. de 2017
Joss Knight
el 23 de Feb. de 2017
You're permuting your data just to move the z-axis to dim 2 so that you can call meshgrid and interp2. With sensible use of ndgrid and interpn, or meshgrid and interp3, your code could be essentially identical but without the permute which is very slow.
Categorías
Más información sobre Matrices and Arrays en Centro de ayuda y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!