cudaMemcpy невалиден аргумент

Програмата ми изпълнява 2 нишки - нишка A (за въвеждане) и B (за обработка). Имам и двойка указатели към 2 буфера, така че когато нишка A приключи с копирането на данни в буфер 1, нишка B започва да обработва буфер 1 и нишка A започва да копира данни в буфер 2. След това, когато буфер 2 е пълен, нишка A копира данни в буфер 1 и поток B обработва буфер 2 и т.н.

Проблемът ми идва, когато се опитам да cudaMemcpy Buffer[] в d_Buffer (който преди това беше cudaMalloc'd от основната нишка, т.е. преди създаването на нишка. Buffer[] също бяха malloc'd от основната нишка). Получавам грешка „невалиден аргумент“, но нямам представа кой е невалидният аргумент.

Намалих програмата си до еднопоточна програма, но все още използвам 2 буфера. Тоест копирането и обработката се извършват едно след друго, вместо едновременно. Линията cudaMemcpy е точно същата като тази с двойна нишка. Програмата с една нишка работи добре.

Не съм сигурен къде е грешката.

Благодаря ти.

Поздрави, Rayne


person Rayne    schedule 11.04.2011    source източник


Отговори (1)


Ако правите това с CUDA 3.2 или по-ранна версия, причината е, че GPU контекстите са свързани с конкретна нишка. Ако многонишкова програма разпредели памет на един и същ GPU от различни нишки на хост, разпределенията приключват с установяването на различни контексти и указателите от един контекст не са преносими към друг контекст. Всеки контекст има собствено "виртуализирано" пространство на паметта, с което да работи.

Решението е или да използвате API за мигриране на контекст, за да прехвърлите един контекст от нишка в нишка, докато работят, или да опитате новата публична версия CUDA 4.0rc2, която трябва да поддържа това, което се опитвате да направите, без използването на миграция на контекст. Недостатъкът е, че 4.0rc2 е версия за тестване и изисква определен драйвер за бета версия. Този драйвер няма да работи с целия хардуер (лаптопи например).

person talonmies    schedule 11.04.2011
comment
Благодаря! Намерих cuCtxPushCurrent и cuCtxPopCurrent, които са API на драйвери. Има ли API по време на изпълнение за контекстна миграция? Мога ли да смесвам API на време за изпълнение и на драйвери в една и съща програма? - person Rayne; 11.04.2011
comment
Няма рутинни процедури за управление на контекста на API по време на изпълнение, тъй като контекстите са имплицитни/абстрахирани в API по време на изпълнение. Въпреки това, тъй като CUDA 3.1 беше пуснат, да, можете безопасно да смесвате време за изпълнение и API извиквания на драйвери. Вероятно ще откриете, че е най-лесно да използвате API на драйвера, за да създадете контекста и да го мигрирате от нишка в нишка, като използвате API по време на изпълнение за останалите операции в рамките на контекст. Имайте предвид, че самата миграция на контекста не е безплатна, тя добавя малко забавяне, но е официалният начин да правите това, което искате преди CUDA 4.0 - person talonmies; 11.04.2011
comment
Искам да изпробвам CUDA 4.0. Трябва ли просто да инсталирам CUDA 4.0 върху текущата ми инсталация на CUDA 3.2? Ще трябва ли да премахна нещо, напр. драйвери и т.н.? - person Rayne; 12.04.2011