def get_bga(adj, strategy, num_bgraph, **kwargs): num_node = adj.size(-1) dv = adj.device() if strategy == "admm": if num_node < 80: bipartite_graphs_dense = admm_bga( adj.to_dense().to(torch.double), M=num_bgraph, **kwargs ) beta = torch.zeros(num_node, num_bgraph, dtype=torch.bool, device=dv) bipartite_graphs = [] for i, B in enumerate(bipartite_graphs_dense): _, vtx_color, _ = is_bipartite_fix(B, fix_flag=True) beta[:, i] = torch.as_tensor(vtx_color) bipartite_graphs.append(SparseTensor.from_dense(B)) return bipartite_graphs, beta else: bipartite_graphs, beta, partptr, perm = admm_lbga_ray( adj, num_bgraph, **kwargs ) elif strategy == "amfs": bipartite_graphs, beta = amfs(adj, level=num_bgraph, **kwargs) else: raise RuntimeError( f"{str(strategy)} is not a valid numerical decomposition algorithm " f"supported at present." ) bipartite_graphs = [SparseTensor.from_scipy(B).to(dv) for B in bipartite_graphs] return bipartite_graphs, beta
def forward(self, x, adj=None, theta=None): theta = SparseTensor.from_dense(theta) x = self.gcn1(x, adj) x = self.gcn2(x.float(), theta.float()) x = self.relu(x) x = self.dropout(x) return x
def to_cpx(mat, layout="csr", dtype=None): assert layout in SparseLayouts import cupy as cp import cupyx.scipy as xcipy if isinstance(mat, torch.Tensor): assert mat.dim() == 2 assert mat.is_cuda if mat.is_sparse: smt = SparseTensor.from_torch_sparse_coo_tensor(mat) else: smt = SparseTensor.from_dense(mat) elif isinstance(mat, SparseTensor): assert mat.dim() == 2 assert mat.is_cuda() smt = mat elif isinstance(mat, xcipy.sparse.spmatrix): assert mat.ndim == 2 cls = { "csr": xcipy.sparse.csr_matrix, "csc": xcipy.sparse.csc_matrix, "coo": xcipy.sparse.coo_matrix, }[layout] smt = cls(mat) return smt else: raise RuntimeError shape = smt.sparse_sizes() if layout == "coo": row, col, value = smt.coo() row = cp.asarray(row.detach()) col = cp.asarray(col.detach()) value = (cp.asarray(value.detach()) if smt.has_value() else cp.ones(smt.nnz(), dtype=dtype)) return xcipy.sparse.coo_matrix((value, (row, col)), shape) elif layout == "csr": rowptr, col, value = smt.csr() rowptr = cp.asarray(rowptr.detach()) col = cp.asarray(col.detach()) value = (cp.asarray(value.detach()) if smt.has_value() else cp.ones(smt.nnz(), dtype=dtype)) return xcipy.sparse.csr_matrix((value, col, rowptr), shape) elif layout == "csc": colptr, row, value = smt.csc() colptr = cp.asarray(colptr.detach()) row = cp.asarray(row.detach()) value = (cp.asarray(value.detach()) if smt.has_value() else cp.ones(smt.nnz(), dtype=dtype)) return xcipy.sparse.csc_matrix((value, row, colptr), shape) else: raise RuntimeError( f"{layout} is not one of valid sparse formats `coo`, `csr` and `csc`." )
def test_laplace(lap_type, device): N = 6 A = torch.rand(N, N) A = A + A.t() A.fill_diagonal_(0) spA = SparseTensor.from_dense(A) L = laplace(spA, lap_type).to_dense() print("\n:", L)
def __init__( self, G: Graph, k: int = 8, in_channels: int = 1, order: int = 16, strategy: str = "admm", level: int = 1, lam_max: float = 2.0, zero_dc: bool = False, **kwargs, ): self.adj = G N = self.adj.size(-1) self.lam_max = lam_max self.strategy = strategy self.num_bgraph = level device = self.adj.device() dtype = self.adj.dtype() if strategy == "admm": if N < 80: bipartite_graphs_dense = admm_bga( self.adj.to_dense().to(torch.double), M=level, **kwargs ) beta = bipartite_graphs_dense.new_zeros(N, level).to(torch.bool) bipartite_graphs = [] bipartite_graphs_dense = bipartite_graphs_dense.to(dtype).to(device) for i, B in enumerate(bipartite_graphs_dense): _, vtx_color, _ = is_bipartite_fix(B, fix_flag=True) beta[:, i] = torch.as_tensor(vtx_color) bipartite_graphs.append(SparseTensor.from_dense(B)) else: bipartite_graphs, beta, self.partptr, self.perm = admm_lbga_ray( self.adj, level, **kwargs ) bipartite_graphs = [ SparseTensor.from_scipy(B).to(dtype).to(device) for B in bipartite_graphs ] elif strategy == "amfs": bipartite_graphs, beta = amfs(self.adj, level=self.num_bgraph, **kwargs) bipartite_graphs = [ SparseTensor.from_scipy(B).to(dtype).to(device) for B in bipartite_graphs ] else: raise RuntimeError( f"{strategy} is not a valid numerical decomposition " f"algorithm supported at present." ) super().__init__( bipartite_graphs, beta, k, in_channels, order, lam_max, zero_dc )
def to_torch_sparse(mat): if isinstance(mat, torch.Tensor): if not mat.is_sparse: stm = SparseTensor.from_dense(mat) else: stm = SparseTensor.from_torch_sparse_coo_tensor(mat) elif isinstance(mat, np.ndarray): stm = SparseTensor.from_dense(torch.as_tensor(mat)) elif isinstance(mat, spmatrix): stm = SparseTensor.from_scipy(mat) elif isinstance(mat, SparseTensor): stm = mat else: raise TypeError(f"{type(mat)} not supported now") return stm
def test_getitem(dtype, device): mat = torch.randn(50, 40, dtype=dtype, device=device) mat = SparseTensor.from_dense(mat) idx1 = torch.randint(0, 50, (10, ), dtype=torch.long, device=device) idx2 = torch.randint(0, 40, (10, ), dtype=torch.long, device=device) assert mat[:10, :10].sizes() == [10, 10] assert mat[..., :10].sizes() == [50, 10] assert mat[idx1, idx2].sizes() == [10, 10] assert mat[idx1.tolist()].sizes() == [10, 40]
def test_transform(self, device, dtype): M, N = 2, 32 K = 30 Bs = [] beta = [] bpg, bt = rand_bipartite(N // 2, N - N // 2, p=0.2, dtype=dtype, device=device, return_partition=True) Bs.append(bpg) beta.append(bt) mask = Bs[0].to_dense() != 0 for i in range(M - 1): bpg, bt = rand_bipartite( N // 2, N - N // 2, p=0.2, dtype=dtype, device=device, return_partition=True, ) dense = bpg.to_dense() temp_mask = dense != 0 dense[mask] = 0 mask = temp_mask + mask Bs.append(SparseTensor.from_dense(dense)) if i % 2 == 0: beta.append(bt) else: beta.append(~bt) beta = torch.stack(beta).T qmf = QmfCore(bipartite_graphs=Bs, beta=beta, order=K) x = torch.rand(N, dtype=dtype, device=device) y = qmf.analyze(x) assert y.shape == (2**M, N, 1) z = qmf.synthesize(y) assert z.shape == (2**M, N, 1) assert (z.sum(0).squeeze() - x).abs().sum() != 0 z.squeeze_() f_hat = z.sum(0) dis = (f_hat - x).abs() pf = snr(f_hat, x) ppprint(dis, pf)
def make_adjmatrix(self, data_dir, fname, zerolen_tripids=None): """ @fname :: trips f : "preprocessed_entire_porto.h5" ex) f["trips/{}".format(num)] where the num is bet 1~all including zerolen_trips make_adjmatrix(data_dir, "preprocessed_entire_porto.h5",) """ file_path = data_dir / self.dataset_name / fname seq_vocabs = open(file_path, "r") # nodes ~ vocabs : self.vocab_start ~ self.vocab_size nodes = list(range(self.vocab_size)) adj_matrix = np.zeros((len(nodes), len(nodes)), ) # (nodes,nodes) # print(adj_matrix.shape) with h5py.File(file_path, 'r') as f: total_len = len(f["trips"].keys()) for num in range(total_len): if num % 3000 == 2999: print("Scanned {} trips out of {}".format( num + 1, total_len)) if num + 1 in set(zerolen_tripids): continue trip = f["trips/" + str(num + 1)][()] # nd.array (2,traj_len) if trip.shape[1] == 1: continue # bc there cannot be any connention try: trip = np.array( self.trip2seq(trip)) # seq of vocabs : (len_trip) trip_pre, trip_curr = trip[:-1], trip[1:] conn = np.array([[pre, curr] for pre, curr in zip(trip_pre, trip_curr) ]) conn = np.unique(conn, axis=0) #(#conn, 2) adj_matrix[conn[:, 0], conn[:, 1]] = 1 except: conn = conn[np.all(conn != 'UNK', axis=1)].astype(int) # (#conn, 2) adj_matrix[conn[:, 0], conn[:, 1]] = 1 adj_matrix = adj_matrix[self.vocab_start:, self.vocab_start:] adj_matrix[np.arange(adj_matrix.shape[0]), np.arange(adj_matrix.shape[0])] = 0 self.adj_matrix = SparseTensor.from_dense(torch.from_numpy(adj_matrix)) return adj_matrix
def to_scipy(mat, layout="csr", dtype=None): assert layout in SparseLayouts if isinstance(mat, torch.Tensor): if not mat.is_sparse: smt = SparseTensor.from_dense(mat).to_scipy(layout, dtype) else: smt = SparseTensor.from_torch_sparse_coo_tensor(mat).to_scipy( layout, dtype) elif isinstance(mat, SparseTensor): smt = mat.to_scipy(layout, dtype) elif isinstance(mat, (spmatrix, np.ndarray)): cls = {"csr": csr_matrix, "csc": csc_matrix, "coo": coo_matrix}[layout] smt = cls(mat) else: raise TypeError(f"{type(mat)} is not supported now or invalid") return smt
def test_getitem(dtype, device): m = 50 n = 40 k = 10 mat = torch.randn(m, n, dtype=dtype, device=device) mat = SparseTensor.from_dense(mat) idx1 = torch.randint(0, m, (k,), dtype=torch.long, device=device) idx2 = torch.randint(0, n, (k,), dtype=torch.long, device=device) bool1 = torch.zeros(m, dtype=torch.bool, device=device) bool2 = torch.zeros(n, dtype=torch.bool, device=device) bool1.scatter_(0, idx1, 1) bool2.scatter_(0, idx2, 1) # idx1 and idx2 may have duplicates k1_bool = bool1.nonzero().size(0) k2_bool = bool2.nonzero().size(0) idx1np = idx1.cpu().numpy() idx2np = idx2.cpu().numpy() bool1np = bool1.cpu().numpy() bool2np = bool2.cpu().numpy() idx1list = idx1np.tolist() idx2list = idx2np.tolist() bool1list = bool1np.tolist() bool2list = bool2np.tolist() assert mat[:k, :k].sizes() == [k, k] assert mat[..., :k].sizes() == [m, k] assert mat[idx1, idx2].sizes() == [k, k] assert mat[idx1np, idx2np].sizes() == [k, k] assert mat[idx1list, idx2list].sizes() == [k, k] assert mat[bool1, bool2].sizes() == [k1_bool, k2_bool] assert mat[bool1np, bool2np].sizes() == [k1_bool, k2_bool] assert mat[bool1list, bool2list].sizes() == [k1_bool, k2_bool] assert mat[idx1].sizes() == [k, n] assert mat[idx1np].sizes() == [k, n] assert mat[idx1list].sizes() == [k, n] assert mat[bool1].sizes() == [k1_bool, n] assert mat[bool1np].sizes() == [k1_bool, n] assert mat[bool1list].sizes() == [k1_bool, n]
def test_batch(): torch_geometric.set_debug(True) x1 = torch.tensor([1, 2, 3], dtype=torch.float) x1_sp = SparseTensor.from_dense(x1.view(-1, 1)) e1 = torch.tensor([[0, 1, 1, 2], [1, 0, 2, 1]]) adj1 = SparseTensor.from_edge_index(e1) s1 = '1' array1 = ['1', '2'] x2 = torch.tensor([1, 2], dtype=torch.float) x2_sp = SparseTensor.from_dense(x2.view(-1, 1)) e2 = torch.tensor([[0, 1], [1, 0]]) adj2 = SparseTensor.from_edge_index(e2) s2 = '2' array2 = ['3', '4', '5'] x3 = torch.tensor([1, 2, 3, 4], dtype=torch.float) x3_sp = SparseTensor.from_dense(x3.view(-1, 1)) e3 = torch.tensor([[0, 1, 1, 2, 2, 3], [1, 0, 2, 1, 3, 2]]) adj3 = SparseTensor.from_edge_index(e3) s3 = '3' array3 = ['6', '7', '8', '9'] data1 = Data(x=x1, x_sp=x1_sp, edge_index=e1, adj=adj1, s=s1, array=array1, num_nodes=3) data2 = Data(x=x2, x_sp=x2_sp, edge_index=e2, adj=adj2, s=s2, array=array2, num_nodes=2) data3 = Data(x=x3, x_sp=x3_sp, edge_index=e3, adj=adj3, s=s3, array=array3, num_nodes=4) batch = Batch.from_data_list([data1]) assert str(batch) == ('Batch(x=[3], edge_index=[2, 4], ' 'x_sp=[3, 1, nnz=3], adj=[3, 3, nnz=4], s=[1], ' 'array=[1], num_nodes=3, batch=[3], ptr=[2])') assert batch.num_graphs == 1 assert len(batch) == 9 assert batch.x.tolist() == [1, 2, 3] assert batch.x_sp.to_dense().view(-1).tolist() == batch.x.tolist() assert batch.edge_index.tolist() == [[0, 1, 1, 2], [1, 0, 2, 1]] edge_index = torch.stack(batch.adj.coo()[:2], dim=0) assert edge_index.tolist() == batch.edge_index.tolist() assert batch.s == ['1'] assert batch.array == [['1', '2']] assert batch.num_nodes == 3 assert batch.batch.tolist() == [0, 0, 0] assert batch.ptr.tolist() == [0, 3] batch = Batch.from_data_list([data1, data2, data3], follow_batch=['s']) assert str(batch) == ('Batch(x=[9], edge_index=[2, 12], ' 'x_sp=[9, 1, nnz=9], adj=[9, 9, nnz=12], s=[3], ' 's_batch=[3], array=[3], num_nodes=9, batch=[9], ' 'ptr=[4])') assert batch.num_graphs == 3 assert len(batch) == 10 assert batch.x.tolist() == [1, 2, 3, 1, 2, 1, 2, 3, 4] assert batch.x_sp.to_dense().view(-1).tolist() == batch.x.tolist() assert batch.edge_index.tolist() == [[0, 1, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8], [1, 0, 2, 1, 4, 3, 6, 5, 7, 6, 8, 7]] edge_index = torch.stack(batch.adj.coo()[:2], dim=0) assert edge_index.tolist() == batch.edge_index.tolist() assert batch.s == ['1', '2', '3'] assert batch.s_batch.tolist() == [0, 1, 2] assert batch.array == [['1', '2'], ['3', '4', '5'], ['6', '7', '8', '9']] assert batch.num_nodes == 9 assert batch.batch.tolist() == [0, 0, 0, 1, 1, 2, 2, 2, 2] assert batch.ptr.tolist() == [0, 3, 5, 9] data = batch[0] assert str(data) == ("Data(x=[3], edge_index=[2, 4], x_sp=[3, 1, nnz=3], " "adj=[3, 3, nnz=4], s='1', array=[2], num_nodes=3)") data = batch[1] assert str(data) == ("Data(x=[2], edge_index=[2, 2], x_sp=[2, 1, nnz=2], " "adj=[2, 2, nnz=2], s='2', array=[3], num_nodes=2)") data = batch[2] assert str(data) == ("Data(x=[4], edge_index=[2, 6], x_sp=[4, 1, nnz=4], " "adj=[4, 4, nnz=6], s='3', array=[4], num_nodes=4)") assert len(batch.index_select([1, 0])) == 2 assert len(batch.index_select(torch.tensor([1, 0]))) == 2 assert len(batch.index_select(torch.tensor([True, False]))) == 1 assert len(batch.index_select(np.array([1, 0], dtype=np.int64))) == 2 assert len(batch.index_select(np.array([True, False]))) == 1 assert len(batch[:2]) == 2 data_list = batch.to_data_list() assert len(data_list) == 3 assert len(data_list[0]) == 7 assert data_list[0].x.tolist() == [1, 2, 3] assert data_list[0].x_sp.to_dense().view(-1).tolist() == [1, 2, 3] assert data_list[0].edge_index.tolist() == [[0, 1, 1, 2], [1, 0, 2, 1]] edge_index = torch.stack(data_list[0].adj.coo()[:2], dim=0) assert edge_index.tolist() == data_list[0].edge_index.tolist() assert data_list[0].s == '1' assert data_list[0].array == ['1', '2'] assert data_list[0].num_nodes == 3 assert len(data_list[1]) == 7 assert data_list[1].x.tolist() == [1, 2] assert data_list[1].x_sp.to_dense().view(-1).tolist() == [1, 2] assert data_list[1].edge_index.tolist() == [[0, 1], [1, 0]] edge_index = torch.stack(data_list[1].adj.coo()[:2], dim=0) assert edge_index.tolist() == data_list[1].edge_index.tolist() assert data_list[1].s == '2' assert data_list[1].array == ['3', '4', '5'] assert data_list[1].num_nodes == 2 assert len(data_list[2]) == 7 assert data_list[2].x.tolist() == [1, 2, 3, 4] assert data_list[2].x_sp.to_dense().view(-1).tolist() == [1, 2, 3, 4] assert data_list[2].edge_index.tolist() == [[0, 1, 1, 2, 2, 3], [1, 0, 2, 1, 3, 2]] edge_index = torch.stack(data_list[2].adj.coo()[:2], dim=0) assert edge_index.tolist() == data_list[2].edge_index.tolist() assert data_list[2].s == '3' assert data_list[2].array == ['6', '7', '8', '9'] assert data_list[2].num_nodes == 4 torch_geometric.set_debug(True)
def read_planetoid_data(folder, prefix): names = ['x', 'tx', 'allx', 'y', 'ty', 'ally', 'graph', 'test.index'] items = [read_file(folder, prefix, name) for name in names] x, tx, allx, y, ty, ally, graph, test_index = items train_index = torch.arange(y.size(0), dtype=torch.long) val_index = torch.arange(y.size(0), y.size(0) + 500, dtype=torch.long) sorted_test_index = test_index.sort()[0] if prefix.lower() == 'citeseer': # There are some isolated nodes in the Citeseer graph, resulting in # none consecutive test indices. We need to identify them and add them # as zero vectors to `tx` and `ty`. len_test_indices = (test_index.max() - test_index.min()).item() + 1 tx_ext = torch.zeros(len_test_indices, tx.size(1)) tx_ext[sorted_test_index - test_index.min(), :] = tx ty_ext = torch.zeros(len_test_indices, ty.size(1)) ty_ext[sorted_test_index - test_index.min(), :] = ty tx, ty = tx_ext, ty_ext if prefix.lower() == 'nell.0.001': tx_ext = torch.zeros(len(graph) - allx.size(0), x.size(1)) tx_ext[sorted_test_index - allx.size(0)] = tx ty_ext = torch.zeros(len(graph) - ally.size(0), y.size(1)) ty_ext[sorted_test_index - ally.size(0)] = ty tx, ty = tx_ext, ty_ext x = torch.cat([allx, tx], dim=0) x[test_index] = x[sorted_test_index] # Creating feature vectors for relations. row, col, value = SparseTensor.from_dense(x).coo() rows, cols, values = [row], [col], [value] mask1 = index_to_mask(test_index, size=len(graph)) mask2 = index_to_mask(torch.arange(allx.size(0), len(graph)), size=len(graph)) mask = ~mask1 | ~mask2 isolated_index = mask.nonzero(as_tuple=False).view(-1)[allx.size(0):] rows += [isolated_index] cols += [torch.arange(isolated_index.size(0)) + x.size(1)] values += [torch.ones(isolated_index.size(0))] x = SparseTensor(row=torch.cat(rows), col=torch.cat(cols), value=torch.cat(values)) else: x = torch.cat([allx, tx], dim=0) x[test_index] = x[sorted_test_index] y = torch.cat([ally, ty], dim=0).max(dim=1)[1] y[test_index] = y[sorted_test_index] train_mask = index_to_mask(train_index, size=y.size(0)) val_mask = index_to_mask(val_index, size=y.size(0)) test_mask = index_to_mask(test_index, size=y.size(0)) edge_index = edge_index_from_dict(graph, num_nodes=y.size(0)) data = Data(x=x, edge_index=edge_index, y=y) data.train_mask = train_mask data.val_mask = val_mask data.test_mask = test_mask return data