はじめに
Windows上でSCOOPというPythonのライブラリで分散コンピューティングを試したときのメモです。
SCOOPはタスク分散のためのPythonライブラリで、Windowsのパッケージ管理ツールのScoopとは別物。ややこしいです。
並列とか分散とかは素人のため、偉い人がやれと言うからには出来るものと信じて色々調べたのですが結果できなかったので、自分と同じ無駄足を踏むものが出ないよう残します。
できない理由
SCOOPによる複数台PCでの分散実行では、処理の中で
os.getpgrp()
という関数を呼び出します。これがUnixでしか使えないため、エラーになってしまいます。
Windows Subsystem for Linuxを使えば、それ上ではgetpgrp()を使えるのですが、あくまでLinux上での実行になってしまうためWindowsでの分散実行にはならないです。
自PC内での並列実行は可能なため騙されそうになりましたが、つまり
--host <host>
を指定するとエラーになります。
やったこと
以下参考のため試した手順を残します。
準備
インスタンスの用意
- AWSにEC2のインスタンスを二つ用意
- 接続元と接続先
- 今回は二つとも「Windows Server 2019」
- Windows Server 2016だとOpenSSHの用意が手動になる
- どちらも固定IPを発行
- 接続先となるインスタンスのセキュリティグループのインバウンドルールに「SSH」を全アドレスOKで追加(面倒なので)
- フォルダの表示設定で「ファイル名拡張子」「隠しファイル」にチェック
SSH接続(公開鍵認証)の用意
- OpenSSH サーバー機能の追加
- 設定→アプリ→オプション機能の管理→機能の追加→「OpenSSH サーバー」をインストール
- サービスからOpenSSHを「開始」し、スタートアップの種類を「自動」に変更
- ファイアウォールの「受信の規則」で「新しい規則...」をポート番号「22」で追加
- 念のためインスタンス間でSSH通信ができることを確認
-
ssh Administrator@<もう一方のインスタンスのIP>
でログインができるかどうか、タイムアウトせず、パスワードを求められるかどうかを確認
-
- 公開鍵通信の設定
- インスタンス間でSSHの公開鍵による通信ができるように設定する
- 接続元のインスタンスでssh-keygenで秘密鍵・公開鍵のペアを作成
- 公開鍵(***.pub)を接続先インスタンスの.sshフォルダ直下に置いて、「authorized_keys」にリネーム
- .sshフォルダは特別なことをしなければ「C:\Users\Administrator\.ssh」にあるはず
- 今回は1個目なのでリネームとしたが、2個目以降はauthorized_keysの中に追記していくこと
- 接続先の「C:\ProgramData\ssh\sshd_config」ファイルの最後の2行(Administratorsがどうとか書いてる行)を「#」でコメントアウトし、OpenSSHを再起動
- configファイルの作成
- 接続元のインスタンスで「.ssh\config」を作成し、以下のように接続名・接続先を定義する
- Host以外にインデントがあるのは複数の接続先を記述した際の読みやすさのためなので面倒なら下げなくてOK
- 今回の例では
ssh test
で接続が成功すればOK
Host <任意の名称>
HostName <接続先のIPアドレス>
User <任意のユーザー>
Port <使用したいポート>
IdentityFile <自分が持っている秘密鍵のパス>
--- 以下は今回の例 ---
Host test
HostName **.***.***.***
User Administrator
Port 22
IdentityFile C:/Users/Administrator/.ssh/id_rsa
build tools for visual studio 2019のインストール
- 公式ページの画面下の方にある「Visual Studio 2019のツール」を開く
- Build Tools for Visual Studio 2019をダウンロードして実行
- C++ Build Toolsにチェック
- この時画面右側に現れるチェックリスト下にあるMSVC140,141の二つにもチェックを入れて「インストール」
Pythonの用意
- pythonをインストール
- 最新版の3.9.0を使用した
- anaconda等を使用せず直でインストール
- ライブラリのインストール
- pip install pyzmq
- SCOOPの公式マニュアルにはダウンロードして来いと書いてますがURLのファイルかなり古いです…
- pip install scoop
- pip install pyzmq
- 分散したいpythonプログラムを用意
-
公式マニュアルの
map_doc.py
をコピペ - 並列実行したい関数は
furures.map(分散したい関数, ←の関数に渡したい引数)
で指定
-
公式マニュアルの
from __future__ import print_function
from scoop import futures
def helloWorld(value):
return "Hello World from Future #{0}".format(value)
if __name__ == "__main__":
returnValues = list(futures.map(helloWorld, range(16)))
print("\n".join(returnValues))
試行
ここまで出来たらあとは公式マニュアルの通りに
python -m scoop -n 8 map_doc.py
これだと自PC内での並列実行であり普通に成功してしまうので
python -m scoop -n 8 --host test map_doc.py
こうすると以下のエラーが出て失敗してしまいます。
このエラーの最後に書いてあるAttributeError: module 'os' has no attribute 'getpgrp'
が失敗の原因です。無いものは無いです。
b'Traceback (most recent call last):\r\n File "C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python39\\lib\\runpy.py", line 197, in _run_module_as_main\r\n return _run_code(code, main_globals, None,\r\n File "C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python39\\lib\\runpy.py", line 87, in _run_code\r\n exec(code, run_globals)\r\n File "C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\scoop\\broker\\__main__.py", line 65, in <module>\r\n sys.stdout.write(str(os.getpgrp()) + "\\n")\r\nAttributeError: module \'os\' has no attribute \'getpgrp\'\r\n'
最後に
諦めかけてきたころ他の人に相談してみると「分散コンピューティングとかやりたいときは将来的にスパコンでも使ってみる、みたいなパターンが多いからそもそもLinux前提でプログラム書くよ、Windowsではあんまりやらないよ」的なコメントいただきました。そういうことらしいです。
今回WindowsでやりたかったのはWindows PC上で動くことが前提で書かれてるプログラムを並列実行したかったからなのですが、OSに関数が無いものは無いということで仕方ないです。
参考リンク
https://scoop.readthedocs.io/en/0.7/index.html
https://docs.python.org/ja/3/library/os.html
http://fx-kirin.com/python/python-scoop/
https://www.server-world.info/query?os=Windows_Server_2019&p=ssh&f=3