Я хочу понять, как контекст cuda создается и ассоциируется с ядром в приложениях API времени выполнения cuda?
Я знаю, что это делается под капотом API драйверов. Но я хотел бы понять сроки создания.
Для начала я знаю, что cudaRegisterFatBinary - это первый вызов cuda api, который регистрирует файл fatbin во время выполнения. За ним следует несколько API-интерфейсов регистрации функций cuda, которые вызывают cuModuleLoad на уровне драйверов. Но затем, если мое приложение API времени выполнения Cuda вызывает cudaMalloc, как указатель на эту функцию связан с контекстом, который, я считаю, должен был быть создан заранее. Как получить дескриптор этого уже созданного контекста и связать с ним будущие вызовы API времени выполнения? Пожалуйста, демистифицируйте внутреннюю работу.
Цитировать документацию NVIDIA по этому вопросу
Вызовы API CUDA Runtime работают с CUcontext API драйвера CUDA, который
привязан к текущему хост-потоку.
Если не существует API-интерфейса драйвера CUDA, CUcontext привязывается к текущему
поток во время вызова API CUDA Runtime, который требует
CUcontext затем CUDA Runtime неявно создаст новый CUcontext
перед выполнением вызова.
Если среда выполнения CUDA создает CUcontext, тогда CUcontext будет
созданный с использованием параметров, указанных в CUDA Runtime API
функции cudaSetDevice, cudaSetValidDevices, cudaSetDeviceFlags,
cudaGLSetGLDevice, cudaD3D9SetDirect3DDevice,
cudaD3D10SetDirect3DDevice и cudaD3D11SetDirect3DDevice. Обратите внимание, что
эти функции завершатся с cudaErrorSetOnActiveProcess, если они
вызывается, когда CUcontext привязан к текущему хост-потоку.
Время жизни CUcontext управляется подсчетом ссылок
механизм. Счетчик ссылок CUcontext изначально установлен на 0,
и увеличивается на cuCtxAttach и уменьшается на cuCtxDetach.
Если CUcontext создается средой выполнения CUDA, то среда выполнения CUDA
уменьшит счетчик ссылок CUcontext в функции
cudaThreadExit. Если CUcontext создается с помощью API драйвера CUDA (или
создается отдельным экземпляром библиотеки CUDA Runtime API),
тогда CUDA Runtime не будет увеличивать или уменьшать ссылку
количество этого CUcontext.
Все состояние CUDA Runtime API (например, адреса глобальных переменных и
значения) путешествует с его базовым CUcontext. В частности, если
CUcontext перемещается из одного потока в другой (с использованием cuCtxPopCurrent
и cuCtxPushCurrent) тогда все состояние API CUDA Runtime будет перемещено в
эта нить также.
Но что я не понимаю, так это как среда выполнения cuda создает контекст? какие вызовы API используются для этого? Компилятор nvcc вставляет некоторые вызовы API, чтобы сделать это во время компиляции, или это делается полностью во время выполнения? Если первое верно, какие API времени выполнения используются для этого управления контекстом? Это правда позже, как именно это сделано?
Если контекст связан с хост-потоком, как мы можем получить доступ к этому контексту? Связывается ли оно автоматически со всеми переменными и ссылками на указатели, обрабатываемыми потоком?
как в конечном итоге происходит загрузка модуля в контексте?