0

CUDA 8.0 を搭載したバージョン 0.8.0RC の JCuda を使用して、GTX1080 GPU で行列乗算を行っています。2 つの行列 A と B を行優先のベクトル形式でデバイスに読み込み、デバイスから積行列を読み取ります。しかし、予想よりも早くデバイスのメモリが不足していることに気付きました。たとえば、行列 A の次元が 100000 * 5000 = 5 億エントリ = 2GB 相当の float 値である場合、次のようになります。

cuMemAlloc(MatrixA, 100000 * 5000 * Sizeof.FLOAT); 

正常に動作します。しかし、数または行を 100000 から 110000 に増やすと、この呼び出しで次のエラーが発生します (行列 B と C のメモリ割り当ての前に行われるため、これらは問題の一部ではありません)。

Exception in thread "main" jcuda.CudaException: CUDA_ERROR_OUT_OF_MEMORY
at jcuda.driver.JCudaDriver.checkResult(JCudaDriver.java:344)
at jcuda.driver.JCudaDriver.cuMemAlloc(JCudaDriver.java:3714)
at JCudaMatrixMultiply.main(JCudaMatrixMultiply.java:84) (my code)

問題は、このサイズのマトリックスをデバイスに割り当てるのに約 2.2GB しかかからず、GTX1080 には 8GB のメモリがあるため、メモリが不足している理由がわかりません。誰もこれについて何か考えがありますか?CUDA 8 のリリース バージョンで JCuda 0.8.0RC を使用しているのは事実ですが、JCuda 0.8.0RC で使用するために CUDA 8 の RC バージョン (8.0.27) をダウンロードしようとしたところ、問題が発生しました。 . ただし、バージョンの互換性が問題になる可能性がある場合は、もう一度試すことができます。

もちろん、100000 * 5000 の行列はかなり大きいので、ニューラル ネットワーク プロジェクトでしばらくの間、より大きな行列を使用する必要はありませんが、この新しいプロジェクトで 8 GB のメモリをすべて使用できると確信したいと思います。カード。助けてくれてありがとう。

4

1 に答える 1

2

tl;dr:

通話時

cuMemAlloc(MatrixA, (long)110000 * 5000 * Sizeof.FLOAT); 
//                     ^ cast to long here

または代わりに

cuMemAlloc(MatrixA, 110000L * 5000 * Sizeof.FLOAT); 
//                        ^ use the "long" literal suffix here

それはうまくいくはずです。


への最後の引数cuMemAllocの型はsize_tです。これは、 「任意の」サイズの実装固有の符号なし整数型です。これに最も近い Java のプリミティブ型は ですlong。そして一般にsize_t、CUDAのすべてlongは JCuda にマッピングされます。この場合、Javaは としてJNI レイヤーにlong渡され、これは実際のネイティブ呼び出しに対して単純にキャストされます。 jlongsize_t

(Java の unsigned 型の欠如と C の奇数の整数型は、依然として問題を引き起こす可能性があります。C の型と Java の型が一致しない場合があります。ただし、割り当てが 900 万テラバイトを超えない限り、 (!)、longここでは a で問題ないはずです...)

しかし、正しい軌道へのリードによるコメント。havogtここ実際に起こるのは整数オーバーフローです: 実際の値の計算

110000 * 5000 * Sizeof.FLOAT = 2200000000

はデフォルトintで Java の型を使用して行われ、ここでオーバーフローが発生します: 2200000000 は より大きいですInteger.MAX_VALUE。結果はの値になります。size_tこれがJNI レイヤーの (符号なし) 値にキャストされると、途方もなく大きなの値になり、明らかにエラーが発生します。

long明示的にキャストするか、リテラルの 1 つにサフィックスを追加することによって、値を使用して計算を行う場合、値は 2200000000 の適切な値として CUDA に渡さlongれます。Llong

于 2016-11-11T17:40:51.780 に答える