feat: judger: limit memory usage and add more docs
This commit is contained in:
parent
976f2700ef
commit
212511d7b4
@ -5,7 +5,7 @@
|
|||||||
```
|
```
|
||||||
.
|
.
|
||||||
├── config.json # 题目配置信息
|
├── config.json # 题目配置信息
|
||||||
├── description.md # (not used) 题目描述必须通过 API 提交给系统
|
├── description.md # (optional) 题目描述,必须通过 API 提交,使用 import 脚本时将读取该文件
|
||||||
├── data # 数据目录
|
├── data # 数据目录
|
||||||
│ ├── input # 输入数据
|
│ ├── input # 输入数据
|
||||||
│ │ ├── (x).input # 第 x 组输入数据
|
│ │ ├── (x).input # 第 x 组输入数据
|
||||||
@ -25,20 +25,21 @@
|
|||||||
|
|
||||||
```json5
|
```json5
|
||||||
{
|
{
|
||||||
"Runtime": {
|
"Runtime": {
|
||||||
// 运行时配置
|
// 运行时配置
|
||||||
"TimeLimit": 1000, // 时间限制 (ms)
|
"TimeLimit": 1000, // 时间限制 (ms)
|
||||||
"MemoryLimit": 16, // 内存限制 (MB)
|
"MemoryLimit": 16, // 内存限制 (MB)
|
||||||
"NProcLimit": 1 // 进(线)程 限制
|
"NProcLimit": 1 // 进(线)程 限制
|
||||||
},
|
},
|
||||||
"Languages": [
|
"Languages": [
|
||||||
|
// 支持的语言
|
||||||
// c 语言,使用自定义评测脚本,脚本为 ./judge/XYZ.Makefile
|
// c 语言,使用自定义评测脚本,脚本为 ./judge/XYZ.Makefile
|
||||||
{"Lang": "c", "Type": "custom", "Script": "XYZ.Makefile", "Cmp": ""},
|
{"Lang": "c", "Type": "custom", "Script": "XYZ.Makefile", "Cmp": ""},
|
||||||
// c++ 语言,使用默认评测脚本,答案比对方式为 NCMP(testlib)
|
// c++ 语言,使用默认评测脚本,答案比对方式为 NCMP(testlib)
|
||||||
{"Lang": "cpp", "Type": "default", "Script": "", "Cmp": "NCMP"}
|
{"Lang": "cpp", "Type": "default", "Script": "", "Cmp": "NCMP"}
|
||||||
], // 支持的语言
|
],
|
||||||
"Tasks": [
|
"Tasks": [
|
||||||
// 评测点信息
|
// 评测点信息
|
||||||
{"Id": 1, "Points": 10}, // 第一个评测点,分值 25 分,使用 ./data/{input,output}/1.{input,output} 为测试数据
|
{"Id": 1, "Points": 10}, // 第一个评测点,分值 25 分,使用 ./data/{input,output}/1.{input,output} 为测试数据
|
||||||
{"Id": 2, "Points": 20},
|
{"Id": 2, "Points": 20},
|
||||||
{"Id": 3, "Points": 30},
|
{"Id": 3, "Points": 30},
|
||||||
@ -51,7 +52,7 @@
|
|||||||
|
|
||||||
1. 默认评测脚本目前只支持 `c` 语言和 `cpp`,参见 `../../framework/template/default/{c,cpp}.Makefile`
|
1. 默认评测脚本目前只支持 `c` 语言和 `cpp`,参见 `../../framework/template/default/{c,cpp}.Makefile`
|
||||||
2. 自定义评测脚本参见 `./judge/XYZ.Makefile`
|
2. 自定义评测脚本参见 `./judge/XYZ.Makefile`
|
||||||
3. `prebuild.Makefile`: 题目初始化脚本,用于编译辅助程序、生成数据等。如果存在改文件,系统会在题目分发到判机后自动执行,否则跳过改步骤
|
3. `prebuild.Makefile`: 题目初始化脚本,用于编译辅助程序、生成数据等。如果存在该文件,系统会在题目分发到判机后自动执行,否则跳过该步骤
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
|
@ -2,16 +2,37 @@
|
|||||||
include ${TEMPLATE}/c.mk ${TEMPLATE}/Judger.mk
|
include ${TEMPLATE}/c.mk ${TEMPLATE}/Judger.mk
|
||||||
|
|
||||||
# 评测分四个阶段
|
# 评测分四个阶段
|
||||||
# 1. prebuild: 用于提前生成测试数据、评测器、spj等工具,runner 只执行一次
|
# 1. prebuild: 用于提前生成测试数据、评测器、spj等工具,runner 只执行一次
|
||||||
# 只有 ./data, ./judge 目录可见
|
# 详细信息见 XYZ.Makefile
|
||||||
# 2. compile: 用于编译用户提交的程序
|
# 2. compile: 用于编译用户提交的程序
|
||||||
# 只有 ./user/$(USER_PROG).$(LANG) 和 ./judge 目录可见
|
# 目录映射情况:
|
||||||
# 3. run: 运行用户程序
|
# /woj/problem
|
||||||
# 只有 ./data/input/*.input 和 ./user/$(USER_PROG).out 可见
|
# ├── judge 映射到题目目录的 ./judge <-- Readonly
|
||||||
# 用户输出存放于 ./user/?.out.usr
|
# └── user 映射到题目目录的 ./user <-- 用户提交的程序在这里,命名:$(USER_PROG).$(LANG)
|
||||||
# 使用 woj-sandbox 运行,等效于 $(PREFIX)/user/$(USER_PROG).out < $(PREFIX)/data/input/$(TEST_NUM).input > $(PREFIX)/user/$(TEST_NUM).out.usr
|
# 环境变量:
|
||||||
# 4. judge: 用于判定输出结果 环境变量 TEST_NUM 表示当前测试点编号
|
# USER_PROG=... <-- 一段随机字符串
|
||||||
# 所有目录 ./data ./judge ./user 可见
|
# LANG=... <-- 用户提交的程序的语言,如 c, cpp
|
||||||
|
# 其余通用环境变量,详见 ubuntu-full.Dockerfile
|
||||||
|
# 执行限制:
|
||||||
|
# 目前版本硬编码限制:时间 60s,内存 256mb
|
||||||
|
# 3. run: 运行用户程序
|
||||||
|
# 只有 ./data/input/*.input 和 ./user/$(USER_PROG).out 可见
|
||||||
|
# 用户输出存放于 ./user/?.out.usr
|
||||||
|
# 使用 woj-sandbox 运行,等效于 $(PREFIX)/user/$(USER_PROG).out < $(PREFIX)/data/input/$(TEST_NUM).input > $(PREFIX)/user/$(TEST_NUM).out.usr
|
||||||
|
# 4. judge: 用于判定输出结果 环境变量 TEST_NUM 表示当前测试点编号,每个测试点都会执行一次
|
||||||
|
# 目录映射情况:
|
||||||
|
# /woj/problem
|
||||||
|
# ├── data 映射到题目目录的 ./data <-- Readonly
|
||||||
|
# ├── judge 映射到题目目录的 ./judge <-- Readonly
|
||||||
|
# └── user
|
||||||
|
# ├── $(TEST_NUM).out.usr <-- 用户程序在 $(TEST_NUM) 上的输出
|
||||||
|
# └── $(TEST_NUM).judge <-- 评测结果写在这里,格式要求为 testlib 的 XML 格式
|
||||||
|
# 环境变量:
|
||||||
|
# TEST_NUM=... <-- 当前测试点编号
|
||||||
|
# CMP=... <-- 在 config.json 中配置的比较器,如 NCMP
|
||||||
|
# 其余通用环境变量,详见 ubuntu-full.Dockerfile
|
||||||
|
# 执行限制:
|
||||||
|
# 目前版本硬编码限制:时间 60s,内存 256mb
|
||||||
|
|
||||||
compile:
|
compile:
|
||||||
$(CC) $(CFLAGS) -o $(PREFIX)/user/$(USER_PROG).out $(PREFIX)/user/$(USER_PROG).$(LANG) $(PREFIX)/judge/gadget.c
|
$(CC) $(CFLAGS) -o $(PREFIX)/user/$(USER_PROG).out $(PREFIX)/user/$(USER_PROG).$(LANG) $(PREFIX)/judge/gadget.c
|
||||||
|
@ -2,6 +2,17 @@ include ${TEMPLATE}/c.mk ${TEMPLATE}/Judger.mk
|
|||||||
|
|
||||||
# 当题目被下载到 runner 后,会自动执行 prebuild 阶段,判题时不会再次执行
|
# 当题目被下载到 runner 后,会自动执行 prebuild 阶段,判题时不会再次执行
|
||||||
|
|
||||||
|
# prebuild 阶段环境信息
|
||||||
|
# 目录映射情况:
|
||||||
|
# /woj/problem
|
||||||
|
# ├── data 映射到题目目录的 ./data
|
||||||
|
# └── judge 映射到题目目录的 ./judge
|
||||||
|
# 环境变量:
|
||||||
|
# PREFIX=/woj/problem
|
||||||
|
# 其余通用环境变量,详见 ubuntu-full.Dockerfile
|
||||||
|
# 执行限制:
|
||||||
|
# 目前版本硬编码限制:时间 300s,内存 1g
|
||||||
|
|
||||||
prebuild:
|
prebuild:
|
||||||
# 生成测试数据生成工具
|
# 生成测试数据生成工具
|
||||||
clang++ -I$(TESTLIB) -Ofast -o $(PREFIX)/judge/gen.out $(PREFIX)/judge/gen.cpp
|
clang++ -I$(TESTLIB) -Ofast -o $(PREFIX)/judge/gen.out $(PREFIX)/judge/gen.cpp
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
. common.sh
|
SCRIPT_PATH=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
. "$SCRIPT_PATH/common.sh"
|
||||||
|
|
||||||
function docker_run() {
|
function docker_run() {
|
||||||
local timeout=${TIMEOUT:-10}
|
local timeout=${TIMEOUT:-10}
|
||||||
|
local network=${NETWORK:-"none"}
|
||||||
|
local memory=${MEMORY:-"256m"}
|
||||||
local log_file=${LOG_FILE:-"/dev/stderr"}
|
local log_file=${LOG_FILE:-"/dev/stderr"}
|
||||||
local log_limit=${LOG_LIMIT:-4K}
|
local log_limit=${LOG_LIMIT:-4K}
|
||||||
log_info "$DOCKER run with timeout $timeout"
|
log_info "$DOCKER run with timeout $timeout"
|
||||||
@ -12,7 +15,7 @@ function docker_run() {
|
|||||||
sleep "$timeout"
|
sleep "$timeout"
|
||||||
$DOCKER kill "$CONTAINER_NAME"
|
$DOCKER kill "$CONTAINER_NAME"
|
||||||
) &
|
) &
|
||||||
$DOCKER run --rm --name "$CONTAINER_NAME" "$@" 2>&1 | head -c "$log_limit" >"$log_file"
|
$DOCKER run --rm --name "$CONTAINER_NAME" --network "$network" --memory "$memory" "$@" 2>&1 | head -c "$log_limit" >"$log_file"
|
||||||
pkill -P $$
|
pkill -P $$
|
||||||
$DOCKER kill "$CONTAINER_NAME" >/dev/null 2>&1
|
$DOCKER kill "$CONTAINER_NAME" >/dev/null 2>&1
|
||||||
return 0
|
return 0
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
. common.sh
|
SCRIPT_PATH=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
. "$SCRIPT_PATH/common.sh"
|
||||||
|
|
||||||
cd "$(dirname "$0")"/../ || exit 1
|
cd "$(dirname "$0")"/../ || exit 1
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
. common.sh
|
SCRIPT_PATH=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
. "$SCRIPT_PATH/common.sh"
|
||||||
|
|
||||||
# get_problem_info
|
# get_problem_info
|
||||||
# extract language info and limits
|
# extract language info and limits
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
||||||
. "$WORKSPACE"/scripts/run_timeout.sh
|
|
||||||
. "$WORKSPACE"/scripts/common.sh
|
. "$WORKSPACE"/scripts/common.sh
|
||||||
|
. "$WORKSPACE"/scripts/docker_run.sh
|
||||||
. "$WORKSPACE"/scripts/problem.sh
|
. "$WORKSPACE"/scripts/problem.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
||||||
. "$WORKSPACE"/scripts/run_timeout.sh
|
|
||||||
. "$WORKSPACE"/scripts/common.sh
|
. "$WORKSPACE"/scripts/common.sh
|
||||||
|
. "$WORKSPACE"/scripts/docker_run.sh
|
||||||
. "$WORKSPACE"/scripts/problem.sh
|
. "$WORKSPACE"/scripts/problem.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
||||||
. "$WORKSPACE"/scripts/run_timeout.sh
|
|
||||||
. "$WORKSPACE"/scripts/common.sh
|
. "$WORKSPACE"/scripts/common.sh
|
||||||
|
. "$WORKSPACE"/scripts/docker_run.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ]; then
|
||||||
log_warn "Usage: $0 <problem> <timeout>"
|
log_warn "Usage: $0 <problem> <timeout>"
|
||||||
@ -22,6 +22,7 @@ if [ ! -f "$WORKSPACE/problem/$1/judge/prebuild.Makefile" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export TIMEOUT=${2:-300}
|
export TIMEOUT=${2:-300}
|
||||||
|
export MEMORY="1g"
|
||||||
docker_run \
|
docker_run \
|
||||||
-v "$WORKSPACE/problem/$1/data":/woj/problem/data \
|
-v "$WORKSPACE/problem/$1/data":/woj/problem/data \
|
||||||
-v "$WORKSPACE/problem/$1/judge":/woj/problem/judge \
|
-v "$WORKSPACE/problem/$1/judge":/woj/problem/judge \
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
||||||
. "$WORKSPACE"/scripts/run_timeout.sh
|
|
||||||
. "$WORKSPACE"/scripts/common.sh
|
. "$WORKSPACE"/scripts/common.sh
|
||||||
|
. "$WORKSPACE"/scripts/docker_run.sh
|
||||||
. "$WORKSPACE"/scripts/problem.sh
|
. "$WORKSPACE"/scripts/problem.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user