code: def test_message_passing_hooks():
      conv = MyConv(8, 32)
  
      x = torch.randn(4, 8)
      edge_index = torch.tensor([[0, 1, 2, 3], [0, 0, 1, 1]])
      value = torch.randn(edge_index.size(1))
      adj = to_torch_csc_tensor(edge_index, value, size=(4, 4))
  
      def pre_hook(module, inputs):
          assert module == conv
          global num_pre_hook_calls
          num_pre_hook_calls += 1
          return inputs
  
      def hook(module, inputs, output):
          assert module == conv
          global num_hook_calls
          num_hook_calls += 1
          return output
  
      handle1 = conv.register_propagate_forward_pre_hook(pre_hook)
      assert len(conv._propagate_forward_pre_hooks) == 1
      handle2 = conv.register_propagate_forward_hook(hook)
      assert len(conv._propagate_forward_hooks) == 1
  
      handle3 = conv.register_message_forward_pre_hook(pre_hook)
      assert len(conv._message_forward_pre_hooks) == 1
      handle4 = conv.register_message_forward_hook(hook)
      assert len(conv._message_forward_hooks) == 1
  
      handle5 = conv.register_aggregate_forward_pre_hook(pre_hook)
      assert len(conv._aggregate_forward_pre_hooks) == 1
      handle6 = conv.register_aggregate_forward_hook(hook)
      assert len(conv._aggregate_forward_hooks) == 1
  
      handle7 = conv.register_message_and_aggregate_forward_pre_hook(
          pre_hook
      )
      assert len(conv._message_and_aggregate_forward_pre_hooks) == 1
      handle8 = conv.register_message_and_aggregate_forward_hook(hook)
      assert len(conv._message_and_aggregate_forward_hooks) == 1
  
      out1 = conv(x, edge_index, value)
      assert num_pre_hook_calls == 3
      assert num_hook_calls == 3
      out2 = conv(x, adj.t())
      assert num_pre_hook_calls == 5
      assert num_hook_calls == 5
      assert torch.allclose(out1, out2, atol=1e-6)
  
      handle1.remove()
      assert len(conv._propagate_forward_pre_hooks) == 0
      handle2.remove()
      assert len(conv._propagate_forward_hooks) == 0
  
      handle3.remove()
      assert len(conv._message_forward_pre_hooks) == 0
      handle4.remove()
      assert len(conv._message_forward_hooks) == 0
  
      handle5.remove()
      assert len(conv._aggregate_forward_pre_hooks) == 0
      handle6.remove()
      assert len(conv._aggregate_forward_hooks) == 0
  
      handle7.remove()
      assert len(conv._message_and_aggregate_forward_pre_hooks) == 0
      handle8.remove()
      assert len(conv._message_and_aggregate_forward_hooks) == 0
  
      conv = MyEdgeConv()
  
      handle1 = conv.register_edge_update_forward_pre_hook(pre_hook)
      assert len(conv._edge_update_forward_pre_hooks) == 1
      handle2 = conv.register_edge_update_forward_hook(hook)
      assert len(conv._edge_update_forward_hooks) == 1
  
      out1 = conv(x, edge_index)
      assert num_pre_hook_calls == 6
      assert num_hook_calls == 6
      out2 = conv(x, adj.t())
      assert num_pre_hook_calls == 7
      assert num_hook_calls == 7
      assert torch.allclose(out1, out2, atol=1e-6)
  
      handle1.remove()
      assert len(conv._propagate_forward_pre_hooks) == 0
      handle2.remove()
      assert len(conv._propagate_forward_hooks) == 0
  
imports: import copy
  from typing import Tuple, Union
  import pytest
  import torch
  from torch import Tensor
  from torch.nn import Linear
  import torch_geometric.typing
  from torch_geometric.nn import MessagePassing, aggr
  from torch_geometric.typing import Adj, OptPairTensor, OptTensor, Size, SparseTensor
  from torch_geometric.utils import add_self_loops, scatter, spmm, to_torch_csc_tensor
label_desc: Use image node_id 11 for calling a global function with example usage: test_message_passing_hooks() and returns: inputs, output