numpy加法过程中隐式发生了什么?

2024-10-01 11:28:26 发布

您现在位置:Python中文网/ 问答频道 /正文

执行numpy数组加法时会发生什么?我在C++中计算了一个CUDA应用程序,计算平方距离,我用CDLL与Python进行接口。Python包装器如下所示:

def sqdist(X: np.ndarray) -> np.ndarray:

    # Organize input and output
    N, D = X.shape
    X = X.astype(np.float32)
    Y = np.zeros((N, N)).astype(np.float32)

    # Prepare memory pointers
    dataIn = X.ctypes.data_as(cdll.POINTER(cdll.c_float))
    dataOut = Y.ctypes.data_as(cdll.POINTER(cdll.c_float))

    # Call the sqdist dll
    cdll.load(_get_build_default())
    cdll.computeSquaredEuclideanDistances(dataIn, N, D, dataOut)
    cdll.unload()

    # Return as numpy array
    return Y

注意,为了使用numpy ctypesdata_as(CUDA使用32位float),需要转换为float32。现在,将此方法的输出与scipy.spatial.distance.cdist(a,a,metric='sqeuclidean')的输出进行比较,我发现一个奇怪的行为:

假设我有一些数据Xcl(numpy数组):

输入1

a = Xcl
b = Xcl + np.zeros(Xcl.shape)
print(a.dtype, type(a), a.shape)
print(b.dtype, type(b), b.shape)
print(np.all(a == b))

输出1

float32 <class 'numpy.ndarray'> (582, 115)
float64 <class 'numpy.ndarray'> (582, 115)
True

输入[2]:

scipydist = scipy.spatial.distance.cdist(a, a, metric='sqeuclidean')
cudadist1 = cuda.sqdist(a)
cudadist2 = cuda.sqdist(b)

plt.figure(figsize=(20, 5))
plt.subplot(131)
plt.imshow(scipydist, vmax=3000)
plt.colorbar()
plt.title("scipydist")
plt.subplot(132)
plt.imshow(cudadist1, vmax=3000)
plt.colorbar()
plt.title("cudadist1")
plt.subplot(133)
plt.imshow(cudadist2, vmax=3000)
plt.colorbar()
plt.title("cudadist2")
plt.show()

输出[2]:

enter image description here

也就是说,我的CUDA算法的输出是不同的,这取决于我是否在输入中加零<怎么会这样?numpy加法过程中隐含的是什么?与np.ones相乘也是如此


Tags: numpyasnppltfloatcudaprintndarray
1条回答
网友
1楼 · 发布于 2024-10-01 11:28:26

好吧。这似乎是由于某种内存布局。使用我的包装中的np.astype,它默认为order='K'

K means as close to the order the array elements appear in memory as possible

而CUDA应用程序希望数据按顺序C排列。将包装器更新为以下内容修复了此问题:

X = X.astype(np.float32, order='C')
Y = np.zeros((N, N)).astype(np.float32, order='C')

因此,我猜numpy添加隐式地将底层数据重新排序为适合它的数据

相关问题 更多 >