Пытаюсь разобраться как работать с технологией Cuda .Net. Делаю пример отсюда: http://www.thevista.ru/page13118-cudanet_dlya_netrazrabotchika_ch3
Скомпилировать программу получилось, изменив немного текст в командной строке события "После построения", но почему-то не получается загрузить полученную программу mykernel.cubin. Вот текст кода, где при выполнении cuda.LoadModule вызывается исключение "GASS.CUDA.CUDAException"
cuda = new CUDA(0, true);//создаем первое устройство
int[] array = Enumerable.Range(0, 4096).ToArray();//формируем массив от 0 до 4095
CUdeviceptr d_input = cuda.CopyHostToDevice(array);//копируем данные в память видеоадаптера
/*FileStream Sr = new FileStream(Path.Combine(Environment.CurrentDirectory, "mykernel.cubin"), FileMode.Open);
byte[] module = new byte[Sr.Length];
Sr.Read(module, 0, module.Length);
cuda.LoadModule(module);*/ //это я пытался но не помогло
CUmodule module = cuda.LoadModule(Path.Combine(Environment.CurrentDirectory, "mykernel.cubin"));//загружаем нашу программу - здесь появляется ошибка
CUfunction func = cuda.GetModuleFunction("test_func");//получаем дескриптор функции test_func
//задаем параметры запуска:
cuda.SetFunctionBlockShape(func, 512, 1, 1);//задается размер блока 512 нитей, блоки одномерные
cuda.SetParameter(func, 0, (uint)d_input.Pointer);//передаем указатель на массив данных
cuda.SetParameter(func, IntPtr.Size, (uint)42);//передаем приращение
cuda.SetParameterSize(func, (uint)(IntPtr.Size + sizeof(uint)));//передаем общий размер параметров функции
//запускаем функцию
cuda.Launch(func, array.Length / 512, 1);//задаем размеры грида
//получаем результат
cuda.CopyDeviceToHost(d_input, array);
//освобождаем выделенную память
cuda.Free(d_input);
//выводим результат
foreach (var item in array)
{
Console.WriteLine(item);
}
}
catch (CUDAException ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("CUDAException");
Console.WriteLine(ex.Message);
}
Console.ReadLine();
В чем может быть проблема?
Comments
Попробовал -arch=sm_21 - не заработало. Проблему решил так: установил NVIDIA GPU Computing Toolkit 32-битный, до этого было 64 бита.
Можно мне тоже исходник на vpdiman@mail.ru . Никак не могу компилировать
Отправил
Нашел причину. Необходимо модуль mykernel.cu компилировать с ключом -arch=sm_20
у меня такая же ошибка, но -arch=sm_20 че то не помогло, командная строка после построения у меня выглядит вот так:
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.0\bin\nvcc.exe" -arch=sm_20 "C:\Users\Vasia\Documents\Visual Studio 2010\Projects\ConsoleApplication3\ConsoleApplication3\kernel.cu" --cubin --compiler-bindir="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin"
построение проходит, cubin создает, но выдает ошибку в том же месте, что у вас. помогите пожалуйста или вышлите ваш проект на vasia-basta-me@list.ru
Такая я же ошибка, причём компиляция проходит успешно при всех различных параметрах arch=sm_11.. arch=sm_20, arch=sm_22..
А при cuda.LoadModule возникает вышеописанный ексепшен:
CUDAError = GASS.CUDA.CUResult.ErrorInvalidImage
Будьте добры, перешлите и мне проектик на artesdi@gmail.com
Заранее спасибо.
Отправил. Надеюсь, поможет.
Хм, у меня проект не заработал.
В свойствах проекта командная строка выглядит так:
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.0\bin\nvcc.exe" -arch=sm_11 "C:\Users\d1\Desktop\TestCuda\TestCuda\mykernel.cu" --cubin
--compiler-bindir="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin"
А Cuda Compute Capability 1.1
я тот, у кого этот проект заработал, у меня командная строка после построения выглядит немного в другом порядке, быть может в этом дело:
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.0\bin\nvcc.exe" "C:\Users\Vasia\Documents\Visual Studio 2010\Projects\TestCuda - копия\TestCuda\mykernel.cu" --cubin --compiler-bindir="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin" -arch=sm_21
а вообще проверь по дате он создает новый cubin или нет. а создавать его должен не при запуске, а при построении. так что внимательно.
Всем спасибо за помощь, в моём случае проблема заключалась в конфиге компилятора nvidia. По каким-то причинам при ранее приходилось переписывать файлик nvcc.profile, вернул всё по-умолчанию, нормально заработало.
Даже и не знаю в чем причина. Может CUDA .Net ориентирован на куду версии 2.
А какая версия CUDA API у вас установлена?
Я последнюю версию 4.0 скачал с официального сайта http://developer.nvidia.com/cuda-toolkit-40
Но Compute Capability зависит от видеокарты, а не от установленной версии CUDA API, если, конечно, причина именно в Compute Capability. Я свой пример только что проверил - компилируется и работает.
Ну это понятно, у меня тоже 4.0, Win 7 x64. Но кстати в cuda.net описана только поддержка CUDA API версии 3.0, странно.
Так же заметил в методе интересную перегрузку:
public CUmodule LoadModule(
byte[] binaryImage
)
Есть мысли, как содержимое компиляции cubin подсунуть в виде массива?
Открыть файл cubin с помощью потока, считать массив байт ну и подсунуть его:
FileStream S = new FileStream(FileName, FileMode.Open, FileAccess.Read);
byte[] cubin = new byte[S.Length];
S.Read(cubin, 0, cubin.Length);
S.Close();
CUmodule module = cuda.LoadModule(cubin);
Тот же эксепшен, я просто думал, не связываться с файлов, а можем как-то напрямик скомпилировать его в массив.
А как его напрямик в массив скомпилировать? Все дело в том, что при компиляции создается файл с расширением cubin - это двоичный файл, который и нужно загрузить с помощью LoadModule. Ну можно еще его загрузить из ресурса, спрятать внутри программы или передать еще каким-нибудь хитрым способом, вот для этого, видимо и сделали возможность передачи последовательности байт. Но здесь видимо что-то не так компилируется, или загружается не то, то надо. А создается устройство с инициализацией? Примерно, вот так: CUDA cuda = new CUDA(0, true);?
Да, конечно, все свойства девайса получить удаётся.
Массив в память адаптера так же копируется.
Да и при работе на С++ никаких проблем не возникало.
Я рекомендую сделать dll на C++, в которой реализовать функцию вызова кода куды, и в программе C# подключить эту библиотеку. И работать будет быстрее. Возможно CUDA .Net еще сырая, да и документации по ней мало.
Проект выслал. Возможно здесь проблема из-за того, что разные видеокарты. Какое значение выдается в первой части примера в строке "Cuda Compute Capability"? У меня 2.0. Попробуйте изменить -arch=sm_xx, где xx - номер "Cuda Compute Capability".
большое спасибо, ваш проект работает и на -arch=sm_20 и на -arch=sm_21 (у меня Cuda Compute Capability 2.1), наверно я что то упустил или какую то глупость совершил. зато теперь у меня есть работающий не работающий проекты
Большое спасибо всем за присланные исходники.
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin - он по этому пути какой-то файл cubin создаёт?
По этому пути берется компилятор C++. Для cubin нужно два компилятора - C++ и CUDA. Поэтому ошибки при компиляции дублируются. Файл cubin помещается туда, где находится скомпилированный файл exe.