Skip to content

Add eqV2_tracegrad Model#273

Draft
TheSheng1103 wants to merge 13 commits intojanosh:mainfrom
TheSheng1103:eqV2_tracegrad
Draft

Add eqV2_tracegrad Model#273
TheSheng1103 wants to merge 13 commits intojanosh:mainfrom
TheSheng1103:eqV2_tracegrad

Conversation

@TheSheng1103
Copy link
Copy Markdown

@TheSheng1103 TheSheng1103 commented Jul 16, 2025

Hello Matbench Discovery Team,

First and foremost, I would like to express my sincere gratitude to you for your incredible efforts in building and maintaining the Matbench Discovery benchmark.Your work has enabled the machine learning models in the field of materials science to continuously progress and improve.

Our team recently trained a conservative model (eqV2_tracegrad) on the MPtrj training set, and we believe it may enhance the performance of the tasks you listed. We would be delighted to incorporate it into your benchmark tests.

I will add all the required files outlined in the contribution guide, please let me know if you need further information.

Checklist

Please open PRs as draft and only mark as ready to review after checking off the following items:

  • I created a new folder and YAML metadata file models/<arch_name>/<model_variant>.yml for my submission. arch_name is the name of the architecture and model_variant.yml includes things like author details, training set names and important hyperparameters.
  • I added the new model as a new attribute Model.<model_variant> enum on the Model enum in enums.py.
  • I uploaded the energy/force/stress model prediction file for the WBM test set to Figshare or another cloud storage service (<yyyy-mm-dd>-<model_variant>-preds.csv.gz).
  • I uploaded the model-relaxed structures file to Figshare or another cloud storage service in JSON lines format (<yyyy-mm-dd>-wbm-IS2RE-FIRE.jsonl.gz). JSON Lines allows fast loading of small numbers of structures with pandas.read_json(lines=True, nrows=100) for inspection.
  • I uploaded the phonon predictions to Figshare or another cloud storage service (<yyyy-mm-dd>-kappa-103-FIRE-<values-of-dist|fmax|symprec>.gz).
  • I have uploaded the diatomic predictions to Figshare or another cloud storage service (<yyyy-mm-dd>-diatomics.json.gz).
  • I included the urls to the Figshare files in the YAML metadata file (models/<arch_name>/<model_variant>.yml). If not using Figshare I have included the urls to the cloud storage service in the description of the PR.
  • I included the test script (test_<arch_name>_<task>.py for task in discovery, kappa, diatomics) that generated the prediction files.
  • I have run just prepare-model-submission <model_variant> as described in the contributing guide to check metadata and generate the plots needed for submission.
  • I have installed/run the pre-commit hooks (prek install or uvx prek) and ensured all checks are passing.

Marking your PR as ready to review will trigger an automated code review, please address any issues raised by the automated review. For the maintainers minimizing the final human review process enables us to merge your submissions much faster!

Additional Information (Optional)

  • I included a training script (train_<arch_name>.py) if I trained a model specifically for this benchmark.
  • I included a readme.md with additional details about my model.

Summary by CodeRabbit

  • New Features

    • Added eqV2 S DeNS TraceGrad model descriptor with metadata, training hyperparameters, and benchmark/discovery metrics.
    • CLI to merge per-model predictions, compute formation energies (optional MP‑2020 corrections), and export aggregated CSV/JSON and large‑error reports.
    • Pipelines to produce geo‑optimized discovery outputs and run WBM relaxation/discovery experiments that export model energies.
    • Parallel thermal‑conductivity (kappa) pipeline with reproducible runs, per‑structure diagnostics, and merged results.
  • Chores

    • Added shell scripts to configure environments and run the discovery, kappa, and aggregation workflows.

@janosh
Copy link
Copy Markdown
Owner

janosh commented Aug 1, 2025

thanks a lot for the kind words and for submitting eqV2_tracegrad. 👍 apologies for the delay, i'll take a look soon (else feel free to ping)

in the meantime could you fix the lint issues and make the scripts more easily runnable by others by removing hard-coded paths like sys.path.insert(0, "/data/fywang/code/fairchem-tracegrad-hanhai/src"). have a look at https://docs.astral.sh/uv/guides/scripts/#declaring-script-dependencies for how you can specify the packages needed by each script. that will allow anyone to just execute uv run path/to/script.py and have the dependencies auto-installed by uv on demand. would help a lot with reproducing your results!

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 19, 2025

📝 Walkthrough

Walkthrough

Adds an eqV2 TraceGrad model descriptor and multiple new scripts for aggregating predictions, exporting geo‑optimized structures, WBM relaxations, and phonon/kappa evaluation. Introduces Typer CLIs, Submitit parallelism, ASE relaxations using FAIRChem OCPCalculator, per-job result aggregation, and shell runners. (50 words)

Changes

Cohort / File(s) Summary
Model descriptor
models/eqV2_tracegrad/eqV2-s-dens-tracegrad-mp.yml
New YAML describing the eqV2 S DeNS TraceGrad model: metadata, training/testing tasks, hyperparameters, dependencies, notes, metrics, and benchmark/analysis outputs.
Prediction join & runner
models/eqV2_tracegrad/join_fairchem_preds.py, models/eqV2_tracegrad/join_fairchem_preds.sh
New script and shell wrapper to aggregate per-model prediction files, merge baseline energies, hydrate pymatgen ComputedStructureEntry objects, optionally apply MP‑2020 corrections, compute formation energies per atom, and emit CSV/JSON and “-bad” reports; exposes a Typer CLI.
Geo‑opt file utility
models/eqV2_tracegrad/save_geo_opt_file.py
Adds format detection helper and a small pipeline to read gzipped ML‑relaxed JSON, add an index, and write a geo‑optimized gzipped JSON at fixed paths.
Kappa (phonon) workflow
models/eqV2_tracegrad/test_fairchem_kappa.py, models/eqV2_tracegrad/test_fairchem_kappa_debug.py, models/eqV2_tracegrad/test_fairchem_kappa.sh
New parallelized kappa/phonon pipeline with KappaSRMERunner classes and Typer CLIs to relax structures, compute FC2/FC3, detect imaginary modes and symmetry breaking, calculate thermal conductivity, save per‑job and merged results; includes a debug variant and shell runner.
TraceGrad relaxation & discovery
models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py, models/eqV2_tracegrad/test_fairchem_tracegrad_discovery_debug.py, models/eqV2_tracegrad/test_fairchem_tracegrad.sh
New WBM relaxation workflows (RelaxJob, AseDBSubset), ASE optimizer mappings, optional cell filters, Submitit orchestration, FAIRChem OCPCalculator integration, wandb logging/artifacts, result serialization, and shell runner; exposes Typer CLIs for run_relax.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CLI as User/CLI
  participant RJ as RelaxJob
  participant ASE as ASE Optimizer
  participant FC as FAIRChem OCPCalculator
  participant WBM as WBM Dataset
  participant Out as Output Store

  CLI->>RJ: run_relax(params)
  RJ->>WBM: Load dataset / split subset
  RJ->>FC: Init calculator (checkpoint)
  loop per structure
    RJ->>ASE: Assign calculator, apply cell filter
    ASE-->>RJ: Relaxed atoms + energy
    RJ->>Out: Append energy + structure
  end
  RJ->>Out: Write gzipped JSON, wandb artifact
Loading
sequenceDiagram
  autonumber
  participant CLI as User/CLI
  participant KR as KappaSRMERunner
  participant ASE as ASE Relax (FIRE)
  participant FC as FAIRChem OCPCalculator
  participant P3 as Phono3py (LT Conductivity)
  participant Out as Output Store

  CLI->>KR: run_kappa(params, num_jobs)
  KR->>FC: Init calculator
  loop per structure (job shard)
    KR->>ASE: Relax with symmetry constraints
    ASE-->>KR: Relaxed structure
    KR->>P3: Build phonon (FC2/FC3)
    P3-->>KR: Frequencies, kappa
    KR->>Out: Save per-structure results
  end
  KR->>Out: Merge job outputs, write json.gz + metrics
Loading
sequenceDiagram
  autonumber
  participant CLI as User/CLI
  participant JP as join_predictions
  participant Files as Per-model files
  participant Base as Baseline eqV2 data
  participant WBM as WBM CSEs
  participant PMG as Pymatgen
  participant Out as Output

  CLI->>JP: join_predictions(input_path, out_path, opts)
  JP->>Files: Read model *.json.gz / *.csv.gz
  JP->>Base: Load baseline energies
  JP->>WBM: Load CSE entries
  JP->>PMG: Hydrate CSEs with ML energies/structures
  JP->>PMG: Compute E_form/atom (MP2020 corrections opt.)
  JP->>Out: Write csv.gz, -bad.csv, json.gz
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas to pay extra attention:

  • Submitit job orchestration and CUDA_VISIBLE_DEVICES handling across scripts.
  • Hydration/updating of pymatgen ComputedStructureEntry objects and MP‑2020 correction logic.
  • Error handling and aggregation in phonon (FC2/FC3) and kappa computation paths.
  • Hard-coded filesystem paths and JSON/gzip format handling in save_geo_opt_file.py and shell runners.

Suggested reviewers

  • janosh

Poem

I twitched my nose at gzipped streams,
I hopped through lattices and learning dreams.
FIRE guided steps and phonons swayed,
Kappa hummed soft where atoms played.
I joined the files — a carrot cheer, hooray! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ⚠️ Warning The PR description lacks required checklist items completion status and omits critical URLs to uploaded prediction files, structures, and phonon data on cloud storage. Complete the checklist by checking off all items including model YAML creation, enum addition, and cloud storage URLs. Provide links to uploaded prediction files and ensure all required metadata is documented.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add eqV2_tracegrad Model' directly describes the main change: introducing a new ML model to the codebase, which aligns with the PR's purpose of adding this model to the Matbench Discovery leaderboard.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

🧹 Nitpick comments (22)
models/eqV2_tracegrad/save_geo_opt_file.py (1)

7-21: Type annotations and minor robustness for format detection.

Add type hints and skip leading whitespace before checking the first non-space char. Also handle empty files gracefully.

-def detect_file_format(file_path):
-    """自动检测JSON文件的格式类型"""
-    with gzip.open(file_path, "rt") as f:
-        first_char = f.read(1)
+def detect_file_format(file_path: str) -> str:
+    """自动检测JSON文件的格式类型"""
+    with gzip.open(file_path, "rt") as f:
+        # skip leading whitespace/newlines
+        first_char = ""
+        while True:
+            ch = f.read(1)
+            if not ch or not ch.isspace():
+                first_char = ch
+                break
         # JSON数组格式以 [ 开头
         if first_char == "[":
             return "array"
         # 行分隔JSON通常以 { 开头
         try:
             f.seek(0)
             line = f.readline().strip()
             json.loads(line)  # 验证是否为完整JSON对象
             return "lines"
         except json.JSONDecodeError:
             return "unknown"
