在MATLAB中使用gpu加速Liu的NMF速度是一个大问题。 这是代码的一部分:
XU = X'*U; % mnk or pk (p<<mn)
UU = U'*U; % mk^2
VUU = V*UU; % nk^2
V = V.*(XU./max(VUU,1e-10));
XV = X*V; % mnk or pk (p<<mn)
VV = V'*V; % nk^2
UVV = U*VV; % mk^2
U = U.*(XV./max(UVV,1e-10)); % 3mk
......
newobj = CalculateObj(X, U, V);
原始变量X,U和V是正态矩阵,使用CPU进行计算。然后我使用gpuArray将X转换为gpuArray,这导致所有计算都使用gpu。一切顺利,直到最后一行,它计算了NMF的对象函数。 CalculateObj的代码为:
function [obj, dV] = CalculateObj(X, U, V, deltaVU, dVordU)
if ~exist('deltaVU','var')
deltaVU = 0;
end
if ~exist('dVordU','var')
dVordU = 1;
end
dV = [];
maxM = 62500000;
[mFea, nSmp] = size(X);
mn = numel(X);
nBlock = floor(mn*3/maxM);
if mn < maxM
dX = U*V'-X;
obj_NMF = sum(sum(dX.^2));
if deltaVU
if dVordU
dV = dX'*U;
else
dV = dX*V;
end
end
else
obj_NMF = 0;
if deltaVU
if dVordU
dV = zeros(size(V));
else
dV = zeros(size(U));
end
end
for i = 1:ceil(nSmp/nBlock)
if i == ceil(nSmp/nBlock)
smpIdx = (i-1)*nBlock+1:nSmp;
else
smpIdx = (i-1)*nBlock+1:i*nBlock;
end
dX = U*V(smpIdx,:)'-X(:,smpIdx);
obj_NMF = obj_NMF + sum(sum(dX.^2));
if deltaVU
if dVordU
dV(smpIdx,:) = dX'*U;
else
dV = dU+dX*V(smpIdx,:);
end
end
end
if deltaVU
if dVordU
dV = dV ;
end
end
end
%obj_Lap = alpha*sum(sum((L*V).*V));
obj = obj_NMF;
我发现执行第40行需要很长时间,这是obj_NMF = obj_NMF + sum(sum(dX。^ 2))。因为dX的类是gpuArray,但是obj_NMF是普通变量,所以似乎系统需要在加法之前等待gpu执行完成,这将花费很长时间。而且,即使将obj_NMF设置为gpuArray对象,它仍然需要等待gpu完成。我想知道: