goo blog サービス終了のお知らせ 

雑記帳(新居)

移転完了しました

Folding@Homeで課題待ち時間を減らして、難病解明にさらに貢献

2020-05-08 00:14:00 | MyPC
新型コロナウイルス解析のプロジェクトが開始されて以来、Folding@home(本記事ではF@Hと略す)の参加者が増えすぎ、課題不足で待たされることが多い。直近ではましになっているものの、新型コロナウイルス解析が始まった3月いっぱいと4月中旬は、本当にひどかった。
F@Hのクライアントは、課題不足で取得に失敗が続いた場合、リトライの待ち時間が倍々ペースで長くなっていく。(それ以外の原因の場合でも同様)これが大問題で、初回のリトライは1分後だが、10回も連続で失敗したら1時間といった待ち時間になる。仕事中か寝ている間、人間が監視できない時間は、全く課題を取得できず、マシンが遊んでいるという事態が多発する。
ここで、F@Hのスロットの停止・再開をすると、この待ち時間がリセットされて、また1分前後の待ち時間から再開できる。
マスクの争奪戦にも似たような状況である。課題は常時少しずつ入荷している。しかし課題が不足している状況には変わりなく、入荷したら、待ち構えている猛者たちにすぐに全部持っていかれる。漠然と動かしているだけでは、いつまでたっても課題を入手できない。
そこで、何らかの方法で課題取得待ちを判定して、待ち状態なら上記のタイマーのリセットをするようなことができないかと漠然と考えていた。するとすでに同じことを考えた人がいた。
Folding@homeでWorkUnitを得られずにシステムリソースを遊ばせてしまう状態を回避する
F@HにはFAHClient APIがあり、Telnetで接続してAPIをたたくことができる(デフォルトでポートは36330)。このAPIを使えば、各スロットの状態を把握、上記の停止・再開もできる。
上の記事の方はrequest-wsを投げてその結果をexpectを使って判定しているが、queue-infoを使ってqueueの状態を取得・解析すれば、待ち状態をより的確に判定できそうだ。大筋では以下のような感じだ。

  1. Telnetでqueue-infoを取得しファイルにリダイレクト

  2. queue-infoを解析して、対象スロットが課題取得待ちかどうかを判定

  3. 課題取得待ち状態のスロットに対して、Telnetでpause→unpause実行



queue-infoを使うと、advanced controlの画面でWork Queueの情報として見られるものがすべて得られる。Work Queueの情報から、StatusがDownloadかつNext Attemptがある程度以上なら、待ち状態と判定できる!さて、Next Attemptの時間の表記は、1分未満ならSS secs、1分以上1時間未満ならMI mins SS secs、1時間以上ならHH hours MI minsという感じ。まともに解析するのは極めて難しそうだ。'min'を含んでいれば1分以上とみなしてスロット停止・再開するという、荒っぽい判定にする。
Telnetの自動実行は、echoでTelnetに食わせたいコマンドを出力して、Telnetにリダイレクトすればよい。まるでコロンブスの卵だ。(続けてコマンドを実行させる場合は、間に適切にスリープを入れる。)
そしてこれをcronで一定間隔で実行する。
ここまでわかれば実装は難しくはない。

これで、ようやく枕を高くして寝ることができる。

課題待ちのときにpause→unpauseするシェルスクリプト(fahcheck.sh)
#!/bin/bash

# if FAHClient is not running, do nothing
ps aux | grep FAH | grep -v grep > /dev/null 2>&1
if [ $? -ne 0 ]; then
  exit 0
fi

# get queue info
( echo "open localhost 36330"; sleep 1; echo "queue-info"; sleep 1; echo "quit" ) | telnet > fahqueue.log
# analyze queue info for slot 00
/usr/bin/python3 fahqueue.py 00
# pause and unpause if slot 00 is waiting
if [ $? -ne 0 ]; then
  echo 'request a WU for slot 00'
  ( echo "open localhost 36330"; sleep 1; echo "pause 00"; sleep 10; echo "unpause 00"; sleep 1; echo "quit" ) | telnet
else
  echo 'slot 00 is working'
fi
# analyze queue info for slot 01
/usr/bin/python3 fahqueue.py 01
# pause and unpause if slot 01 is waiting
if [ $? -ne 0 ]; then
  echo 'request a WU for slot 01'
  ( echo "open localhost 36330"; sleep 1; echo "pause 01"; sleep 10; echo "unpause 01"; sleep 1; echo "quit" ) | telnet
else
  echo 'slot 01 is working'
fi


課題待ちを判定するpythonスクリプト(fahqueue.py)
#!/usr/bin/python3
import json
import sys

path = '/home/yourname/fahqueue.log'

queueinf = ''
skip = True
with open(path) as f:
  for s_line in f:
    if s_line.startswith('['):
      skip = False
    if s_line.startswith(']'):
      queueinf += ']'
      skip = True
    if skip:
      continue
    queueinf += s_line

print(queueinf)

args = sys.argv
slot = args[1]

queue = json.loads(queueinf)
request = True
for work in queue:
  print(work['id'])
  if work['slot'] != slot:
    continue
  if work['state'] == 'RUNNING':
    print('running')
    request = False
    break
  if work['state'] == 'DOWNLOAD' and 'min' not in work['nextattempt']:
    print('retry soon')
    request = False
    break
print(request)
if request:
  sys.exit(1)
else:
  sys.exit(0)



最新の画像もっと見る

コメントを投稿

サービス終了に伴い、10月1日にコメント投稿機能を終了させていただく予定です。