【问题标题】:Vectorize kroniker multiplcation with trace calculations用迹计算矢量化克罗内克乘法
【发布时间】:2016-08-04 04:20:32
【问题描述】:

重新发布更多细节,这些细节极大地改变了我的第一个问题的范围。这是原始代码:

K = zeros(N*N)
for a=1:N
    for i=1:I
        for j=1:J
            M = kron(X(:,:,a).',Y(:,:,a,i,j));

            pr = real(trace(E*M));
            K = K+H(i,j,a)*M/pr;
        end
    end
end

其中 E 是布尔掩码,H 是包含 N 个 IxJ 直方图的 3D 矩阵。 K是输出

目标是向量化 kroniker 乘法调用。我的直觉是将 X 和 Y 视为矩阵的容器(作为参考,提供给 kron 的 X 和 Y 的切片是 7x7 阶的方阵)。在此容器方案下,X 显示为 1-D 容器,Y 显示为 3-D 容器。我的下一个猜测是将 Y 重塑为 2-D 容器,或者更好的是 1-D 容器,然后对 X 和 Y 进行元素乘法。问题是:如何以保留 M 和轨迹的方式进行这种重塑matlab 甚至可以在这个容器的想法中处理这个想法,还是容器需要进一步重塑以进一步暴露内部矩阵元素?

【问题讨论】:

    标签: matlab vectorization trace


    【解决方案1】:

    矩阵乘法与7D permute

    % Get sizes
    [m1,m2,~] =  size(X);
    [n1,n2,N,n4,n5] =  size(Y);
    
    % Perform kron format elementwise multiplication betwen the first two dims
    % of X and Y, keeping the third dim aligned and "pushing out" leftover dims
    % from Y to the back
    mults = bsxfun(@times,permute(X,[4,2,5,1,3]),permute(Y,[1,6,2,7,3,4,5]));
    mults3D = reshape(mults,m1*n1,m2*n2,[]);
    Emults3D = reshape(E*reshape(mults3D,size(mults3D,1),[]),size(mults3D));
    
    % Trace summations by using linear indices of diagonal on 3D slices in Emults3D
    MN = m1*n1;
    idx = 1:MN+1:MN^2;
    idx2D = bsxfun(@plus,idx(:),MN^2*(0:size(Emults3D,3)-1));
    pr_sums = sum(Emults3D(idx2D),1);
    
    % Perform "M/pr" equivalent elementwise divisions and then use
    % matrix-multiplication to reduce the iterative summations
    Mp = bsxfun(@rdivide,mults3D,reshape(pr_sums,1,1,[]));
    out = reshape(Mp,[],size(Mp,3))*reshape(permute(H,[3,1,2]),[],1);
    out = reshape(out,m1*n1,m2*n2);
    

    基准测试

    输入是这样设置的 -

    % Size parameter
    n = 5;
    
    % Setup inputs
    X = rand(n,n,n);
    Y = rand(n,n,n,n,n);
    E = rand(n*n,n*n)>0.5;
    H = rand(n,n,n);
    num_iter = 500; % Number of iterations to run the approaches for
    

    运行时结果是 -

    ----------------------------- With Loop
    Elapsed time is 8.806286 seconds.
    ----------------------------- With Vectorization
    Elapsed time is 1.471877 seconds.
    

    将大小参数n 设置为10,运行时为-

    ----------------------------- With Loop
    Elapsed time is 5.068872 seconds.
    ----------------------------- With Vectorization
    Elapsed time is 4.399783 seconds.
    

    【讨论】:

    • 在我的实际项目中使用您的解决方案,它只提供大约 15% 的加速。大部分时间(51%)都花在Emults3D = reshape(E*reshape(mults3D,size(mults3D,1),[]),size(mults3D)); 线上,有没有更好的优化呢?这条线到底是怎么回事这么慢:乘以 E 或将如此大的对象(在我的特定应用程序中为 81x81x17600)重塑两次?
    • @MikeVandenberg 我会再次将大量输入和内存带宽归咎于创建巨大的Emults3D。恐怕对于如此庞大的数据集,我们已经达到了那里的性能极限。
    • 尝试用较低级别的语言重写它以优化内存分配和移动是否有任何优势?如果 E 是一个非常简单的掩码(例如单位矩阵),是否有任何“捷径”可以避免多次整形或简化提取痕迹?
    • @MikeVandenberg 可能是!或者,如果您可以使用 GPU,可能值得将其移植到 gpuarrays:mathworks.com/help/distcomp/gpuarray.html
    • GPU 必须是 nvidia 才能进行 cuda 加速吗?
    猜你喜欢
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 2019-12-07
    相关资源
    最近更新 更多