...
 
Commits (123)
......@@ -3,6 +3,8 @@
.DS_Store
*.txt
*.tmp
*.json
# Object files
*.o
......@@ -17,3 +19,7 @@ solver
# Python files
*.pyc
__pycache__/
# client-icons
client-icon/
This diff is collapsed.
This diff is collapsed.
SIZE 8X8X8
LAYER 1
2,35,35,35,15,19,17,9
7,35,37,37,15,15,17,11
7,35,37,39,0,0,0,11
7,35,37,39,0,0,0,11
0,35,37,39,0,0,0,11
0,35,37,39,0,11,11,11
0,11,11,11,11,11,3,4
1,0,0,0,0,0,3,4
LAYER 2
2,33,31,0,43,19,41,9
25,0,31,0,43,15,17,11
25,0,31,0,43,15,17,13
7,7,7,7,0,15,17,13
27,27,27,7,0,15,17,13
0,0,0,7,0,15,17,13
25,25,0,7,0,17,17,0
1,25,0,7,7,7,3,4
LAYER 3
2,33,0,0,41,19,41,9
41,41,41,41,41,19,0,9
25,0,31,0,0,19,0,9
25,31,31,0,19,19,0,9
27,31,27,27,27,27,27,9
25,31,30,30,30,15,9,9
25,31,30,0,19,9,9,0
1,25,25,19,19,9,3,4
LAYER 4
2,33,0,0,41,41,41,21
0,33,47,23,48,48,0,45
0,33,47,23,0,48,0,45
25,33,47,23,19,48,0,45
25,33,0,23,19,48,0,45
25,33,0,23,19,15,0,45
0,30,30,23,19,15,0,45
1,1,1,21,21,15,4,4
LAYER 5
2,6,16,22,22,0,0,21
46,6,16,22,24,29,29,21
46,16,16,22,24,29,34,21
46,16,47,22,24,0,34,21
46,16,47,22,24,48,34,21
46,22,47,22,24,48,34,21
46,22,47,47,24,48,21,21
22,22,1,0,21,21,21,0
LAYER 6
2,5,10,20,20,26,26,26
6,6,10,20,0,32,32,26
10,10,10,29,29,29,0,26
10,28,28,28,28,28,28,28
10,16,16,16,0,0,0,0
10,22,22,22,0,0,34,0
10,42,42,42,42,42,42,42
10,42,1,1,1,1,1,1
LAYER 7
2,5,8,8,8,8,8,0
6,5,18,20,0,32,8,0
14,18,18,20,0,32,8,26
14,18,20,20,0,32,8,8
14,18,20,16,0,32,0,8
14,18,20,44,0,32,34,8
12,18,20,44,0,32,34,8
10,42,20,44,0,32,34,1
LAYER 8
2,2,2,2,2,2,2,2
6,5,0,12,12,12,12,0
12,12,12,12,40,38,36,0
12,0,0,0,40,38,36,0
12,0,0,16,40,38,36,0
12,0,0,16,40,38,36,0
12,18,0,16,38,38,36,8
10,18,20,16,36,36,36,1
SIZE 72X72X8
LINE_NUM 10
LINE#1 (6,22,8) (32,22,8)
LINE#2 (8,26,8) (29,26,8)
LINE#3 (8,27,8) (8,34,8)
LINE#4 (29,27,8) (29,37,8)
LINE#5 (8,35,8) (28,35,8)
LINE#6 (8,36,8) (8,36,1)
LINE#7 (44,23,8) (44,36,8)
LINE#8 (52,24,8) (52,35,8)
LINE#9 (61,23,8) (61,42,8)
LINE#10 (44,37,8) (44,37,1)
SIZE 72X72X8
LINE_NUM 22
LINE#1 (36,71,8) (36,71,2)
LINE#2 (37,71,5) (38,71,5)
LINE#3 (71,39,7) (71,34,7)
LINE#4 (71,34,6) (71,34,3)
LINE#5 (71,39,2) (71,34,2)
LINE#6 (34,1,7) (34,1,3)
LINE#7 (39,1,7) (35,1,7)
LINE#8 (39,1,6) (39,1,2)
LINE#9 (34,1,2) (38,1,2)
LINE#10 (1,35,7) (1,38,7)
LINE#11 (1,34,5) (1,39,5)
LINE#12 (1,36,4) (1,37,4)
LINE#13 (1,35,3) (1,36,3)
LINE#14 (1,34,2) (1,35,2)
LINE#15 (35,21,1) (12,21,1)
LINE#16 (57,55,1) (11,55,1)
LINE#17 (58,24,1) (58,55,1)
LINE#18 (56,5,7) (56,67,7)
LINE#19 (17,5,3) (17,67,3)
LINE#20 (56,22,8) (17,32,2)
LINE#21 (56,36,8) (17,46,2)
LINE#22 (56,50,8) (17,60,2)
SIZE 8X8X8
LINE_NUM 48
LINE#1 (0,7,1) (7,7,8)
LINE#2 (0,0,1) (7,0,8)
LINE#3 (6,6,1) (6,7,3)
LINE#4 (6,7,4) (7,6,1)
LINE#5 (1,1,8) (1,0,6)
LINE#6 (0,1,8) (1,0,5)
LINE#7 (0,1,1) (5,7,2)
LINE#8 (7,6,8) (2,0,7)
LINE#9 (5,7,3) (7,0,1)
LINE#10 (2,0,6) (0,7,8)
LINE#11 (1,6,1) (7,1,2)
LINE#12 (6,1,8) (0,6,7)
LINE#13 (7,2,2) (7,5,2)
LINE#14 (0,2,7) (0,5,7)
LINE#15 (4,0,1) (5,7,4)
LINE#16 (3,7,8) (2,0,5)
LINE#17 (6,0,1) (5,6,2)
LINE#18 (1,7,8) (2,1,7)
LINE#19 (5,0,1) (3,7,3)
LINE#20 (2,7,8) (4,0,6)
LINE#21 (3,7,4) (7,0,4)
LINE#22 (4,0,5) (0,7,5)
LINE#23 (3,1,4) (3,6,4)
LINE#24 (4,1,5) (4,6,5)
LINE#25 (0,1,2) (2,7,3)
LINE#26 (7,2,7) (5,0,6)
LINE#27 (6,4,3) (0,4,3)
LINE#28 (7,3,6) (1,3,6)
LINE#29 (6,1,5) (3,2,6)
LINE#30 (1,6,4) (4,5,3)
LINE#31 (2,0,2) (1,6,3)
LINE#32 (5,7,7) (6,1,6)
LINE#33 (1,0,2) (1,5,4)
LINE#34 (6,7,7) (6,2,5)
LINE#35 (3,0,1) (1,5,1)
LINE#36 (6,2,8) (4,7,8)
LINE#37 (3,1,1) (2,5,1)
LINE#38 (4,6,8) (5,2,8)
LINE#39 (3,2,1) (3,5,1)
LINE#40 (4,2,8) (4,5,8)
LINE#41 (6,0,2) (0,1,3)
LINE#42 (1,7,7) (7,6,6)
LINE#43 (4,0,2) (4,2,2)
LINE#44 (3,5,7) (3,7,7)
LINE#45 (7,1,4) (7,6,4)
LINE#46 (0,1,5) (0,6,5)
LINE#47 (2,1,4) (3,6,5)
LINE#48 (5,6,5) (4,1,4)
SIZE 8X8X8
LINE_NUM 49
LINE#1 (0,7,1) (7,7,8)
LINE#2 (0,0,1) (7,0,8)
LINE#3 (6,6,1) (6,7,3)
LINE#4 (6,7,4) (7,6,1)
LINE#5 (1,1,8) (1,0,6)
LINE#6 (0,1,8) (1,0,5)
LINE#7 (0,1,1) (5,7,2)
LINE#8 (7,6,8) (2,0,7)
LINE#9 (5,7,3) (7,0,1)
LINE#10 (2,0,6) (0,7,8)
LINE#11 (1,6,1) (7,1,2)
LINE#12 (6,1,8) (0,6,7)
LINE#13 (7,2,2) (7,5,2)
LINE#14 (0,2,7) (0,5,7)
LINE#15 (4,0,1) (5,7,4)
LINE#16 (3,7,8) (2,0,5)
LINE#17 (6,0,1) (5,6,2)
LINE#18 (1,7,8) (2,1,7)
LINE#19 (5,0,1) (3,7,3)
LINE#20 (2,7,8) (4,0,6)
LINE#21 (3,7,4) (7,0,4)
LINE#22 (4,0,5) (0,7,5)
LINE#23 (3,1,4) (3,6,4)
LINE#24 (4,1,5) (4,6,5)
LINE#25 (0,1,2) (2,7,3)
LINE#26 (7,2,7) (5,0,6)
LINE#27 (6,4,3) (0,4,3)
LINE#28 (7,3,6) (1,3,6)
LINE#29 (6,1,5) (3,2,6)
LINE#30 (1,6,4) (4,5,3)
LINE#31 (2,0,2) (1,6,3)
LINE#32 (5,7,7) (6,1,6)
LINE#33 (1,0,2) (1,5,4)
LINE#34 (6,7,7) (6,2,5)
LINE#35 (3,0,1) (1,5,1)
LINE#36 (6,2,8) (4,7,8)
LINE#37 (3,1,1) (2,5,1)
LINE#38 (4,6,8) (5,2,8)
LINE#39 (3,2,1) (3,5,1)
LINE#40 (4,2,8) (4,5,8)
LINE#41 (6,0,2) (0,1,3)
LINE#42 (1,7,7) (7,6,6)
LINE#43 (4,0,2) (4,2,2)
LINE#44 (3,5,7) (3,7,7)
LINE#45 (7,1,4) (7,6,4)
LINE#46 (0,1,5) (0,6,5)
LINE#47 (2,1,4) (3,6,5)
LINE#48 (5,6,5) (4,1,4)
LINE#49 (6,5,6) (6,7,6)
This diff is collapsed.
# ADC2018
---
A cooperative system using multiple FPGAs for a simple 3D-Numberlink puzzle solver
## Environments
実際のソルバで使用している環境.
+ デバイス
- Raspberry Pi 3 B+
- PYNQ
- ZU3EG
+ ソフトウェア
- Python >= 3.5 (通信プログラム)
* Flask
* gevent
* gevent-websocket
- Vivado (Web Pack) >= 18.1 (FPGAの合成)
## Setups
[Wiki](https://www.togawa.cs.waseda.ac.jp/gitlab/adc2018/adc2018-system/wikis/home)も参照されたい.
各端末でこのリポジトリをCloneする.
```
cd ~
git clone https://www.togawa.cs.waseda.ac.jp/gitlab/adc2018/adc2018-system.git
```
## System
+ サーバ
- [通信用スクリプト](comm/server)
+ ソルバ
- [通信用スクリプト](comm/client)
- [高位合成用プログラム](hls)
+ リゾルバ
- [通信用スクリプト](comm/resolver)
## Our previous works
* [pynq-router](https://github.com/kotarot/pynq-router)
* [nl-solver](https://github.com/kotarot/nl-solver)
## License
This software is released under GPL v3 License, see [LICENSE](LICENSE).
# DAS2017 ADC RaspberryPi・PYNQ間HTTP通信プログラム
# DAS2018 ADC RaspberryPi, ソルバ, リゾルバ HTTP通信プログラム
# 概要
DAS2017アルゴリズムデザインコンテストに向けた,端末間通信プラグラム.
親となるRaspberry Piから,子となる複数のPYNQに対し問題を配信し,結果を受け取る.
DAS2018アルゴリズムデザインコンテストに向けた,端末間通信プラグラム.
親となるRaspberry Piから,子となる複数のソルバ,リゾルバに対し問題を配信し,結果を受け取る.
# 構成
+ server: Raspberry Pi上で実行するためのサーバプラグラム.問題をクライアントに配信し,結果を受け取る.
+ client: PYNQ上で実行するためのクライアントプログラム.問題をサーバから受け取り,問題を解いて回答をサーバに返す.
+ server: Raspberry Pi上で実行するためのサーバプラグラム.問題をソルバに配信し,結果を受け取る.
+ client: ソルバをFPGA上で実行するためのクライアントプログラム.問題をサーバから受け取り,問題を解いて解けたら結果をリゾルバに送り,解けなかったら結果をサーバに報告する.
+ resolver: ソルバから初期解を受け取り,リゾルバでより良い解に整形する.
+ README.md: このファイル.
# Requirements
......
DAS2017 ADC クライアントプログラム
DAS2018 ADC クライアントプログラム
===
DAS2017 アルゴリズムデザインコンテスト用クライアントプログラム
DAS2018 アルゴリズムデザインコンテスト用クライアントプログラム
## Description
問題データをサーバから受信し,結果をサーバへ返すプログラム.
問題データをサーバから受信し,結果をリゾルバやサーバへ送るプログラム.
## Requirements
......@@ -22,7 +22,7 @@ python3 main.py [--port XXXX] [--host XXXX]
<dl>
<dt>-H, --host</dt>
<dd>サーバホストのアドレス (デフォルト:192.168.4.1:5000)</dd>
<dd>サーバホストのアドレス (デフォルト:192.168.5.1:5000)</dd>
<dt>-p, --port</dt>
<dd>使用するポート (デフォルト:5000)</dd>
......
......@@ -17,65 +17,16 @@ from urllib.parse import urlparse
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../solver')
import BoardStr
import pynqrouter
import adc2018solver as pynqrouter
app = Flask(__name__)
args = {}
pynq_thread = None
client_baseurl = ""
# Reference: https://teratail.com/questions/52593
class StoppableThread(threading.Thread):
def __init__(self, target, qname, qstr, qseed):
super(StoppableThread, self).__init__(target=target)
self._th_stop = threading.Event()
self._qname = qname
self._qstr = qstr
self._qseed = int(qseed)
self._answer = None
def run(self):
global client_baseurl
global pynq_thread
global args
# Main funciton (the solver should be placed here)
boardstr = BoardStr.conv_boardstr(self._qstr.split('\n'), 'random', self._qseed)
result = pynqrouter.solve(boardstr, self._qseed)
if result['solved']:
answer = result['solution']
else:
answer = None
pynq_thread = None
return
res = {
"client": client_baseurl,
"qname": self._qname,
"answer": answer,
"cputime": result['elapsed']
}
self._answer = answer
r = requests.post("http://{}/post".format(args["host"]), data=res)
if args["verbose"]:
print(res)
pynq_thread = None
def stop(self):
self._th_stop.set()
def stopped(self):
return self._th_stop.isSet()
def get_answer(self):
return self._answer
@app.route('/start', methods=["POST"])
def start():
global pynq_thread
# global pynq_thread
global args
global client_baseurl
......@@ -84,13 +35,26 @@ def start():
if args["verbose"]:
print(request.form)
if pynq_thread is None:
if pynqrouter.solver_thread is not None:
pynqrouter.stop_solver()
if pynqrouter.solver_thread is None:
qstr = request.form["question"]
qname = request.form["qname"]
qseed = request.form["qseed"]
pynq_thread = StoppableThread(target=StoppableThread, qname=qname, qstr=qstr, qseed=qseed)
boardstr = BoardStr.conv_boardstr(qstr.split('\n'), 'random', int(qseed))
option = {
"name": qname,
"host": args['host'],
"client": client_baseurl,
"req_id": request.form['req_id'],
"resolver": request.form['resolver']
}
pynq_thread.start()
print(option['req_id'])
pynqrouter.start_solver(boardstr, qseed, option)
# 実行だけ開始する
ans["status"] = "Processing"
......@@ -106,26 +70,21 @@ def start():
@app.route('/stop')
def stop():
global pynq_thread
if pynq_thread is None:
if pynqrouter.solver_thread is None:
ans = {"status": "No threads"}
else:
pynq_thread.stop()
# pynq_thread.stop()
pynqrouter.stop_solver()
ans = {"status": "Stopped"}
pynq_thread = None
return json.dumps(ans)
@app.route("/status")
def status():
global pynq_thread
res_mes = ""
if pynq_thread is None:
if pynqrouter.solver_thread is None:
res_mes = "Ready"
else:
res_mes = "Working"
......@@ -147,6 +106,11 @@ def before_request():
if __name__ == "__main__":
# Check if this script runs as "root" user
if os.getuid() != 0:
raise Exception("Must run as root")
sys.exit(1)
parser = argparse.ArgumentParser(description="PYNQ client.")
parser.add_argument("-p", "--port", action="store", type=int, default=5000, help="Port")
parser.add_argument("-H", "--host", action="store", type=str, default="192.168.4.1:5000", help="Host address")
......@@ -157,3 +121,4 @@ if __name__ == "__main__":
if args["debug"]:
app.debug = True
app.run(host='0.0.0.0', port=args["port"], threaded=True)
DAS2018 ADC クライアント(リゾルバ)プログラム
===
DAS2018 アルゴリズムデザインコンテスト用クライアントプログラム
## Description
解答データをソルバから受信し,整形した結果をサーバへ返すプログラム.
## Requirements
- Python 3.5以上(くらい)
- Flask
## Usage
```
python3 main.py [--port XXXX] [--host XXXX]
```
### Options
<dl>
<dt>-H, --host</dt>
<dd>サーバホストのアドレス (デフォルト:192.168.5.1:5000)</dd>
<dt>-p, --port</dt>
<dd>使用するポート (デフォルト:5000)</dd>
</dl>
#!/usr/bin/env python3
"""
This script provides a PYNQ client.
This is intended to run on the client server (PYNQ).
"""
import argparse
import json
import os
import platform
import queue
import requests
import subprocess
import sys
import threading
import time
from flask import Flask, render_template, request, g
from urllib.parse import urlparse
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../solver')
import BoardStr
# import adc2018solver as pynqrouter
app = Flask(__name__)
args = {}
client_baseurl = ""
resolve_queue = None
def resolve():
"""
queueを受け取りそこに入ってきた答えを整形し,ホストに送信します.
"""
global args
global client_baseurl
global resolve_queue
while True:
if resolve_queue is None:
time.sleep(1)
continue
else:
data = resolve_queue.get()
if args['verbose']:
print("Processing queued data...")
print(data)
outpath = "./works/resolved.txt"
probpath = "./problems/{}".format(data['qname'])
tmppath = "./works/answer.txt"
with open(tmppath, "w") as fp:
fp.write(data['answer'])
# Resolver
cmd = "/home/pi/adc2017/pynq-router/resolver/solver --reroute --output {} {} {}".format(outpath, probpath, tmppath)
subprocess.call(cmd.strip().split(" "))
resolved = ""
with open(outpath, "r") as fp:
resolved = fp.read()
print(data['req_id'])
res = {
'solution': resolved,
'solved': True,
'solver': data['client'],
'resolver': client_baseurl,
'client': client_baseurl,
'cputime': data['cputime'],
'qname': data['qname'],
'req_id': data['req_id']
}
# 結果をホストに返す
r = requests.post("http://{}/post".format(args['host']), data=res)
if args['verbose']:
print("Done.")
print(res)
@app.route('/post', methods=["POST"])
def start():
# global pynq_thread
global args
global client_baseurl
global resolve_queue
if args["verbose"]:
print(request.form)
data = {
'client': request.form['client'],
'qname': request.form['qname'],
'answer': request.form['solution'],
'cputime': request.form['cputime'],
'req_id': request.form['req_id']
}
resolve_queue.put(data)
ans = {"status": "Queued"}
if args["verbose"]:
print(ans)
return json.dumps(ans)
@app.route('/stop')
def stop():
global resolve_queue
if resolve_queue.empty() is None:
ans = {"status": "Nothing queued"}
else:
# pynq_thread.stop()
while not resolve_queue.empty():
resolve_queue.get()
ans = {"status": "Stopped"}
return json.dumps(ans)
@app.route("/status")
def status():
res_mes = ""
if resolve_queue.empty():
res_mes = "Ready"
else:
res_mes = "Working"
res = {"status": res_mes}
return json.dumps(res)
@app.route("/")
def index():
return platform.node()
@app.before_request
def before_request():
global client_baseurl
_url = request.url
parse = urlparse(_url)
client_baseurl = parse.netloc
if __name__ == "__main__":
# Check if this script runs as "root" user
# if os.getuid() != 0:
# raise Exception("Must run as root")
# sys.exit(1)
parser = argparse.ArgumentParser(description="PYNQ client (for resolver).")
parser.add_argument("-p", "--port", action="store", type=int, default=5000, help="Port")
parser.add_argument("-H", "--host", action="store", type=str, default="192.168.5.1:5000", help="Host address")
parser.add_argument("--debug", action="store_true", default=False, help="Debug mode.")
parser.add_argument("-v", "--verbose", action="store_true", default=False, help="Verbose.")
args = vars(parser.parse_args())
# Start resolver thread
resolve_queue = queue.Queue()
th = threading.Thread(target=resolve, args=())
th.setDaemon(True)
th.start()
if args["debug"]:
app.debug = True
app.run(host='0.0.0.0', port=args["port"], threaded=True)
DAS2017 ADC サーバプログラム
DAS218 ADC サーバプログラム
===
DAS2017 アルゴリズムデザインコンテスト用サーバプログラム
DAS2018 アルゴリズムデザインコンテスト用サーバプログラム
## Description
......@@ -22,7 +22,11 @@ python3 main.py [--question XXXX] [--port XXXX] [--clients XXXX]
<dl>
<dt>-c, --client</dt>
<dd>クライアントを定義したテキストファイル.1行ずつホスト名を記述する(必要ならばポート番号も記述する),必須</dd>
<dd>
クライアントを定義したテキストファイル.1行ずつアドレスと役割を記述する(必要ならばポート番号も記述する),必須.
ホスト名と対応するアイコン画像もオプションで指定できる.<br />
`アドレス 役割 [名前] [画像ファイルへのパス]`
</dd>
<dt>-q, --question</dt>
<dd>問題ファイルのパス (デフォルト:./)</dd>
......@@ -33,13 +37,13 @@ python3 main.py [--question XXXX] [--port XXXX] [--clients XXXX]
<dt>-p, --port</dt>
<dd>サーバのポート (デフォルト:5000)</dd>
<dt>-l, --line-num-th</dt>
<dd>処理を分岐させるライン数の閾値</dd>
<dt>-t, --timeout</dt>
<dd>PYNQで処理させるタイムアウト(秒)</dd>
<dt>-a, --adccli</dt>
<dd>
ADC自動運営システムへのログイン情報を記録したjsonファイルへのパス.
`{"url": XXX, "username": YYY, "password": ZZZ}`の形式で保存する.
</dd>
</dl>
## Comments
This project uses some libraries: jQuery, Bootstrap
This project uses some libraries: jQuery, Bootstrap, and three.js.
#!/usr/bin/env python3
import subprocess
PYTHON2 = "/usr/bin/python"
ADCCLI = "/home/pi/adc2018/conmgr/client/adccli"
def _exec_adccli(cmd):
exec_cmd = "{} {} {}".format(PYTHON2, ADCCLI, cmd).strip()
print("ADCCLI: {}".format(exec_cmd))
p = subprocess.run(exec_cmd, stdout=subprocess.PIPE, shell=True)
res = p.stdout.decode().strip()
print(res)
return res
def login(url, username, password):
cmd = "--URL='{}' --username='{}' --password='{}' login".format(url, username, password)
return _exec_adccli(cmd)
def logout():
cmd = "logout"
return _exec_adccli(cmd)
def whoami():
cmd = "whoami"
return _exec_adccli(cmd)
def put_message(message):
cmd = "put-user-alive '{}'"
return _exec_adccli(cmd)
def post_user_q(qnum, filepath):
cmd = "post-user-q {} {}".format(qnum, filepath)
return _exec_adccli(cmd)
def get_q_all(outpath):
cmd = "get-q"
question_list = _exec_adccli(cmd).split("\n")
print("--- ADCCLI questions ---")
print(question_list)
for v in question_list:
if v.startswith("Q"):
qnumber = int(v.replace("Q", ""))
out_file_path = "{}/NL_Q{:02d}.txt".format(outpath, qnumber)
cmd = "--output {} get-q {}".format(out_file_path, qnumber)
r = _exec_adccli(cmd)
return question_list
def put_a(qnum, filepath):
cmd = "put-a {} {}".format(qnum, filepath)
return _exec_adccli(cmd)
def put_a_info(qnum, cpu, mem, misc):
cmd = "put-a-info {} {} {} '{}'".format(qnum, cpu, mem, misc)
return _exec_adccli(cmd)
This diff is collapsed.
This diff is collapsed.
html, body{
font-size: 11px;
overflow: hidden;
}
body{
padding-top: 10px;
}
/* scrollbar settings */
::-webkit-scrollbar{
width: 20px;
border: 1px solid rgba(0, 0, 50, .2);
}
::-webkit-scrollbar-thumb{
background-color: rgba(0, 0, 50, .5);
}
#question-table-wrapper{
height: calc(100vh - 50px);
overflow-y: scroll;
overflow-x: hidden;
}
#question-table-wrapper th.large-cell,
#question-table-wrapper td.large-cell{
width: 24%;
}
#question-table-wrapper th.small-cell,
#question-table-wrapper td.small-cell{
width: 14%;
}
#question-table-wrapper tr.question-row,
#question-table-wrapper tr.question-row td{
cursor: pointer;
}
#question-table-wrapper tr.question-row.q-selected{
background-color: rgba(200, 100, 100, .3);
}
#question-table-wrapper tr.question-row:hover{
background-color: rgba(200, 100, 100, .15);
}
#client-control-pane{
height: calc(100vh - 20px);
overflow-y: scroll;
}
#client-control-pane table th.large-cell,
#client-control-pane table td.large-cell{
width: 40%;
}
#client-control-pane table th.small-cell,
#client-control-pane table td.small-cell{
width: 20%;
}
#question-control-pane h3{
display: inline-block;
}
#client-control-pane tr.answer-detail-row,
#client-control-pane tr.answer-detail-row td{
cursor: pointer;
}
#client-control-pane tr.answer-detail-row:hover{
background-color: rgba(200, 100, 100, .15);
}
#client-control-pane tr.answer-detail-row.submit-answer{
background-color: rgba(100, 200, 100, .3);
}
This diff is collapsed.
This diff is collapsed.
......@@ -63,8 +63,6 @@ var PynqManager = (function(){
}).done(function(res){
var answer = res;
$("#solving-question-status").text(answer["status"]);
$("#solved-result").text(answer["answer"]["answer"]);
$("#solved-client").text(answer["answer"]["client"]);
if (after !== null){
after();
......@@ -75,9 +73,200 @@ var PynqManager = (function(){
_p.sendStop = function(){
console.log("Not implemented!");
for (var key in this.clients){
(function(_key, _client){
var statusObj = $(".client-status-row[data-cname='"+_key+"']").find(".client-status-value").eq(0)
$.ajax({
type: "POST",
url: "/stop",
dataType: "json",
data: {
"client": _client
}
}).done(function(res){
var answer = res["status"];
var message = "";
if (answer) {
message = answer;
}else{
message = "Illegal response: " + res;
}
statusObj.text(message);
}).fail(function(){
statusObj.text("Connection error");
});
})(key, this.clients[key]);
}
}
return PynqManager;
})();
$(function(){
var pynqClients = {}
var pm = null;
var last_req = 0;
var refresh_question_table = function(){
$.ajax({
type: "GET",
dataType: "html",
url: "/get_question_table"
}).done(function(d){
$("#question-table-wrapper").find("#question-table").remove();
$("#question-table-wrapper").html(d);
$(".question-row td").click(function(){
var $tr = $(this).parent("tr.question-row");
$(".question-row").removeClass("q-selected");
$tr.addClass("q-selected");
var qname = $tr.data("qname");
// show_question_status(qname);
location.hash = "#" + qname;
return false;
});
var hash = location.hash.replace("#", "");
if(hash != ""){
$(".question-row[data-qname='" + hash + "']").addClass("q-selected");
}
});
}
var show_client_table = function(){
$.ajax({
type: "GET",
dataType: "html",
url: "/get_client_table"
}).done(function(d){
$("#client-control-pane").html("");
$("#client-control-pane").html(d);
var button_action_with_ajax = function($obj, url){
$obj.prop("disabled", "disabled");
$.ajax({
type: "GET",
url: url,
dataType: "json",
}).done((data)=>{
$obj.prop("disabled", false);
alert(data['message']);
});
};
$("#adccli-login-button").click(function(){
button_action_with_ajax($(this), "/adccli-login");
});
$("#adccli-logout-button").click(function(){
button_action_with_ajax($(this), "/adccli-logout");
});
$("#adccli-get-all-q").click(function(){
button_action_with_ajax($(this), "/adccli-get-all-q");
});
$.ajax({
type: "GET",
url: "/adccli-whoami",
dataType: "json",
}).done((data)=>{
if(data['status'])
$("#adccli-status").text("ログイン中");
else
$("#adccli-status").text("ログアウト");
});
if(pm) pm.getStatus();
});
}
var show_question_status = function(qname){
$.ajax({
type: "GET",
dataType: "html",
url: "/get_question_status",
data: {qname: qname}
}).done(function(d){
$("#client-control-pane").html("");
$("#client-control-pane").html(d);
$("#client-control-pane").find(".start-button").eq(0).click(function(){
var qname = $(this).data("qname");
pm.sendQuestion(qname);
});
$("#client-control-pane").find(".stop-button").eq(0).click(function(){
pm.sendStop();
});
$("#client-control-pane").find(".save-button").eq(0).click(function(){
var qname = $(this).data("qname");
$.ajax({
type: "POST",
dataType: "json",
url: "/save",
data: {qname: qname}
}).done((data) => {
alert(data['status']);
});
});
$("#client-control-pane").find(".submit-button").eq(0).click(function(){
var qname = $(this).data("qname");
$.ajax({
type: "POST",
dataType: "json",
url: "/adccli-put-a",
data: {qname: qname}
}).done((data) => {
alert(data['message']);
});
});
$(".answer-detail-row td").click(function(){
var json_name = $(this).parent("tr").data("json");
var qname = $(this).parent("tr").data("qname");
var viewer_url = "/board-viewer#" + qname + "," + json_name
window.open(viewer_url, "_blank");
})
});
}
$(window).on('hashchange', function(){
var hash = location.hash.replace("#", "");
if(hash == ""){
show_client_table();
}else{
show_question_status(hash);
}
}).trigger('hashchange');
var ws = new WebSocket("ws://" + location.host + "/ws");
ws.onmessage = function(e){
var recv = JSON.parse(e.data.replace(/\n/g, "\\n"));
console.log(recv);
var hash = location.hash.replace("#", "");
if(hash == recv['qname']){
show_question_status(hash);
}
refresh_question_table();
};
refresh_question_table();
$.ajax({
type: "GET",
dataType: "json",
url: "/get_clients"
}).done(function(d){
pynqClients = d;
pm = PynqManager(pynqClients);
if(location.hash.replace("#", "") == ""){
pm.getStatus();
}
});
});
This diff is collapsed.
This diff is collapsed.
......@@ -6,144 +6,31 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/pynq-manager.css">
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.bundle.min.js"></script>
<script src="/static/js/pynq-manager.js"></script>
<style>
html, body{
/*width: 800px;*/
/*height: 500px;*/
font-size: 11px;
overflow: hidden;
}
body{
margin-top: 20px;
}
/* scrollbar settings */
::-webkit-scrollbar{
width: 30px;
border: 1px solid rgba(0, 0, 50, .2);
}
::-webkit-scrollbar-thumb{
background-color: rgba(0, 0, 50, .5);
}
#question-table-wrapper{
height: 350px;
overflow: scroll;
}
#question-table-wrapper th.large-cell,
#question-table-wrapper td.large-cell{
width: 24%;
}
#question-table-wrapper th.small-cell,
#question-table-wrapper td.small-cell{
width: 14%;
}
#client-control-pane table th,
#client-control-pane table td{
width: 50%;
}
</style>
<script>
$(function(){
var pynqClients = {}
var pm = null;
var refresh_question_table = function(){
$.ajax({
type: "GET",
dataType: "html",
url: "/get_question_table"
}).done(function(d){
$("#question-table-wrapper").find("#question-table").remove();
$("#question-table-wrapper").html(d);
$(".show-question-status-button").click(function(){
var qname = $(this).data("qname");
show_question_status(qname);
return false;
});
});
}
var refresh_client_table = function(){
$.ajax({
type: "GET",
dataType: "html",
url: "/get_client_table"
}).done(function(d){
$("#client-control-pane").html("");
$("#client-control-pane").html(d);
$.ajax({
type: "GET",
dataType: "json",
url: "/get_clients"
}).done(function(d){
pynqClients = d;
pm = PynqManager(pynqClients);
pm.getStatus();
});
});
}
var show_question_status = function(qname){
$.ajax({
type: "GET",
dataType: "html",
url: "/get_question_status",
data: {qname: qname}
}).done(function(d){
$("#client-control-pane").html("");
$("#client-control-pane").html(d);
$("#client-control-pane").find(".start-button").eq(0).click(function(){
var qname = $(this).data("qname");
pm.sendQuestion(qname, after=refresh_question_table);
});
});
}
refresh_question_table();
refresh_client_table();
$("#view-server-status-button").click(function(){
refresh_client_table();
return false;
});
});
</script>
</head>
<body>
<div id="wrapper">
<div id="contorol-panel-wrapper" class="container">
<div class="row">
<div class="col" id="question-control-pane">
<h3>問題一覧</h3>
<p><a href="#" id="view-server-status-button">サーバ状況</a></p>
<div id="control-panel-wrapper" class="container-fluid">
<div id="control-panel-row" class="row">
<div class="col-5" id="question-control-pane">
<h3>問題一覧</h3>&nbsp;
<span><a href="/#" id="view-server-status-button">システム状況</a></span>
<div id="question-table-wrapper">
<p>Loading...</p>
</div>
</div>
<div id="question-table-wrapper">
<div class="col-7" id="client-control-pane">
<p>Loading...</p>
</div>
</div>
<div class="col" id="client-control-pane">
<p>Loading...</p>
</div>
</div>
</div>
......
<h3>クライアント状況</h3>
<h3>システム状況</h3>
<h4>動作モード</h4>
<p>
{% if local_mode %}
Normal Mode
{% else %}
Viewer Mode
{% endif %}
</p>
{% if local_mode %}
<h4>自動運営システム</h4>
<button type="button" class="btn btn-primary" id="adccli-login-button">Login</button>
<button type="button" class="btn btn-light" id="adccli-logout-button">Logout</button>
<button type="button" class="btn btn-info" id="adccli-get-all-q">問題DL</button>
<span id="adccli-status"></span>
{% endif %}
<h4>クライアント</h4>
<table class="table table-bordered" id="clients-table">
<tr>
<th>クライアント名</th>
<th>ステータス</th>
<th class="">Client</th>
<th class="">Role</th>
<th class="">Status</th>
</tr>
{% for c in clients %}
<tr class="client-status-row" data-cname="{{c}}">
<td class="client-status-name">{{c}}</td>
<tr class="client-status-row" data-cname="{{c[0]}}">
<td class="client-status-name">
{% if c|length > 3 %}
<img src="static/client-icon/{{c[3]}}" alt="{{c[2]}}" height="30" />&nbsp;
{% endif %}
{{c[0]}}
{% if c|length > 2 %}
&nbsp;({{c[2]}})
{% endif %}
</td>
<td class="">{{c[1]}}</td>
<td class="client-status-value"></td>
</tr>
{% endfor %}
......
<table class="table table-bordered" id="question-table">
<table class="table table-bordered table-hover" id="question-table">
<tr>
<th class="large-cell">ファイル名</th>
<th class="large-cell">File Name</th>
<th class="large-cell">Size</th>
<th class="small-cell">Line</th>
<th class="large-cell">ステータス</th>
<th class="small-cell">操作</th>
<th class="large-cell">Status</th>
</tr>
{% for k, v in questions.items() %}
<tr>
<tr class="question-row" data-qname="{{k}}">
<td class="large-cell">{{k}}</td>
<td class="large-cell">{{v.board_size}}</td>
<td class="small-cell">{{v.line_num}}</td>
<td class="large-cell">{{v.status}}</td>
<td class="small-cell">
<a href="#" class="show-question-status-button" data-qname="{{k}}">選択</a>
</td>
</tr>
{% endfor %}
</table>
TARGET = sim
OBJS = $(CPPS:.cpp=.o)
CPPS = $(wildcard *.cpp)
CXX = g++
CXXFLAGS = -O3 -Wall -Wno-unknown-pragmas -Wno-unused-label -DSOFTWARE -DCALCTIME
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) -O3 -o $@ $(OBJS)
run:
python3 ../NLGenerator.py -x 20 -y 20 -z 6 -l 100;\
python3 ./gen_boardstr.py Q-20x20x5_100_10.txt |\
./$(TARGET) -
clean:
rm *.o
rm $(TARGET)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <stdio.h>
#include <stdlib.h>
#define STRLEN 65536
int main(void){
char q[STRLEN], command[STRLEN];
char dir[64] = "../lines256_length128";
FILE *fp;
fp = fopen("q.txt", "r");
if(fp == NULL){
printf("File does not exist.\n");
exit(1);
}
int counter = 1;
while(1){
if(fscanf(fp, "%s", q) == EOF) break;
printf("Q. %d\n", counter++);
sprintf(command, "./%s/sim.exe %s", dir, q);
//printf("(command) %s\n", command);
int ret = system(command);
printf("ret: %d\n", ret);
}
fclose(fp);
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.