11import re
2+ import numba
23
34import torch
45import numpy as np
56import scipy .sparse as sparse
67
78
9+ @numba .njit
10+ def reindex (node_idx , col ):
11+ node_dict = dict ()
12+ cnt = 0
13+ for i in node_idx :
14+ node_dict [i ] = cnt
15+ cnt += 1
16+ new_col = [node_dict [i ] for i in col ]
17+ return np .array (new_col )
18+
19+
820class Data (object ):
921 r"""A plain old python object modeling a single graph with various
1022 (optional) attributes:
@@ -184,6 +196,12 @@ def _build_adj_(self):
184196 if self .__adj is not None :
185197 return
186198 num_edges = self .edge_index .shape [1 ]
199+
200+ self .edge_row , col = self .edge_index .cpu ()
201+ self .edge_col = col .numpy ()
202+
203+ self .node_idx = torch .unique (self .edge_index ).cpu ().numpy ()
204+
187205 edge_index_np = self .edge_index .cpu ().numpy ()
188206 num_nodes = self .x .shape [0 ]
189207 edge_attr_np = np .ones (num_edges )
@@ -205,7 +223,9 @@ def subgraph(self, node_idx):
205223 edge_attr = torch .from_numpy (adj_coo .data ).to (self .x .device )
206224 edge_index = torch .from_numpy (np .stack ([row , col ], axis = 0 )).to (self .x .device ).long ()
207225 keys = self .keys
208- attrs = {key : self [key ][node_idx ] for key in keys if "edge" not in key }
226+
227+ print (keys )
228+ attrs = {key : self [key ][node_idx ] for key in keys if "edge" not in key and "node_idx" not in key }
209229 attrs ["edge_index" ] = edge_index
210230 if edge_attr is not None :
211231 attrs ["edge_attr" ] = edge_attr
@@ -243,37 +263,32 @@ def sample_adj(self, batch, size=-1, replace=True):
243263 adj = self .__adj [batch ].tocsr ()
244264 batch_size = len (batch )
245265 if size == - 1 :
246- adj = adj .tocoo ()
247- row , col = torch .from_numpy (adj .row ), torch .from_numpy (adj .col )
248- node_idx = torch .unique (col )
266+ row , col = self .edge_row , self .edge_col
267+ _node_idx = self .node_idx
249268 else :
250269 indices = torch .from_numpy (adj .indices )
251270 indptr = torch .from_numpy (adj .indptr )
252271 node_idx , (row , col ) = self ._sample_adj (batch_size , indices , indptr , size )
253- col = col .numpy ()
254- _node_idx = node_idx .numpy ()
272+ col = col .numpy ()
273+ _node_idx = node_idx .numpy ()
255274
256275 # Reindexing: target nodes are always put at the front
257- _node_idx = list ( batch ) + list ( set ( _node_idx ). difference ( set ( batch )))
258- node_dict = { val : key for key , val in enumerate ( _node_idx )}
259- new_col = torch .LongTensor ([ node_dict [ i ] for i in col ] )
276+ _node_idx = np . concatenate (( batch , np . setdiff1d ( _node_idx , batch )))
277+
278+ new_col = torch .as_tensor ( reindex ( _node_idx , col ), dtype = torch . long )
260279 edge_index = torch .stack ([row .long (), new_col ])
261280
262- node_idx = torch .Tensor (_node_idx ) .long ( ).to (self .x .device )
281+ node_idx = torch .as_tensor (_node_idx , dtype = torch .long ).to (self .x .device )
263282 edge_index = edge_index .long ().to (self .x .device )
264283 return node_idx , edge_index
265284
266285 def _sample_adj (self , batch_size , indices , indptr , size ):
267- indptr = indptr
268- row_counts = torch .Tensor ([indptr [i ] - indptr [i - 1 ] for i in range (1 , len (indptr ))])
286+ row_counts = torch .as_tensor ([indptr [i ] - indptr [i - 1 ] for i in range (1 , len (indptr ))]).long ()
269287
270- # if not replace:
271- # edge_cols = [col[indptr[i]: indptr[i+1]] for i in range(len(indptr)-1)]
272- # edge_cols = [np.random.choice(x, min(size, len(x)), replace=False) for x in edge_cols]
273- # else:
274288 rand = torch .rand (batch_size , size )
275289 rand = rand * row_counts .view (- 1 , 1 )
276290 rand = rand .long ()
291+
277292 rand = rand + indptr [:- 1 ].view (- 1 , 1 )
278293 edge_cols = indices [rand ].view (- 1 )
279294 row = torch .arange (0 , batch_size ).view (- 1 , 1 ).repeat (1 , size ).view (- 1 )
0 commit comments