Commit ca2e8c1b authored by Kento HASEGAWA's avatar Kento HASEGAWA
Browse files

Merge branch 'comm' into 'master'

Add support for resolver and improve UI

See merge request adc2018/adc2018-system!9
parents 4cffa912 5e4c621e
Loading
Loading
Loading
Loading
+6 −0
Changes for .gitignore: 6 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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/
+8 −9
Changes for comm/client/main.py: 8 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import adc2018solver as pynqrouter

app = Flask(__name__)
args = {}
# pynq_thread = None
client_baseurl = ""

@app.route('/start', methods=["POST"])
@@ -45,10 +44,15 @@ def start():
        qseed = request.form["qseed"]
	
        boardstr = BoardStr.conv_boardstr(qstr.split('\n'), 'random', int(qseed))
        option = {"name": qname, "host": args['host'], "client": client_baseurl} 
        option = {
            "name": qname,
            "host": args['host'],
            "client": client_baseurl,
            "req_id": request.form['req_id'],
            "resolver": request.form['resolver']
        } 

        pynqrouter.start_solver(boardstr, qseed, option)
        # pynq_thread = pynqrouter.start_solver(boardstr, qseed, option)

        # 実行だけ開始する
        ans["status"] = "Processing"
@@ -64,8 +68,6 @@ def start():
@app.route('/stop')
def stop():

    # global pynq_thread

    if pynqrouter.solver_thread is None:
        ans = {"status": "No threads"}
    else:
@@ -73,15 +75,11 @@ def 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 pynqrouter.solver_thread is None:
@@ -121,3 +119,4 @@ if __name__ == "__main__":
    if args["debug"]:
        app.debug = True
    app.run(host='0.0.0.0', port=args["port"], threaded=True)
+29 −0
Changes for comm/resolver/README.md: 29 added lines, 0 removed lines.
Original line number Diff line number Diff line
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>

comm/resolver/main.py

0 → 100644
+171 −0
Changes for comm/resolver/main.py: 171 added lines, 0 removed lines.
Original line number Diff line number Diff line
#!/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()

            res = {
                'answer': 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)
+2 −8
Changes for comm/server/README.md: 2 added lines, 8 removed lines.
Original line number Diff line number Diff line
DAS2017 ADC サーバプログラム
DAS218 ADC サーバプログラム
===

DAS2017 アルゴリズムデザインコンテスト用サーバプログラム
DAS2018 アルゴリズムデザインコンテスト用サーバプログラム

## Description

@@ -32,12 +32,6 @@ 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>
</dl>

## Comments
Loading