質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

2949閲覧

numba for CUDA の使い方が分からない

takasi2216

総合スコア8

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/30 10:02

質問の背景

nunba for cuda を使用するとpythonでの計算が数百倍になるという記事を読んで、実際にやってみようと思いましたが、エラーが出てしまいます。

1万まで1を足していくプログラムを試しに作ってみましたが、

py

1from numba import cuda 2 3@cuda.jit 4def hello(): 5 count = 0 6 for i in range(10000): 7 count+=1 8 return count 9 10print(hello()) 11

error

1ValueError: 2Kernel launch configuration was not specified. Use the syntax: 3 4kernel_function[blockspergrid, threadsperblock](arg0, arg1, ..., argn) 5 6See https://numba.pydata.org/numba-doc/latest/cuda/kernels.html#kernel-invocation for help.

このようなエラーが出てきてしまいました。

おそらく使い方が間違っていると思いますが、ネットに情報が少なくどうすればいいかよく分かりません。

###質問

例えば質問の背景に示したように0から1を1万回足すプログラムをnumba for cudaを用いて高速化したい場合、どのように記述すればいいですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2021/10/30 10:15 編集

参考にした記事、調査、試したことの詳細を記載ください。 なお、質問への追記・修正の依頼や回答がついていいるにもかかわらず、それらに反応がない過去の質問が多いようですが、受け答えができない(あなたが放置する)ユーザーとみなされると(第三者にも)放置される可能性が高いことを認識ください。
guest

回答2

0

1を1万回足すプログラム

を、「1万個の1を足すプログラム」と置き換えて、以下書きます

ただし、一つの変数に結果を合算するのは、
CUDAで配列の総和を求めてみた
等に書かれてるように、CUDAで速度を出すために並列化するにはいろいろと工夫が要るケースで、この回答のCUDAを用いたコードはそこを頑張ってないので、

python

1import numpy as np 2import time 3 4number_of_maximum_loop = 10000 5 6start = time.time() 7count = np.sum(np.ones(number_of_maximum_loop, dtype="int")) 8elapsed_time = time.time() - start 9print(count) 10print("elapsed_time:{0}".format(elapsed_time) + "[sec]")

に速度で圧倒的に負けますので、

numba for cudaを用いて高速化

は満たしてません
とりあえず、こう書けばエラーが出なくなります、というだけです
(注:【追記】に書いたように、データのサイズを大きくしたらCUDAとnumpyの速度が逆転しました)

 
numba cuda does not produce correct result with += (gpu reduction needed?)
を参考にした、質問に掲載のエラーを回避したコード

python

1from numba import cuda 2import time 3 4@cuda.jit 5def cuda_kernel(number_of_maximum_loop, result): 6 i = cuda.grid(1) 7 if i < number_of_maximum_loop: 8 cuda.atomic.add(result, 0, 1) 9 10number_of_maximum_loop = 10000 11threadsperblock = 1024 12blockspergrid = (number_of_maximum_loop + (threadsperblock - 1)) // threadsperblock 13 14result = cuda.to_device([0]) 15cuda_kernel[blockspergrid, threadsperblock](number_of_maximum_loop, result) 16count = result.copy_to_host()[0] 17# 1回目はコンパイルするため2回目を測定 18start = time.time() 19result = cuda.to_device([0]) 20cuda_kernel[blockspergrid, threadsperblock](number_of_maximum_loop, result) 21count = result.copy_to_host()[0] 22elapsed_time = time.time() - start 23print(count) 24print("elapsed_time:{0}".format(elapsed_time) + "[sec]")

 
.
GPU Reduction
を参考にしたコード

python

1 2import numpy as np 3from numba import cuda 4import time 5 6@cuda.reduce 7def sum_reduce(a, b): 8 return a + b 9 10number_of_maximum_loop = 10000 11 12count = sum_reduce(np.ones(number_of_maximum_loop, dtype="int")) 13# 1回目はコンパイルするため2回目を測定 14start = time.time() 15count = sum_reduce(np.ones(number_of_maximum_loop, dtype="int")) 16elapsed_time = time.time() - start 17print(count) 18print("elapsed_time:{0}".format(elapsed_time) + "[sec]")

 
.
【追記】
Google ColabでGPUを有効にして確認したところ、

python

1number_of_maximum_loop = 10000

python

1number_of_maximum_loop = 1000000000

に変えたら、上記の一つ目のCUDAを用いたコードの速度はnumpyだけのコードの速度をやや上回りましたので、扱うデータのサイズが大きくなるとCUDAが有利になるようです
CUDAのコードを、回答の最初に提示したWebページに書かれてるような合算の高速化に対応させたものにすれば、さらにCUDAの方が有利になると思います (未確認)
ただし、「number_of_maximum_loop = 1000000000」の場合でも上記二つ目のCUDAを用いたコードはnumpyだけのコードよりもやや遅いです
もしかしたら、下記で指摘されてるバグが、まだ直ってないのかもしれません
Numba CUDA vectorize and reduce decorators slower than expected #2266

投稿2021/10/30 13:10

編集2021/11/01 05:19
jbpb0

総合スコア7653

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

エラーメッセージの最後に表示されている文言にある URL にアクセスしてみると、

See https://numba.pydata.org/numba-doc/latest/cuda/kernels.html#kernel-invocation for help.

以下の様に書かれています。

Kernel invocation

A kernel is typically launched in the following way:

threadsperblock = 32 blockspergrid = (an_array.size + (threadsperblock - 1)) // threadsperblock increment_by_one[blockspergrid, threadsperblock](an_array)

なので、hello() 関数の呼び出しは以下の様に記述するのではないでしょうか([10, 20] は適当な値です)。

python

1print(hello[10, 20]())

投稿2021/10/30 11:43

melian

総合スコア20655

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問