【问题标题】:Segmentation Fault in Pycuda using NVIDIA's cuSolver LibraryPycuda 中的分段错误使用 NVIDIA 的 cuSolver 库
【发布时间】:2015-06-28 20:26:16
【问题描述】:

我正在尝试制作一个受scikits-cuda 库启发的 pycuda 包装器,对于 Nvidia 的新 cuSolver 库中提供的一些操作,首先我需要通过 cusolverDnSgetrf() 操作执行 LU 分解。但在此之前,我需要“工作空间”参数,cuSolver 提供的用于获取该参数的工具名为 cusolverDnSgetrf_bufferSize();但是当我使用它时,只是崩溃并返回一个分段错误。我做错了什么?

注意:我已经使用 scikits-cuda 处理了这个操作,但是 cuSolver 库使用了很多此类参数,我想比较 scikits-cuda 和我的实现与新库之间的用法。


import numpy as np
import pycuda.gpuarray
import ctypes
import ctypes.util

libcusolver = ctypes.cdll.LoadLibrary('libcusolver.so')

class _types:
  handle = ctypes.c_void_p

libcusolver.cusolverDnCreate.restype = int
libcusolver.cusolverDnCreate.argtypes = [_types.handle]

def cusolverCreate():
    handle = _types.handle()
    libcusolver.cusolverDnCreate(ctypes.byref(handle))
    return handle.value

libcusolver.cusolverDnDestroy.restype = int
libcusolver.cusolverDnDestroy.argtypes = [_types.handle]

def cusolverDestroy(handle):
    libcusolver.cusolverDnDestroy(handle)


libcusolver.cusolverDnSgetrf_bufferSize.restype = int
libcusolver.cusolverDnSgetrf_bufferSize.argtypes =[_types.handle,
                                       ctypes.c_int,
                                       ctypes.c_int,
                                       ctypes.c_void_p,
                                       ctypes.c_int,
                                       ctypes.c_void_p]

def cusolverLUFactorization(handle, matrix):
    m,n=matrix.shape
    mtx_gpu = gpuarray.to_gpu(matrix.astype('float32'))
    work=gpuarray.zeros(1, np.float32)
    status=libcusolver.cusolverDnSgetrf_bufferSize(
                          handle, m, n,
                          int(mtx_gpu.gpudata),
                          n, int(work.gpudata))
    print status


x = np.asarray(np.random.rand(3, 3), np.float32)
handle_solver=cusolverCreate()
cusolverLUFactorization(handle_solver,x)
cusolverDestroy(handle_solver)

【问题讨论】:

  • 你定义的句柄类型不对。它不应该是指向 void 的指针。这没有任何意义
  • 来自cuSolver documentation: > 这是一个指向不透明 cuSolverDN 上下文的指针类型,用户必须在调用任何其他库函数之前通过调用 cusolverDnCreate() 对其进行初始化。 Scikits-cuda 使用与我使用的定义相同的定义,但使用 CUBLAS 库,我也为 CUBLAS 进行了硬编码并且工作顺利

标签: cuda segmentation-fault pycuda scikits cusolver


【解决方案1】:

cusolverDnSgetrf_bufferSize的最后一个参数应该是常规指针,而不是GPU内存指针。尝试修改cusolverLUFactorization()函数如下:

def cusolverLUFactorization(handle, matrix):
    m,n=matrix.shape
    mtx_gpu = gpuarray.to_gpu(matrix.astype('float32'))

    work = ctypes.c_int()
    status = libcusolver.cusolverDnSgetrf_bufferSize(
                         handle, m, n,
                         int(mtx_gpu.gpudata),
                         n, ctypes.pointer(work))
    print status
    print work.value

【讨论】:

  • 好收获。并且使用该常规指针是因为它应该指向一个宿主变量 (Lwork),该变量将包含后续调用 cusolverDnSgetrf 所需的临时工作空间的 size,因此请确保后续调用中的Workspace pointer 指向设备分配的Lwork 大小的空间。
  • 贾!非常感谢列别多夫,你是男人!和@Robert Crovella,你指出这也是完全正确的,我将编辑 lebedov 答案以包含流程中的下一步,如果有人需要它,则实际执行 LU 分解。
  • @MiguelDiaz:可能比我为回答您的其他问题而发布的answer 更可取。
猜你喜欢
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
  • 2010-11-13
  • 1970-01-01
  • 2015-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多