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.
Files changed (380) hide show
  1. {tgraphx-1.2.0/tgraphx.egg-info → tgraphx-1.3.0}/PKG-INFO +1 -1
  2. {tgraphx-1.2.0 → tgraphx-1.3.0}/pyproject.toml +1 -1
  3. tgraphx-1.3.0/tests/test_kg_hpo_v130.py +162 -0
  4. tgraphx-1.3.0/tests/test_kg_simple_v130.py +162 -0
  5. tgraphx-1.3.0/tests/test_notebooks_v130.py +126 -0
  6. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/__init__.py +1 -1
  7. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/__init__.py +3 -1
  8. tgraphx-1.3.0/tgraphx/kg/hpo.py +395 -0
  9. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/models.py +83 -0
  10. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/high_level_api.py +42 -1
  11. {tgraphx-1.2.0 → tgraphx-1.3.0/tgraphx.egg-info}/PKG-INFO +1 -1
  12. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/SOURCES.txt +4 -0
  13. {tgraphx-1.2.0 → tgraphx-1.3.0}/LICENSE +0 -0
  14. {tgraphx-1.2.0 → tgraphx-1.3.0}/README.md +0 -0
  15. {tgraphx-1.2.0 → tgraphx-1.3.0}/setup.cfg +0 -0
  16. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_3d_support.py +0 -0
  17. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_algorithms.py +0 -0
  18. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_amp_compile.py +0 -0
  19. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_api_stability_labels.py +0 -0
  20. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_backward_compatibility.py +0 -0
  21. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_benchmark_smoke.py +0 -0
  22. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_calibration.py +0 -0
  23. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_chunking.py +0 -0
  24. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_cluster_gcn.py +0 -0
  25. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_continuous_rl_algorithms.py +0 -0
  26. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dashboard.py +0 -0
  27. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dashboard_metadata.py +0 -0
  28. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_cache.py +0 -0
  29. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_docs_claims.py +0 -0
  30. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_download_mocked.py +0 -0
  31. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_dataset_registry.py +0 -0
  32. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_datasets_base.py +0 -0
  33. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_devices.py +0 -0
  34. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_distributed_compat.py +0 -0
  35. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_distributed_helpers.py +0 -0
  36. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_distributed_smoke.py +0 -0
  37. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_documentation_claims.py +0 -0
  38. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_edge_features.py +0 -0
  39. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_edge_weight.py +0 -0
  40. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_estimators_v05.py +0 -0
  41. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_evolutionary_graph_optimization.py +0 -0
  42. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_experiments.py +0 -0
  43. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_explainability.py +0 -0
  44. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_factories.py +0 -0
  45. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_folder_datasets.py +0 -0
  46. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_gat_chunking.py +0 -0
  47. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_generation_rl_benchmarks_smoke.py +0 -0
  48. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_gnn_families.py +0 -0
  49. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_gradients.py +0 -0
  50. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph.py +0 -0
  51. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_action_spaces.py +0 -0
  52. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_api.py +0 -0
  53. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_builders.py +0 -0
  54. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_generation_data_model.py +0 -0
  55. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_generation_metrics.py +0 -0
  56. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_rl_algorithms.py +0 -0
  57. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_rl_environments.py +0 -0
  58. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_transformer_v027.py +0 -0
  59. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graph_utils.py +0 -0
  60. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_graphsaint.py +0 -0
  61. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_han_hgt_overfit.py +0 -0
  62. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hard_negative_sampling.py +0 -0
  63. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_batch.py +0 -0
  64. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_layers.py +0 -0
  65. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_layers_v05.py +0 -0
  66. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_hetero_sampling.py +0 -0
  67. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_imports.py +0 -0
  68. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_io_graphml_v120.py +0 -0
  69. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_benchmarks_smoke.py +0 -0
  70. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_data_model.py +0 -0
  71. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_datasets.py +0 -0
  72. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_evaluation.py +0 -0
  73. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_gnn_integration.py +0 -0
  74. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_models.py +0 -0
  75. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_multimodal.py +0 -0
  76. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_negative_sampling.py +0 -0
  77. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_reasoning.py +0 -0
  78. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_rescal_v120.py +0 -0
  79. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_temporal.py +0 -0
  80. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_kg_training.py +0 -0
  81. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_layers.py +0 -0
  82. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_loader_feature_store_integration.py +0 -0
  83. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_loader_robustness_v110.py +0 -0
  84. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_loaders_feature_store.py +0 -0
  85. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_matching_coloring_flow.py +0 -0
  86. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_math.py +0 -0
  87. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_math_correctness_v110.py +0 -0
  88. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_math_invariants_v030.py +0 -0
  89. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_metrics.py +0 -0
  90. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_centrality.py +0 -0
  91. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_core.py +0 -0
  92. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_generators_spectral.py +0 -0
  93. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_graph_learning.py +0 -0
  94. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_paths_algorithms.py +0 -0
  95. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_mining_structural.py +0 -0
  96. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_model_zoo.py +0 -0
  97. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_models.py +0 -0
  98. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_negative_sampling.py +0 -0
  99. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_neural_mining.py +0 -0
  100. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_neural_mining_batched.py +0 -0
  101. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_node2vec_kg_hypergraph.py +0 -0
  102. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_ogb_tgb_wrappers.py +0 -0
  103. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_packaging.py +0 -0
  104. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_performance_smoke.py +0 -0
  105. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_plotting.py +0 -0
  106. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_public_benchmarks.py +0 -0
  107. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_pyg_dgl_ogb_wrappers.py +0 -0
  108. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_random_walk_sample.py +0 -0
  109. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_readme_links.py +0 -0
  110. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_release_validation_v030.py +0 -0
  111. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_reproducibility.py +0 -0
  112. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rl_baselines.py +0 -0
  113. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rl_callbacks_v120.py +0 -0
  114. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rl_high_level_api.py +0 -0
  115. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_rollout_buffer.py +0 -0
  116. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sampling.py +0 -0
  117. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sampling_loaders.py +0 -0
  118. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sparse_backend_select.py +0 -0
  119. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_sparse_vgae_rgcn.py +0 -0
  120. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_synthetic_datasets.py +0 -0
  121. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_temporal_sampling.py +0 -0
  122. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_temporal_v025.py +0 -0
  123. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_temporal_v05.py +0 -0
  124. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_tgn_tgat_overfit.py +0 -0
  125. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_time_encoding.py +0 -0
  126. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_tiny_overfit_v030.py +0 -0
  127. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_torchvision_wrappers.py +0 -0
  128. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_tracking.py +0 -0
  129. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_training.py +0 -0
  130. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_transforms.py +0 -0
  131. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_user_friendly_llm_snippets.py +0 -0
  132. {tgraphx-1.2.0 → tgraphx-1.3.0}/tests/test_v024_features.py +0 -0
  133. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/__main__.py +0 -0
  134. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/__init__.py +0 -0
  135. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/connectivity.py +0 -0
  136. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/structural.py +0 -0
  137. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/algorithms/traversal.py +0 -0
  138. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/benchmarks/__init__.py +0 -0
  139. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/benchmarks/public.py +0 -0
  140. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/calibration.py +0 -0
  141. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/cluster_gcn.py +0 -0
  142. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/__init__.py +0 -0
  143. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/dataloader.py +0 -0
  144. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/graph.py +0 -0
  145. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/graph_utils.py +0 -0
  146. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/hetero_batch.py +0 -0
  147. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/hetero_graph.py +0 -0
  148. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/temporal.py +0 -0
  149. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/temporal_batch.py +0 -0
  150. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/core/utils.py +0 -0
  151. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/__init__.py +0 -0
  152. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/__main__.py +0 -0
  153. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/app.py +0 -0
  154. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/static/dashboard.css +0 -0
  155. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/dashboard/static/dashboard.js +0 -0
  156. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/__init__.py +0 -0
  157. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/base.py +0 -0
  158. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/cache.py +0 -0
  159. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/converters.py +0 -0
  160. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/dgl_wrappers.py +0 -0
  161. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/download.py +0 -0
  162. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/errors.py +0 -0
  163. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/folder.py +0 -0
  164. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/metadata.py +0 -0
  165. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/ogb_wrappers.py +0 -0
  166. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/pyg_wrappers.py +0 -0
  167. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/registry.py +0 -0
  168. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/synthetic.py +0 -0
  169. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/datasets/torchvision_wrappers.py +0 -0
  170. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/distributed.py +0 -0
  171. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/doctor.py +0 -0
  172. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/__init__.py +0 -0
  173. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_data.py +0 -0
  174. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_diagnostics.py +0 -0
  175. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_discovery.py +0 -0
  176. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_exceptions.py +0 -0
  177. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_models.py +0 -0
  178. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_results.py +0 -0
  179. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/easy/_workflows.py +0 -0
  180. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/__init__.py +0 -0
  181. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/base.py +0 -0
  182. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/early_stopping.py +0 -0
  183. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/label_propagation.py +0 -0
  184. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/node2vec.py +0 -0
  185. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/splits.py +0 -0
  186. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/estimators/vgae.py +0 -0
  187. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/__init__.py +0 -0
  188. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/algorithms.py +0 -0
  189. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/config.py +0 -0
  190. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/fitness.py +0 -0
  191. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/genome.py +0 -0
  192. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/high_level_api.py +0 -0
  193. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/metrics.py +0 -0
  194. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/multi_objective.py +0 -0
  195. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/operators.py +0 -0
  196. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/reports.py +0 -0
  197. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/evolutionary/selection.py +0 -0
  198. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/__init__.py +0 -0
  199. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/callbacks.py +0 -0
  200. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/checkpoints.py +0 -0
  201. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/cli.py +0 -0
  202. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/config.py +0 -0
  203. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/grid.py +0 -0
  204. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/runner.py +0 -0
  205. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/experiments/summarize.py +0 -0
  206. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/__init__.py +0 -0
  207. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/attention.py +0 -0
  208. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/edge_attribution.py +0 -0
  209. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/export.py +0 -0
  210. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/integrated_gradients.py +0 -0
  211. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/patch_heatmap.py +0 -0
  212. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/saliency.py +0 -0
  213. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/explain/utils.py +0 -0
  214. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/feature_store.py +0 -0
  215. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/__init__.py +0 -0
  216. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/actions.py +0 -0
  217. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/classical.py +0 -0
  218. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/config.py +0 -0
  219. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/data_model.py +0 -0
  220. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/high_level_api.py +0 -0
  221. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/metrics.py +0 -0
  222. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/neural.py +0 -0
  223. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/projectors.py +0 -0
  224. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/generation/reports.py +0 -0
  225. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/graph_builders.py +0 -0
  226. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/graphsaint.py +0 -0
  227. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/hetero_sampling.py +0 -0
  228. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/interop.py +0 -0
  229. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/io/__init__.py +0 -0
  230. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/io/graphml.py +0 -0
  231. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/data.py +0 -0
  232. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/datasets.py +0 -0
  233. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/evaluation.py +0 -0
  234. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/gnn.py +0 -0
  235. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/losses.py +0 -0
  236. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/multimodal.py +0 -0
  237. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/projectors.py +0 -0
  238. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/reasoning.py +0 -0
  239. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/reports.py +0 -0
  240. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/sampling.py +0 -0
  241. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/temporal.py +0 -0
  242. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/kg/trainer.py +0 -0
  243. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/__init__.py +0 -0
  244. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/_dim.py +0 -0
  245. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/_scatter.py +0 -0
  246. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/aggregator.py +0 -0
  247. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/appnp.py +0 -0
  248. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/attention_message.py +0 -0
  249. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/base.py +0 -0
  250. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/conv_message.py +0 -0
  251. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/factory.py +0 -0
  252. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/gat.py +0 -0
  253. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/gatv2.py +0 -0
  254. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/gin.py +0 -0
  255. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/graph_transformer.py +0 -0
  256. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/han.py +0 -0
  257. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/hetero.py +0 -0
  258. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/hetero_readout.py +0 -0
  259. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/hgt.py +0 -0
  260. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/pooling.py +0 -0
  261. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/rgcn.py +0 -0
  262. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/safe_pool.py +0 -0
  263. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/sage.py +0 -0
  264. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/temporal_readout.py +0 -0
  265. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/transformer_encodings.py +0 -0
  266. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/layers/vector_gcn.py +0 -0
  267. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/learned_graph.py +0 -0
  268. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/loaders.py +0 -0
  269. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/__init__.py +0 -0
  270. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/classification.py +0 -0
  271. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/link_prediction.py +0 -0
  272. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/ogb.py +0 -0
  273. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/ranking.py +0 -0
  274. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/regression.py +0 -0
  275. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/metrics/reports.py +0 -0
  276. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/__init__.py +0 -0
  277. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/anomaly.py +0 -0
  278. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/api.py +0 -0
  279. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/centrality.py +0 -0
  280. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/communities.py +0 -0
  281. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/embeddings.py +0 -0
  282. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/frequent.py +0 -0
  283. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/generators.py +0 -0
  284. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/graph_io.py +0 -0
  285. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/graph_learning.py +0 -0
  286. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/hetero.py +0 -0
  287. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/hypergraph.py +0 -0
  288. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/kernels.py +0 -0
  289. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/knowledge_graph.py +0 -0
  290. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/label_prop.py +0 -0
  291. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/link_prediction.py +0 -0
  292. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/matching_coloring.py +0 -0
  293. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/motifs.py +0 -0
  294. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/neural.py +0 -0
  295. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/node2vec.py +0 -0
  296. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/paths.py +0 -0
  297. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/patterns.py +0 -0
  298. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/prototype.py +0 -0
  299. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/random_walk.py +0 -0
  300. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/reports.py +0 -0
  301. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/sequence_models.py +0 -0
  302. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/similarity.py +0 -0
  303. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/spectral.py +0 -0
  304. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/structural.py +0 -0
  305. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/structural_encodings.py +0 -0
  306. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/temporal.py +0 -0
  307. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/mining/vgae.py +0 -0
  308. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/__init__.py +0 -0
  309. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/cnn_encoder.py +0 -0
  310. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/cnn_gnn_model.py +0 -0
  311. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/edge_predictor.py +0 -0
  312. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/factory.py +0 -0
  313. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/graph_classifier.py +0 -0
  314. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/hetero_models.py +0 -0
  315. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/model_zoo.py +0 -0
  316. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/node_classifier.py +0 -0
  317. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/pre_encoder.py +0 -0
  318. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/regressors.py +0 -0
  319. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/models/temporal_models.py +0 -0
  320. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/performance.py +0 -0
  321. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/__init__.py +0 -0
  322. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/graph.py +0 -0
  323. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/layouts.py +0 -0
  324. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/mining.py +0 -0
  325. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/plotting/utils.py +0 -0
  326. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/reproducibility.py +0 -0
  327. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/__init__.py +0 -0
  328. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/__init__.py +0 -0
  329. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/actor_critic.py +0 -0
  330. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/base.py +0 -0
  331. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/baselines.py +0 -0
  332. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/continuous.py +0 -0
  333. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/dqn.py +0 -0
  334. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/ppo.py +0 -0
  335. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/reinforce.py +0 -0
  336. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/algorithms/replay_buffer.py +0 -0
  337. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/callbacks.py +0 -0
  338. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/config.py +0 -0
  339. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/__init__.py +0 -0
  340. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/base.py +0 -0
  341. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/coloring.py +0 -0
  342. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/continuous.py +0 -0
  343. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/generation.py +0 -0
  344. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/kg_reasoning.py +0 -0
  345. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/max_cut.py +0 -0
  346. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/navigation.py +0 -0
  347. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/shortest_path.py +0 -0
  348. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/environments/vertex_cover.py +0 -0
  349. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/exploration/__init__.py +0 -0
  350. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/exploration/strategies.py +0 -0
  351. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/metrics.py +0 -0
  352. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/__init__.py +0 -0
  353. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/actor_critic.py +0 -0
  354. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/policy.py +0 -0
  355. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/projectors.py +0 -0
  356. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/qnetwork.py +0 -0
  357. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/networks/value.py +0 -0
  358. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/rl/reports.py +0 -0
  359. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sampling.py +0 -0
  360. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sampling_loaders.py +0 -0
  361. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sampling_negative.py +0 -0
  362. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/sparse.py +0 -0
  363. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/__init__.py +0 -0
  364. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/tgat.py +0 -0
  365. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/tgn.py +0 -0
  366. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal/time_encoding.py +0 -0
  367. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/temporal_sampling.py +0 -0
  368. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/tracking.py +0 -0
  369. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/training.py +0 -0
  370. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/__init__.py +0 -0
  371. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/compose.py +0 -0
  372. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/features.py +0 -0
  373. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/graph.py +0 -0
  374. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/patch.py +0 -0
  375. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/positional.py +0 -0
  376. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx/transforms/splits.py +0 -0
  377. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/dependency_links.txt +0 -0
  378. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/entry_points.txt +0 -0
  379. {tgraphx-1.2.0 → tgraphx-1.3.0}/tgraphx.egg-info/requires.txt +0 -0
  380. {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.2.0
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.2.0"
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.2.0"
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