From df78d79a7103f3b0c6f14f3a94894e9229653270 Mon Sep 17 00:00:00 2001 From: navidgh67 Date: Thu, 8 Oct 2026 22:58:03 -0400 Subject: [PATCH] Update computational help and add the production worker manifest - Help page: the form defaults and examples are for testing the workflow, not convergence-tested research settings; access and run limits now describe the production platform (any project's PI or members, two active runs per person, four per cluster). - User-facing errors no longer mention the pilot. - geddes/k8s/10-computation-worker.yaml: the worker Deployment and volume now running in production, with what it needs and how to roll it out or turn computations off. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01QS1dbWTNbwqxXZUMEARjhm --- api/computations/store.py | 4 +- geddes/k8s/10-computation-worker.yaml | 103 ++++++++++++++++++++++++++ web/components/computational-faq.tsx | 11 +-- 3 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 geddes/k8s/10-computation-worker.yaml diff --git a/api/computations/store.py b/api/computations/store.py index b37edef..f868eff 100644 --- a/api/computations/store.py +++ b/api/computations/store.py @@ -47,7 +47,7 @@ class SubmissionCapacityError(RuntimeError): def _enforce_submission_budget(cur, *, user_id: str, project_id: str, cluster_name: str) -> None: allowed = {value.strip() for value in os.getenv("RCAC_ALLOWED_PROJECT_IDS", "").split(",") if value.strip()} if allowed and project_id not in allowed: - raise PermissionError("Computations are restricted to the approved pilot project") + raise PermissionError("Computations are not enabled for this project") per_user = int(os.getenv("RCAC_MAX_ACTIVE_RUNS_PER_USER", "0")) per_cluster = int(os.getenv("RCAC_MAX_ACTIVE_RUNS_PER_CLUSTER", "0")) if per_user < 0 or per_cluster < 0: @@ -65,7 +65,7 @@ def _enforce_submission_budget(cur, *, user_id: str, project_id: str, cluster_na ) counts = cur.fetchone() if (per_user and counts["user_count"] >= per_user) or (per_cluster and counts["cluster_count"] >= per_cluster): - raise SubmissionCapacityError("Pilot run limit reached; wait for an active run to finish") + raise SubmissionCapacityError("Run limit reached; wait for an active run to finish") def feature_enabled() -> bool: diff --git a/geddes/k8s/10-computation-worker.yaml b/geddes/k8s/10-computation-worker.yaml new file mode 100644 index 0000000..d904c36 --- /dev/null +++ b/geddes/k8s/10-computation-worker.yaml @@ -0,0 +1,103 @@ +# RCAC computation worker for the production platform (ncn-digitaltwins-zchen). +# Deployed 2026-10-08. It polls computation_runs, calls the registered Globus +# gateway on Negishi/Gautschi, and stores results; it serves no traffic. +# +# Needs, in the same namespace: +# configmap dt-computation-config RCAC_* and GLOBUS_COMPUTE_* settings +# (also loaded by dt-api via envFrom) +# secret dt-globus-confidential-client client-secret (also mounted in dt-api) +# secret dt-computation-materials-project api-key +# secret dt-api-secret PG_* including PG_WORKER_USER/PASS +# +# Roll out a new release after dt-db-migrate and dt-api: +# kubectl -n ncn-digitaltwins-zchen set image deployment/dt-computation-worker \ +# worker=geddes-registry.rcac.purdue.edu/sdx/dt-computation-worker:@ +# Turn computations off: set RCAC_COMPUTE_ENABLED=false in dt-computation-config, +# restart dt-api and this worker (cancel active runs first; see +# RCAC_SIM2L_INTEGRATION.md, Rollback). +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: dt-computation-worker-data + namespace: ncn-digitaltwins-zchen + labels: + app: dt-computation-worker +spec: + accessModes: ["ReadWriteOnce"] + storageClassName: geddes-standard-singlenode + resources: + requests: + storage: 5Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dt-computation-worker + namespace: ncn-digitaltwins-zchen + labels: + app: dt-computation-worker +spec: + # One replica on purpose: Postgres leases protect each run, and one poller + # keeps Slurm status queries to one per cluster per cycle. + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: dt-computation-worker + template: + metadata: + labels: + app: dt-computation-worker + spec: + imagePullSecrets: + - name: sdx-registry-secret + securityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + fsGroup: 10001 + containers: + - name: worker + image: geddes-registry.rcac.purdue.edu/sdx/dt-computation-worker:computational-e543b59@sha256:dd413aef311189be1a3bee60a262c1e0b81206f94e3078afd7a441b643aaafcc + args: ["python", "-m", "computations.worker", "--poll-seconds", "30"] + envFrom: + - configMapRef: + name: dt-computation-config + env: + - name: USE_MOCK_DATABASE + value: "false" + - name: PG_HOST + valueFrom: {secretKeyRef: {name: dt-api-secret, key: PG_HOST}} + - name: PG_PORT + valueFrom: {secretKeyRef: {name: dt-api-secret, key: PG_PORT}} + - name: PG_DB + valueFrom: {secretKeyRef: {name: dt-api-secret, key: PG_DB}} + - name: PG_USER + valueFrom: {secretKeyRef: {name: dt-api-secret, key: PG_USER}} + - name: PG_PASS + valueFrom: {secretKeyRef: {name: dt-api-secret, key: PG_PASS}} + # Background role: not superuser, not BYPASSRLS. + - name: PG_WORKER_USER + valueFrom: {secretKeyRef: {name: dt-api-secret, key: PG_WORKER_USER}} + - name: PG_WORKER_PASS + valueFrom: {secretKeyRef: {name: dt-api-secret, key: PG_WORKER_PASS}} + - name: MATERIALS_PROJECT_API_KEY + valueFrom: {secretKeyRef: {name: dt-computation-materials-project, key: api-key}} + resources: + requests: {cpu: 100m, memory: 512Mi} + limits: {cpu: "1", memory: 2Gi} + volumeMounts: + - {name: globus, mountPath: /run/globus, readOnly: true} + - {name: worker-data, mountPath: /var/lib/dt-computation-worker} + - {name: worker-tmp, mountPath: /tmp} + volumes: + - name: globus + secret: + secretName: dt-globus-confidential-client + defaultMode: 0440 + - name: worker-data + persistentVolumeClaim: + claimName: dt-computation-worker-data + - name: worker-tmp + emptyDir: {} diff --git a/web/components/computational-faq.tsx b/web/components/computational-faq.tsx index b61e002..c590761 100644 --- a/web/components/computational-faq.tsx +++ b/web/components/computational-faq.tsx @@ -43,7 +43,7 @@ export function ComputationalFaq() { question: "Where do I start?", keywords: "login sign in nanoHUB Purdue VPN Rushik Justin RCAC-PILOT project access", answer: <> -

Sign in with your own nanoHUB account, open Projects, and select your assigned project. Rushik and Justin use Computational Student Pilot (RCAC-PILOT) on the private pilot site, reached from Purdue’s network or VPN.

+

Sign in with your own nanoHUB account, open Projects, and select a project where you are the PI or a member.

On the project page, find Registered computational experiments. You can also click New RCAC Run beside a computational process step to open the form with its tool selected.

, }, @@ -72,7 +72,7 @@ export function ComputationalFaq() { keywords: "researcher student member owner administrator role permissions viewer PI forbidden restricted approved pilot project", answer: <>

No. Researcher is the normal student platform role. To submit or cancel a calculation, you must be a PI or member of the project; platform Administrators can also submit. A viewer of an open project can see its runs but cannot submit. Administrator is the highest platform role, used for managing users, registrations, and other platform settings.

-

In this pilot, calculations can be submitted only in Computational Student Pilot (RCAC-PILOT). Other projects show “Computations are restricted to the approved pilot project.” You do not need to provide an RCAC password or SSH key in the run form.

+

Any project where you are the PI or a member can submit calculations. You do not need to provide an RCAC password or SSH key in the run form.

, }, { @@ -104,7 +104,8 @@ export function ComputationalFaq() { question: "What values can I use for my first pilot check?", keywords: "example defaults silicon graphene mp-149 mp-48 30 180 20 vacuum 1e-8 1e-4 pressure", answer: <> -

The 3D column is the explicit small silicon workflow check; the 2D column gives the current graphene pilot defaults. These examples exercise the workflow. Establish convergence-tested settings for your scientific comparisons.

+

The form defaults and these examples are for testing the workflow, not for research results. They have not been convergence-tested for any material. Before you compare or publish results, test the cutoff and k-points for your own system.

+

The 3D column is the small silicon workflow check; the 2D column gives the current graphene defaults.

@@ -149,7 +150,7 @@ export function ComputationalFaq() { answer: <>

Select one of the available clusters in RCAC cluster, review your inputs, and click Submit once. Negishi and Gautschi are available in the pilot. The selector shows each installation’s Quantum ESPRESSO version; record it when comparing results across clusters.

An accepted request appears in the run list below the form. It may wait in Slurm’s queue before running.

-

The pilot allows at most two active runs per person and one active run per cluster, counted across everyone in the pilot. If another student’s run is active on Negishi, choose Gautschi or wait. When a limit is reached, the form shows “Pilot run limit reached; wait for an active run to finish.” If no cluster is ready, contact Navid.

+

The platform allows at most two active runs per person and four active runs per cluster, counted across everyone. If a cluster is full, choose the other cluster or wait. When a limit is reached, the form shows “Run limit reached; wait for an active run to finish.” If no cluster is ready, contact Navid.

, }, { @@ -186,7 +187,7 @@ export function ComputationalFaq() { question: "Can I choose cores, nodes, memory or walltime?", keywords: "resources cores ranks MPI nodes memory walltime time limit concurrent strain calculations allocation MaxRSS ReqMem", answer: <> -

Yes, within this pilot’s limits. Under Computational resources the form shows each cluster’s allowed range and default, and which controls that cluster offers. Leave a field blank to use the default.

+

Yes, within the platform’s limits. Under Computational resources the form shows each cluster’s allowed range and default, and which controls that cluster offers. Leave a field blank to use the default.

  • MPI ranks (CPU cores): 1 to 64 per calculation, or per ElasticDFT strain calculation. Each rank uses one CPU core. Default 64.
  • Nodes: fixed at one. The pilot does not run multi-node calculations, so the form does not offer them.
Input values for the first 3D silicon and 2D graphene pilot checks