Ran into this error during CI:
https://github.com/awslabs/graphstorm/actions/runs/15907555054/job/44866847860?pr=1288
[2025-06-26T16:53:30.453Z] =================================== FAILURES ===================================
[2025-06-26T16:53:30.453Z] _____________________________ test_parse_edge_data _____________________________
[2025-06-26T16:53:30.453Z] def test_parse_edge_data():
[2025-06-26T16:53:30.453Z] np.random.seed(1)
[2025-06-26T16:53:30.453Z] with tempfile.TemporaryDirectory() as tmpdirname:
[2025-06-26T16:53:30.453Z] str_src_ids = np.array([str(i) for i in range(10)])
[2025-06-26T16:53:30.453Z] str_dst_ids = np.array([str(i) for i in range(15)])
[2025-06-26T16:53:30.453Z] node_id_map = {"src": IdMap(str_src_ids),
[2025-06-26T16:53:30.453Z] "dst": IdMap(str_dst_ids)}
[2025-06-26T16:53:30.453Z]
[2025-06-26T16:53:30.453Z] src_ids = np.array([str(random.randint(0, 20)) for _ in range(15)])
[2025-06-26T16:53:30.453Z] dst_ids = np.array([str(random.randint(0, 25)) for _ in range(15)])
[2025-06-26T16:53:30.453Z] feat = np.random.rand(15, 10)
[2025-06-26T16:53:30.453Z] data = {
[2025-06-26T16:53:30.453Z] "src_id": src_ids,
[2025-06-26T16:53:30.453Z] "dst_id": dst_ids,
[2025-06-26T16:53:30.453Z] "feat": feat,
[2025-06-26T16:53:30.453Z] }
[2025-06-26T16:53:30.453Z]
[2025-06-26T16:53:30.453Z] feat_ops = [Noop("feat", "feat", None)]
[2025-06-26T16:53:30.453Z] label_ops = [
[2025-06-26T16:53:30.453Z] LinkPredictionProcessor(None, None, [0.7,0.1,0.2], None)]
[2025-06-26T16:53:30.453Z] data_file = os.path.join(tmpdirname, "data.parquet")
[2025-06-26T16:53:30.453Z] write_data_parquet(data, data_file)
[2025-06-26T16:53:30.453Z]
[2025-06-26T16:53:30.453Z] conf = {
[2025-06-26T16:53:30.453Z] "source_id_col": "src_id",
[2025-06-26T16:53:30.453Z] "dest_id_col": "dst_id",
[2025-06-26T16:53:30.453Z] "relation": ("src", "rel", "dst"),
[2025-06-26T16:53:30.453Z] "features": [
[2025-06-26T16:53:30.453Z] {"feature_col": "feat", "feature_name": "feat", "feature_dim": [10]}
[2025-06-26T16:53:30.453Z] ]
[2025-06-26T16:53:30.453Z] }
[2025-06-26T16:53:30.453Z] keys = ["src_id", "dst_id", "feat"]
[2025-06-26T16:53:30.453Z] src_ids, dst_ids, feat_data, _ = \
[2025-06-26T16:53:30.453Z] > parse_edge_data(data_file, feat_ops, label_ops, node_id_map,
[2025-06-26T16:53:30.453Z] partial(read_data_parquet, data_fields=keys),
[2025-06-26T16:53:30.453Z] conf, skip_nonexist_edges=True)
[2025-06-26T16:53:30.453Z] tests/unit-tests/gconstruct/test_construct_graph.py:2031:
[2025-06-26T16:53:30.453Z] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[2025-06-26T16:53:30.453Z] python/graphstorm/gconstruct/construct_graph.py:211: in parse_edge_data
[2025-06-26T16:53:30.453Z] feat_data = {key: feat[dst_exist_locs] \
[2025-06-26T16:53:30.453Z] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[2025-06-26T16:53:30.453Z] .0 = <dict_itemiterator object at 0x7f04fd70aca0>
[2025-06-26T16:53:30.453Z] > feat_data = {key: feat[dst_exist_locs] \
[2025-06-26T16:53:30.453Z] for key, feat in feat_data.items()}
[2025-06-26T16:53:30.453Z] E IndexError: arrays used as indices must be of integer (or boolean) type
[2025-06-26T16:53:30.453Z] python/graphstorm/gconstruct/construct_graph.py:211: IndexError
[2025-06-26T16:53:30.453Z] ------------------------------ Captured log call -------------------------------
[2025-06-26T16:53:30.453Z] WARNING root:id_map.py:299 source nodes of src do not exist. Skip 10 edges
[2025-06-26T16:53:30.453Z] WARNING root:id_map.py:314 dest nodes of dst do not exist. Skip 5 edges
[2025-06-26T16:53:30.453Z] =============================== warnings summary ===============================
[2025-06-26T16:53:30.453Z] ../usr/local/lib/python3.10/dist-packages/torchdata/datapipes/__init__.py:18
[2025-06-26T16:53:30.453Z] /usr/local/lib/python3.10/dist-packages/torchdata/datapipes/__init__.py:18: UserWarning:
[2025-06-26T16:53:30.453Z] ################################################################################
[2025-06-26T16:53:30.453Z] WARNING!
[2025-06-26T16:53:30.453Z] The 'datapipes', 'dataloader2' modules are deprecated and will be removed in a
[2025-06-26T16:53:30.453Z] future torchdata release! Please see https://github.com/pytorch/data/issues/1196
[2025-06-26T16:53:30.453Z] to learn more and leave feedback.
[2025-06-26T16:53:30.453Z] ################################################################################
[2025-06-26T16:53:30.453Z]
[2025-06-26T16:53:30.453Z] deprecation_warning()
[2025-06-26T16:53:30.453Z] tests/unit-tests/test_gsf.py:681
[2025-06-26T16:53:30.453Z] /graphstorm/tests/unit-tests/test_gsf.py:681: DeprecationWarning: invalid escape sequence '\g'
[2025-06-26T16:53:30.453Z] graph_name = "\graph_name"
[2025-06-26T16:53:30.453Z] tests/unit-tests/gconstruct/test_construct_graph.py::test_process_features_fp16
[2025-06-26T16:53:30.453Z] /graphstorm/python/graphstorm/gconstruct/utils.py:633: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ../torch/csrc/utils/tensor_new.cpp:274.)
[2025-06-26T16:53:30.453Z] arr = th.tensor(self._arr)
[2025-06-26T16:53:30.453Z] tests/unit-tests/gconstruct/test_construct_graph.py::test_label
[2025-06-26T16:53:30.453Z] /graphstorm/python/graphstorm/gconstruct/transform.py:1932: RuntimeWarning: invalid value encountered in cast
[2025-06-26T16:53:30.453Z] res[self.label_name] = np.int32(label)
[2025-06-26T16:53:30.453Z] -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
[2025-06-26T16:53:30.453Z] =========================== short test summary info ============================
[2025-06-26T16:53:30.453Z] FAILED tests/unit-tests/gconstruct/test_construct_graph.py::test_parse_edge_data
[2025-06-26T16:53:30.453Z] !!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
[2025-06-26T16:53:30.453Z] =================== 1 failed, 24 passed, 4 warnings in 9.92s ===================
[2025-06-26T16:53:31.344Z] Exit code: 1
Potential cause (from GenAI analysis)
The problem is in how the feature data is being indexed in parse_edge_data after filtering out non-existent edges.
In map_node_ids, when skip_nonexist_edges=True, it returns src_exist_locs and dst_exist_locs to indicate which edges should be kept. However, in parse_edge_data, the code is trying to apply these filters sequentially:
if src_exist_locs is not None:
feat_data = {key: feat[src_exist_locs] \
for key, feat in feat_data.items()}
if dst_exist_locs is not None:
feat_data = {key: feat[dst_exist_locs] \
for key, feat in feat_data.items()}
The issue is that after applying src_exist_locs, the feature data is already filtered, but then it tries to apply dst_exist_locs which still contains indices based on the original unfiltered data. This causes the indexing error because dst_exist_locs contains indices that are now out of bounds.
Ran into this error during CI:
https://github.com/awslabs/graphstorm/actions/runs/15907555054/job/44866847860?pr=1288
Potential cause (from GenAI analysis)
The problem is in how the feature data is being indexed in
parse_edge_dataafter filtering out non-existent edges.In
map_node_ids, whenskip_nonexist_edges=True, it returnssrc_exist_locsanddst_exist_locsto indicate which edges should be kept. However, inparse_edge_data, the code is trying to apply these filters sequentially:The issue is that after applying
src_exist_locs, the feature data is already filtered, but then it tries to applydst_exist_locswhich still contains indices based on the original unfiltered data. This causes the indexing error becausedst_exist_locscontains indices that are now out of bounds.