k3-node 1.0.0__py3-none-any.whl

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 (459) hide show
  1. k3_node/__init__.py +122 -0
  2. k3_node/applications/__init__.py +17 -0
  3. k3_node/applications/bio/__init__.py +21 -0
  4. k3_node/applications/chemistry/__init__.py +155 -0
  5. k3_node/applications/materials/__init__.py +127 -0
  6. k3_node/applications/materials/basis.py +449 -0
  7. k3_node/applications/materials/chgnet.py +360 -0
  8. k3_node/applications/materials/core.py +351 -0
  9. k3_node/applications/materials/grace.py +246 -0
  10. k3_node/applications/materials/io.py +230 -0
  11. k3_node/applications/materials/m3gnet.py +462 -0
  12. k3_node/applications/materials/megnet.py +395 -0
  13. k3_node/applications/materials/qet.py +220 -0
  14. k3_node/applications/materials/readout.py +235 -0
  15. k3_node/applications/materials/so3net.py +234 -0
  16. k3_node/applications/materials/tensornet.py +381 -0
  17. k3_node/applications/materials/test_materials.py +167 -0
  18. k3_node/applications/materials/wrappers.py +95 -0
  19. k3_node/data/__init__.py +47 -0
  20. k3_node/data/batch.py +102 -0
  21. k3_node/data/collate.py +282 -0
  22. k3_node/data/data.py +532 -0
  23. k3_node/data/database.py +154 -0
  24. k3_node/data/dataset.py +182 -0
  25. k3_node/data/download.py +49 -0
  26. k3_node/data/extract.py +45 -0
  27. k3_node/data/feature_store.py +70 -0
  28. k3_node/data/graph_store.py +92 -0
  29. k3_node/data/hetero_data.py +374 -0
  30. k3_node/data/hypergraph_data.py +59 -0
  31. k3_node/data/in_memory_dataset.py +177 -0
  32. k3_node/data/makedirs.py +7 -0
  33. k3_node/data/on_disk_dataset.py +77 -0
  34. k3_node/data/separate.py +115 -0
  35. k3_node/data/storage.py +593 -0
  36. k3_node/data/temporal.py +154 -0
  37. k3_node/data/test_batch.py +67 -0
  38. k3_node/data/test_data.py +68 -0
  39. k3_node/data/test_dataset_and_stores.py +111 -0
  40. k3_node/data/test_hetero_data.py +33 -0
  41. k3_node/data/test_temporal_and_hyper.py +32 -0
  42. k3_node/data/view.py +43 -0
  43. k3_node/datasets/__init__.py +88 -0
  44. k3_node/datasets/actor.py +101 -0
  45. k3_node/datasets/airports.py +84 -0
  46. k3_node/datasets/amazon.py +66 -0
  47. k3_node/datasets/ba2motif_dataset.py +73 -0
  48. k3_node/datasets/ba_shapes.py +81 -0
  49. k3_node/datasets/bitcoin_otc.py +77 -0
  50. k3_node/datasets/citation_full.py +81 -0
  51. k3_node/datasets/coauthor.py +66 -0
  52. k3_node/datasets/dblp.py +106 -0
  53. k3_node/datasets/digits.py +63 -0
  54. k3_node/datasets/email_eu_core.py +60 -0
  55. k3_node/datasets/entities.py +158 -0
  56. k3_node/datasets/explainer_dataset.py +101 -0
  57. k3_node/datasets/facebook.py +51 -0
  58. k3_node/datasets/fake.py +256 -0
  59. k3_node/datasets/freebase.py +90 -0
  60. k3_node/datasets/geometric_shapes.py +69 -0
  61. k3_node/datasets/github.py +51 -0
  62. k3_node/datasets/graph_generator/__init__.py +6 -0
  63. k3_node/datasets/graph_generator/ba_graph.py +20 -0
  64. k3_node/datasets/graph_generator/base.py +29 -0
  65. k3_node/datasets/graph_generator/er_graph.py +21 -0
  66. k3_node/datasets/icews.py +58 -0
  67. k3_node/datasets/imdb.py +96 -0
  68. k3_node/datasets/jodie.py +56 -0
  69. k3_node/datasets/karate.py +56 -0
  70. k3_node/datasets/lastfm_asia.py +51 -0
  71. k3_node/datasets/mesh_correspondence.py +50 -0
  72. k3_node/datasets/molecule_net.py +148 -0
  73. k3_node/datasets/motif_generator/__init__.py +7 -0
  74. k3_node/datasets/motif_generator/base.py +29 -0
  75. k3_node/datasets/motif_generator/custom.py +17 -0
  76. k3_node/datasets/motif_generator/cycle.py +25 -0
  77. k3_node/datasets/motif_generator/house.py +27 -0
  78. k3_node/datasets/movielens.py +55 -0
  79. k3_node/datasets/planetoid.py +137 -0
  80. k3_node/datasets/polblogs.py +63 -0
  81. k3_node/datasets/ppi.py +189 -0
  82. k3_node/datasets/qm7.py +65 -0
  83. k3_node/datasets/qm9.py +132 -0
  84. k3_node/datasets/reddit.py +121 -0
  85. k3_node/datasets/sbm_dataset.py +165 -0
  86. k3_node/datasets/seal.py +74 -0
  87. k3_node/datasets/shape_scenes.py +92 -0
  88. k3_node/datasets/test_datasets.py +322 -0
  89. k3_node/datasets/tu_dataset.py +131 -0
  90. k3_node/datasets/twitch.py +66 -0
  91. k3_node/datasets/webkb.py +102 -0
  92. k3_node/datasets/wikics.py +85 -0
  93. k3_node/datasets/word_net.py +184 -0
  94. k3_node/etl/__init__.py +37 -0
  95. k3_node/etl/encoders.py +248 -0
  96. k3_node/etl/graph_builders.py +270 -0
  97. k3_node/etl/relational_to_graph.py +201 -0
  98. k3_node/etl/table_to_graph.py +244 -0
  99. k3_node/etl/test_etl.py +318 -0
  100. k3_node/export/__init__.py +15 -0
  101. k3_node/export/cross_backend.py +172 -0
  102. k3_node/export/onnx_exporter.py +190 -0
  103. k3_node/export/runtime.py +254 -0
  104. k3_node/export/tensorrt_exporter.py +201 -0
  105. k3_node/export/test_export.py +337 -0
  106. k3_node/export/tflite_exporter.py +112 -0
  107. k3_node/hub/__init__.py +29 -0
  108. k3_node/hub/dataset_hub.py +242 -0
  109. k3_node/hub/hub_mixin.py +599 -0
  110. k3_node/hub/model_card.py +133 -0
  111. k3_node/hub/test_hub.py +419 -0
  112. k3_node/io/__init__.py +22 -0
  113. k3_node/io/fs.py +117 -0
  114. k3_node/io/npz.py +45 -0
  115. k3_node/io/off.py +29 -0
  116. k3_node/io/planetoid.py +98 -0
  117. k3_node/io/tu.py +137 -0
  118. k3_node/io/txt_array.py +58 -0
  119. k3_node/layers/__init__.py +14 -0
  120. k3_node/layers/aggr/__init__.py +70 -0
  121. k3_node/layers/aggr/attention.py +77 -0
  122. k3_node/layers/aggr/base.py +403 -0
  123. k3_node/layers/aggr/basic.py +412 -0
  124. k3_node/layers/aggr/deep_sets.py +65 -0
  125. k3_node/layers/aggr/deepsets.py +29 -0
  126. k3_node/layers/aggr/equilibrium.py +107 -0
  127. k3_node/layers/aggr/fused.py +43 -0
  128. k3_node/layers/aggr/gmt.py +89 -0
  129. k3_node/layers/aggr/gru.py +58 -0
  130. k3_node/layers/aggr/lcm.py +143 -0
  131. k3_node/layers/aggr/lstm.py +58 -0
  132. k3_node/layers/aggr/mlp.py +75 -0
  133. k3_node/layers/aggr/multi.py +154 -0
  134. k3_node/layers/aggr/patch_transformer.py +137 -0
  135. k3_node/layers/aggr/quantile.py +125 -0
  136. k3_node/layers/aggr/resolver.py +68 -0
  137. k3_node/layers/aggr/scaler.py +133 -0
  138. k3_node/layers/aggr/set2set.py +87 -0
  139. k3_node/layers/aggr/set_transformer.py +107 -0
  140. k3_node/layers/aggr/sort.py +68 -0
  141. k3_node/layers/aggr/test_aggr.py +337 -0
  142. k3_node/layers/aggr/utils.py +210 -0
  143. k3_node/layers/aggr/variance_preserving.py +54 -0
  144. k3_node/layers/attention/__init__.py +5 -0
  145. k3_node/layers/attention/pair_attention.py +448 -0
  146. k3_node/layers/attention/performer.py +187 -0
  147. k3_node/layers/attention/polynormer.py +160 -0
  148. k3_node/layers/attention/qformer.py +143 -0
  149. k3_node/layers/attention/sgformer.py +106 -0
  150. k3_node/layers/attention/test_attention.py +68 -0
  151. k3_node/layers/attention/test_pair_attention.py +91 -0
  152. k3_node/layers/conv/__init__.py +149 -0
  153. k3_node/layers/conv/agnn_conv.py +120 -0
  154. k3_node/layers/conv/antisymmetric_conv.py +94 -0
  155. k3_node/layers/conv/appnp.py +105 -0
  156. k3_node/layers/conv/appnp_conv.py +157 -0
  157. k3_node/layers/conv/arma_conv.py +231 -0
  158. k3_node/layers/conv/cg_conv.py +92 -0
  159. k3_node/layers/conv/cheb_conv.py +137 -0
  160. k3_node/layers/conv/cluster_gcn_conv.py +102 -0
  161. k3_node/layers/conv/conv.py +100 -0
  162. k3_node/layers/conv/crystal_conv.py +140 -0
  163. k3_node/layers/conv/cugraph.py +84 -0
  164. k3_node/layers/conv/diffusion_conv.py +144 -0
  165. k3_node/layers/conv/dir_gnn_conv.py +93 -0
  166. k3_node/layers/conv/dna_conv.py +192 -0
  167. k3_node/layers/conv/edge_conv.py +107 -0
  168. k3_node/layers/conv/eg_conv.py +155 -0
  169. k3_node/layers/conv/fa_conv.py +107 -0
  170. k3_node/layers/conv/feast_conv.py +126 -0
  171. k3_node/layers/conv/film_conv.py +143 -0
  172. k3_node/layers/conv/gat_conv.py +244 -0
  173. k3_node/layers/conv/gated_graph_conv.py +136 -0
  174. k3_node/layers/conv/gatv2_conv.py +205 -0
  175. k3_node/layers/conv/gcn.py +144 -0
  176. k3_node/layers/conv/gcn2_conv.py +126 -0
  177. k3_node/layers/conv/gcn_conv.py +135 -0
  178. k3_node/layers/conv/gen_conv.py +163 -0
  179. k3_node/layers/conv/general_conv.py +218 -0
  180. k3_node/layers/conv/gin_conv.py +218 -0
  181. k3_node/layers/conv/gmm_conv.py +172 -0
  182. k3_node/layers/conv/gps_conv.py +153 -0
  183. k3_node/layers/conv/graph_attention.py +262 -0
  184. k3_node/layers/conv/graph_conv.py +84 -0
  185. k3_node/layers/conv/gravnet_conv.py +93 -0
  186. k3_node/layers/conv/han_conv.py +175 -0
  187. k3_node/layers/conv/heat_conv.py +131 -0
  188. k3_node/layers/conv/hetero_conv.py +128 -0
  189. k3_node/layers/conv/hgt_conv.py +218 -0
  190. k3_node/layers/conv/hypergraph_conv.py +182 -0
  191. k3_node/layers/conv/le_conv.py +81 -0
  192. k3_node/layers/conv/lg_conv.py +58 -0
  193. k3_node/layers/conv/meshcnn_conv.py +84 -0
  194. k3_node/layers/conv/message_passing.py +451 -0
  195. k3_node/layers/conv/mf_conv.py +95 -0
  196. k3_node/layers/conv/mixhop_conv.py +108 -0
  197. k3_node/layers/conv/nn_conv.py +110 -0
  198. k3_node/layers/conv/pan_conv.py +100 -0
  199. k3_node/layers/conv/pdn_conv.py +109 -0
  200. k3_node/layers/conv/pna_conv.py +177 -0
  201. k3_node/layers/conv/point_conv.py +101 -0
  202. k3_node/layers/conv/point_gnn_conv.py +90 -0
  203. k3_node/layers/conv/point_transformer_conv.py +132 -0
  204. k3_node/layers/conv/ppf_conv.py +135 -0
  205. k3_node/layers/conv/ppnp.py +89 -0
  206. k3_node/layers/conv/res_gated_graph_conv.py +126 -0
  207. k3_node/layers/conv/rgat_conv.py +251 -0
  208. k3_node/layers/conv/rgcn_conv.py +321 -0
  209. k3_node/layers/conv/sage_conv.py +154 -0
  210. k3_node/layers/conv/sg_conv.py +96 -0
  211. k3_node/layers/conv/signed_conv.py +100 -0
  212. k3_node/layers/conv/simple_conv.py +75 -0
  213. k3_node/layers/conv/spline_conv.py +182 -0
  214. k3_node/layers/conv/ssg_conv.py +101 -0
  215. k3_node/layers/conv/supergat_conv.py +195 -0
  216. k3_node/layers/conv/tag_conv.py +98 -0
  217. k3_node/layers/conv/test_backend_consistency.py +164 -0
  218. k3_node/layers/conv/test_conv.py +176 -0
  219. k3_node/layers/conv/test_conv_pyg.py +566 -0
  220. k3_node/layers/conv/transformer_conv.py +168 -0
  221. k3_node/layers/conv/utils.py +403 -0
  222. k3_node/layers/conv/wl_conv.py +151 -0
  223. k3_node/layers/conv/x_conv.py +187 -0
  224. k3_node/layers/dense/__init__.py +40 -0
  225. k3_node/layers/dense/dense_gat_conv.py +149 -0
  226. k3_node/layers/dense/dense_gcn_conv.py +117 -0
  227. k3_node/layers/dense/dense_gin_conv.py +88 -0
  228. k3_node/layers/dense/dense_graph_conv.py +95 -0
  229. k3_node/layers/dense/dense_sage_conv.py +85 -0
  230. k3_node/layers/dense/diff_pool.py +76 -0
  231. k3_node/layers/dense/dmon_pool.py +223 -0
  232. k3_node/layers/dense/linear.py +327 -0
  233. k3_node/layers/dense/mincut_pool.py +92 -0
  234. k3_node/layers/dense/test_dense.py +377 -0
  235. k3_node/layers/functional/__init__.py +13 -0
  236. k3_node/layers/functional/bro.py +49 -0
  237. k3_node/layers/functional/edge_dropout.py +55 -0
  238. k3_node/layers/functional/gini.py +44 -0
  239. k3_node/layers/functional/test_functional.py +34 -0
  240. k3_node/layers/kge/__init__.py +17 -0
  241. k3_node/layers/kge/base.py +255 -0
  242. k3_node/layers/kge/complex.py +98 -0
  243. k3_node/layers/kge/distmult.py +79 -0
  244. k3_node/layers/kge/loader.py +50 -0
  245. k3_node/layers/kge/rotate.py +103 -0
  246. k3_node/layers/kge/test_kge.py +76 -0
  247. k3_node/layers/kge/transe.py +96 -0
  248. k3_node/layers/norm/__init__.py +23 -0
  249. k3_node/layers/norm/batch_norm.py +328 -0
  250. k3_node/layers/norm/diff_group_norm.py +141 -0
  251. k3_node/layers/norm/graph_norm.py +105 -0
  252. k3_node/layers/norm/graph_size_norm.py +57 -0
  253. k3_node/layers/norm/instance_norm.py +163 -0
  254. k3_node/layers/norm/layer_norm.py +245 -0
  255. k3_node/layers/norm/mean_subtraction_norm.py +57 -0
  256. k3_node/layers/norm/msg_norm.py +58 -0
  257. k3_node/layers/norm/pair_norm.py +94 -0
  258. k3_node/layers/norm/test_norm.py +275 -0
  259. k3_node/layers/pool/__init__.py +83 -0
  260. k3_node/layers/pool/approx_knn.py +101 -0
  261. k3_node/layers/pool/asap.py +173 -0
  262. k3_node/layers/pool/avg_pool.py +165 -0
  263. k3_node/layers/pool/cluster_pool.py +168 -0
  264. k3_node/layers/pool/connect/__init__.py +10 -0
  265. k3_node/layers/pool/connect/base.py +103 -0
  266. k3_node/layers/pool/connect/filter_edges.py +113 -0
  267. k3_node/layers/pool/consecutive.py +30 -0
  268. k3_node/layers/pool/decimation.py +48 -0
  269. k3_node/layers/pool/edge_pool.py +189 -0
  270. k3_node/layers/pool/glob.py +139 -0
  271. k3_node/layers/pool/graclus.py +66 -0
  272. k3_node/layers/pool/knn.py +253 -0
  273. k3_node/layers/pool/max_pool.py +159 -0
  274. k3_node/layers/pool/mem_pool.py +145 -0
  275. k3_node/layers/pool/pan_pool.py +144 -0
  276. k3_node/layers/pool/point_cloud.py +212 -0
  277. k3_node/layers/pool/pool.py +119 -0
  278. k3_node/layers/pool/sag_pool.py +174 -0
  279. k3_node/layers/pool/select/__init__.py +10 -0
  280. k3_node/layers/pool/select/base.py +112 -0
  281. k3_node/layers/pool/select/topk.py +206 -0
  282. k3_node/layers/pool/test_pool.py +456 -0
  283. k3_node/layers/pool/topk_pool.py +103 -0
  284. k3_node/layers/pool/voxel_grid.py +70 -0
  285. k3_node/layers/unpool/__init__.py +9 -0
  286. k3_node/layers/unpool/knn_interpolate.py +57 -0
  287. k3_node/layers/unpool/test_unpool.py +31 -0
  288. k3_node/loader/__init__.py +62 -0
  289. k3_node/loader/base.py +69 -0
  290. k3_node/loader/cache.py +68 -0
  291. k3_node/loader/cluster.py +127 -0
  292. k3_node/loader/data_list_loader.py +45 -0
  293. k3_node/loader/dataloader.py +117 -0
  294. k3_node/loader/dense_data_loader.py +62 -0
  295. k3_node/loader/dynamic_batch_sampler.py +93 -0
  296. k3_node/loader/graph_saint.py +188 -0
  297. k3_node/loader/hgt_loader.py +90 -0
  298. k3_node/loader/imbalanced_sampler.py +87 -0
  299. k3_node/loader/keras_dataset.py +334 -0
  300. k3_node/loader/link_loader.py +179 -0
  301. k3_node/loader/link_neighbor_loader.py +202 -0
  302. k3_node/loader/mixin.py +190 -0
  303. k3_node/loader/neighbor_loader.py +159 -0
  304. k3_node/loader/neighbor_sampler.py +167 -0
  305. k3_node/loader/node_loader.py +185 -0
  306. k3_node/loader/prefetch.py +115 -0
  307. k3_node/loader/random_node_loader.py +89 -0
  308. k3_node/loader/sampler_utils.py +499 -0
  309. k3_node/loader/shadow.py +115 -0
  310. k3_node/loader/temporal_dataloader.py +98 -0
  311. k3_node/loader/test_dataloader.py +113 -0
  312. k3_node/loader/test_keras_dataset.py +221 -0
  313. k3_node/loader/test_neighbor_loader.py +122 -0
  314. k3_node/loader/test_sampler_utils.py +82 -0
  315. k3_node/loader/test_samplers.py +96 -0
  316. k3_node/loader/test_subgraph_loaders.py +89 -0
  317. k3_node/loader/utils.py +232 -0
  318. k3_node/loader/zip_loader.py +88 -0
  319. k3_node/metrics.py +94 -0
  320. k3_node/models/__init__.py +424 -0
  321. k3_node/models/attentive_fp.py +232 -0
  322. k3_node/models/attract_repel.py +108 -0
  323. k3_node/models/autoencoder.py +318 -0
  324. k3_node/models/basic_gnn.py +443 -0
  325. k3_node/models/bio/__init__.py +4 -0
  326. k3_node/models/captum.py +52 -0
  327. k3_node/models/chemistry/__init__.py +4 -0
  328. k3_node/models/correct_and_smooth.py +146 -0
  329. k3_node/models/deep_graph_infomax.py +113 -0
  330. k3_node/models/deepgcn.py +121 -0
  331. k3_node/models/dimenet.py +737 -0
  332. k3_node/models/dimenet_utils.py +153 -0
  333. k3_node/models/gnnff.py +263 -0
  334. k3_node/models/gps_model.py +1122 -0
  335. k3_node/models/gpse.py +638 -0
  336. k3_node/models/graph_unet.py +199 -0
  337. k3_node/models/graphmae2.py +954 -0
  338. k3_node/models/graphormer.py +1258 -0
  339. k3_node/models/graphormer_3d.py +868 -0
  340. k3_node/models/grover.py +1066 -0
  341. k3_node/models/jumping_knowledge.py +200 -0
  342. k3_node/models/label_prop.py +110 -0
  343. k3_node/models/lightgcn.py +171 -0
  344. k3_node/models/linkx.py +181 -0
  345. k3_node/models/lpformer.py +404 -0
  346. k3_node/models/mask_label.py +114 -0
  347. k3_node/models/materials/__init__.py +33 -0
  348. k3_node/models/meta.py +133 -0
  349. k3_node/models/metapath2vec.py +234 -0
  350. k3_node/models/mlp.py +264 -0
  351. k3_node/models/mole_bert.py +379 -0
  352. k3_node/models/neural_fingerprint.py +95 -0
  353. k3_node/models/node2vec.py +213 -0
  354. k3_node/models/pmlp.py +157 -0
  355. k3_node/models/polynormer.py +229 -0
  356. k3_node/models/rect.py +93 -0
  357. k3_node/models/renet.py +221 -0
  358. k3_node/models/rev_gnn.py +128 -0
  359. k3_node/models/schnet.py +484 -0
  360. k3_node/models/sgformer.py +195 -0
  361. k3_node/models/signed_gcn.py +185 -0
  362. k3_node/models/test_attentive_fp.py +32 -0
  363. k3_node/models/test_attract_repel.py +33 -0
  364. k3_node/models/test_autoencoder.py +119 -0
  365. k3_node/models/test_basic_gnn.py +102 -0
  366. k3_node/models/test_correct_and_smooth.py +40 -0
  367. k3_node/models/test_deep_graph_infomax.py +68 -0
  368. k3_node/models/test_deepgcn.py +21 -0
  369. k3_node/models/test_dimenet.py +86 -0
  370. k3_node/models/test_domain_apis.py +138 -0
  371. k3_node/models/test_gnnff.py +24 -0
  372. k3_node/models/test_gps_model.py +271 -0
  373. k3_node/models/test_gpse.py +34 -0
  374. k3_node/models/test_graph_unet.py +26 -0
  375. k3_node/models/test_graphmae2.py +226 -0
  376. k3_node/models/test_graphormer.py +233 -0
  377. k3_node/models/test_graphormer3d.py +163 -0
  378. k3_node/models/test_grover.py +287 -0
  379. k3_node/models/test_jumping_knowledge.py +129 -0
  380. k3_node/models/test_label_prop.py +37 -0
  381. k3_node/models/test_lightgcn.py +38 -0
  382. k3_node/models/test_linkx.py +31 -0
  383. k3_node/models/test_lpformer.py +22 -0
  384. k3_node/models/test_mask_label.py +90 -0
  385. k3_node/models/test_meta.py +159 -0
  386. k3_node/models/test_metapath2vec.py +45 -0
  387. k3_node/models/test_mlp.py +62 -0
  388. k3_node/models/test_mole_bert.py +164 -0
  389. k3_node/models/test_neural_fingerprint.py +13 -0
  390. k3_node/models/test_node2vec.py +57 -0
  391. k3_node/models/test_pmlp.py +81 -0
  392. k3_node/models/test_polynormer.py +104 -0
  393. k3_node/models/test_rect.py +23 -0
  394. k3_node/models/test_renet.py +32 -0
  395. k3_node/models/test_rev_gnn.py +24 -0
  396. k3_node/models/test_schnet.py +43 -0
  397. k3_node/models/test_sgformer.py +48 -0
  398. k3_node/models/test_signed_gcn.py +28 -0
  399. k3_node/models/test_tgn.py +77 -0
  400. k3_node/models/test_unimol.py +179 -0
  401. k3_node/models/test_unimol2.py +114 -0
  402. k3_node/models/test_unimol_plus.py +131 -0
  403. k3_node/models/test_visnet.py +44 -0
  404. k3_node/models/tgn.py +382 -0
  405. k3_node/models/unimol.py +1156 -0
  406. k3_node/models/unimol2.py +616 -0
  407. k3_node/models/unimol_docking_v2.py +301 -0
  408. k3_node/models/unimol_plus.py +456 -0
  409. k3_node/models/utils.py +97 -0
  410. k3_node/models/visnet.py +759 -0
  411. k3_node/ops/__init__.py +4 -0
  412. k3_node/ops/conv.py +56 -0
  413. k3_node/ops/creation.py +43 -0
  414. k3_node/ops/graph.py +27 -0
  415. k3_node/ops/host.py +41 -0
  416. k3_node/ops/matmul.py +49 -0
  417. k3_node/ops/numpy.py +24 -0
  418. k3_node/ops/segment.py +54 -0
  419. k3_node/ops/sparse.py +51 -0
  420. k3_node/rag/__init__.py +49 -0
  421. k3_node/rag/encoders.py +312 -0
  422. k3_node/rag/pipeline.py +192 -0
  423. k3_node/rag/projector.py +184 -0
  424. k3_node/rag/subgraph.py +270 -0
  425. k3_node/rag/test_rag.py +347 -0
  426. k3_node/rag/verbalizer.py +162 -0
  427. k3_node/tasks/__init__.py +19 -0
  428. k3_node/tasks/backbone_resolver.py +125 -0
  429. k3_node/tasks/base.py +67 -0
  430. k3_node/tasks/graph_classification.py +270 -0
  431. k3_node/tasks/graph_regression.py +228 -0
  432. k3_node/tasks/link_prediction.py +306 -0
  433. k3_node/tasks/node_classification.py +194 -0
  434. k3_node/tasks/node_regression.py +138 -0
  435. k3_node/tasks/test_tasks.py +319 -0
  436. k3_node/test_docstring_examples.py +106 -0
  437. k3_node/test_training_forwarding.py +116 -0
  438. k3_node/training.py +115 -0
  439. k3_node/transforms/__init__.py +166 -0
  440. k3_node/transforms/base_transform.py +32 -0
  441. k3_node/transforms/compose.py +58 -0
  442. k3_node/transforms/general.py +676 -0
  443. k3_node/transforms/graph.py +1070 -0
  444. k3_node/transforms/spatial.py +797 -0
  445. k3_node/transforms/test_random_link_split.py +45 -0
  446. k3_node/transforms/test_spatial_transforms.py +65 -0
  447. k3_node/transforms/test_transforms.py +253 -0
  448. k3_node/transforms/utils.py +102 -0
  449. k3_node/utils/__init__.py +5 -0
  450. k3_node/utils/backend_import.py +12 -0
  451. k3_node/utils/graph.py +286 -0
  452. k3_node/utils/keras.py +94 -0
  453. k3_node/utils/random.py +103 -0
  454. k3_node/utils/smiles.py +235 -0
  455. k3_node-1.0.0.dist-info/METADATA +284 -0
  456. k3_node-1.0.0.dist-info/RECORD +459 -0
  457. k3_node-1.0.0.dist-info/WHEEL +5 -0
  458. k3_node-1.0.0.dist-info/licenses/LICENSE +21 -0
  459. k3_node-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,251 @@
