Skip to content

Commit 0d06023

Browse files
jlee733cursoragent
andcommitted
Merge branch 'gemmi' into dev
Resolve conflicts in CLI and workflow modules: keep gemmi work_dir / project_root / resolve_artifacts_dir API; drop dev string MDP path overrides and broken mdmx.main (undefined chimerax_exec). Co-authored-by: Cursor <[email protected]>
2 parents c2b9175 + 4e13de5 commit 0d06023

13 files changed

Lines changed: 860 additions & 379 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
__pycache__/
22
**/__pycache__/
3+
.nv/
34
*.pdb
45
*.log
56
*.cxc

Dockerfile

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Docker Hub image tag: diffuseproject/md:0.0.2
22
# ==================== BUILDER ====================
3-
FROM ubuntu:22.04 AS builder
3+
# CUDA *devel* image supplies nvcc + headers so GROMACS can configure with -DGMX_GPU=CUDA.
4+
# Must match the major.minor of the final runtime image (below) for sane libcudart/cufft ABI.
5+
# docker build --build-arg CUDA_IMAGE_TAG=12.4.1 -t diffuseproject/md:gemmi .
6+
ARG CUDA_IMAGE_TAG=12.6.3
7+
FROM nvidia/cuda:${CUDA_IMAGE_TAG}-devel-ubuntu22.04 AS builder
48

59
ENV DEBIAN_FRONTEND=noninteractive
610

@@ -59,6 +63,7 @@ dependencies:
5963
- cmake =3.31.2
6064
- awscli
6165
- gnuplot =5.4.10
66+
- gemmi =0.7.4
6267
YAML
6368

6469
RUN $MAMBA_EXE create -y -f /tmp/lunus.yaml && rm /tmp/lunus.yaml
@@ -80,6 +85,9 @@ RUN set -ex \
8085
&& mkdir build && cd build \
8186
&& cmake .. \
8287
-DGMX_BUILD_OWN_FFTW=ON \
88+
-DGMX_GPU=CUDA \
89+
-DCUDAToolkit_ROOT=/usr/local/cuda \
90+
-DGMX_CUDA_TARGET_SM=90 \
8391
&& make -j"$(nproc)" \
8492
&& make install \
8593
&& cd / \
@@ -101,27 +109,24 @@ RUN $MAMBA_EXE remove -n lunus -y scons cmake \
101109
true
102110

103111
# ==================== FINAL ====================
104-
FROM ubuntu:22.04
112+
# NVIDIA CUDA runtime: libcudart / cuFFT etc. for CUDA GROMACS at run time.
113+
# Host still needs the driver + NVIDIA Container Toolkit; use docker run --gpus all ...
114+
# CUDA_IMAGE_TAG is set by the global ARG at the top of this file.
115+
FROM nvidia/cuda:${CUDA_IMAGE_TAG}-runtime-ubuntu22.04
116+
105117

106118
ENV DEBIAN_FRONTEND=noninteractive
119+
# Let GPU-requiring processes see the GPU by default (can override at run time).
120+
ENV NVIDIA_VISIBLE_DEVICES=all
121+
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
107122

