2012-07-02 2 views
6

У меня есть класс, написанный на C++, который также использует некоторые определения из cuda_runtime.h, это часть проекта с открытым исходным кодом с именем ADOL-C, вы можете посмотреть here!Передача класса C++/CUDA исходному модулю PyCUDA

Это работает, когда я использую CUDA-C, но я хочу каким-то образом импортировать этот класс в PyCUDA, если есть возможность сделать это. Поэтому я буду использовать этот класс внутри ядер (а не в «main») для определения конкретных переменных, которые используются для вычисления производных функции. Есть ли способ передать этот класс в SourceModule PyCUDA?

Я задал аналогичный вопрос, но здесь я хотел бы еще немного объяснить это. Итак, есть решение, которое компилирует мой C-код, используя nvcc -cubin (благодаря talonmies), а затем импортируя его с помощью driver.module_from_file(), но я хотел бы использовать SourceModule и писать эти ядра внутри файла .py он может быть более удобным для пользователя. Мой пример будет выглядеть примерно так:

from pycuda import driver, gpuarray 
from pycuda.compiler import SourceModule 
import pycuda.autoinit 
kernel_code_template=""" 
__global__ void myfunction(float* inx, float* outy, float* outderiv) 
{ 
    //defining thread index 
    ... 
    //declare dependent and independet variables as adoubles 
    //this is a part of my question 
    adtl::adouble y[3]; 
    adtl::adouble x[3]; 
    // ... 
} 
""" 

... это только идея, но SourceModule не будет знать, какие «AЩелкните двойным в», так как они определены в определении класса adoublecuda.h, так что я надеюсь, теперь вы поймете мой вопрос лучше. Кто-нибудь знает, с чего мне начать? Если нет, я буду писать эти ядра в CUDA-C и использовать опцию nvcc -cubin.

Спасибо за помощь!

ответ

6

Система SourceModule PyCUDA - это действительно только способ получить код, который вы передаете в файл, скомпилировав этот файл с nvcc в кубинский файл и (необязательно) загрузив этот кубинный файл в текущий контекст CUDA. Модуль компилятора PyCUDA абсолютно ничего не знает о синтаксисе или коде ядра ядра CUDA и практически не влияет на код, который скомпилирован [почти определитель - это потому, что он может скопировать отправленный пользователем код с объявлением extern "C" { }, чтобы остановить сбой символа C++].

Так делать то, что я думаю, что вы спрашиваете, вы должны требовать только в #include заявление для любой заголовки код устройства должен в представленном строку, и соответствующий набор путей поиска в списке питона прошел через include_dirs ключевое слово. Если вы сделаете что-то вроде этого:

from pycuda import driver, gpuarray 
from pycuda.compiler import SourceModule 
import pycuda.autoinit 
kernel_code_template=""" 

#include "adoublecuda.h" 
__global__ void myfunction(float* inx, float* outy, float* outderiv) 
{ 
    //defining thread index 
    ... 
    //declare dependent and independet variables as adoubles 
    //this is a part of my question 
    adtl::adouble y[3]; 
    adtl::adouble x[3]; 
    // ... 
} 

""" 

module = SourceModule(kernel_code_template, include_dirs=['path/to/adoublecuda']) 

и он должен автоматически работать (обратите внимание на непроверенные, используйте на свой страх и риск).

+0

Вау, это решение, которое я искал! Я просто хотел включить этот заголовочный файл, так что мои ядра знают, где определение класса adouble, но я не знал, как это сделать. Я не буду использовать этот класс adouble внутри «main», но мне нужно будет выяснить, как получить этот массив adouble из gpu. Как вы можете видеть, класс adouble имеет только два частных члена: 'double val' ' double ADVAL' Возможно, мне нужно будет создать структуру в python, подобную этому. Большое вам спасибо за помощь! – Banana

+0

Когда я пытаюсь включить этот класс, я получаю слишком много ошибок, говоря: «У этой декларации, возможно, нет внешней связи C». Нужно ли мне менять adoublecuda.h или что-то еще? – Banana

+0

Как я уже отмечал в своем ответе, SourceModule может скопировать строки кода с помощью выражения «extern» C «{}». С чистыми определениями C++ в вашем коде вы этого не хотите. Вы можете отключить это поведение с аргументом ключевого слова 'no_extern_c = True'. На выходе будет отображаться символ, вам может потребоваться принять это в свой код Python. На данный момент у меня нет рабочей установки PyCUDA для тестирования. – talonmies

Смежные вопросы