1
+ from typing import Optional
2
+ import keras
3
+ from keras import ops
4
+ from keras.layers import Dense
5
+
6
+ from k3_node.layers.conv.message_passing import MessagePassing
7
+ from k3_node.layers.conv.utils import softmax
8
+
9
+
10
+ class RGATConv(MessagePassing):
11
+ r"""The relational graph attentional operator from the
12
+ `"Relational Graph Attention Networks" <https://arxiv.org/abs/1904.05811>`_ paper.
13
+
14
+ Example:
15
+ ```python
16
+ import numpy as np
17
+ from k3_node.layers import RGATConv
18
+
19
+ x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
20
+ edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
21
+ edge_type = np.random.randint(0, 3, size=(30,)) # relation type of each edge
22
+
23
+ layer = RGATConv(in_channels=8, out_channels=16, num_relations=3)
24
+ out = layer(x, edge_index, edge_type)
25
+ print(tuple(out.shape)) # (10, 16)
26
+ ```
27
+ """
28
+ def __init__(
29
+ self,
30
+ in_channels: int,
31
+ out_channels: int,
32
+ num_relations: int,
33
+ num_bases: Optional[int] = None,
34
+ num_blocks: Optional[int] = None,
35
+ mod: Optional[str] = None,
36
+ attention_mechanism: str = "across-relation",
37
+ attention_mode: str = "additive-self-attention",
38
+ heads: int = 1,
39
+ dim: int = 1,
40
+ concat: bool = True,
41
+ negative_slope: float = 0.2,
42
+ dropout: float = 0.0,
43
+ edge_dim: Optional[int] = None,
44
+ bias: bool = True,
45
+ **kwargs,
46
+ ):
47
+ kwargs.setdefault("aggr", "add")
48
+ super().__init__(**kwargs)
49
+
50
+ self.in_channels = in_channels
51
+ self.out_channels = out_channels
52
+ self.num_relations = num_relations
53
+ self.num_bases = num_bases
54
+ self.num_blocks = num_blocks
55
+ self.mod = mod
56
+ self.attention_mechanism = attention_mechanism
57
+ self.attention_mode = attention_mode
58
+ self.heads = heads
59
+ self.dim = dim
60
+ self.concat = concat
61
+ self.negative_slope = negative_slope
62
+ self.dropout_rate = dropout
63
+ self.edge_dim = edge_dim
64
+ self.use_bias = bias
65
+
66
+ self.q = self.add_weight(
67
+ shape=(heads * out_channels, heads * dim),
68
+ initializer="glorot_uniform",
69
+ name="q",
70
+ )
71
+ self.k = self.add_weight(
72
+ shape=(heads * out_channels, heads * dim),
73
+ initializer="glorot_uniform",
74
+ name="k",
75
+ )
76
+ if edge_dim is not None:
77
+ self.lin_edge = Dense(heads * out_channels, use_bias=False)
78
+ self.e = self.add_weight(
79
+ shape=(heads * out_channels, heads * dim),
80
+ initializer="glorot_uniform",
81
+ name="e",
82
+ )
83
+ else:
84
+ self.lin_edge = None
85
+ self.e = None
86
+
87
+ if num_bases is not None:
88
+ self.att = self.add_weight(
89
+ shape=(num_relations, num_bases),
90
+ initializer="glorot_uniform",
91
+ name="att",
92
+ )
93
+ self.basis = self.add_weight(
94
+ shape=(num_bases, in_channels, heads * out_channels),
95
+ initializer="glorot_uniform",
96
+ name="basis",
97
+ )
98
+ elif num_blocks is not None:
99
+ assert (
100
+ in_channels % num_blocks == 0
101
+ and (heads * out_channels) % num_blocks == 0
102
+ )
103
+ self.weight = self.add_weight(
104
+ shape=(
105
+ num_relations,
106
+ num_blocks,
107
+ in_channels // num_blocks,
108
+ (heads * out_channels) // num_blocks,
109
+ ),
110
+ initializer="glorot_uniform",
111
+ name="weight",
112
+ )
113
+ else:
114
+ self.weight = self.add_weight(
115
+ shape=(num_relations, in_channels, heads * out_channels),
116
+ initializer="glorot_uniform",
117
+ name="weight",
118
+ )
119
+
120
+ if bias:
121
+ out_dim = heads * out_channels if concat else out_channels
122
+ self.bias = self.add_weight(
123
+ shape=(out_dim,),
124
+ initializer="zeros",
125
+ name="bias",
126
+ )
127
+ else:
128
+ self.bias = None
129
+
130
+ def build(self, input_shape=None):
131
+ if self.lin_edge is not None and self.edge_dim is not None:
132
+ self.lin_edge.build((None, self.edge_dim))
133
+ self.built = True
134
+
135
+ def _get_weight(self):
136
+ if self.num_bases is not None:
137
+ b_flat = ops.reshape(self.basis, (self.num_bases, -1))
138
+ w = ops.matmul(self.att, b_flat)
139
+ return ops.reshape(
140
+ w, (self.num_relations, self.in_channels, self.heads * self.out_channels)
141
+ )
142
+ return self.weight
143
+
144
+ def call(
145
+ self,
146
+ inputs,
147
+ edge_index=None,
148
+ edge_type=None,
149
+ edge_attr=None,
150
+ **kwargs,
151
+ ):
152
+ if edge_index is None:
153
+ if isinstance(inputs, (list, tuple)):
154
+ if len(inputs) == 4:
155
+ x, edge_index, edge_type, edge_attr = inputs
156
+ elif len(inputs) == 3:
157
+ x, edge_index, edge_type = inputs
158
+ elif len(inputs) == 2:
159
+ x, edge_index = inputs
160
+ else:
161
+ raise ValueError("Unexpected inputs length")
162
+ else:
163
+ raise ValueError("Expected (x, edge_index, ...)")
164
+ else:
165
+ x = inputs
166
+
167
+ if not self.built:
168
+ self.build()
169
+
170
+ if isinstance(x, (list, tuple)):
171
+ x_l, x_r = x
172
+ else:
173
+ x_l = x_r = x
174
+
175
+ edge_index = ops.cast(edge_index, "int32")
176
+ if edge_type is not None:
177
+ edge_type = ops.cast(edge_type, "int32")
178
+
179
+ num_nodes = ops.shape(x_r)[0]
180
+ size = (ops.shape(x_l)[0], num_nodes)
181
+
182
+ out = self.propagate(
183
+ edge_index,
184
+ x=(x_l, x_r),
185
+ edge_type=edge_type,
186
+ edge_attr=edge_attr,
187
+ size=size,
188
+ )
189
+
190
+ if self.concat:
191
+ out = ops.reshape(out, (-1, self.heads * self.out_channels))
192
+ else:
193
+ out = ops.mean(out, axis=1)
194
+
195
+ if self.bias is not None:
196
+ out = out + self.bias
197
+
198
+ return out
199
+
200
+ def message(self, x_i, x_j, index=None, edge_type=None, edge_attr=None, size_i=None):
201
+ weight = self._get_weight()
202
+
203
+ if edge_type is None:
204
+ edge_type = ops.zeros((ops.shape(index)[0],), dtype="int32")
205
+
206
+ if self.num_blocks is not None:
207
+ w_r = ops.take(weight, edge_type, axis=0) # (E, num_blocks, in_b, out_b)
208
+ x_i_b = ops.reshape(
209
+ x_i,
210
+ (-1, self.num_blocks, 1, self.in_channels // self.num_blocks),
211
+ )
212
+ x_j_b = ops.reshape(
213
+ x_j,
214
+ (-1, self.num_blocks, 1, self.in_channels // self.num_blocks),
215
+ )
216
+ outi = ops.reshape(ops.matmul(x_i_b, w_r), (-1, self.heads * self.out_channels))
217
+ outj = ops.reshape(ops.matmul(x_j_b, w_r), (-1, self.heads * self.out_channels))
218
+ else:
219
+ w_r = ops.take(weight, edge_type, axis=0) # (E, in_channels, heads * out_channels)
220
+ outi = ops.squeeze(ops.matmul(ops.expand_dims(x_i, 1), w_r), 1)
221
+ outj = ops.squeeze(ops.matmul(ops.expand_dims(x_j, 1), w_r), 1)
222
+
223
+ qi = ops.matmul(outi, self.q)
224
+ kj = ops.matmul(outj, self.k)
225
+
226
+ alpha_edge, alpha = 0.0, 0.0
227
+ if edge_attr is not None and self.lin_edge is not None:
228
+ edge_attributes = ops.reshape(self.lin_edge(edge_attr), (-1, self.heads * self.out_channels))
229
+ alpha_edge = ops.matmul(edge_attributes, self.e)
230
+
231
+ if self.attention_mode == "additive-self-attention":
232
+ alpha = qi + kj
233
+ if edge_attr is not None and self.lin_edge is not None:
234
+ alpha = alpha + alpha_edge
235
+ alpha = ops.leaky_relu(alpha, negative_slope=self.negative_slope)
236
+ elif self.attention_mode == "multiplicative-self-attention":
237
+ alpha = qi * kj
238
+ if edge_attr is not None and self.lin_edge is not None:
239
+ alpha = alpha * alpha_edge
240
+
241
+ alpha = softmax(alpha, index, num_nodes=size_i, dim=0)
242
+
243
+ outj_h = ops.reshape(outj, (-1, self.heads, self.out_channels))
244
+ if self.attention_mode == "additive-self-attention":
245
+ alpha_h = ops.reshape(alpha, (-1, self.heads, 1))
246
+ return outj_h * alpha_h
247
+ else:
248
+ alpha_h = ops.reshape(alpha, (-1, self.heads, self.dim, 1))
249
+ outj_exp = ops.expand_dims(outj_h, -2)
250
+ msg = alpha_h * outj_exp
251
+ return ops.mean(msg, axis=2)
@@ -0,0 +1,321 @@
1
+ from typing import Optional, Union, Tuple
2
+
3
+ import numpy as np
4
+ from keras import ops
5
+
6
+ from k3_node.layers.conv.message_passing import MessagePassing
7
+ from k3_node.layers.conv.utils import scatter
8
+
9
+
10
+ class RGCNConv(MessagePassing):
11
+ r"""The relational graph convolutional operator from the
12
+ `"Modeling Relational Data with Graph Convolutional Networks"
13
+ <https://arxiv.org/abs/1703.06103>`_ paper.
14
+
15
+ Example:
16
+ ```python
17
+ import numpy as np
18
+ from k3_node.layers import RGCNConv
19
+
20
+ x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
21
+ edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
22
+ edge_type = np.random.randint(0, 3, size=(30,)) # relation type of each edge
23
+
24
+ layer = RGCNConv(in_channels=8, out_channels=16, num_relations=3)
25
+ out = layer(x, edge_index, edge_type)
26
+ print(tuple(out.shape)) # (10, 16)
27
+ ```
28
+ """
29
+ def __init__(
30
+ self,
31
+ in_channels: Union[int, Tuple[int, int]],
32
+ out_channels: int,
33
+ num_relations: int,
34
+ num_bases: Optional[int] = None,
35
+ num_blocks: Optional[int] = None,
36
+ aggr: str = "mean",
37
+ root_weight: bool = True,
38
+ is_sorted: bool = False,
39
+ bias: bool = True,
40
+ **kwargs,
41
+ ):
42
+ kwargs.setdefault("aggr", aggr)
43
+ super().__init__(**kwargs)
44
+
45
+ self.in_channels = in_channels
46
+ self.out_channels = out_channels
47
+ self.num_relations = num_relations
48
+ self.num_bases = num_bases
49
+ self.num_blocks = num_blocks
50
+ self.root_weight = root_weight
51
+ self.is_sorted = is_sorted
52
+ self.use_bias = bias
53
+
54
+ if isinstance(in_channels, int):
55
+ self.in_channels_l = in_channels
56
+ self.in_channels_r = in_channels
57
+ else:
58
+ self.in_channels_l, self.in_channels_r = in_channels
59
+
60
+ if num_bases is not None:
61
+ self.weight = self.add_weight(
62
+ shape=(num_bases, self.in_channels_l, out_channels),
63
+ initializer="glorot_uniform",
64
+ name="weight",
65
+ )
66
+ self.comp = self.add_weight(
67
+ shape=(num_relations, num_bases),
68
+ initializer="glorot_uniform",
69
+ name="comp",
70
+ )
71
+ elif num_blocks is not None:
72
+ assert (
73
+ self.in_channels_l % num_blocks == 0
74
+ and out_channels % num_blocks == 0
75
+ ), "in_channels and out_channels must be divisible by num_blocks"
76
+ self.weight = self.add_weight(
77
+ shape=(
78
+ num_relations,
79
+ num_blocks,
80
+ self.in_channels_l // num_blocks,
81
+ out_channels // num_blocks,
82
+ ),
83
+ initializer="glorot_uniform",
84
+ name="weight",
85
+ )
86
+ else:
87
+ self.weight = self.add_weight(
88
+ shape=(num_relations, self.in_channels_l, out_channels),
89
+ initializer="glorot_uniform",
90
+ name="weight",
91
+ )
92
+
93
+ if root_weight:
94
+ self.root = self.add_weight(
95
+ shape=(self.in_channels_r, out_channels),
96
+ initializer="glorot_uniform",
97
+ name="root",
98
+ )
99
+ else:
100
+ self.root = None
101
+
102
+ if bias:
103
+ self.bias = self.add_weight(
104
+ shape=(out_channels,),
105
+ initializer="zeros",
106
+ name="bias",
107
+ )
108
+ else:
109
+ self.bias = None
110
+
111
+ def build(self, input_shape=None):
112
+ self.built = True
113
+
114
+ def _get_weight(self):
115
+ if self.num_bases is not None:
116
+ # comp @ weight.reshape(num_bases, -1) -> (num_relations, in_channels, out_channels)
117
+ w_flat = ops.reshape(self.weight, (self.num_bases, -1))
118
+ w = ops.matmul(self.comp, w_flat)
119
+ return ops.reshape(
120
+ w, (self.num_relations, self.in_channels_l, self.out_channels)
121
+ )
122
+ return self.weight
123
+
124
+ def call(self, inputs, edge_index=None, edge_type=None, **kwargs):
125
+ if edge_index is None:
126
+ if isinstance(inputs, (list, tuple)):
127
+ if len(inputs) == 3:
128
+ x, edge_index, edge_type = inputs
129
+ elif len(inputs) == 2:
130
+ x, edge_index = inputs
131
+ else:
132
+ raise ValueError(f"Unexpected input length {len(inputs)}")
133
+ else:
134
+ raise ValueError("Expected (x, edge_index) or x and edge_index")
135
+ else:
136
+ x = inputs
137
+
138
+ if isinstance(x, (list, tuple)):
139
+ x_l, x_r = x
140
+ else:
141
+ x_l = x_r = x
142
+
143
+ edge_index = ops.cast(edge_index, "int32")
144
+ edge_type = ops.cast(edge_type, "int32")
145
+ # Featureless nodes (x=None): node i's input is the one-hot vector e_i, so in_channels is
146
+ # the number of nodes and x @ W reduces to looking up row i of W.
147
+ size = (
148
+ self.in_channels_l if x_l is None else ops.shape(x_l)[0],
149
+ self.in_channels_r if x_r is None else ops.shape(x_r)[0],
150
+ )
151
+
152
+ # Either transform every source node once per relation and look up each edge's message
153
+ # ([relations * nodes, out] values), or multiply every edge with its relation's weight
154
+ # ([edges, in, out] values). Featureless nodes always use the lookup.
155
+ self._node_messages = None
156
+ if x_l is None or self._prefer_node_transform(x_l, edge_index):
157
+ self._node_messages = self._relation_features(x_l)
158
+ self._num_sources = size[0]
159
+ x_l = None
160
+
161
+ out = self.propagate(
162
+ edge_index, x=x_l, edge_type=edge_type, size=size
163
+ )
164
+ self._node_messages = None
165
+
166
+ if self.root is not None:
167
+ out = out + (self.root if x_r is None else ops.matmul(x_r, self.root))
168
+
169
+ if self.bias is not None:
170
+ out = out + self.bias
171
+
172
+ return out
173
+
174
+ def _prefer_node_transform(self, x, edge_index) -> bool:
175
+ num_nodes, num_edges = x.shape[0], edge_index.shape[1]
176
+ if not isinstance(num_nodes, int) or not isinstance(num_edges, int):
177
+ return True
178
+ if _is_concrete(edge_index):
179
+ # Eagerly, edges are grouped by relation instead (see `_grouped_message`), which costs
180
+ # one [in, out] product per edge instead of one per node and relation.
181
+ return self.num_relations * num_nodes < num_edges
182
+ in_per_block = self.in_channels_l // (self.num_blocks or 1)
183
+ return self.num_relations * num_nodes <= num_edges * in_per_block
184
+
185
+ def _relation_features(self, x):
186
+ """Returns ``x @ W_r`` for every relation ``r`` and node, flattened to ``[R * N, out]``."""
187
+ weight = self._get_weight()
188
+ if x is None: # featureless: node i's input is the one-hot e_i, so x @ W_r is row i of W_r
189
+ if self.num_blocks is not None:
190
+ raise ValueError("Block decomposition does not support featureless nodes (x=None).")
191
+ h = weight
192
+ elif self.num_blocks is not None:
193
+ x_b = ops.reshape(x, (-1, self.num_blocks, self.in_channels_l // self.num_blocks))
194
+ h = ops.einsum("nbi,rbio->rnbo", x_b, weight)
195
+ else:
196
+ h = ops.einsum("ni,rio->rno", x, weight)
197
+ return ops.reshape(h, (-1, self.out_channels))
198
+
199
+ def message(self, x_j, edge_type):
200
+ if x_j is None: # look up the pre-transformed source node of every edge
201
+ return ops.take(self._node_messages, edge_type * self._num_sources + self.index_sources, axis=0)
202
+ if _is_concrete(edge_type):
203
+ return self._grouped_message(x_j, edge_type)
204
+ weight = self._get_weight()
205
+ if self.num_blocks is not None:
206
+ w_r = ops.take(weight, edge_type, axis=0) # (E, num_blocks, in_b, out_b)
207
+ x_j_b = ops.reshape(
208
+ x_j,
209
+ (-1, self.num_blocks, 1, self.in_channels_l // self.num_blocks),
210
+ )
211
+ msg = ops.matmul(x_j_b, w_r)
212
+ return ops.reshape(msg, (-1, self.out_channels))
213
+ else:
214
+ w_r = ops.take(weight, edge_type, axis=0) # (E, in_channels, out_channels)
215
+ x_j_exp = ops.expand_dims(x_j, 1)
216
+ msg = ops.squeeze(ops.matmul(x_j_exp, w_r), 1)
217
+ return msg
218
+
219
+ def _grouped_message(self, x_j, edge_type):
220
+ """Messages of edges grouped by relation, as in PyG: the edges of relation ``r`` are
221
+ multiplied with ``W_r`` together (``[edges, out]`` memory, no per-edge weight matrices)."""
222
+ weight = self._get_weight()
223
+ edge_type = np.asarray(ops.convert_to_numpy(edge_type)).astype(np.int64)
224
+ order = np.argsort(edge_type, kind="stable")
225
+ counts = np.bincount(edge_type, minlength=self.num_relations)
226
+ outs, start = [], 0
227
+ for r in np.nonzero(counts)[0]:
228
+ x_r = ops.take(x_j, order[start:start + counts[r]], axis=0)
229
+ start += counts[r]
230
+ if self.num_blocks is not None:
231
+ x_r = ops.reshape(x_r, (-1, self.num_blocks, self.in_channels_l // self.num_blocks))
232
+ out = ops.reshape(ops.einsum("ebi,bio->ebo", x_r, weight[int(r)]), (-1, self.out_channels))
233
+ else:
234
+ out = ops.matmul(x_r, weight[int(r)])
235
+ outs.append(out)
236
+ if not outs:
237
+ return ops.zeros((0, self.out_channels), dtype=x_j.dtype)
238
+ inverse = np.empty_like(order)
239
+ inverse[order] = np.arange(len(order))
240
+ return ops.take(ops.concatenate(outs, axis=0), inverse, axis=0)
241
+
242
+ def aggregate(self, inputs, edge_index=None, index=None, edge_type=None, dim_size=None, **kwargs):
243
+ if index is None and edge_index is not None:
244
+ index = edge_index[1]
245
+ if self.aggr == "mean" and edge_type is not None and index is not None:
246
+ one_hot = ops.one_hot(edge_type, self.num_relations)
247
+ norm = scatter(one_hot, index, dim=0, dim_size=dim_size, reduce="sum")
248
+ norm_per_edge = ops.take(norm, index, axis=0)
249
+ edge_type_expanded = ops.expand_dims(edge_type, -1)
250
+ norm_val = ops.take_along_axis(norm_per_edge, edge_type_expanded, axis=1)
251
+ norm_val = ops.maximum(norm_val, 1.0)
252
+ inputs = inputs / ops.cast(norm_val, inputs.dtype)
253
+ return scatter(inputs, index, dim=0, dim_size=dim_size, reduce="sum")
254
+ return super().aggregate(inputs, edge_index=edge_index, index=index, dim_size=dim_size, **kwargs)
255
+
256
+
257
+ def _is_concrete(t) -> bool:
258
+ """Whether ``t`` has values on the host now (not traced, symbolic or on torch's meta device)."""
259
+ from k3_node.layers.conv.utils import is_tracing
260
+ from k3_node.ops.host import _in_shape_inference, _is_meta
261
+
262
+ return t is not None and not is_tracing(t) and not _in_shape_inference() and not _is_meta(t)
263
+
264
+
265
+ class FastRGCNConv(RGCNConv):
266
+ r"""See :class:`RGCNConv`.
267
+
268
+ Example:
269
+ ```python
270
+ import numpy as np
271
+ from k3_node.layers import FastRGCNConv
272
+
273
+ x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
274
+ edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
275
+ edge_type = np.random.randint(0, 3, size=(30,)) # relation type of each edge
276
+
277
+ layer = FastRGCNConv(in_channels=8, out_channels=16, num_relations=3)
278
+ out = layer(x, edge_index, edge_type)
279
+ print(tuple(out.shape)) # (10, 16)
280
+ ```
281
+ """
282
+
283
+
284
+ class CuGraphRGCNConv(RGCNConv):
285
+ r"""Fallback for CuGraphRGCNConv.
286
+
287
+ Example:
288
+ ```python
289
+ import numpy as np
290
+ from k3_node.layers import CuGraphRGCNConv
291
+
292
+ x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
293
+ edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
294
+ edge_type = np.random.randint(0, 3, size=(30,)) # relation type of each edge
295
+
296
+ layer = CuGraphRGCNConv(in_channels=8, out_channels=16, num_relations=3)
297
+ out = layer(x, edge_index, edge_type)
298
+ print(tuple(out.shape)) # (10, 16)
299
+ ```
300
+ """
301
+ def __init__(
302
+ self,
303
+ in_channels: int,
304
+ out_channels: int,
305
+ num_relations: int,
306
+ num_bases: Optional[int] = None,
307
+ aggr: str = "mean",
308
+ root_weight: bool = True,
309
+ bias: bool = True,
310
+ **kwargs,
311
+ ):
312
+ super().__init__(
313
+ in_channels=in_channels,
314
+ out_channels=out_channels,
315
+ num_relations=num_relations,
316
+ num_bases=num_bases,
317
+ aggr=aggr,
318
+ root_weight=root_weight,
319
+ bias=bias,
320
+ **kwargs,
321
+ )