def compute_blocks(self) -> list:
        """Extracts DGL blocks from `MiniBatch` to construct graphical
        structures and ID mappings.
        """
        from dgl.convert import create_block, EID, NID

        is_heterogeneous = isinstance(
            self.sampled_subgraphs[0].sampled_csc, Dict
        )

        # Casts to minimum dtype in-place and returns self.
        def cast_to_minimum_dtype(v: CSCFormatBase):
            # Checks if number of vertices and edges fit into an int32.
            dtype = (
                torch.int32
                if max(v.indptr.size(0) - 2, v.indices.size(0))
                <= torch.iinfo(torch.int32).max
                else torch.int64
            )
            v.indptr = v.indptr.to(dtype)
            v.indices = v.indices.to(dtype)
            return v

        blocks = []
        for subgraph in self.sampled_subgraphs:
            original_row_node_ids = subgraph.original_row_node_ids
            assert (
                original_row_node_ids is not None
            ), "Missing `original_row_node_ids` in sampled subgraph."
            original_column_node_ids = subgraph.original_column_node_ids
            assert (
                original_column_node_ids is not None
            ), "Missing `original_column_node_ids` in sampled subgraph."
            if is_heterogeneous:
                node_types = set()
                sampled_csc = {}
                for v in subgraph.sampled_csc.values():
                    cast_to_minimum_dtype(v)
                for etype, v in subgraph.sampled_csc.items():
                    etype_tuple = etype_str_to_tuple(etype)
                    node_types.add(etype_tuple[0])
                    node_types.add(etype_tuple[2])
                    sampled_csc[etype_tuple] = (
                        "csc",
                        (
                            v.indptr,
                            v.indices,
                            torch.arange(
                                0,
                                len(v.indices),
                                device=v.indptr.device,
                                dtype=v.indptr.dtype,
                            ),
                        ),
                    )
                num_src_nodes = {
                    ntype: (
                        original_row_node_ids[ntype].size(0)
                        if original_row_node_ids.get(ntype) is not None
                        else 0
                    )
                    for ntype in node_types
                }
                num_dst_nodes = {
                    ntype: (
                        original_column_node_ids[ntype].size(0)
                        if original_column_node_ids.get(ntype) is not None
                        else 0
                    )
                    for ntype in node_types
                }
            else:
                sampled_csc = cast_to_minimum_dtype(subgraph.sampled_csc)
                sampled_csc = (
                    "csc",
                    (
                        sampled_csc.indptr,
                        sampled_csc.indices,
                        torch.arange(
                            0,
                            len(sampled_csc.indices),
                            device=sampled_csc.indptr.device,
                            dtype=sampled_csc.indptr.dtype,
                        ),
                    ),
                )
                num_src_nodes = original_row_node_ids.size(0)
                num_dst_nodes = original_column_node_ids.size(0)
            blocks.append(
                create_block(
                    sampled_csc,
                    num_src_nodes=num_src_nodes,
                    num_dst_nodes=num_dst_nodes,
                    node_count_check=False,
                )
            )

        if is_heterogeneous:
            # Assign reverse node ids to the outermost layer's source nodes.
            for node_type, reverse_ids in self.sampled_subgraphs[
                0
            ].original_row_node_ids.items():
                blocks[0].srcnodes[node_type].data[NID] = reverse_ids
            # Assign reverse edges ids.
            for block, subgraph in zip(blocks, self.sampled_subgraphs):
                if subgraph.original_edge_ids is not None:
                    for (
                        edge_type,
                        reverse_ids,
                    ) in subgraph.original_edge_ids.items():
                        block.edges[etype_str_to_tuple(edge_type)].data[
                            EID
                        ] = reverse_ids
        else:
            blocks[0].srcdata[NID] = self.sampled_subgraphs[
                0
            ].original_row_node_ids
            # Assign reverse edges ids.
            for block, subgraph in zip(blocks, self.sampled_subgraphs):
                if subgraph.original_edge_ids is not None:
                    block.edata[EID] = subgraph.original_edge_ids
        return blocks
Extracts DGL blocks from `MiniBatch` to construct graphical
        structures and ID mappings.
        
python/dgl/graphbolt/minibatch.py