class CC_Process(Process): def __init__(self, compare_func=strictly_compare, name: str = '', max_time: list = [], max_memery: list = [], inputfiles: list = [], score: int = 100, sub_score: list = [], anses: list = [], input_cc_code: str = '', tmp_cc_path: str = 'main.cpp', tmp_output_dir: str = './', output_cc_file='./main', additional_args: list = [], compare_in_memory: bool = True, load_ans: bool = False,exit_if_error:bool=True, use_cc_file=False, enable_o2: bool = True,clean:bool=False): super().__init__() self.process = Process() self.compare_func = compare_func self.name = name self.max_time = max_time self.max_memory = max_memery self.inputfiles = inputfiles self.anses = anses self.input_cc_code = input_cc_code self.output_cc_file = output_cc_file self.additional_args = additional_args self.compare_in_memory = compare_in_memory self.use_cc_file = use_cc_file self.enable_o2 = enable_o2 self.tmp_cc_path = tmp_cc_path self.tmp_output_dir = tmp_output_dir self.load_ans = load_ans self.tmp_output_files = [] self.report = {'compile': {}, 'details': []} self.score = score self.sub_score = sub_score self._clean=clean self.exit_if_error=exit_if_error async def create_tasks(self): # self.process.add_block_task(await self.compile_cc_task()) for i in range(len(self.anses)): if self.compare_in_memory: self.process.add_task_chain(self.run_cc_task(in_file=self.inputfiles[i], maxtime=self.max_time[i], max_memory=self.max_memory[i])) self.process.add_nonblock_task(await self.compare_output(self.anses[i], '')) else: _out = self.tmp_output_dir + '/' + str(time.time()) self.tmp_output_files.append(_out) self.process.add_block_task( self.run_cc_task(in_file=self.inputfiles[i], out_file=_out, maxtime=self.max_time[i], max_memory=self.max_memory[i])) self.process.add_nonblock_task(await self.compare_output(self.anses[i], _out)) for i in self.process.process: i[0].exit_if_error=self.exit_if_error async def run(self): logging.debug('Compiling') compile = await self.compile_cc_task() await compile.run() if compile.err: logging.debug('Compile error') # logging.debug(compile.report) # print(compile.err) self.report['compile']['state'] = STATE.CompileError.value self.report['compile']['info'] = compile.err_detail self.score = 0 return STATE.CompileError self.report['compile']['state'] = STATE.CompileSuccess.value self.report['compile']['info'] = '' logging.debug('Create tasks') await self.create_tasks() # self.process.add_block_task(self.run_cc_task('test_example/1.in')) logging.debug('Start run process') await self.process.run() # os.unlink(self.tmp_cc_path) logging.debug('Finish run process') if self._clean: await self.clean() return await self.get_report() async def compile_cc_task(self): if not self.use_cc_file: async with aiofiles.open(self.tmp_cc_path, 'w') as f: await f.write(self.input_cc_code) self.input_cc_code = self.tmp_cc_path if self.enable_o2: operation = 'g++ -fno-asm -w -lm --static -std=c++11 -O2 {} -o {}'.format(self.input_cc_code, self.output_cc_file) else: operation = 'g++ -fno-asm -w -lm --static -std=c++11 {} -o {}'.format(self.input_cc_code, self.output_cc_file) # os.unlink(self.tmp_cc_path) return Lrun_task(operation=operation, cputime=5000, realtime=5000, exit_if_error=True) def run_cc_task(self, in_file: str, out_file: str = '', maxtime: int = 1000, max_memory: int = 128): if not self.compare_in_memory: operation = '{} <{} >{}'.format(self.output_cc_file, in_file, out_file) else: operation = '{} <{}'.format(self.output_cc_file, in_file) # operation=self.output_cc_file return Lrun_task(operation=operation, cputime=maxtime, realtime=maxtime, memory=max_memory) async def compare_output(self, _ans: str, _out): info = {} if self.load_ans: async with aiofiles.open(_ans) as f: info['ans'] = await f.read() else: info['ans'] = _ans if self.compare_in_memory: info['use_file'] = False return Function_task(args=[info], func=self.compare_func) else: info['use_file'] = True return Function_task(args=[info, _out], func=self.compare_func) async def clean(self): os.unlink(self.output_cc_file) if not self.use_cc_file: os.unlink(self.input_cc_code) if not self.compare_in_memory: for i in self.tmp_output_files: os.unlink(i) async def get_report(self): state = STATE.Accept # for i in self.report: # print(i) max_time = 0 max_memory = 0 for i in range(0, len(self.process.process), 2): tmp = self.process.process[i][0].report # print(self.process.process[i][0].__class__.__name__) print(tmp) max_time = max(max_time, max(self.process.process[i][0].report['cputime'], self.process.process[i][0].report['realtime'])) max_memory = max(max_memory, self.process.process[i][0].report['memory']) if self.process.process[i][0].err: state = self.process.process[i][0].err tmp['state'] = state self.score -= self.sub_score[i // 2] elif self.process.process[i + 1][0].err: state = self.process.process[i + 1][0].err tmp['state'] = state self.score -= self.sub_score[i // 2] else: tmp['state'] = STATE.Accept self.report['details'].append(tmp) if self.process.process[i][0].err != None and self.process.process[i][0].exit_if_error: break if self.process.process[i+1][0].err != None and self.process.process[i+1][0].exit_if_error: break self.report['ans'] = {'score': self.score, 'max_time': max_time, 'max_memory': max_memory, 'result': state} # print(self.report) return state