Ошибка сегментации в Pycuda с использованием библиотеки NVIDIA cuSolver

Я пытаюсь создать оболочку pycuda, вдохновленную библиотекой scikits-cuda. , для некоторых операций, предусмотренных в новой библиотеке cuSolver от Nvidia, сначала мне нужно выполнить факторизацию LU через cusolverDnSgetrf() op. но перед этим мне нужен аргумент «Рабочее пространство», инструмент, который 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)

person Miguel Diaz    schedule 21.04.2015    source источник
comment
Определенный вами тип дескриптора неверен. Это не должно быть указателем на void. Это бессмысленно   -  person talonmies    schedule 21.04.2015
comment
из документации cuSolver: › Это тип указателя на непрозрачное cuSolverDN контекст, который пользователь должен инициализировать, вызвав cusolverDnCreate() перед вызовом любой другой библиотечной функции. Scikits-cuda использует тот же определение, которое я использую, но с библиотекой CUBLAS, я также жестко запрограммировал для CUBLAS и работает без сбоев   -  person Miguel Diaz    schedule 21.04.2015


Ответы (1)


Последний параметр cusolverDnSgetrf_bufferSize должен быть обычным указателем, а не указателем памяти графического процессора. Попробуйте изменить функцию 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

person lebedov    schedule 21.04.2015
comment
хороший улов. И этот обычный указатель используется, потому что он должен указывать на переменную хоста (Lwork), которая будет содержать размер временной рабочей области, необходимой для последующего вызова cusolverDnSgetrf, поэтому убедитесь, что Workspace указатель в последующем вызове указывает на устройство выделило пространство размером Lwork. - person Robert Crovella; 22.04.2015
comment
джа! спасибо большое лебедов ты мужик! и @Robert Crovella, вы указываете, что это тоже совершенно правильно, я отредактирую ответ Лебедова, чтобы он содержал следующий шаг в потоке процесса, который должен фактически выполнить факторизацию LU, если это кому-то там нужно. - person Miguel Diaz; 22.04.2015
comment
@MiguelDiaz: может быть предпочтительнее просто дать ссылку на ответ Я написал в ответ на другой твой вопрос. - person lebedov; 22.04.2015