# Multigraph neural networks in Julia

**URL:** <https://discourse.julialang.org/t/multigraph-neural-networks-in-julia/70595>\
**Category:** Machine Learning\
**Tags:** flux, geometricflux, graphneuralnetworks, chemellia\
**Created:** [October 29, 2021, 1:38am UTC](https://discourse.julialang.org/t/multigraph-neural-networks-in-julia/70595 "2021-10-29T01:38:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bad\_at\_math](https://avatars.discourse-cdn.com/v4/letter/b/51bf81/32.png) [@bad\_at\_math](https://discourse.julialang.org/u/bad_at_math)\
**Post date:** [October 29, 2021, 1:38am UTC](https://discourse.julialang.org/t/multigraph-neural-networks-in-julia/70595/1 "2021-10-29T01:38:26Z")

</div>

GeometricFlux.jl ([https://fluxml.ai/GeometricFlux.jl/dev/manual/conv/#Crystal-Graph-Convolutional-Network-1](https://fluxml.ai/GeometricFlux.jl/dev/manual/conv/#Crystal-Graph-Convolutional-Network-1)) and GraphNeuralNetworks.jl ([Convolutional Layers · GraphNeuralNetworks.jl](https://carlolucibello.github.io/GraphNeuralNetworks.jl/dev/api/conv/#GraphNeuralNetworks.CGConv)) both implement a layer based on the Crystal Graph Convolutional Neural Network (CGCNN)([Phys. Rev. Lett. 120, 145301 (2018) - Crystal Graph Convolutional Neural Networks for an Accurate and Interpretable Prediction of Material Properties](https://doi.org/10.1103/PhysRevLett.120.145301)).

The CGCNN architecture is usually defined over a multi-graph, where a pair of nodes might have multiple connecting edges, and each edge has a different encoding vector. Is this input datatype supported in current Julia graph network packages; or, failing that, is it easily implemented? Light searching has revealed a separate Multigraph.jl package ([https://github.com/QuantumBFS/Multigraphs.jl](https://github.com/QuantumBFS/Multigraphs.jl)) that is not (perhaps?) integrated into the general Graphs ecsystem.

It’s not obvious that the `GNNGraph` type ([https://github.com/CarloLucibello/GraphNeuralNetworks.jl/blob/master/src/gnngraph.jl](https://github.com/CarloLucibello/GraphNeuralNetworks.jl/blob/master/src/gnngraph.jl)) in GraphNeuralNetworks.jl supports multigraphs, but I might be missing something obvious.

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [October 29, 2021, 1:47am UTC](https://discourse.julialang.org/t/multigraph-neural-networks-in-julia/70595/2 "2021-10-29T01:47:33Z")

</div>

All I can do is pattern match on “CGCNN”, but does [https://github.com/Chemellia/AtomicGraphNets.jl](https://github.com/Chemellia/AtomicGraphNets.jl) meet your use case?

---

<div class="post-metadata">

**Author:** ![CarloLucibello](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carlolucibello/32/3278_2.png) [@CarloLucibello](https://discourse.julialang.org/u/CarloLucibello)\
**Post date:** [October 29, 2021, 7:36am UTC](https://discourse.julialang.org/t/multigraph-neural-networks-in-julia/70595/3 "2021-10-29T07:36:59Z")

</div>

> [@bad\_at\_math](#):
>
> It’s not obvious that the `GNNGraph` type ([GraphNeuralNetworks.jl/gnngraph.jl at master · CarloLucibello/GraphNeuralNetworks.jl · GitHub](https://github.com/CarloLucibello/GraphNeuralNetworks.jl/blob/master/src/gnngraph.jl)) in GraphNeuralNetworks.jl supports multigraphs, but I might be missing something obvious.

It does, but it should be made more explicit indeed. In order to construct a GNNGraph with multi-edges you cannot go through a Graphs.jl graph but you explicitly give the source and target nodes:

```julia
julia> using GraphNeuralNetworks

julia> s = [1,1,2,3];

julia> t = [2,2,2,4]; # we have both multi-edges and self-edges

julia> g = GNNGraph(s, t)
GNNGraph:
    num_nodes = 4
    num_edges = 4
    num_graphs = 1
    ndata:
    edata:
    gdata:

julia> x = rand(Float32, 2, g.num_nodes)
2×4 Matrix{Float32}:
 0.00534022 0.873903 0.757006 0.235914
 0.0701774 0.788159 0.0483252 0.217582

julia> e = rand(Float32, 3, g.num_edges)
3×4 Matrix{Float32}:
 0.801664 0.531405 0.810002 0.690981
 0.158637 0.630085 0.830421 0.19566
 0.579666 0.750919 0.0782821 0.926121

julia> conv = CGConv((2,3) => 4, tanh)
CGConv((2, 3) => 4, tanh, residual=false)

julia> y = conv(g, x, e) 
4×4 Matrix{Float32}:
 0.0 -0.24086 0.0 -0.0644639
 0.0 -1.03614 0.0 0.0932009
 0.0 -1.30664 0.0 -0.45532
 0.0 -0.0407019 0.0 0.0959732
```

---

<div class="post-metadata">

**Author:** ![bad\_at\_math](https://avatars.discourse-cdn.com/v4/letter/b/51bf81/32.png) [@bad\_at\_math](https://discourse.julialang.org/u/bad_at_math)\
**Post date:** [November 15, 2021, 5:29pm UTC](https://discourse.julialang.org/t/multigraph-neural-networks-in-julia/70595/4 "2021-11-15T17:29:17Z")

</div>

@CarloLucibello it seems that there might be an error in the `has_multi_edges` function (or I’m misunderstanding its use):

```julia
using GraphNeuralNetworks
s = [1,1,2,3];
t = [2,2,2,4];
g = GNNGraph(s, t);

has_multi_edges(g) # evaluates as `false`

```

---

<div class="post-metadata">

**Author:** ![CarloLucibello](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carlolucibello/32/3278_2.png) [@CarloLucibello](https://discourse.julialang.org/u/CarloLucibello)\
**Post date:** [November 15, 2021, 7:21pm UTC](https://discourse.julialang.org/t/multigraph-neural-networks-in-julia/70595/5 "2021-11-15T19:21:20Z")

</div>

thanks for reporitng this, being fixed in [https://github.com/CarloLucibello/GraphNeuralNetworks.jl/pull/75](https://github.com/CarloLucibello/GraphNeuralNetworks.jl/pull/75)
