frost-gnn 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- frost_gnn-0.3.1/.env.example +5 -0
- frost_gnn-0.3.1/.github/scripts/build_pypi_release.py +128 -0
- frost_gnn-0.3.1/.github/scripts/update_coverage_badge.py +40 -0
- frost_gnn-0.3.1/.github/scripts/verify_pypi_release.py +95 -0
- frost_gnn-0.3.1/.github/workflows/coverage.yml +88 -0
- frost_gnn-0.3.1/.github/workflows/publish-pypi.yml +71 -0
- frost_gnn-0.3.1/.gitignore +109 -0
- frost_gnn-0.3.1/.python-version +1 -0
- frost_gnn-0.3.1/.vscode/settings.json +119 -0
- frost_gnn-0.3.1/CITATION.cff +38 -0
- frost_gnn-0.3.1/CMakeLists.txt +35 -0
- frost_gnn-0.3.1/LICENSE +21 -0
- frost_gnn-0.3.1/PKG-INFO +175 -0
- frost_gnn-0.3.1/README.md +133 -0
- frost_gnn-0.3.1/assets/frost-banner.png +0 -0
- frost_gnn-0.3.1/assets/frost-banner.prompt +9 -0
- frost_gnn-0.3.1/configs/config.yaml +65 -0
- frost_gnn-0.3.1/configs/model/apan.yaml +20 -0
- frost_gnn-0.3.1/configs/model/cawn.yaml +19 -0
- frost_gnn-0.3.1/configs/model/dygformer.yaml +25 -0
- frost_gnn-0.3.1/configs/model/graph_mixer.yaml +23 -0
- frost_gnn-0.3.1/configs/model/jodie.yaml +19 -0
- frost_gnn-0.3.1/configs/model/tcl.yaml +20 -0
- frost_gnn-0.3.1/configs/model/tgat.yaml +21 -0
- frost_gnn-0.3.1/configs/model/tgn.yaml +28 -0
- frost_gnn-0.3.1/configs/neg_sampler/rnd_dst_then_fixed.yaml +8 -0
- frost_gnn-0.3.1/configs/neg_sampler/rnd_dst_then_fixed_all.yaml +9 -0
- frost_gnn-0.3.1/configs/neg_sampler/rnd_dst_then_hist.yaml +7 -0
- frost_gnn-0.3.1/configs/neg_sampler/rnd_dst_then_post_train.yaml +8 -0
- frost_gnn-0.3.1/configs/neg_sampler/rnd_dst_then_random.yaml +10 -0
- frost_gnn-0.3.1/configs/neg_sampler/rnd_dst_then_tgb.yaml +11 -0
- frost_gnn-0.3.1/configs/neg_sampler/rnd_dst_then_tgb_wiki.yaml +4 -0
- frost_gnn-0.3.1/configs/ngh_sampler/recent.yaml +2 -0
- frost_gnn-0.3.1/configs/ngh_sampler/time_interval_aware.yaml +3 -0
- frost_gnn-0.3.1/configs/ngh_sampler/uniform.yaml +2 -0
- frost_gnn-0.3.1/configs/predict.yaml +13 -0
- frost_gnn-0.3.1/docs/model_training.md +229 -0
- frost_gnn-0.3.1/pyproject.toml +88 -0
- frost_gnn-0.3.1/run.py +7 -0
- frost_gnn-0.3.1/src/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/__main__.py +7 -0
- frost_gnn-0.3.1/src/frost/cli.py +94 -0
- frost_gnn-0.3.1/src/frost/data/__init__.py +35 -0
- frost_gnn-0.3.1/src/frost/data/catalog.py +86 -0
- frost_gnn-0.3.1/src/frost/data/cli.py +299 -0
- frost_gnn-0.3.1/src/frost/data/dgb.py +278 -0
- frost_gnn-0.3.1/src/frost/data/graph_policy.py +111 -0
- frost_gnn-0.3.1/src/frost/data/paths.py +167 -0
- frost_gnn-0.3.1/src/frost/data/preparation.py +690 -0
- frost_gnn-0.3.1/src/frost/data/sources.py +27 -0
- frost_gnn-0.3.1/src/frost/data/tgb.py +242 -0
- frost_gnn-0.3.1/src/frost/data/tgb_download.py +209 -0
- frost_gnn-0.3.1/src/frost/data/tgb_protocol.py +21 -0
- frost_gnn-0.3.1/src/frost/datatypes/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/datatypes/env.py +73 -0
- frost_gnn-0.3.1/src/frost/datatypes/graph.py +231 -0
- frost_gnn-0.3.1/src/frost/datatypes/mem_mail_box/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/datatypes/mem_mail_box/_data_ops.py +188 -0
- frost_gnn-0.3.1/src/frost/datatypes/mem_mail_box/box.py +64 -0
- frost_gnn-0.3.1/src/frost/datatypes/mem_mail_box/mail.py +47 -0
- frost_gnn-0.3.1/src/frost/datatypes/mem_mail_box/mem.py +53 -0
- frost_gnn-0.3.1/src/frost/datatypes/meta.py +56 -0
- frost_gnn-0.3.1/src/frost/datatypes/n_feat_nid.py +94 -0
- frost_gnn-0.3.1/src/frost/datatypes/plan.py +137 -0
- frost_gnn-0.3.1/src/frost/datatypes/result.py +28 -0
- frost_gnn-0.3.1/src/frost/datatypes/sampled_layout.py +124 -0
- frost_gnn-0.3.1/src/frost/datatypes/tasks.py +138 -0
- frost_gnn-0.3.1/src/frost/launch/__init__.py +1 -0
- frost_gnn-0.3.1/src/frost/launch/affinity.py +593 -0
- frost_gnn-0.3.1/src/frost/launch/config.py +93 -0
- frost_gnn-0.3.1/src/frost/launch/dispatch.py +62 -0
- frost_gnn-0.3.1/src/frost/launch/distributed.py +70 -0
- frost_gnn-0.3.1/src/frost/launch/factory.py +76 -0
- frost_gnn-0.3.1/src/frost/launch/gpu_topology.py +235 -0
- frost_gnn-0.3.1/src/frost/launch/plan.py +67 -0
- frost_gnn-0.3.1/src/frost/launch/single_gpu_resident.py +127 -0
- frost_gnn-0.3.1/src/frost/launch/storage.py +200 -0
- frost_gnn-0.3.1/src/frost/launcher.py +575 -0
- frost_gnn-0.3.1/src/frost/metrics.py +53 -0
- frost_gnn-0.3.1/src/frost/models/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/models/contracts.py +95 -0
- frost_gnn-0.3.1/src/frost/models/encoder/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/models/encoder/apan.py +42 -0
- frost_gnn-0.3.1/src/frost/models/encoder/cawn.py +495 -0
- frost_gnn-0.3.1/src/frost/models/encoder/dygformer.py +563 -0
- frost_gnn-0.3.1/src/frost/models/encoder/graph_mixer.py +328 -0
- frost_gnn-0.3.1/src/frost/models/encoder/jodie.py +104 -0
- frost_gnn-0.3.1/src/frost/models/encoder/tcl.py +292 -0
- frost_gnn-0.3.1/src/frost/models/encoder/tgat.py +305 -0
- frost_gnn-0.3.1/src/frost/models/encoder/tgn.py +172 -0
- frost_gnn-0.3.1/src/frost/models/header.py +44 -0
- frost_gnn-0.3.1/src/frost/models/mem_updater.py +266 -0
- frost_gnn-0.3.1/src/frost/models/modules/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/models/modules/temporal_graph_attention_layer.py +247 -0
- frost_gnn-0.3.1/src/frost/models/modules/time_encoder.py +37 -0
- frost_gnn-0.3.1/src/frost/models/outputs.py +79 -0
- frost_gnn-0.3.1/src/frost/models/protocols.py +25 -0
- frost_gnn-0.3.1/src/frost/models/recipes.py +183 -0
- frost_gnn-0.3.1/src/frost/models/temporal_link_model.py +67 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/__init__.py +25 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/_contextual.py +42 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/_utils.py +335 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/historical.py +151 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/inductive.py +167 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/precomputed.py +144 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/protocols.py +33 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/random.py +239 -0
- frost_gnn-0.3.1/src/frost/neg_sampler/tgb_eval.py +238 -0
- frost_gnn-0.3.1/src/frost/predict/__init__.py +1 -0
- frost_gnn-0.3.1/src/frost/predict/cli.py +215 -0
- frost_gnn-0.3.1/src/frost/predict/config.py +67 -0
- frost_gnn-0.3.1/src/frost/predict/data.py +179 -0
- frost_gnn-0.3.1/src/frost/predict/model.py +437 -0
- frost_gnn-0.3.1/src/frost/py.typed +0 -0
- frost_gnn-0.3.1/src/frost/runtime/_early_stopping.py +20 -0
- frost_gnn-0.3.1/src/frost/runtime/_thread_base.py +201 -0
- frost_gnn-0.3.1/src/frost/runtime/control_plane.py +273 -0
- frost_gnn-0.3.1/src/frost/runtime/dynamic_state_policy.py +98 -0
- frost_gnn-0.3.1/src/frost/runtime/host/__init__.py +9 -0
- frost_gnn-0.3.1/src/frost/runtime/host/_batch_balance.py +70 -0
- frost_gnn-0.3.1/src/frost/runtime/host/_config.py +52 -0
- frost_gnn-0.3.1/src/frost/runtime/host/_engine.py +821 -0
- frost_gnn-0.3.1/src/frost/runtime/host/_plan_router.py +338 -0
- frost_gnn-0.3.1/src/frost/runtime/host/_scatter.py +242 -0
- frost_gnn-0.3.1/src/frost/runtime/host/analyzer.py +303 -0
- frost_gnn-0.3.1/src/frost/runtime/host/p2p_planner/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/runtime/host/p2p_planner/_dynamic_planner.py +851 -0
- frost_gnn-0.3.1/src/frost/runtime/host/p2p_planner/_static_planner.py +237 -0
- frost_gnn-0.3.1/src/frost/runtime/host/protocols.py +59 -0
- frost_gnn-0.3.1/src/frost/runtime/host/types.py +39 -0
- frost_gnn-0.3.1/src/frost/runtime/protocols.py +11 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_batch_convergence.py +103 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_benchmark_observer.py +271 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_checkpoint.py +71 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_config.py +58 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_direct_writeback.py +182 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_direct_writeback_sync.py +56 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_dynamic_assembler.py +319 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_dynamic_state.py +698 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_engine.py +424 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_feature_staging.py +342 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_gpu_resident_writeback.py +162 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_h2d_credit.py +139 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_host_to_device.py +253 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_pipeline.py +308 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_receiver.py +185 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_split_benchmark_observer.py +152 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_state_coordinator.py +384 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_static_assembler.py +388 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_telemetry.py +95 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_tensor_lifetime.py +52 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/_trainer.py +458 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/mailbox_router.py +39 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/p2p_syncer/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/p2p_syncer/_p2p_comm.py +199 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/p2p_syncer/_task_handlers.py +313 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/p2p_syncer/_writer.py +335 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/p2p_syncer/utils/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/p2p_syncer/utils/_interaction_ops.py +79 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/p2p_syncer/utils/_p2p_task_maker.py +103 -0
- frost_gnn-0.3.1/src/frost/runtime/worker/types.py +35 -0
- frost_gnn-0.3.1/src/frost/sampling/ngh_sampler.py +285 -0
- frost_gnn-0.3.1/src/frost/sampling/protocols.py +26 -0
- frost_gnn-0.3.1/src/frost/seq_sampler/__init__.py +96 -0
- frost_gnn-0.3.1/src/frost/seq_sampler/_core.pyi +224 -0
- frost_gnn-0.3.1/src/frost/seq_sampler/planner_ownership.hpp +315 -0
- frost_gnn-0.3.1/src/frost/seq_sampler/sampler_base.h +212 -0
- frost_gnn-0.3.1/src/frost/seq_sampler/sampler_common.h +75 -0
- frost_gnn-0.3.1/src/frost/seq_sampler/sampler_seq.hpp +251 -0
- frost_gnn-0.3.1/src/frost/seq_sampler/seq_sampler_main.cpp +67 -0
- frost_gnn-0.3.1/src/frost/shm/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/shm/_core.py +401 -0
- frost_gnn-0.3.1/src/frost/shm/control_plane.py +161 -0
- frost_gnn-0.3.1/src/frost/shm/dataset_mgr.py +707 -0
- frost_gnn-0.3.1/src/frost/shm/dynamic_state_sync.py +374 -0
- frost_gnn-0.3.1/src/frost/shm/mem_mgr.py +238 -0
- frost_gnn-0.3.1/src/frost/shm/ring_buf.py +300 -0
- frost_gnn-0.3.1/src/frost/tpnet/LICENSE +21 -0
- frost_gnn-0.3.1/src/frost/tpnet/NOTICE.md +45 -0
- frost_gnn-0.3.1/src/frost/tpnet/__init__.py +2 -0
- frost_gnn-0.3.1/src/frost/tpnet/config.py +228 -0
- frost_gnn-0.3.1/src/frost/tpnet/data.py +326 -0
- frost_gnn-0.3.1/src/frost/tpnet/layers.py +107 -0
- frost_gnn-0.3.1/src/frost/tpnet/model.py +610 -0
- frost_gnn-0.3.1/src/frost/tpnet/sampling.py +747 -0
- frost_gnn-0.3.1/src/frost/tpnet/train.py +771 -0
- frost_gnn-0.3.1/src/frost/tpnet/training.py +63 -0
- frost_gnn-0.3.1/src/frost/utils/__init__.py +0 -0
- frost_gnn-0.3.1/src/frost/utils/_logger.py +34 -0
- frost_gnn-0.3.1/src/frost/utils/dtypes.py +35 -0
- frost_gnn-0.3.1/src/frost/utils/tensor_set.py +128 -0
- frost_gnn-0.3.1/src/frost/utils/utils.py +24 -0
- frost_gnn-0.3.1/tests/fixtures/tpnet/README.md +45 -0
- frost_gnn-0.3.1/tests/fixtures/tpnet/classic.json +1781 -0
- frost_gnn-0.3.1/tests/fixtures/tpnet/tgb.json +1934 -0
- frost_gnn-0.3.1/tests/test_access_plan_analyzer.py +168 -0
- frost_gnn-0.3.1/tests/test_affinity.py +389 -0
- frost_gnn-0.3.1/tests/test_architecture_boundaries.py +40 -0
- frost_gnn-0.3.1/tests/test_batch_balance.py +35 -0
- frost_gnn-0.3.1/tests/test_batch_convergence.py +36 -0
- frost_gnn-0.3.1/tests/test_control_plane.py +165 -0
- frost_gnn-0.3.1/tests/test_data_catalog.py +61 -0
- frost_gnn-0.3.1/tests/test_data_ops_determinism.py +196 -0
- frost_gnn-0.3.1/tests/test_data_paths.py +82 -0
- frost_gnn-0.3.1/tests/test_data_preparation.py +249 -0
- frost_gnn-0.3.1/tests/test_dataset_mgr.py +424 -0
- frost_gnn-0.3.1/tests/test_direct_dynamic_writeback.py +270 -0
- frost_gnn-0.3.1/tests/test_direct_writeback_sync.py +86 -0
- frost_gnn-0.3.1/tests/test_dispatch.py +48 -0
- frost_gnn-0.3.1/tests/test_dtypes.py +24 -0
- frost_gnn-0.3.1/tests/test_dynamic_planner_debug_dump.py +103 -0
- frost_gnn-0.3.1/tests/test_dynamic_planner_routing.py +242 -0
- frost_gnn-0.3.1/tests/test_dynamic_state_policy.py +93 -0
- frost_gnn-0.3.1/tests/test_dynamic_state_sync_runtime.py +368 -0
- frost_gnn-0.3.1/tests/test_early_stopping.py +17 -0
- frost_gnn-0.3.1/tests/test_encoders.py +513 -0
- frost_gnn-0.3.1/tests/test_eval_metric_selection.py +34 -0
- frost_gnn-0.3.1/tests/test_eval_sampler_reset.py +101 -0
- frost_gnn-0.3.1/tests/test_feature_staging.py +121 -0
- frost_gnn-0.3.1/tests/test_gpu_topology.py +89 -0
- frost_gnn-0.3.1/tests/test_graph.py +252 -0
- frost_gnn-0.3.1/tests/test_host_macro_metadata.py +100 -0
- frost_gnn-0.3.1/tests/test_host_protocols.py +6 -0
- frost_gnn-0.3.1/tests/test_host_sampler_inputs.py +78 -0
- frost_gnn-0.3.1/tests/test_interaction_ops.py +44 -0
- frost_gnn-0.3.1/tests/test_launcher.py +118 -0
- frost_gnn-0.3.1/tests/test_mailbox_router.py +27 -0
- frost_gnn-0.3.1/tests/test_mem_mgr.py +229 -0
- frost_gnn-0.3.1/tests/test_mem_updater.py +38 -0
- frost_gnn-0.3.1/tests/test_meta.py +44 -0
- frost_gnn-0.3.1/tests/test_model_configs.py +95 -0
- frost_gnn-0.3.1/tests/test_model_contracts.py +66 -0
- frost_gnn-0.3.1/tests/test_models.py +345 -0
- frost_gnn-0.3.1/tests/test_neg_sampler.py +315 -0
- frost_gnn-0.3.1/tests/test_ngh_sampler.py +214 -0
- frost_gnn-0.3.1/tests/test_p2p_comm.py +50 -0
- frost_gnn-0.3.1/tests/test_p2p_task_maker.py +82 -0
- frost_gnn-0.3.1/tests/test_plan.py +189 -0
- frost_gnn-0.3.1/tests/test_plan_router.py +80 -0
- frost_gnn-0.3.1/tests/test_prediction_cli.py +397 -0
- frost_gnn-0.3.1/tests/test_pypi_release.py +109 -0
- frost_gnn-0.3.1/tests/test_receiver_control_plane.py +53 -0
- frost_gnn-0.3.1/tests/test_repository_hygiene.py +138 -0
- frost_gnn-0.3.1/tests/test_result.py +34 -0
- frost_gnn-0.3.1/tests/test_ring_buf.py +134 -0
- frost_gnn-0.3.1/tests/test_run_stable_mode.py +47 -0
- frost_gnn-0.3.1/tests/test_sampled_layout.py +99 -0
- frost_gnn-0.3.1/tests/test_seq_sampler.py +178 -0
- frost_gnn-0.3.1/tests/test_shared_dynamic_state_sync.py +373 -0
- frost_gnn-0.3.1/tests/test_shm_numa.py +82 -0
- frost_gnn-0.3.1/tests/test_single_gpu_resident.py +71 -0
- frost_gnn-0.3.1/tests/test_state_coordinator.py +393 -0
- frost_gnn-0.3.1/tests/test_static_assembler.py +283 -0
- frost_gnn-0.3.1/tests/test_static_planner_timing.py +136 -0
- frost_gnn-0.3.1/tests/test_temporal_attention.py +256 -0
- frost_gnn-0.3.1/tests/test_tensor_lifetime.py +114 -0
- frost_gnn-0.3.1/tests/test_tensor_set.py +101 -0
- frost_gnn-0.3.1/tests/test_tgb_download.py +121 -0
- frost_gnn-0.3.1/tests/test_tgb_eval.py +204 -0
- frost_gnn-0.3.1/tests/test_tgb_sampler_config.py +165 -0
- frost_gnn-0.3.1/tests/test_tpnet_backend.py +428 -0
- frost_gnn-0.3.1/tests/test_tpnet_train.py +210 -0
- frost_gnn-0.3.1/tests/test_train_only_epoch.py +129 -0
- frost_gnn-0.3.1/tests/test_worker_benchmark_observer.py +76 -0
- frost_gnn-0.3.1/tests/test_worker_epoch_reset.py +217 -0
- frost_gnn-0.3.1/tests/test_worker_grad_context.py +61 -0
- frost_gnn-0.3.1/tests/test_worker_pipeline_init.py +57 -0
- frost_gnn-0.3.1/tests/test_worker_shm_sync.py +412 -0
- frost_gnn-0.3.1/tests/test_worker_split_benchmark_observer.py +119 -0
- frost_gnn-0.3.1/tests/test_writer_empty_writeback.py +96 -0
- frost_gnn-0.3.1/uv.lock +1285 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Build public distributions from a clean commit without a second README source."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import hashlib
|
|
7
|
+
import io
|
|
8
|
+
import json
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import re
|
|
11
|
+
import shutil
|
|
12
|
+
import subprocess
|
|
13
|
+
import tarfile
|
|
14
|
+
import tempfile
|
|
15
|
+
import tomllib
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
PUBLIC_INSTALL = """## 📦 Install
|
|
19
|
+
|
|
20
|
+
On Linux x86-64 (glibc 2.31+) with Python 3.12:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
python -m pip install frost_gnn
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The Python import is `frost`; the command is `frost`. The CSV trainer runs on CPU
|
|
27
|
+
unless you select a GPU. To use CPU-only PyTorch, install `torch==2.9.0` from
|
|
28
|
+
`https://download.pytorch.org/whl/cpu` before installing FROST. CUDA execution
|
|
29
|
+
requires a compatible NVIDIA driver.
|
|
30
|
+
|
|
31
|
+
If upgrading from the old FROST 0.1.0 distribution, first run
|
|
32
|
+
`python -m pip uninstall frost` to avoid overlapping package files.
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def public_readme(source: str) -> str:
|
|
38
|
+
"""Reuse user documentation, stripping repository-only artwork and links."""
|
|
39
|
+
intro = source.index("A multi-GPU framework")
|
|
40
|
+
result = "# FROST\n\n" + source[intro:]
|
|
41
|
+
result, count = re.subn(
|
|
42
|
+
r"^## 📦 Install\n.*?(?=^## )",
|
|
43
|
+
PUBLIC_INSTALL,
|
|
44
|
+
result,
|
|
45
|
+
count=1,
|
|
46
|
+
flags=re.MULTILINE | re.DOTALL,
|
|
47
|
+
)
|
|
48
|
+
if count != 1:
|
|
49
|
+
raise ValueError("Expected exactly one installation section in README.md.")
|
|
50
|
+
|
|
51
|
+
def link(match):
|
|
52
|
+
label, target = match.groups()
|
|
53
|
+
if "://" in target or target.startswith(("#", "mailto:")):
|
|
54
|
+
return match.group(0)
|
|
55
|
+
return f"{label} (`{target.split('#')[0]}` in the source distribution)"
|
|
56
|
+
|
|
57
|
+
result = re.sub(r"\[([^\[\]]+)\]\(([^\s)]+)\)", link, result)
|
|
58
|
+
if "github.com/dttutty/frost_dev" in result:
|
|
59
|
+
raise ValueError(
|
|
60
|
+
"The public package description still contains private repository links."
|
|
61
|
+
)
|
|
62
|
+
return result
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def build(output: Path) -> None:
|
|
66
|
+
repo = Path(__file__).resolve().parents[2]
|
|
67
|
+
subprocess.run(["git", "diff", "--exit-code", "HEAD", "--"], cwd=repo, check=True)
|
|
68
|
+
commit = subprocess.check_output(
|
|
69
|
+
["git", "rev-parse", "HEAD"], cwd=repo, text=True
|
|
70
|
+
).strip()
|
|
71
|
+
output = output.resolve()
|
|
72
|
+
output.mkdir(parents=True, exist_ok=False)
|
|
73
|
+
raw, assets = output / "raw", output / "assets"
|
|
74
|
+
assets.mkdir()
|
|
75
|
+
archive = subprocess.check_output(["git", "archive", "HEAD"], cwd=repo)
|
|
76
|
+
with tempfile.TemporaryDirectory(prefix="frost-pypi-source-") as temp:
|
|
77
|
+
stage = Path(temp)
|
|
78
|
+
with tarfile.open(fileobj=io.BytesIO(archive)) as source:
|
|
79
|
+
source.extractall(stage, filter="data")
|
|
80
|
+
readme = stage / "README.md"
|
|
81
|
+
readme.write_text(public_readme(readme.read_text()))
|
|
82
|
+
metadata = tomllib.loads((stage / "pyproject.toml").read_text())["project"]
|
|
83
|
+
subprocess.run(["uv", "build", "--out-dir", str(raw)], cwd=stage, check=True)
|
|
84
|
+
wheels, sdists = list(raw.glob("*.whl")), list(raw.glob("*.tar.gz"))
|
|
85
|
+
if len(wheels) != 1 or len(sdists) != 1:
|
|
86
|
+
raise ValueError("Expected one wheel and one source distribution.")
|
|
87
|
+
subprocess.run(
|
|
88
|
+
[
|
|
89
|
+
"uvx",
|
|
90
|
+
"--with",
|
|
91
|
+
"patchelf",
|
|
92
|
+
"auditwheel",
|
|
93
|
+
"repair",
|
|
94
|
+
"--plat",
|
|
95
|
+
"manylinux_2_31_x86_64",
|
|
96
|
+
"--wheel-dir",
|
|
97
|
+
str(assets),
|
|
98
|
+
str(wheels[0]),
|
|
99
|
+
],
|
|
100
|
+
check=True,
|
|
101
|
+
)
|
|
102
|
+
shutil.copy2(sdists[0], assets / sdists[0].name)
|
|
103
|
+
subprocess.run(
|
|
104
|
+
["uvx", "twine", "check", *map(str, sorted(assets.iterdir()))], check=True
|
|
105
|
+
)
|
|
106
|
+
info = {
|
|
107
|
+
"distribution": metadata["name"],
|
|
108
|
+
"version": metadata["version"],
|
|
109
|
+
"source_commit": commit,
|
|
110
|
+
"platform": "manylinux_2_31_x86_64",
|
|
111
|
+
"python": "3.12",
|
|
112
|
+
"readme": "Generated from README.md by build_pypi_release.py",
|
|
113
|
+
}
|
|
114
|
+
(assets / "BUILD_INFO.json").write_text(json.dumps(info, indent=2) + "\n")
|
|
115
|
+
manifest = "".join(
|
|
116
|
+
f"{hashlib.sha256(p.read_bytes()).hexdigest()} {p.name}\n"
|
|
117
|
+
for p in sorted(assets.iterdir())
|
|
118
|
+
)
|
|
119
|
+
(assets / "SHA256SUMS").write_text(manifest)
|
|
120
|
+
print(f"Release artifacts: {assets}")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
if __name__ == "__main__":
|
|
124
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
125
|
+
parser.add_argument(
|
|
126
|
+
"--output", type=Path, required=True, help="New build directory."
|
|
127
|
+
)
|
|
128
|
+
build(parser.parse_args().output)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Update the README badge from a real coverage.py JSON report."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import re
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
14
|
+
parser.add_argument("report", type=Path)
|
|
15
|
+
args = parser.parse_args()
|
|
16
|
+
totals = json.loads(args.report.read_text())["totals"]
|
|
17
|
+
total = int(totals["num_statements"])
|
|
18
|
+
covered = int(totals["covered_lines"])
|
|
19
|
+
if not 0 <= covered <= total or total == 0:
|
|
20
|
+
raise ValueError("Coverage report must contain a nonempty Python source measurement")
|
|
21
|
+
percent = 100 * covered / total
|
|
22
|
+
color = "brightgreen" if percent >= 80 else "yellowgreen" if percent >= 60 else "orange"
|
|
23
|
+
repository = os.environ.get("GITHUB_REPOSITORY", "dttutty/frost_dev")
|
|
24
|
+
badge = (
|
|
25
|
+
f"[]"
|
|
27
|
+
f"(https://github.com/{repository}/actions/workflows/coverage.yml)"
|
|
28
|
+
)
|
|
29
|
+
readme = Path(__file__).resolve().parents[2] / "README.md"
|
|
30
|
+
updated, count = re.subn(
|
|
31
|
+
r"^\[!\[CPU coverage\].*$", badge, readme.read_text(), flags=re.MULTILINE
|
|
32
|
+
)
|
|
33
|
+
if count != 1:
|
|
34
|
+
raise ValueError(f"Expected one CPU coverage badge in README, found {count}")
|
|
35
|
+
readme.write_text(updated)
|
|
36
|
+
print(f"CPU Python line coverage: {covered}/{total} = {percent:.1f}%")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
main()
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Verify private release assets before copying public distributions to dist/."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
from email.parser import BytesParser
|
|
7
|
+
import hashlib
|
|
8
|
+
import json
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import re
|
|
11
|
+
import shutil
|
|
12
|
+
import tarfile
|
|
13
|
+
import zipfile
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def verify(source: Path, output: Path, tag: str, commit: str) -> None:
|
|
17
|
+
if not re.fullmatch(r"v\d+\.\d+\.\d+(?:(?:a|b|rc)\d+)?", tag):
|
|
18
|
+
raise ValueError("Expected a version tag such as v0.3.1.")
|
|
19
|
+
version = tag[1:]
|
|
20
|
+
hashes = {}
|
|
21
|
+
for line in (source / "SHA256SUMS").read_text().splitlines():
|
|
22
|
+
digest, name = line.split(" ", 1)
|
|
23
|
+
if (
|
|
24
|
+
not re.fullmatch(r"[a-f0-9]{64}", digest)
|
|
25
|
+
or Path(name).name != name
|
|
26
|
+
or name in hashes
|
|
27
|
+
):
|
|
28
|
+
raise ValueError("Invalid checksum manifest entry.")
|
|
29
|
+
hashes[name] = digest
|
|
30
|
+
files = {p.name for p in source.iterdir() if p.is_file()} - {"SHA256SUMS"}
|
|
31
|
+
if files != hashes.keys():
|
|
32
|
+
raise ValueError("Checksum manifest must cover every release asset.")
|
|
33
|
+
for name, digest in hashes.items():
|
|
34
|
+
if hashlib.sha256((source / name).read_bytes()).hexdigest() != digest:
|
|
35
|
+
raise ValueError(f"Checksum mismatch: {name}")
|
|
36
|
+
info = json.loads((source / "BUILD_INFO.json").read_text())
|
|
37
|
+
if info["version"] != version or info["source_commit"] != commit:
|
|
38
|
+
raise ValueError("Release version or source commit does not match the tag.")
|
|
39
|
+
distributions = sorted(
|
|
40
|
+
p for p in source.iterdir() if p.suffix == ".whl" or p.name.endswith(".tar.gz")
|
|
41
|
+
)
|
|
42
|
+
if (
|
|
43
|
+
not any(p.suffix == ".whl" for p in distributions)
|
|
44
|
+
or sum(p.name.endswith(".tar.gz") for p in distributions) != 1
|
|
45
|
+
):
|
|
46
|
+
raise ValueError("Expected at least one wheel and one source distribution.")
|
|
47
|
+
for path in distributions:
|
|
48
|
+
if path.suffix == ".whl":
|
|
49
|
+
with zipfile.ZipFile(path) as wheel:
|
|
50
|
+
names = [
|
|
51
|
+
n for n in wheel.namelist() if n.endswith(".dist-info/METADATA")
|
|
52
|
+
]
|
|
53
|
+
if len(names) != 1:
|
|
54
|
+
raise ValueError("Expected one wheel metadata record.")
|
|
55
|
+
metadata = wheel.read(names[0])
|
|
56
|
+
else:
|
|
57
|
+
with tarfile.open(path) as sdist:
|
|
58
|
+
names = [
|
|
59
|
+
m
|
|
60
|
+
for m in sdist.getmembers()
|
|
61
|
+
if m.name.count("/") == 1 and m.name.endswith("/PKG-INFO")
|
|
62
|
+
]
|
|
63
|
+
if len(names) != 1:
|
|
64
|
+
raise ValueError("Expected one source metadata record.")
|
|
65
|
+
stream = sdist.extractfile(names[0])
|
|
66
|
+
if stream is None:
|
|
67
|
+
raise ValueError("Missing source metadata.")
|
|
68
|
+
metadata = stream.read()
|
|
69
|
+
record = BytesParser().parsebytes(metadata)
|
|
70
|
+
name = re.sub(r"[-_.]+", "-", record["Name"]).lower()
|
|
71
|
+
if name != "frost-gnn" or record["Version"] != version:
|
|
72
|
+
raise ValueError(f"Wrong distribution name/version: {path.name}")
|
|
73
|
+
if (
|
|
74
|
+
b"github.com/dttutty/frost_dev" in metadata
|
|
75
|
+
or b"not available yet" in metadata
|
|
76
|
+
):
|
|
77
|
+
raise ValueError(
|
|
78
|
+
"Distribution description is not ready for public installation."
|
|
79
|
+
)
|
|
80
|
+
output.mkdir(parents=True, exist_ok=False)
|
|
81
|
+
for path in distributions:
|
|
82
|
+
shutil.copy2(path, output / path.name)
|
|
83
|
+
print(
|
|
84
|
+
f"Verified {len(distributions)} frost-gnn {version} distributions from {commit}."
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
90
|
+
parser.add_argument("--source", type=Path, required=True)
|
|
91
|
+
parser.add_argument("--output", type=Path, required=True)
|
|
92
|
+
parser.add_argument("--tag", required=True)
|
|
93
|
+
parser.add_argument("--commit", required=True)
|
|
94
|
+
args = parser.parse_args()
|
|
95
|
+
verify(args.source, args.output, args.tag, args.commit)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: CPU coverage
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths-ignore: [README.md]
|
|
7
|
+
pull_request:
|
|
8
|
+
paths-ignore: [README.md]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: cpu-coverage-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
tests:
|
|
20
|
+
runs-on: ubuntu-22.04
|
|
21
|
+
timeout-minutes: 20
|
|
22
|
+
env:
|
|
23
|
+
CUDA_VISIBLE_DEVICES: ""
|
|
24
|
+
OMP_NUM_THREADS: "2"
|
|
25
|
+
MKL_NUM_THREADS: "2"
|
|
26
|
+
CMAKE_BUILD_PARALLEL_LEVEL: "2"
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
29
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.12"
|
|
32
|
+
enable-cache: true
|
|
33
|
+
- name: Install CPU test environment
|
|
34
|
+
run: |
|
|
35
|
+
uv venv --python 3.12
|
|
36
|
+
uv pip install torch==2.9.0 --index-url https://download.pytorch.org/whl/cpu
|
|
37
|
+
uv pip install --no-sources -e . pytest pytest-cov
|
|
38
|
+
- name: Measure Python line coverage
|
|
39
|
+
run: >-
|
|
40
|
+
uv run --no-sync pytest tests/ -q
|
|
41
|
+
--cov=src/frost --cov-report=term:skip-covered
|
|
42
|
+
--cov-report=json:coverage.json --cov-report=html:htmlcov
|
|
43
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
44
|
+
if: always()
|
|
45
|
+
with:
|
|
46
|
+
name: cpu-coverage
|
|
47
|
+
path: |
|
|
48
|
+
coverage.json
|
|
49
|
+
htmlcov/
|
|
50
|
+
retention-days: 14
|
|
51
|
+
if-no-files-found: warn
|
|
52
|
+
|
|
53
|
+
badge:
|
|
54
|
+
needs: tests
|
|
55
|
+
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
|
56
|
+
runs-on: ubuntu-22.04
|
|
57
|
+
timeout-minutes: 5
|
|
58
|
+
permissions:
|
|
59
|
+
contents: write
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
62
|
+
with:
|
|
63
|
+
ref: ${{ github.sha }}
|
|
64
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
65
|
+
with:
|
|
66
|
+
python-version: "3.12"
|
|
67
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
68
|
+
with:
|
|
69
|
+
name: cpu-coverage
|
|
70
|
+
path: ${{ runner.temp }}/cpu-coverage
|
|
71
|
+
- name: Update measured badge on the tested revision
|
|
72
|
+
env:
|
|
73
|
+
COVERAGE_REPORT: ${{ runner.temp }}/cpu-coverage/coverage.json
|
|
74
|
+
run: |
|
|
75
|
+
uv run --no-project --python 3.12 python .github/scripts/update_coverage_badge.py "$COVERAGE_REPORT"
|
|
76
|
+
if git diff --quiet -- README.md; then
|
|
77
|
+
exit 0
|
|
78
|
+
fi
|
|
79
|
+
git fetch origin main
|
|
80
|
+
if [ "$(git rev-parse origin/main)" != "$GITHUB_SHA" ]; then
|
|
81
|
+
echo "main advanced; a newer run will update the badge."
|
|
82
|
+
exit 0
|
|
83
|
+
fi
|
|
84
|
+
git config user.name 'github-actions[bot]'
|
|
85
|
+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
86
|
+
git add README.md
|
|
87
|
+
git commit -m 'docs: update CPU coverage badge'
|
|
88
|
+
git push origin HEAD:main
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
release_tag:
|
|
7
|
+
description: 'Verified GitHub Release tag, e.g. v0.3.1'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
dry_run:
|
|
11
|
+
description: 'Validate artifacts without publishing'
|
|
12
|
+
required: true
|
|
13
|
+
default: true
|
|
14
|
+
type: boolean
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
concurrency:
|
|
20
|
+
group: pypi-publication
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
prepare:
|
|
25
|
+
if: github.ref == 'refs/heads/main'
|
|
26
|
+
runs-on: ubuntu-22.04
|
|
27
|
+
timeout-minutes: 10
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
|
30
|
+
with:
|
|
31
|
+
fetch-depth: 0
|
|
32
|
+
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
33
|
+
with:
|
|
34
|
+
python-version: '3.12'
|
|
35
|
+
- name: Download and verify release assets
|
|
36
|
+
env:
|
|
37
|
+
GH_TOKEN: ${{ github.token }}
|
|
38
|
+
RELEASE_TAG: ${{ inputs.release_tag }}
|
|
39
|
+
run: |
|
|
40
|
+
[[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+((a|b|rc)[0-9]+)?$ ]]
|
|
41
|
+
gh release download "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --dir release-assets
|
|
42
|
+
release_commit=$(git rev-parse --verify "${RELEASE_TAG}^{commit}")
|
|
43
|
+
uv run --no-project --python 3.12 python .github/scripts/verify_pypi_release.py \
|
|
44
|
+
--source release-assets --output dist --tag "$RELEASE_TAG" --commit "$release_commit"
|
|
45
|
+
uvx twine check dist/*
|
|
46
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
47
|
+
with:
|
|
48
|
+
name: pypi-distributions
|
|
49
|
+
path: dist/
|
|
50
|
+
if-no-files-found: error
|
|
51
|
+
retention-days: 7
|
|
52
|
+
|
|
53
|
+
publish:
|
|
54
|
+
needs: prepare
|
|
55
|
+
if: github.ref == 'refs/heads/main' && !inputs.dry_run
|
|
56
|
+
runs-on: ubuntu-22.04
|
|
57
|
+
timeout-minutes: 10
|
|
58
|
+
environment:
|
|
59
|
+
name: pypi
|
|
60
|
+
url: https://pypi.org/project/frost-gnn/
|
|
61
|
+
permissions:
|
|
62
|
+
id-token: write
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
65
|
+
with:
|
|
66
|
+
name: pypi-distributions
|
|
67
|
+
path: dist/
|
|
68
|
+
- name: Publish verified distributions
|
|
69
|
+
uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # release/v1
|
|
70
|
+
with:
|
|
71
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Data & model artifacts
|
|
2
|
+
/models/
|
|
3
|
+
checkpoints/
|
|
4
|
+
data/
|
|
5
|
+
!src/frost/data/
|
|
6
|
+
!src/frost/data/*.py
|
|
7
|
+
datasets/
|
|
8
|
+
*.pt
|
|
9
|
+
*.pth
|
|
10
|
+
*.pkl
|
|
11
|
+
*.h5
|
|
12
|
+
*.ckpt
|
|
13
|
+
*.gz
|
|
14
|
+
*.zip
|
|
15
|
+
|
|
16
|
+
# Build
|
|
17
|
+
build/
|
|
18
|
+
develop-eggs/
|
|
19
|
+
dist/
|
|
20
|
+
downloads/
|
|
21
|
+
eggs/
|
|
22
|
+
.eggs/
|
|
23
|
+
lib/
|
|
24
|
+
lib64/
|
|
25
|
+
parts/
|
|
26
|
+
sdist/
|
|
27
|
+
var/
|
|
28
|
+
wheels/
|
|
29
|
+
*.egg-info/
|
|
30
|
+
.installed.cfg
|
|
31
|
+
*.egg
|
|
32
|
+
MANIFEST
|
|
33
|
+
*.so
|
|
34
|
+
|
|
35
|
+
# Python
|
|
36
|
+
__pycache__/
|
|
37
|
+
*.pyc
|
|
38
|
+
*.pyo
|
|
39
|
+
*.pyd
|
|
40
|
+
.Python
|
|
41
|
+
.venv/
|
|
42
|
+
env/
|
|
43
|
+
venv/
|
|
44
|
+
ENV/
|
|
45
|
+
.pytest_cache/
|
|
46
|
+
.mypy_cache/
|
|
47
|
+
|
|
48
|
+
# Logs & outputs
|
|
49
|
+
outputs/
|
|
50
|
+
logs/
|
|
51
|
+
artifacts/
|
|
52
|
+
/results/
|
|
53
|
+
*.log
|
|
54
|
+
|
|
55
|
+
# Experiment
|
|
56
|
+
experiment_logs*
|
|
57
|
+
result.json
|
|
58
|
+
_tgmem_out/
|
|
59
|
+
wandb/
|
|
60
|
+
.wandb/
|
|
61
|
+
tensorboard/
|
|
62
|
+
runs/
|
|
63
|
+
slurm/
|
|
64
|
+
|
|
65
|
+
# IDE & OS
|
|
66
|
+
.idea/
|
|
67
|
+
.claude/
|
|
68
|
+
*.swp
|
|
69
|
+
*.swo
|
|
70
|
+
*~
|
|
71
|
+
.DS_Store
|
|
72
|
+
.ipynb_checkpoints/
|
|
73
|
+
*.ipynb
|
|
74
|
+
|
|
75
|
+
# Paper repositories are maintained outside the code repository.
|
|
76
|
+
/overleaf/
|
|
77
|
+
/revision/
|
|
78
|
+
|
|
79
|
+
# Misc
|
|
80
|
+
.env.local
|
|
81
|
+
.trash/
|
|
82
|
+
.ruff_cache/
|
|
83
|
+
hydralance/
|
|
84
|
+
temp/
|
|
85
|
+
traces/
|
|
86
|
+
|
|
87
|
+
DATA/DGB*
|
|
88
|
+
DATA/.temp
|
|
89
|
+
DATA/TGL*
|
|
90
|
+
TGL_DATA/
|
|
91
|
+
/DATA
|
|
92
|
+
tmp/
|
|
93
|
+
*.tar
|
|
94
|
+
*.tar.gz
|
|
95
|
+
|
|
96
|
+
# Generated experiment artifacts
|
|
97
|
+
seed_sweeps/**
|
|
98
|
+
seed_sweeps_old/**
|
|
99
|
+
|
|
100
|
+
download_data.sh
|
|
101
|
+
*.txt
|
|
102
|
+
*.tsv
|
|
103
|
+
|
|
104
|
+
# Local reproduction tools and compatibility navigation (not part of the library).
|
|
105
|
+
/benchmarks
|
|
106
|
+
/docs/artifact_organization.md
|
|
107
|
+
/docs/camera_ready_sources.md
|
|
108
|
+
/.vscode/launch.json
|
|
109
|
+
/.vscode/tasks.json
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"git.detectSubmodules": true,
|
|
3
|
+
"git.detectSubmodulesLimit": 30,
|
|
4
|
+
"git.autoRepositoryDetection": true,
|
|
5
|
+
"scm.alwaysShowRepositories": true,
|
|
6
|
+
"scm.repositories.selectionMode": "multiple",
|
|
7
|
+
|
|
8
|
+
"ruff.nativeServer": "auto",
|
|
9
|
+
"python.languageServer": "Pylance",
|
|
10
|
+
"python.analysis.typeCheckingMode": "basic",
|
|
11
|
+
"python.analysis.diagnosticMode": "openFilesOnly",
|
|
12
|
+
"python.analysis.indexing": false,
|
|
13
|
+
"python.analysis.exclude": [
|
|
14
|
+
"**/.*",
|
|
15
|
+
"**/.git",
|
|
16
|
+
"**/__pycache__",
|
|
17
|
+
"**/.ruff_cache",
|
|
18
|
+
"**/node_modules",
|
|
19
|
+
"**/logs",
|
|
20
|
+
"**/checkpoints",
|
|
21
|
+
"**/wandb",
|
|
22
|
+
"**/data",
|
|
23
|
+
"**/outputs",
|
|
24
|
+
"**/build",
|
|
25
|
+
"**/dist",
|
|
26
|
+
"**/.venv",
|
|
27
|
+
"**/third_party"
|
|
28
|
+
],
|
|
29
|
+
"python.analysis.extraPaths": [
|
|
30
|
+
"./src"
|
|
31
|
+
],
|
|
32
|
+
"python.autoComplete.extraPaths": [
|
|
33
|
+
"./src"
|
|
34
|
+
],
|
|
35
|
+
|
|
36
|
+
"[python]": {
|
|
37
|
+
"editor.defaultFormatter": "charliermarsh.ruff",
|
|
38
|
+
"editor.formatOnSave": true,
|
|
39
|
+
"editor.codeActionsOnSave": {
|
|
40
|
+
"source.fixAll.ruff": "explicit",
|
|
41
|
+
"source.organizeImports.ruff": "explicit"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
"files.watcherExclude": {
|
|
46
|
+
"**/.git/**": true,
|
|
47
|
+
"**/__pycache__/**": true,
|
|
48
|
+
"**/.ruff_cache/**": true,
|
|
49
|
+
"**/node_modules/**": true,
|
|
50
|
+
"**/logs/**": true,
|
|
51
|
+
"**/checkpoints/**": true,
|
|
52
|
+
"**/wandb/**": true,
|
|
53
|
+
"**/data/**": true,
|
|
54
|
+
"**/outputs/**": true,
|
|
55
|
+
"**/build/**": true,
|
|
56
|
+
"**/dist/**": true,
|
|
57
|
+
"**/.venv/**": true,
|
|
58
|
+
"**/third_party/**": true
|
|
59
|
+
},
|
|
60
|
+
"files.exclude": {
|
|
61
|
+
"**/.git": true,
|
|
62
|
+
"**/.svn": true,
|
|
63
|
+
"**/.hg": true,
|
|
64
|
+
"**/.DS_Store": true,
|
|
65
|
+
"**/Thumbs.db": true,
|
|
66
|
+
"**/.venv": true,
|
|
67
|
+
"**/build": true,
|
|
68
|
+
"**/dist": true,
|
|
69
|
+
"hydralance": true
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
"cmake.configureSettings": {
|
|
73
|
+
"Python_EXECUTABLE": "${workspaceFolder}/.venv/bin/python",
|
|
74
|
+
"nanobind_DIR": "${workspaceFolder}/.venv/lib/python3.12/site-packages/nanobind/cmake"
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
|
|
78
|
+
"python-envs.defaultEnvManager": "ms-python.python:venv",
|
|
79
|
+
"python-envs.defaultPackageManager": "ms-python.python:pip",
|
|
80
|
+
|
|
81
|
+
"latex-workshop.latex.autoBuild.run": "onSave",
|
|
82
|
+
"latex-workshop.latex.recipe.default": "first",
|
|
83
|
+
"latex-workshop.latex.recipes": [
|
|
84
|
+
{
|
|
85
|
+
"name": "latexmk",
|
|
86
|
+
"tools": ["latexmk"]
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"latex-workshop.latex.tools": [
|
|
90
|
+
{
|
|
91
|
+
"name": "latexmk",
|
|
92
|
+
"command": "latexmk",
|
|
93
|
+
"args": [
|
|
94
|
+
"-pdf",
|
|
95
|
+
"-synctex=1",
|
|
96
|
+
"-interaction=nonstopmode",
|
|
97
|
+
"-file-line-error",
|
|
98
|
+
"-outdir=%OUTDIR%",
|
|
99
|
+
"%DOC%"
|
|
100
|
+
],
|
|
101
|
+
"env": {
|
|
102
|
+
"PATH": "${env:PATH}"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"latex-workshop.latex.clean.command": "latexmk",
|
|
107
|
+
|
|
108
|
+
"hydralance.excludePatterns": [
|
|
109
|
+
".venv/**",
|
|
110
|
+
"outputs/**",
|
|
111
|
+
"third_party/**"
|
|
112
|
+
],
|
|
113
|
+
"hydralance.hideHelperFolder": true,
|
|
114
|
+
|
|
115
|
+
"workbench.editorAssociations": {
|
|
116
|
+
"README.md": "vscode.markdown.preview.editor",
|
|
117
|
+
"**/README.md": "vscode.markdown.preview.editor"
|
|
118
|
+
}
|
|
119
|
+
}
|