GPU と CPU を跨ぐようなデータの取り扱いについて

591 views
Skip to first unread message

相川始

unread,
Mar 6, 2016, 1:53:41 AM3/6/16
to Chainer Japanese User Group
相川と申します.
件名にもありますように,GPU と CPU を跨ぐようなデータの取り扱いについてお聞きしたいことがあります.
お手数お掛けしますが,ご回答頂けますと幸いです.

(1)

ある Variable object の data を cupy.ndarray 型として入力に与え,何らかの関数を計算した結果として帰ってくる Variable object の data は常に cupy.ndarray 型のものとなっているという理解でよろしいのでしょうか?
mnist のサンプルを確認したところ,計算結果として帰ってくる loss.data を足し合わせたものを,to_cpu() メソッド等を用いず直接 CPU 側の変数である loss_sum に和算することが出来ているようでした.
上記のような規則性を持っているものと仮定すると,GPU 上に配置されている loss.data が,CPU 上に配置されている sum_loss に足されているように見えます.
かなり前の経験なため記憶があいまいなのですが,ネイティブの CUDA で書く場合,そのようなケースでは一度 GPU 上に配置されたデータを CPU 側に転送してから足し合わせる必要があったような気がするので,Chainer では GPU 上と CPU 上のデータをどのように扱っているのかが気になりました.
どのような理屈で上記のような計算手続きが実現されているのでしょうか.
また GPU と CPU を跨ぐデータの取り扱いに関して,何か一貫した規則のようなものがありましたら,お教え頂けませんでしょうか.

(2)

(1)と似たような質問です.
Chainer で GPU を使用してモデルを学習する場合,model (Link object) を to_gpu() メソッド等を用いて,GPU 側に配置しなければならないものと理解しています.
この to_gpu() メソッドは,対応する オブジェクトを全て GPU 側のメモリに移行し,CPU 側のメモリは一度全て解放している認識でよろしいのでしょうか?
仮に GPU 側にオブジェクトを全て転送していた場合,CPU 側のメモリにはデータが残っていないはずだと思うのですが,mnist のサンプルを見ると to_cpu() を使うことなく,save_npz() を使用することが出来ているようなので気になりました.

私自身,プログラムはあまり得意なほうではないので,見当違いなことを言っていたら申し訳ありません.
質問をまとめさせて頂くと,Chainer における GPU 上と CPU 上を跨ぐようなデータの取り扱いについてより詳しく知りたいということです.
ご回答やアドバイスを頂けますと非常に助かります,よろしくお願いいたします.

Kenta Oono

unread,
Mar 7, 2016, 8:23:18 AM3/7/16
to Chainer Japanese User Group
大野です。

(1) model.loss.dataはcupy.ndarrayですが、float()実行時にcupy.ndarray.__float__()が呼ばれ、
そこで、cupy.ndarray.get()によりデータをCPUに転送しています。

(2) modelをto_cpu()することなく保存することができるのは、
save_npzが内部で利用しているDictionarySerializerの仕様によるものです。
DictionarySerializerはcupy.ndarrayをシリアライズするときに、データをCPUに転送しています。

このような返答でお答えになっていますでしょうか。

2016年3月6日日曜日 15時53分41秒 UTC+9 相川始:

相川始

unread,
Mar 8, 2016, 1:22:40 PM3/8/16
to Chainer Japanese User Group
大野さま

ご返信頂きありがとうございます.
返信が遅くなってしまい申し訳ありません.

お聞きしたかったのはご回答頂いたような内容で合っております.
おそらく内部で隠蔽してやってくれているのであろうなとは感じていたのですが,私には内部まで目を通す力が不足しておりました故.

念のため追加でお聞きしておきたいことがあるのですが,GPU と CPU のデータ処理を利用者側で明示的に行わなければならない状況はどのような場合が考えられるのでしょうか.
現状私が理解している範囲では,ネットワークモデルの転送と 学習用データの転送の 2 状況だけなのですが,それ以外にも明示的にデータの転送処理をしなければならない状況 (転送処理が隠蔽されていない状況) はあるのでしょうか?

以上,お手数お掛けしてしまい申し訳ありませんがご回答頂けますと助かります.
よろしくお願いいたします.

相川

2016年3月7日月曜日 22時23分18秒 UTC+9 Kenta Oono:

Kenta Oono

unread,
Mar 10, 2016, 1:49:31 AM3/10/16
to Chainer Japanese User Group
大野です

> 念のため追加でお聞きしておきたいことがあるのですが,GPU と CPUのデータ処理を利用者側で
> 明示的に行わなければならない状況はどのような場合が考えられるのでしょうか.
記憶している範囲では、CPU側にあるデータをGPU側で処理をしたい時には、
明示的にデータをGPUに送る必要があります(間違っていたらすみません)。

ただ、Chainerの利用シーンをすべて網羅するのは難しいので、
ある関数内で暗黙的にCPU・GPU間の転送や異なるGPU間での転送が行われるかは、
インタープリタで簡単なコードを書いて実験をしてみるのが確実な方法だと思います。


2016年3月9日水曜日 3時22分40秒 UTC+9 相川始:

相川始

unread,
Mar 10, 2016, 1:15:25 PM3/10/16
to Chainer Japanese User Group
大野さま

ご返信頂きありがとうございます.
暗黙のデータ転送に何かルールのようなものがないのかなと思い質問させて頂いたのですが,やはりコードレベルで実際に試してみて転送の有無を確認するのが確実なのですね.
今後は関数を使用する前にメモリ転送の挙動を調べる,もしくはメモリ転送は常に明示的に制御するといった形式でコードを書いてみようと思います.
漠然とした質問であったにも関わらず丁寧にご対応して頂き誠にありがとうございました.

相川

2016年3月10日木曜日 15時49分31秒 UTC+9 Kenta Oono:
Reply all
Reply to author
Forward
0 new messages