//  [python]
def _interest_fusion_extraction_new(self, X, A, 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

            #  self.A = A
            #  self.X = X

            # gcn
            #  D = tf.reduce_sum(A, axis=1)  # degree for each atom
            #  d += np.spacing(np.array(0, W.dtype))
            #  d = 1 / np.sqrt(d)
            #  D = np.diag(d.squeeze())  # D^{-1/2}
            #  I = np.identity(d.size, dtype=W.dtype)
            #  L = I - D * W * D

            # 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, 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, return_alpha=True)
                        else:
                            _, f_2 = self._attention_fcn(self.recent_embedding_mean, X, 'f2_layer_'+str(layer)+'_'+str(i), False, return_alpha=True)
                if self.layer_shared:
                    _, f_1 = self._attention_fcn(Xq, X, 'f1_shared'+'_'+str(i), reuse, 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, return_alpha=True)
                        else:
                            _, f_2 = self._attention_fcn(self.recent_embedding_mean, X, 'f2_shared'+'_'+str(i), reuse, return_alpha=True)

                #  node_score += [f_1 + f_2]
                #  node_score += [0.5*f_1 + 0.5*f_2]
                #  node_score += [f_2]

                ## 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
                    #  E = A_bool * tf.expand_dims(0.1 * f_1,1) + A_bool * tf.transpose(tf.expand_dims(0.9 * f_2,1), (0,2,1)) # B*L*1 x B*L*1 -> B*L*L
                    #  E = A_bool * tf.expand_dims(0.3 * f_1,1) + A_bool * tf.transpose(tf.expand_dims(0.7 * f_2,1), (0,2,1)) # B*L*1 x B*L*1 -> B*L*L
                    #  E = A_bool * tf.expand_dims(0.5 * f_1,1) + A_bool * tf.transpose(tf.expand_dims(0.5 * 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 = tf.reduce_mean(tf.stack(node_score, 0), 0)
#
            #  Xc = X

            #  _, f_11 = self._attention_fcn(Xq, X, 'f11_shared'+'_'+str(i), reuse, return_alpha=True)
            #  _, f_22 = self._attention_fcn(self.target_item_embedding, X, 'f22_shared'+'_'+str(i), reuse, return_alpha=True)
            #  _, f_11 = self._attention_fcn(Xq, X, 'f11_shared', reuse, return_alpha=True)
            #  _, f_22 = self._attention_fcn(self.target_item_embedding, X, 'f22_shared', reuse, return_alpha=True)
            #  node_score = f_11 + f_22
            #  node_score = f_22
            node_score = f_2
            graph_readout = tf.reduce_sum(Xc*tf.expand_dims(node_score,-1)*tf.expand_dims(tf.cast(self.mask, tf.float32), -1), 1)
            #  graph_readout = tf.reduce_sum(X*tf.expand_dims(node_score,-1)*tf.expand_dims(tf.cast(self.mask, tf.float32), -1), 1)

            # new node score
            #  node_score = f_2
            #  _, node_score = self._attention_fcn(self.target_item_embedding, X, 'AGRU', False, return_alpha=True)
            #  _, node_score = self._attention_fcn(self.target_item_embedding, Xc, 'AGRU', False, return_alpha=True)

#          with tf.name_scope('interest_extraction'):
#              ## cluster fitness score
#              Xq = tf.matmul(A, tf.matmul(A, Xc)) # B*L*F
#
#              cluster_score = []
#              for i in range(self.attention_heads):
#                  if not self.layer_shared:
#                      _, f_1 = self._attention_fcn(Xq, Xc, 'f1_layer_'+str(layer)+'_'+str(i), True, return_alpha=True)
#                      #  _, f_1 = self._attention_fcn(Xq, Xc, 'f1_layer_'+str(layer)+'_'+str(i), False, return_alpha=True)
#                      if not self.remove_target:
#                          if not self.recent_target:
#                              _, f_2 = self._attention_fcn(self.target_item_embedding, Xc, 'f2_layer_'+str(layer)+'_'+str(i), True, return_alpha=True)
#                              #  _, f_2 = self._attention_fcn(self.target_item_embedding, Xc, 'f2_layer_'+str(layer)+'_'+str(i), False, return_alpha=True)
#                          else:
#                              _, f_2 = self._attention_fcn(self.recent_embedding_mean, Xc, 'f2_layer_'+str(layer)+'_'+str(i), True, return_alpha=True)
#                              #  _, f_2 = self._attention_fcn(self.recent_embedding_mean, Xc, 'f2_layer_'+str(layer)+'_'+str(i), False, return_alpha=True)
#                  if self.layer_shared:
#                      _, f_1 = self._attention_fcn(Xq, Xc, 'f1_shared'+'_'+str(i), True, return_alpha=True)
#                      #  _, f_1 = self._attention_fcn(Xq, Xc, 'f1_shared'+'_'+str(i), False, return_alpha=True)
#                      if not self.remove_target:
#                          if not self.recent_target:
#                              _, f_2 = self._attention_fcn(self.target_item_embedding, Xc, 'f2_shared'+'_'+str(i), True, return_alpha=True)
#                              #  _, f_2 = self._attention_fcn(self.target_item_embedding, Xc, 'f2_shared'+'_'+str(i), False, return_alpha=True)
#                          else:
#                              _, f_2 = self._attention_fcn(self.recent_embedding_mean, Xc, 'f2_shared'+'_'+str(i), True, return_alpha=True)
#                              #  _, f_2 = self._attention_fcn(self.recent_embedding_mean, Xc, 'f2_shared'+'_'+str(i), False, return_alpha=True)
#                  if not self.remove_target:
#                      cluster_score += [f_1 + f_2]
#                  else:
#                      cluster_score += [f_1]
#              cluster_score = tf.reduce_mean(tf.stack(cluster_score, 0), 0)
#
#  #              # cosine distance
#              #  # f1
#              #  #求模
#              #  Xc_norm = tf.sqrt(tf.reduce_sum(tf.square(Xc), axis=2))
#              #  Xq_norm = tf.sqrt(tf.reduce_sum(tf.square(Xq), axis=2))
#              #  #内积
#              #  Xc_Xq = tf.reduce_sum(tf.multiply(Xc, Xq), axis=2)
#              #  f1_cos = Xc_Xq / (Xc_norm * Xq_norm)
#              #  # f2
#              #  #求模
#              #  Xt = tf.expand_dims(self.target_item_embedding, 1)
#              #  Xt_norm = tf.sqrt(tf.reduce_sum(tf.square(Xt), axis=2))
#              #  #内积
#              #  Xc_Xt = tf.reduce_sum(tf.multiply(Xc, Xt), axis=2)
#              #  f2_cos = Xc_Xt / (Xc_norm * Xt_norm)
#              #
#              #  cluster_score = f1_cos + f2_cos
#  #              #  cluster_score = f2_cos
#
#              boolean_mask = tf.equal(self.mask, tf.ones_like(self.mask))
#              mask_paddings = tf.ones_like(cluster_score) * (-(2 ** 32) + 1)
#              cluster_score = tf.nn.softmax(
#                  tf.where(boolean_mask, cluster_score, mask_paddings),
#                  axis = -1
#              )
#
#              ## graph pooling
#              num_nodes = tf.reduce_sum(self.mask, 1) # B
#              boolean_pool = tf.greater(num_nodes, self.pool_length)
#              to_keep = tf.where(boolean_pool,
#                                 tf.cast(self.pool_length + (self.real_sequence_length - self.pool_length)/self.pool_layers*(self.pool_layers-layer-1), tf.int32),
#                                 num_nodes)  # B
#              cluster_score = cluster_score * self.float_mask # B*L
#              if 'kwai' in socket.gethostname():
#                  sorted_score = tf.contrib.framework.sort(cluster_score, direction='DESCENDING', axis=-1) # B*L
#                  target_index = tf.stack([tf.range(tf.shape(Xc)[0]), tf.cast(to_keep, tf.int32)], 1) # B*2
#                  target_score = tf.gather_nd(sorted_score, target_index) + K.epsilon() # indices[:-1]=(B) + data[indices[-1]=() --> (B)
#              else:
#                  sorted_score = tf.sort(cluster_score, direction='DESCENDING', axis=-1) # B*L
#                  target_score = tf.gather_nd(sorted_score, tf.expand_dims(tf.cast(to_keep, tf.int32), -1), batch_dims=1) + K.epsilon() # indices[:-1]=(B) + data[indices[-1]=() --> (B)
#              topk_mask = tf.greater(cluster_score, tf.expand_dims(target_score, -1)) # B*L + B*1 -> B*L
#              self.mask = tf.cast(topk_mask, tf.int32)
#              self.float_mask = tf.cast(self.mask, tf.float32)
#              self.reduced_sequence_length = tf.reduce_sum(self.mask, 1)
#
#              ## ensure graph connectivity
#              E = E * tf.expand_dims(self.float_mask, -1) * tf.expand_dims(self.float_mask, -2)
#              A = tf.matmul(tf.matmul(E, A_bool),
#                            tf.transpose(E, (0,2,1))) # B*C*L x B*L*L x B*L*C = B*C*C
#              ## graph readout
#              graph_readout = tf.reduce_sum(Xc*tf.expand_dims(cluster_score,-1)*tf.expand_dims(self.float_mask, -1), 1)

            #  graph_readout = tf.reduce_sum(Xc*tf.expand_dims(node_score,-1)*tf.expand_dims(self.float_mask, -1), 1)

            #  Xc,A, cluster_score = self._diffpool(Xc, A)
            #  Xc,A, cluster_score = self._diffpool(X, Xc, A)
            #  Xc,A, cluster_score = self._diffpool(X, Xc, A, node_score)
            Xc, A, cluster_score = self._diffpool(Xc, A, node_score)
            #  Xc, A, cluster_score = self._diffpool(self.normalize(Xc), A, node_score)
            #  Xc, A, cluster_score = self._diffpool(X, A, node_score)
            #  Xc,A = self._diffpool(self.normalize(Xc), A)
            #  cluster_score = node_score

            # None
            #  _, node_score = self._attention_fcn(self.target_item_embedding, Xc, 'AGRU', False, return_alpha=True)
            #  graph_readout = tf.reduce_sum(Xc*tf.expand_dims(node_score,-1)*tf.expand_dims(tf.cast(self.mask, tf.float32), -1), 1)
            #  graph_readout = tf.reduce_sum(Xc*tf.expand_dims(cluster_score,-1)*tf.expand_dims(tf.cast(self.mask, tf.float32), -1), 1)
            #  graph_readout = tf.reduce_sum(Xc*tf.expand_dims(tf.cast(self.mask, tf.float32), -1), 1)

        return Xc, A, graph_readout, cluster_score