执行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]:
也就是说,我的CUDA算法的输出是不同的,这取决于我是否在输入中加零<怎么会这样?numpy加法过程中隐含的是什么?与np.ones
相乘也是如此
好吧。这似乎是由于某种内存布局。使用我的包装中的
np.astype
,它默认为order='K'
:而CUDA应用程序希望数据按顺序C排列。将包装器更新为以下内容修复了此问题:
因此,我猜numpy添加隐式地将底层数据重新排序为适合它的数据
相关问题 更多 >
编程相关推荐