使用Cupy从GPU上的另一个矩阵创建距离矩阵

问题描述

我已经使用numpy编写了代码,该代码采用大小为(m x n)的数组...行(m)是由(n)个特征组成的单个观察结果...并且创建了大小为(m x m)的平方距离矩阵。该距离矩阵是给定观察值与所有其他观察值的距离。例如。第0行第9列是观测值0与观测值9之间的距离。

import numpy as np
#import cupy as np

def l1_distance(arr):
    return np.linalg.norm(arr,1)

X = np.random.randint(low=0,high=255,size=(700,4096))

distance = np.empty((700,700))

for i in range(700):
    for j in range(700):
        distance[i,j] = l1_distance(X[i,:] - X[j,:])

我通过注释第二条import语句在cupy上尝试在GPU上进行此操作,但显然double for循环的效率极低。它需要大约numpy大约6秒,但是cupy需要26秒。我知道为什么,但是我现在还不清楚如何并行处理此过程。

我知道我需要编写某种归约内核,但我想不出如何从对另一个数组元素的迭代操作中构造一个cupy数组。

解决方法

在A100 GPU中使用广播CuPy需要0.10秒,而在NumPy中使用广播CuPy需要6.6秒

    for i in range(700):
        distance[i,:] = np.abs(np.broadcast_to(X[i,:],X.shape) - X).sum(axis=1)

此向量化使一个向量与所有其他向量的距离平行。