Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
df9b080
Updated graphcast implementation
szaman19 Apr 3, 2026
ec9b6b8
Add compute benchmark pdf
szaman19 Apr 13, 2026
a1ad36e
Add cost model benchmarking
szaman19 Apr 13, 2026
060db3e
Update the gather fit to use non-linear fit
szaman19 Apr 13, 2026
ecddcd6
Decompose common benchmark funcs
szaman19 Apr 17, 2026
a89e2db
Add crossover benchmark to measure communication compute tradeoff
szaman19 Apr 18, 2026
62f0248
Add running crossover benchmark and visualization
szaman19 Apr 25, 2026
1d8f90b
Add GCN implementation
szaman19 May 1, 2026
0497ab3
Add sparse implementation of GCN
szaman19 May 1, 2026
630f81e
Add fixed end to end benchmark code for OGB with sparse GCN
szaman19 May 6, 2026
b9e73e6
Update OGB end to end with command line options
szaman19 May 22, 2026
2e1f881
Fix main with sparse GCN implementation for OGB
szaman19 May 22, 2026
01ca083
Remove extra prints
szaman19 May 22, 2026
caa2cee
Completed OGB fix and experiments
szaman19 Jul 10, 2026
fc37edc
Add GraphCast benchmarks
szaman19 Jul 17, 2026
ee4a4b5
Add distributed comm pattern test for graphcast
szaman19 Jul 17, 2026
804b1e7
Updated to fix the allocation issue on graphcast
szaman19 Jul 17, 2026
d22c194
Fixing the incorrect encoder tensor
szaman19 Jul 17, 2026
145ec63
Bipartite fix with running single GPU run working
szaman19 Jul 17, 2026
af43721
Removed stub preprocess code used for fast testing
szaman19 Jul 17, 2026
fca2d70
Temporary fix on the grid out of bounds error
szaman19 Jul 17, 2026
39af504
Update inference benchmark for graphcast
szaman19 Jul 31, 2026
a8a3a71
Updated cost model code for paper
szaman19 Jul 31, 2026
13ff675
Fix stale communication pattern code
szaman19 Jul 31, 2026
6181ab0
Remove inter-node requirements
szaman19 Jul 31, 2026
3ad6957
Add experiment script
szaman19 Jul 31, 2026
a5174cf
Fix shell script with syntax error
szaman19 Jul 31, 2026
d96d01c
Update primitives to handle NaNs
szaman19 Jul 31, 2026
f0ed3cd
Remove unnecessary e2e file
szaman19 Jul 31, 2026
a3442be
Fix bug in compute code that double counted forward pass
szaman19 Jul 31, 2026
90762f6
Multi-node experiemts + removing dead code
szaman19 Jul 31, 2026
0ce080e
Update multinode to use HPC-launcher
szaman19 Aug 1, 2026
4366d94
Updated compute pred and scatter-add plotting
szaman19 Aug 1, 2026
4d4f9df
Add SpMM GCN layer and F-dependent T_comp; fix concurrency benchmark …
szaman19 Aug 1, 2026
1cac71b
Add updated compute forms and mutlinode runner
szaman19 Aug 1, 2026
2b946f0
Update visualization code and sweep across multiple graph sizes and m…
szaman19 Aug 1, 2026
adb3a8c
Update crossover code to include gcn_cpmm
szaman19 Aug 1, 2026
888b27f
Updated end to end test to include gcn spmm
szaman19 Aug 1, 2026
4f37fc3
Fix plot comute
szaman19 Aug 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 110 additions & 26 deletions DGraph/distributed/commInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,46 +47,102 @@ def compute_halo_vertices(
"""
Computes halo vertices. Supports both homogeneous and bipartite/heterogeneous relations.
"""
# Fallback for homogeneous graphs
if dst_partitioning is None:
dst_partitioning = src_partitioning

src_rank = src_partitioning[edge_list[:, 0]]
dst_rank = dst_partitioning[edge_list[:, 1]]

# Cross-rank mask: source is local, destination is remote
cross_mask = (src_rank == rank) & (dst_rank != rank)
# FIX: Cross-rank mask for pull model: source is remote, destination is local
cross_mask = (src_rank != rank) & (dst_rank == rank)

# Return unique destination vertex IDs from those edges
return torch.unique(edge_list[cross_mask, 1])
# FIX: Return unique SOURCE vertex IDs from those edges
return torch.unique(edge_list[cross_mask, 0])


def compute_local_edge_list(
global_edge_list: torch.Tensor, # [E, 2]
partitioning: torch.Tensor, # [V]
local_vertices_global: torch.Tensor, # [num_local]
halo_vertices_global: torch.Tensor, # [num_halo]
partitioning: torch.Tensor, # [V_dst] (Acts as dst_partitioning)
local_vertices_global: torch.Tensor, # [num_local], dst vertex space
halo_vertices_global: torch.Tensor, # [num_halo], src vertex space
rank: int,
src_partitioning: Optional[torch.Tensor] = None,
src_local_vertices_global: Optional[torch.Tensor] = None, # [num_src_local], src space
) -> torch.Tensor:
"""
Remaps a global edge list [E, 2] (col0=src/neighbor, col1=dst/local) into
local numbering.

The dst column (col1) maps to ``[0, num_local)``. The src column (col0) maps
into the augmented src feature buffer ``[src_local ; halo]`` that the halo
exchange produces: locally-owned src vertices -> ``[0, num_src_local)`` and
halo (remote) src vertices -> ``[num_src_local, num_src_local + num_halo)``.

For homogeneous graphs (src_partitioning=None), src and dst share one vertex
ID space (num_src_local == num_local) and a single remap table is used for
both columns. For bipartite/heterogeneous graphs, src_partitioning's vertex
space may be sized differently than partitioning's (dst) space, so a separate
src remap table is built; it must cover BOTH local and halo src vertices,
since a bipartite relation can have on-rank src vertices (e.g. every edge is
intra-rank at world_size=1, so num_halo=0 and every src is local).
"""
num_local = local_vertices_global.size(0)
num_halo = halo_vertices_global.size(0)
num_global = partitioning.size(0)
num_dst_global = partitioning.size(0)

# Filter edges owned by this rank
local_edge_mask = partitioning[global_edge_list[:, 0]] == rank
# FIX: Filter edges where the DESTINATION is owned by this rank (Index 1)
local_edge_mask = partitioning[global_edge_list[:, 1]] == rank
local_edges_global = global_edge_list[local_edge_mask]

# Build inverse map: global_id -> local_idx via scatter
g2l = torch.empty(num_global, dtype=torch.long, device=global_edge_list.device)
g2l.scatter_(0, local_vertices_global, torch.arange(num_local, device=g2l.device))
g2l.scatter_(
0,
halo_vertices_global,
torch.arange(num_local, num_local + num_halo, device=g2l.device),
# dst remap table: dst global id -> local index [0, num_local)
g2l_dst = torch.empty(
num_dst_global, dtype=torch.long, device=global_edge_list.device
)
g2l_dst.scatter_(0, local_vertices_global, torch.arange(num_local, device=g2l_dst.device))

if src_partitioning is None:
# Homogeneous: src and dst share one ID space and one remap table. Local
# src vertices are already mapped to [0, num_local) via g2l_dst above.
g2l_dst.scatter_(
0,
halo_vertices_global,
torch.arange(num_local, num_local + num_halo, device=g2l_dst.device),
)
g2l_src = g2l_dst
else:
# Heterogeneous/bipartite: src vertices live in the (differently-sized)
# src vertex space and need their own remap table covering both the
# locally-owned src vertices and the halo (remote) src vertices, matching
# the augmented src feature buffer layout [src_local ; halo].
if src_local_vertices_global is None:
raise ValueError(
"src_local_vertices_global is required for bipartite/heterogeneous "
"edge lists (src_partitioning is not None)."
)
num_src_global = src_partitioning.size(0)
num_src_local = src_local_vertices_global.size(0)
g2l_src = torch.empty(
num_src_global, dtype=torch.long, device=global_edge_list.device
)
# local src -> [0, num_src_local)
g2l_src.scatter_(
0,
src_local_vertices_global,
torch.arange(num_src_local, device=g2l_src.device),
)
# halo src -> [num_src_local, num_src_local + num_halo)
g2l_src.scatter_(
0,
halo_vertices_global,
torch.arange(
num_src_local, num_src_local + num_halo, device=g2l_src.device
),
)

# Remap to local numbering: col0 via src table, col1 via dst table.
local_edge_list = torch.stack(
[g2l_src[local_edges_global[:, 0]], g2l_dst[local_edges_global[:, 1]]], dim=1
)

# Remap to local numbering
local_edge_list = g2l[local_edges_global]

return local_edge_list

Expand Down Expand Up @@ -169,25 +225,53 @@ def build_communication_pattern(
partitioning: torch.Tensor,
rank: int,
world_size: int,
src_partitioning: Optional[torch.Tensor] = None,
) -> CommunicationPattern:
"""

Args:
global_edge_list (torch.Tensor)): A tensor of shape [E, 2]
partitioning (torch.Tensor): A tensor of shape [V]
global_edge_list (torch.Tensor)): A tensor of shape [E, 2], col0=src/neighbor,
col1=dst/local (dst is always the aggregation target and is guaranteed local)
partitioning (torch.Tensor): A tensor of shape [V_dst]; the dst/local-vertex
partitioning
rank (int): Rank of this process
world_size (int): Total number of processes
src_partitioning (Optional[torch.Tensor]): A tensor of shape [V_src], the
partitioning of the (possibly differently-sized) neighbor/src vertex
space, for bipartite/heterogeneous relations. Defaults to `partitioning`
for homogeneous graphs.

Returns:
CommunicationPattern
"""
src_part = partitioning if src_partitioning is None else src_partitioning

local_verts = compute_local_vertices(partitioning, rank)
halo_verts = compute_halo_vertices(global_edge_list, partitioning, rank)
src_local_verts = (
local_verts
if src_partitioning is None
else compute_local_vertices(src_partitioning, rank)
)

halo_verts = compute_halo_vertices(
global_edge_list, src_part, rank, dst_partitioning=partitioning
)
local_edges = compute_local_edge_list(
global_edge_list, partitioning, local_verts, halo_verts, rank
global_edge_list,
partitioning,
local_verts,
halo_verts,
rank,
src_partitioning=src_partitioning,
src_local_vertices_global=src_local_verts,
)
send_idx, send_off = compute_boundary_vertices(
global_edge_list, partitioning, local_verts, rank, world_size
global_edge_list,
src_part,
src_local_verts,
rank,
world_size,
dst_partitioning=partitioning,
)
comm = compute_comm_map(send_off, world_size)
recv_off, recv_back_off = compute_recv_offsets(comm, rank)
Expand Down
34 changes: 0 additions & 34 deletions DGraph/utils.py

This file was deleted.

Loading