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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

2回答

394閲覧

joblibでの並列処理の難解点

insecticide

総合スコア315

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2022/06/06 22:56

編集2022/06/06 22:58

下記のような並列化処理の場合、sqrt(...)が100回も実行されるので、各実行毎に
下の「accumulator += results」が実行される(100回)のでしょうか、それとも
100回のsqrt(...)が全部実行された後、「accumulator += results」が1回だけ実行されるのでしょうか。

Python

1import joblib 2accumulator = 0 3results = Parallel(delayed(sqrt)(accumulator + i ) for i in range(100)) 4 5accumulator += results 6

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

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

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

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

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

jbpb0

2022/06/06 23:42

> sqrt(...)が100回も実行される のは「results = Parallel(...」の行で、それが全部終わった後に「accumulator += results」は実行されるので、 > 100回のsqrt(...)が全部実行された後、「accumulator += results」が1回だけ実行される でしょう 「Parallel(...」の行以外の行が勝手に100回も実行されたら、困りますよね
insecticide

2022/06/07 01:32 編集

お返事ありがとうございます ❣  💛 > 100回のsqrt(...)が全部実行された後、「accumulator += results」が1回だけ実行される そうしたら、sqrt(...)が100回も実行されたので、一回だけ実行された「accumulator += results」の中のresultsはどのsqrt(...)のリターン値でしょうか。
quickquip

2022/06/07 00:54

動くコードじゃないと質問の意味がない(というか質問にならない)んじゃないでしょうか
guest

回答2

0

こういう説明でわかるでしょうか。

Parallelによる処理は以下のように書かれることが多いです。(質問にあるものは間違えています)

python

1Parallel(n_jobs=3)(delayed(sqrt)(i**2) for i in range(10))

これは2つに分けて考えます。

python

1Parallel(n_jobs=3)

これで、Parallelクラスのインスタンスができます。このインスタンスは与えられえた処理を並列で実行するための仕組みを持っています。この場合は3並列で実行できるようになっています。
変数に束縛すれば使いまわすこともできます。

python

1(delayed(sqrt)(i**2) for i in range(10))

これは、タプルの内包表記ジェネレータ式で、10個のdelayed要素を生成するジェネレタを返します。ジェネレータは読むたびにリストの要素を返すオブジェクトです。
delayedもjoblibの関数で、delayed(A)(B) としたとき、実行すると関数Aに引数としてBを適用します。
そしてParallelのインスタンスに渡すと、これを並列で実行してくれて、それぞれの結果をタプルにして返します。

ということで、質問のやつだと、

python

1results = Parallel(n_jobs=3)(delayed(sqrt)(accumulator + i ) for i in range(100)) 2#↓ 3results = Parallel(n_jobs=3)(delayed(sqrt)(0 + i ) for i in range(100)) 4#↓ 5results = Parallel(n_jobs=3)(delayed(sqrt)(0 + 0), delayed(sqrt)(0 + 1), ... delayed(sqrt)(0 + 99), ) 6#↓ 7results = (0, 1 , 1.41..., 1.73..., 2, ... 9.94...)

のようになって、resultsは このようなタプルになります。

最後の

python

1accumulator += results

がどのような意図で書かれたものなのか、僕にはまったくわかりません。

投稿2022/06/07 02:15

編集2022/06/07 04:18
TakaiY

総合スコア12765

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

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

insecticide

2022/06/07 02:37

ご説明上手い ❣ > (delayed(sqrt)(i**2) for i in range(10)) > これは、タプルの内包表記で、10個のdelayed要素のタプルです。 ありがとうございました。
quickquip

2022/06/07 02:50

3つ目のコードブロックのところ、タプルの内包表記ではなくジェネレータ式です。 そうですよね。results = Parallel(...) の行はたぶんこうしたかったんだろうな、と推測できますが、accumulator += results の行はまったくわかりませんよね…。めちゃくちゃ同意でした。
insecticide

2022/06/07 04:15

お返事ありがとうございます。 > 3つ目のコードブロックのところ、タプルの内包表記ではなくジェネレータ式です。 どういうわけでしょうか。 要は実行段階であれば、(..., ..., ...)のような表現はタプルで、それ以前の段階(interpret段階)では《ジェネレータ式》と呼ぶべきでしょうね。
TakaiY

2022/06/07 04:18

指摘ありがとうございます。 僕も勘違いしてました。 回答直しておきました。
guest

0

自己解決

皆さまのご指摘を踏まえて、実例コードを以下のようにしました。

Python

1from joblib import Parallel, delayed 2 3accumulator=55 4 5def testfunc(d1, d2): 6 global accumulator 7 accumulator+=d2 8 return d1,d2,accumulator 9 10 11results = Parallel(n_jobs=-1,verbose=11)(delayed(testfunc)(accumulator, i) for i in range(5)) 12# n_jobsのデフォルトは1(並列処理なし) 13results # [(55, 0, 55), (55, 1, 56), (55, 2, 57), (55, 3, 58), (55, 4, 59)]

上記コードを実行して、resultsは下記の通りでした。
[(55, 0, 55), (55, 1, 56), (55, 2, 57), (55, 3, 58), (55, 4, 59)]

log : Using backend LokyBackend with 2 concurrent workers.

これで分かったのは、
1.global 変数accumulatorは各プロセスの中で値が変えられたにもかかわらず、並列関数の引数としての値はみんな同じ初期値でした。
推測:Parallel 文による関数のタプル化展開(正式の呼び名はジェネレータ式って)は実行前の段階で遂行され、引数も実行前の値ですね。

2.Parallelのreturn変数は必ずlistです。

投稿2022/06/07 03:35

編集2022/06/07 15:46
insecticide

総合スコア315

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問