//  [python]
def _interest_fusion_extraction_new(self, X, A, mask, layer, reuse):
        with tf.name_scope('interest_fusion'):
            ## cluster embedding
            A_bool = tf.cast(tf.greater(A, 0), A.dtype)
            A_bool = A_bool * (tf.ones([A.shape.as_list()[1],A.shape.as_list()[1]]) - tf.eye(A.shape.as_list()[1])) + tf.eye(A.shape.as_list()[1])
            D = tf.reduce_sum(A_bool, axis=-1) # B*L
            D = tf.sqrt(D)[:, None] + K.epsilon() # B*1*L
            A = (A_bool / D) / tf.transpose(D, perm=(0,2,1)) # B*L*L / B*1*L / B*L*1
            Xq = tf.matmul(A, tf.matmul(A, X)) # B*L*F

            # multi-head gat
            Xc = []
            node_score = []
            for i in range(self.attention_heads):
                ## cluster- and query-aware attention
                if not self.layer_shared:
                    _, f_1 = self._attention_fcn(Xq, X, 'f1_layer_'+str(layer)+'_'+str(i), False, mask, return_alpha=True)
                    if not self.remove_target:
                        if not self.recent_target:
                            _, f_2 = self._attention_fcn(self.target_item_embedding, X, 'f2_layer_'+str(layer)+'_'+str(i), False, mask, return_alpha=True)
                        else:
                            _, f_2 = self._attention_fcn(self.recent_embedding_mean, X, 'f2_layer_'+str(layer)+'_'+str(i), False, mask, return_alpha=True)
                if self.layer_shared:
                    _, f_1 = self._attention_fcn(Xq, X, 'f1_shared'+'_'+str(i), reuse, mask, return_alpha=True)
                    if not self.remove_target:
                        if not self.recent_target:
                            _, f_2 = self._attention_fcn(self.target_item_embedding, X, 'f2_shared'+'_'+str(i), reuse, mask, return_alpha=True)
                        else:
                            _, f_2 = self._attention_fcn(self.recent_embedding_mean, X, 'f2_shared'+'_'+str(i), reuse, mask, return_alpha=True)

                ## graph attentive convolution
                if not self.remove_target:
                    E = A_bool * tf.expand_dims(f_1,1) + A_bool * tf.transpose(tf.expand_dims(f_2,1), (0,2,1)) # B*L*1 x B*L*1 -> B*L*L
                    
                else:
                    E = A_bool * tf.expand_dims(f_1,1)
                E = tf.nn.leaky_relu(E)
                boolean_mask = tf.equal(A_bool, tf.ones_like(A_bool))
                mask_paddings = tf.ones_like(E) * (-(2 ** 32) + 1)
                E = tf.nn.softmax(
                    tf.where(boolean_mask, E, mask_paddings),
                    axis = -1
                )
                Xc_one = tf.matmul(E, X) # B*L*L x B*L*F -> B*L*F
                Xc_one = tf.layers.dense(Xc_one, self.hparams.hidden_size, use_bias=False)
                #  Xc_one = self.normalize(Xc_one)
                Xc_one += X
                Xc += [tf.nn.leaky_relu(Xc_one)]
                #  Xc += [Xc_one]
            Xc = tf.reduce_mean(tf.stack(Xc, 0), 0)

            node_score = f_2
            graph_readout = tf.reduce_sum(Xc*tf.expand_dims(node_score,-1)*tf.expand_dims(tf.cast(mask, tf.float32), -1), 1)

            Xc, A, cluster_score, mask, auxiliary_loss = self._diffpool(Xc, A, node_score, mask)


        return Xc, A, graph_readout, cluster_score, mask, auxiliary_loss