Different 'normalize adjacent matrix' implementation between 'dgl.nn.GraphConv' and 'dgl.nn.APPNPConv'

In ‘dgl.nn.APPNPConv’, graph convolution by normalized adjacent matrix is like:

out_degs = graph.out_degrees().float().clamp(min=1)
left_norm = th.pow(out_degs, -0.5).unsqueeze(-1)
feat_src = feat_src * left_norm
# convolution operations, update_all and etc.
in_degs = graph.in_degrees().float().clamp(min=1)
right_norm = th.pow(in_degs, -0.5).unsqueeze(-1)
feat_dst = feat_dst * right_norm

But in ‘dgl.nn.GraphConv’, message propagation by normalized adjacent matrix is like:

in_degs = graph.in_degrees().float().clamp(min=1)
norm = th.pow(in_degs, -0.5).unsqueeze(-1)
feat_src = feat_src * norm
# convolution operations, update_all and etc.
feat_dst = feat_dst * norm

It seems that GraphConv is implemented for directed graph and APPNPConv is implemented for undirected graph? But the example for APPNPConv is about a directed graph.

I thin the first code snippet is from GraphConv and the second code snippet is from APPNPConv. So it should be that GraphConv supports directed graphs while APPNPConv supports undirected graphs, not the other way. I believe this is a bug and should be addressed in PR 2324.

1 Like