108-
ARG CHIMERAX_URL="https://www.cgl.ucsf.edu/chimerax/cgi-bin/secure/chimerax-get.py?file=current/ubuntu-22.04/chimerax-daily.deb"
109123
RUN apt-get update && apt-get install -y --no-install-recommends \
110124
ca-certificates \
111125
coreutils \
112126
rsync \
113127
bc \
114128
bzip2 \
115-
curl \
116129
libgomp1 \
117-
&& curl -s -c /tmp/cx_cookies -d "choice=Accept" "${CHIMERAX_URL}" \
118-
| grep -oP 'url=\K[^"]*' > /tmp/cx_redirect \
119-
&& curl -s -b /tmp/cx_cookies -o /tmp/chimerax.deb \
120-
"https://www.cgl.ucsf.edu$(cat /tmp/cx_redirect)" \
121-
&& apt-get install -y /tmp/chimerax.deb \
122-
&& rm -f /tmp/chimerax.deb /tmp/cx_cookies /tmp/cx_redirect \
123-
&& apt-get purge -y curl \
124-
&& apt-get autoremove -y \
125130
&& rm -rf /var/lib/apt/lists/*
126131

127132
# ---------- bashrc (inline of bashrc_new) ----------

md_workflows/cli.py

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import argparse
66
import sys
7+
from pathlib import Path
78

89
from . import equilibrate
910
from . import make_crystal
@@ -20,26 +21,55 @@ def _single_command_cli(command: str) -> None:
2021

2122
if command == "param_prot":
2223
parser.add_argument("--pdb-id", default="6B8X")
24+
parser.add_argument(
25+
"--project-root",
26+
type=Path,
27+
default=None,
28+
help="Directory containing artifacts/ and optional <PDB>.pdb (default: cwd)",
29+
)
2330
elif command == "make_crystal":
2431
parser.add_argument("--ix", type=int, default=1)
2532
parser.add_argument("--iy", type=int, default=None)
2633
parser.add_argument("--iz", type=int, default=None)
27-
parser.add_argument("--chimerax-exec", default="chimerax")
34+
parser.add_argument(
35+
"--work-dir",
36+
type=Path,
37+
default=None,
38+
help="Run directory with prot.pdb, pdb_clean.pdb, etc. (default: cwd)",
39+
)
2840
elif command == "make_waterbox":
2941
parser.add_argument("--ntomp", type=int, default=26)
30-
parser.add_argument("--min-water", dest="min_water_mdp", default="artifacts/min_water.mdp", help="Path to min_water.mdp file")
31-
parser.add_argument("--equil-water", dest="equil_water_mdp", default="artifacts/equil_water.mdp", help="Path to equil_water.mdp file")
42+
parser.add_argument("--work-dir", type=Path, default=None)
43+
parser.add_argument(
44+
"--artifacts-dir",
45+
type=Path,
46+
default=None,
47+
help="Override MDP directory (default: <project-root>/artifacts)",
48+
)
49+
parser.add_argument(
50+
"--project-root",
51+
type=Path,
52+
default=None,
53+
help="Project root containing artifacts/ (default: cwd; inferred from --work-dir if possible)",
54+
)
3255
elif command == "solvate":
33-
pass
56+
parser.add_argument("--work-dir", type=Path, default=None)
3457
elif command == "minimize":
3558
parser.add_argument("--ntomp", type=int, default=26)
36-
parser.add_argument("--min", dest="min_mdp", default="artifacts/min.mdp", help="Path to min.mdp file")
59+
parser.add_argument("--work-dir", type=Path, default=None)
60+
parser.add_argument("--artifacts-dir", type=Path, default=None)
61+
parser.add_argument("--project-root", type=Path, default=None)
3762
elif command == "equilibrate":
3863
parser.add_argument("--ntomp", type=int, default=26)
39-
parser.add_argument("--equil", dest="equil_mdp", default="artifacts/equil.mdp", help="Path to equil.mdp file")
64+
parser.add_argument("--work-dir", type=Path, default=None)
65+
parser.add_argument("--artifacts-dir", type=Path, default=None)
66+
parser.add_argument("--project-root", type=Path, default=None)
4067
elif command == "resolvate":
4168
parser.add_argument("--ntmpi", type=int, default=8)
4269
parser.add_argument("--ntomp", type=int, default=1)
70+
parser.add_argument("--work-dir", type=Path, default=None)
71+
parser.add_argument("--artifacts-dir", type=Path, default=None)
72+
parser.add_argument("--project-root", type=Path, default=None)
4373
elif command == "run_params_gaussian":
4474
parser.add_argument("--g16root", default="/Users/mewall/packages")
4575
parser.add_argument("--nproc", type=int, default=8)
@@ -49,19 +79,52 @@ def _single_command_cli(command: str) -> None:
4979
args = parser.parse_args(sys.argv[1:])
5080

5181
if command == "param_prot":
52-
param_prot.run(pdb_id=args.pdb_id)
82+
root = (args.project_root or Path.cwd()).resolve()
83+
wd = param_prot.run(pdb_id=args.pdb_id, project_root=root)
84+
print(wd)
5385
elif command == "make_crystal":
54-
make_crystal.run(ix=args.ix, iy=args.iy, iz=args.iz, chimerax_exec=args.chimerax_exec)
86+
wd = (args.work_dir or Path.cwd()).resolve()
87+
make_crystal.run(ix=args.ix, iy=args.iy, iz=args.iz, work_dir=wd)
5588
elif command == "make_waterbox":
56-
make_waterbox.run(ntomp=args.ntomp, min_water_mdp=args.min_water_mdp, equil_water_mdp=args.equil_water_mdp)
89+
wd = (args.work_dir or Path.cwd()).resolve()
90+
pr = args.project_root.resolve() if args.project_root else None
91+
make_waterbox.run(
92+
ntomp=args.ntomp,
93+
work_dir=wd,
94+
artifacts_dir=args.artifacts_dir,
95+
project_root=pr,
96+
)
5797
elif command == "solvate":
58-
solvate.run()
98+
wd = (args.work_dir or Path.cwd()).resolve()
99+
solvate.run(work_dir=wd)
59100
elif command == "minimize":
60-
minimize.run(ntomp=args.ntomp, min_mdp=args.min_mdp)
101+
wd = (args.work_dir or Path.cwd()).resolve()
102+
pr = args.project_root.resolve() if args.project_root else None
103+
minimize.run(
104+
ntomp=args.ntomp,
105+
work_dir=wd,
106+
artifacts_dir=args.artifacts_dir,
107+
project_root=pr,
108+
)
61109
elif command == "equilibrate":
62-
equilibrate.run(ntomp=args.ntomp, equil_mdp=args.equil_mdp)
110+
wd = (args.work_dir or Path.cwd()).resolve()
111+
pr = args.project_root.resolve() if args.project_root else None
112+
equilibrate.run(
113+
ntomp=args.ntomp,
114+
work_dir=wd,
115+
artifacts_dir=args.artifacts_dir,
116+
project_root=pr,
117+
)
63118
elif command == "resolvate":
64-
resolvate.run(ntmpi=args.ntmpi, ntomp=args.ntomp)
119+
wd = (args.work_dir or Path.cwd()).resolve()
120+
pr = args.project_root.resolve() if args.project_root else None
121+
resolvate.run(
122+
ntmpi=args.ntmpi,
123+
ntomp=args.ntomp,
124+
work_dir=wd,
125+
artifacts_dir=args.artifacts_dir,
126+
project_root=pr,
127+
)
65128
elif command == "run_params_gaussian":
66129
run_params_gaussian.run(
67130
g16root=args.g16root,

0 commit comments

Comments
 (0)