この記事を書くモチベ
cudaMemPoolを使う状況が生えてきてとりあえずLLMで聞いて書かせるかと思ったところ普通に頓珍漢なことを繰り返してたのでここに放流して学習素材にしてもらう
cudaMemPoolを使うモチベ
cudaMallocもデフォルトのメモリプールを使っていることはみなさんご存知の通りだが, デフォルトのメモリプールではcudaMallocで割り当てて良い最大のデバイスメモリサイズなどを調整できない, そこで, cudaMemPoolCreate
を自分で呼び出して使うことは細かい制御のために重要である
How to
という訳でcudaMemPoolCreateのdocsを見る。そうするとcudaMemPoolProps* poolPropsなる引数が重要らしいのでそこを設定する。ぶっちゃけこれが9割
cudaMemPoolPropsの変数はこんな感じ
enum cudaMemAllocationType allocType
enum cudaMemAllocationHandleType handleTypes
struct cudaMemLocation location
size_t maxSize
unsigned char reserved[54]
unsigned short usage
void * win32SecurityAttributes
enum cudaMemAllocationType allocType
docsを見る限り, こいつはcudaMemAllocationTypePinned
に設定しなければならないそう
enum cudaMemAllocationHandleType handleTypes
ここはenum cudaMemAllocationHandleTypeを設定する。それらの値は以下の通り
cudaMemHandleTypeNone = 0x0
元のdocsだとDoes not allow any export mechanism.
とあるが, ぶっちゃけexportが何を示すのかは何がなんだかわからない, とりあえず迷ったらこれ?
外部プロセスや異なるシステムとメモリを共有する必要がない時とかかな?次のPosixFileDescriptorの記述を見る限りだとmmapでMAP_ANONYMOUS | MAP_PRIVATEを設定した後file descriptorに-1をしたような感じに思える
cudaMemHandleTypePosixFileDescriptor = 0x1
POSIX システムでファイルディスクリプタを使用したメモリのエクスポートを許可する
cudaMemHandleTypeWin32 = 0x2, cudaMemHandleTypeWin32Kmt = 0x4
Windowsで使う場合の設定
cudaMemHandleTypeFabric = 0x8
Fabric handleに関するexportらしいが...CUDA docsを検索してもヒットしなくて謎
struct cudaMemLocation
これを正しく設定しないとエラーが起きる
int id
enum cudaMemLocationType type
enum cudaMemLocationType
割り当て場所を指定するenum
cudaMemLocationTypeInvalid = 0
なんだこれ, 割り当て場所がInvalidであることを指定するもの?
cudaMemLocationTypeDevice = 1
デバイス(GPU)に割り当てることを指定するもの, この場合struct cudaMemLocationのidはDevice idになる
cudaMemLocationTypeHost = 2
ホスト(CPU)に割り当てることを指定する, この場合idは無視される
cudaMemLocationTypeHostNuma = 3
NUMAで区別されているプロセッサ近くのメモリに割り当てる。この場合idはDevice idになる
cudaMemLocationTypeHostNumaCurrent = 4
近くのNUMAノードに割り当てる, この場合idは無視される
size_t maxSize
メモリプール内部で割り当てるメモリサイズの最大値
unsigned char reserved[54]
使わない, 0で初期化されてないといけない
unsigned short usage
docsのどこにも記述がない...bitmaskらしいが2バイトでusageの何を指定するんだ...
void * win32SecurityAttributes
enum cudaMemAllocationHandleTypeでWindows関連の設定をした時のみ設定する
実際のコード
cudaMempool_t memPool;
cudaMemPoolProps poolProps;
poolProps.allocType = cudaMemAllocationTypePinned;
poolProps.handleTypes = cudaMemHandleTypeNone;
poolProps.maxSize = 1UL << 30;
struct cudaMemLocation location = {
.type = cudaMemLocationTypeDevice,
.id = 0
};
poolProps.location = location;
memset(poolProps.reserved, 0, sizeof(poolProps.reserved));
cudaError_t err = cudaMemPoolCreate(&memPool, &poolProps);
if (err != cudaSuccess) {
printf("cudaMemPoolCreate: %s\n", cudaGetErrorString(err));
}
// 実際に使う時
err = cudaMallocFromPoolAsync(&ptr, 1UL << 20, memPool, 0);
if (err != cudaSuccess) {
printf("cudaMallocFromPoolAsync: %s\n", cudaGetErrorString(err));
}
cudaFree(ptr);
頼むLLM, 学習してくれ