models/eqV2_tracegrad/eqV2-s-dens-tracegrad-mp.yml (1)

76-77: Fill or drop empty URLs to avoid dangling metadata.

These keys are present but empty. Either provide the URLs or remove the keys to prevent downstream tooling from assuming availability.

-      pred_file_url:
+      pred_file_url:  # add URL or remove this line
@@
-      analysis_file_url:
+      analysis_file_url:  # add URL or remove this line
@@
-      analysis_file_url:
+      analysis_file_url:  # add URL or remove this line

Also applies to: 88-89, 96-97

models/eqV2_tracegrad/join_fairchem_preds.py (1)

88-96: Avoid mutating private attributes; construct a new CSE instead.

Directly setting cse._energy and cse._structure relies on private internals. Prefer creating a new ComputedStructureEntry.

-        # cse._energy is the uncorrected energy
-        cse._energy = pred_energy  # noqa: SLF001
-        # cse._energy = pred_energy_ori  # added by fywang
-        cse._structure = mlip_struct  # noqa: SLF001
-        df_fairchem.loc[mat_id, computed_structure_entry_key] = cse
+        df_fairchem.loc[mat_id, computed_structure_entry_key] = ComputedStructureEntry(
+            structure=mlip_struct,
+            energy=pred_energy,
+            parameters=cse.parameters,
+            data=cse.data,
+        )
models/eqV2_tracegrad/join_fairchem_preds.sh (1)

1-1: Fix shebang (no leading space).

Shellcheck SC1114: remove leading space for the shebang line.

- #!/bin/bash
+#!/bin/bash
models/eqV2_tracegrad/test_fairchem_kappa_debug.py (3)

326-336: Typer help strings contain full-width punctuation; switch to ASCII for linting/consistency.

Replace Chinese full-width punctuation with ASCII to satisfy linters (RUF001) and keep CLI help consistent.

-    checkpoint_path: Annotated[Path, typer.Option(help="路径,包含 checkpoint.pt")],
+    checkpoint_path: Annotated[Path, typer.Option(help="路径, 包含 checkpoint.pt")],
@@
-    model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
-    identifier: Annotated[str, typer.Option(help="运行标识,用于文件夹命名")],
-    atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
-    seed: Annotated[int, typer.Option(help="随机种子")] = 42,
-    num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
-    debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
-    slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
+    model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
+    identifier: Annotated[str, typer.Option(help="运行标识, 用于文件夹命名")],
+    atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
+    seed: Annotated[int, typer.Option(help="随机种子")] = 42,
+    num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
+    debug: Annotated[bool, typer.Option(help="调试模式, 仅运行一个 job")] = False,
+    slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,

341-349: Executor is configured but not used; unused args (num_jobs/debug).

For a “debug” script, either remove the submitit executor and the unused args, or wire them up so users can run N jobs. Presently they’re dead code.

Two options:

  • Keep it purely local: drop executor config and arguments.
  • Or implement simple job-splitting using num_jobs and loop over range(num_jobs) submitting job.run(job_number=i) to the executor.

I can provide a minimal executor-backed variant if you want multi-job runs here.

Also applies to: 351-361


162-170: Relaxation step-check and stress reporting.

  • FIRE exposes optimizer.nsteps; the change is fine. Consider logging both steps and whether reached_max_steps.
  • atoms.get_stress() returns 6 components (Voigt). Reshaping to (2, 3) and taking max(axis=1) isn’t meaningful. Either keep the 6-vector or compute np.max(np.abs(stress)).
-                    max_stress = (
-                        atoms.get_stress().reshape((2, 3), order="C").max(axis=1)
-                    )
+                    stress_voigt = atoms.get_stress()
+                    max_stress = float(abs(stress_voigt).max())

Also applies to: 171-176

models/eqV2_tracegrad/test_fairchem_kappa.py (7)

70-74: Type annotation for env_vars is incorrect (breaks IDEs/linters).

env_vars is annotated as None, but the code treats it like a mapping. Use a proper optional mapping type.

-    def run(self, env_vars: None, job_number: int = 0) -> None:
+    def run(self, env_vars: dict[str, str] | None, job_number: int = 0) -> None:

110-130: Potential concurrent write race to run_params.json.

All jobs write the same run_params.json in a shared out_dir, causing non-deterministic content or partial writes. Make this per-job.

-        with open(save_dir / "run_params.json", mode="w") as file:
+        with open(save_dir / f"run_params_{job_number:03}.json", mode="w") as file:
             json.dump(run_params, file, indent=4)

175-177: Incorrect stress reshaping; use norm/abs-based scalar instead.

Reshaping a 6-component Voigt stress vector into shape (2, 3) and taking max(axis=1) is arbitrary and potentially misleading. Use an absolute max over the Voigt vector or compute a proper norm.

-                    max_stress = (
-                        atoms.get_stress().reshape((2, 3), order="C").max(axis=1)
-                    )
+                    # stress returned as Voigt vector [sxx, syy, szz, syz, sxz, sxy]
+                    stress = atoms.get_stress()
+                    max_stress = float(abs(stress).max())

301-319: Combine step may run on multiple workers; harmless but noisy.

Each job may enter the combine block simultaneously when all shards exist, duplicating the combine work and console logs. Consider gating combine to a single job (e.g., job_number == 0) to cut noise.

-        if len(file_list) == self.num_jobs:
+        if job_number == 0 and len(file_list) == self.num_jobs:

327-336: Fix ambiguous full-width punctuation in Typer help strings (ruff RUF001).

Use ASCII punctuation to satisfy linters.

-    checkpoint_path: Annotated[Path, typer.Option(help="路径,包含 checkpoint.pt")],
+    checkpoint_path: Annotated[Path, typer.Option(help="Path containing checkpoint.pt")],
@@
-    model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
-    identifier: Annotated[str, typer.Option(help="运行标识,用于文件夹命名")],
-    atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
-    seed: Annotated[int, typer.Option(help="随机种子")] = 42,
-    num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
-    debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
-    slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
+    model_name: Annotated[str, typer.Option(help="Subdirectory name under out-path")],
+    identifier: Annotated[str, typer.Option(help="Run identifier used for folder naming")],
+    atom_disp: Annotated[float, typer.Option(help="Displacement distance for phonon calc")] = 0.03,
+    seed: Annotated[int, typer.Option(help="Random seed")] = 42,
+    num_jobs: Annotated[int, typer.Option(help="Number of parallel jobs")] = 10,
+    debug: Annotated[bool, typer.Option(help="Debug mode: run a single job")] = False,
+    slurm_timeout: Annotated[int, typer.Option(help="Slurm time out in hours")] = 80,

354-367: Comment contradicts code regarding num_jobs in debug mode.

The comment says “设置为0处理前3个样本” but you pass num_jobs=1. Either set it to 0 or update the comment to avoid confusion.

-                num_jobs=1,  # 设置为0处理前3个样本
+                num_jobs=1,  # debug: a single job

372-391: Standardize GPU assignment using Submitit’s gpus_per_task instead of manual CUDA_VISIBLE_DEVICES

Manual setting of CUDA_VISIBLE_DEVICES across test suites will break or collide when num_jobs exceeds the physical GPU count. Since you’re already calling:

executor.update_parameters(
    cpus_per_task=1,
    gpus_per_task=1,
    …
)

you can remove all env_vars = {"CUDA_VISIBLE_DEVICES": …} assignments and let Submitit handle GPU placement. If you still need explicit indexing, guard against the available GPUs (e.g. modulo torch.cuda.device_count()).

Files/locations to refactor:

  • models/eqV2_tracegrad/test_fairchem_kappa.py
    • debug mode: lines 357–359
    • batch loop: lines 375–379
  • models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py
    • debug mode: lines 268–269
    • batch loop: lines 273–277
  • models/hienet/test_hienet_kappa.py
    • lines 64–66
  • models/hienet/test_hienet_discovery.py
    • lines 65–67

By removing these overrides, you ensure robust GPU scheduling even when num_jobs > available GPUs.

models/eqV2_tracegrad/test_fairchem_kappa.sh (1)

3-10: Avoid hard-coded absolute paths; make script relocatable.

Consider using environment variables (e.g., FAIRCHEM_CHECKPOINT, MBD_OUT) or accepting these as positional args to the script.

models/eqV2_tracegrad/test_fairchem_tracegrad.sh (3)

1-1: Remove leading space before shebang (SC1114).

- #!/bin/bash
+#!/usr/bin/env bash
+set -euo pipefail

16-25: Same trailing backslash in commented block (SC1143).

Remove the trailing backslash to avoid confusion, or move the comment above.

-#     --num-jobs 1\
+#     --num-jobs 1

5-14: Parameterize absolute paths for portability.

Use env vars (e.g., OUT_PATH, CKPT) or accept inputs as args. This aligns with maintainers’ request and CI runners.

models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py (4)

54-59: Add return type annotation for private helper (ruff ANN202).

-    def _add_fairchem_to_sys_path(self):
+    def _add_fairchem_to_sys_path(self) -> None:

74-79: Type annotation for env_vars is incorrect.

env_vars should be optional mapping.

-        env_vars: None,
+        env_vars: dict[str, str] | None,

90-96: Use current device index for device name.

You print the current device id but then query get_device_name(0), which may not correspond to the current device when CUDA_VISIBLE_DEVICES is set.

-            print(f"Current CUDA device: {torch.cuda.current_device()}")
-            print(f"Device name: {torch.cuda.get_device_name(0)}")
+            dev = torch.cuda.current_device()
+            print(f"Current CUDA device: {dev}")
+            print(f"Device name: {torch.cuda.get_device_name(dev)}")

268-277: GPU assignment via CUDA_VISIBLE_DEVICES equals job index can over-subscribe VRAM.

Prefer letting Slurm/Submitit handle placement when using gpus_per_task=1. If you must set it, guard against job_number >= num_visible_gpus.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f52b4d9 and 7fe7109.

