tgraphx 1.3.3__tar.gz → 1.3.4__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.
- {tgraphx-1.3.3/tgraphx.egg-info → tgraphx-1.3.4}/PKG-INFO +1 -1
- {tgraphx-1.3.3 → tgraphx-1.3.4}/pyproject.toml +1 -1
- tgraphx-1.3.4/tests/test_colab_regressions_v134.py +417 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_notebooks_v130.py +24 -5
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/__init__.py +1 -1
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/benchmarks/__init__.py +10 -2
- tgraphx-1.3.4/tgraphx/benchmarks/run_v13_benchmark_suite.py +51 -0
- tgraphx-1.3.4/tgraphx/benchmarks/suite.py +290 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/__init__.py +113 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/kernels.py +34 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4/tgraphx.egg-info}/PKG-INFO +1 -1
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx.egg-info/SOURCES.txt +3 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/LICENSE +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/README.md +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/setup.cfg +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_3d_support.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_algorithms.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_amp_compile.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_api_stability_labels.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_backward_compatibility.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_benchmark_smoke.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_calibration.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_chunking.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_cluster_gcn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_continuous_rl_algorithms.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_dashboard.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_dashboard_metadata.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_dataset_cache.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_dataset_docs_claims.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_dataset_download_mocked.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_dataset_registry.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_datasets_base.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_devices.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_distributed_compat.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_distributed_helpers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_distributed_smoke.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_documentation_claims.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_edge_features.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_edge_weight.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_estimators_v05.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_evolutionary_graph_optimization.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_evolutionary_history_v132.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_experiments.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_explainability.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_factories.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_folder_datasets.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_gat_chunking.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_generation_rl_benchmarks_smoke.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_gnn_families.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_gradients.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_action_spaces.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_api.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_builders.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_generation_data_model.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_generation_metrics.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_rl_algorithms.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_rl_environments.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_transformer_v027.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graph_utils.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_graphsaint.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_han_hgt_overfit.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_hard_negative_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_hetero_batch.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_hetero_layers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_hetero_layers_v05.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_hetero_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_imports.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_io_graphml_v120.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_benchmarks_smoke.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_data_model.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_datasets.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_evaluation.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_feature_aware_v131.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_gnn_integration.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_hpo_v130.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_models.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_multimodal.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_negative_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_reasoning.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_rescal_v120.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_simple_v130.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_temporal.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_kg_training.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_layers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_loader_feature_store_integration.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_loader_robustness_v110.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_loaders_feature_store.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_matching_coloring_flow.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_math.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_math_correctness_v110.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_math_invariants_v030.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_metrics.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_mining_centrality.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_mining_core.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_mining_generators_spectral.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_mining_graph_learning.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_mining_paths_algorithms.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_mining_structural.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_model_zoo.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_models.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_negative_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_neural_mining.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_neural_mining_batched.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_node2vec_kg_hypergraph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_ogb_tgb_wrappers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_packaging.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_performance_smoke.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_plotting.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_public_benchmarks.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_pyg_dgl_ogb_wrappers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_random_walk_sample.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_readme_links.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_release_validation_v030.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_reproducibility.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_reproducibility_easy_v133.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_rl_baselines.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_rl_callbacks_v120.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_rl_high_level_api.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_rollout_buffer.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_sampling_loaders.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_sparse_backend_select.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_sparse_vgae_rgcn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_synthetic_datasets.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_temporal_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_temporal_v025.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_temporal_v05.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_tgn_tgat_overfit.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_time_encoding.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_tiny_overfit_v030.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_torchvision_wrappers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_tracking.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_training.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_transforms.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_user_friendly_llm_snippets.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tests/test_v024_features.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/__main__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/algorithms/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/algorithms/connectivity.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/algorithms/structural.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/algorithms/traversal.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/benchmarks/public.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/calibration.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/cluster_gcn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/dataloader.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/graph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/graph_utils.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/hetero_batch.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/hetero_graph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/temporal.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/temporal_batch.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/core/utils.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/dashboard/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/dashboard/__main__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/dashboard/app.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/dashboard/static/dashboard.css +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/dashboard/static/dashboard.js +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/base.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/cache.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/converters.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/dgl_wrappers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/download.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/errors.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/folder.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/metadata.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/ogb_wrappers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/pyg_wrappers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/registry.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/synthetic.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/datasets/torchvision_wrappers.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/distributed.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/doctor.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/_data.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/_diagnostics.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/_discovery.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/_exceptions.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/_models.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/_results.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/easy/_workflows.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/estimators/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/estimators/base.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/estimators/early_stopping.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/estimators/label_propagation.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/estimators/node2vec.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/estimators/splits.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/estimators/vgae.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/algorithms.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/config.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/fitness.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/genome.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/high_level_api.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/metrics.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/multi_objective.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/operators.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/reports.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/evolutionary/selection.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/callbacks.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/checkpoints.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/cli.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/config.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/grid.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/runner.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/experiments/summarize.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/attention.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/edge_attribution.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/export.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/integrated_gradients.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/patch_heatmap.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/saliency.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/explain/utils.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/feature_store.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/actions.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/classical.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/config.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/data_model.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/high_level_api.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/metrics.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/neural.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/projectors.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/generation/reports.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/graph_builders.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/graphsaint.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/hetero_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/interop.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/io/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/io/graphml.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/data.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/datasets.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/evaluation.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/gnn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/hpo.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/losses.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/models.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/multimodal.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/projectors.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/reasoning.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/reports.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/temporal.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/kg/trainer.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/_dim.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/_scatter.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/aggregator.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/appnp.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/attention_message.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/base.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/conv_message.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/factory.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/gat.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/gatv2.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/gin.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/graph_transformer.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/han.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/hetero.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/hetero_readout.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/hgt.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/pooling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/rgcn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/safe_pool.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/sage.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/temporal_readout.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/transformer_encodings.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/layers/vector_gcn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/learned_graph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/loaders.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/metrics/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/metrics/classification.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/metrics/link_prediction.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/metrics/ogb.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/metrics/ranking.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/metrics/regression.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/metrics/reports.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/anomaly.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/api.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/centrality.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/communities.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/embeddings.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/frequent.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/generators.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/graph_io.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/graph_learning.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/hetero.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/hypergraph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/knowledge_graph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/label_prop.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/link_prediction.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/matching_coloring.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/motifs.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/neural.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/node2vec.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/paths.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/patterns.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/prototype.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/random_walk.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/reports.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/sequence_models.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/similarity.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/spectral.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/structural.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/structural_encodings.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/temporal.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/mining/vgae.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/cnn_encoder.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/cnn_gnn_model.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/edge_predictor.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/factory.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/graph_classifier.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/hetero_models.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/model_zoo.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/node_classifier.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/pre_encoder.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/regressors.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/models/temporal_models.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/performance.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/plotting/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/plotting/graph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/plotting/layouts.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/plotting/mining.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/plotting/utils.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/reproducibility.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/actor_critic.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/base.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/baselines.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/continuous.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/dqn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/ppo.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/reinforce.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/algorithms/replay_buffer.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/callbacks.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/config.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/base.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/coloring.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/continuous.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/generation.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/kg_reasoning.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/max_cut.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/navigation.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/shortest_path.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/environments/vertex_cover.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/exploration/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/exploration/strategies.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/high_level_api.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/metrics.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/networks/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/networks/actor_critic.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/networks/policy.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/networks/projectors.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/networks/qnetwork.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/networks/value.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/rl/reports.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/sampling_loaders.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/sampling_negative.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/sparse.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/temporal/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/temporal/tgat.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/temporal/tgn.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/temporal/time_encoding.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/temporal_sampling.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/tracking.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/training.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/transforms/__init__.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/transforms/compose.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/transforms/features.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/transforms/graph.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/transforms/patch.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/transforms/positional.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx/transforms/splits.py +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx.egg-info/dependency_links.txt +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx.egg-info/entry_points.txt +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx.egg-info/requires.txt +0 -0
- {tgraphx-1.3.3 → tgraphx-1.3.4}/tgraphx.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tgraphx
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: Tensor-aware graph neural networks preserving spatial node feature layouts
|
|
5
5
|
Author-email: Arash Sajjadi <arash.sajjadi@usask.ca>
|
|
6
6
|
Maintainer-email: Arash Sajjadi <arash.sajjadi@usask.ca>
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tgraphx"
|
|
7
7
|
# Keep this in sync with tgraphx/__init__.py::__version__
|
|
8
|
-
version = "1.3.
|
|
8
|
+
version = "1.3.4"
|
|
9
9
|
description = "Tensor-aware graph neural networks preserving spatial node feature layouts"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"""Colab regression tests (v1.3.4).
|
|
2
|
+
|
|
3
|
+
One test per public snippet that was reported as broken from a Colab / PyPI install.
|
|
4
|
+
These tests pin the exact user-facing code patterns so they can never silently regress.
|
|
5
|
+
|
|
6
|
+
All tests must:
|
|
7
|
+
- Use only public APIs (importable after `pip install tgraphx`).
|
|
8
|
+
- Run on CPU without network.
|
|
9
|
+
- Be fast (< 30 seconds each).
|
|
10
|
+
- Fail with a clear message if the bug reappears.
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import math
|
|
16
|
+
import tempfile
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
import pytest
|
|
20
|
+
import torch
|
|
21
|
+
import torch.nn.functional as F
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# ── Bug A — Easy Mode deterministic reproducibility ───────────────────────────
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TestReproducibilityDetministicCPU:
|
|
28
|
+
"""Same seed + deterministic=True + device=cpu must give identical final loss."""
|
|
29
|
+
|
|
30
|
+
def _run_once(self):
|
|
31
|
+
import tgraphx as tgx
|
|
32
|
+
from tgraphx.reproducibility import set_seed
|
|
33
|
+
|
|
34
|
+
set_seed(42, deterministic=True)
|
|
35
|
+
data = tgx.easy.synthetic_tensor_node_classification(
|
|
36
|
+
num_nodes=64, node_shape=(4, 4, 4), num_classes=3,
|
|
37
|
+
num_edges=200, seed=42,
|
|
38
|
+
)
|
|
39
|
+
r = tgx.easy.train_node_classifier(
|
|
40
|
+
data, epochs=2, batch_size=16, fanouts=[5, 3],
|
|
41
|
+
verbose=False, seed=42, deterministic=True, device="cpu",
|
|
42
|
+
)
|
|
43
|
+
return r
|
|
44
|
+
|
|
45
|
+
def test_deterministic_cpu_exact_match(self):
|
|
46
|
+
r1 = self._run_once()
|
|
47
|
+
r2 = self._run_once()
|
|
48
|
+
diff = abs(r1.metrics["loss"] - r2.metrics["loss"])
|
|
49
|
+
assert diff < 1e-7, f"CPU deterministic loss diff too large: {diff:.2e}"
|
|
50
|
+
|
|
51
|
+
def test_synthetic_data_reproducible(self):
|
|
52
|
+
import tgraphx as tgx
|
|
53
|
+
d1 = tgx.easy.synthetic_tensor_node_classification(num_nodes=32, seed=7)
|
|
54
|
+
d2 = tgx.easy.synthetic_tensor_node_classification(num_nodes=32, seed=7)
|
|
55
|
+
assert torch.equal(d1.node_features, d2.node_features)
|
|
56
|
+
assert torch.equal(d1.edge_index, d2.edge_index)
|
|
57
|
+
|
|
58
|
+
def test_set_seed_returns_state_dict(self):
|
|
59
|
+
from tgraphx.reproducibility import set_seed
|
|
60
|
+
state = set_seed(42, deterministic=True)
|
|
61
|
+
assert isinstance(state, dict)
|
|
62
|
+
assert state["seed"] == 42
|
|
63
|
+
assert state["deterministic"] is True
|
|
64
|
+
assert "torch_version" in state
|
|
65
|
+
|
|
66
|
+
def test_train_stores_reproducibility_state(self):
|
|
67
|
+
r = self._run_once()
|
|
68
|
+
state = r.config.get("reproducibility_state", {})
|
|
69
|
+
assert state.get("seed") == 42
|
|
70
|
+
assert state.get("deterministic") is True
|
|
71
|
+
|
|
72
|
+
def test_exact_user_colab_snippet(self):
|
|
73
|
+
"""Exact snippet from the reproducibility bug report."""
|
|
74
|
+
import tgraphx as tgx
|
|
75
|
+
from tgraphx.reproducibility import set_seed
|
|
76
|
+
|
|
77
|
+
results = []
|
|
78
|
+
for _ in range(2):
|
|
79
|
+
set_seed(42, deterministic=True)
|
|
80
|
+
data = tgx.easy.synthetic_tensor_node_classification(
|
|
81
|
+
num_nodes=64, node_shape=(4, 4, 4), num_classes=3,
|
|
82
|
+
num_edges=200, seed=42,
|
|
83
|
+
)
|
|
84
|
+
r = tgx.easy.train_node_classifier(
|
|
85
|
+
data, epochs=2, batch_size=16, fanouts=[5, 3],
|
|
86
|
+
verbose=False, seed=42, deterministic=True, device="cpu",
|
|
87
|
+
)
|
|
88
|
+
results.append(r.metrics["loss"])
|
|
89
|
+
|
|
90
|
+
diff = abs(results[0] - results[1])
|
|
91
|
+
assert diff < 1e-7, diff
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# ── Bug B — NSGA-II composite_fitness misuse ──────────────────────────────────
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestNSGAIIOptimizer:
|
|
98
|
+
"""NSGAIIOptimizer requires a list of objectives, not composite_fitness directly."""
|
|
99
|
+
|
|
100
|
+
def _genome(self, seed=0):
|
|
101
|
+
from tgraphx.evolutionary import GraphGenome
|
|
102
|
+
torch.manual_seed(seed)
|
|
103
|
+
return GraphGenome(edge_index=torch.randint(0, 8, (2, 10)), num_nodes=8)
|
|
104
|
+
|
|
105
|
+
def test_nsga_with_list_of_objectives(self):
|
|
106
|
+
from tgraphx.evolutionary import NSGAIIOptimizer, EvolutionConfig, connectivity_fitness
|
|
107
|
+
objectives = [connectivity_fitness, connectivity_fitness]
|
|
108
|
+
config = EvolutionConfig(population_size=6, n_generations=4, seed=0)
|
|
109
|
+
pop = [self._genome(i) for i in range(6)]
|
|
110
|
+
r = NSGAIIOptimizer(config, objectives).optimize(pop)
|
|
111
|
+
assert r.pareto_front is not None
|
|
112
|
+
assert r.best_fitness >= 0.0
|
|
113
|
+
assert len(r.history) == 4
|
|
114
|
+
|
|
115
|
+
def test_ga_history_works(self):
|
|
116
|
+
from tgraphx.evolutionary import (
|
|
117
|
+
GeneticAlgorithmOptimizer, GeneticAlgorithmConfig, connectivity_fitness,
|
|
118
|
+
)
|
|
119
|
+
config = GeneticAlgorithmConfig(population_size=6, n_generations=5, seed=42)
|
|
120
|
+
pop = [self._genome(i) for i in range(6)]
|
|
121
|
+
r = GeneticAlgorithmOptimizer(config, connectivity_fitness).optimize(pop)
|
|
122
|
+
assert len(r.history) == 5
|
|
123
|
+
assert "generation" in r.history[0]
|
|
124
|
+
assert "best_fitness" in r.history[0]
|
|
125
|
+
|
|
126
|
+
def test_nsga_history_works(self):
|
|
127
|
+
from tgraphx.evolutionary import NSGAIIOptimizer, EvolutionConfig, connectivity_fitness
|
|
128
|
+
config = EvolutionConfig(population_size=4, n_generations=3, seed=0)
|
|
129
|
+
pop = [self._genome(i) for i in range(4)]
|
|
130
|
+
r = NSGAIIOptimizer(config, [connectivity_fitness]).optimize(pop)
|
|
131
|
+
assert len(r.history) == 3
|
|
132
|
+
|
|
133
|
+
def test_evolution_result_to_dict_json_serializable(self):
|
|
134
|
+
from tgraphx.evolutionary import (
|
|
135
|
+
GeneticAlgorithmOptimizer, GeneticAlgorithmConfig, connectivity_fitness,
|
|
136
|
+
)
|
|
137
|
+
config = GeneticAlgorithmConfig(population_size=4, n_generations=3, seed=0)
|
|
138
|
+
pop = [self._genome(i) for i in range(4)]
|
|
139
|
+
r = GeneticAlgorithmOptimizer(config, connectivity_fitness).optimize(pop)
|
|
140
|
+
d = r.to_dict()
|
|
141
|
+
json.dumps(d) # must not raise
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# ── Bug C — GraphML exception handling ───────────────────────────────────────
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class TestGraphMLExceptionHandling:
|
|
148
|
+
"""ValueError from write_graphml must be formatted with str(e), not e[:120]."""
|
|
149
|
+
|
|
150
|
+
def test_str_exception_not_slice(self, tmp_path):
|
|
151
|
+
"""Ensures str(e)[:120] works; e[:120] would TypeError in real code."""
|
|
152
|
+
from tgraphx import Graph
|
|
153
|
+
from tgraphx.io import write_graphml
|
|
154
|
+
|
|
155
|
+
x_spatial = torch.randn(4, 3, 8, 8)
|
|
156
|
+
g = Graph(node_features=x_spatial,
|
|
157
|
+
edge_index=torch.tensor([[0, 1], [1, 2]]))
|
|
158
|
+
|
|
159
|
+
caught = None
|
|
160
|
+
try:
|
|
161
|
+
write_graphml(g, tmp_path / "test.graphml", include_tensor_features=True)
|
|
162
|
+
except ValueError as e:
|
|
163
|
+
caught = e
|
|
164
|
+
msg = str(e)[:120] # must not raise TypeError
|
|
165
|
+
assert "multi-dimensional" in msg or "rank" in msg or "shape" in msg or "tensor" in msg.lower()
|
|
166
|
+
|
|
167
|
+
assert caught is not None, "Expected ValueError for [N,C,H,W] tensor features"
|
|
168
|
+
|
|
169
|
+
def test_1d_features_round_trip(self, tmp_path):
|
|
170
|
+
"""1-D node features must round-trip through GraphML without error."""
|
|
171
|
+
from tgraphx import Graph
|
|
172
|
+
from tgraphx.io import write_graphml, read_graphml
|
|
173
|
+
|
|
174
|
+
x = torch.tensor([[0.5], [1.0], [0.25]])
|
|
175
|
+
ei = torch.tensor([[0, 1], [1, 2]], dtype=torch.long)
|
|
176
|
+
g = Graph(node_features=x, edge_index=ei)
|
|
177
|
+
path = tmp_path / "roundtrip.graphml"
|
|
178
|
+
write_graphml(g, path, include_tensor_features=True)
|
|
179
|
+
g2 = read_graphml(path)
|
|
180
|
+
assert g2.num_nodes == 3
|
|
181
|
+
assert g2.num_edges == 2
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# ── Bug D — motif_profile / graph_summary import ─────────────────────────────
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class TestMiningImports:
|
|
188
|
+
def test_motif_profile_importable(self):
|
|
189
|
+
from tgraphx.mining import motif_profile
|
|
190
|
+
assert callable(motif_profile)
|
|
191
|
+
|
|
192
|
+
def test_graph_summary_importable(self):
|
|
193
|
+
from tgraphx.mining import graph_summary
|
|
194
|
+
assert callable(graph_summary)
|
|
195
|
+
|
|
196
|
+
def test_graph_summary_returns_expected_keys(self):
|
|
197
|
+
from tgraphx.mining import graph_summary
|
|
198
|
+
ei = torch.tensor([[0, 1, 2, 3, 4], [1, 2, 3, 4, 0]], dtype=torch.long)
|
|
199
|
+
s = graph_summary(ei, num_nodes=5)
|
|
200
|
+
for key in ("num_nodes", "num_edges"):
|
|
201
|
+
assert key in s, f"Missing key: {key}"
|
|
202
|
+
assert s["num_nodes"] == 5
|
|
203
|
+
|
|
204
|
+
def test_motif_profile_returns_dict_with_triangles(self):
|
|
205
|
+
from tgraphx.mining import motif_profile
|
|
206
|
+
# Triangle graph
|
|
207
|
+
ei = torch.tensor([[0, 1, 2, 1, 2, 0], [1, 2, 0, 0, 1, 2]], dtype=torch.long)
|
|
208
|
+
m = motif_profile(ei, num_nodes=3)
|
|
209
|
+
assert isinstance(m, dict)
|
|
210
|
+
# There is at least one triangle
|
|
211
|
+
assert m.get("triangles", 0) > 0 or "triangles" in str(m)
|
|
212
|
+
|
|
213
|
+
def test_degree_statistics_importable(self):
|
|
214
|
+
from tgraphx.mining import degree_statistics
|
|
215
|
+
ei = torch.tensor([[0, 0, 0, 0], [1, 2, 3, 4]], dtype=torch.long)
|
|
216
|
+
s = degree_statistics(ei, num_nodes=5)
|
|
217
|
+
assert isinstance(s, dict)
|
|
218
|
+
|
|
219
|
+
def test_notebook_20_smoke(self):
|
|
220
|
+
"""Exact imports from notebook 20."""
|
|
221
|
+
from tgraphx.mining import motif_profile, graph_summary
|
|
222
|
+
from tgraphx.mining.matching_coloring import enumerate_maximal_cliques
|
|
223
|
+
import torch
|
|
224
|
+
N = 5
|
|
225
|
+
ei = torch.tensor([[0, 1, 2, 3, 4], [1, 2, 3, 4, 0]], dtype=torch.long)
|
|
226
|
+
summary = graph_summary(ei, num_nodes=N)
|
|
227
|
+
assert isinstance(summary, dict)
|
|
228
|
+
profile = motif_profile(ei, num_nodes=N)
|
|
229
|
+
assert isinstance(profile, dict)
|
|
230
|
+
cliques = enumerate_maximal_cliques(ei, num_nodes=N, max_nodes=50)
|
|
231
|
+
assert isinstance(cliques, list)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
# ── Bug E — wl_subtree_kernel import ─────────────────────────────────────────
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class TestWLSubtreeKernel:
|
|
238
|
+
def test_importable(self):
|
|
239
|
+
from tgraphx.mining import wl_subtree_kernel
|
|
240
|
+
assert callable(wl_subtree_kernel)
|
|
241
|
+
|
|
242
|
+
def test_identical_graphs_higher_than_different(self):
|
|
243
|
+
from tgraphx.mining import wl_subtree_kernel
|
|
244
|
+
ei_ring5 = torch.tensor([[0, 1, 2, 3, 4], [1, 2, 3, 4, 0]], dtype=torch.long)
|
|
245
|
+
ei_ring3 = torch.tensor([[0, 1, 2], [1, 2, 0]], dtype=torch.long)
|
|
246
|
+
k_self = wl_subtree_kernel(ei_ring5, 5, ei_ring5, 5, h=3)
|
|
247
|
+
k_cross = wl_subtree_kernel(ei_ring5, 5, ei_ring3, 3, h=3)
|
|
248
|
+
assert k_self >= k_cross
|
|
249
|
+
|
|
250
|
+
def test_symmetry(self):
|
|
251
|
+
from tgraphx.mining import wl_subtree_kernel
|
|
252
|
+
ei_a = torch.tensor([[0, 1], [1, 2]], dtype=torch.long)
|
|
253
|
+
ei_b = torch.tensor([[0, 1, 2], [1, 2, 0]], dtype=torch.long)
|
|
254
|
+
k_ab = wl_subtree_kernel(ei_a, 3, ei_b, 3, h=2)
|
|
255
|
+
k_ba = wl_subtree_kernel(ei_b, 3, ei_a, 3, h=2)
|
|
256
|
+
assert abs(k_ab - k_ba) < 1e-6
|
|
257
|
+
|
|
258
|
+
def test_normalize_finite(self):
|
|
259
|
+
from tgraphx.mining import wl_subtree_kernel
|
|
260
|
+
ei = torch.tensor([[0, 1], [1, 0]], dtype=torch.long)
|
|
261
|
+
k = wl_subtree_kernel(ei, 2, ei, 2, h=2, normalize=True)
|
|
262
|
+
assert math.isfinite(k)
|
|
263
|
+
|
|
264
|
+
def test_notebook_21_smoke(self):
|
|
265
|
+
"""Exact import from notebook 21."""
|
|
266
|
+
from tgraphx.mining.kernels import wl_subtree_kernel
|
|
267
|
+
# Must work through kernels module too via alias; check from mining
|
|
268
|
+
from tgraphx.mining import wl_subtree_kernel as wl_sk
|
|
269
|
+
ei5 = torch.tensor([[0, 1, 2, 3, 4], [1, 2, 3, 4, 0]], dtype=torch.long)
|
|
270
|
+
ei3 = torch.tensor([[0, 1, 2], [1, 2, 0]], dtype=torch.long)
|
|
271
|
+
k = wl_sk(ei5, 5, ei3, 3, h=3)
|
|
272
|
+
assert k >= 0
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# ── Bug F — centrality_summary import ────────────────────────────────────────
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class TestCentralitySummary:
|
|
279
|
+
def test_importable(self):
|
|
280
|
+
from tgraphx.mining import centrality_summary
|
|
281
|
+
assert callable(centrality_summary)
|
|
282
|
+
|
|
283
|
+
def test_star_center_is_top(self):
|
|
284
|
+
from tgraphx.mining import centrality_summary
|
|
285
|
+
# Star graph: node 0 is center
|
|
286
|
+
star_ei = torch.tensor([[0, 0, 0, 0, 1, 2, 3, 4],
|
|
287
|
+
[1, 2, 3, 4, 0, 0, 0, 0]], dtype=torch.long)
|
|
288
|
+
cs = centrality_summary(star_ei, num_nodes=5)
|
|
289
|
+
assert cs["top_degree_nodes"][0][0] == 0, "Star center must be top"
|
|
290
|
+
|
|
291
|
+
def test_returns_expected_keys(self):
|
|
292
|
+
from tgraphx.mining import centrality_summary
|
|
293
|
+
ei = torch.tensor([[0, 1], [1, 2]], dtype=torch.long)
|
|
294
|
+
cs = centrality_summary(ei, num_nodes=3)
|
|
295
|
+
for key in ("num_nodes", "num_edges", "top_degree_nodes"):
|
|
296
|
+
assert key in cs
|
|
297
|
+
|
|
298
|
+
def test_notebook_22_smoke(self):
|
|
299
|
+
"""Exact imports from notebook 22."""
|
|
300
|
+
from tgraphx.mining import degree_statistics, centrality_summary
|
|
301
|
+
star_ei = torch.tensor([[0, 0, 0, 0, 1, 2, 3, 4],
|
|
302
|
+
[1, 2, 3, 4, 0, 0, 0, 0]], dtype=torch.long)
|
|
303
|
+
ds = degree_statistics(star_ei, num_nodes=5)
|
|
304
|
+
cs = centrality_summary(star_ei, num_nodes=5)
|
|
305
|
+
assert isinstance(ds, dict)
|
|
306
|
+
assert isinstance(cs, dict)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
# ── Bug G — Package-level benchmark suite ────────────────────────────────────
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
class TestPackageBenchmarkSuite:
|
|
313
|
+
def test_importable_from_package(self):
|
|
314
|
+
from tgraphx.benchmarks import run_v13_benchmark_suite
|
|
315
|
+
assert callable(run_v13_benchmark_suite)
|
|
316
|
+
|
|
317
|
+
def test_runs_outside_repo_tree(self, tmp_path):
|
|
318
|
+
"""Simulate running from outside repo: use package API, not repo script."""
|
|
319
|
+
import subprocess, sys
|
|
320
|
+
result = subprocess.run(
|
|
321
|
+
[sys.executable, "-c",
|
|
322
|
+
"from tgraphx.benchmarks import run_v13_benchmark_suite;"
|
|
323
|
+
"data = run_v13_benchmark_suite(small=True, return_dict=True);"
|
|
324
|
+
"assert 'benchmarks' in data;"
|
|
325
|
+
"print('OK', len(data['benchmarks']))"],
|
|
326
|
+
capture_output=True, text=True, timeout=120,
|
|
327
|
+
cwd=str(tmp_path), # Run from an empty temp dir, not repo
|
|
328
|
+
)
|
|
329
|
+
assert result.returncode == 0, f"STDERR: {result.stderr[:300]}"
|
|
330
|
+
assert "OK" in result.stdout
|
|
331
|
+
|
|
332
|
+
def test_returns_expected_schema(self):
|
|
333
|
+
from tgraphx.benchmarks import run_v13_benchmark_suite
|
|
334
|
+
data = run_v13_benchmark_suite(small=True, return_dict=True)
|
|
335
|
+
assert "suite" in data
|
|
336
|
+
assert "benchmarks" in data
|
|
337
|
+
for row in data["benchmarks"]:
|
|
338
|
+
assert "name" in row
|
|
339
|
+
assert "status" in row
|
|
340
|
+
|
|
341
|
+
def test_json_serializable(self):
|
|
342
|
+
from tgraphx.benchmarks import run_v13_benchmark_suite
|
|
343
|
+
data = run_v13_benchmark_suite(small=True, return_dict=True)
|
|
344
|
+
json.dumps(data, default=str)
|
|
345
|
+
|
|
346
|
+
def test_python_m_cli(self, tmp_path):
|
|
347
|
+
"""python -m tgraphx.benchmarks.run_v13_benchmark_suite --small --json"""
|
|
348
|
+
import subprocess, sys
|
|
349
|
+
out_file = tmp_path / "out.json"
|
|
350
|
+
result = subprocess.run(
|
|
351
|
+
[sys.executable, "-m", "tgraphx.benchmarks.run_v13_benchmark_suite",
|
|
352
|
+
"--small", "--out", str(out_file)],
|
|
353
|
+
capture_output=True, text=True, timeout=120,
|
|
354
|
+
cwd=str(tmp_path),
|
|
355
|
+
)
|
|
356
|
+
assert result.returncode == 0, f"STDERR: {result.stderr[:300]}"
|
|
357
|
+
data = json.loads(out_file.read_text())
|
|
358
|
+
assert "benchmarks" in data
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
# ── Bug H — ConvMessagePassing / NeighborLoader seed-node loss ───────────────
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
class TestConvMessagePassingNeighborLoader:
|
|
365
|
+
def test_seed_logits_no_unsafe_slicing(self):
|
|
366
|
+
"""batch.seed_logits(logits) must work; logits[:batch_size] would be wrong."""
|
|
367
|
+
from tgraphx import Graph, NeighborLoader
|
|
368
|
+
import torch.nn as nn
|
|
369
|
+
|
|
370
|
+
torch.manual_seed(0)
|
|
371
|
+
N, D = 50, 8
|
|
372
|
+
x = torch.randn(N, D)
|
|
373
|
+
ei = torch.randint(0, N, (2, 200))
|
|
374
|
+
y = torch.randint(0, 3, (N,))
|
|
375
|
+
g = Graph(node_features=x, edge_index=ei, y=y)
|
|
376
|
+
|
|
377
|
+
loader = NeighborLoader(g, fanouts=[5, 3], batch_size=8, seed=0)
|
|
378
|
+
linear = nn.Linear(D, 3)
|
|
379
|
+
opt = torch.optim.Adam(linear.parameters(), lr=1e-2)
|
|
380
|
+
|
|
381
|
+
batch = next(iter(loader))
|
|
382
|
+
logits = linear(batch.node_features)
|
|
383
|
+
# Correct API: batch.seed_logits extracts supervision-node logits.
|
|
384
|
+
seed_logits = batch.seed_logits(logits)
|
|
385
|
+
assert seed_logits.shape[0] == batch.batch_size
|
|
386
|
+
loss = F.cross_entropy(seed_logits, batch.seed_y)
|
|
387
|
+
loss.backward()
|
|
388
|
+
assert torch.isfinite(loss)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
# ── Bug I — Feature-aware KG regression (v1.3.1 fix) ────────────────────────
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
class TestFeatureAwareKGRegression:
|
|
395
|
+
def test_entity_features_score_triples(self):
|
|
396
|
+
"""Exact snippet from v1.3.1 Colab bug report."""
|
|
397
|
+
from tgraphx.kg import KnowledgeGraph, TransEModel
|
|
398
|
+
|
|
399
|
+
torch.manual_seed(0)
|
|
400
|
+
N_e, N_r, N_t = 10, 3, 30
|
|
401
|
+
heads = torch.randint(0, N_e, (N_t,))
|
|
402
|
+
rels = torch.randint(0, N_r, (N_t,))
|
|
403
|
+
tails = torch.randint(0, N_e, (N_t,))
|
|
404
|
+
entity_features = {"visual": torch.randn(N_e, 32)}
|
|
405
|
+
|
|
406
|
+
kg = KnowledgeGraph.from_hrt(
|
|
407
|
+
heads, rels, tails,
|
|
408
|
+
num_entities=N_e, num_relations=N_r,
|
|
409
|
+
entity_features=entity_features,
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
model = TransEModel(N_e, N_r, embedding_dim=16, entity_feature_dim=32)
|
|
413
|
+
triples = torch.stack([heads, rels, tails], dim=1)
|
|
414
|
+
scores = model.score_triples(triples, entity_features=kg.entity_features["visual"])
|
|
415
|
+
assert scores.shape == (N_t,)
|
|
416
|
+
scores.mean().backward()
|
|
417
|
+
assert model.entity_proj.proj.weight.grad is not None
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
"""Notebook structural tests (v1.3).
|
|
1
|
+
"""Notebook structural tests (v1.3 / v1.3.4+).
|
|
2
2
|
|
|
3
3
|
Validates every notebook/*.ipynb without executing code.
|
|
4
|
+
|
|
5
|
+
The notebooks/ folder is NOT tracked in git (it is gitignored as of v1.3.4).
|
|
6
|
+
These tests skip gracefully when notebooks/ is absent so that CI remains
|
|
7
|
+
green in the absence of locally generated notebooks.
|
|
8
|
+
|
|
9
|
+
To run locally, first generate notebooks with::
|
|
10
|
+
|
|
11
|
+
python tools/generate_notebooks.py
|
|
4
12
|
"""
|
|
5
13
|
from __future__ import annotations
|
|
6
14
|
|
|
@@ -11,26 +19,36 @@ from pathlib import Path
|
|
|
11
19
|
import pytest
|
|
12
20
|
|
|
13
21
|
NOTEBOOKS_DIR = Path("notebooks")
|
|
14
|
-
|
|
22
|
+
_NOTEBOOKS_PRESENT = NOTEBOOKS_DIR.exists() and bool(list(NOTEBOOKS_DIR.glob("*.ipynb")))
|
|
23
|
+
NOTEBOOKS = sorted(NOTEBOOKS_DIR.glob("*.ipynb")) if NOTEBOOKS_DIR.exists() else []
|
|
15
24
|
|
|
16
25
|
_PRIVATE_PATH_RE = re.compile(r"/home/[a-zA-Z0-9_]+|/Users/[a-zA-Z0-9_]+")
|
|
17
26
|
_SECRET_RE = re.compile(r"(?i)(token\s*=|password\s*=|api_key\s*=)['\"]?\w{8,}")
|
|
18
27
|
|
|
28
|
+
_skip_if_absent = pytest.mark.skipif(
|
|
29
|
+
not _NOTEBOOKS_PRESENT,
|
|
30
|
+
reason="notebooks/ not found locally; generate with: python tools/generate_notebooks.py",
|
|
31
|
+
)
|
|
32
|
+
|
|
19
33
|
|
|
20
34
|
@pytest.fixture(scope="module")
|
|
21
35
|
def all_notebooks():
|
|
22
|
-
|
|
23
|
-
|
|
36
|
+
if not _NOTEBOOKS_PRESENT:
|
|
37
|
+
pytest.skip("notebooks/ not found")
|
|
24
38
|
return {nb.name: json.loads(nb.read_text(encoding="utf-8")) for nb in NOTEBOOKS}
|
|
25
39
|
|
|
26
40
|
|
|
27
41
|
class TestNotebooksExist:
|
|
28
|
-
def
|
|
42
|
+
def test_notebooks_dir_exists_or_skips(self):
|
|
43
|
+
if not _NOTEBOOKS_PRESENT:
|
|
44
|
+
pytest.skip("notebooks/ not found locally — OK in CI without local notebooks")
|
|
29
45
|
assert NOTEBOOKS_DIR.exists()
|
|
30
46
|
|
|
47
|
+
@_skip_if_absent
|
|
31
48
|
def test_at_least_7_notebooks(self):
|
|
32
49
|
assert len(NOTEBOOKS) >= 7, f"Expected >=7 notebooks, found {len(NOTEBOOKS)}"
|
|
33
50
|
|
|
51
|
+
@_skip_if_absent
|
|
34
52
|
@pytest.mark.parametrize("name", [
|
|
35
53
|
"01_easy_tensor_node_classification.ipynb",
|
|
36
54
|
"02_image_patch_tensor_graph.ipynb",
|
|
@@ -106,6 +124,7 @@ class TestNotebookContent:
|
|
|
106
124
|
|
|
107
125
|
|
|
108
126
|
class TestNotebookValidationTool:
|
|
127
|
+
@_skip_if_absent
|
|
109
128
|
def test_validate_notebooks_passes(self):
|
|
110
129
|
import subprocess, sys
|
|
111
130
|
result = subprocess.run(
|
|
@@ -10,7 +10,7 @@ Common one-liner imports::
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
# Keep this in sync with [project].version in pyproject.toml.
|
|
13
|
-
__version__ = "1.3.
|
|
13
|
+
__version__ = "1.3.4"
|
|
14
14
|
|
|
15
15
|
# ── Core data structures ──────────────────────────────────────────────────────
|
|
16
16
|
from .core.graph import Graph, GraphBatch
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
"""Public-benchmark integration helpers (OGB / TGB).
|
|
1
|
+
"""Public-benchmark integration helpers (OGB / TGB) and v1.3 benchmark suite.
|
|
2
2
|
|
|
3
3
|
Optional, dependency-light evaluator wrappers around the official
|
|
4
4
|
benchmark packages. Importing this module never triggers a network
|
|
5
5
|
call; callers must explicitly download datasets via the upstream
|
|
6
6
|
packages.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
The v1.3 benchmark suite is available as a package-level function so it
|
|
9
|
+
can be called without a cloned repository::
|
|
10
|
+
|
|
11
|
+
from tgraphx.benchmarks import run_v13_benchmark_suite
|
|
12
|
+
results = run_v13_benchmark_suite(small=True, return_dict=True)
|
|
13
|
+
|
|
14
|
+
Stability: Beta (v0.5.0+). ``run_v13_benchmark_suite`` — Beta (v1.3.4+).
|
|
9
15
|
"""
|
|
10
16
|
from __future__ import annotations
|
|
11
17
|
|
|
@@ -15,10 +21,12 @@ from .public import (
|
|
|
15
21
|
OGBGraphEvaluator,
|
|
16
22
|
TGBLinkEvaluator,
|
|
17
23
|
)
|
|
24
|
+
from .suite import run_v13_benchmark_suite
|
|
18
25
|
|
|
19
26
|
__all__ = [
|
|
20
27
|
"OGBNodeEvaluator",
|
|
21
28
|
"OGBLinkEvaluator",
|
|
22
29
|
"OGBGraphEvaluator",
|
|
23
30
|
"TGBLinkEvaluator",
|
|
31
|
+
"run_v13_benchmark_suite",
|
|
24
32
|
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""CLI entry point for the v1.3 benchmark suite.
|
|
2
|
+
|
|
3
|
+
Usage::
|
|
4
|
+
|
|
5
|
+
python -m tgraphx.benchmarks.run_v13_benchmark_suite --small --json
|
|
6
|
+
python -m tgraphx.benchmarks.run_v13_benchmark_suite --out out.json
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import json
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
from .suite import run_v13_benchmark_suite
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main():
|
|
18
|
+
p = argparse.ArgumentParser(description="TGraphX v1.3 benchmark suite")
|
|
19
|
+
p.add_argument("--small", action="store_true", help="Use tiny configs (CI-safe).")
|
|
20
|
+
p.add_argument("--device", default="cpu", choices=["cpu", "cuda"])
|
|
21
|
+
p.add_argument("--seed", type=int, default=42)
|
|
22
|
+
p.add_argument("--out", default=None, help="JSON output path.")
|
|
23
|
+
p.add_argument("--repeat", type=int, default=1, help="Repeats per benchmark.")
|
|
24
|
+
p.add_argument("--json", action="store_true", help="Print JSON to stdout.")
|
|
25
|
+
args = p.parse_args()
|
|
26
|
+
|
|
27
|
+
data = run_v13_benchmark_suite(
|
|
28
|
+
small=args.small,
|
|
29
|
+
device=args.device,
|
|
30
|
+
seed=args.seed,
|
|
31
|
+
repeat=args.repeat,
|
|
32
|
+
return_dict=True,
|
|
33
|
+
out=args.out,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
if args.out:
|
|
37
|
+
print(f"[v13-suite] wrote {args.out}")
|
|
38
|
+
|
|
39
|
+
if args.json or args.out is None:
|
|
40
|
+
print(json.dumps(data, indent=2))
|
|
41
|
+
|
|
42
|
+
failed = [r for r in data["benchmarks"] if r["status"] == "failed"]
|
|
43
|
+
if failed:
|
|
44
|
+
print(f"\n[v13-suite] {len(failed)} failed:", file=sys.stderr)
|
|
45
|
+
for r in failed:
|
|
46
|
+
print(f" - {r['name']}: {r.get('error', '')}", file=sys.stderr)
|
|
47
|
+
sys.exit(1)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|