cursus.steps.scripts.run_gconstruct

GraphConstruction step script (Nexus run_gconstruct.sh → Cursus).

Ports the Nexus run_gconstruct.sh wrapper into a contract-driven Python entry point. Runs inside the BYO GraphStorm image (GraphStorm + DGL are baked into the image, not pip-provisioned).

Responsibilities (verbatim port of the shell wrapper):
  1. Path rewrite — GraphFeatureProcessing (Step 2) wrote /opt/ml/processing/output/... paths into gconstruct_config.json; here those files mount at /opt/ml/processing/input/data/.... Rewrite the config in place and chdir into the data dir so any relative paths resolve.

  2. GraphStorm bug patch — inject hard_edge_neg_ops = [] after edges = {} in the container’s construct_graph.py (an unbound-variable bug), idempotently. Prefer pinning a fixed GraphStorm version in the Dockerfile so this becomes unnecessary; the guard stays for image-version drift.

  3. Run python3 -m graphstorm.gconstruct.construct_graph with the fixed --conf-file / --output-dir (constant container paths) plus the config-sourced --graph-name / --num-processes / --num-parts / [--skip-nonexist-edges] — multi-process partitioning on a single instance. Emits a partitioned DGL heterograph.

Contract args (from graph_construction.step.yaml job_arguments): –graph-name, –num-processes, –num-parts (+ –skip-nonexist-edges appended by the config’s gconstruct_arguments when set).

rewrite_config_paths()[source]

Rewrite the Step-2 output paths in gconstruct_config.json to the Step-3 input mount.

patch_graphstorm_bug()[source]

Inject hard_edge_neg_ops = [] after edges = {} in construct_graph.py (idempotent).

Mirrors the sed in run_gconstruct.sh. Best-effort — a pinned GraphStorm version makes it moot, and it must never fail the job if the file/layout differs in a newer image.

main()[source]