Skip to content

Commit

Permalink
Add storage namespace to binary cache key
Browse files Browse the repository at this point in the history
  • Loading branch information
hieplpvip committed Oct 5, 2024
1 parent 2ce35b4 commit 6016d8c
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 13 deletions.
2 changes: 1 addition & 1 deletion dmoj/checkers/bridged.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def get_executor(problem_id, storage_namespace, files, flags, lang, compiler_tim
filenames = list(files.unwrap())

filenames = [os.path.join(get_problem_root(problem_id, storage_namespace), f) for f in filenames]
executor = compile_with_auxiliary_files(filenames, flags, lang, compiler_time_limit)
executor = compile_with_auxiliary_files(storage_namespace, filenames, flags, lang, compiler_time_limit)

return executor

Expand Down
4 changes: 3 additions & 1 deletion dmoj/commands/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def validate_problem(self, problem_id: str) -> bool:

filenames = [os.path.abspath(os.path.join(problem_root, name)) for name in filenames]
try:
executor = compile_with_auxiliary_files(filenames, lang=language, compiler_time_limit=compiler_time_limit)
executor = compile_with_auxiliary_files(
None, filenames, lang=language, compiler_time_limit=compiler_time_limit
)
except CompileError as compilation_error:
print_ansi('#ansi[Failed compiling validator!](red|bold)')
print(compilation_error.message.rstrip())
Expand Down
2 changes: 2 additions & 0 deletions dmoj/executors/base_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def __init__(
self,
problem_id: str,
source_code: bytes,
storage_namespace: Optional[str] = None,
dest_dir: Optional[str] = None,
hints: Optional[List[str]] = None,
unbuffered: bool = False,
Expand All @@ -145,6 +146,7 @@ def __init__(
self._dir = None
self.problem = problem_id
self.source = source_code
self.storage_namespace = '' if storage_namespace is None else storage_namespace
self._hints = hints or []
self.unbuffered = unbuffered
self.meta: Dict[str, Any] = {}
Expand Down
5 changes: 4 additions & 1 deletion dmoj/executors/c_like_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ def get_binary_cache_key(self) -> bytes:
command = self.get_command()
assert command is not None
key_components = (
[self.problem, command, self.get_march_flag()] + self.get_defines() + self.get_flags() + self.get_ldflags()
[self.storage_namespace, self.problem, command, self.get_march_flag()]
+ self.get_defines()
+ self.get_flags()
+ self.get_ldflags()
)
return utf8bytes(''.join(key_components)) + b''.join(self.source_dict.values())

Expand Down
2 changes: 1 addition & 1 deletion dmoj/executors/compiled_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def handle_compile_error(self, output: bytes) -> None:
raise CompileError(output)

def get_binary_cache_key(self) -> bytes:
return utf8bytes(self.problem) + self.source
return utf8bytes(self.storage_namespace) + utf8bytes(self.problem) + self.source

def compile(self) -> str:
process = self.create_compile_process(self.get_compile_args())
Expand Down
7 changes: 6 additions & 1 deletion dmoj/graders/bridged.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,10 @@ def _generate_interactor_binary(self) -> BaseExecutor:
flags = self.handler_data.get('flags', [])
unbuffered = self.handler_data.get('unbuffered', True)
return compile_with_auxiliary_files(
filenames, flags, self.handler_data.lang, self.handler_data.compiler_time_limit, unbuffered
self.problem.storage_namespace,
filenames,
flags,
self.handler_data.lang,
self.handler_data.compiler_time_limit,
unbuffered,
)
11 changes: 9 additions & 2 deletions dmoj/graders/communication.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ def _generate_binary(self) -> BaseExecutor:
aux_sources[signature_data['header']] = header
entry = entry_point
return executors[self.language].Executor(
self.problem.id, entry, aux_sources=aux_sources, defines=['-DSIGNATURE_GRADER']
self.problem.id,
entry,
storage_namespace=self.problem.storage_namespace,
aux_sources=aux_sources,
defines=['-DSIGNATURE_GRADER'],
)
elif self.language in java_siggraders:
aux_sources = {}
Expand All @@ -218,7 +222,9 @@ def _generate_binary(self) -> BaseExecutor:
entry = self.source
aux_sources[self.problem.id + '_lib'] = entry_point

return executors[self.language].Executor(self.problem.id, entry, aux_sources=aux_sources)
return executors[self.language].Executor(
self.problem.id, entry, storage_namespace=self.problem.storage_namespace, aux_sources=aux_sources
)
else:
raise InternalError('no valid runtime for signature grading %s found' % self.language)

Expand All @@ -236,6 +242,7 @@ def _generate_manager_binary(self) -> BaseExecutor:
lang = self.handler_data.manager.lang
compiler_time_limit = self.handler_data.manager.compiler_time_limit
return compile_with_auxiliary_files(
self.problem.storage_namespace,
filenames,
flags,
lang,
Expand Down
10 changes: 8 additions & 2 deletions dmoj/graders/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ def _generate_binary(self) -> BaseExecutor:
aux_sources[handler_data['header']] = header
entry = entry_point
return executors[self.language].Executor(
self.problem.id, entry, aux_sources=aux_sources, defines=['-DSIGNATURE_GRADER']
self.problem.id,
entry,
storage_namespace=self.problem.storage_namespace,
aux_sources=aux_sources,
defines=['-DSIGNATURE_GRADER'],
)
elif self.language in java_siggraders:
aux_sources = {}
Expand All @@ -43,6 +47,8 @@ def _generate_binary(self) -> BaseExecutor:
entry = self.source
aux_sources[self.problem.id + '_lib'] = entry_point

return executors[self.language].Executor(self.problem.id, entry, aux_sources=aux_sources)
return executors[self.language].Executor(
self.problem.id, entry, storage_namespace=self.problem.storage_namespace, aux_sources=aux_sources
)
else:
raise InternalError('no valid runtime for signature grading %s found' % self.language)
1 change: 1 addition & 0 deletions dmoj/graders/standard.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def _generate_binary(self) -> BaseExecutor:
return executors[self.language].Executor(
self.problem.id,
self.source,
storage_namespace=self.problem.storage_namespace,
hints=self.problem.config.hints or [],
unbuffered=self.problem.config.unbuffered,
meta=self.problem.config.meta or {},
Expand Down
4 changes: 3 additions & 1 deletion dmoj/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,9 @@ def _run_generator(self, gen: Union[str, ConfigNode], args: Optional[Iterable[st
filenames = [filenames]

filenames = [os.path.abspath(os.path.join(base, name)) for name in filenames]
executor = compile_with_auxiliary_files(filenames, flags, lang, compiler_time_limit)
executor = compile_with_auxiliary_files(
self.problem.storage_namespace, filenames, flags, lang, compiler_time_limit
)

# convert all args to str before launching; allows for smoother int passing
assert args is not None
Expand Down
12 changes: 9 additions & 3 deletions dmoj/utils/helper_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def mkdtemp():


def compile_with_auxiliary_files(
storage_namespace: Optional[str],
filenames: Sequence[str],
flags: List[str] = [],
lang: Optional[str] = None,
Expand Down Expand Up @@ -70,7 +71,12 @@ def find_runtime(*languages):

executor = executors.executors[lang].Executor

kwargs = {'fs': executor.fs + [RecursiveDir(tempfile.gettempdir())]}
kwargs = {
'storage_namespace': storage_namespace,
'cached': True,
'unbuffered': unbuffered,
'fs': executor.fs + [RecursiveDir(tempfile.gettempdir())],
}

if issubclass(executor, CompiledExecutor):
kwargs['compiler_time_limit'] = compiler_time_limit
Expand All @@ -81,11 +87,11 @@ def find_runtime(*languages):
# Optimize the common case.
if use_cpp or use_c:
# Some auxiliary files (like those using testlib.h) take an extremely long time to compile, so we cache them.
executor = executor('_aux_file', None, aux_sources=sources, cached=True, unbuffered=unbuffered, **kwargs)
executor = executor('_aux_file', None, aux_sources=sources, **kwargs)
else:
if len(sources) > 1:
raise InternalError('non-C/C++ auxiliary programs cannot be multi-file')
executor = executor('_aux_file', list(sources.values())[0], cached=True, unbuffered=unbuffered, **kwargs)
executor = executor('_aux_file', list(sources.values())[0], **kwargs)

return executor

Expand Down

0 comments on commit 6016d8c

Please sign in to comment.