Skip to content

Commit f102cf3

Browse files
feat: add /api/query/result endpoint, fetch Fugaku FOM in estimate code=qws system=MiyabiG
1 parent 8a6a587 commit f102cf3

5 files changed

Lines changed: 160 additions & 8 deletions

File tree

programs/qws/estimate.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ est_benchmark_system="$est_system"
1818
est_benchmark_fom="$est_fom"
1919
est_benchmark_nodes="$est_node_count"
2020

21-
# --- Dummy estimation model (scale-mock) ---
22-
# Current system: Fugaku — FOM scaled by 10x
21+
# --- Current system: Fugaku — fetch real FOM from result_server ---
2322
est_current_system="Fugaku"
24-
est_current_fom=$(awk -v fom="$est_fom" 'BEGIN {printf "%.3f", fom * 10}')
23+
CURRENT_EXP="" # Set specific Exp here if needed (e.g. "default")
24+
fetch_current_fom "$est_code" "$CURRENT_EXP"
2525
est_current_nodes="$est_node_count"
26-
est_current_method="scale-mock"
26+
est_current_method="measured"
2727

28-
# Future system: FugakuNEXT — FOM scaled by 2x
28+
# Future system: FugakuNEXT — FOM scaled by 2x (dummy)
2929
est_future_system="FugakuNEXT"
3030
est_future_fom=$(awk -v fom="$est_fom" 'BEGIN {printf "%.3f", fom * 2}')
3131
est_future_nodes="$est_node_count"

programs/qws/list.csv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ system,mode,queue_group,nodes,numproc_node,nthreads,elapse
55
#FugakuCN,native,small,2,4,12,0:10:00
66
#RC_GH200,native,dummy,1,1,12,0:10:00
77
#RC_DGXS,native,dummy,1,1,20,0:10:00
8-
RC_GENOA,native,dummy,1,1,96,0:10:00
8+
#RC_GENOA,native,dummy,1,1,96,0:10:00
99
MiyabiG,cross,debug-g,1,1,72,0:10:00
10-
MiyabiC,cross,debug-c,1,1,112,0:10:00
10+
#MiyabiC,cross,debug-c,1,1,112,0:10:00

