tgraphx 1.2.0__tar.gz → 1.3.0__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.2.0/tgraphx.egg-info → tgraphx-1.3.0}/PKG-INFO +1 -1
- {tgraphx-1.2.0 → tgraphx-1.3.0}/pyproject.toml +1 -1
- tgraphx-1.3.0/tests/test_kg_hpo_v130.py +162 -0
- tgraphx-1.3.0/tests/test_kg_simple_v130.py +162 -0
- tgraphx-1.3.0/tests/test_notebooks_v130.py +126 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/__init__.py +1 -1
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/__init__.py +3 -1
- tgraphx-1.3.0/tgraphx/kg/hpo.py +395 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/models.py +83 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/high_level_api.py +42 -1
- {tgraphx-1.2.0 → tgraphx-1.3.0/tgraphx.egg-info}/PKG-INFO +1 -1
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/SOURCES.txt +4 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/LICENSE +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/README.md +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/setup.cfg +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_3d_support.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_algorithms.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_amp_compile.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_api_stability_labels.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_backward_compatibility.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_benchmark_smoke.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_calibration.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_chunking.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_cluster_gcn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_continuous_rl_algorithms.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dashboard.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dashboard_metadata.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_cache.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_docs_claims.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_download_mocked.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_registry.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_datasets_base.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_devices.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_distributed_compat.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_distributed_helpers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_distributed_smoke.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_documentation_claims.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_edge_features.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_edge_weight.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_estimators_v05.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_evolutionary_graph_optimization.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_experiments.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_explainability.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_factories.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_folder_datasets.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_gat_chunking.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_generation_rl_benchmarks_smoke.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_gnn_families.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_gradients.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_action_spaces.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_api.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_builders.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_generation_data_model.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_generation_metrics.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_rl_algorithms.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_rl_environments.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_transformer_v027.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_utils.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graphsaint.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_han_hgt_overfit.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hard_negative_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_batch.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_layers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_layers_v05.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_imports.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_io_graphml_v120.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_benchmarks_smoke.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_data_model.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_datasets.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_evaluation.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_gnn_integration.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_models.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_multimodal.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_negative_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_reasoning.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_rescal_v120.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_temporal.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_training.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_layers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_loader_feature_store_integration.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_loader_robustness_v110.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_loaders_feature_store.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_matching_coloring_flow.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_math.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_math_correctness_v110.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_math_invariants_v030.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_metrics.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_centrality.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_core.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_generators_spectral.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_graph_learning.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_paths_algorithms.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_structural.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_model_zoo.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_models.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_negative_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_neural_mining.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_neural_mining_batched.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_node2vec_kg_hypergraph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_ogb_tgb_wrappers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_packaging.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_performance_smoke.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_plotting.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_public_benchmarks.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_pyg_dgl_ogb_wrappers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_random_walk_sample.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_readme_links.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_release_validation_v030.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_reproducibility.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rl_baselines.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rl_callbacks_v120.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rl_high_level_api.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rollout_buffer.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sampling_loaders.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sparse_backend_select.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sparse_vgae_rgcn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_synthetic_datasets.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_temporal_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_temporal_v025.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_temporal_v05.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_tgn_tgat_overfit.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_time_encoding.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_tiny_overfit_v030.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_torchvision_wrappers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_tracking.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_training.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_transforms.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_user_friendly_llm_snippets.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_v024_features.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/__main__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/connectivity.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/structural.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/traversal.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/benchmarks/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/benchmarks/public.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/calibration.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/cluster_gcn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/dataloader.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/graph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/graph_utils.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/hetero_batch.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/hetero_graph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/temporal.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/temporal_batch.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/utils.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/__main__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/app.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/static/dashboard.css +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/static/dashboard.js +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/base.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/cache.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/converters.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/dgl_wrappers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/download.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/errors.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/folder.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/metadata.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/ogb_wrappers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/pyg_wrappers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/registry.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/synthetic.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/torchvision_wrappers.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/distributed.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/doctor.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_data.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_diagnostics.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_discovery.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_exceptions.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_models.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_results.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_workflows.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/base.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/early_stopping.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/label_propagation.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/node2vec.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/splits.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/vgae.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/algorithms.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/config.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/fitness.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/genome.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/high_level_api.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/metrics.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/multi_objective.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/operators.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/reports.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/selection.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/callbacks.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/checkpoints.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/cli.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/config.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/grid.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/runner.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/summarize.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/attention.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/edge_attribution.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/export.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/integrated_gradients.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/patch_heatmap.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/saliency.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/utils.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/feature_store.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/actions.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/classical.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/config.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/data_model.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/high_level_api.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/metrics.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/neural.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/projectors.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/reports.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/graph_builders.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/graphsaint.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/hetero_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/interop.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/io/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/io/graphml.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/data.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/datasets.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/evaluation.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/gnn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/losses.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/multimodal.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/projectors.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/reasoning.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/reports.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/temporal.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/trainer.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/_dim.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/_scatter.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/aggregator.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/appnp.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/attention_message.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/base.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/conv_message.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/factory.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/gat.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/gatv2.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/gin.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/graph_transformer.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/han.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/hetero.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/hetero_readout.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/hgt.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/pooling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/rgcn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/safe_pool.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/sage.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/temporal_readout.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/transformer_encodings.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/vector_gcn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/learned_graph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/loaders.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/classification.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/link_prediction.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/ogb.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/ranking.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/regression.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/reports.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/anomaly.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/api.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/centrality.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/communities.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/embeddings.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/frequent.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/generators.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/graph_io.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/graph_learning.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/hetero.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/hypergraph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/kernels.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/knowledge_graph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/label_prop.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/link_prediction.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/matching_coloring.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/motifs.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/neural.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/node2vec.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/paths.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/patterns.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/prototype.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/random_walk.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/reports.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/sequence_models.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/similarity.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/spectral.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/structural.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/structural_encodings.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/temporal.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/vgae.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/cnn_encoder.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/cnn_gnn_model.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/edge_predictor.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/factory.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/graph_classifier.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/hetero_models.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/model_zoo.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/node_classifier.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/pre_encoder.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/regressors.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/temporal_models.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/performance.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/graph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/layouts.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/mining.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/utils.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/reproducibility.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/actor_critic.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/base.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/baselines.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/continuous.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/dqn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/ppo.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/reinforce.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/replay_buffer.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/callbacks.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/config.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/base.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/coloring.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/continuous.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/generation.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/kg_reasoning.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/max_cut.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/navigation.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/shortest_path.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/vertex_cover.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/exploration/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/exploration/strategies.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/metrics.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/actor_critic.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/policy.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/projectors.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/qnetwork.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/value.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/reports.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sampling_loaders.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sampling_negative.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sparse.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/tgat.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/tgn.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/time_encoding.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal_sampling.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/tracking.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/training.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/__init__.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/compose.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/features.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/graph.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/patch.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/positional.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/splits.py +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/dependency_links.txt +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/entry_points.txt +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/requires.txt +0 -0
- {tgraphx-1.2.0 → tgraphx-1.3.0}/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
|
+
Version: 1.3.0
|
|
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.
|
|
8
|
+
version = "1.3.0"
|
|
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,162 @@
|
|
|
1
|
+
"""KG HPO (hyperparameter search) tests (v1.3)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
import torch
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def tiny_kg():
|
|
13
|
+
from tgraphx.kg import KnowledgeGraph
|
|
14
|
+
torch.manual_seed(0)
|
|
15
|
+
heads = torch.randint(0, 15, (60,))
|
|
16
|
+
rels = torch.randint(0, 2, (60,))
|
|
17
|
+
tails = torch.randint(0, 15, (60,))
|
|
18
|
+
return KnowledgeGraph.from_hrt(
|
|
19
|
+
heads, rels, tails, num_entities=15, num_relations=2
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TestKGHPOGrid:
|
|
24
|
+
def test_grid_search_covers_all_combos(self, tiny_kg):
|
|
25
|
+
from tgraphx.kg import run_kg_hpo
|
|
26
|
+
result = run_kg_hpo(
|
|
27
|
+
tiny_kg,
|
|
28
|
+
model_names=["TransE", "DistMult"],
|
|
29
|
+
search_space={"embedding_dim": [8, 16]},
|
|
30
|
+
strategy="grid",
|
|
31
|
+
epochs=1, seed=0,
|
|
32
|
+
)
|
|
33
|
+
# 2 models × 2 embedding dims = 4 trials
|
|
34
|
+
assert len(result.trials) == 4
|
|
35
|
+
|
|
36
|
+
def test_max_trials_cap(self, tiny_kg):
|
|
37
|
+
from tgraphx.kg import run_kg_hpo
|
|
38
|
+
result = run_kg_hpo(
|
|
39
|
+
tiny_kg,
|
|
40
|
+
model_names=["TransE", "DistMult", "SimplE"],
|
|
41
|
+
search_space={"embedding_dim": [8, 16]},
|
|
42
|
+
strategy="grid",
|
|
43
|
+
max_trials=3,
|
|
44
|
+
epochs=1, seed=0,
|
|
45
|
+
)
|
|
46
|
+
assert len(result.trials) <= 3
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TestKGHPORandom:
|
|
50
|
+
def test_random_strategy_deterministic(self, tiny_kg):
|
|
51
|
+
from tgraphx.kg import run_kg_hpo
|
|
52
|
+
r1 = run_kg_hpo(
|
|
53
|
+
tiny_kg,
|
|
54
|
+
model_names=["TransE", "DistMult"],
|
|
55
|
+
search_space={"embedding_dim": [8, 16]},
|
|
56
|
+
strategy="random",
|
|
57
|
+
max_trials=2,
|
|
58
|
+
epochs=1, seed=42,
|
|
59
|
+
)
|
|
60
|
+
r2 = run_kg_hpo(
|
|
61
|
+
tiny_kg,
|
|
62
|
+
model_names=["TransE", "DistMult"],
|
|
63
|
+
search_space={"embedding_dim": [8, 16]},
|
|
64
|
+
strategy="random",
|
|
65
|
+
max_trials=2,
|
|
66
|
+
epochs=1, seed=42,
|
|
67
|
+
)
|
|
68
|
+
# Same seed → same trial order → same best model.
|
|
69
|
+
assert r1.best_model_name == r2.best_model_name
|
|
70
|
+
assert r1.best_config == r2.best_config
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class TestKGHPOBestSelection:
|
|
74
|
+
def test_best_trial_has_highest_mrr(self, tiny_kg):
|
|
75
|
+
from tgraphx.kg import run_kg_hpo
|
|
76
|
+
result = run_kg_hpo(
|
|
77
|
+
tiny_kg,
|
|
78
|
+
model_names=["TransE", "DistMult"],
|
|
79
|
+
search_space={"embedding_dim": [8]},
|
|
80
|
+
metric="mrr",
|
|
81
|
+
epochs=2, seed=0,
|
|
82
|
+
)
|
|
83
|
+
ok_trials = [t for t in result.trials if t.status == "ok"]
|
|
84
|
+
best_mrr = max(t.metrics["mrr"] for t in ok_trials)
|
|
85
|
+
assert result.best_metrics["mrr"] == pytest.approx(best_mrr, abs=1e-6)
|
|
86
|
+
|
|
87
|
+
def test_mr_uses_lower_is_better(self, tiny_kg):
|
|
88
|
+
from tgraphx.kg import run_kg_hpo
|
|
89
|
+
result = run_kg_hpo(
|
|
90
|
+
tiny_kg,
|
|
91
|
+
model_names=["TransE", "DistMult"],
|
|
92
|
+
search_space={"embedding_dim": [8]},
|
|
93
|
+
metric="mr",
|
|
94
|
+
epochs=2, seed=0,
|
|
95
|
+
)
|
|
96
|
+
ok_trials = [t for t in result.trials if t.status == "ok"]
|
|
97
|
+
best_mr = min(t.metrics["mr"] for t in ok_trials)
|
|
98
|
+
assert result.best_metrics["mr"] == pytest.approx(best_mr, abs=1e-6)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class TestKGHPOResultObject:
|
|
102
|
+
def test_result_to_dict_json_serialisable(self, tiny_kg):
|
|
103
|
+
from tgraphx.kg import run_kg_hpo
|
|
104
|
+
result = run_kg_hpo(
|
|
105
|
+
tiny_kg,
|
|
106
|
+
model_names=["SimplE"],
|
|
107
|
+
search_space={"embedding_dim": [8]},
|
|
108
|
+
epochs=1, seed=0,
|
|
109
|
+
)
|
|
110
|
+
d = result.to_dict()
|
|
111
|
+
json.dumps(d) # Must not raise.
|
|
112
|
+
|
|
113
|
+
def test_summary_returns_string(self, tiny_kg):
|
|
114
|
+
from tgraphx.kg import run_kg_hpo
|
|
115
|
+
result = run_kg_hpo(
|
|
116
|
+
tiny_kg,
|
|
117
|
+
model_names=["TransE"],
|
|
118
|
+
search_space={"embedding_dim": [8]},
|
|
119
|
+
epochs=1, seed=0,
|
|
120
|
+
)
|
|
121
|
+
s = result.summary()
|
|
122
|
+
assert isinstance(s, str)
|
|
123
|
+
assert "best model" in s.lower() or "Best model" in s
|
|
124
|
+
|
|
125
|
+
def test_write_dashboard_artifacts(self, tmp_path, tiny_kg):
|
|
126
|
+
from tgraphx.kg import run_kg_hpo
|
|
127
|
+
result = run_kg_hpo(
|
|
128
|
+
tiny_kg,
|
|
129
|
+
model_names=["TransE"],
|
|
130
|
+
search_space={"embedding_dim": [8]},
|
|
131
|
+
epochs=1, seed=0,
|
|
132
|
+
dashboard_dir=str(tmp_path / "hpo_run"),
|
|
133
|
+
)
|
|
134
|
+
assert (tmp_path / "hpo_run" / "kg_hpo_results.json").exists()
|
|
135
|
+
assert (tmp_path / "hpo_run" / "metrics_summary.json").exists()
|
|
136
|
+
# JSON must be valid.
|
|
137
|
+
data = json.loads((tmp_path / "hpo_run" / "kg_hpo_results.json").read_text())
|
|
138
|
+
assert "best_model_name" in data
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class TestKGHPOErrors:
|
|
142
|
+
def test_unknown_metric(self, tiny_kg):
|
|
143
|
+
from tgraphx.kg import run_kg_hpo
|
|
144
|
+
with pytest.raises(ValueError, match="metric"):
|
|
145
|
+
run_kg_hpo(tiny_kg, metric="bad_metric", epochs=1)
|
|
146
|
+
|
|
147
|
+
def test_unknown_strategy(self, tiny_kg):
|
|
148
|
+
from tgraphx.kg import run_kg_hpo
|
|
149
|
+
with pytest.raises(ValueError, match="strategy"):
|
|
150
|
+
run_kg_hpo(tiny_kg, strategy="bayesian", epochs=1)
|
|
151
|
+
|
|
152
|
+
def test_unknown_model_name(self, tiny_kg):
|
|
153
|
+
from tgraphx.kg import run_kg_hpo
|
|
154
|
+
with pytest.raises(ValueError, match="model"):
|
|
155
|
+
run_kg_hpo(tiny_kg, model_names=["FakeModel"], epochs=1)
|
|
156
|
+
|
|
157
|
+
def test_no_mutation_of_input_kg(self, tiny_kg):
|
|
158
|
+
from tgraphx.kg import run_kg_hpo
|
|
159
|
+
original_triples = tiny_kg.triples.clone()
|
|
160
|
+
run_kg_hpo(tiny_kg, model_names=["TransE"],
|
|
161
|
+
search_space={"embedding_dim": [8]}, epochs=1, seed=0)
|
|
162
|
+
assert torch.equal(tiny_kg.triples, original_triples)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""SimplE KG model tests (v1.3).
|
|
2
|
+
|
|
3
|
+
SimplE: f(h, r, t) = 0.5 * (⟨h_head, r_fwd, t_tail⟩ + ⟨t_head, r_inv, h_tail⟩)
|
|
4
|
+
Reference: Kazemi & Poole, NeurIPS 2018.
|
|
5
|
+
|
|
6
|
+
These tests pin shape, hand-computed values, gradient flow, dtype/device,
|
|
7
|
+
asymmetry behavior, and a tiny overfit sanity check.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
import torch
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestSimplEShape:
|
|
16
|
+
def test_score_shape(self):
|
|
17
|
+
from tgraphx.kg import SimplEModel
|
|
18
|
+
model = SimplEModel(num_entities=6, num_relations=3, embedding_dim=4)
|
|
19
|
+
triples = torch.tensor([[0, 0, 1], [2, 1, 3], [4, 2, 5]], dtype=torch.long)
|
|
20
|
+
scores = model.score_triples(triples)
|
|
21
|
+
assert scores.shape == (3,)
|
|
22
|
+
assert scores.dtype == torch.float32
|
|
23
|
+
|
|
24
|
+
def test_forward_alias(self):
|
|
25
|
+
from tgraphx.kg import SimplEModel
|
|
26
|
+
model = SimplEModel(num_entities=4, num_relations=2, embedding_dim=4)
|
|
27
|
+
triples = torch.tensor([[0, 0, 1]], dtype=torch.long)
|
|
28
|
+
assert torch.equal(model.score_triples(triples), model.forward(triples))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TestSimplEHandComputed:
|
|
32
|
+
"""Hand-computed reference values for SimplE scoring.
|
|
33
|
+
|
|
34
|
+
Setup:
|
|
35
|
+
D=1 (scalar embeddings for easy hand-calculation).
|
|
36
|
+
entity_head = [h0=1, h1=2, h2=3, h3=4]
|
|
37
|
+
entity_tail = [t0=5, t1=6, t2=7, t3=8]
|
|
38
|
+
relation_fwd = [r0=2, r1=3]
|
|
39
|
+
relation_inv = [r0=4, r1=5]
|
|
40
|
+
|
|
41
|
+
Triple (h=0, r=0, t=1):
|
|
42
|
+
fwd = h_head[0] * r_fwd[0] * t_tail[1] = 1 * 2 * 6 = 12
|
|
43
|
+
inv = t_head[1] * r_inv[0] * h_tail[0] = 2 * 4 * 5 = 40
|
|
44
|
+
score = 0.5 * (12 + 40) = 26
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def _setup_d1_model(self):
|
|
48
|
+
from tgraphx.kg import SimplEModel
|
|
49
|
+
model = SimplEModel(num_entities=4, num_relations=2, embedding_dim=1)
|
|
50
|
+
with torch.no_grad():
|
|
51
|
+
# D=1 so each weight is a column vector [N, 1].
|
|
52
|
+
model.entity_head.weight.data = torch.tensor([[1.0], [2.0], [3.0], [4.0]])
|
|
53
|
+
model.entity_tail.weight.data = torch.tensor([[5.0], [6.0], [7.0], [8.0]])
|
|
54
|
+
model.relation_fwd.weight.data = torch.tensor([[2.0], [3.0]])
|
|
55
|
+
model.relation_inv.weight.data = torch.tensor([[4.0], [5.0]])
|
|
56
|
+
return model
|
|
57
|
+
|
|
58
|
+
def test_hand_computed_triple_0_0_1(self):
|
|
59
|
+
model = self._setup_d1_model()
|
|
60
|
+
triples = torch.tensor([[0, 0, 1]], dtype=torch.long)
|
|
61
|
+
score = model.score_triples(triples)
|
|
62
|
+
# fwd = 1 * 2 * 6 = 12; inv = 2 * 4 * 5 = 40; score = 0.5*(12+40) = 26
|
|
63
|
+
assert score.item() == pytest.approx(26.0, abs=1e-5)
|
|
64
|
+
|
|
65
|
+
def test_hand_computed_triple_1_1_2(self):
|
|
66
|
+
model = self._setup_d1_model()
|
|
67
|
+
triples = torch.tensor([[1, 1, 2]], dtype=torch.long)
|
|
68
|
+
score = model.score_triples(triples)
|
|
69
|
+
# fwd = entity_head[1] * r_fwd[1] * entity_tail[2]
|
|
70
|
+
# = 2 * 3 * 7 = 42
|
|
71
|
+
# inv = entity_head[2] * r_inv[1] * entity_tail[1]
|
|
72
|
+
# = 3 * 5 * 6 = 90
|
|
73
|
+
# score = 0.5 * (42 + 90) = 66
|
|
74
|
+
assert score.item() == pytest.approx(66.0, abs=1e-5)
|
|
75
|
+
|
|
76
|
+
def test_asymmetry(self):
|
|
77
|
+
"""f(h, r, t) ≠ f(t, r, h) in general — SimplE can model asymmetric relations."""
|
|
78
|
+
model = self._setup_d1_model()
|
|
79
|
+
fwd = model.score_triples(torch.tensor([[0, 0, 1]], dtype=torch.long))
|
|
80
|
+
rev = model.score_triples(torch.tensor([[1, 0, 0]], dtype=torch.long))
|
|
81
|
+
# fwd=26 as computed above; rev:
|
|
82
|
+
# fwd_term = entity_head[1] * r_fwd[0] * entity_tail[0] = 2*2*5 = 20
|
|
83
|
+
# inv_term = entity_head[0] * r_inv[0] * entity_tail[1] = 1*4*6 = 24
|
|
84
|
+
# rev_score = 0.5*(20+24) = 22 (different from 26)
|
|
85
|
+
assert rev.item() == pytest.approx(22.0, abs=1e-5)
|
|
86
|
+
assert not torch.allclose(fwd, rev)
|
|
87
|
+
|
|
88
|
+
def test_symmetric_when_head_eq_tail_embeddings(self):
|
|
89
|
+
"""If head_emb == tail_emb and fwd_rel == inv_rel, score is symmetric."""
|
|
90
|
+
from tgraphx.kg import SimplEModel
|
|
91
|
+
model = SimplEModel(num_entities=4, num_relations=2, embedding_dim=2)
|
|
92
|
+
with torch.no_grad():
|
|
93
|
+
same = torch.randn(4, 2)
|
|
94
|
+
model.entity_head.weight.data = same.clone()
|
|
95
|
+
model.entity_tail.weight.data = same.clone()
|
|
96
|
+
same_r = torch.randn(2, 2)
|
|
97
|
+
model.relation_fwd.weight.data = same_r.clone()
|
|
98
|
+
model.relation_inv.weight.data = same_r.clone()
|
|
99
|
+
# With identical embeddings, f(h,r,t) and f(t,r,h) should be equal.
|
|
100
|
+
fwd = model.score_triples(torch.tensor([[0, 0, 1]], dtype=torch.long))
|
|
101
|
+
rev = model.score_triples(torch.tensor([[1, 0, 0]], dtype=torch.long))
|
|
102
|
+
assert torch.allclose(fwd, rev, atol=1e-5)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class TestSimplEGradient:
|
|
106
|
+
def test_finite_nonzero_gradient(self):
|
|
107
|
+
from tgraphx.kg import SimplEModel
|
|
108
|
+
torch.manual_seed(0)
|
|
109
|
+
model = SimplEModel(num_entities=6, num_relations=3, embedding_dim=8)
|
|
110
|
+
triples = torch.tensor([[0, 0, 1], [2, 1, 3], [4, 2, 5]], dtype=torch.long)
|
|
111
|
+
scores = model.score_triples(triples)
|
|
112
|
+
scores.sum().backward()
|
|
113
|
+
for emb in [model.entity_head, model.entity_tail, model.relation_fwd, model.relation_inv]:
|
|
114
|
+
assert emb.weight.grad is not None
|
|
115
|
+
assert torch.isfinite(emb.weight.grad).all()
|
|
116
|
+
# Referenced entities/relations must have nonzero gradient.
|
|
117
|
+
assert model.entity_head.weight.grad[0].abs().sum() > 0
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class TestSimplEDeviceDtype:
|
|
121
|
+
def test_cpu_float32(self):
|
|
122
|
+
from tgraphx.kg import SimplEModel
|
|
123
|
+
model = SimplEModel(num_entities=4, num_relations=2, embedding_dim=4)
|
|
124
|
+
assert model.entity_head.weight.device.type == "cpu"
|
|
125
|
+
assert model.entity_head.weight.dtype == torch.float32
|
|
126
|
+
|
|
127
|
+
def test_cuda_smoke(self):
|
|
128
|
+
from tgraphx.kg import SimplEModel
|
|
129
|
+
if not torch.cuda.is_available():
|
|
130
|
+
pytest.skip("CUDA unavailable")
|
|
131
|
+
model = SimplEModel(num_entities=4, num_relations=2, embedding_dim=4).cuda()
|
|
132
|
+
triples = torch.tensor([[0, 0, 1]], device="cuda", dtype=torch.long)
|
|
133
|
+
scores = model.score_triples(triples)
|
|
134
|
+
assert scores.device.type == "cuda"
|
|
135
|
+
assert torch.isfinite(scores).all()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TestSimplETinyOverfit:
|
|
139
|
+
def test_margin_loss_decreases(self):
|
|
140
|
+
from tgraphx.kg import SimplEModel
|
|
141
|
+
torch.manual_seed(42)
|
|
142
|
+
model = SimplEModel(num_entities=6, num_relations=2, embedding_dim=8)
|
|
143
|
+
opt = torch.optim.Adam(model.parameters(), lr=1e-2)
|
|
144
|
+
pos = torch.tensor([[0, 0, 1], [2, 1, 3]], dtype=torch.long)
|
|
145
|
+
neg = torch.tensor([[0, 0, 3], [2, 1, 1]], dtype=torch.long)
|
|
146
|
+
initial = (1.0 + model.score_triples(neg) - model.score_triples(pos)).clamp(min=0).mean()
|
|
147
|
+
for _ in range(60):
|
|
148
|
+
loss = (1.0 + model.score_triples(neg) - model.score_triples(pos)).clamp(min=0).mean()
|
|
149
|
+
opt.zero_grad(); loss.backward(); opt.step()
|
|
150
|
+
final = (1.0 + model.score_triples(neg) - model.score_triples(pos)).clamp(min=0).mean()
|
|
151
|
+
assert final.item() <= initial.item() + 0.3, \
|
|
152
|
+
f"Loss did not decrease: {initial.item():.4f} -> {final.item():.4f}"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class TestSimplERegistry:
|
|
156
|
+
def test_in_list_kg_models(self):
|
|
157
|
+
from tgraphx.kg import list_kg_models
|
|
158
|
+
assert "SimplE" in list_kg_models()
|
|
159
|
+
|
|
160
|
+
def test_importable_from_kg(self):
|
|
161
|
+
from tgraphx.kg import SimplEModel
|
|
162
|
+
assert SimplEModel is not None
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Notebook structural tests (v1.3).
|
|
2
|
+
|
|
3
|
+
Validates every notebook/*.ipynb without executing code.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import re
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
NOTEBOOKS_DIR = Path("notebooks")
|
|
14
|
+
NOTEBOOKS = sorted(NOTEBOOKS_DIR.glob("*.ipynb"))
|
|
15
|
+
|
|
16
|
+
_PRIVATE_PATH_RE = re.compile(r"/home/[a-zA-Z0-9_]+|/Users/[a-zA-Z0-9_]+")
|
|
17
|
+
_SECRET_RE = re.compile(r"(?i)(token\s*=|password\s*=|api_key\s*=)['\"]?\w{8,}")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.fixture(scope="module")
|
|
21
|
+
def all_notebooks():
|
|
22
|
+
assert NOTEBOOKS_DIR.exists(), f"notebooks/ directory not found: {NOTEBOOKS_DIR}"
|
|
23
|
+
assert len(NOTEBOOKS) > 0, f"No .ipynb files in {NOTEBOOKS_DIR}"
|
|
24
|
+
return {nb.name: json.loads(nb.read_text(encoding="utf-8")) for nb in NOTEBOOKS}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TestNotebooksExist:
|
|
28
|
+
def test_notebooks_dir_exists(self):
|
|
29
|
+
assert NOTEBOOKS_DIR.exists()
|
|
30
|
+
|
|
31
|
+
def test_at_least_7_notebooks(self):
|
|
32
|
+
assert len(NOTEBOOKS) >= 7, f"Expected >=7 notebooks, found {len(NOTEBOOKS)}"
|
|
33
|
+
|
|
34
|
+
@pytest.mark.parametrize("name", [
|
|
35
|
+
"01_easy_tensor_node_classification.ipynb",
|
|
36
|
+
"02_image_patch_tensor_graph.ipynb",
|
|
37
|
+
"03_kg_completion_rescal_simple_hpo.ipynb",
|
|
38
|
+
"04_graph_generation_and_optimization.ipynb",
|
|
39
|
+
"05_graph_rl_coloring_and_navigation.ipynb",
|
|
40
|
+
"06_graph_io_roundtrip.ipynb",
|
|
41
|
+
"07_benchmark_suite_and_dashboard.ipynb",
|
|
42
|
+
])
|
|
43
|
+
def test_specific_notebook_exists(self, name):
|
|
44
|
+
assert (NOTEBOOKS_DIR / name).exists(), f"Missing: {name}"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TestNotebookStructure:
|
|
48
|
+
def test_all_valid_json(self, all_notebooks):
|
|
49
|
+
# Already validated by the fixture (json.loads raises on invalid).
|
|
50
|
+
assert len(all_notebooks) >= 7
|
|
51
|
+
|
|
52
|
+
def test_all_have_nbformat_4(self, all_notebooks):
|
|
53
|
+
for name, nb in all_notebooks.items():
|
|
54
|
+
assert nb.get("nbformat") == 4, f"{name}: expected nbformat 4"
|
|
55
|
+
|
|
56
|
+
def test_all_have_cells(self, all_notebooks):
|
|
57
|
+
for name, nb in all_notebooks.items():
|
|
58
|
+
assert len(nb.get("cells", [])) >= 3, f"{name}: too few cells"
|
|
59
|
+
|
|
60
|
+
def test_all_have_markdown_cells(self, all_notebooks):
|
|
61
|
+
for name, nb in all_notebooks.items():
|
|
62
|
+
md = [c for c in nb["cells"] if c.get("cell_type") == "markdown"]
|
|
63
|
+
assert len(md) >= 2, f"{name}: needs at least 2 Markdown cells"
|
|
64
|
+
|
|
65
|
+
def test_all_have_code_cells(self, all_notebooks):
|
|
66
|
+
for name, nb in all_notebooks.items():
|
|
67
|
+
code = [c for c in nb["cells"] if c.get("cell_type") == "code"]
|
|
68
|
+
assert len(code) >= 2, f"{name}: needs at least 2 code cells"
|
|
69
|
+
|
|
70
|
+
def test_first_cell_is_heading(self, all_notebooks):
|
|
71
|
+
for name, nb in all_notebooks.items():
|
|
72
|
+
first = nb["cells"][0]
|
|
73
|
+
src = "".join(first.get("source", []))
|
|
74
|
+
assert first["cell_type"] == "markdown", f"{name}: first cell must be Markdown"
|
|
75
|
+
assert src.strip().startswith("#"), f"{name}: first cell must start with #"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class TestNotebookContent:
|
|
79
|
+
def _all_source(self, nb: dict) -> str:
|
|
80
|
+
return "\n".join(
|
|
81
|
+
"".join(c.get("source", [])) for c in nb.get("cells", [])
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def test_references_tgraphx(self, all_notebooks):
|
|
85
|
+
for name, nb in all_notebooks.items():
|
|
86
|
+
assert "tgraphx" in self._all_source(nb).lower(), \
|
|
87
|
+
f"{name}: does not reference tgraphx"
|
|
88
|
+
|
|
89
|
+
def test_no_private_paths(self, all_notebooks):
|
|
90
|
+
for name, nb in all_notebooks.items():
|
|
91
|
+
matches = _PRIVATE_PATH_RE.findall(self._all_source(nb))
|
|
92
|
+
assert not matches, f"{name}: private path found: {matches}"
|
|
93
|
+
|
|
94
|
+
def test_no_secrets(self, all_notebooks):
|
|
95
|
+
for name, nb in all_notebooks.items():
|
|
96
|
+
matches = _SECRET_RE.findall(self._all_source(nb))
|
|
97
|
+
assert not matches, f"{name}: potential secret: {matches}"
|
|
98
|
+
|
|
99
|
+
def test_no_excessive_outputs(self, all_notebooks):
|
|
100
|
+
for name, nb in all_notebooks.items():
|
|
101
|
+
for i, cell in enumerate(nb.get("cells", [])):
|
|
102
|
+
for out in cell.get("outputs", []):
|
|
103
|
+
text = out.get("text", [])
|
|
104
|
+
n = len(text) if isinstance(text, list) else text.count("\n")
|
|
105
|
+
assert n < 200, f"{name} cell {i}: excessive output ({n} lines)"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class TestNotebookValidationTool:
|
|
109
|
+
def test_validate_notebooks_passes(self):
|
|
110
|
+
import subprocess, sys
|
|
111
|
+
result = subprocess.run(
|
|
112
|
+
[sys.executable, "tools/validate_notebooks.py"],
|
|
113
|
+
capture_output=True, text=True,
|
|
114
|
+
)
|
|
115
|
+
assert result.returncode == 0, \
|
|
116
|
+
f"tools/validate_notebooks.py failed:\n{result.stdout}\n{result.stderr}"
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class TestColabGallery:
|
|
120
|
+
def test_colab_gallery_doc_exists(self):
|
|
121
|
+
assert Path("docs/colab_gallery.md").exists()
|
|
122
|
+
|
|
123
|
+
def test_colab_gallery_lists_notebooks(self):
|
|
124
|
+
text = Path("docs/colab_gallery.md").read_text()
|
|
125
|
+
for i in range(1, 8):
|
|
126
|
+
assert f"0{i}_" in text, f"Notebook {i} not in colab_gallery.md"
|
|
@@ -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.
|
|
13
|
+
__version__ = "1.3.0"
|
|
14
14
|
|
|
15
15
|
# ── Core data structures ──────────────────────────────────────────────────────
|
|
16
16
|
from .core.graph import Graph, GraphBatch
|
|
@@ -46,7 +46,7 @@ from .sampling import (
|
|
|
46
46
|
TypedNegativeSampler,
|
|
47
47
|
)
|
|
48
48
|
from .evaluation import KGEvaluator, evaluate_filtered_ranking
|
|
49
|
-
from .models import TransEModel, DistMultModel, ComplExModel, RotatEModel, RESCALModel
|
|
49
|
+
from .models import TransEModel, DistMultModel, ComplExModel, RotatEModel, RESCALModel, SimplEModel
|
|
50
50
|
from .losses import MarginRankingLoss, BCEKGLoss, SoftplusKGLoss
|
|
51
51
|
from .trainer import KGTrainer, KGTrainingConfig
|
|
52
52
|
from .gnn import KGRGCNModel, kg_to_edge_index
|
|
@@ -58,6 +58,7 @@ from .datasets import (
|
|
|
58
58
|
MultimodalKG,
|
|
59
59
|
generate_synthetic_kg,
|
|
60
60
|
)
|
|
61
|
+
from .hpo import run_kg_hpo, KGSearchResult, KGTrialResult
|
|
61
62
|
from .reports import (
|
|
62
63
|
write_kg_summary,
|
|
63
64
|
write_kg_evaluation_report,
|
|
@@ -76,6 +77,7 @@ _KG_MODELS: dict = {
|
|
|
76
77
|
"ComplEx": "Complex-valued embeddings (Trouillon et al., 2016).",
|
|
77
78
|
"RotatE": "Rotation-based relational embedding (Sun et al., 2019).",
|
|
78
79
|
"RESCAL": "Bilinear matrix scoring h^T M_r t (Nickel et al., 2011).",
|
|
80
|
+
"SimplE": "Symmetric bilinear with inverse embeddings (Kazemi & Poole, 2018).",
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
|