-
Notifications
You must be signed in to change notification settings - Fork 373
/
grade_all.py
123 lines (93 loc) · 3.44 KB
/
grade_all.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import argparse
import importlib
import json
import os
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor, TimeoutError
import gym_cutting_stock
import gymnasium as gym
from configs import CONFIGS
from tqdm import tqdm
def import_submodule(full_name):
module_name = full_name.split(".")
submodule_name = module_name[-1]
module_name = ".".join(module_name[:-1])
module = importlib.import_module(module_name)
submodule = getattr(module, submodule_name)
return submodule
def create_env(config):
env = gym.make(
"gym_cutting_stock/CuttingStock-v0",
**config,
)
return env
def run_one_episode(config, policy):
env = create_env(config)
observation, info = env.reset(seed=config["seed"])
terminated = False
truncated = False
try:
while not terminated and not truncated:
action = policy.get_action(observation, info)
observation, reward, terminated, truncated, info = env.step(action)
except Exception as e:
print(f"Error: {e}")
info = {"filled_ratio": 1.0, "trim_loss": 1.0}
return info
def grade_one_group(group_folder, force=False):
module_name = "policy" + group_folder[1:]
module_name = (
f"student_submissions.{group_folder}.{module_name}.Policy{group_folder[1:]}"
)
policy_class = import_submodule(module_name)
for pid in [1, 2]:
if not force and os.path.exists(
f"student_submissions/{group_folder}/grade_p{pid}.json"
):
print(f"{group_folder} is already graded!")
continue
results = []
for config in CONFIGS:
try:
policy = policy_class(policy_id=pid)
except Exception as e:
print(f"Error: {e}")
results.append({"filled_ratio": 1.0, "trim_loss": 1.0})
continue
executor = ThreadPoolExecutor(max_workers=1)
# Pass the arguments to the function via `submit`
future = executor.submit(run_one_episode, config, policy)
try:
# Timeout after 900 seconds
result = future.result(timeout=900)
except TimeoutError:
print("Function execution exceeded the time limit!")
result = {"filled_ratio": 1.0, "trim_loss": 1.0}
results.append(result)
# Save the results
with open(f"student_submissions/{group_folder}/grade_p{pid}.json", "w") as f:
json.dump(results, f, indent=4)
return True
def grade_all_groups(args):
group_folders = os.listdir("student_submissions")
group_folders.remove("s2210xxx")
# Sort the group folders
group_folders = sorted(group_folders)
# Ensure that the group_folders are folders
group_folders = [
group_folder
for group_folder in group_folders
if os.path.isdir(f"student_submissions/{group_folder}")
and group_folder.startswith("s")
]
with ProcessPoolExecutor(max_workers=args.num_workers) as executor:
results = list(
tqdm(executor.map(grade_one_group, group_folders),
total=len(group_folders))
)
if sum(results) == len(group_folders):
print("Grading completed successfully!")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--num_workers", type=int, default=4)
args = parser.parse_args()
grade_all_groups(args)