-
Notifications
You must be signed in to change notification settings - Fork 8
114 singularity integration #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…nvironment variable configuration
…environment variable setup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds Singularity container support as an alternative to Docker for running BraTS algorithms, addressing issue #114. The implementation allows users to switch between Docker and Singularity backends via an environment variable or method parameter.
- Implements Singularity container runtime functionality alongside existing Docker support
- Adds backend selection mechanism through environment variable or explicit parameter
- Updates all algorithm inference methods to support the new backend parameter
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
brats/core/singularity.py | New module implementing Singularity container execution logic |
brats/core/brats_algorithm.py | Updated to dispatch between Docker and Singularity backends |
brats/constants.py | Added Backends enum for backend type definitions |
brats/core/segmentation_algorithms.py | Added backend parameter support to inference methods |
brats/core/missing_mri_algorithms.py | Added backend parameter support to inference methods |
brats/core/inpainting_algorithms.py | Added backend parameter support to inference methods |
pyproject.toml | Added spython dependency for Singularity support |
tests/core/test_singularity.py | Comprehensive test suite for Singularity functionality |
README.md | Updated documentation with Singularity installation instructions |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
/format |
🤖 I will now format your code with black. Check the status here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README.md also needs adjustments :)
please have a look at co-pilot comments and ensure tests are passing :)
please mark as ready for review once @MarcelRosier and me should review :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
force_cpu: bool, | ||
internal_external_name_map: Optional[Dict[str, str]] = None, | ||
): | ||
"""Run a docker container for the provided algorithm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring incorrectly states 'Run a docker container' when this function actually runs a Singularity container. This should be updated to reflect the correct container technology.
"""Run a docker container for the provided algorithm. | |
"""Run a Singularity container for the provided algorithm. |
Copilot uses AI. Check for mistakes.
image = _ensure_image(image=algorithm.run_args.docker_image) | ||
|
||
additional_files_path = _get_additional_files_path(algorithm) | ||
print(f"Additional files path: {additional_files_path}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This debug print statement should be replaced with a proper logger call for consistency with the rest of the codebase. Use logger.debug(f'Additional files path: {additional_files_path}')
instead.
print(f"Additional files path: {additional_files_path}") | |
logger.debug(f"Additional files path: {additional_files_path}") |
Copilot uses AI. Check for mistakes.
executor = Client.run( | ||
image, | ||
options=options, | ||
args=["infer", *command_args.split(" "), *extra_args], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Splitting command_args
by spaces can break arguments that contain spaces (e.g., file paths with spaces). This could cause incorrect argument parsing. Consider using a more robust argument parsing approach or ensure command_args
is already properly tokenized.
Copilot uses AI. Check for mistakes.
log_file (Optional[Path | str], optional): Save logs to this file. Defaults to None. | ||
backend (str, optional): Backend to use for inference. Defaults to "docker". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The docstring formatting is inconsistent. Line 134 has a period at the end while line 135 doesn't. For consistency, both lines should either have periods or not have them.
Copilot uses AI. Check for mistakes.
cuda_devices=self.cuda_devices, | ||
force_cpu=self.force_cpu, | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] This extra blank line is unnecessary and reduces code readability. Remove the empty line after the runner()
function call.
Copilot uses AI. Check for mistakes.
inputs: dict[str, Path | str], | ||
output_file: Path | str, | ||
log_file: Optional[Path | str] = None, | ||
backend: str = "docker", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use the Backend enum as type and default value? Would be cleaner IMO
data_folder: Path | str, | ||
output_folder: Path | str, | ||
log_file: Optional[Path | str] = None, | ||
backend: str = "docker", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
mask: Path | str, | ||
output_file: Path | str, | ||
log_file: Optional[Path | str] = None, | ||
backend: Optional[str] = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same for all algorithm classes: use the enum
backend (str, optional): Backend to use for inference. Defaults to "docker". | ||
""" | ||
if backend is None: | ||
backend_env = os.environ.get("BRATS_ORCHESTRATOR_BACKEND") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no difference but prettier: backend = os.environ.get("BRATS_ORCHESTRATOR_BACKEND", "docker")
# ensure output folder exists | ||
output_path.mkdir(parents=True, exist_ok=True) | ||
|
||
volume_mappings = _get_volume_mappings_mlcube( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will only work for algorithms up to 2024. In 2025 mlcube was not used anymore, see the difference here
_sanity_check_output( | ||
data_path=data_path, | ||
output_path=output_path, | ||
container_output="", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for debugging its really helpful to pass the actual output. always logging it on info lvl as done rn seems a bit excessive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Copilot's and @MarcelRosier's comments
fixes #114