📒 Files selected for processing (10)
  • models/eqV2_tracegrad/eqV2-s-dens-tracegrad-mp.yml (1 hunks)
  • models/eqV2_tracegrad/join_fairchem_preds.py (1 hunks)
  • models/eqV2_tracegrad/join_fairchem_preds.sh (1 hunks)
  • models/eqV2_tracegrad/save_geo_opt_file.py (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_kappa.py (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_kappa.sh (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_kappa_debug.py (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_tracegrad.sh (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_tracegrad_discovery_debug.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
models/eqV2_tracegrad/join_fairchem_preds.py (3)
matbench_discovery/enums.py (3)
  • DataFiles (472-573)
  • MbdKey (46-123)
  • path (549-573)
matbench_discovery/data.py (1)
  • as_dict_handler (42-51)
matbench_discovery/energy.py (1)
  • get_e_form_per_atom (149-182)
models/eqV2_tracegrad/test_fairchem_kappa_debug.py (4)
matbench_discovery/enums.py (4)
  • metadata (368-377)
  • DataFiles (472-573)
  • path (549-573)
  • base_dir (209-211)
matbench_discovery/phonons/__init__.py (1)
  • check_imaginary_freqs (16-42)
models/eqV2_tracegrad/test_fairchem_kappa.py (4)
  • seed_everywhere (45-48)
  • KappaSRMERunner (51-323)
  • run (70-323)
  • run_kappa (326-391)
matbench_discovery/phonons/thermal_conductivity.py (4)
  • init_phono3py (110-152)
  • get_fc2_and_freqs (155-188)
  • calculate_fc3_set (68-107)
  • calculate_conductivity (212-274)
models/eqV2_tracegrad/test_fairchem_kappa.py (3)
matbench_discovery/enums.py (4)
  • metadata (368-377)
  • DataFiles (472-573)
  • path (549-573)
  • base_dir (209-211)
matbench_discovery/phonons/__init__.py (1)
  • check_imaginary_freqs (16-42)
matbench_discovery/phonons/thermal_conductivity.py (4)
  • init_phono3py (110-152)
  • get_fc2_and_freqs (155-188)
  • calculate_fc3_set (68-107)
  • calculate_conductivity (212-274)
models/eqV2_tracegrad/save_geo_opt_file.py (1)
matbench_discovery/enums.py (1)
  • geo_opt_path (418-436)
models/eqV2_tracegrad/test_fairchem_tracegrad_discovery_debug.py (5)
matbench_discovery/enums.py (3)
  • path (549-573)
  • MbdKey (46-123)
  • Task (127-141)
matbench_discovery/data.py (1)
  • as_dict_handler (42-51)
matbench_discovery/plots.py (1)
  • wandb_scatter (696-722)
models/eqV2_tracegrad/test_fairchem_kappa_debug.py (1)
  • run (68-323)
models/eqV2_tracegrad/test_fairchem_kappa.py (1)
  • run (70-323)
models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py (3)
matbench_discovery/enums.py (2)
  • MbdKey (46-123)
  • Task (127-141)
matbench_discovery/data.py (1)
  • as_dict_handler (42-51)
matbench_discovery/plots.py (1)
  • wandb_scatter (696-722)
🪛 Shellcheck (0.10.0)
models/eqV2_tracegrad/test_fairchem_kappa.sh

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)


[error] 11-11: This backslash is part of a comment and does not continue the line.

(SC1143)

models/eqV2_tracegrad/test_fairchem_tracegrad.sh

[error] 1-1: Remove leading spaces before the shebang.

(SC1114)

models/eqV2_tracegrad/join_fairchem_preds.sh

[error] 1-1: Remove leading spaces before the shebang.

(SC1114)

🪛 Ruff (0.12.2)
models/eqV2_tracegrad/join_fairchem_preds.py

66-66: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)

models/eqV2_tracegrad/test_fairchem_kappa_debug.py

327-327: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


330-330: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


333-333: Unused function argument: num_jobs

(ARG001)


334-334: Boolean default positional argument in function definition

(FBT002)


334-334: Unused function argument: debug

(ARG001)


334-334: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


335-335: String contains ambiguous (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?

(RUF001)


335-335: String contains ambiguous (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?

(RUF001)

models/eqV2_tracegrad/test_fairchem_kappa.py

327-327: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


330-330: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


334-334: Boolean default positional argument in function definition

(FBT002)


334-334: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


335-335: String contains ambiguous (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?

(RUF001)


335-335: String contains ambiguous (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?

(RUF001)


356-356: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)


356-356: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)


372-372: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)

models/eqV2_tracegrad/save_geo_opt_file.py

7-7: Missing return type annotation for public function detect_file_format

Add return type annotation: str | None

(ANN201)


7-7: Missing type annotation for function argument file_path

(ANN001)


19-19: Consider moving this statement to an else block

(TRY300)


25-25: Line too long (120 > 88)

(E501)


26-26: Line too long (117 > 88)

(E501)

models/eqV2_tracegrad/test_fairchem_tracegrad_discovery_debug.py

40-40: Line too long (147 > 88)

(E501)


41-41: Line too long (129 > 88)

(E501)


80-80: info() call on root logger

(LOG015)


165-165: info() call on root logger

(LOG015)


177-177: Line too long (97 > 88)

(E501)


178-178: Line too long (112 > 88)

(E501)


191-191: exception() call on root logger

(LOG015)

models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py

54-54: Missing return type annotation for private function _add_fairchem_to_sys_path

Add return type annotation: None

(ANN202)


90-90: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)


100-100: info() call on root logger

(LOG015)


176-176: info() call on root logger

(LOG015)


197-197: exception() call on root logger

(LOG015)

🪛 Gitleaks (8.27.2)
models/eqV2_tracegrad/eqV2-s-dens-tracegrad-mp.yml

2-2: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (5)
models/eqV2_tracegrad/eqV2-s-dens-tracegrad-mp.yml (1)

99-119: Verify metrics consistency (FPR/TNR vs Accuracy) and units.

  • most_stable_10k: TPR=1.0 and FPR=1.0 implies predicting all positives; check if Accuracy (0.976) aligns with TP/FP counts given class distribution.
  • missing_percent is annotated as “fraction” but values include a percent sign (e.g., "0.00%"). Use a numeric fraction or correct the comment.

If needed, I can help recompute and update these blocks from your result files.

Also applies to: 120-139, 140-158

models/eqV2_tracegrad/join_fairchem_preds.py (1)

40-46: Minor: glob logic and logging are fine.

Pattern and discovery are correct given the naming scheme.

models/eqV2_tracegrad/test_fairchem_kappa_debug.py (1)

217-236: FC3 gating logic reads well; continue if fail.

Conditioning FC3 on non-imaginary freqs and symmetry is a reasonable gate. The warnings and skip behavior are appropriate.

Also applies to: 240-249

models/eqV2_tracegrad/test_fairchem_tracegrad_discovery_debug.py (2)

80-91: Root logger usage is fine for a debug script.

Given this is a debug/local runner, using the root logger and suppressing detailed setup is acceptable.


195-222: CLI defaults mirror production; good parity.

The Typer interface is consistent with the production runner, which keeps UX aligned for users switching between modes.

Comment on lines +61 to +65
df_fairchem_ori = pd.read_csv(
"/data/fywang/code/matbench-discovery/pred_results/eqV2-small-dens/test/eqV2-s-dens-mp-ori.csv.gz",
compression="gzip",
).set_index(Key.mat_id) # 开源结果

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove hard-coded baseline path; make it optional CLI input.

Hard-coded absolute paths break reproducibility. Make the “eqV2 open-data baseline” path a parameter.

 def join_predictions(
@@
     apply_mp_corrections: Annotated[
         bool, typer.Option(help="Apply MP 2020 corrections to formation energies")
     ] = False,
+    baseline_path: Annotated[
+        str | None,
+        typer.Option(help="Optional path to baseline eqV2-ori energies (csv.gz)"),
+    ] = None,
 ) -> None:
@@
-    df_fairchem_ori = pd.read_csv(
-        "/data/fywang/code/matbench-discovery/pred_results/eqV2-small-dens/test/eqV2-s-dens-mp-ori.csv.gz",
-        compression="gzip",
-    ).set_index(Key.mat_id)  # 开源结果
-
-    # 合并df_fairchem_ori中的pred_energy到df_fairchem,根据mat_id匹配
-    df_fairchem = df_fairchem.merge(
-        df_fairchem_ori[["eqV2-31M-dens-MP-p5_energy"]],
-        left_index=True,
-        right_index=True,
-    )
+    if baseline_path:
+        df_fairchem_ori = pd.read_csv(baseline_path, compression="gzip").set_index(
+            Key.mat_id
+        )  # 开源结果
+        # 合并df_fairchem_ori中的pred_energy到df_fairchem,根据mat_id匹配
+        df_fairchem = df_fairchem.merge(
+            df_fairchem_ori[["eqV2-31M-dens-MP-p5_energy"]],
+            left_index=True,
+            right_index=True,
+        )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
df_fairchem_ori = pd.read_csv(
"/data/fywang/code/matbench-discovery/pred_results/eqV2-small-dens/test/eqV2-s-dens-mp-ori.csv.gz",
compression="gzip",
).set_index(Key.mat_id) # 开源结果
def join_predictions(
@@
apply_mp_corrections: Annotated[
bool, typer.Option(help="Apply MP 2020 corrections to formation energies")
] = False,
baseline_path: Annotated[
str | None,
typer.Option(help="Optional path to baseline eqV2-ori energies (csv.gz)"),
] = None,
) -> None:
@@
- df_fairchem_ori = pd.read_csv(
- "/data/fywang/code/matbench-discovery/pred_results/eqV2-small-dens/test/eqV2-s-dens-mp-ori.csv.gz",
- compression="gzip",
- ).set_index(Key.mat_id) # 开源结果
-
- # 合并df_fairchem_ori中的pred_energy到df_fairchem,根据mat_id匹配
- df_fairchem = df_fairchem.merge(
- df_fairchem_ori[["eqV2-31M-dens-MP-p5_energy"]],
- left_index=True,
- right_index=True,
if baseline_path:
df_fairchem_ori = (
pd.read_csv(baseline_path, compression="gzip")
.set_index(Key.mat_id)
) # 开源结果
# 合并 df_fairchem_ori 中的 pred_energy 到 df_fairchem,根据 mat_id 匹配
df_fairchem = df_fairchem.merge(
df_fairchem_ori[["eqV2-31M-dens-MP-p5_energy"]],
left_index=True,
right_index=True,
)

Comment thread models/eqV2_tracegrad/join_fairchem_preds.py
Comment on lines +98 to +107
if apply_mp_corrections is True:
# apply energy corrections
processed = MaterialsProject2020Compatibility().process_entries(
df_fairchem[computed_structure_entry_key], verbose=True, clean=True
)
if len(processed) != len(df_fairchem):
raise ValueError(
f"not all entries processed: {len(processed)=} {len(df_fairchem)=}"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

MP2020 corrections are computed but never applied to the CSEs used below.

process_entries() returns corrected entries; you only check count. You must write them back before computing formation energies.

     if apply_mp_corrections is True:
         # apply energy corrections
         processed = MaterialsProject2020Compatibility().process_entries(
             df_fairchem[computed_structure_entry_key], verbose=True, clean=True
         )
         if len(processed) != len(df_fairchem):
             raise ValueError(
                 f"not all entries processed: {len(processed)=} {len(df_fairchem)=}"
             )
+        # Replace uncorrected entries with corrected ones in the same order
+        df_fairchem[computed_structure_entry_key] = processed
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if apply_mp_corrections is True:
# apply energy corrections
processed = MaterialsProject2020Compatibility().process_entries(
df_fairchem[computed_structure_entry_key], verbose=True, clean=True
)
if len(processed) != len(df_fairchem):
raise ValueError(
f"not all entries processed: {len(processed)=} {len(df_fairchem)=}"
)
if apply_mp_corrections is True:
# apply energy corrections
processed = MaterialsProject2020Compatibility().process_entries(
df_fairchem[computed_structure_entry_key], verbose=True, clean=True
)
if len(processed) != len(df_fairchem):
raise ValueError(
f"not all entries processed: {len(processed)=} {len(df_fairchem)=}"
)
# Replace uncorrected entries with corrected ones in the same order
df_fairchem[computed_structure_entry_key] = processed
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/join_fairchem_preds.py around lines 98 to 107, you call
MaterialsProject2020Compatibility().process_entries(...) and only check that
counts match, but you never replace the CSEs in df_fairchem with the corrected
entries; write the returned processed entries back into
df_fairchem[computed_structure_entry_key] (preserving row order or mapping by
index if process_entries reorders) before any formation-energy computation, so
downstream code uses the corrected entries.

Comment on lines +127 to +136
df_fairchem.select_dtypes("number").to_csv(out_path / f"{model_name}.csv.gz")
df_bad = df_fairchem[bad_mask].drop(
columns=[computed_structure_entry_key, struct_col]
)
df_bad[MbdKey.e_form_dft] = df_wbm[MbdKey.e_form_dft]
df_bad.to_csv(f"{out_path}-bad.csv")

df_fairchem.reset_index().to_json(
out_path / f"{model_name}.json.gz", default_handler=as_dict_handler
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ensure compression for .csv.gz and .json.gz outputs; also write -bad.csv as gzip.

Explicitly set compression to avoid uncompressed files with .gz suffix. Also avoid SettingWithCopy on df_bad, and keep consistent gz for the “bad” file.

-    df_fairchem.select_dtypes("number").to_csv(out_path / f"{model_name}.csv.gz")
+    df_fairchem.select_dtypes("number").to_csv(
+        out_path / f"{model_name}.csv.gz", compression="gzip"
+    )
     df_bad = df_fairchem[bad_mask].drop(
         columns=[computed_structure_entry_key, struct_col]
     )
-    df_bad[MbdKey.e_form_dft] = df_wbm[MbdKey.e_form_dft]
-    df_bad.to_csv(f"{out_path}-bad.csv")
+    df_bad = df_bad.assign(**{MbdKey.e_form_dft: df_wbm.loc[df_bad.index, MbdKey.e_form_dft]})
+    df_bad.to_csv(out_path / f"{model_name}-bad.csv.gz", compression="gzip")
@@
-    df_fairchem.reset_index().to_json(
-        out_path / f"{model_name}.json.gz", default_handler=as_dict_handler
-    )
+    df_fairchem.reset_index().to_json(
+        out_path / f"{model_name}.json.gz",
+        compression="gzip",
+        default_handler=as_dict_handler,
+        orient="records",
+    )

🌐 Web query:

Does pandas DataFrame.to_json support a compression parameter?

💡 Result:

Yes. DataFrame.to_json accepts a compression parameter (str or dict, default "infer") and will compress the output when you pass a filename. (pandas.pydata.org)

Examples:

  • Let pandas infer from the extension:
    df.to_json("out.json.gz") # compression inferred from .gz
  • Specify compression explicitly:
    df.to_json("out.json.gz", compression="gzip")
  • Pass compression options as a dict:
    df.to_json("out.json.gz", compression={"method": "gzip", "compresslevel": 1, "mtime": 1}). (pandas.pydata.org)

Note: compression is only applied when the first argument is a filename (if path_or_buf is None the method returns a JSON string; if you pass a file-like object you can wrap it yourself with gzip.open/etc.). (pandas.pydata.org)

Citations:


Add gzip compression to CSV/JSON outputs and fix df_bad assignment

Ensure all “.gz” files are actually compressed and avoid a SettingWithCopy on df_bad. In models/eqV2_tracegrad/join_fairchem_preds.py (lines 127–136):

-    df_fairchem.select_dtypes("number").to_csv(out_path / f"{model_name}.csv.gz")
+    df_fairchem.select_dtypes("number").to_csv(
+        out_path / f"{model_name}.csv.gz",
+        compression="gzip",
+    )

     df_bad = df_fairchem[bad_mask].drop(
         columns=[computed_structure_entry_key, struct_col]
     )
-    df_bad[MbdKey.e_form_dft] = df_wbm[MbdKey.e_form_dft]
-    df_bad.to_csv(f"{out_path}-bad.csv")
+    df_bad = df_bad.assign(
+        **{MbdKey.e_form_dft: df_wbm.loc[df_bad.index, MbdKey.e_form_dft]}
+    )
+    df_bad.to_csv(
+        out_path / f"{model_name}-bad.csv.gz",
+        compression="gzip",
+    )

-    df_fairchem.reset_index().to_json(
-        out_path / f"{model_name}.json.gz", default_handler=as_dict_handler
-    )
+    df_fairchem.reset_index().to_json(
+        out_path / f"{model_name}.json.gz",
+        compression="gzip",
+        default_handler=as_dict_handler,
+        orient="records",
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
df_fairchem.select_dtypes("number").to_csv(out_path / f"{model_name}.csv.gz")
df_bad = df_fairchem[bad_mask].drop(
columns=[computed_structure_entry_key, struct_col]
)
df_bad[MbdKey.e_form_dft] = df_wbm[MbdKey.e_form_dft]
df_bad.to_csv(f"{out_path}-bad.csv")
df_fairchem.reset_index().to_json(
out_path / f"{model_name}.json.gz", default_handler=as_dict_handler
)
df_fairchem.select_dtypes("number").to_csv(
out_path / f"{model_name}.csv.gz",
compression="gzip",
)
df_bad = df_fairchem[bad_mask].drop(
columns=[computed_structure_entry_key, struct_col]
)
df_bad = df_bad.assign(
**{MbdKey.e_form_dft: df_wbm.loc[df_bad.index, MbdKey.e_form_dft]}
)
df_bad.to_csv(
out_path / f"{model_name}-bad.csv.gz",
compression="gzip",
)
df_fairchem.reset_index().to_json(
out_path / f"{model_name}.json.gz",
compression="gzip",
default_handler=as_dict_handler,
orient="records",
)
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/join_fairchem_preds.py around lines 127–136, the
CSV/JSON outputs are named with “.gz” but not actually compressed and df_bad is
modified in a way that can trigger a SettingWithCopy warning; fix by making
df_bad a true copy (e.g., append .copy() after the .drop(...) call) and perform
assignment with .loc (df_bad.loc[:, MbdKey.e_form_dft] =
df_wbm[MbdKey.e_form_dft]), write the numeric CSV and the bad-rows CSV with gzip
compression (use pandas to_csv with compression='gzip' or write via gzip.open)
and write the JSON in compressed form (either pandas to_json with
compression='gzip' or write the JSON string to a gzip file) ensuring filenames
end with .csv.gz / .json.gz as intended.

@@ -0,0 +1,15 @@
#!/bin/bash

export PYTHONPATH=/data/fywang/code/fairchem-main/src:$PYTHONPATH
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove hard-coded PYTHONPATH; rely on declared script dependencies and uv run.

Avoid machine-specific paths. Use uv run so dependencies are installed automatically per the contribution guide.

-export PYTHONPATH=/data/fywang/code/fairchem-main/src:$PYTHONPATH
+# Run with uv so dependencies declared in the script are auto-installed:
+# uv run models/eqV2_tracegrad/join_fairchem_preds.py ...
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export PYTHONPATH=/data/fywang/code/fairchem-main/src:$PYTHONPATH
# Run with uv so dependencies declared in the script are auto-installed:
# uv run models/eqV2_tracegrad/join_fairchem_preds.py ...
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/join_fairchem_preds.sh around line 3, remove the
hard-coded export of PYTHONPATH and instead run the Python command via the
project's task runner so dependencies are installed automatically; delete the
export line and replace direct python invocations with "uv run <script or
module>" (or wrap the script execution in uv run), and ensure the script relies
on declared dependencies in pyproject/uv configuration per the contribution
guide.

Comment on lines +3 to +4
sys.path.insert(0, "/data/fywang/code/fairchem-tracegrad-hanhai/src")
import json
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove hard-coded sys.path insertion; rely on installed packages or uv script deps.

Local path hacks break reproducibility and CI. Install the dependency or declare it in uv scripts so uv run can resolve it.

-import sys
-
-sys.path.insert(0, "/data/fywang/code/fairchem-tracegrad-hanhai/src")
+import sys
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sys.path.insert(0, "/data/fywang/code/fairchem-tracegrad-hanhai/src")
import json
import sys
import json
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py around lines 3 to
4, remove the hard-coded sys.path.insert call that prepends a local source path;
instead declare the project dependency properly so the test imports resolve via
installed packages or the uv run script. Fix by removing the sys.path
modification, adding the package to test-time dependencies (e.g.,
requirements/dev or pyproject/uv script), or ensuring the test environment
installs the src package so imports work without path hacks.

Comment on lines +33 to +36
BASE_PATH = Path("/data/fywang/code/matbench-discovery/data/wbm")
DATABASE_PATH = {
Task.IS2RE: str(BASE_PATH / "WBM_IS2RE_initial_atoms.aselmdb"),
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Avoid hard-coded dataset path; make it configurable.

Hard-coding /data/.../WBM_IS2RE_initial_atoms.aselmdb ties execution to your machine. Either:

  • use a DataFiles enum if available (e.g., DataFiles.wbm_is2re.path), or
  • accept a --db-path CLI option and default from repo data if present.

I can help wire this in if you confirm preferred source.

To locate a suitable DataFiles entry, run:


🏁 Script executed:

#!/bin/bash
# Try to find an enum or path for WBM IS2RE in the codebase
rg -n -C2 -P 'WBM_IS2RE|aselmdb|wbm.*is2re' --type=py

Length of output: 3253


🏁 Script executed:

#!/bin/bash
# Search for DataFiles enum or class to use for DB paths
rg -n -P 'class\s+DataFiles|enum\s+DataFiles|DataFiles\.' --type=py

Length of output: 12040


🏁 Script executed:

#!/bin/bash
# Show imports and context for DataFiles usage
sed -n '1,50p' models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py

Length of output: 1554


Use the shared DataFiles enum for the DB path instead of a hard-coded absolute path

Replace the hard-coded BASE_PATH/DATABASE_PATH in
models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py (lines 33–36) with the built-in DataFiles entry:

• Import and use DataFiles.wbm_initial_atoms.path for Task.IS2RE
• (Optional) Expose a --db-path CLI flag defaulting to that same value

Suggested diff:

-from pathlib import Path
-
-BASE_PATH = Path("/data/fywang/code/matbench-discovery/data/wbm")
-DATABASE_PATH = {
-    Task.IS2RE: str(BASE_PATH / "WBM_IS2RE_initial_atoms.aselmdb"),
-}
+from matbench_discovery.enums import DataFiles
+
+DATABASE_PATH = {
+    Task.IS2RE: DataFiles.wbm_initial_atoms.path,
+}

If you’d like a CLI override, you can add:

db_path: Path = typer.Option(
    DataFiles.wbm_initial_atoms.path,
    "--db-path",
    help="Path to the WBM IS2RE ASELMDB file",
)
# …then use db_path instead of DataFiles.wbm_initial_atoms.path directly

Let me know if you need help wiring up the CLI option.

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py around lines 33 to
36, replace the hard-coded BASE_PATH and DATABASE_PATH values with the shared
DataFiles enum entry: use DataFiles.wbm_initial_atoms.path for Task.IS2RE
(import DataFiles from its module), and remove the absolute Path("/data/...")
constants; optionally add a typer CLI option db_path: Path =
typer.Option(DataFiles.wbm_initial_atoms.path, "--db-path", help="Path to the
WBM IS2RE ASELMDB file") and use that variable wherever the DB path is consumed
to allow overrides.

Comment on lines +257 to +265
# 设置 submitit Executor 来管理并行任务
executor = AutoExecutor(folder=out_path)
executor.update_parameters(
cpus_per_task=1,
slurm_gpus_per_task=1, # 每个任务使用一个 GPU
nodes=1,
timeout_min=60 * slurm_timeout,
mem_gb=80,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Submitit param name likely invalid: use gpus_per_task (or gpus_per_node).

slurm_gpus_per_task isn’t a standard Submitit parameter and will be ignored. Use gpus_per_task=1 as in your other script, or gpus_per_node depending on your cluster policy.

-        cpus_per_task=1,
-        slurm_gpus_per_task=1,  # 每个任务使用一个 GPU
+        cpus_per_task=1,
+        gpus_per_task=1,  # one GPU per task
         nodes=1,
         timeout_min=60 * slurm_timeout,
         mem_gb=80,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 设置 submitit Executor 来管理并行任务
executor = AutoExecutor(folder=out_path)
executor.update_parameters(
cpus_per_task=1,
slurm_gpus_per_task=1, # 每个任务使用一个 GPU
nodes=1,
timeout_min=60 * slurm_timeout,
mem_gb=80,
)
# 设置 submitit Executor 来管理并行任务
executor = AutoExecutor(folder=out_path)
executor.update_parameters(
cpus_per_task=1,
gpus_per_task=1, # one GPU per task
nodes=1,
timeout_min=60 * slurm_timeout,
mem_gb=80,
)
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py around lines 257
to 265, the Submitit parameter slurm_gpus_per_task is invalid and will be
ignored; replace it with the correct Submitit parameter (e.g., gpus_per_task=1
or gpus_per_node=1 depending on cluster policy) so the job actually requests GPU
resources, keep other executor.update_parameters entries unchanged, and ensure
consistency with other scripts that use gpus_per_task.

Comment on lines +2 to +3
export WANDB_MODE=offline
export PYTHONPATH=/data/fywang/code/fairchem-tracegrad-hanhai/src:$PYTHONPATH
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid hard-coded PYTHONPATH; prefer uv-managed deps.

Make this reproducible for others without your local layout.

-export WANDB_MODE=offline
-export PYTHONPATH=/data/fywang/code/fairchem-tracegrad-hanhai/src:$PYTHONPATH
+export WANDB_MODE=offline
+# Dependencies should be auto-installed by uv using declared script dependencies.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_tracegrad.sh around lines 2-3, the script
sets an absolute PYTHONPATH to a local developer directory which breaks
reproducibility; remove the hard-coded path and either (a) compute the src path
relative to the script at runtime so the script works on other clones, or (b)
stop manipulating PYTHONPATH and require/install the package into the virtualenv
(pip install -e . or via your project’s dependency manager like pip/poetry/venv)
and run tests with python -m so dependencies are managed by the environment
rather than a hard-coded path.

Comment on lines +5 to +15
python test_fairchem_tracegrad_discovery.py \
--out-path /data/fywang/code/matbench-discovery/pred_results/ \
--model-name eqV2-small-dens-tracegrad \
--optimizer FIRE \
--cell-filter unit \
--force-max 0.02 \
--max-steps 500 \
--num-jobs 10 \
--device cuda \
--checkpoint-path /data/fywang/code/fairchem-tracegrad-hanhai/checkpoints/2025-06-16-14-11-12/best_checkpoint.pt \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use module invocation and fix dangling backslashes before commented lines.

Also makes the script runnable from repo root.

- python test_fairchem_tracegrad_discovery.py \
+ uv run -m models.eqV2_tracegrad.test_fairchem_tracegrad_discovery \
    --out-path /data/fywang/code/matbench-discovery/pred_results/ \
    --model-name eqV2-small-dens-tracegrad \
    --optimizer FIRE \
    --cell-filter unit \
    --force-max 0.02 \
    --max-steps 500 \
    --num-jobs 10 \
    --device cuda \
-    --checkpoint-path /data/fywang/code/fairchem-tracegrad-hanhai/checkpoints/2025-06-16-14-11-12/best_checkpoint.pt \
+    --checkpoint-path /data/fywang/code/fairchem-tracegrad-hanhai/checkpoints/2025-06-16-14-11-12/best_checkpoint.pt
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
python test_fairchem_tracegrad_discovery.py \
--out-path /data/fywang/code/matbench-discovery/pred_results/ \
--model-name eqV2-small-dens-tracegrad \
--optimizer FIRE \
--cell-filter unit \
--force-max 0.02 \
--max-steps 500 \
--num-jobs 10 \
--device cuda \
--checkpoint-path /data/fywang/code/fairchem-tracegrad-hanhai/checkpoints/2025-06-16-14-11-12/best_checkpoint.pt \
python -m models.eqV2_tracegrad.test_fairchem_tracegrad_discovery \
--out-path /data/fywang/code/matbench-discovery/pred_results/ \
--model-name eqV2-small-dens-tracegrad \
--optimizer FIRE \
--cell-filter unit \
--force-max 0.02 \
--max-steps 500 \
--num-jobs 10 \
--device cuda \
--checkpoint-path /data/fywang/code/fairchem-tracegrad-hanhai/checkpoints/2025-06-16-14-11-12/best_checkpoint.pt
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_tracegrad.sh around lines 5–15, the
script uses a direct python script path with trailing backslashes that leave a
dangling line continuation before commented lines and hard-coded absolute paths;
change the invocation to module form (python -m
models.eqV2_tracegrad.test_fairchem_tracegrad_discovery) remove any trailing
backslashes that precede comments or the end of the command so the shell line
continuations are correct, and make file paths repo-root relative (or derive
them from the script location) so the script can be run from the repository
root.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
models/eqV2_tracegrad/join_fairchem_preds.py (4)

61-65: Fix the hard-coded baseline path.

The hard-coded path to the baseline results file violates reproducibility. Based on the PR feedback, this needs to be parameterized.


73-74: Add missing lines=True parameter for JSON Lines file.

The WBM computed structure entries file is a JSON Lines (.jsonl.gz) format that requires lines=True for proper parsing.


98-107: Apply the processed MP corrections to the DataFrame.

The MP2020 corrections are computed but never applied to the entries used for formation energy calculations.


127-136: Add compression parameters and fix df_bad output path.

The output files need explicit compression settings and the bad results file should use a proper path structure.

🧹 Nitpick comments (3)
models/eqV2_tracegrad/join_fairchem_preds.py (3)

66-66: Replace fullwidth comma with standard comma.

The comment contains an ambiguous fullwidth comma character that should be replaced with a standard comma for consistency.

-    # 合并df_fairchem_ori中的pred_energy到df_fairchem,根据mat_id匹配
+    # 合并df_fairchem_ori中的pred_energy到df_fairchem,根据mat_id匹配

40-41: Remove commented duplicate line.

Line 40 contains commented code that duplicates line 41.

-    # glob_pattern = f"{model_name}*.json.gz"
     glob_pattern = f"{model_name}*.json.gz"

93-93: Remove commented alternative energy assignment.

This commented line appears to be debugging code that should be removed.

-        # cse._energy = pred_energy_ori  # added by fywang
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7fe7109 and ef79c62.

⛔ Files ignored due to path filters (1)
  • models/eqV2_tracegrad/eqV2-s-dens-mp-ori.csv.gz is excluded by !**/*.gz
📒 Files selected for processing (1)
  • models/eqV2_tracegrad/join_fairchem_preds.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
models/eqV2_tracegrad/join_fairchem_preds.py (3)
matbench_discovery/enums.py (2)
  • DataFiles (472-573)
  • MbdKey (46-123)
matbench_discovery/data.py (1)
  • as_dict_handler (42-51)
matbench_discovery/energy.py (1)
  • get_e_form_per_atom (149-182)
🪛 Ruff (0.12.2)
models/eqV2_tracegrad/join_fairchem_preds.py

66-66: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)

@TheSheng1103
Copy link
Copy Markdown
Author

Hello Matbench Discovery Team,
we have made some modifications to the eqV2_tracegrad model as per your request. Currently, it runs smoothly in our server environment, but it has not passed your testing yet. Could you please provide us with your testing process and script so that we can identify and correct the issue in our local environment?

@janosh
Copy link
Copy Markdown
Owner

janosh commented Oct 26, 2025

@TheSheng1103 we're not running your model in CI. the issues reported in Lint / prek are purely stylistic/formatting errors. for example, you seem to have a lot of unusual characters in your script. make sure you use UTF-8 encoding (and also fix the other lints)

 models/eqV2_tracegrad/test_fairchem_kappa.py:334:51: RUF001 String contains ambiguous `,` (FULLWIDTH COMMA). Did you mean `,` (COMMA)?
  models/eqV2_tracegrad/test_fairchem_kappa.py:335:64: RUF001 String contains ambiguous `(` (FULLWIDTH LEFT PARENTHESIS). Did you mean `(` (LEFT PARENTHESIS)?
  models/eqV2_tracegrad/test_fairchem_kappa.py:335:67: RUF001 String contains ambiguous `)` (FULLWIDTH RIGHT PARENTHESIS). Did you mean `)` (RIGHT PARENTHESIS)?
  models/eqV2_tracegrad/test_fairchem_kappa.py:356:15: RUF003 Comment contains ambiguous `,` (FULLWIDTH COMMA). Did you mean `,` (COMMA)?
  models/eqV2_tracegrad/test_fairchem_kappa.py:356:23: RUF003 Comment contains ambiguous `,` (FULLWIDTH COMMA). Did you mean `,` (COMMA)?
  models/eqV2_tracegrad/test_fairchem_kappa.py:372:15: RUF003 Comment contains ambiguous `,` (FULLWIDTH COMMA). Did you mean `,` (COMMA)?

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (1)
models/eqV2_tracegrad/test_fairchem_kappa.py (1)

288-299: JSON compression issue already flagged.

This segment has the same JSON compression issue that was identified in the previous review. Files are written with .json.gz extension but to_json() is called without compression="gzip", which will cause read failures later.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95715bc and 4462f9d.

📒 Files selected for processing (1)
  • models/eqV2_tracegrad/test_fairchem_kappa.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
models/eqV2_tracegrad/test_fairchem_kappa.py (3)
matbench_discovery/enums.py (4)
  • metadata (379-388)
  • DataFiles (503-604)
  • path (580-604)
  • base_dir (208-210)
matbench_discovery/phonons/__init__.py (1)
  • check_imaginary_freqs (16-42)
matbench_discovery/phonons/thermal_conductivity.py (4)
  • init_phono3py (116-158)
  • get_fc2_and_freqs (161-194)
  • calculate_fc3_set (74-113)
  • calculate_conductivity (218-280)
🪛 GitHub Actions: Lint
models/eqV2_tracegrad/test_fairchem_kappa.py

[error] 239-239: hunted by diagnostics: unsupported-operator in test file during CI (likely due to path/union type handling).

🪛 Ruff (0.14.2)
models/eqV2_tracegrad/test_fairchem_kappa.py

192-192: Do not catch blind exception: Exception

(BLE001)


255-255: Do not catch blind exception: Exception

(BLE001)


270-270: Do not catch blind exception: Exception

(BLE001)


310-310: Do not catch blind exception: Exception

(BLE001)


327-327: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


330-330: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: pytest (windows-latest) / tests
  • GitHub Check: pytest (ubuntu-latest) / tests
  • GitHub Check: scripts (scripts/evals/discovery.py)
🔇 Additional comments (8)
models/eqV2_tracegrad/test_fairchem_kappa.py (8)

1-49: LGTM!

The imports are well-organized and the seed_everywhere function correctly seeds all RNG sources for reproducibility.


51-68: LGTM!

The constructor clearly stores all configuration parameters needed for the parallel workflow.


132-200: LGTM!

The relaxation workflow is well-structured with proper error handling, symmetry checks, and detailed logging. The use of optimizer.nsteps on line 171 is correct.


202-263: LGTM!

The force constant calculation logic correctly handles FC2/FC3 computation, imaginary frequency checks, and symmetry conditions. Error handling is comprehensive.


265-280: LGTM!

The thermal conductivity calculation is straightforward with appropriate error handling and result aggregation.


301-324: LGTM!

The result aggregation logic properly waits for all parallel jobs to complete before merging results, with appropriate error handling for file I/O.


337-353: LGTM!

The output directory structure and Submitit executor configuration are properly set up for parallel job submission.


394-395: LGTM!

The main guard correctly exposes the Typer CLI for command-line execution.

Comment on lines +70 to +74
def run(self, env_vars: None, job_number: int = 0) -> None:
# 设置 CUDA_VISIBLE_DEVICES 环境变量
if env_vars:
os.environ.update(env_vars)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix incorrect type hint and remove Chinese comment.

Two issues:

  1. The type hint env_vars: None is incorrect since the code checks if env_vars: on line 72. Should be dict[str, str] | None.
  2. The Chinese comment on line 71 should be removed or translated to English per the maintainer's feedback on encoding issues.

Apply this diff:

-    def run(self, env_vars: None, job_number: int = 0) -> None:
-        # 设置 CUDA_VISIBLE_DEVICES 环境变量
+    def run(self, env_vars: dict[str, str] | None = None, job_number: int = 0) -> None:
+        # Set CUDA_VISIBLE_DEVICES environment variable
         if env_vars:
             os.environ.update(env_vars)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def run(self, env_vars: None, job_number: int = 0) -> None:
# 设置 CUDA_VISIBLE_DEVICES 环境变量
if env_vars:
os.environ.update(env_vars)
def run(self, env_vars: dict[str, str] | None = None, job_number: int = 0) -> None:
# Set CUDA_VISIBLE_DEVICES environment variable
if env_vars:
os.environ.update(env_vars)
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa.py around lines 70 to 74, the
method signature currently uses the incorrect type hint env_vars: None and
contains a Chinese comment; change the signature to env_vars: dict[str, str] |
None and remove (or replace with an English comment) the Chinese comment so the
code correctly types optional environment variable mappings and avoids non-ASCII
comment issues, leaving the body that checks if env_vars and updates os.environ
unchanged.

save_dir = self.out_dir

# Log run parameters
timestamp = f"{datetime.now().astimezone():%Y-%m-%d %H:%M:%S}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Variable name shadows imported function.

The local variable timestamp on line 110 shadows the imported timestamp function from matbench_discovery (line 37). While not currently causing issues in this code, it reduces readability and could lead to bugs if the function is needed later.

Apply this diff:

-        timestamp = f"{datetime.now().astimezone():%Y-%m-%d %H:%M:%S}"
+        run_timestamp = f"{datetime.now().astimezone():%Y-%m-%d %H:%M:%S}"
         run_params = {
-            "timestamp": timestamp,
+            "timestamp": run_timestamp,

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa.py around line 110, the local
variable named `timestamp` shadows the imported `timestamp` function from
matbench_discovery; rename the local variable (for example to
`current_timestamp` or `ts`) and update its usages on this line to avoid
shadowing and preserve readability.

Comment on lines +326 to +336
def run_kappa(
checkpoint_path: Annotated[Path, typer.Option(help="路径,包含 checkpoint.pt")],
out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
identifier: Annotated[str, typer.Option(help="运行标识,用于文件夹命名")],
atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
seed: Annotated[int, typer.Option(help="随机种子")] = 42,
num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
) -> None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Replace Chinese help text with English and fix fullwidth characters.

The maintainer specifically flagged these lint errors (RUF001, RUF003) caused by fullwidth characters in Chinese text. All help strings must use English with standard ASCII punctuation.

Apply this diff:

 def run_kappa(
-    checkpoint_path: Annotated[Path, typer.Option(help="路径,包含 checkpoint.pt")],
+    checkpoint_path: Annotated[Path, typer.Option(help="Path containing checkpoint.pt")],
     out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
-    model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
-    identifier: Annotated[str, typer.Option(help="运行标识,用于文件夹命名")],
-    atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
-    seed: Annotated[int, typer.Option(help="随机种子")] = 42,
-    num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
-    debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
-    slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
+    model_name: Annotated[str, typer.Option(help="Subdirectory name for output")],
+    identifier: Annotated[str, typer.Option(help="Run identifier for folder naming")],
+    atom_disp: Annotated[float, typer.Option(help="Displacement distance for phonon calculations")] = 0.03,
+    seed: Annotated[int, typer.Option(help="Random seed")] = 42,
+    num_jobs: Annotated[int, typer.Option(help="Number of parallel jobs")] = 10,
+    debug: Annotated[bool, typer.Option(help="Debug mode, run only one job")] = False,
+    slurm_timeout: Annotated[int, typer.Option(help="SLURM timeout in hours")] = 80,
 ) -> None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def run_kappa(
checkpoint_path: Annotated[Path, typer.Option(help="路径,包含 checkpoint.pt")],
out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
identifier: Annotated[str, typer.Option(help="运行标识,用于文件夹命名")],
atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
seed: Annotated[int, typer.Option(help="随机种子")] = 42,
num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
) -> None:
def run_kappa(
checkpoint_path: Annotated[Path, typer.Option(help="Path containing checkpoint.pt")],
out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
model_name: Annotated[str, typer.Option(help="Subdirectory name for output")],
identifier: Annotated[str, typer.Option(help="Run identifier for folder naming")],
atom_disp: Annotated[float, typer.Option(help="Displacement distance for phonon calculations")] = 0.03,
seed: Annotated[int, typer.Option(help="Random seed")] = 42,
num_jobs: Annotated[int, typer.Option(help="Number of parallel jobs")] = 10,
debug: Annotated[bool, typer.Option(help="Debug mode, run only one job")] = False,
slurm_timeout: Annotated[int, typer.Option(help="SLURM timeout in hours")] = 80,
) -> None:
🧰 Tools
🪛 Ruff (0.14.2)

327-327: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


330-330: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa.py around lines 326-336, the
Annotated typer.Option help strings currently contain Chinese text and fullwidth
punctuation which triggered lint errors (RUF001, RUF003); replace each help
string with concise English equivalents using standard ASCII characters and
punctuation (for example "Path containing checkpoint.pt", "Output path to write
results files", "Subdirectory name for output", "Run identifier for naming
folders", "Displacement distance used to compute phonon properties", "Random
seed", "Number of parallel jobs", "Debug mode: run only one job", "Slurm timeout
(hours)"), and ensure all punctuation is ASCII (commas, parentheses, hyphens)
and no fullwidth characters remain.

Comment on lines +354 to +370
# 继续填充函数
if debug:
# 调试模式,只运行一个任务,使用GPU 0
env_vars = {"CUDA_VISIBLE_DEVICES": "0"}
job = executor.submit(
KappaSRMERunner(
seed=seed,
model_dir=checkpoint_path,
out_dir=out_path,
save_name=model_name,
identifier=identifier,
atom_disp=atom_disp,
num_jobs=1, # 设置为0处理前3个样本
).run,
env_vars=env_vars,
job_number=0,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove Chinese comment and fix fullwidth comma.

Line 356 contains a Chinese comment with fullwidth characters that must be fixed per the maintainer's lint feedback.

Apply this diff:

-    # 继续填充函数
+    # Submit jobs
     if debug:
-        # 调试模式,只运行一个任务,使用GPU 0
+        # Debug mode: run a single task using GPU 0
         env_vars = {"CUDA_VISIBLE_DEVICES": "0"}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 继续填充函数
if debug:
# 调试模式,只运行一个任务,使用GPU 0
env_vars = {"CUDA_VISIBLE_DEVICES": "0"}
job = executor.submit(
KappaSRMERunner(
seed=seed,
model_dir=checkpoint_path,
out_dir=out_path,
save_name=model_name,
identifier=identifier,
atom_disp=atom_disp,
num_jobs=1, # 设置为0处理前3个样本
).run,
env_vars=env_vars,
job_number=0,
)
# Submit jobs
if debug:
# Debug mode: run a single task using GPU 0
env_vars = {"CUDA_VISIBLE_DEVICES": "0"}
job = executor.submit(
KappaSRMERunner(
seed=seed,
model_dir=checkpoint_path,
out_dir=out_path,
save_name=model_name,
identifier=identifier,
atom_disp=atom_disp,
num_jobs=1, # 设置为0处理前3个样本
).run,
env_vars=env_vars,
job_number=0,
)
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa.py around lines 354 to 370, remove
the Chinese inline comment on line 356 and replace the fullwidth comma with an
ASCII comma in that line; ensure the remaining comment (if needed) is in English
and uses standard ASCII punctuation, e.g., change "设置为0处理前3个样本" to an English
comment or delete it and replace the fullwidth comma "," with "," so the file
passes linting.

Comment on lines +371 to +391
else:
# 正常模式,提交多个任务
jobs = []
with executor.batch():
for job_number in range(num_jobs):
# 为每个任务分配不同的 GPU
env_vars = {"CUDA_VISIBLE_DEVICES": str(job_number)}
job = executor.submit(
KappaSRMERunner(
seed=seed,
model_dir=checkpoint_path,
out_dir=out_path,
save_name=model_name,
identifier=identifier,
atom_disp=atom_disp,
num_jobs=num_jobs,
).run,
env_vars=env_vars,
job_number=job_number,
)
jobs.append(job)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove Chinese comment and fix GPU assignment logic.

Two issues:

  1. Line 372 contains a Chinese comment that should be in English.
  2. Line 377 assigns GPU by job_number directly, which will fail if num_jobs exceeds available GPUs. Should distribute jobs across available devices.

Apply this diff:

     else:
-        # 正常模式,提交多个任务
+        # Normal mode: submit multiple tasks
         jobs = []
         with executor.batch():
             for job_number in range(num_jobs):
-                # 为每个任务分配不同的 GPU
-                env_vars = {"CUDA_VISIBLE_DEVICES": str(job_number)}
+                # Assign GPU by round-robin across available devices
+                # Adjust num_gpus based on your cluster configuration
+                num_gpus = 8  # or pass as parameter
+                env_vars = {"CUDA_VISIBLE_DEVICES": str(job_number % num_gpus)}
                 job = executor.submit(

Alternatively, remove the CUDA_VISIBLE_DEVICES assignment entirely and let the cluster scheduler handle GPU allocation, which is more robust:

             for job_number in range(num_jobs):
-                # 为每个任务分配不同的 GPU
-                env_vars = {"CUDA_VISIBLE_DEVICES": str(job_number)}
+                env_vars = None
                 job = executor.submit(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
else:
# 正常模式,提交多个任务
jobs = []
with executor.batch():
for job_number in range(num_jobs):
# 为每个任务分配不同的 GPU
env_vars = {"CUDA_VISIBLE_DEVICES": str(job_number)}
job = executor.submit(
KappaSRMERunner(
seed=seed,
model_dir=checkpoint_path,
out_dir=out_path,
save_name=model_name,
identifier=identifier,
atom_disp=atom_disp,
num_jobs=num_jobs,
).run,
env_vars=env_vars,
job_number=job_number,
)
jobs.append(job)
else:
# Normal mode: submit multiple tasks
jobs = []
with executor.batch():
for job_number in range(num_jobs):
# Assign GPU by round-robin across available devices
# Adjust num_gpus based on your cluster configuration
num_gpus = 8 # or pass as parameter
env_vars = {"CUDA_VISIBLE_DEVICES": str(job_number % num_gpus)}
job = executor.submit(
KappaSRMERunner(
seed=seed,
model_dir=checkpoint_path,
out_dir=out_path,
save_name=model_name,
identifier=identifier,
atom_disp=atom_disp,
num_jobs=num_jobs,
).run,
env_vars=env_vars,
job_number=job_number,
)
jobs.append(job)
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa.py around lines 371 to 391, replace
the Chinese inline comment with an English one and fix GPU assignment: do not
set CUDA_VISIBLE_DEVICES to job_number directly (fails when num_jobs > available
GPUs); either remove the CUDA_VISIBLE_DEVICES env_var entirely to let the
scheduler handle allocation, or compute device_id = job_number % available_gpus
(detected via torch.cuda.device_count() if torch is available or by parsing
CUDA_VISIBLE_DEVICES env var as a fallback) and set
env_vars={"CUDA_VISIBLE_DEVICES": str(device_id)} before submitting each job.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (7)
models/eqV2_tracegrad/test_fairchem_kappa_debug.py (1)

289-289: Write gzipped outputs for .json.gz files.

This issue was already flagged in a previous review. pd.DataFrame.to_json() does not infer compression from the filename extension. You must explicitly specify compression="gzip" to actually compress the output.

Apply this diff to fix the compression issue:

-        df_kappa.reset_index().to_json(json_path)
+        df_kappa.reset_index().to_json(json_path, compression="gzip", orient="records")

And at line 315:

-                combined_df.to_json(save_dir / "kappa-103-FIRE.json.gz")
+                combined_df.to_json(
+                    save_dir / "kappa-103-FIRE.json.gz", compression="gzip", orient="records"
+                )

Also applies to: 315-315

models/eqV2_tracegrad/join_fairchem_preds.py (2)

60-70: Hard-coded baseline file path still present.

The baseline CSV is loaded from a hard-coded relative path without directory context. This assumes the script runs from a specific working directory and breaks reproducibility.

As noted in previous reviews, make this an optional CLI parameter with a default value or use a project-relative path.


97-106: Corrected entries must be written back to the DataFrame.

When MP2020 corrections are applied, the processed entries are validated but never replace the uncorrected entries in df_fairchem[computed_structure_entry_key]. This means formation energies computed later still use uncorrected values.

Apply the fix from the previous review:

     if apply_mp_corrections is True:
         # apply energy corrections
         processed = MaterialsProject2020Compatibility().process_entries(
             df_fairchem[computed_structure_entry_key], verbose=True, clean=True
         )
         if len(processed) != len(df_fairchem):
             raise ValueError(
                 f"not all entries processed: {len(processed)=} {len(df_fairchem)=}"
             )
+        # Replace uncorrected entries with corrected ones in the same order
+        df_fairchem[computed_structure_entry_key] = processed
models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py (4)

3-4: Remove hard-coded sys.path manipulation.

This hard-coded absolute path breaks reproducibility and was flagged in previous reviews. The maintainer recommended declaring script dependencies so others can run the code.

Remove these lines and ensure FAIRChem is installed in the environment or declared as a script dependency per the maintainer's recommendation.


33-36: Use DataFiles enum instead of hard-coded database path.

This hard-coded absolute path was flagged in previous reviews. The recommended solution was to use DataFiles.wbm_initial_atoms.path.

Apply the fix from the previous review to use the shared DataFiles enum.


54-58: Remove hard-coded path manipulation from worker processes.

This method replicates the same hard-coded sys.path issue from lines 3-4 for parallel workers.

Remove this method entirely once FAIRChem is properly installed in the environment.


261-261: Fix invalid Submitit parameter name.

slurm_gpus_per_task is not a valid Submitit parameter and will be ignored. This was flagged in previous reviews.

Apply this diff:

         cpus_per_task=1,
-        slurm_gpus_per_task=1,  # 每个任务使用一个 GPU
+        gpus_per_task=1,  # one GPU per task
         nodes=1,
🧹 Nitpick comments (1)
models/eqV2_tracegrad/join_fairchem_preds.py (1)

91-93: Remove unused noqa directives.

The # noqa:SLF001 comments are unnecessary since SLF001 is not enabled in your linter configuration.

Apply this diff:

-        cse._energy = pred_energy  # noqa:SLF001
+        cse._energy = pred_energy
         # cse._energy = pred_energy_ori  # added by fywang
-        cse._structure = mlip_struct  # noqa:SLF001
+        cse._structure = mlip_struct
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4462f9d and 47d471c.

📒 Files selected for processing (3)
  • models/eqV2_tracegrad/join_fairchem_preds.py (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_kappa_debug.py (1 hunks)
  • models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-18T14:36:56.526Z
Learnt from: teddykoker
Repo: janosh/matbench-discovery PR: 276
File: models/nequix/nequix-mp-1.yml:33-36
Timestamp: 2025-08-18T14:36:56.526Z
Learning: In matbench-discovery model YAML files, test_task values can use more detailed specifications like "IS2RE-SR" (Initial Structure to Relaxed Energy - Structure Relaxation) even though the core Task enum in matbench_discovery/enums.py only defines "IS2RE". This "-SR" suffix is widely used across 30+ model configurations to indicate the structure relaxation variant.

Applied to files:

  • models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py
🧬 Code graph analysis (3)
models/eqV2_tracegrad/test_fairchem_kappa_debug.py (3)
matbench_discovery/enums.py (4)
  • metadata (379-388)
  • DataFiles (503-604)
  • path (580-604)
  • base_dir (208-210)
matbench_discovery/phonons/__init__.py (1)
  • check_imaginary_freqs (16-42)
matbench_discovery/phonons/thermal_conductivity.py (4)
  • init_phono3py (116-158)
  • get_fc2_and_freqs (161-194)
  • calculate_fc3_set (74-113)
  • calculate_conductivity (218-280)
models/eqV2_tracegrad/join_fairchem_preds.py (3)
matbench_discovery/enums.py (3)
  • DataFiles (503-604)
  • MbdKey (46-122)
  • path (580-604)
matbench_discovery/data.py (1)
  • as_dict_handler (46-55)
matbench_discovery/energy.py (1)
  • get_e_form_per_atom (149-182)
models/eqV2_tracegrad/test_fairchem_tracegrad_discovery.py (3)
matbench_discovery/enums.py (2)
  • MbdKey (46-122)
  • Task (126-140)
matbench_discovery/data.py (1)
  • as_dict_handler (46-55)
matbench_discovery/plots.py (1)
  • wandb_scatter (703-729)
🪛 GitHub Actions: Lint
models/eqV2_tracegrad/join_fairchem_preds.py

[error] 87-87: RUF059 Unpacked variable pred_energy_ori is never used

🪛 Ruff (0.14.3)
models/eqV2_tracegrad/test_fairchem_kappa_debug.py

188-188: Do not catch blind exception: Exception

(BLE001)


251-251: Do not catch blind exception: Exception

(BLE001)


266-266: Do not catch blind exception: Exception

(BLE001)


310-310: Do not catch blind exception: Exception

(BLE001)


327-327: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


330-330: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


333-333: Unused function argument: num_jobs

(ARG001)


334-334: Unused function argument: debug

(ARG001)

models/eqV2_tracegrad/join_fairchem_preds.py

87-87: Unpacked variable pred_energy_ori is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


91-91: Unused noqa directive (non-enabled: SLF001)

Remove unused noqa directive

(RUF100)


93-93: Unused noqa directive (non-enabled: SLF001)

Remove unused noqa directive

(RUF100)


103-105: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: pytest (ubuntu-latest) / tests
  • GitHub Check: pytest (windows-latest) / tests
  • GitHub Check: scripts (scripts/evals/discovery.py)
🔇 Additional comments (5)
models/eqV2_tracegrad/test_fairchem_kappa_debug.py (5)

1-46: LGTM!

The imports, copyright header, and seed_everywhere utility are appropriate for the thermal conductivity workflow.


49-66: LGTM!

The constructor correctly initializes all instance variables.


91-94: LGTM!

The partitioning logic correctly splits work across jobs when num_jobs > 0, and falls back to processing the first 3 samples for local debugging when num_jobs <= 0.


188-196: Broad exception catching is acceptable here.

While static analysis flags broad Exception catching, this pattern is appropriate for a workflow orchestration script where you want to log errors and continue processing remaining structures rather than failing entirely.

Also applies to: 251-259, 266-274


364-365: LGTM!

Standard Typer CLI entry point pattern.

for row in tqdm(
df_fairchem.itertuples(), total=len(df_fairchem), desc="ML energies to CSEs"
):
mat_id, struct_dict, pred_energy, pred_energy_ori, *_ = row
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix unused variable triggering pipeline failure.

pred_energy_ori is unpacked but never used, causing the RUF059 lint failure.

Apply this diff:

-        mat_id, struct_dict, pred_energy, pred_energy_ori, *_ = row
+        mat_id, struct_dict, pred_energy, _pred_energy_ori, *_ = row
🧰 Tools
🪛 GitHub Actions: Lint

[error] 87-87: RUF059 Unpacked variable pred_energy_ori is never used

🪛 Ruff (0.14.3)

87-87: Unpacked variable pred_energy_ori is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/join_fairchem_preds.py around line 87, the tuple
unpacking includes pred_energy_ori which is never used and triggers a RUF059
lint failure; remove pred_energy_ori from the unpacking (e.g., change to
"mat_id, struct_dict, pred_energy, *_ = row") or replace it with a single
underscore placeholder if you prefer explicit unused slot (e.g., "mat_id,
struct_dict, pred_energy, _ , *_ = row"), ensuring no other code references
pred_energy_ori.

Comment on lines +124 to +136
out_path = Path(out_path)
out_path = str(out_path) # 将其重新转换为字符串

df_fairchem.select_dtypes("number").to_csv(out_path / f"{model_name}.csv.gz")
df_bad = df_fairchem[bad_mask].drop(
columns=[computed_structure_entry_key, struct_col]
)
df_bad[MbdKey.e_form_dft] = df_wbm[MbdKey.e_form_dft]
df_bad.to_csv(f"{out_path}-bad.csv")

df_fairchem.reset_index().to_json(
out_path / f"{model_name}.json.gz", default_handler=as_dict_handler
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical type error: remove string conversion that breaks Path operations.

Line 125 converts out_path to a string, but lines 127 and 135 attempt to use the / operator which only works with Path objects. This will cause a runtime TypeError.

Apply this diff to remove the problematic string conversion:

     out_path = Path(out_path)
-    out_path = str(out_path)    # 将其重新转换为字符串

-    df_fairchem.select_dtypes("number").to_csv(out_path / f"{model_name}.csv.gz")
+    df_fairchem.select_dtypes("number").to_csv(
+        out_path / f"{model_name}.csv.gz",
+        compression="gzip",
+    )
     df_bad = df_fairchem[bad_mask].drop(
         columns=[computed_structure_entry_key, struct_col]
     )
-    df_bad[MbdKey.e_form_dft] = df_wbm[MbdKey.e_form_dft]
-    df_bad.to_csv(f"{out_path}-bad.csv")
+    df_bad = df_bad.copy()
+    df_bad.loc[:, MbdKey.e_form_dft] = df_wbm.loc[df_bad.index, MbdKey.e_form_dft]
+    df_bad.to_csv(
+        out_path / f"{model_name}-bad.csv.gz",
+        compression="gzip",
+    )

     df_fairchem.reset_index().to_json(
-        out_path / f"{model_name}.json.gz", default_handler=as_dict_handler
+        out_path / f"{model_name}.json.gz",
+        compression="gzip",
+        default_handler=as_dict_handler,
     )
🤖 Prompt for AI Agents
In models/eqV2_tracegrad/join_fairchem_preds.py around lines 124-136, the code
converts out_path to a string which breaks subsequent Path operations using the
/ operator; remove the line that casts out_path to str so out_path remains a
Path, and ensure any functions that expect a string (if any) receive
str(out_path) explicitly at the call site instead of changing out_path itself.

Comment on lines +327 to +335
checkpoint_path: Annotated[Path, typer.Option(help="路径,包含 checkpoint.pt")],
out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
identifier: Annotated[str, typer.Option(help="运行标识,用于文件夹命名")],
atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
seed: Annotated[int, typer.Option(help="随机种子")] = 42,
num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix fullwidth commas in help strings.

The maintainer explicitly requested fixing UTF-8 encoding issues and fullwidth characters. These Chinese help strings contain fullwidth commas (,) that should be replaced with regular commas (,) to pass lint checks.

Apply this diff to replace fullwidth commas:

-    checkpoint_path: Annotated[Path, typer.Option(help="路径,包含 checkpoint.pt")],
+    checkpoint_path: Annotated[Path, typer.Option(help="路径, 包含 checkpoint.pt")],
     out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
     model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
-    identifier: Annotated[str, typer.Option(help="运行标识,用于文件夹命名")],
+    identifier: Annotated[str, typer.Option(help="运行标识, 用于文件夹命名")],
     atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
     seed: Annotated[int, typer.Option(help="随机种子")] = 42,
     num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
-    debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
+    debug: Annotated[bool, typer.Option(help="调试模式, 仅运行一个 job")] = False,
     slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
checkpoint_path: Annotated[Path, typer.Option(help="路径包含 checkpoint.pt")],
out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
identifier: Annotated[str, typer.Option(help="运行标识用于文件夹命名")],
atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
seed: Annotated[int, typer.Option(help="随机种子")] = 42,
num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
checkpoint_path: Annotated[Path, typer.Option(help="路径, 包含 checkpoint.pt")],
out_path: Annotated[Path, typer.Option(help="Output path to write results files")],
model_name: Annotated[str, typer.Option(help="输出目录的子目录名")],
identifier: Annotated[str, typer.Option(help="运行标识, 用于文件夹命名")],
atom_disp: Annotated[float, typer.Option(help="用于计算声子性质的位移距离")] = 0.03,
seed: Annotated[int, typer.Option(help="随机种子")] = 42,
num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
debug: Annotated[bool, typer.Option(help="调试模式, 仅运行一个 job")] = False,
slurm_timeout: Annotated[int, typer.Option(help="slurm 超时时间(小时)")] = 80,
🧰 Tools
🪛 Ruff (0.14.3)

327-327: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


330-330: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


333-333: Unused function argument: num_jobs

(ARG001)


334-334: Unused function argument: debug

(ARG001)

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa_debug.py around lines 327 to 335,
several Chinese help strings use fullwidth commas (,); replace each fullwidth
comma with a standard ASCII comma (,) in the typer.Option help text for
checkpoint_path, out_path, model_name, identifier, atom_disp, seed, num_jobs,
debug, and slurm_timeout so the file contains only regular commas and passes
UTF-8/lint checks.

Comment on lines +333 to +334
num_jobs: Annotated[int, typer.Option(help="并行任务数")] = 10,
debug: Annotated[bool, typer.Option(help="调试模式,仅运行一个 job")] = False,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove unused function parameters.

The num_jobs and debug parameters are declared but never used in the function body. Line 358 hardcodes num_jobs=1 instead of using the parameter value, and debug is never referenced.

Either use these parameters as intended or remove them from the function signature. If they should control the behavior, apply this diff:

     job = KappaSRMERunner(
         seed=seed,
         model_dir=checkpoint_path,
         out_dir=out_path,
         save_name=model_name,
         identifier=identifier,
         atom_disp=atom_disp,
-        num_jobs=1,  # 设置为0处理前3个样本
+        num_jobs=0 if debug else num_jobs,
     )

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.14.3)

333-333: Unused function argument: num_jobs

(ARG001)


334-334: Unused function argument: debug

(ARG001)

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa_debug.py around lines 333-334 and
reference to line 358, the function declares parameters num_jobs and debug but
never uses them (num_jobs is hardcoded to 1 at line 358 and debug is unused);
either remove them or wire them into behavior: replace the hardcoded num_jobs=1
with the num_jobs parameter and use the debug flag to override/force single-job
behavior when True (e.g., if debug: num_jobs = 1), or if you prefer to remove
them, delete both parameters from the signature and any related references;
ensure function behavior and any callers are updated accordingly.

save_name=model_name,
identifier=identifier,
atom_disp=atom_disp,
num_jobs=1, # 设置为0处理前3个样本
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify debug mode logic.

The comment states "设置为0处理前3个样本" (set to 0 to process first 3 samples), but the code sets num_jobs=1. Based on the logic at lines 91-94, num_jobs=0 triggers debug mode (first 3 samples), while num_jobs > 0 partitions across jobs.

The hardcoded value and comment are inconsistent with the declared debug parameter. See the suggestion in the previous comment to use the debug parameter properly.

🤖 Prompt for AI Agents
In models/eqV2_tracegrad/test_fairchem_kappa_debug.py around line 358, the
inline comment claims "设置为0处理前3个样本" but the code sets num_jobs=1, which
conflicts with the debug-mode logic at lines 91–94 where num_jobs==0 enables the
first-3-samples debug path; update the code so num_jobs is derived from the
debug parameter (e.g., if debug: num_jobs=0 else keep configured value) or
explicitly set num_jobs=0 when intending debug, and correct the comment to match
the actual behavior.

@CompRhys CompRhys changed the title feat:add eqV2_tracegrad to Matbench Discovery leaderboard Add eqV2_tracegrad Model Jan 14, 2026
@CompRhys CompRhys marked this pull request as draft January 16, 2026 21:28
@janosh janosh force-pushed the main branch 2 times, most recently from ff888ab to 93cc690 Compare February 3, 2026 15:13
@janosh janosh force-pushed the main branch 5 times, most recently from 76b10f0 to e069cc4 Compare March 4, 2026 15:36
@janosh janosh force-pushed the main branch 2 times, most recently from 441c1f6 to d2838a7 Compare March 13, 2026 21:13
@janosh janosh force-pushed the main branch 5 times, most recently from 11b8e76 to 1e4ecf1 Compare March 25, 2026 08:44
@janosh janosh force-pushed the main branch 2 times, most recently from 610666a to 0edb8a4 Compare April 14, 2026 15:03
@janosh janosh force-pushed the main branch 3 times, most recently from 4c72f3f to dc6b114 Compare April 30, 2026 00:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new model Model submission

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants