Search All of the Math Forum:
Views expressed in these public forums are not endorsed by
Drexel University or The Math Forum.



Re: histc for gpu
Posted:
Feb 15, 2014 9:39 AM


Edric M Ellis <eellis@mathworks.com> wrote in message <ytwmwihkabl.fsf@ukeellis0l.dhcp.mathworks.com>... > "Christian " <proechri@umich.edu> writes: > > > Path: news.mathworks.com!notformail > > Newsgroups: comp.softsys.matlab > > Subject: histc for gpu > > Date: Sat, 25 Jan 2014 21:28:07 +0000 (UTC) > > Organization: The MathWorks, Inc. > > > > Hi, > > > > I hope to use histc on CUDA, but it's not a supported function. So I tried a workaround because I'm actually just interested in the second output argument: > > > > [~,ind] = histc(x,x_grid); > > > > is more or less equivalent to the following code (except for points outside the grid). > > > > ind=ones(size(x)); > > for j=1:length(x_grid)1 > > ind(x>=x_grid(j) & x<x_grid(j+1)) = j; > > end > > > > But this latter code is much slower than histc, probably due to the loop. For instance, for my inputs the first code requires 0.03 seconds, the latter needs 1.8 seconds. > > > > Is it possible to speed up the second code so that I can still run it > > on CUDA? > > I haven't profiled this, but you can run just the binning part of HISTC > on the GPU using arrayfun and uplevel variables to access the bins: > > %%%%%%%%%%%%%%%%%%%% > function test() > > % Test inputs > q = gpuArray.randi([1 10], 1, 1000); > edges = 1:8; > > % Implementation > nEdges = numel(edges); > function b = bindata(x) > b = 0; > if x == edges(nEdges) > b = nEdges; > else > for idx = 1:(nEdges1) > if x >= edges(idx) && x < edges(idx + 1) > b = idx; > break; > end > end > end > end > b = arrayfun(@bindata, q); > > % Check against the CPU > [~, bcheck] = histc(gather(q), edges); > assert(isequal(b, bcheck)); > end > %%%%%%%%%%%%%%%%%%%% > > Cheers, > > Edric.
Thanks, Edric. I have some trouble getting your code running. I've set up a function file:
function b = bindata(x,edges) nEdges = 100; b = 0; if x == edges(end) b = nEdges; else for idx = 1:(nEdges1) if x >= edges(idx) && x < edges(idx + 1) b = idx; break; end end end end
I changed nEdges=numel(edges) to just the size of edges because the arrayfun command didn't like numel. But still when running the code from my main file using
indx = arrayfun(@bindata, xpgpu, x_gridgpu);
I receive the message Error using gpuArray/arrayfun Indexing is not supported. for lines 4 and 8.
Thanks for your help, Christian



