gpuArray related memory issue
Show older comments
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 Comment
Joss Knight
on 20 Feb 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?
Answers (1)
Joss Knight
on 20 Feb 2017
1 vote
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 Comments
Emre Topal
on 21 Feb 2017
Joss Knight
on 21 Feb 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
on 22 Feb 2017
Joss Knight
on 23 Feb 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.
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!