tf2_gnn/layers/message_passing/message_passing.py
def call(self, inputs: MessagePassingInput, training: bool = False):
        """Call the message passing layer.

        Args:
            inputs: A tuple containing two items:
                node_embeddings: float32 tensor of shape [V, D], the original representation of each
                    node in the graph.
                adjacency_lists: Tuple of L adjacency lists, represented as int32 tensors of shape
                    [E, 2]. Concretely, adjacency_lists[l][k,:] == [v, u] means that the k-th edge
                    of type l connects node v to node u.
            training: A bool that denotes whether we are in training mode.

        Returns:
            float32 tensor of shape [V, hidden_dim]
        """
        """
        Call the message passing layer.
            Args:
                inputs: A tuple containing two items:
                    node_embeddings: float32 tensor of shape [V, D], the original representation of each
                        node in the graph.
                    adjacency_lists: Tuple of L adjacency lists, represented as int32 tensors of shape
                        [E, A_l], where A_l is the arity of l-th relation.
                        Concretely, adjacency_lists[l][k,:] == [v_1, ..., v_{A_l}] means that
                        the k-th edge of type l connects nodes v_1 ... v_{A_l}.
                training: A bool that denotes whether we are in training mode.
            Returns:
                float32 tensor of shape [V, hidden_dim]
        """
        node_embeddings, adjacency_lists = inputs.node_embeddings, inputs.adjacency_lists
        num_nodes = tf.shape(node_embeddings)[0]


        # Compute messages and message targets for each edge type:
        messages = []  # list of tensors of messages of shape [E, H]
        messages_targets = []  # list of indices indicating the node receiving the message
        counter=0
        for edge_type_idx, adjacency_list_for_edge_type in enumerate(adjacency_lists):
            edge_arity = adjacency_list_for_edge_type.shape[1]

            # Compute edge embeddings update function inputs by concatening all connected nodes:
            edges_node_representations = []
            for endpoint_idx in range(edge_arity):
                node_idxs = adjacency_list_for_edge_type[:, endpoint_idx]
                edges_node_representations.append(tf.gather(params=node_embeddings, indices=node_idxs))
                #edges_node_representations.append(gather_dense_gradient(params=node_embeddings, indices=node_idxs))

            raw_edge_representations = tf.concat(edges_node_representations, axis=-1)
            # Now actually compute one result per involved node, using a separate function for
            # each hyperedge endpoint:
            for endpoint_idx in range(edge_arity):
                target_state_ids = adjacency_list_for_edge_type[:, endpoint_idx]
                messages.append(
                    self._hyperedge_type_mlps[counter](
                        raw_edge_representations, training
                    )
                )
                messages_targets.append(target_state_ids)
                counter=counter+1

        messages = tf.concat(messages, axis=0)  # Shape [M, H]
        messages_targets = tf.concat(messages_targets, axis=0)  # Shape [M]

        # Node embedding
        aggregated_messages = tf.math.unsorted_segment_sum(
            data=messages,
            segment_ids=messages_targets,
            num_segments=num_nodes
        )

        return tf.nn.relu(aggregated_messages)




        # messages_per_type = self._calculate_messages_per_type(
        #     adjacency_lists, node_embeddings, training
        # )
        #
        # edge_type_to_message_targets = [
        #     adjacency_list_for_edge_type[:, 1] for adjacency_list_for_edge_type in adjacency_lists
        # ]
        #
        # new_node_states = self._compute_new_node_embeddings(
        #     node_embeddings, messages_per_type, edge_type_to_message_targets, num_nodes, training,
        # )  # Shape [V, H]
        #
        # return new_node_states
Call the message passing layer.

        Args:
            inputs: A tuple containing two items:
                node_embeddings: float32 tensor of shape [V, D], the original representation of each
                    node in the graph.
                adjacency_lists: Tuple of L adjacency lists, represented as int32 tensors of shape
                    [E, 2]. Concretely, adjacency_lists[l][k,:] == [v, u] means that the k-th edge
                    of type l connects node v to node u.
            training: A bool that denotes whether we are in training mode.

        Returns:
            float32 tensor of shape [V, hidden_dim]
        