result_server/routes/api.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
POST /upload-tgz → ingest_padata
1313
"""
1414

15-
from flask import Blueprint, request, abort, current_app
15+
from flask import Blueprint, request, abort, current_app, jsonify
1616
import os
17+
import json
1718
import uuid
1819
import shutil
1920
from datetime import datetime
@@ -147,6 +148,55 @@ def ingest_padata():
147148
}, 200
148149

149150

151+
# ==========================================
152+
# Query API: /api/query/*
153+
# ==========================================
154+
155+
@api_bp.route("/api/query/result", methods=["GET"])
156+
def query_result():
157+
"""Search results by system, code, exp and return the latest match.
158+
159+
Query parameters:
160+
system (required): e.g. Fugaku
161+
code (required): e.g. qws
162+
exp (optional): e.g. default
163+
164+
Returns the full JSON of the most recent matching result file.
165+
"""
166+
require_api_key()
167+
168+
system = request.args.get("system")
169+
code = request.args.get("code")
170+
exp = request.args.get("exp")
171+
172+
if not system or not code:
173+
abort(400, description="system and code are required")
174+
175+
received_dir = current_app.config["RECEIVED_DIR"]
176+
json_files = sorted(
177+
[f for f in os.listdir(received_dir) if f.endswith(".json")],
178+
reverse=True,
179+
)
180+
181+
for json_file in json_files:
182+
try:
183+
with open(os.path.join(received_dir, json_file), "r", encoding="utf-8") as f:
184+
data = json.load(f)
185+
except Exception:
186+
continue
187+
188+
if data.get("system") != system:
189+
continue
190+
if data.get("code") != code:
191+
continue
192+
if exp is not None and data.get("Exp") != exp:
193+
continue
194+
195+
return jsonify(data), 200
196+
197+
abort(404, description=f"No result found for system={system}, code={code}, exp={exp}")
198+
199+
150200
# ==========================================
151201
# 互換ルート (deprecated)
152202
# ==========================================

result_server/tests/test_api_routes.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,63 @@ def test_estimated_route_accessible(self, app):
274274
assert any("/estimated/" in r for r in rules)
275275

276276

277+
# ============================================================
278+
# /api/query/result
279+
# ============================================================
280+
281+
class TestQueryResult:
282+
def _seed_result(self, received_dir, data, filename="result_20250101_000000_aaaa.json"):
283+
path = os.path.join(received_dir, filename)
284+
with open(path, "w") as f:
285+
json.dump(data, f)
286+
287+
def test_query_returns_latest_match(self, client, tmp_dirs):
288+
received, _ = tmp_dirs
289+
old = {"system": "Fugaku", "code": "qws", "Exp": "default", "FOM": 1.0}
290+
new = {"system": "Fugaku", "code": "qws", "Exp": "default", "FOM": 9.9}
291+
self._seed_result(received, old, "result_20250101_000000_aaaa.json")
292+
self._seed_result(received, new, "result_20250102_000000_bbbb.json")
293+
294+
resp = client.get(
295+
"/api/query/result?system=Fugaku&code=qws",
296+
headers={"X-API-Key": API_KEY},
297+
)
298+
assert resp.status_code == 200
299+
assert resp.get_json()["FOM"] == 9.9
300+
301+
def test_query_with_exp_filter(self, client, tmp_dirs):
302+
received, _ = tmp_dirs
303+
d1 = {"system": "Fugaku", "code": "qws", "Exp": "A", "FOM": 1.0}
304+
d2 = {"system": "Fugaku", "code": "qws", "Exp": "B", "FOM": 2.0}
305+
self._seed_result(received, d1, "result_20250101_000000_aaaa.json")
306+
self._seed_result(received, d2, "result_20250102_000000_bbbb.json")
307+
308+
resp = client.get(
309+
"/api/query/result?system=Fugaku&code=qws&exp=A",
310+
headers={"X-API-Key": API_KEY},
311+
)
312+
assert resp.status_code == 200
313+
assert resp.get_json()["FOM"] == 1.0
314+
315+
def test_query_no_match_returns_404(self, client, tmp_dirs):
316+
resp = client.get(
317+
"/api/query/result?system=Fugaku&code=nonexistent",
318+
headers={"X-API-Key": API_KEY},
319+
)
320+
assert resp.status_code == 404
321+
322+
def test_query_missing_params_returns_400(self, client):
323+
resp = client.get(
324+
"/api/query/result?system=Fugaku",
325+
headers={"X-API-Key": API_KEY},
326+
)
327+
assert resp.status_code == 400
328+
329+
def test_query_missing_api_key_returns_401(self, client):
330+
resp = client.get("/api/query/result?system=Fugaku&code=qws")
331+
assert resp.status_code == 401
332+
333+
277334
# ============================================================
278335
# ヘルパー
279336
# ============================================================

scripts/estimate_common.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,51 @@ performance_ratio() {
7777
'BEGIN { if (fut == 0) printf "0"; else printf "%.3f", cur / fut }'
7878
}
7979

80+
# ---------------------------------------------------------------------------
81+
# fetch_current_fom — Fetch Fugaku FOM from result_server API
82+
#
83+
# Arguments:
84+
# $1 code (e.g. qws)
85+
# $2 exp (optional, e.g. default)
86+
#
87+
# Requires: RESULT_SERVER, RESULT_SERVER_KEY environment variables
88+
# Sets: est_current_fom (FOM value from Fugaku result)
89+
# Exits with 1 on failure.
90+
# ---------------------------------------------------------------------------
91+
fetch_current_fom() {
92+
local code="$1"
93+
local exp="${2:-}"
94+
95+
if [[ -z "${RESULT_SERVER:-}" ]]; then
96+
echo "ERROR: RESULT_SERVER is not set" >&2
97+
exit 1
98+
fi
99+
if [[ -z "${RESULT_SERVER_KEY:-}" ]]; then
100+
echo "ERROR: RESULT_SERVER_KEY is not set" >&2
101+
exit 1
102+
fi
103+
104+
local url="${RESULT_SERVER}/api/query/result?system=Fugaku&code=${code}"
105+
if [[ -n "$exp" ]]; then
106+
url="${url}&exp=${exp}"
107+
fi
108+
109+
local response
110+
response=$(curl -sf -H "X-API-Key: ${RESULT_SERVER_KEY}" "$url")
111+
if [[ $? -ne 0 || -z "$response" ]]; then
112+
echo "ERROR: Failed to fetch Fugaku result for code=${code}, exp=${exp}" >&2
113+
exit 1
114+
fi
115+
116+
est_current_fom=$(echo "$response" | jq -r '.FOM')
117+
if [[ -z "$est_current_fom" || "$est_current_fom" == "null" ]]; then
118+
echo "ERROR: FOM not found in Fugaku result for code=${code}, exp=${exp}" >&2
119+
exit 1
120+
fi
121+
122+
echo "Fetched Fugaku FOM for ${code}: ${est_current_fom}"
123+
}
124+
80125
# ---------------------------------------------------------------------------
81126
# print_json — Output an Estimate_JSON to stdout
82127
#

0 commit comments

Comments
 (0)