Commit a71930a4 authored by w-mj's avatar w-mj

a template

parent 29031d5e
.idea/
result/
*.tar.gz
\ No newline at end of file
*.tar.gz
*.zip
\ No newline at end of file
FROM jupyter/base-notebook
LABEL MAINTAINER=w-mj<wmj@alphamj.cn>
USER root
RUN apt update && apt install -y --no-install-recommends gcc libc-dev && rm -rf /var/lib/apt/lists/*
RUN pip install pygrading
RUN mkdir -p /kernel/
RUN groupadd -r cguser && useradd --no-log-init -m -r -g cguser cguser
COPY kernel.zip /home/cguser/kernel.zip
USER cguser
ENTRYPOINT ["python", "/home/cguser/kernel.zip"]
\ No newline at end of file
KERNEL_NAME := cg/universial-template
VERSION := v1.0.1
DOCKER := $(KERNEL_NAME):$(VERSION)
build:
rm -f kernel.zip
cd kernel && zip -0 -r ../kernel.zip *
docker_build: build
docker image build --force-rm -t $(KERNEL_NAME):$(VERSION) .
img: docker_build
docker save $(DOCKER) | pigz -c > $(subst /,-, $(KERNEL_NAME))_$(VERSION).tar.gz
test: build
python test.py $(DOCKER)
FORCE: ;
# GPU-Judge-v2
# 通用评测核心模板
{}
\ No newline at end of file
import pygrading.general_test as gg
import pygrading.html as html
from verdict import Verdict
class CG:
class Exception(Exception):
def __init__(self, verdict: str, comment: str):
self.verdict = verdict
self.comment = comment
class RuntimeError(Exception):
def __init__(self, comment: str):
CG.Exception.__init__(self, Verdict.RE, comment)
class CompileError(Exception):
def __init__(self, comment: str):
CG.Exception.__init__(self, Verdict.CE, comment)
class WrongAnswer(Exception):
def __init__(self, comment: str):
CG.Exception.__init__(self, Verdict.WA, comment)
class UnknownError(Exception):
def __init__(self, comment: str):
CG.Exception.__init__(self, Verdict.UE, comment)
@staticmethod
def catch(fun):
def wrapper(job: gg.Job, *args, **kwargs):
try:
return fun(job, *args, **kwargs)
except CG.Exception as e:
job.verdict(e.verdict)
job.comment(html.str2html(e.comment))
job.score(0)
job.rank({"rank": "-1"})
job.terminate()
return wrapper
import pygrading.general_test as gg
from render import make_verdict, make_table, make_one_line_table
from verdict import Verdict
def postwork(job: gg.Job):
pass
summary = job.get_summary()
score = job.get_total_score()
verdict = make_verdict([x['verdict'] for x in summary])
job.verdict(verdict)
job.score(score)
rank = job.get_total_time() if score == 100 else 0
job.rank({"rank": rank})
job.comment(make_table(summary, ['name', 'verdict', 'score', 'time']))
details = ""
for sum in summary:
if sum["verdict"] == Verdict.RE:
details += make_one_line_table(sum, ["stderr", "return_code"])
else:
details += make_one_line_table(sum, ["output", "answer"])
job.detail(details)
import pygrading.general_test as gg
import os
from exception import CG
@CG.catch
def prework(job: gg.Job):
pass
\ No newline at end of file
config = job.get_config()
if len(os.listdir(config['submit_dir'])) == 0:
raise CG.CompileError("No submit file")
source_code = os.path.join(config["submit_dir"], "*.c")
# compile_cmd = f"nvcc {source_code} -O2 -Wall -o {config['exec_src']}"
compile_cmd = f"gcc {source_code} -O2 -Wall -o {config['exec_src']}"
compile_result = gg.utils.exec(compile_cmd)
if compile_result.returncode != 0:
raise CG.CompileError(compile_result.stdout + '\n' + compile_result.stderr)
if config['testcase_num'] == 0:
raise CG.UnknownError("No test case file")
testcases = gg.create_std_testcase(config["testcase_dir"], config["testcase_num"])
job.set_testcases(testcases)
from pygrading.html import *
from verdict import Verdict
# data = {
# 'name': '4位全加器',
......@@ -13,74 +14,45 @@ from pygrading.html import *
# summary = ['name', 'time', 'score', 'verdict'] # 摘要内容
# details = ['input', 'stdout', 'answer'] # 细节内容
js = "<script>function ec(a){var b=document.getElementById(a);b.style.display=(b.style.display=='none')?'table':'none';}</script>"
def make_html(data, title, summary, details):
ans = make_title(data, title)
if summary and data.get('detail'):
ans += make_summary(data, summary, True if details else False)
if details:
ans += make_details(data, details)
ans += js
return ans
def make_title(data, title):
ans = div()
for key in title:
ans << h4().set_text(str2html(f'{key}: {data[key]}'))
return str(ans)
def make_summary(data, summary, have_details=False):
def make_table(data, summary):
ans = table(border="1")
# 创建表头
thead = tr()
for key in summary:
thead << th().set_text(key)
# if have_details:
# thead << th().set_text('details')
ans << thead
# 创建表主体
for test in data['detail']:
for test in data:
# print(data)
row = tr()
for key in summary:
row << td().set_text(str2html(str(test[key])))
# if have_details:
# row << td().set_text(f"<button onclick=\"ec('{test['name']}d')\">expand/collapse</button>")
# row << td(a(onclick=f'ec("{test["name"]}d")').set_text('expand/collapse'))
ans << row
return str(ans)
def make_details(data, details):
ans = div()
for test in data['detail']:
tab = table(id=f"{test['name']}d", style="display: table", border="1")
# 创建表头
tab << tr(th(colspan=str(len(details))).set_text(test['name']))
thead = tr()
for key in details:
thead << th().set_text(key)
tab << thead
# 创建表主体
row = tr()
for key in details:
row << td().set_text(str2html(str(test[key])))
tab << row
ans << tab
def make_one_line_table(data, header):
tab = table(border="1")
tab << tr(th(colspan=str(len(header))).set_text(data['name']))
thead = tr()
for key in header:
thead << th().set_text(key)
tab << thead
return str(ans)
# 创建表主体
row = tr()
for key in header:
row << td().set_text(str2html(str(data[key])))
tab << row
return str(tab)
# verdicts = ['Accept', 'Accept', 'Wrong Answer']
def make_verdict(verdicts: list):
for x in verdicts:
if x not in ('Accept', 'AC'):
if x != Verdict.Accept:
return x
return 'Accept'
return Verdict.Accept
import pygrading.general_test as gg
from verdict import Verdict
def run(job: gg.Job, testcase: gg.TestCases.SingleTestCase):
pass
config = job.get_config()
result = {'name': testcase.name, 'score': 0}
input_str = gg.utils.readfile(str(testcase.input_src))
run_result = gg.utils.exec(config['exec_src'], input_str=input_str)
result['output'] = run_result.stdout
result['time'] = run_result.exec_time
if run_result.returncode != config['return_code']:
result['verdict'] = Verdict.RuntimeError
result['stderr'] = run_result.stderr
result['return_code'] = run_result.returncode
return result
answer = gg.utils.readfile(str(testcase.output_src))
result['answer'] = answer
if gg.utils.compare_str(answer, run_result.stdout):
result['verdict'] = Verdict.Accept
result['score'] = testcase.score
else:
result['verdict'] = Verdict.WrongAnswer
return result
......@@ -23,7 +23,7 @@ class Env:
self.config = {
'submit_dir': '/coursegrader/submit',
'testcase_dir': '/coursegrader/testdata',
'errcode': 0,
'return_code': 0,
"exec_dir": tempfile.mkdtemp()
}
......@@ -37,7 +37,7 @@ class Env:
self.is_debug = self.config.get("debug", False)
if "testcase_num" not in self.config:
self.config["testcase_num"] = count_testcase(self.config["testcase_dir"])
self.config["exec_path"] = os.path.join(self.config["exec_dir"], "exec.out")
self.config["exec_src"] = os.path.join(self.config["exec_dir"], "exec.out")
loge(self.config)
return self
......
class Verdict:
AC = "Accept"
WA = "Wrong Answer"
CE = "Compile Error"
RE = "Runtime Error"
UE = "Unknown Error"
Accept = AC
WrongAnswer = WA
CompileError = CE
RuntimeError = RE
UnknownError = UE
import pygrading.general_test as gg
import os
import sys
import json
only_run = []
def test(image):
test_src = os.path.join(os.getcwd(), 'test')
print(test_src)
if not os.path.exists(test_src):
print("No test cases")
exit(1)
test_result_src = os.path.join(os.getcwd(), "test_result")
# os.makedirs(test_result_src, exist_ok=True)
cmds = []
# lst = [int(x) for x in os.listdir(test_src)]
# lst = sorted(lst)
# lst = [str(x) for x in lst]
lst = os.listdir(test_src)
statistic = {}
for test in lst:
if only_run and test not in only_run:
continue
testcase = os.path.join(test_src, test)
if not os.path.isdir(testcase):
continue
local_submit = os.path.join(testcase, "submit")
local_testcase = os.path.join(testcase, "testdata")
docker_submit = '/mnt/cgsubmit'
cmd = f"docker run --rm " \
f"-e CONFIG_SRC=/mnt/config.json " \
f"--mount type=bind,source=\"{os.getcwd()}/config.json\",target=\"/mnt/config.json\" " \
f"--mount type=bind,source=\"{local_testcase}\",target=\"/coursegrader/testdata\" " \
f"--mount type=bind,source=\"{local_submit}\",target=\"/coursegrader/submit\" " \
f"--mount type=bind,source=\"{os.getcwd()}/kernel.zip\",target=\"/home/cguser/kernel.zip\" " \
f"-u root {image} python /home/cguser/kernel.zip"
cmds.append(cmd)
res = gg.utils.exec(cmd)
try:
res_json = json.loads(res.stdout)
except:
res_json = {"verdict": "Not Json", "score": 0}
# os.system(cmd)
print(f"test: {test} result: {res_json['verdict']} score: {res_json['score']}")
if not res_json['verdict'] in statistic:
statistic[res_json['verdict']] = []
statistic[res_json['verdict']].append(test)
result_src = os.path.join(testcase, f"result")
os.makedirs(result_src, exist_ok=True)
with open(os.path.join(result_src, 'result.json'), 'w') as f:
f.write(res.stdout)
with open(os.path.join(result_src, 'stderr.txt'), 'w') as f:
f.write(res.stderr)
with open(os.path.join(result_src, "result.html"), 'w') as f:
f.write(str(res_json.get('comment', "No COMMENT</br>")))
f.write(str(res_json.get('detail', "No DETAIL</br>")))
for cmd in cmds:
print(cmd)
for k, v in statistic.items():
if k == 'Accept':
print(f"{k}: {len(v)}")
else:
print(f"{k}: {v}")
if __name__ == '__main__':
test(sys.argv[1])
#include <stdio.h>
int main(void) {
int n;
int a, b;
while (~scanf("%d", &n)) {
while (n--) {
scanf("%d%d", &a, &b);
printf("%u\n", a + b);
}
}
return 0;
}
\ No newline at end of file
10
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
5
-1 -2
-1 1
100 200
65537 65537
0 0
3
7
11
15
19
23
27
31
35
39
-3
0
300
131074
0
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment