Передача класса C++/CUDA в SourceModule PyCUDA

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

Это работает, когда я использую CUDA-C, но я хочу как-то импортировать этот класс в PyCUDA, если есть возможность это сделать. Итак, я буду использовать этот класс внутри ядра (не в «основном») для определения конкретных переменных, которые используются для вычисления производных функции. Есть ли способ передать этот класс в 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 не будет знать, что такое "adouble", потому что они определены в определении класса adoublecuda.h, поэтому я надеюсь, что теперь вы лучше понимаете мой вопрос. Кто-нибудь знает, с чего мне начать? Если нет, то я напишу эти ядра на CUDA-C и использую опцию nvcc -cubin.

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


person Banana    schedule 02.07.2012    source источник


Ответы (1)


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

Итак, чтобы сделать то, о чем, как я думаю, вы спрашиваете, вам нужно только указать оператор #include для любых заголовков, которые нужны вашему коду устройства в представленной строке, и подходящий набор путей поиска в списке Python, переданном через параметр ключевого слова 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'])

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

person talonmies    schedule 02.07.2012
comment
Вау, это решение, которое я искал! Я просто хотел включить этот заголовочный файл, чтобы мои ядра знали, где находится определение класса adouble, но я не знал, как это сделать. Я не буду использовать этот класс adouble внутри основного, но мне нужно выяснить, как получить этот массив adouble от gpu. Как видите, в классе adouble всего два закрытых члена: double val double ADVAL Возможно, мне нужно будет создать структуру на питоне, подобную этой. Большое спасибо за помощь! - person Banana; 02.07.2012
comment
Когда я пытаюсь включить этот класс, я получаю слишком много ошибок, говорящих: это объявление может не иметь внешней связи C. Нужно ли менять adoublecuda.h или есть что-то еще? - person Banana; 02.07.2012
comment
Как я отметил в своем ответе, SourceModule может заключать строки кода в скобки с объявлением extern "C" {}. С чистыми определениями C++ в вашем коде вам это не нужно. Вы можете отключить это поведение с помощью аргумента ключевого слова no_extern_c=True. В выводе будет искажение символов, возможно, вам придется принять это во внимание в вашем коде Python. На данный момент у меня нет работающей установки PyCUDA для тестирования. - person talonmies; 02.07.2012
comment
Да, если я использую такой оператор: mod = SourceModule(kernel_code_template, include_dirs=['path/to/adoublecuda'],no_extern_c=True), то получаю сообщение об ошибке при попытке доступа к myfunction, например: cuModuleGetFunction failed: not found - person Banana; 03.07.2012
comment
Вот решение для этого: Использование шаблонов функций C++ в PyCUDA - person Banana; 03.07.2012