Description:
change memory resolution in report to kbytes
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r164:447fdbbeac2c - - 3 files changed: 4 inserted, 4 deleted

@@ -153,97 +153,97
153 cmp_file = File.open(cmp_msg_fname)
153 cmp_file = File.open(cmp_msg_fname)
154 cmp_msg = cmp_file.read
154 cmp_msg = cmp_file.read
155 cmp_file.close
155 cmp_file.close
156
156
157 result_file_name = "#{test_result_dir}/1/result"
157 result_file_name = "#{test_result_dir}/1/result"
158
158
159 if File.exists?(result_file_name)
159 if File.exists?(result_file_name)
160 output_file_name = "#{test_result_dir}/1/output.txt"
160 output_file_name = "#{test_result_dir}/1/output.txt"
161 results = []
161 results = []
162 File.open("#{test_result_dir}/1/result") do |f|
162 File.open("#{test_result_dir}/1/result") do |f|
163 results = f.readlines
163 results = f.readlines
164 end
164 end
165 stat = extract_running_stat(results)
165 stat = extract_running_stat(results)
166
166
167 return {
167 return {
168 :output_file_name => output_file_name,
168 :output_file_name => output_file_name,
169 :running_stat => stat,
169 :running_stat => stat,
170 :comment => "",
170 :comment => "",
171 :cmp_msg => cmp_msg}
171 :cmp_msg => cmp_msg}
172 else
172 else
173 return {
173 return {
174 :running_stat => nil,
174 :running_stat => nil,
175 :comment => "Compilation error",
175 :comment => "Compilation error",
176 :cmp_msg => cmp_msg}
176 :cmp_msg => cmp_msg}
177 end
177 end
178 end
178 end
179
179
180 def extract_running_stat(results)
180 def extract_running_stat(results)
181 running_stat_line = results[-1]
181 running_stat_line = results[-1]
182
182
183 # extract exit status line
183 # extract exit status line
184 run_stat = ""
184 run_stat = ""
185 if !(/[Cc]orrect/.match(results[0]))
185 if !(/[Cc]orrect/.match(results[0]))
186 run_stat = results[0].chomp
186 run_stat = results[0].chomp
187 else
187 else
188 run_stat = 'Program exited normally'
188 run_stat = 'Program exited normally'
189 end
189 end
190
190
191 # extract running time
191 # extract running time
192 if res = /r(.*)u(.*)s/.match(running_stat_line)
192 if res = /r(.*)u(.*)s/.match(running_stat_line)
193 seconds = (res[1].to_f + res[2].to_f)
193 seconds = (res[1].to_f + res[2].to_f)
194 time_stat = "Time used: #{seconds} sec."
194 time_stat = "Time used: #{seconds} sec."
195 else
195 else
196 seconds = nil
196 seconds = nil
197 time_stat = "Time used: n/a sec."
197 time_stat = "Time used: n/a sec."
198 end
198 end
199
199
200 # extract memory usage
200 # extract memory usage
201 - if res = /s(.*)m/.match(running_stat_line)
201 + if res = /s(.*)kbytes/.match(running_stat_line)
202 memory_used = res[1].to_i
202 memory_used = res[1].to_i
203 else
203 else
204 memory_used = -1
204 memory_used = -1
205 end
205 end
206
206
207 return {
207 return {
208 :msg => "#{run_stat}\n#{time_stat}",
208 :msg => "#{run_stat}\n#{time_stat}",
209 :running_time => seconds,
209 :running_time => seconds,
210 :exit_status => run_stat,
210 :exit_status => run_stat,
211 :memory_usage => memory_used
211 :memory_usage => memory_used
212 }
212 }
213 end
213 end
214
214
215 def save_result(test_request,result)
215 def save_result(test_request,result)
216 if result[:output_file_name]!=nil
216 if result[:output_file_name]!=nil
217 test_request.output_file_name = link_output_file(test_request,
217 test_request.output_file_name = link_output_file(test_request,
218 result[:output_file_name])
218 result[:output_file_name])
219 end
219 end
220 test_request.graded_at = Time.now
220 test_request.graded_at = Time.now
221 test_request.compiler_message = (result[:cmp_msg] or '')
221 test_request.compiler_message = (result[:cmp_msg] or '')
222 test_request.grader_comment = (result[:comment] or '')
222 test_request.grader_comment = (result[:comment] or '')
223 if result[:running_stat]!=nil
223 if result[:running_stat]!=nil
224 test_request.running_stat = (result[:running_stat][:msg] or '')
224 test_request.running_stat = (result[:running_stat][:msg] or '')
225 test_request.running_time = (result[:running_stat][:running_time] or nil)
225 test_request.running_time = (result[:running_stat][:running_time] or nil)
226 test_request.exit_status = result[:running_stat][:exit_status]
226 test_request.exit_status = result[:running_stat][:exit_status]
227 test_request.memory_usage = result[:running_stat][:memory_usage]
227 test_request.memory_usage = result[:running_stat][:memory_usage]
228 else
228 else
229 test_request.running_stat = ''
229 test_request.running_stat = ''
230 end
230 end
231 test_request.save
231 test_request.save
232 end
232 end
233
233
234 protected
234 protected
235 def link_output_file(test_request, fname)
235 def link_output_file(test_request, fname)
236 target_file_name = random_output_file_name(test_request.user,
236 target_file_name = random_output_file_name(test_request.user,
237 test_request.problem)
237 test_request.problem)
238 FileUtils.mkdir_p(File.dirname(target_file_name))
238 FileUtils.mkdir_p(File.dirname(target_file_name))
239 Grader::link_or_copy("#{fname}", "#{target_file_name}")
239 Grader::link_or_copy("#{fname}", "#{target_file_name}")
240 return target_file_name
240 return target_file_name
241 end
241 end
242
242
243 def random_output_file_name(user,problem)
243 def random_output_file_name(user,problem)
244 problem_name = TestRequest.name_of(problem)
244 problem_name = TestRequest.name_of(problem)
245 begin
245 begin
246 tmpname = "#{@config.test_request_output_base_dir}" +
246 tmpname = "#{@config.test_request_output_base_dir}" +
247 "/#{user.login}/#{problem_name}/#{rand(10000)}"
247 "/#{user.login}/#{problem_name}/#{rand(10000)}"
248 end while File.exists?(tmpname)
248 end while File.exists?(tmpname)
249 tmpname
249 tmpname
@@ -115,146 +115,146
115 static void die(char *msg, ...) NONRET;
115 static void die(char *msg, ...) NONRET;
116 static void sample_mem_peak(void);
116 static void sample_mem_peak(void);
117
117
118 /*** Meta-files ***/
118 /*** Meta-files ***/
119
119
120 static FILE *metafile;
120 static FILE *metafile;
121
121
122 static void
122 static void
123 meta_open(const char *name)
123 meta_open(const char *name)
124 {
124 {
125 if (!strcmp(name, "-"))
125 if (!strcmp(name, "-"))
126 {
126 {
127 metafile = stdout;
127 metafile = stdout;
128 return;
128 return;
129 }
129 }
130 metafile = fopen(name, "w");
130 metafile = fopen(name, "w");
131 if (!metafile)
131 if (!metafile)
132 die("Failed to open metafile '%s'",name);
132 die("Failed to open metafile '%s'",name);
133 }
133 }
134
134
135 static void
135 static void
136 meta_close(void)
136 meta_close(void)
137 {
137 {
138 if (metafile && metafile != stdout)
138 if (metafile && metafile != stdout)
139 fclose(metafile);
139 fclose(metafile);
140 }
140 }
141
141
142 static void __attribute__((format(printf,1,2)))
142 static void __attribute__((format(printf,1,2)))
143 meta_printf(const char *fmt, ...)
143 meta_printf(const char *fmt, ...)
144 {
144 {
145 if (!metafile)
145 if (!metafile)
146 return;
146 return;
147
147
148 va_list args;
148 va_list args;
149 va_start(args, fmt);
149 va_start(args, fmt);
150 vfprintf(metafile, fmt, args);
150 vfprintf(metafile, fmt, args);
151 va_end(args);
151 va_end(args);
152 }
152 }
153
153
154
154
155 static void print_running_stat(double wall_time,
155 static void print_running_stat(double wall_time,
156 double user_time,
156 double user_time,
157 double system_time,
157 double system_time,
158 int mem_usage)
158 int mem_usage)
159 {
159 {
160 //total is user
160 //total is user
161 //wall is wall
161 //wall is wall
162 //
162 //
163 - fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n",
163 + fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dkbytes\n",
164 wall_time, user_time, system_time, mem_usage);
164 wall_time, user_time, system_time, mem_usage);
165 }
165 }
166
166
167 static void
167 static void
168 final_stats(struct rusage *rus)
168 final_stats(struct rusage *rus)
169 {
169 {
170 struct timeval total, now, wall;
170 struct timeval total, now, wall;
171 timeradd(&rus->ru_utime, &rus->ru_stime, &total);
171 timeradd(&rus->ru_utime, &rus->ru_stime, &total);
172 total_ms = total.tv_sec*1000 + total.tv_usec/1000;
172 total_ms = total.tv_sec*1000 + total.tv_usec/1000;
173 gettimeofday(&now, NULL);
173 gettimeofday(&now, NULL);
174 timersub(&now, &start_time, &wall);
174 timersub(&now, &start_time, &wall);
175 wall_ms = wall.tv_sec*1000 + wall.tv_usec/1000;
175 wall_ms = wall.tv_sec*1000 + wall.tv_usec/1000;
176 sys_ms = rus->ru_stime.tv_sec * 1000 + rus->ru_stime.tv_usec / 1000;
176 sys_ms = rus->ru_stime.tv_sec * 1000 + rus->ru_stime.tv_usec / 1000;
177
177
178 meta_printf("time:%d.%03d\n", total_ms/1000, total_ms%1000);
178 meta_printf("time:%d.%03d\n", total_ms/1000, total_ms%1000);
179 meta_printf("time-wall:%d.%03d\n", wall_ms/1000, wall_ms%1000);
179 meta_printf("time-wall:%d.%03d\n", wall_ms/1000, wall_ms%1000);
180 meta_printf("mem:%llu\n", (unsigned long long) mem_peak_kb * 1024);
180 meta_printf("mem:%llu\n", (unsigned long long) mem_peak_kb * 1024);
181 }
181 }
182
182
183 /*** Messages and exits ***/
183 /*** Messages and exits ***/
184
184
185 static void NONRET
185 static void NONRET
186 box_exit(int rc)
186 box_exit(int rc)
187 {
187 {
188 if (box_pid > 0)
188 if (box_pid > 0)
189 {
189 {
190 sample_mem_peak();
190 sample_mem_peak();
191 if (is_ptraced)
191 if (is_ptraced)
192 ptrace(PTRACE_KILL, box_pid);
192 ptrace(PTRACE_KILL, box_pid);
193 kill(-box_pid, SIGKILL);
193 kill(-box_pid, SIGKILL);
194 kill(box_pid, SIGKILL);
194 kill(box_pid, SIGKILL);
195 meta_printf("killed:1\n");
195 meta_printf("killed:1\n");
196
196
197 struct rusage rus;
197 struct rusage rus;
198 int p, stat;
198 int p, stat;
199 do
199 do
200 p = wait4(box_pid, &stat, 0, &rus);
200 p = wait4(box_pid, &stat, 0, &rus);
201 while (p < 0 && errno == EINTR);
201 while (p < 0 && errno == EINTR);
202 if (p < 0)
202 if (p < 0)
203 fprintf(stderr, "UGH: Lost track of the process (%m)\n");
203 fprintf(stderr, "UGH: Lost track of the process (%m)\n");
204 else {
204 else {
205 final_stats(&rus);
205 final_stats(&rus);
206 }
206 }
207 }
207 }
208 print_running_stat(
208 print_running_stat(
209 (double)wall_ms/1000,
209 (double)wall_ms/1000,
210 (double)total_ms/1000,
210 (double)total_ms/1000,
211 (double)sys_ms/1000,
211 (double)sys_ms/1000,
212 - (mem_peak_kb + 1023) / 1024);
212 + mem_peak_kb);
213 meta_close();
213 meta_close();
214 exit(rc);
214 exit(rc);
215 }
215 }
216
216
217 static void
217 static void
218 flush_line(void)
218 flush_line(void)
219 {
219 {
220 if (partial_line)
220 if (partial_line)
221 fputc('\n', stderr);
221 fputc('\n', stderr);
222 partial_line = 0;
222 partial_line = 0;
223 }
223 }
224
224
225 /* Report an error of the sandbox itself */
225 /* Report an error of the sandbox itself */
226 static void NONRET __attribute__((format(printf,1,2)))
226 static void NONRET __attribute__((format(printf,1,2)))
227 die(char *msg, ...)
227 die(char *msg, ...)
228 {
228 {
229 va_list args;
229 va_list args;
230 va_start(args, msg);
230 va_start(args, msg);
231 flush_line();
231 flush_line();
232 char buf[1024];
232 char buf[1024];
233 vsnprintf(buf, sizeof(buf), msg, args);
233 vsnprintf(buf, sizeof(buf), msg, args);
234 meta_printf("status:XX\nmessage:%s\n", buf);
234 meta_printf("status:XX\nmessage:%s\n", buf);
235 fputs(buf, stderr);
235 fputs(buf, stderr);
236 fputc('\n', stderr);
236 fputc('\n', stderr);
237 box_exit(2);
237 box_exit(2);
238 }
238 }
239
239
240 /* Report an error of the program inside the sandbox */
240 /* Report an error of the program inside the sandbox */
241 static void NONRET __attribute__((format(printf,1,2)))
241 static void NONRET __attribute__((format(printf,1,2)))
242 err(char *msg, ...)
242 err(char *msg, ...)
243 {
243 {
244 va_list args;
244 va_list args;
245 va_start(args, msg);
245 va_start(args, msg);
246 flush_line();
246 flush_line();
247 if (msg[0] && msg[1] && msg[2] == ':' && msg[3] == ' ')
247 if (msg[0] && msg[1] && msg[2] == ':' && msg[3] == ' ')
248 {
248 {
249 meta_printf("status:%c%c\n", msg[0], msg[1]);
249 meta_printf("status:%c%c\n", msg[0], msg[1]);
250 msg += 4;
250 msg += 4;
251 }
251 }
252 char buf[1024];
252 char buf[1024];
253 vsnprintf(buf, sizeof(buf), msg, args);
253 vsnprintf(buf, sizeof(buf), msg, args);
254 meta_printf("message:%s\n", buf);
254 meta_printf("message:%s\n", buf);
255 fputs(buf, stderr);
255 fputs(buf, stderr);
256 fputc('\n', stderr);
256 fputc('\n', stderr);
257 box_exit(1);
257 box_exit(1);
258 }
258 }
259
259
260 /* Write a message, but only if in verbose mode */
260 /* Write a message, but only if in verbose mode */
@@ -1,84 +1,84
1 #!/usr/bin/env ruby
1 #!/usr/bin/env ruby
2
2
3 CORRECT_MARK = 'P'
3 CORRECT_MARK = 'P'
4 INCORRECT_MARK = '-'
4 INCORRECT_MARK = '-'
5 TIMEOUT_MARK = 'T'
5 TIMEOUT_MARK = 'T'
6 RUN_ERROR_MARK = 'x'
6 RUN_ERROR_MARK = 'x'
7
7
8 def log(str='')
8 def log(str='')
9 if ENV['TALKATIVE']!=nil
9 if ENV['TALKATIVE']!=nil
10 puts str
10 puts str
11 end
11 end
12 if ENV['GRADER_LOGGING']!=nil
12 if ENV['GRADER_LOGGING']!=nil
13 log_fname = ENV['GRADER_LOGGING']
13 log_fname = ENV['GRADER_LOGGING']
14 fp = File.open(log_fname,"a")
14 fp = File.open(log_fname,"a")
15 fp.puts("grade: #{Time.new.strftime("%H:%M")} #{str}")
15 fp.puts("grade: #{Time.new.strftime("%H:%M")} #{str}")
16 fp.close
16 fp.close
17 end
17 end
18 end
18 end
19
19
20 def char_comment(comment)
20 def char_comment(comment)
21 if comment =~ /[Ii]ncorrect/
21 if comment =~ /[Ii]ncorrect/
22 INCORRECT_MARK
22 INCORRECT_MARK
23 elsif comment =~ /[Cc]orrect/
23 elsif comment =~ /[Cc]orrect/
24 CORRECT_MARK
24 CORRECT_MARK
25 elsif comment =~ /[Tt]ime/
25 elsif comment =~ /[Tt]ime/
26 TIMEOUT_MARK
26 TIMEOUT_MARK
27 elsif res = /^[Cc]omment:(.*)$/.match(comment)
27 elsif res = /^[Cc]omment:(.*)$/.match(comment)
28 res[1]
28 res[1]
29 else
29 else
30 RUN_ERROR_MARK # these are run time errors
30 RUN_ERROR_MARK # these are run time errors
31 end
31 end
32 end
32 end
33
33
34 def extract_time(t)
34 def extract_time(t)
35 puts "TIME: #{t}"
35 puts "TIME: #{t}"
36 - if (result=/^(.*)r(.*)u(.*)s(.*)m/.match(t))
36 + if (result=/^(.*)r(.*)u(.*)s(.*)kbytes/.match(t))
37 {:real => result[1], :user => result[2], :sys => result[3], :mem => result[4]}
37 {:real => result[1], :user => result[2], :sys => result[3], :mem => result[4]}
38 else
38 else
39 #{:real => 0, :user => 0, :sys => 0}
39 #{:real => 0, :user => 0, :sys => 0}
40 #puts "ERROR READING RUNNING TIME: #{t}"
40 #puts "ERROR READING RUNNING TIME: #{t}"
41 raise "Error reading running time: #{t}"
41 raise "Error reading running time: #{t}"
42 end
42 end
43 end
43 end
44
44
45 problem_home = ENV['PROBLEM_HOME']
45 problem_home = ENV['PROBLEM_HOME']
46 require "#{problem_home}/script/test_dsl.rb"
46 require "#{problem_home}/script/test_dsl.rb"
47 load "#{problem_home}/test_cases/all_tests.cfg"
47 load "#{problem_home}/test_cases/all_tests.cfg"
48 problem = Problem.get_instance
48 problem = Problem.get_instance
49
49
50 if problem.well_formed? == false
50 if problem.well_formed? == false
51 log "The problem specification is not well formed."
51 log "The problem specification is not well formed."
52 exit(127)
52 exit(127)
53 end
53 end
54
54
55 all_score = 0
55 all_score = 0
56 all_comment = ''
56 all_comment = ''
57 peak_memory = -1
57 peak_memory = -1
58 max_runtime = -1
58 max_runtime = -1
59 (1..(problem.runs.length-1)).each do |k|
59 (1..(problem.runs.length-1)).each do |k|
60 log "grade run #{k}"
60 log "grade run #{k}"
61 run = problem.runs[k]
61 run = problem.runs[k]
62 run_score = nil
62 run_score = nil
63 run_comment = ''
63 run_comment = ''
64 run_comment_short = ''
64 run_comment_short = ''
65 run.tests.each do |test_num|
65 run.tests.each do |test_num|
66 result_file_name = "#{test_num}/result"
66 result_file_name = "#{test_num}/result"
67 if not File.exists?(result_file_name)
67 if not File.exists?(result_file_name)
68 run_comment += "result file for test #{test_num} not found\n"
68 run_comment += "result file for test #{test_num} not found\n"
69 run_comment_short += RUN_ERROR_MARK
69 run_comment_short += RUN_ERROR_MARK
70 log "Cannot find the file #{test_num}/result!"
70 log "Cannot find the file #{test_num}/result!"
71 else
71 else
72 result_file = File.new(result_file_name, "r")
72 result_file = File.new(result_file_name, "r")
73 result_file_lines = result_file.readlines
73 result_file_lines = result_file.readlines
74 if result_file_lines.length>=3
74 if result_file_lines.length>=3
75 current_run_score = result_file_lines[1].to_i
75 current_run_score = result_file_lines[1].to_i
76 run_comment += result_file_lines[0]
76 run_comment += result_file_lines[0]
77 run_comment_short += char_comment(result_file_lines[0].chomp)
77 run_comment_short += char_comment(result_file_lines[0].chomp)
78
78
79 #update max runtime & memory
79 #update max runtime & memory
80 run_stat = extract_time result_file_lines[2]
80 run_stat = extract_time result_file_lines[2]
81 peak_memory = [peak_memory,run_stat[:mem].to_i].max
81 peak_memory = [peak_memory,run_stat[:mem].to_i].max
82 max_runtime = [max_runtime,run_stat[:user].to_f + run_stat[:sys].to_f].max
82 max_runtime = [max_runtime,run_stat[:user].to_f + run_stat[:sys].to_f].max
83 else
83 else
84 current_run_score = 0
84 current_run_score = 0
You need to be logged in to leave comments. Login now