Loading .gitignore +4 −0 Changes for .gitignore: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -19,3 +19,7 @@ solver # Python files *.pyc __pycache__/ # client-icons client-icon/ comm/server/README.md +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 Loading Loading @@ -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 comm/server/main.py +107 −55 Changes for comm/server/main.py: 107 added lines, 55 removed lines. Original line number Diff line number Diff line Loading @@ -28,32 +28,10 @@ questions = None clients = None current_seed = 1 def update_answer_list(qname): global app_args global questions questions[qname]['answers'] = [] _folder_name = os.path.splitext(qname)[0] _answers_path = "{}/{}".format(app_args['out'], _folder_name) if os.path.isdir(_answers_path): answer_log_file = glob.glob("{}/*.json".format(_answers_path)) answer_log_file.sort() answer_log_file.reverse() for v2 in answer_log_file: with open(v2, "r") as fp: answer_log = json.load(fp) questions[qname]['answers'].append(answer_log) @app.before_request def before_request(): def load_questions(): global app_args global questions global clients if questions is None: question_path = os.path.abspath(app_args["question"]) question_list = glob.glob("{}/NL_*.txt".format(question_path)) question_list.sort() Loading Loading @@ -81,6 +59,7 @@ def before_request(): "queue": Queue(), "board_size": board_size, "line_num": line_num, "last_req": None, "answers": [], } Loading @@ -103,12 +82,30 @@ def before_request(): except KeyError as e: pass if clients is None: def update_answer_list(qname): with open(app_args["client"], "r") as fp: _clients = fp.readlines() global app_args global questions questions[qname]['answers'] = [] _folder_name = os.path.splitext(qname)[0] _answers_path = "{}/{}".format(app_args['out'], _folder_name) if os.path.isdir(_answers_path): answer_log_file = glob.glob("{}/*.json".format(_answers_path)) answer_log_file.sort() answer_log_file.reverse() for v2 in answer_log_file: with open(v2, "r") as fp: answer_log = json.load(fp) questions[qname]['answers'].append(answer_log) @app.before_request def before_request(): global app_args clients = [v.rstrip() for v in _clients] g.local_mode = (request.remote_addr == "127.0.0.1") @app.route("/post", methods=["POST"]) def post(): Loading @@ -116,18 +113,24 @@ def post(): global questions global app_args _client = request.form["client"] _qname = request.form["qname"] _answer = request.form["answer"] _cputime = request.form["cputime"] _client = request.form["client"] if "solver" in request.form: _solver = request.form["solver"] else: _solver = _client receive_time = datetime.datetime.now() receive_time_str = receive_time.strftime("%Y%m%d%H%M%S") dat = { "req_id": request.form['req_id'], "client": _client, "solver": _solver, "answer": _answer, "cputime": _cputime, "cputime": request.form['cputime'], "timestamp": receive_time.strftime("%Y/%m/%d %H:%M:%S") } Loading @@ -149,7 +152,6 @@ def post(): pattern = r"judge += +\[(.+?), ([0-9.]+)\]" m = re.match(pattern, nlcheck) print(nlcheck, m) if m and (m.group(1) == "True"): dat["nlcheck"] = float(m.group(2)) else: Loading Loading @@ -192,22 +194,11 @@ def start(): qstr = "\n".join(_q_lines) qnumber = _question_name.replace(".txt", "").replace("NL_Q", "") probpath = "{}/{}".format(app_args["question"], _question_name) tmppath = "{}/T03_A{}_tmp.txt".format(app_args["out"], qnumber) outpath = "{}/T03_A{}.txt".format(app_args["out"], qnumber) res = {} if line_num >= 0: # LINE_NUMが閾値未満のとき,PYNQに問題を配信して問題を解かせる res = solve_questions(_question_name, qstr) # 整形ルーティング (再配線) する #cmd = "/home/pi/pynq-router/resolver/solver --reroute --output {} {} {}".format(outpath, probpath, tmppath) cmd = "/home/pi/adc2017/pynq-router/resolver/solver --reroute --output {} {} {}".format(outpath, probpath, tmppath) print("`{}`".format(cmd)) subprocess.call(cmd.strip().split(" ")) # 最終結果だけを保存 questions[_question_name]["status"] = res["status"] Loading @@ -222,22 +213,35 @@ def solve_questions(qname, qstr): global clients global questions global current_seed global app_args def worker(host, qname, qstr, qseed, request_time): def worker(host, qname, qstr, qseed, req_id, resolver): _url = "http://{}/start".format(host) data = { "client": host, "qname": qname, "question": qstr, "qseed": qseed, "req_id": req_id, "resolver": resolver } try: r = requests.post(_url, data={"client": host, "qname": qname, "question": qstr, "qseed": qseed, "request_time": request_time}) r = requests.post(_url, data=data) client_res = json.loads(r.text) except Exception as e: sys.stderr.write(str(e) + "\n") threads = [] request_time = time.time() # 時刻をリクエストIDとして設定 req_id = time.time() questions[qname]['last_req'] = req_id for c in clients: _th = threading.Thread(name=c, target=worker, args=(c, qname, qstr, current_seed, request_time)) for c in clients['solver']: # 問題はSolverに送る client_addr = c[0] idx_of_resolver = current_seed % len(clients['resolver']) resolver = clients['resolver'][idx_of_resolver][0] _th = threading.Thread(name=client_addr, target=worker, args=(client_addr, qname, qstr, current_seed, req_id, resolver)) _th.start() threads.append(_th) current_seed += 1 Loading @@ -246,6 +250,22 @@ def solve_questions(qname, qstr): return res @app.route("/stop", methods=["POST"]) def stop(): _client = request.form["client"] _url = _client + "/stop" try: r = requests.get(_url) client_res = json.loads(r.text)["status"] except Exception as e: client_res = "Connection error" sys.stderr.write(str(e) + "\n") res = {"status": client_res} return json.dumps(res) @app.route("/status", methods=["POST"]) def get_status(): _client = request.form["client"] Loading @@ -268,8 +288,9 @@ def get_clients(): res = OrderedDict() for c in clients: res[c] = "http://{}".format(c) for c in clients['all']: client_ip = c[0] res[client_ip] = "http://{}".format(client_ip) return json.dumps(res) Loading @@ -289,7 +310,7 @@ def client_table(): global app_args global clients return render_template("part_client_table.html", clients=clients) return render_template("part_client_table.html", clients=clients["all"], local_mode=g.local_mode) @app.route("/get_question_status") def question_status(): Loading @@ -303,33 +324,64 @@ def question_status(): update_answer_list(qname) qdata = questions[qname] return render_template("part_question_status.html", qname=qname, qdata=qdata, clients=clients) return render_template("part_question_status.html", qname=qname, qdata=qdata, solvers=clients["solver"]) @app.route("/") def index(): global app_args global questions global clients question_path = os.path.abspath(app_args["question"]) return render_template("index.html", questions=questions, question_path=question_path, clients=clients) return render_template("index.html", questions=questions, question_path=question_path) def main(args): raise NotImprementedError() def init_system(): global app_args global questions global clients if questions is None: load_questions() if clients is None: with open(app_args["client"], "r") as fp: _clients = fp.readlines() all_clients = [v.rstrip().split() for v in _clients] solver = [] resolver = [] for v in all_clients: if v[1].lower() == "solver": solver.append(v) elif v[1].lower() == "resolver": resolver.append(v) clients = { "all": all_clients, "solver": solver, "resolver": resolver } if __name__ == "__main__": parser = argparse.ArgumentParser(description="PYNQ control panel.") parser.add_argument("-c", "--client", action="store", type=str, default=None, required=True, help="Client list.") parser.add_argument("-q", "--question", action="store", type=str, default="./problems", help="Path to the question folder.") parser.add_argument("-o", "--out", action="store", type=str, default="./answers", help="Path to the output folder.") parser.add_argument("-t", "--timeout", action="store", type=int, default=300, help="Timeout.") parser.add_argument("--debug", action="store_true", default=False, help="Debug mode.") args = vars(parser.parse_args()) app_args = args init_system() if args["debug"]: app.debug = True app.run(host='0.0.0.0', threaded=True) comm/server/static/css/pynq-manager.css +7 −3 Changes for comm/server/static/css/pynq-manager.css: 7 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -46,9 +46,13 @@ body{ overflow-y: scroll; } #client-control-pane table th, #client-control-pane table td{ width: 50%; #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{ Loading comm/server/static/js/pynq-manager.js +52 −16 Changes for comm/server/static/js/pynq-manager.js: 52 added lines, 16 removed lines. Original line number Diff line number Diff line Loading @@ -74,7 +74,31 @@ 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]); } } Loading @@ -101,13 +125,19 @@ $(function(){ $(".question-row").removeClass("q-selected"); $tr.addClass("q-selected"); var qname = $tr.data("qname"); show_question_status(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 refresh_client_table = function(){ var show_client_table = function(){ $.ajax({ type: "GET", dataType: "html", Loading @@ -115,17 +145,8 @@ $(function(){ }).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){ Loading @@ -142,15 +163,30 @@ $(function(){ var qname = $(this).data("qname"); pm.sendQuestion(qname, after=refresh_question_table); }); $("#client-control-pane").find(".stop-button").eq(0).click(function(){ pm.sendStop(); }); }); } $(window).on('hashchange', function(){ var hash = location.hash.replace("#", ""); if(hash == ""){ show_client_table(); }else{ show_question_status(hash); } }).trigger('hashchange'); refresh_question_table(); refresh_client_table(); $("#view-server-status-button").click(function(){ refresh_client_table(); return false; $.ajax({ type: "GET", dataType: "json", url: "/get_clients" }).done(function(d){ pynqClients = d; pm = PynqManager(pynqClients); }); }); Loading
.gitignore +4 −0 Changes for .gitignore: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -19,3 +19,7 @@ solver # Python files *.pyc __pycache__/ # client-icons client-icon/
comm/server/README.md +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 Loading Loading @@ -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
comm/server/main.py +107 −55 Changes for comm/server/main.py: 107 added lines, 55 removed lines. Original line number Diff line number Diff line Loading @@ -28,32 +28,10 @@ questions = None clients = None current_seed = 1 def update_answer_list(qname): global app_args global questions questions[qname]['answers'] = [] _folder_name = os.path.splitext(qname)[0] _answers_path = "{}/{}".format(app_args['out'], _folder_name) if os.path.isdir(_answers_path): answer_log_file = glob.glob("{}/*.json".format(_answers_path)) answer_log_file.sort() answer_log_file.reverse() for v2 in answer_log_file: with open(v2, "r") as fp: answer_log = json.load(fp) questions[qname]['answers'].append(answer_log) @app.before_request def before_request(): def load_questions(): global app_args global questions global clients if questions is None: question_path = os.path.abspath(app_args["question"]) question_list = glob.glob("{}/NL_*.txt".format(question_path)) question_list.sort() Loading Loading @@ -81,6 +59,7 @@ def before_request(): "queue": Queue(), "board_size": board_size, "line_num": line_num, "last_req": None, "answers": [], } Loading @@ -103,12 +82,30 @@ def before_request(): except KeyError as e: pass if clients is None: def update_answer_list(qname): with open(app_args["client"], "r") as fp: _clients = fp.readlines() global app_args global questions questions[qname]['answers'] = [] _folder_name = os.path.splitext(qname)[0] _answers_path = "{}/{}".format(app_args['out'], _folder_name) if os.path.isdir(_answers_path): answer_log_file = glob.glob("{}/*.json".format(_answers_path)) answer_log_file.sort() answer_log_file.reverse() for v2 in answer_log_file: with open(v2, "r") as fp: answer_log = json.load(fp) questions[qname]['answers'].append(answer_log) @app.before_request def before_request(): global app_args clients = [v.rstrip() for v in _clients] g.local_mode = (request.remote_addr == "127.0.0.1") @app.route("/post", methods=["POST"]) def post(): Loading @@ -116,18 +113,24 @@ def post(): global questions global app_args _client = request.form["client"] _qname = request.form["qname"] _answer = request.form["answer"] _cputime = request.form["cputime"] _client = request.form["client"] if "solver" in request.form: _solver = request.form["solver"] else: _solver = _client receive_time = datetime.datetime.now() receive_time_str = receive_time.strftime("%Y%m%d%H%M%S") dat = { "req_id": request.form['req_id'], "client": _client, "solver": _solver, "answer": _answer, "cputime": _cputime, "cputime": request.form['cputime'], "timestamp": receive_time.strftime("%Y/%m/%d %H:%M:%S") } Loading @@ -149,7 +152,6 @@ def post(): pattern = r"judge += +\[(.+?), ([0-9.]+)\]" m = re.match(pattern, nlcheck) print(nlcheck, m) if m and (m.group(1) == "True"): dat["nlcheck"] = float(m.group(2)) else: Loading Loading @@ -192,22 +194,11 @@ def start(): qstr = "\n".join(_q_lines) qnumber = _question_name.replace(".txt", "").replace("NL_Q", "") probpath = "{}/{}".format(app_args["question"], _question_name) tmppath = "{}/T03_A{}_tmp.txt".format(app_args["out"], qnumber) outpath = "{}/T03_A{}.txt".format(app_args["out"], qnumber) res = {} if line_num >= 0: # LINE_NUMが閾値未満のとき,PYNQに問題を配信して問題を解かせる res = solve_questions(_question_name, qstr) # 整形ルーティング (再配線) する #cmd = "/home/pi/pynq-router/resolver/solver --reroute --output {} {} {}".format(outpath, probpath, tmppath) cmd = "/home/pi/adc2017/pynq-router/resolver/solver --reroute --output {} {} {}".format(outpath, probpath, tmppath) print("`{}`".format(cmd)) subprocess.call(cmd.strip().split(" ")) # 最終結果だけを保存 questions[_question_name]["status"] = res["status"] Loading @@ -222,22 +213,35 @@ def solve_questions(qname, qstr): global clients global questions global current_seed global app_args def worker(host, qname, qstr, qseed, request_time): def worker(host, qname, qstr, qseed, req_id, resolver): _url = "http://{}/start".format(host) data = { "client": host, "qname": qname, "question": qstr, "qseed": qseed, "req_id": req_id, "resolver": resolver } try: r = requests.post(_url, data={"client": host, "qname": qname, "question": qstr, "qseed": qseed, "request_time": request_time}) r = requests.post(_url, data=data) client_res = json.loads(r.text) except Exception as e: sys.stderr.write(str(e) + "\n") threads = [] request_time = time.time() # 時刻をリクエストIDとして設定 req_id = time.time() questions[qname]['last_req'] = req_id for c in clients: _th = threading.Thread(name=c, target=worker, args=(c, qname, qstr, current_seed, request_time)) for c in clients['solver']: # 問題はSolverに送る client_addr = c[0] idx_of_resolver = current_seed % len(clients['resolver']) resolver = clients['resolver'][idx_of_resolver][0] _th = threading.Thread(name=client_addr, target=worker, args=(client_addr, qname, qstr, current_seed, req_id, resolver)) _th.start() threads.append(_th) current_seed += 1 Loading @@ -246,6 +250,22 @@ def solve_questions(qname, qstr): return res @app.route("/stop", methods=["POST"]) def stop(): _client = request.form["client"] _url = _client + "/stop" try: r = requests.get(_url) client_res = json.loads(r.text)["status"] except Exception as e: client_res = "Connection error" sys.stderr.write(str(e) + "\n") res = {"status": client_res} return json.dumps(res) @app.route("/status", methods=["POST"]) def get_status(): _client = request.form["client"] Loading @@ -268,8 +288,9 @@ def get_clients(): res = OrderedDict() for c in clients: res[c] = "http://{}".format(c) for c in clients['all']: client_ip = c[0] res[client_ip] = "http://{}".format(client_ip) return json.dumps(res) Loading @@ -289,7 +310,7 @@ def client_table(): global app_args global clients return render_template("part_client_table.html", clients=clients) return render_template("part_client_table.html", clients=clients["all"], local_mode=g.local_mode) @app.route("/get_question_status") def question_status(): Loading @@ -303,33 +324,64 @@ def question_status(): update_answer_list(qname) qdata = questions[qname] return render_template("part_question_status.html", qname=qname, qdata=qdata, clients=clients) return render_template("part_question_status.html", qname=qname, qdata=qdata, solvers=clients["solver"]) @app.route("/") def index(): global app_args global questions global clients question_path = os.path.abspath(app_args["question"]) return render_template("index.html", questions=questions, question_path=question_path, clients=clients) return render_template("index.html", questions=questions, question_path=question_path) def main(args): raise NotImprementedError() def init_system(): global app_args global questions global clients if questions is None: load_questions() if clients is None: with open(app_args["client"], "r") as fp: _clients = fp.readlines() all_clients = [v.rstrip().split() for v in _clients] solver = [] resolver = [] for v in all_clients: if v[1].lower() == "solver": solver.append(v) elif v[1].lower() == "resolver": resolver.append(v) clients = { "all": all_clients, "solver": solver, "resolver": resolver } if __name__ == "__main__": parser = argparse.ArgumentParser(description="PYNQ control panel.") parser.add_argument("-c", "--client", action="store", type=str, default=None, required=True, help="Client list.") parser.add_argument("-q", "--question", action="store", type=str, default="./problems", help="Path to the question folder.") parser.add_argument("-o", "--out", action="store", type=str, default="./answers", help="Path to the output folder.") parser.add_argument("-t", "--timeout", action="store", type=int, default=300, help="Timeout.") parser.add_argument("--debug", action="store_true", default=False, help="Debug mode.") args = vars(parser.parse_args()) app_args = args init_system() if args["debug"]: app.debug = True app.run(host='0.0.0.0', threaded=True)
comm/server/static/css/pynq-manager.css +7 −3 Changes for comm/server/static/css/pynq-manager.css: 7 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -46,9 +46,13 @@ body{ overflow-y: scroll; } #client-control-pane table th, #client-control-pane table td{ width: 50%; #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{ Loading
comm/server/static/js/pynq-manager.js +52 −16 Changes for comm/server/static/js/pynq-manager.js: 52 added lines, 16 removed lines. Original line number Diff line number Diff line Loading @@ -74,7 +74,31 @@ 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]); } } Loading @@ -101,13 +125,19 @@ $(function(){ $(".question-row").removeClass("q-selected"); $tr.addClass("q-selected"); var qname = $tr.data("qname"); show_question_status(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 refresh_client_table = function(){ var show_client_table = function(){ $.ajax({ type: "GET", dataType: "html", Loading @@ -115,17 +145,8 @@ $(function(){ }).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){ Loading @@ -142,15 +163,30 @@ $(function(){ var qname = $(this).data("qname"); pm.sendQuestion(qname, after=refresh_question_table); }); $("#client-control-pane").find(".stop-button").eq(0).click(function(){ pm.sendStop(); }); }); } $(window).on('hashchange', function(){ var hash = location.hash.replace("#", ""); if(hash == ""){ show_client_table(); }else{ show_question_status(hash); } }).trigger('hashchange'); refresh_question_table(); refresh_client_table(); $("#view-server-status-button").click(function(){ refresh_client_table(); return false; $.ajax({ type: "GET", dataType: "json", url: "/get_clients" }).done(function(d){ pynqClients = d; pm = PynqManager(pynqClients); }); });