Call the message passing layer.
Call the message passing layer .
def call(self, inputs: MessagePassingInput, training: bool = False):
        node_embeddings, adjacency_lists = inputs.node_embeddings, inputs.adjacency_lists
        num_nodes = tf.shape(node_embeddings)[0]
        messages = []  
        messages_targets = []  
        counter=0
        for edge_type_idx, adjacency_list_for_edge_type in enumerate(adjacency_lists):
            edge_arity = adjacency_list_for_edge_type.shape[1]
            edges_node_representations = []
            for endpoint_idx in range(edge_arity):
                node_idxs = adjacency_list_for_edge_type[:, endpoint_idx]
                edges_node_representations.append(tf.gather(params=node_embeddings, indices=node_idxs))
            raw_edge_representations = tf.concat(edges_node_representations, axis=-1)
            for endpoint_idx in range(edge_arity):
                target_state_ids = adjacency_list_for_edge_type[:, endpoint_idx]
                messages.append(
                    self._hyperedge_type_mlps[counter](
                        raw_edge_representations, training
                    )
                )
                messages_targets.append(target_state_ids)
                counter=counter+1
        messages = tf.concat(messages, axis=0)  
        messages_targets = tf.concat(messages_targets, axis=0)  
        aggregated_messages = tf.math.unsorted_segment_sum(
            data=messages,
            segment_ids=messages_targets,
            num_segments=num_nodes
        )
        return tf.nn.relu(aggregated_messages)
         edge_type_to_message_targets = [
             adjacency_list_for_edge_type[:, 1] for adjacency_list_for_edge_type in adjacency_lists
         ]
         new_node_states = self._compute_new_node_embeddings(
             node_embeddings, messages_per_type, edge_type_to_message_targets, num_nodes, training,
           Shape [V, H]
         return new_node_states
def call ( self , inputs : MessagePassingInput , training : bool = False ) : """
        Call the message passing layer.
            Args:
                inputs: A tuple containing two items:
                    node_embeddings: float32 tensor of shape [V, D], the original representation of each
                        node in the graph.
                    adjacency_lists: Tuple of L adjacency lists, represented as int32 tensors of shape
                        [E, A_l], where A_l is the arity of l-th relation.
                        Concretely, adjacency_lists[l][k,:] == [v_1, ..., v_{A_l}] means that
                        the k-th edge of type l connects nodes v_1 ... v_{A_l}.
                training: A bool that denotes whether we are in training mode.
            Returns:
                float32 tensor of shape [V, hidden_dim]
        """ node_embeddings , adjacency_lists = inputs . node_embeddings , inputs . adjacency_lists num_nodes = tf . shape ( node_embeddings ) [ 0 ] messages = [ ] messages_targets = [ ] counter = 0 for edge_type_idx , adjacency_list_for_edge_type in enumerate ( adjacency_lists ) : edge_arity = adjacency_list_for_edge_type . shape [ 1 ] edges_node_representations = [ ] for endpoint_idx in range ( edge_arity ) : node_idxs = adjacency_list_for_edge_type [ : , endpoint_idx ] edges_node_representations . append ( tf . gather ( params = node_embeddings , indices = node_idxs ) ) raw_edge_representations = tf . concat ( edges_node_representations , axis = - 1 ) for endpoint_idx in range ( edge_arity ) : target_state_ids = adjacency_list_for_edge_type [ : , endpoint_idx ] messages . append ( self . _hyperedge_type_mlps [ counter ] ( raw_edge_representations , training ) ) messages_targets . append ( target_state_ids ) counter = counter + 1 messages = tf . concat ( messages , axis = 0 ) messages_targets = tf . concat ( messages_targets , axis = 0 ) aggregated_messages = tf . math . unsorted_segment_sum ( data = messages , segment_ids = messages_targets , num_segments = num_nodes ) return tf . nn . relu ( aggregated_messages )
Call the message passing layer.
Call the message passing layer .
"""Call the message passing layer.

        Args:
            inputs: A tuple containing two items:
                node_embeddings: float32 tensor of shape [V, D], the original representation of each
                    node in the graph.
                adjacency_lists: Tuple of L adjacency lists, represented as int32 tensors of shape
                    [E, 2]. Concretely, adjacency_lists[l][k,:] == [v, u] means that the k-th edge
                    of type l connects node v to node u.
            training: A bool that denotes whether we are in training mode.

        Returns:
            float32 tensor of shape [V, hidden_dim]
        """ """
        Call the message passing layer.
            Args:
                inputs: A tuple containing two items:
                    node_embeddings: float32 tensor of shape [V, D], the original representation of each
                        node in the graph.
                    adjacency_lists: Tuple of L adjacency lists, represented as int32 tensors of shape
                        [E, A_l], where A_l is the arity of l-th relation.
                        Concretely, adjacency_lists[l][k,:] == [v_1, ..., v_{A_l}] means that
                        the k-th edge of type l connects nodes v_1 ... v_{A_l}.
                training: A bool that denotes whether we are in training mode.
            Returns:
                float32 tensor of shape [V, hidden_dim]
        """ # Compute messages and message targets for each edge type: # list of tensors of messages of shape [E, H] # list of indices indicating the node receiving the message # Compute edge embeddings update function inputs by concatening all connected nodes: #edges_node_representations.append(gather_dense_gradient(params=node_embeddings, indices=node_idxs)) # Now actually compute one result per involved node, using a separate function for # each hyperedge endpoint: # Shape [M, H] # Shape [M] # Node embedding # messages_per_type = self._calculate_messages_per_type( #     adjacency_lists, node_embeddings, training # ) # # edge_type_to_message_targets = [ #     adjacency_list_for_edge_type[:, 1] for adjacency_list_for_edge_type in adjacency_lists # ] # # new_node_states = self._compute_new_node_embeddings( #     node_embeddings, messages_per_type, edge_type_to_message_targets, num_nodes, training, # )  # Shape [V, H] # # return new_node_states
float32 tensor of shape [V, hidden_dim]
float32 tensor of shape [ V hidden_dim ]
self
inputs
MessagePassingInput
A tuple containing two items:
node_embeddings: float32 tensor of shape [V, D], the original representation of each
node in the graph.
adjacency_lists: Tuple of L adjacency lists, represented as int32 tensors of shape
[E, 2]. Concretely, adjacency_lists[l][k,:] == [v, u] means that the k-th edge
of type l connects node v to node u.
A tuple containing two items : node_embeddings : float32 tensor of shape [ V D ] the original representation of each node in the graph . adjacency_lists : Tuple of L adjacency lists represented as int32 tensors of shape [ E 2 ] . Concretely adjacency_lists [ l ] [ k : ] == [ v u ] means that the k - th edge of type l connects node v to node u .
training
bool
A bool that denotes whether we are in training mode.
A bool that denotes whether we are in training mode .