如何将上/下gpuarray转换为cublasStbsv所需的特定格式?

时间:2014-11-28 09:21:07

标签: cuda pycuda cublas scikits

我目前正在使用pycuda和scikits.cuda来求解线性方程A * x = b,其中A是上/下矩阵。但是,cublasStbsv例程需要特定的格式。 举个例子:如果下面的矩阵A = [[1,0,0],[2,3,0],[4,5,6]],那么cublasStbsv所需的输入应该是[[1,3] ,6],[2,5,0],[4,0,0]],其中行分别是对角线,子对角线1,子对角线2。如果使用numpy,这可以通过stride_tricks.as_strided轻松完成,但我不知道如何使用pycuda.gpuarray做类似的事情。任何帮助将不胜感激,谢谢。我找到了pycuda.compyte.array.as_strided,但它不能应用于gpuarray。

1 个答案:

答案 0 :(得分:1)

我通过使用theano完成了它。首先将它转换为cudandarray,改变步幅并将副本复制回gpuarray。请注意Fortran和C顺序之间的变化。 更新: 终于通过使用gpuarray.multi_take_put

完成了它
def make_triangle(s_matrix, uplo = 'L'):
"""convert triangle matrix to the specific format
required by cublasStbsv, matrix should be in Fortran order,
s_matrix: gpuarray    
"""
#make sure the dytpe is float32     
if s_matrix.dtype != 'f':
    s_matrix = s_matrix.astype('f')
dim = s_matrix.shape[0]
if uplo == 'L':
    idx_tuple = np.tril_indices(dim)
    gidx = gpuarray.to_gpu(idx_tuple[0] + idx_tuple[1] * dim)
    gdst = gpuarray.to_gpu(idx_tuple[0] + idx_tuple[1] * (dim - 1))
    return gpuarray.multi_take_put([s_matrix], gdst, gidx, (dim, dim))[0]
else:
    idx_tuple = np.triu_indices(dim)
    gidx = gpuarray.to_gpu(idx_tuple[0] + idx_tuple[1] * dim)
    gdst = gpuarray.to_gpu(idx_tuple[0] + (idx_tuple[1] + 1) * (dim - 1))
    return gpuarray.multi_take_put([s_matrix], gdst, gidx, (dim, dim))[0]