async def score_subtask(
    client: PistonClient,
    subtask: dict,
    submission: str,
    test_case_run_cache: Union[dict, None] = None,
    test_batch_size: int = 1,
) -> SubtaskResult:
    """
    Scores all test cases in a subtask.

    Args:
        client: PistonClient instance for executing code
        subtask: Dictionary containing subtask configuration
        test_cases: Dictionary mapping test names to (input, output) tuples
        submission: Source code of the submission
        test_case_run_cache: Optional cache of previously run test cases
        test_batch_size: evaluate these many test cases in parallel, then check if any of them failed (0 score): if so stop evaluating; otherwise continue with the next batch of test cases.
        -1 to evaluate all test cases in parallel
    Returns:
        SubtaskResult: Result of the subtask evaluation
    """
    subtask_result = SubtaskResult(
        problem=subtask["id"],
        subtask=subtask["subtask"],
        points=subtask["score"],
        score_precision=subtask["score_precision"],
        test_results=[],
    )

    # tests that are not cached
    tests_to_run = [
        (ti, test_name)
        for ti, test_name in enumerate(subtask["test_names"])
        if test_case_run_cache is None or test_name not in test_case_run_cache
    ]

    # initialize test results with cached results or empty (SKIPPED) TestResult objects
    subtask_result.test_results = [
        test_case_run_cache[test_name]
        if test_case_run_cache is not None and test_name in test_case_run_cache
        else TestResult(test_name=test_name)
        for test_name in subtask["test_names"]
    ]

    # we skip submissions where no code was extracted
    # no need to do anything, as we have a failed cached result
    if not submission or any(
        test_result.status != "SKIPPED" and test_result.score == 0.0 for test_result in subtask_result.test_results
    ):
        return subtask_result

    if "test_cases" in subtask:
        test_cases = subtask["test_cases"]
        if isinstance(subtask["test_cases"], list):
            test_cases = {test_name: test for test_name, test in zip(subtask["test_names"], subtask["test_cases"])}
    else:
        test_cases = load_ioi_tests(subtask["year"], subtask["id"])

    # run one batch, check if any of them failed (0 score): if so stop evaluating; otherwise continue with the next batch of test cases.
    for test_batch_to_run in batched(tests_to_run, test_batch_size):
        results = await asyncio.gather(
            *[
                asyncio.create_task(
                    score_single_test_case(
                        client, subtask, test_name, test_cases[test_name][0], test_cases[test_name][1], submission
                    )
                )
                for _, test_name in test_batch_to_run
            ]
        )
        for (ti, test_name), test_result in zip(test_batch_to_run, results):
            if test_case_run_cache is not None:
                test_case_run_cache[test_name] = test_result
            subtask_result.test_results[ti] = test_result

        # Stop early if it failed
        if any(test_result.score == 0.0 for test_result in results):
            break

    return subtask_result

    Scores all test cases in a subtask.

    Args:
        client: PistonClient instance for executing code
        subtask: Dictionary containing subtask configuration
        test_cases: Dictionary mapping test names to (input, output) tuples
        submission: Source code of the submission
        test_case_run_cache: Optional cache of previously run test cases
        test_batch_size: evaluate these many test cases in parallel, then check if any of them failed (0 score): if so stop evaluating; otherwise continue with the next batch of test cases.
        -1 to evaluate all test cases in parallel
    Returns:
        SubtaskResult: Result of the subtask evaluation
    
src/open_r1/utils/competitive_programming/ioi_scoring.py