Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added submissions/MR-zero/case0.h5
Binary file not shown.
Binary file added submissions/MR-zero/case1.h5
Binary file not shown.
Binary file added submissions/MR-zero/case2.h5
Binary file not shown.
Binary file added submissions/MR-zero/case3.h5
Binary file not shown.
Binary file added submissions/MR-zero/case4.h5
Binary file not shown.
117 changes: 117 additions & 0 deletions submissions/MR-zero/simulation_mr0.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"""MR-zero simulation and timing reference for all five cases.

Writes ``case0.h5`` … ``case4.h5`` next to this file (raw ADC, acquisition
order). Prints the wall-clock of the MR-zero run itself, after the phantom
and the sequence are loaded, and names the CPU or GPU that ran it. The same
lines are written to ``timings.txt`` as each case finishes. Copy your own
wall-clock into ``runtime_s`` and the time recorded here into
``mrzero_runtime_s``. Evaluation divides the two.

Install::

pip install mrzerocore==1.0.8 numpy h5py

The GPU is used when one is present. Pass ``cpu`` or ``gpu`` to choose::

python submissions/003_MR-zero/simulation_mr0.py
python submissions/003_MR-zero/simulation_mr0.py cpu
python submissions/003_MR-zero/simulation_mr0.py gpu
"""
import sys
import time
from pathlib import Path

import h5py
import MRzeroCore as mr0
import numpy as np
import torch

here = Path(__file__).resolve().parent
root = here.parents[0] #modify this so it points to git base directory to run
LARMOR = 127.7292e6 # Hz. Published with the sequences.

# Example solver setup, not a challenge rule.
MAX_STATES = 200
MIN_STATE = 1e-3

# Case 4 repeats the EPI file on the phantom that carries T2'.
CASES = (
(0, 'case0_fid.seq', 'challenge-brain-4mm.json'),
(1, 'case1_gre.seq', 'challenge-brain-4mm.json'),
(2, 'case2_tse.seq', 'challenge-brain-4mm.json'),
(3, 'case3_epi.seq', 'challenge-brain-4mm.json'),
(4, 'case3_epi.seq', 'challenge-brain-4mm-t2star.json'),
)


def use_gpu(argv: list[str]) -> bool:
choice = argv[1] if len(argv) > 1 else 'auto'
if choice == 'cpu':
return False
if choice == 'gpu' and not torch.cuda.is_available():
raise SystemExit('gpu was requested, but CUDA is not available')
if choice not in {'auto', 'gpu'}:
raise SystemExit('usage: simulation_mr0.py [cpu|gpu]')
return torch.cuda.is_available()


def hardware(gpu: bool) -> str:
if gpu:
return torch.cuda.get_device_name(0)
return 'cpu'


def load_phantom(name: str, gpu: bool):
obj = mr0.TissueDict.load(str(root / 'phantoms' / 'brainweb' / name)).build()
return obj.cuda() if gpu else obj


def load_sequence(name: str, gpu: bool):
seq = mr0.Sequence.import_file(str(root / 'sequences' / name), larmor_hz=LARMOR)
return seq.cuda() if gpu else seq


def write_signal(index: int, signal: np.ndarray) -> Path:
path = here / f'case{index}.h5'
with h5py.File(path, 'w') as handle:
handle.create_dataset('signal_real', data=signal.real)
handle.create_dataset('signal_imag', data=signal.imag)
return path


def write_timings(where: str, lines: list[str]) -> Path:
path = here / 'timings.txt'
path.write_text('hardware: ' + where + '\n' + '\n'.join(lines) + '\n')
return path


def main() -> None:
gpu = use_gpu(sys.argv)
where = hardware(gpu)
phantoms: dict[str, object] = {}
lines: list[str] = []
print(f'hardware: {where}')
for index, seq_name, phantom_name in CASES:
if phantom_name not in phantoms:
phantoms[phantom_name] = load_phantom(phantom_name, gpu)
seq = load_sequence(seq_name, gpu)
obj = phantoms[phantom_name]
if gpu:
torch.cuda.synchronize()
started = time.perf_counter()
graph = mr0.compute_graph(seq, obj, max_state_count=MAX_STATES, min_state_mag=MIN_STATE)
signal = mr0.execute_graph(graph, seq, obj, print_progress=False)
if gpu:
torch.cuda.synchronize()
seconds = time.perf_counter() - started
adc = np.asarray(signal.detach().cpu()).reshape(-1)
path = write_signal(index, adc)
line = f'case {index} {seconds:8.1f} s {adc.size:5d} samples {path.name}'
print(line)
lines.append(line)
write_timings(where, lines)
print(f'wrote {here / "timings.txt"}')


if __name__ == '__main__':
main()
19 changes: 19 additions & 0 deletions submissions/MR-zero/submission.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"group": "zMRI Lab (Prof. Zaiss)",
"tool_name": "MR-zero",
"tool_version": "1.0.8",
"tool_commit": "",
"tool_date": "",
"solver": "",
"project_page": "https://github.com/MRsources/MRzero-Core",
"paper": "",
"hardware": "Intel Core i7-12700K",
"cases": [
{"case": 0, "runtime_s": 3.5, "mrzero_runtime_s": 3.5},
{"case": 1, "runtime_s": 25, "mrzero_runtime_s": 25},
{"case": 2, "runtime_s": 10.8, "mrzero_runtime_s": 10.8},
{"case": 3, "runtime_s": 13.1, "mrzero_runtime_s": 13.1},
{"case": 4, "runtime_s": 13.5, "mrzero_runtime_s": 13.5}
],
"setup_notes": "Maximum RAM usage minus baseline usage in GB: case0: 9, case1: 2, case2: 2, case3: 37, case4: 37"
}
Loading