@@ -1196,7 +1196,13 @@ def test_from_pandas_bad_node_cols_not_specified():
11961196
11971197@pytest .fixture
11981198def tgb_dataset_factory ():
1199- def _make_dataset (split : str = 'all' , with_node_feats : bool = False , thgl = False ):
1199+ def _make_dataset (
1200+ split : str = 'all' ,
1201+ with_node_feats : bool = False ,
1202+ with_edge_feats : bool = False ,
1203+ thgl = False ,
1204+ tkgl = False ,
1205+ ):
12001206 num_events , num_train , num_val = 10 , 7 , 2
12011207 train_indices = np .arange (0 , num_train )
12021208 val_indices = np .arange (num_train , num_train + num_val )
@@ -1205,7 +1211,12 @@ def _make_dataset(split: str = 'all', with_node_feats: bool = False, thgl=False)
12051211 sources = np .random .randint (0 , 1000 , size = num_events )
12061212 destinations = np .random .randint (0 , 1000 , size = num_events )
12071213 timestamps = np .arange (num_events )
1208- edge_feat = None
1214+ if not with_edge_feats :
1215+ edge_feat = None
1216+ elif with_edge_feats and not tkgl :
1217+ edge_feat = np .random .rand (num_events , 10 )
1218+ elif with_edge_feats and tkgl :
1219+ edge_feat = np .random .rand (num_events // 2 , 10 )
12091220
12101221 train_mask = np .zeros (num_events , dtype = bool )
12111222 val_mask = np .zeros (num_events , dtype = bool )
@@ -1249,6 +1260,9 @@ def _make_dataset(split: str = 'all', with_node_feats: bool = False, thgl=False)
12491260 max (sources .max (), destinations .max ()) + 1
12501261 )
12511262
1263+ if tkgl :
1264+ mock_dataset .full_data ['edge_type' ] = np .arange (num_events )
1265+
12521266 return mock_dataset
12531267
12541268 return _make_dataset
@@ -1316,6 +1330,59 @@ def _make_dataset(split: str = 'all', with_edge_type=True, with_node_type=False)
13161330 return _make_dataset
13171331
13181332
1333+ @pytest .fixture
1334+ def bad_tkgl_dataset_factory (): # Missing edge_type
1335+ def _make_dataset (split : str = 'all' ):
1336+ num_events , num_train , num_val = 10 , 7 , 2
1337+ train_indices = np .arange (0 , num_train )
1338+ val_indices = np .arange (num_train , num_train + num_val )
1339+ test_indices = np .arange (num_train + num_val , num_events )
1340+
1341+ sources = np .random .randint (0 , 1000 , size = num_events )
1342+ destinations = np .random .randint (0 , 1000 , size = num_events )
1343+ timestamps = np .arange (num_events )
1344+ edge_feat = None
1345+ w = np .random .rand (num_events , 10 )
1346+
1347+ train_mask = np .zeros (num_events , dtype = bool )
1348+ val_mask = np .zeros (num_events , dtype = bool )
1349+ test_mask = np .zeros (num_events , dtype = bool )
1350+
1351+ train_mask [train_indices ] = True
1352+ val_mask [val_indices ] = True
1353+ test_mask [test_indices ] = True
1354+
1355+ mock_dataset = MagicMock ()
1356+ mock_dataset .train_mask = train_mask
1357+ mock_dataset .val_mask = val_mask
1358+ mock_dataset .test_mask = test_mask
1359+ mock_dataset .num_edges = num_events
1360+ mock_dataset .full_data = {
1361+ 'sources' : sources ,
1362+ 'destinations' : destinations ,
1363+ 'timestamps' : timestamps ,
1364+ 'edge_feat' : edge_feat ,
1365+ 'w' : w ,
1366+ }
1367+
1368+ if split == 'all' :
1369+ 1 + max (np .max (sources ), np .max (destinations ))
1370+ else :
1371+ mask = {'train' : train_mask , 'val' : val_mask , 'test' : test_mask }[split ]
1372+ valid_src , valid_dst = sources [mask ], destinations [mask ]
1373+ 1 + max (np .max (valid_src ), np .max (valid_dst ))
1374+
1375+ mock_dataset .node_feat = None
1376+
1377+ mock_dataset .full_data ['node_label_dict' ] = {}
1378+ for i in range (5 ):
1379+ mock_dataset .full_data ['node_label_dict' ][i ] = {i : np .zeros (10 )}
1380+
1381+ return mock_dataset
1382+
1383+ return _make_dataset
1384+
1385+
13191386@pytest .fixture
13201387def tgb_seq_dataset_factory ():
13211388 def _make_dataset (
@@ -1369,11 +1436,6 @@ def _make_dataset(
13691436 return _make_dataset
13701437
13711438
1372- def test_from_tkgl ():
1373- with pytest .raises (NotImplementedError ):
1374- DGData .from_tgb ('tkgl-foo' )
1375-
1376-
13771439def test_from_bad_tgb_name ():
13781440 with pytest .raises (ValueError ):
13791441 DGData .from_tgb ('foo' )
@@ -2258,3 +2320,58 @@ def test_from_pandas_with_static_node_type():
22582320 )
22592321 assert isinstance (data , DGData )
22602322 torch .testing .assert_close (data .node_type .tolist (), node_dict ['node_type' ])
2323+
2324+
2325+ @pytest .mark .parametrize ('with_node_feats' , [True , False ])
2326+ @pytest .mark .parametrize ('with_edge_feats' , [True , False ])
2327+ @pytest .mark .parametrize ('tkgl' , [True ])
2328+ @patch ('tgb.linkproppred.dataset.LinkPropPredDataset' )
2329+ @patch .dict ('tgm.core.timedelta.TGB_TIME_DELTAS' , {'tkgl-smallpedia' : TimeDeltaDG ('D' )})
2330+ def test_from_tkgl (
2331+ mock_dataset_cls , tgb_dataset_factory , with_node_feats , with_edge_feats , tkgl
2332+ ):
2333+ dataset = tgb_dataset_factory (
2334+ with_node_feats = with_node_feats , with_edge_feats = with_edge_feats , tkgl = tkgl
2335+ )
2336+ mock_dataset_cls .return_value = dataset
2337+
2338+ mock_native_time_delta = TimeDeltaDG ('D' ) # Patched value
2339+
2340+ def _get_exp_edges ():
2341+ src , dst = dataset .full_data ['sources' ], dataset .full_data ['destinations' ]
2342+ return np .stack ([src , dst ], axis = 1 )
2343+
2344+ def _get_exp_times ():
2345+ return dataset .full_data ['timestamps' ]
2346+
2347+ def _get_exp_edge_type ():
2348+ return dataset .full_data ['edge_type' ]
2349+
2350+ def _get_exp_edge_feat ():
2351+ edge_feat_np = dataset .full_data ['edge_feat' ]
2352+ return np .concatenate ((edge_feat_np , edge_feat_np ))
2353+
2354+ data = DGData .from_tgb (name = 'tkgl-smallpedia' )
2355+ assert isinstance (data , DGData )
2356+ assert data .time_delta == mock_native_time_delta
2357+ np .testing .assert_allclose (data .edge_index .numpy (), _get_exp_edges ())
2358+ np .testing .assert_allclose (data .time .numpy (), _get_exp_times ())
2359+ np .testing .assert_allclose (data .edge_type .numpy (), _get_exp_edge_type ())
2360+ if with_edge_feats :
2361+ np .testing .assert_allclose (data .edge_x .numpy (), _get_exp_edge_feat ())
2362+
2363+ # Confirm correct dataset instantiation
2364+ mock_dataset_cls .assert_called_once_with (name = 'tkgl-smallpedia' )
2365+
2366+ if with_node_feats :
2367+ torch .testing .assert_close (data .static_node_x , torch .Tensor (dataset .node_feat ))
2368+ else :
2369+ assert data .static_node_x is None
2370+
2371+
2372+ @patch ('tgb.linkproppred.dataset.LinkPropPredDataset' )
2373+ def test_from_bad_thgl (mock_dataset_cls , bad_tkgl_dataset_factory ):
2374+ dataset = bad_tkgl_dataset_factory ()
2375+ mock_dataset_cls .return_value = dataset
2376+ with pytest .raises (ValueError ):
2377+ data = DGData .from_tgb (name = 'tkgl-smallpedia' )
0 commit comments