cudaランタイムAPIアプリケーションでcudaコンテキストが作成され、カーネルに関連付けられる方法を理解したいですか?
私はそれがドライバーAPIによって内部で行われていることを知っています。しかし、私は作成のタイムラインを理解したいと思います。
まず、cudaRegisterFatBinaryが最初に行われたcuda api呼び出しであり、実行時にfatbinファイルを登録することを知っています。その後に、ドライバー層でcuModuleLoadを呼び出すいくつかのcuda関数登録APIが続きます。しかし、私のCudaランタイムAPIアプリケーションがcudaMallocを呼び出す場合、コンテキストに関連付けられたこの関数へのポインターはどのように提供されますか。これは事前に作成されているはずです。このすでに作成されたコンテキストへのハンドルを取得し、将来のランタイムAPI呼び出しをそれに関連付けるにはどうすればよいですか?内部の仕組みをわかりやすく説明してください。
これに関するNVIDIAのドキュメントを引用するには
CUDAランタイムAPI呼び出しは、現在のホストスレッドにバインドされているCUDAドライバーAPICUcontextで動作します。
CUcontextを必要とするCUDAランタイムAPI呼び出し時に、現在のスレッドにバインドされたCUDAドライバーAPI CUcontextが存在しない場合、CUDAランタイムは呼び出しを実行する前に暗黙的に新しいCUcontextを作成します。
CUDAランタイムがCUcontextを作成する場合、CUcontextは、CUDAランタイムAPI関数cudaSetDevice、cudaSetValidDevices、cudaSetDeviceFlags、cudaGLSetGLDevice、cudaD3D9SetDirect3DDevice、cudaD3D10SetDirect3DDevice、およびcudaD3D11SetDirect3DDeviceによって指定されたパラメーターを使用して作成されます。これらの関数は、CUcontextが現在のホストスレッドにバインドされているときに呼び出された場合、cudaErrorSetOnActiveProcessで失敗することに注意してください。
CUcontextの存続期間は、参照カウントメカニズムによって管理されます。CUcontextの参照カウントは最初は0に設定され、cuCtxAttachによってインクリメントされ、cuCtxDetachによってデクリメントされます。
CUDAランタイムによってCUcontextが作成された場合、CUDAランタイムは関数cudaThreadExitでそのCUcontextの参照カウントをデクリメントします。CUcontextがCUDADriverAPIによって作成された場合(またはCUDA Runtime APIライブラリの別のインスタンスによって作成された場合)、CUDARuntimeはそのCUcontextの参照カウントをインクリメントまたはデクリメントしません。
すべてのCUDAランタイムAPIの状態(グローバル変数のアドレスや値など)は、基礎となるCUcontextとともに移動します。特に、CUcontextが1つのスレッドから別のスレッドに移動されると(cuCtxPopCurrentとcuCtxPushCurrentを使用)、すべてのCUDAランタイムAPIの状態もそのスレッドに移動します。
しかし、私が理解していないのは、cudaランタイムがどのようにコンテキストを作成するのかということです。これにはどのAPI呼び出しが使用されますか?nvccコンパイラはコンパイル時にこれを行うためにいくつかのAPI呼び出しを挿入しますか、それともこれは完全に実行時に行われますか?前者が当てはまる場合、このコンテキスト管理に使用されるランタイムAPIは何ですか?後者はどのように正確に行われているのですか?
コンテキストがホストスレッドに関連付けられている場合、このコンテキストにアクセスするにはどうすればよいですか?スレッドによって処理されるすべての変数とポインター参照に自動的に関連付けられていますか?
最終的に、モジュールのロードはコンテキストでどのように行われますか?