text:
"""
The SPC-MGR is built based in part on graph attention mechanism (https://arxiv.org/abs/1710.10903),
part on MG-SCR (https://www.ijcai.org/proceedings/2021/0135),
and includes open-source codes provided by
the project of Graph Attention Network (GAT) at https://github.com/PetarV-/GAT,
and the project of MG-SCR at https://github.com/Kali-Hac/MG-SCR.
"""

import time
import numpy as np
import tensorflow as tf
import os, sys
from models import GAT as MSRL  # (Veličković et al.)
from utils import process_L3 as process
from utils.faiss_rerank import compute_jaccard_distance
from tensorflow.python.layers.core import Dense
from sklearn.preprocessing import label_binarize
from sklearn.cluster import DBSCAN
import torch
import collections
from sklearn.metrics import average_precision_score

dataset = ''
probe = ''
pre_dir = 'ReID_Models/'
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
config = tf.ConfigProto()
config.gpu_options.allow_growth = True

nb_nodes = 20       # number of nodes in joint-scale graph
nhood = 1           # structural relation learning (nhood=1 for neighbor nodes)
fusion_lambda = 1   # collaboration fusion coefficient
ft_size = 3         # originial node feature dimension (D)
time_step = 6       # sequence length (f)

# training params
batch_size = 256
nb_epochs = 100000
patience = 250     # patience for early stopping
hid_units = [8]  # numbers of hidden units per each attention head in each layer
Ms = [8, 1]  # additional entry for the output layer
k1, k2 = 20, 6  # parameters to compute feature distance matrix
residual = False
nonlinearity = tf.nn.elu

tf.app.flags.DEFINE_string('dataset', 'KS20', "Dataset: IAS, KS20, BIWI, CASIA-B or KGBD")
tf.app.flags.DEFINE_string('length', '6', "4, 6, 8, 10 or 12")
tf.app.flags.DEFINE_string('t', '0.07', "temperature for contrastive learning")
tf.app.flags.DEFINE_string('lr', '0.00035', "learning rate")
tf.app.flags.DEFINE_string('eps', '0.6', "distance parameter in DBSCAN")
tf.app.flags.DEFINE_string('min_samples', '2', "minimum sample number in DBSCAN")
tf.app.flags.DEFINE_string('probe', 'probe', "for testing probe")
tf.app.flags.DEFINE_string('gpu', '0', "GPU number")
tf.app.flags.DEFINE_string('probe_view', '', "test different views on CASIA B or KS20")
tf.app.flags.DEFINE_string('gallery_view', '', "test different views on CASIA B or KS20")
tf.app.flags.DEFINE_string('struct_only', '0', "struct_only")
tf.app.flags.DEFINE_string('m', '8', "structural relation heads")
tf.app.flags.DEFINE_string('probe_type', '', "probe.gallery")
tf.app.flags.DEFINE_string('patience', '200', "epochs for early stopping")
tf.app.flags.DEFINE_string('fusion_lambda', '1', "collaboration fusion coefficient")
tf.app.flags.DEFINE_string('S_dataset', '', "Source Dataset")
tf.app.flags.DEFINE_string('S_probe', '', "Source Dataset probe")
tf.app.flags.DEFINE_string('mode', 'UF', "Unsupervised Fine-tuning (UF) or Direct Generalization (DG)")
tf.app.flags.DEFINE_string('evaluate', '0', "evaluate on the best model")
FLAGS = tf.app.flags.FLAGS

# check parameters
if FLAGS.dataset not in ['IAS', 'KGBD', 'KS20', 'BIWI', 'CASIA_B']:
	raise Exception('Dataset must be IAS, KGBD, KS20, BIWI or CASIA B.')
if not FLAGS.gpu.isdigit() or int(FLAGS.gpu) < 0:
	raise Exception('GPU number must be a positive integer.')
if FLAGS.dataset == 'CASIA_B':
	pass
else:
	if FLAGS.length not in ['4', '6', '8', '10', '12']:
		raise Exception('Length number must be 4, 6, 8, 10 or 12.')
if FLAGS.probe not in ['probe', 'Walking', 'Still', 'A', 'B']:
	raise Exception('Dataset probe must be "A" (for IAS-A), "B" (for IAS-B), "probe" (for KS20, KGBD).')
if float(FLAGS.fusion_lambda) < 0 or float(FLAGS.fusion_lambda) > 1:
	raise Exception('Multi-Level Graph Fusion coefficient must be not less than 0 or not larger than 1.')
if FLAGS.mode not in ['UF', 'DG']:
	raise Exception('Mode must be UF or DG.')
if FLAGS.mode == 'DG' and FLAGS.S_dataset == '':
	raise Exception('DG mode must set a source dataset.')
if FLAGS.mode == 'UF' and FLAGS.S_dataset != '':
	raise Exception('UF mode does not use a source dataset.')

os.environ["CUDA_VISIBLE_DEVICES"] = FLAGS.gpu
dataset = FLAGS.dataset

# optimal paramters
if dataset == 'KGBD':
	batch_size = 256
	FLAGS.lr = '0.00035'
	FLAGS.min_samples = '4'
	FLAGS.t = '0.06'
elif dataset == 'CASIA_B':
	batch_size = 128
	FLAGS.lr = '0.00035'
	FLAGS.min_samples = '2'
	FLAGS.eps = '0.75'
	FLAGS.t = '0.075'
else:
	batch_size = 128
	FLAGS.lr = '0.00035'
if dataset == 'KS20' or dataset == 'IAS':
	FLAGS.t = '0.08'
	FLAGS.eps = '0.8'
elif dataset == 'BIWI':
	FLAGS.t = '0.07'

eps = float(FLAGS.eps)
min_samples = int(FLAGS.min_samples)

time_step = int(FLAGS.length)
fusion_lambda = float(FLAGS.fusion_lambda)
probe = FLAGS.probe
patience = int(FLAGS.patience)

global_att = False
struct_only = False
P = '8'

change = ''

if FLAGS.probe_type != '':
	change += '_CME'
if FLAGS.fusion_lambda != '1':
	change = '_lambda_' + FLAGS.fusion_lambda

if FLAGS.struct_only == '1':
	struct_only = True

if FLAGS.dataset == 'KGBD':
	FLAGS.m = '16'
if FLAGS.m != '8':
	m = FLAGS.m
	Ms = [int(m), 1]

try:
	os.mkdir(pre_dir)
except:
	pass

if struct_only:
	pre_dir += '_struct_only'
if P != '8':
	pre_dir += '_P_' + P

if dataset == 'KS20':
	nb_nodes = 25

if dataset == 'CASIA_B':
	nb_nodes = 14

print('----- Model hyperparams -----')
# print('skeleton_nodes: ' + str(nb_nodes))
print('seqence_length: ' + str(time_step))
print('fusion_lambda: ' + str(fusion_lambda))
print('batch_size: ' + str(batch_size))
print('lr: ' + str(FLAGS.lr))
print('temperature: ' + FLAGS.t)
print('eps: ' + FLAGS.eps)
print('min_samples: ' + FLAGS.min_samples)
print('m: ' + FLAGS.m)
print('fusion_lambda: ' + FLAGS.fusion_lambda)
# print('patience: ' + FLAGS.patience)

print('Mode: ' + FLAGS.mode)
print('Evaluate: ' + FLAGS.evaluate)

if FLAGS.mode == 'DG':
	print('----- Mode Information  -----')
	print('Source Dataset: ' + FLAGS.S_dataset)
	print('Target Dataset: ' + FLAGS.dataset)
	print('Target Probe: ' + FLAGS.probe)
elif FLAGS.mode == 'UF':
	print('----- Dataset Information  -----')
	print('Dataset: ' + dataset)
	if dataset == 'CASIA_B':
		print('Probe.Gallery: ', FLAGS.probe_type.split('.')[0], FLAGS.probe_type.split('.')[1])
	else:
		print('Probe: ' + FLAGS.probe)

"""
 Obtain training and testing data in part-level, body-scale, and hyper-body-scale.
 Generate corresponding adjacent matrix and bias.
"""
if FLAGS.probe_type == '':
	if FLAGS.probe_view == '' and FLAGS.gallery_view == '':
		_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_test_P, X_test_B, X_test_H_B, _, y_test, \
		_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
			process.gen_train_data(dataset=dataset, split=probe, time_step=time_step,
			                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size, )
	else:
		if dataset == 'KS20':
			_, _, _, _, _, _, _, X_test_P, X_test_B, X_test_H_B, _, y_test, \
			_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
				process.gen_train_data(dataset=dataset, split='view_'+FLAGS.probe_view, time_step=time_step,
				                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
				                       )
			X_train_P_all = []
			X_train_B_all = []
			X_train_H_B_all = []
			y_train_all = []
			for i in range(5):
				if str(i) not in [FLAGS.probe_view, FLAGS.gallery_view]:
					_, _, _, _, _, _, _, X_train_P, X_train_B, X_train_H_B, _, y_train, \
					_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
						process.gen_train_data(dataset=dataset, split='view_' + str(i), time_step=time_step,
						                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att,
						                       batch_size=batch_size,
						                       )
					X_train_H_B_all.extend(X_train_H_B)
					X_train_P_all.extend(X_train_P)
					X_train_B_all.extend(X_train_B)
					y_train_all.extend(y_train_all)
			X_train_P = np.array(X_train_P_all)
			X_train_B = np.array(X_train_B_all)
			X_train_H_B = np.array(X_train_H_B_all)
			y_train = np.array(y_train)

else:
	from utils import process_cme_L3 as process
	_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_test_P, X_test_B, X_test_H_B, _, y_test, \
	_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
		process.gen_train_data(dataset=dataset, split=probe, time_step=time_step,
		                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size, PG_type=FLAGS.probe_type.split('.')[0])
	print('## [Probe].[Gallery]', FLAGS.probe_type)

all_ftr_size = hid_units[0] * (15 + 3)
loaded_graph = tf.Graph()

cluster_epochs = 15000
display = 20

if FLAGS.evaluate == '1':
	FLAGS.S_dataset = FLAGS.dataset
	FLAGS.S_probe = FLAGS.probe
	FLAGS.mode = 'DG'

if FLAGS.mode == 'UF':
	with tf.Graph().as_default():
		with tf.name_scope('Input'):
			P_in = tf.placeholder(dtype=tf.float32, shape=(batch_size * time_step, 10, ft_size))
			B_in = tf.placeholder(dtype=tf.float32, shape=(batch_size * time_step, 5, ft_size))
			H_B_in = tf.placeholder(dtype=tf.float32, shape=(batch_size * time_step, 3, ft_size))
			P_bias_in = tf.placeholder(dtype=tf.float32, shape=(1, 10, 10))
			B_bias_in = tf.placeholder(dtype=tf.float32, shape=(1, 5, 5))
			H_B_bias_in = tf.placeholder(dtype=tf.float32, shape=(1, 3, 3))
			attn_drop = tf.placeholder(dtype=tf.float32, shape=())
			ffd_drop = tf.placeholder(dtype=tf.float32, shape=())
			is_train = tf.placeholder(dtype=tf.bool, shape=())
			pseudo_lab = tf.placeholder(dtype=tf.int32, shape=(batch_size,))
			cluster_ftr = tf.placeholder(dtype=tf.float32, shape=(None, all_ftr_size))

		with tf.name_scope("MG"), tf.variable_scope("MG", reuse=tf.AUTO_REUSE):
			def SRL(J_in, J_bias_in, nb_nodes):
				W_h = tf.Variable(tf.random_normal([3, hid_units[-1]]))
				b_h = tf.Variable(tf.zeros(shape=[hid_units[-1], ]))
				J_h = tf.reshape(J_in, [-1, ft_size])

				J_h = tf.matmul(J_h, W_h) + b_h
				J_h = tf.reshape(J_h, [batch_size*time_step, nb_nodes, hid_units[-1]])
				J_seq_ftr = MSRL.inference(J_h, 0, nb_nodes, is_train,
				                         attn_drop, ffd_drop,
				                         bias_mat=J_bias_in,
				                         hid_units=hid_units, n_heads=Ms,
				                         residual=residual, activation=nonlinearity, r_pool=True)
				return J_seq_ftr

			def FCRL(s1, s2, s1_num, s2_num, hid_in):
				r_unorm = tf.matmul(s2, tf.transpose(s1, [0, 2, 1]))
				att_w = tf.nn.softmax(r_unorm)
				att_w = tf.expand_dims(att_w, axis=-1)
				s1 = tf.reshape(s1, [s1.shape[0], 1, s1.shape[1], hid_in])
				c_ftr = tf.reduce_sum(att_w * s1, axis=2)
				c_ftr = tf.reshape(c_ftr, [-1, hid_in])
				att_w = tf.reshape(att_w, [-1, s1_num * s2_num])
				return r_unorm, c_ftr

			def MSC(P_in, B_in, H_B_in, P_bias_in, B_bias_in,  H_B_bias_in, hid_in, hid_out):
				h_P_seq_ftr = SRL(J_in=P_in, J_bias_in=P_bias_in, nb_nodes=10)
				h_B_seq_ftr = SRL(J_in=B_in, J_bias_in=B_bias_in, nb_nodes=5)
				h_H_B_seq_ftr = SRL(J_in=H_B_in, J_bias_in=H_B_bias_in, nb_nodes=3)

				h_P_seq_ftr = tf.reshape(h_P_seq_ftr, [-1, 10, hid_in])
				h_B_seq_ftr = tf.reshape(h_B_seq_ftr, [-1, 5, hid_in])
				h_H_B_seq_ftr = tf.reshape(h_H_B_seq_ftr, [-1, 3, hid_in])

				W_cs_23 = tf.Variable(tf.random_normal([hid_in, hid_out]))
				W_cs_24 = tf.Variable(tf.random_normal([hid_in, hid_out]))
				W_cs_34 = tf.Variable(tf.random_normal([hid_in, hid_out]))

				W_self_2 = tf.Variable(tf.random_normal([hid_in, hid_out]))
				W_self_3 = tf.Variable(tf.random_normal([hid_in, hid_out]))
				W_self_4 = tf.Variable(tf.random_normal([hid_in, hid_out]))

				self_a_2, self_r_2 = FCRL(h_P_seq_ftr, h_P_seq_ftr, 10, 10, hid_in)
				self_a_3, self_r_3 = FCRL(h_B_seq_ftr, h_B_seq_ftr, 5, 5, hid_in)
				self_a_4, self_r_4 = FCRL(h_H_B_seq_ftr, h_H_B_seq_ftr, 3, 3, hid_in)

				h_P_seq_ftr = tf.reshape(h_P_seq_ftr, [-1, hid_in])
				h_B_seq_ftr = tf.reshape(h_B_seq_ftr, [-1, hid_in])
				h_H_B_seq_ftr = tf.reshape(h_H_B_seq_ftr, [-1, hid_in])

				h_P_seq_ftr = tf.reshape(h_P_seq_ftr, [-1, 10, hid_in])
				h_B_seq_ftr = tf.reshape(h_B_seq_ftr, [-1, 5, hid_in])
				h_H_B_seq_ftr = tf.reshape(h_H_B_seq_ftr, [-1, 3, hid_in])

				a_23, r_23 = FCRL(h_B_seq_ftr, h_P_seq_ftr, 5, 10, hid_in)
				a_24, r_24 = FCRL(h_H_B_seq_ftr, h_P_seq_ftr, 3, 10, hid_in)
				a_34, r_34 = FCRL(h_H_B_seq_ftr, h_B_seq_ftr, 3, 5, hid_in)

				h_P_seq_ftr = tf.reshape(h_P_seq_ftr, [-1, hid_in])
				h_B_seq_ftr = tf.reshape(h_B_seq_ftr, [-1, hid_in])
				h_H_B_seq_ftr = tf.reshape(h_H_B_seq_ftr, [-1, hid_in])

				if not struct_only:
					h_P_seq_ftr = h_P_seq_ftr + float(FLAGS.fusion_lambda) * (
								tf.matmul(self_r_2, W_self_2) + tf.matmul(r_23, W_cs_23) + tf.matmul(r_24, W_cs_24))
					h_B_seq_ftr = h_B_seq_ftr + float(FLAGS.fusion_lambda) * (tf.matmul(self_r_3, W_self_3) + tf.matmul(r_34, W_cs_34))
					h_H_B_seq_ftr = h_H_B_seq_ftr + float(FLAGS.fusion_lambda) * (tf.matmul(self_r_4, W_self_4))

				h_P_seq_ftr = tf.reshape(h_P_seq_ftr, [-1, 10,  hid_out])
				h_B_seq_ftr = tf.reshape(h_B_seq_ftr, [-1, 5,  hid_out])
				h_H_B_seq_ftr = tf.reshape(h_H_B_seq_ftr, [-1, 3, hid_out])

				return h_H_B_seq_ftr, h_B_seq_ftr, h_P_seq_ftr

			h_H_B_seq_ftr, h_B_seq_ftr, h_P_seq_ftr = MSC(P_in, B_in, H_B_in, P_bias_in, B_bias_in, H_B_bias_in,
			                                            hid_units[-1], hid_units[-1])

			h_P_seq_ftr = tf.reshape(h_P_seq_ftr, [-1, hid_units[-1]])
			h_B_seq_ftr = tf.reshape(h_B_seq_ftr, [-1, hid_units[-1]])
			h_H_B_seq_ftr = tf.reshape(h_H_B_seq_ftr, [-1, hid_units[-1]])

			optimizer = tf.train.AdamOptimizer(learning_rate=float(FLAGS.lr))
			P_encode = tf.reduce_mean(tf.reshape(h_P_seq_ftr, [batch_size, time_step, -1]), axis=1)
			B_encode = tf.reduce_mean(tf.reshape(h_B_seq_ftr, [batch_size, time_step, -1]), axis=1)
			H_B_encode = tf.reduce_mean(tf.reshape(h_H_B_seq_ftr, [batch_size, time_step, -1]), axis=1)

			P_encode = tf.reshape(P_encode, [batch_size, -1])
			B_encode = tf.reshape(B_encode, [batch_size, -1])
			H_B_encode = tf.reshape(H_B_encode, [batch_size, -1])

			all_ftr = tf.concat([P_encode, B_encode, H_B_encode], axis=-1)
			all_ftr = tf.reshape(all_ftr, [batch_size, -1])

			output = tf.matmul(all_ftr, tf.transpose(cluster_ftr))

			def cluster_loss(pseudo_lab, all_ftr, cluster_ftr):
				all_ftr = tf.nn.l2_normalize(all_ftr, axis=-1)
				cluster_ftr = tf.nn.l2_normalize(cluster_ftr, axis=-1)
				output = tf.matmul(all_ftr, tf.transpose(cluster_ftr))
				output /= float(FLAGS.t)
				loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=pseudo_lab, logits=output))
				return loss

			def empty_loss(b):
				return tf.zeros([1])

			contrastive_loss = tf.cond(tf.reduce_sum(pseudo_lab) > 0,
			                           lambda: cluster_loss(pseudo_lab, all_ftr, cluster_ftr),
			                           lambda: empty_loss(pseudo_lab))
			cluster_train_op = optimizer.minimize(contrastive_loss)

		saver = tf.train.Saver()
		init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())

		with tf.Session(config=config) as sess:
			sess.run(init_op)
			def train_loader(X_train_P, X_train_B, X_train_H_B, y_train):
				tr_step = 0
				tr_size = X_train_P.shape[0]
				train_logits_all = []
				train_labels_all = []
				train_features_all = []
				while tr_step * batch_size < tr_size:
					if (tr_step + 1) * batch_size > tr_size:
						break
					X_input_P = X_train_P[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_P = X_input_P.reshape([-1, 10, 3])
					X_input_B = X_train_B[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_B = X_input_B.reshape([-1, 5, 3])
					X_input_H_B = X_train_H_B[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
					labels = y_train[tr_step * batch_size:(tr_step + 1) * batch_size]
					P_en, B_en, all_features = sess.run([P_encode, B_encode, all_ftr],
					                                                          feed_dict={
						                                                          P_in: X_input_P,
						                                                          B_in: X_input_B,
						                                                          H_B_in: X_input_H_B,
						                                                          P_bias_in: biases_P,
						                                                          B_bias_in: biases_B,
						                                                          H_B_bias_in: biases_H_B,
						                                                          is_train: True,
						                                                          attn_drop: 0.0, ffd_drop: 0.0,
						                                                          pseudo_lab: np.zeros([batch_size, ]),
						                                                          cluster_ftr: np.zeros(
							                                                          [batch_size, all_ftr_size])})
					train_features_all.extend(all_features.tolist())
					train_labels_all.extend(labels.tolist())
					tr_step += 1

				train_features_all = np.array(train_features_all).astype(np.float32)
				train_features_all = torch.from_numpy(train_features_all)
				return train_features_all, train_labels_all

			def gal_loader(X_train_P, X_train_B, X_train_H_B, y_train):
				tr_step = 0
				tr_size = X_train_P.shape[0]
				gal_logits_all = []
				gal_labels_all = []
				gal_features_all = []

				while tr_step * batch_size < tr_size:
					if (tr_step + 1) * batch_size > tr_size:
						break
					X_input_P = X_train_P[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_P = X_input_P.reshape([-1, 10, 3])
					X_input_B = X_train_B[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_B = X_input_B.reshape([-1, 5, 3])
					X_input_H_B = X_train_H_B[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
					labels = y_train[tr_step * batch_size:(tr_step + 1) * batch_size]

					P_en, B_en, all_features = sess.run([P_encode, B_encode, all_ftr],
					                                                          feed_dict={
						                                                          P_in: X_input_P,
						                                                          B_in: X_input_B,
						                                                          H_B_in: X_input_H_B,
						                                                          P_bias_in: biases_P,
						                                                          B_bias_in: biases_B,
						                                                          H_B_bias_in: biases_H_B,
						                                                          is_train: True,
						                                                          attn_drop: 0.0, ffd_drop: 0.0,
						                                                          pseudo_lab: np.zeros([batch_size, ]),
						                                                          cluster_ftr: np.zeros(
							                                                          [batch_size, all_ftr_size])})
					gal_features_all.extend(all_features.tolist())
					gal_labels_all.extend(labels.tolist())
					tr_step += 1

				return gal_features_all, gal_labels_all

			def evaluation():
				vl_step = 0
				vl_size = X_test_P.shape[0]
				pro_labels_all = []
				pro_features_all = []
				loaded_graph = tf.get_default_graph()
				while vl_step * batch_size < vl_size:
					if (vl_step + 1) * batch_size > vl_size:
						break
					X_input_P = X_test_P[vl_step * batch_size:(vl_step + 1) * batch_size]
					X_input_P = X_input_P.reshape([-1, 10, 3])
					X_input_B = X_test_B[vl_step * batch_size:(vl_step + 1) * batch_size]
					X_input_B = X_input_B.reshape([-1, 5, 3])
					X_input_H_B = X_test_H_B[vl_step * batch_size:(vl_step + 1) * batch_size]
					X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
					labels = y_test[vl_step * batch_size:(vl_step + 1) * batch_size]
					P_en, B_en, all_features = sess.run([P_encode, B_encode, all_ftr],
					                                                          feed_dict={
						                                                          P_in: X_input_P,
						                                                          B_in: X_input_B,
						                                                          H_B_in: X_input_H_B,
						                                                          P_bias_in: biases_P,
						                                                          B_bias_in: biases_B,
						                                                          H_B_bias_in: biases_H_B,
						                                                          is_train: False,
						                                                          attn_drop: 0.0, ffd_drop: 0.0,
						                                                          pseudo_lab: np.zeros([batch_size, ]),
						                                                          cluster_ftr: np.zeros(
							                                                          [batch_size, all_ftr_size])})
					pro_labels_all.extend(labels.tolist())
					pro_features_all.extend(all_features.tolist())
					vl_step += 1
				X = np.array(gal_features_all)
				y = np.array(gal_labels_all)
				t_X = np.array(pro_features_all)
				t_y = np.array(pro_labels_all)
				# print(X.shape, t_X.shape)
				t_y = np.argmax(t_y, axis=-1)
				y = np.argmax(y, axis=-1)

				def mean_ap(distmat, query_ids=None, gallery_ids=None,
				            query_cams=None, gallery_cams=None):
					# distmat = to_numpy(distmat)
					m, n = distmat.shape
					# Fill up default values
					if query_ids is None:
						query_ids = np.arange(m)
					if gallery_ids is None:
						gallery_ids = np.arange(n)
					if query_cams is None:
						query_cams = np.zeros(m).astype(np.int32)
					if gallery_cams is None:
						gallery_cams = np.ones(n).astype(np.int32)
					# Ensure numpy array
					query_ids = np.asarray(query_ids)
					gallery_ids = np.asarray(gallery_ids)
					query_cams = np.asarray(query_cams)
					gallery_cams = np.asarray(gallery_cams)
					# Sort and find correct matches
					indices = np.argsort(distmat, axis=1)
					matches = (gallery_ids[indices] == query_ids[:, np.newaxis])
					# Compute AP for each query
					aps = []
					if (FLAGS.probe_view != '' and (FLAGS.probe_view == FLAGS.gallery_view or FLAGS.probe_type == 'nm.nm')) or (FLAGS.probe_type == 'cl.cl' or FLAGS.probe_type == 'bg.bg'):
						for i in range(1, m):
							valid = ((gallery_ids[indices[i]] != query_ids[i]) |
							         (gallery_cams[indices[i]] != query_cams[i]))
							y_true = matches[i, valid]
							y_score = -distmat[i][indices[i]][valid]
							if not np.any(y_true): continue
							aps.append(average_precision_score(y_true, y_score))
					else:
						for i in range(m):
							valid = ((gallery_ids[indices[i]] != query_ids[i]) |
							         (gallery_cams[indices[i]] != query_cams[i]))
							y_true = matches[i, valid]
							y_score = -distmat[i][indices[i]][valid]
							if not np.any(y_true): continue
							aps.append(average_precision_score(y_true, y_score))
					if len(aps) == 0:
						raise RuntimeError("No valid query")
					return np.mean(aps)

				def metrics(X, y, t_X, t_y):
					# compute Euclidean distance
					if dataset != 'CASIA_B':
						a, b = torch.from_numpy(t_X), torch.from_numpy(X)
						m, n = a.size(0), b.size(0)
						a = a.view(m, -1)
						b = b.view(n, -1)
						dist_m = torch.pow(a, 2).sum(dim=1, keepdim=True).expand(m, n) + \
						         torch.pow(b, 2).sum(dim=1, keepdim=True).expand(n, m).t()
						dist_m.addmm_(1, -2, a, b.t())
						dist_m = dist_m.sqrt()
						mAP = mean_ap(distmat=dist_m.numpy(), query_ids=t_y, gallery_ids=y)
						_, dist_sort = dist_m.sort(1)
						dist_sort = dist_sort.numpy()
					else:
						X = np.array(X)
						t_X = np.array(t_X)
						# pred = [cp.argmin(cp.linalg.norm(X - i, axis=1)).tolist() for i in t_X]
						dist_m = [(np.linalg.norm(X - i, axis=1)).tolist() for i in t_X]
						dist_m = np.array(dist_m)
						mAP = mean_ap(distmat=dist_m, query_ids=t_y, gallery_ids=y)
						dist_sort = [np.argsort(np.linalg.norm(X - i, axis=1)).tolist() for i in t_X]
						dist_sort = np.array(dist_sort)

					top_1 = top_5 = top_10 = 0
					probe_num = dist_sort.shape[0]
					if (FLAGS.probe_view != '' and (FLAGS.probe_view == FLAGS.gallery_view or FLAGS.probe_type == 'nm.nm')) or (FLAGS.probe_type == 'cl.cl' or FLAGS.probe_type == 'bg.bg'):
						for i in range(probe_num):
							# print(dist_sort[i, :10])
							if t_y[i] in y[dist_sort[i, 1:2]]:
								top_1 += 1
							if t_y[i] in y[dist_sort[i, 1:6]]:
								top_5 += 1
							if t_y[i] in y[dist_sort[i, 1:11]]:
								top_10 += 1
					else:
						for i in range(probe_num):
							# print(dist_sort[i, :10])
							if t_y[i] in y[dist_sort[i, :1]]:
								top_1 += 1
							if t_y[i] in y[dist_sort[i, :5]]:
								top_5 += 1
							if t_y[i] in y[dist_sort[i, :10]]:
								top_10 += 1
					return mAP, top_1 / probe_num, top_5 / probe_num, top_10 / probe_num

				mAP, top_1, top_5, top_10 = metrics(X, y, t_X, t_y)
				return mAP, top_1, top_5, top_10

			max_acc_1 = 0
			max_acc_2 = 0
			best_cluster_info_1 = [0, 0]
			best_cluster_info_2 = [0, 0]
			cur_patience = 0
			if dataset == 'KGBD' or dataset == 'KS20':
				if FLAGS.gallery_view == '' and FLAGS.probe_view == '':
					_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
					_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
						process.gen_train_data(dataset=dataset, split='gallery', time_step=time_step,
						                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
						                       )
				else:
					_, _, _, _, _, _, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
					_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, b_, nb_classes = \
						process.gen_train_data(dataset=dataset, split='view_'+FLAGS.gallery_view, time_step=time_step,
						                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att,
						                       batch_size=batch_size,
						                       )
			elif dataset == 'BIWI':
				if probe == 'Walking':
					_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
					_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
						process.gen_train_data(dataset=dataset, split='Still', time_step=time_step,
						                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
						                       )
				else:
					_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
					_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
						process.gen_train_data(dataset=dataset, split='Walking', time_step=time_step,
						                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att,
						                       batch_size=batch_size,
						                       )
			elif dataset == 'IAS':
				if probe == 'A':
					_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
					_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
						process.gen_train_data(dataset=dataset, split='B', time_step=time_step,
						                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
						                       )
				else:
					_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
					_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
						process.gen_train_data(dataset=dataset, split='A', time_step=time_step,
						                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att,
						                       batch_size=batch_size,
						                       )
			elif dataset == 'CASIA_B':
				_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
				_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
					process.gen_train_data(dataset=dataset, split=probe, time_step=time_step,
					                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
					                       PG_type=FLAGS.probe_type.split('.')[1])
			for epoch in range(cluster_epochs):
				train_features_all, train_labels_all = train_loader(X_train_P, X_train_B, X_train_H_B, y_train)
				gal_features_all, gal_labels_all = gal_loader(X_gal_P, X_gal_B, X_gal_H_B, y_gal)
				mAP, top_1, top_5, top_10 = evaluation()
				cur_patience += 1
				if epoch > 0 and top_1 > max_acc_2:
					max_acc_1 = mAP
					best_cluster_info_1[0] = num_cluster
					best_cluster_info_1[1] = outlier_num
					cur_patience = 0
					if FLAGS.mode == 'UF' and FLAGS.S_dataset == '':
						if FLAGS.probe_view == '' and FLAGS.gallery_view == '' and FLAGS.dataset != 'CASIA_B':
							# checkpt_file = pre_dir + dataset + '/' + probe + '_' + str(fusion_lambda) + '_' + str(
							# 	nhood) + '_' + str(
							# 	time_step) + '_' +  FLAGS.min_samples + '_' + FLAGS.lr + '_' + FLAGS.eps + '_' + \
							#                FLAGS.t + '_' + change + '_best.ckpt'
							checkpt_file = pre_dir + dataset + '/' + probe  + change + '_best.ckpt'
						elif FLAGS.dataset == 'CASIA_B':
							# checkpt_file = pre_dir + dataset + '/' + probe + '_' + str(fusion_lambda) + '_' + str(
							# 	nhood) + '_' + str(
							# 	time_step) + '_' + FLAGS.min_samples + '_' + FLAGS.lr + '_' + FLAGS.eps + '_' + \
							#                FLAGS.t + '_' + change + '_' + FLAGS.probe_type + '_best.ckpt'
							checkpt_file = pre_dir + dataset + '/' + probe + change + '_' + FLAGS.probe_type + '_best.ckpt'
						else:
							# checkpt_file = pre_dir + dataset + '/' + probe + '_' + str(fusion_lambda) + '_' + str(
							# 	nhood) + '_' + str(
							# 	time_step) + '_' +  FLAGS.min_samples + '_' + FLAGS.lr + '_' + FLAGS.eps + '_' + \
							#                FLAGS.t + '_' + FLAGS.probe_view + 'v' + FLAGS.gallery_view + change + '_best.ckpt'
							checkpt_file = pre_dir + dataset + '/' + probe + '_' + FLAGS.probe_view + 'v' + FLAGS.gallery_view + change + '_best.ckpt'
						print(checkpt_file)
						saver.save(sess, checkpt_file)
				if epoch > 0 and top_1 > max_acc_2:
					max_acc_2 = top_1
					best_cluster_info_2[0] = num_cluster
					best_cluster_info_2[1] = outlier_num
					cur_patience = 0
				if epoch > 0:
					if FLAGS.probe_view != '' and FLAGS.gallery_view != '':
						print('[UF] View: %s v %s | mAP: %.4f (%.4f) | Top-1: %.4f (%.4f) | Top-5: %.4f | Top-10: %.4f | % d + o: %d |' % (
							FLAGS.probe_view, FLAGS.gallery_view, mAP, max_acc_1,
							top_1, max_acc_2, top_5, top_10,
							best_cluster_info_2[0], best_cluster_info_2[1]))
					else:
						print(
							'[UF] %s - %s | mAP: %.4f (%.4f) | Top-1: %.4f (%.4f) | Top-5: %.4f | Top-10: %.4f | % d + o: %d |' % (
							FLAGS.dataset, FLAGS.probe, mAP, max_acc_1,
							top_1, max_acc_2, top_5, top_10,
							best_cluster_info_2[0], best_cluster_info_2[1]))
				if cur_patience == patience:
					break
				rerank_dist = compute_jaccard_distance(train_features_all, k1=k1, k2=k2)

				if dataset == 'IAS' or dataset == 'KS20':
					cluster = DBSCAN(eps=eps, min_samples=min_samples, metric='precomputed', n_jobs=-1)
				else:
					cluster = DBSCAN(eps=eps, min_samples=min_samples, metric='precomputed', n_jobs=-1)
				pseudo_labels = cluster.fit_predict(rerank_dist)
				# discard outliers
				train_features_all = train_features_all[np.where(pseudo_labels != -1)]
				X_train_P_new = X_train_P[np.where(pseudo_labels != -1)]
				X_train_B_new = X_train_B[np.where(pseudo_labels != -1)]
				X_train_H_B_new = X_train_H_B[np.where(pseudo_labels != -1)]
				outlier_num = np.sum(pseudo_labels == -1)
				pseudo_labels = pseudo_labels[np.where(pseudo_labels != -1)]
				num_cluster = len(set(pseudo_labels)) - (1 if -1 in pseudo_labels else 0)

				def generate_cluster_features(labels, features):
					centers = collections.defaultdict(list)
					for i, label in enumerate(labels):
						if label == -1:
							continue
						centers[labels[i]].append(features[i])

					centers = [
						torch.stack(centers[idx], dim=0).mean(0) for idx in sorted(centers.keys())
					]
					centers = torch.stack(centers, dim=0)
					return centers

				cluster_features = generate_cluster_features(pseudo_labels, train_features_all)
				cluster_features = cluster_features.numpy()
				cluster_features = cluster_features.astype(np.float64)

				tr_step = 0
				tr_size = X_train_P_new.shape[0]
				while tr_step * batch_size < tr_size:
					if (tr_step + 1) * batch_size > tr_size:
						break
					X_input_P = X_train_P_new[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_P = X_input_P.reshape([-1, 10, 3])
					X_input_B = X_train_B_new[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_B = X_input_B.reshape([-1, 5, 3])
					X_input_H_B = X_train_H_B_new[tr_step * batch_size:(tr_step + 1) * batch_size]
					X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
					labels = pseudo_labels[tr_step * batch_size:(tr_step + 1) * batch_size]
					_, loss, P_en, B_en, all_features  = sess.run(
						[cluster_train_op, contrastive_loss, P_encode, B_encode, all_ftr],
						feed_dict={
							P_in: X_input_P,
							B_in: X_input_B,
							H_B_in: X_input_H_B,
							P_bias_in: biases_P,
							B_bias_in: biases_B,
							H_B_bias_in: biases_H_B,
							is_train: True,
							attn_drop: 0.0, ffd_drop: 0.0,
							pseudo_lab: labels,
							cluster_ftr: cluster_features})
					if tr_step % display == 0:
						print('[%s] Batch num: %d | Cluser num: %d | Outlier: %d | Loss: %.5f |' %
						      (str(epoch), tr_step, num_cluster, outlier_num, loss))
					tr_step += 1
			sess.close()

elif FLAGS.mode == 'DG' and FLAGS.S_dataset != '':
	if FLAGS.S_dataset == 'KGBD':
		batch_size = 256
		FLAGS.lr = '0.00035'
		FLAGS.min_samples = '4'
		FLAGS.eps = '0.6'
	elif FLAGS.S_dataset == 'CASIA_B':
		batch_size = 128
		FLAGS.lr = '0.00035'
		FLAGS.min_samples = '2'
		FLAGS.eps = '0.75'
	else:
		batch_size = 128
		FLAGS.lr = '0.00035'
	if FLAGS.S_dataset == 'IAS' or FLAGS.S_dataset == 'KS20':
		# if FLAGS.mode != 'DG':
		FLAGS.eps = '0.8'
		FLAGS.min_samples = '2'
		if FLAGS.S_dataset == 'KS20':
			FLAGS.min_samples = '2'

	if FLAGS.S_dataset == 'BIWI':
		FLAGS.min_samples = '2'
		if FLAGS.S_probe == 'Walking':
			FLAGS.eps = '0.6'
		else:
			FLAGS.eps = '0.7'
	# checkpt_file = pre_dir + FLAGS.S_dataset + '/' + FLAGS.S_probe + '_' + str(fusion_lambda) + '_' + str(
	# 	nhood) + '_' + str(
	# 	time_step) + '_' +  FLAGS.min_samples + '_' + FLAGS.lr + '_' + FLAGS.eps + '_' + \
	# 						               FLAGS.t + '_' + change + '_best.ckpt'
	checkpt_file = pre_dir + dataset + '/' + probe + change + '_best.ckpt'
	change = '_DG'
	with tf.Session(graph=loaded_graph, config=config) as sess:
		loader = tf.train.import_meta_graph(checkpt_file + '.meta')
		P_in = loaded_graph.get_tensor_by_name("Input/Placeholder:0")
		B_in = loaded_graph.get_tensor_by_name("Input/Placeholder_1:0")
		H_B_in = loaded_graph.get_tensor_by_name("Input/Placeholder_2:0")
		P_bias_in = loaded_graph.get_tensor_by_name("Input/Placeholder_3:0")
		B_bias_in = loaded_graph.get_tensor_by_name("Input/Placeholder_4:0")
		H_B_bias_in = loaded_graph.get_tensor_by_name("Input/Placeholder_5:0")
		attn_drop = loaded_graph.get_tensor_by_name("Input/Placeholder_6:0")
		ffd_drop = loaded_graph.get_tensor_by_name("Input/Placeholder_7:0")
		is_train = loaded_graph.get_tensor_by_name("Input/Placeholder_8:0")
		pseudo_lab = loaded_graph.get_tensor_by_name("Input/Placeholder_9:0")
		cluster_ftr = loaded_graph.get_tensor_by_name("Input/Placeholder_10:0")

		P_encode = loaded_graph.get_tensor_by_name("MG/MG/Reshape_45:0")
		B_encode = loaded_graph.get_tensor_by_name("MG/MG/Reshape_46:0")
		H_B_encode = loaded_graph.get_tensor_by_name("MG/MG/Reshape_47:0")
		all_ftr = loaded_graph.get_tensor_by_name("MG/MG/Reshape_48:0")

		contrastive_loss = loaded_graph.get_tensor_by_name("MG/MG/cond/Merge:0")
		cluster_train_op = loaded_graph.get_operation_by_name("MG/MG/Adam")

		init_op = tf.global_variables_initializer()
		sess.run(init_op)
		loader.restore(sess, checkpt_file)
		saver = tf.train.Saver()

		def train_loader(X_train_P, X_train_B, X_train_H_B, y_train):
			tr_step = 0
			tr_size = X_train_P.shape[0]
			train_logits_all = []
			train_labels_all = []
			train_features_all = []
			while tr_step * batch_size < tr_size:
				if (tr_step + 1) * batch_size > tr_size:
					break

				X_input_P = X_train_P[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_P = X_input_P.reshape([-1, 10, 3])
				X_input_B = X_train_B[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_B = X_input_B.reshape([-1, 5, 3])
				X_input_H_B = X_train_H_B[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
				labels = y_train[tr_step * batch_size:(tr_step + 1) * batch_size]
				P_en, B_en, all_features = sess.run([P_encode, B_encode, all_ftr],
				                                    feed_dict={
					                                    P_in: X_input_P,
					                                    B_in: X_input_B,
					                                    H_B_in: X_input_H_B,
					                                    P_bias_in: biases_P,
					                                    B_bias_in: biases_B,
					                                    H_B_bias_in: biases_H_B,
					                                    is_train: True,
					                                    attn_drop: 0.0, ffd_drop: 0.0,
					                                    pseudo_lab: np.zeros([batch_size, ]),
					                                    cluster_ftr: np.zeros(
						                                    [batch_size, all_ftr_size])})
				train_features_all.extend(all_features.tolist())
				train_labels_all.extend(labels.tolist())
				tr_step += 1

			train_features_all = np.array(train_features_all).astype(np.float32)
			train_features_all = torch.from_numpy(train_features_all)
			return train_features_all, train_labels_all

		def gal_loader(X_train_P, X_train_B, X_train_H_B, y_train):
			tr_step = 0
			tr_size = X_train_P.shape[0]
			gal_logits_all = []
			gal_labels_all = []
			gal_features_all = []
			while tr_step * batch_size < tr_size:
				if (tr_step + 1) * batch_size > tr_size:
					break

				X_input_P = X_train_P[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_P = X_input_P.reshape([-1, 10, 3])
				X_input_B = X_train_B[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_B = X_input_B.reshape([-1, 5, 3])
				X_input_H_B = X_train_H_B[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
				labels = y_train[tr_step * batch_size:(tr_step + 1) * batch_size]
				P_en, B_en, all_features = sess.run([P_encode, B_encode, all_ftr],
				                                    feed_dict={
					                                    P_in: X_input_P,
					                                    B_in: X_input_B,
					                                    H_B_in: X_input_H_B,
					                                    P_bias_in: biases_P,
					                                    B_bias_in: biases_B,
					                                    H_B_bias_in: biases_H_B,
					                                    is_train: True,
					                                    attn_drop: 0.0, ffd_drop: 0.0,
					                                    pseudo_lab: np.zeros([batch_size, ]),
					                                    cluster_ftr: np.zeros(
						                                    [batch_size, all_ftr_size])})
				gal_features_all.extend(all_features.tolist())
				gal_labels_all.extend(labels.tolist())
				tr_step += 1

			return gal_features_all, gal_labels_all

		def evaluation():
			vl_step = 0
			vl_size = X_test_P.shape[0]
			pro_labels_all = []
			pro_features_all = []
			loaded_graph = tf.get_default_graph()
			while vl_step * batch_size < vl_size:
				if (vl_step + 1) * batch_size > vl_size:
					break

				X_input_P = X_test_P[vl_step * batch_size:(vl_step + 1) * batch_size]
				X_input_P = X_input_P.reshape([-1, 10, 3])
				X_input_B = X_test_B[vl_step * batch_size:(vl_step + 1) * batch_size]
				X_input_B = X_input_B.reshape([-1, 5, 3])
				X_input_H_B = X_test_H_B[vl_step * batch_size:(vl_step + 1) * batch_size]
				X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
				labels = y_test[vl_step * batch_size:(vl_step + 1) * batch_size]
				P_en, B_en, all_features = sess.run([P_encode, B_encode, all_ftr],
				                                    feed_dict={
					                                    P_in: X_input_P,
					                                    B_in: X_input_B,
					                                    H_B_in: X_input_H_B,
					                                    P_bias_in: biases_P,
					                                    B_bias_in: biases_B,
					                                    H_B_bias_in: biases_H_B,
					                                    is_train: False,
					                                    attn_drop: 0.0, ffd_drop: 0.0,
					                                    pseudo_lab: np.zeros([batch_size, ]),
					                                    cluster_ftr: np.zeros(
						                                    [batch_size, all_ftr_size])})
				pro_labels_all.extend(labels.tolist())
				pro_features_all.extend(all_features.tolist())
				vl_step += 1
			X = np.array(gal_features_all)
			y = np.array(gal_labels_all)
			t_X = np.array(pro_features_all)
			t_y = np.array(pro_labels_all)
			# print(X.shape, t_X.shape)
			t_y = np.argmax(t_y, axis=-1)
			y = np.argmax(y, axis=-1)

			def mean_ap(distmat, query_ids=None, gallery_ids=None,
			            query_cams=None, gallery_cams=None):
				# distmat = to_numpy(distmat)
				m, n = distmat.shape
				# Fill up default values
				if query_ids is None:
					query_ids = np.arange(m)
				if gallery_ids is None:
					gallery_ids = np.arange(n)
				if query_cams is None:
					query_cams = np.zeros(m).astype(np.int32)
				if gallery_cams is None:
					gallery_cams = np.ones(n).astype(np.int32)
				# Ensure numpy array
				query_ids = np.asarray(query_ids)
				gallery_ids = np.asarray(gallery_ids)
				query_cams = np.asarray(query_cams)
				gallery_cams = np.asarray(gallery_cams)
				# Sort and find correct matches
				indices = np.argsort(distmat, axis=1)
				matches = (gallery_ids[indices] == query_ids[:, np.newaxis])
				# Compute AP for each query
				aps = []
				if (FLAGS.probe_view != '' and FLAGS.probe_view == FLAGS.gallery_view) or (FLAGS.probe_type == 'nm.nm' or FLAGS.probe_type == 'cl.cl' or FLAGS.probe_type == 'bg.bg'):
					for i in range(1, m):
						valid = ((gallery_ids[indices[i]] != query_ids[i]) |
						         (gallery_cams[indices[i]] != query_cams[i]))
						y_true = matches[i, valid]
						y_score = -distmat[i][indices[i]][valid]
						if not np.any(y_true): continue
						aps.append(average_precision_score(y_true, y_score))
				else:
					for i in range(m):
						valid = ((gallery_ids[indices[i]] != query_ids[i]) |
						         (gallery_cams[indices[i]] != query_cams[i]))
						y_true = matches[i, valid]
						y_score = -distmat[i][indices[i]][valid]
						if not np.any(y_true): continue
						aps.append(average_precision_score(y_true, y_score))
				if len(aps) == 0:
					raise RuntimeError("No valid query")
				return np.mean(aps)

			def metrics(X, y, t_X, t_y):
				a, b = torch.from_numpy(t_X), torch.from_numpy(X)
				# compute Euclidean distance
				m, n = a.size(0), b.size(0)
				a = a.view(m, -1)
				b = b.view(n, -1)
				dist_m = torch.pow(a, 2).sum(dim=1, keepdim=True).expand(m, n) + \
				         torch.pow(b, 2).sum(dim=1, keepdim=True).expand(n, m).t()
				dist_m.addmm_(1, -2, a, b.t())
				dist_m = dist_m.sqrt()

				mAP = mean_ap(distmat=dist_m.numpy(), query_ids=t_y, gallery_ids=y)
				_, dist_sort = dist_m.sort(1)
				dist_sort = dist_sort.numpy()

				top_1 = top_5 = top_10 = 0
				probe_num = dist_sort.shape[0]
				if (FLAGS.probe_view != '' and FLAGS.probe_view == FLAGS.gallery_view) or (FLAGS.probe_type == 'nm.nm' or FLAGS.probe_type == 'cl.cl' or FLAGS.probe_type == 'bg.bg'):
					for i in range(probe_num):
						# print(dist_sort[i, :10])
						if t_y[i] in y[dist_sort[i, 1:2]]:
							top_1 += 1
						if t_y[i] in y[dist_sort[i, 1:6]]:
							top_5 += 1
						if t_y[i] in y[dist_sort[i, 1:11]]:
							top_10 += 1
				else:
					for i in range(probe_num):
						# print(dist_sort[i, :10])
						if t_y[i] in y[dist_sort[i, :1]]:
							top_1 += 1
						if t_y[i] in y[dist_sort[i, :5]]:
							top_5 += 1
						if t_y[i] in y[dist_sort[i, :10]]:
							top_10 += 1
				return mAP, top_1 / probe_num, top_5 / probe_num, top_10 / probe_num

			mAP, top_1, top_5, top_10 = metrics(X, y, t_X, t_y)
			return mAP, top_1, top_5, top_10

		max_acc_1 = 0
		max_acc_2 = 0
		best_cluster_info_1 = [0, 0]
		best_cluster_info_2 = [0, 0]
		cur_patience = 0
		if dataset == 'KGBD' or dataset == 'KS20':
			if FLAGS.gallery_view == '' and FLAGS.probe_view == '':
				_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
				_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
					process.gen_train_data(dataset=dataset, split='gallery', time_step=time_step,
					                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
					                       )
			else:
				_, _, _, _, _, _, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
				_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
					process.gen_train_data(dataset=dataset, split='view_' + FLAGS.gallery_view, time_step=time_step,
					                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att,
					                       batch_size=batch_size,
					                       )
		elif dataset == 'BIWI':
			if probe == 'Walking':
				_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
				_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
					process.gen_train_data(dataset=dataset, split='Still', time_step=time_step,
					                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
					                       )
			else:
				_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
				_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
					process.gen_train_data(dataset=dataset, split='Walking', time_step=time_step,
					                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att,
					                       batch_size=batch_size,
					                       )
		elif dataset == 'IAS':
			if probe == 'A':
				_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
				_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
					process.gen_train_data(dataset=dataset, split='B', time_step=time_step,
					                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
					                       )
			else:
				_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
				_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
					process.gen_train_data(dataset=dataset, split='A', time_step=time_step,
					                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att,
					                       batch_size=batch_size,
					                       )
		elif dataset == 'CASIA_B':
			_, X_train_P, X_train_B, X_train_H_B, _, y_train, _, X_gal_P, X_gal_B, X_gal_H_B, _, y_gal, \
			_, _, adj_P, biases_P, adj_B, biases_B, adj_H_B, biases_H_B, _, _, nb_classes = \
				process.gen_train_data(dataset=dataset, split=probe, time_step=time_step,
				                       nb_nodes=nb_nodes, nhood=nhood, global_att=global_att, batch_size=batch_size,
				                       PG_type=FLAGS.probe_type.split('.')[1])
		for epoch in range(cluster_epochs):
			train_features_all, train_labels_all = train_loader(X_train_P, X_train_B, X_train_H_B, y_train)
			# train_features_all = train_features_all.numpy()
			gal_features_all, gal_labels_all = gal_loader(X_gal_P, X_gal_B, X_gal_H_B, y_gal)
			mAP, top_1, top_5, top_10 = evaluation()
			cur_patience += 1
			if epoch > 0 and top_1 > max_acc_2:
				max_acc_1 = mAP
				best_cluster_info_1[0] = num_cluster
				best_cluster_info_1[1] = outlier_num
				cur_patience = 0
				if FLAGS.mode == 'DG' and FLAGS.S_dataset != '':
					if FLAGS.probe_view == '' and FLAGS.gallery_view == '':
						# checkpt_file = pre_dir + dataset + '/' + probe + '_' + str(fusion_lambda) + '_' + str(
						# 	nhood) + '_' + str(
						# 	time_step) + '_' + FLAGS.min_samples + '_' + FLAGS.lr + '_' + FLAGS.eps + '_' + \
						#                FLAGS.density_lambda + '_' + change + '_best.ckpt'
						checkpt_file = pre_dir + dataset + '/' + probe + change + '_best.ckpt'
					else:
						checkpt_file = pre_dir + dataset + '/' + probe + '_' + FLAGS.probe_view + 'v' + \
						               FLAGS.gallery_view + change + '_best.ckpt'
					print(checkpt_file)
					saver.save(sess, checkpt_file)
			if epoch > 0 and top_1 > max_acc_2:
				max_acc_2 = top_1
				best_cluster_info_2[0] = num_cluster
				best_cluster_info_2[1] = outlier_num
				cur_patience = 0
			if FLAGS.evaluate == '1':
				print(
						'[Evaluate on %s - %s] | mAP: %.4f | Top-1: %.4f | Top-5: %.4f | Top-10: %.4f' % (
					FLAGS.dataset, FLAGS.probe, mAP,
					top_1, top_5, top_10))
				exit()
			else:
				if FLAGS.probe_view != '' and FLAGS.gallery_view != '':
					print(
					'[DG] View: %s v %s | mAP: %.4f (%.4f) | Top-1: %.4f (%.4f) | Top-5: %.4f | Top-10: %.4f | % d + o: %d |' % (
						FLAGS.probe_view, FLAGS.gallery_view, mAP, max_acc_1,
						top_1, max_acc_2, top_5, top_10,
						best_cluster_info_2[0], best_cluster_info_2[1]))
				else:
					print(
							'[DG] %s - %s | mAP: %.4f (%.4f) | Top-1: %.4f (%.4f) | Top-5: %.4f | Top-10: %.4f | % d + o: %d |' % (
						FLAGS.dataset, FLAGS.probe, mAP, max_acc_1,
						top_1, max_acc_2, top_5, top_10,
						best_cluster_info_2[0], best_cluster_info_2[1]))
			if cur_patience == patience:
				break
			rerank_dist = compute_jaccard_distance(train_features_all, k1=k1, k2=k2)
			if dataset == 'IAS' or dataset == 'KS20':
				cluster = DBSCAN(eps=eps, min_samples=min_samples, metric='precomputed', n_jobs=-1)
			else:
				cluster = DBSCAN(eps=eps, min_samples=min_samples, metric='precomputed', n_jobs=-1)
			pseudo_labels = cluster.fit_predict(rerank_dist)
			# discard outliers
			train_features_all = train_features_all[np.where(pseudo_labels != -1)]

			X_train_P_new = X_train_P[np.where(pseudo_labels != -1)]
			X_train_B_new = X_train_B[np.where(pseudo_labels != -1)]
			X_train_H_B_new = X_train_H_B[np.where(pseudo_labels != -1)]
			outlier_num = np.sum(pseudo_labels == -1)
			pseudo_labels = pseudo_labels[np.where(pseudo_labels != -1)]
			# print(pseudo_labels)
			num_cluster = len(set(pseudo_labels)) - (1 if -1 in pseudo_labels else 0)

			def generate_cluster_features(labels, features):
				centers = collections.defaultdict(list)
				for i, label in enumerate(labels):
					if label == -1:
						continue
					centers[labels[i]].append(features[i])

				centers = [
					torch.stack(centers[idx], dim=0).mean(0) for idx in sorted(centers.keys())
				]
				# print(centers)

				centers = torch.stack(centers, dim=0)
				return centers

			cluster_features = generate_cluster_features(pseudo_labels, train_features_all)
			cluster_features = cluster_features.numpy()
			cluster_features = cluster_features.astype(np.float64)

			tr_step = 0
			tr_size = X_train_P_new.shape[0]
			# pro_en_P = []
			# pro_en_B = []
			while tr_step * batch_size < tr_size:
				if (tr_step + 1) * batch_size > tr_size:
					break
				X_input_P = X_train_P_new[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_P = X_input_P.reshape([-1, 10, 3])
				X_input_B = X_train_B_new[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_B = X_input_B.reshape([-1, 5, 3])
				X_input_H_B = X_train_H_B_new[tr_step * batch_size:(tr_step + 1) * batch_size]
				X_input_H_B = X_input_H_B.reshape([-1, 3, 3])
				labels = pseudo_labels[tr_step * batch_size:(tr_step + 1) * batch_size]
				_, loss, P_en, B_en, all_features = sess.run(
					[cluster_train_op, contrastive_loss, P_encode, B_encode, all_ftr],
					feed_dict={
						P_in: X_input_P,
						B_in: X_input_B,
						H_B_in: X_input_H_B,
						P_bias_in: biases_P,
						B_bias_in: biases_B,
						H_B_bias_in: biases_H_B,
						is_train: True,
						attn_drop: 0.0, ffd_drop: 0.0,
						pseudo_lab: labels,
						cluster_ftr: cluster_features})
				if tr_step % display == 0:
					print('[%s] Batch num: %d | Cluser num: %d | Outlier: %d | Loss: %.5f |' %
					      (str(epoch), tr_step, num_cluster, outlier_num, loss))
				tr_step += 1
		sess.close()

print('----- Model hyperparams -----')
# print('skeleton_nodes: ' + str(nb_nodes))
print('seqence_length: ' + str(time_step))
print('fusion_lambda: ' + str(fusion_lambda))
print('batch_size: ' + str(batch_size))
print('lr: ' + str(FLAGS.lr))
print('temperature: ' + FLAGS.t)
print('eps: ' + FLAGS.eps)
print('min_samples: ' + FLAGS.min_samples)
print('m: ' + FLAGS.m)
print('fusion_lambda: ' + FLAGS.fusion_lambda)
print('patience: ' + FLAGS.patience)

print('Mode: ' + FLAGS.mode)

if FLAGS.mode == 'DG':
	print('----- Mode Information  -----')
	print('Source Dataset: ' + FLAGS.S_dataset)
	print('Target Dataset: ' + FLAGS.dataset)
	print('Target Probe: ' + FLAGS.probe)
elif FLAGS.mode == 'UF':
	print('----- Dataset Information  -----')
	print('Dataset: ' + dataset)
	print('Probe: ' + FLAGS.probe)

max_stars_repo_name: Kali-Hac/SPC-MGR

max_issues_repo_name: Kali-Hac/SPC-MGR

max_forks_repo_name: Kali-Hac/SPC-MGR


text:
import numpy as np
import pandas as pd
import pathlib

def generate_edgelist(n_nodes, rel_ratio_min=0.1, rel_ratio_max=0.3, n_nodes_mu=4.5, weight_mu=2, weight_sigma=0.5):
    df_list = []
    for i in range(6):
        rel_min = int((n_nodes - 6) * rel_ratio_min)
        rel_max = int((n_nodes - 6) * rel_ratio_max)
        if rel_max <= 1:
            rel_max = 2
        n_suppliers = np.random.randint(rel_min, rel_max, 1)
        n_customers = np.random.randint(rel_min, rel_max, 1)
        suppliers = np.random.choice(list(range(6, n_nodes)), n_suppliers, replace=False)
        customers = np.random.choice(list(range(6, n_nodes)), n_customers, replace=False)
        supplier_weights = np.random.normal(weight_mu * (np.log(n_nodes) / n_nodes_mu), weight_sigma, n_suppliers)
        customer_weights = np.random.normal(weight_mu * (np.log(n_nodes) / n_nodes_mu), weight_sigma, n_customers)
        df_suppliers = pd.DataFrame({
            'src': i,
            'dst': suppliers,
            'weight': supplier_weights
        })
        df_customers = pd.DataFrame({
            'src': customers,
            'dst': i,
            'weight': customer_weights
        })
        df_list.append(df_suppliers)
        df_list.append(df_customers)
    df_edges = pd.concat(df_list)
    df_edges = df_edges[df_edges['weight'] > 0].reset_index(drop=True)
    return df_edges

def generate_files(output_dir, n_graphs=1000, n_nodes_mu=4.5, n_nodes_sigma=1.0):
    # make data directory
    path = pathlib.Path(output_dir)
    path.mkdir(parents=True, exist_ok=True)
    # generate graphs
    n_nodes_list = np.random.lognormal(n_nodes_mu, n_nodes_sigma, n_graphs).astype(int) + 8
    for i in range(n_graphs):
        df_edgelist = generate_edgelist(n_nodes_list[i])
        while df_edgelist.empty:
            df_edgelist = generate_edgelist(n_nodes_list[i])
        filename = path / '{}.edgelist'.format(i)
        df_edgelist.to_csv(filename, header=False, index=False)
    # generate target file
    target_ratios = np.sqrt(6 / n_nodes_list)
    targets = [ np.random.choice([0, 1], p=[1-r, r]) for r in target_ratios ]
    df_targets = pd.DataFrame({
        'company_id': list(range(n_graphs)),
        'target': targets
    }).set_index('company_id')
    filename = path / 'target.csv'
    df_targets.to_csv(filename)

if __name__ == '__main__':
    np.random.seed(123)
    train_data_dir = 'data/train'
    test_data_dir = 'data/test'
    generate_files(train_data_dir)
    generate_files(test_data_dir)

ext: py

reason: import numpy


text:
import numpy as np  #数値計算用モジュール
import runge_kutta2

def func_dydt1(t, y):
    return np.cos(t)  #dy/dt = cos(t)

t_list1, y_list1 = runge_kutta2.ode_calc(func_dydt1, 0.0, 5.0, -5.0, 1e-1)
runge_kutta2.visualization(t_list1, y_list1)

def func_dydt2(t, y):
    return -y  #dy/dt = -y(t)

t_list2, y_list2 = runge_kutta2.ode_calc(func_dydt2, 5.0, 0.0, 10.0, 1e-1)
runge_kutta2.visualization(t_list2, y_list2)


text:
from mylib.centroidtracker import CentroidTracker
from mylib.trackableobject import TrackableObject
from imutils.video import VideoStream
from imutils.video import FPS
#from imutils import resize
from mylib.mailer import Mailer
from mylib import config,thread
from mylib.config import x1,y1,x2,y2,vertical_direction,enter_direction,cam_place
import time, schedule, csv
import numpy as np
import argparse, imutils
import time, dlib, cv2, datetime
from itertools import zip_longest
from Lineiterator import createLineIterator
from limitexceed import check_exceed
from get_requests import send_req
from os.path import exists
from excel_data_converter import create_summary, data_converter

t0 = time.time()

def run():

	# construct the argument parse and parse the arguments
	ap = argparse.ArgumentParser()
	ap.add_argument("-p", "--prototxt", required=False,
		help="path to Caffe 'deploy' prototxt file")
	ap.add_argument("-m", "--model", required=True,
		help="path to Caffe pre-trained model")
	ap.add_argument("-i", "--input", type=str,
		help="path to optional input video file")
	ap.add_argument("-cam", "--camera", required=True,type=str,
		help="summary camera name")
	ap.add_argument("-o", "--output", type=str,
		help="path to optional output video file")
	# confidence default 0.4
	ap.add_argument("-c", "--confidence", type=float, default=0.4,
		help="minimum probability to filter weak detections")
	ap.add_argument("-s", "--skip-frames", type=int, default=30,
		help="# of skip frames between detections")
	args = vars(ap.parse_args())

	# initialize the list of class labels MobileNet SSD was trained to
	# detect
	CLASSES = ["background", "aeroplane", "bicycle", "bird", "boat",
		"bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
		"dog", "horse", "motorbike", "person", "pottedplant", "sheep",
		"sofa", "train", "tvmonitor"]

	# load our serialized model from disk
	net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])

	# if a video path was not supplied, grab a reference to the ip camera
	if not args.get("input", False):
		print("[INFO] Starting the live stream..")
		vs = VideoStream(src=config.url).start()
		#time.sleep(2.0)

	# otherwise, grab a reference to the video file
	else:
		print("[INFO] Starting the video..")
		vs = cv2.VideoCapture(args["input"])

	# initialize the video writer (we'll instantiate later if need be)
	writer = None

	# initialize the frame dimensions (we'll set them as soon as we read
	# the first frame from the video)
	W = None
	H = None

	if config.five_mins == True:
		now=datetime.datetime.now()
		fivemin= now+datetime.timedelta(0,300)
	if config.people_change == True:
		peoplechangelist= []
	###################################
	try:
		m = ((-1*y2)-y1)/((x2)-x1)
	except:
		m = 1000000001
	print(m)
	# m = (y2-y1)/(x2-x1)
	# 0,0 -w // 2, -hi
	#print(m)
	iterlist=createLineIterator(np.array([int(round(x1)), int(round(y1))]),np.array([int(round(x2)), int(round(y2))]))
	#cv2.line(frame, (0, int(round(0))), (W // 2, int(round(H))), (0, 0, 0), 3)
	#iterlist=createLineIterator(np.array([0, round(hi * 0.8)]),np.array([wi, round(hi * 0.80)]))
	#iterlist= [(x,hi-y) for (x,y) in iterlist]
	#print(iterlist)
	#print(iterlist)
	# instantiate our centroid tracker, then initialize a list to store
	# each of our dlib correlation trackers, followed by a dictionary to
	# map each unique object ID to a TrackableObject
	################

	ct = CentroidTracker(maxDisappeared=40, maxDistance=50)
	trackers = []
	trackableObjects = {}

	# initialize the total number of frames processed thus far, along
	# with the total number of objects that have moved either up or down
	totalFrames = 0
	x = []
	#if enter_direction == 'down':
	totalDown = 0
	totalUp = 0
	empty=[]
	empty1=[]

	# start the frames per second throughput estimator
	fps = FPS().start()

	if config.Thread:
		vs = thread.ThreadingClass(config.url)

	# loop over frames from the video stream
	while True:
		# grab the next frame and handle if we are reading from either
		# VideoCapture or VideoStream
		frame = vs.read()

		frame = frame[1] if args.get("input", False) else frame

		# if we are viewing a video and we did not grab a frame then we
		# have reached the end of the video
		if args["input"] is not None and frame is None:
			break

		# resize the frame to have a maximum width of 500 pixels (the
		# less data we have, the faster we can process it), then convert
		# the frame from BGR to RGB for dlib
		try:
			frame = imutils.resize(frame, width = 500)
		except AttributeError:
			print(frame)
			raise AttributeError

		rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

		# if the frame dimensions are empty, set them
		try:

			if W is None or H is None:
				(H, W) = frame.shape[:2]
				print(f"Frame height  is : {H}, frame width is : {W}")
		except AttributeError:
			print('(H, W) = frame.shape[:2] error')
			raise AttributeError

		# if we are supposed to be writing a video to disk, initialize
		# the writer
		if args["output"] is not None and writer is None:
			fourcc = cv2.VideoWriter_fourcc(*"mp4v")
			writer = cv2.VideoWriter(args["output"], fourcc, 30,
				(W, H), True)

		# initialize the current status along with our list of bounding
		# box rectangles returned by either (1) our object detector or
		# (2) the correlation trackers
		status = "Waiting"
		rects = []

		if config.five_mins == True:
			if datetime.datetime.now() >= fivemin:
				enterp=info[1][1]
				exitp=info[0][1]
				send_req(enterp,exitp)
				now = datetime.datetime.now()
				fivemin = now + datetime.timedelta(0,300)
		if config.people_change == True:
			if len(peoplechangelist) >= 2:
				if peoplechangelist[-1] != peoplechangelist[-2]:
					enterp=info[1][1]
					exitp=info[0][1]
					print(peoplechangelist)
					send_req(enterp,exitp)
			if len(peoplechangelist) > 2:
				del peoplechangelist[:-2]

		# check to see if we should run a more computationally expensive
		# object detection method to aid our tracker
		if totalFrames % args["skip_frames"] == 0:
			# set the status and initialize our new set of object trackers
			status = "Detecting"
			trackers = []

			# convert the frame to a blob and pass the blob through the
			# network and obtain the detections
			blob = cv2.dnn.blobFromImage(frame, 0.007843, (W, H), 127.5)
			net.setInput(blob)
			detections = net.forward()

			# loop over the detections
			for i in np.arange(0, detections.shape[2]):
				# extract the confidence (i.e., probability) associated
				# with the prediction
				confidence = detections[0, 0, i, 2]

				# filter out weak detections by requiring a minimum
				# confidence
				if confidence > args["confidence"]:
					# extract the index of the class label from the
					# detections list
					idx = int(detections[0, 0, i, 1])

					# if the class label is not a person, ignore it
					if CLASSES[idx] != "person":
						continue

					# compute the (x, y)-coordinates of the bounding box
					# for the object
					box = detections[0, 0, i, 3:7] * np.array([W, H, W, H])
					(startX, startY, endX, endY) = box.astype("int")

					# construct a dlib rectangle object from the bounding
					# box coordinates and then start the dlib correlation
					# tracker
					tracker = dlib.correlation_tracker()
					rect = dlib.rectangle(startX, startY, endX, endY)
					tracker.start_track(rgb, rect)

					# add the tracker to our list of trackers so we can
					# utilize it during skip frames
					trackers.append(tracker)

		# otherwise, we should utilize our object *trackers* rather than
		# object *detectors* to obtain a higher frame processing throughput
		else:
			# loop over the trackers
			for tracker in trackers:
				# set the status of our system to be 'tracking' rather
				# than 'waiting' or 'detecting'
				status = "Tracking"

				# update the tracker and grab the updated position
				tracker.update(rgb)
				pos = tracker.get_position()

				# unpack the position object
				startX = int(pos.left())
				startY = int(pos.top())
				endX = int(pos.right())
				endY = int(pos.bottom())

				# add the bounding box coordinates to the rectangles list
				rects.append((startX, startY, endX, endY))

		# draw a horizontal line in the center of the frame -- once an
		# object crosses this line we will determine whether they were
		# moving 'up' or 'down'
		cv2.line(frame, (int(round(x1)), int(round(y1))), (int(round(x2)), int(round(y2))), (0, 0, 255), 3)
		#iterlist=createLineIterator(np.array([0, round(H * 0.50)]),np.array([W, round(H * 0.66)]),frame)
		#print(len(iterlist))
		cv2.putText(frame, "-Prediction border - Entrance-", (10, H - ((i * 20) + 200)),
			cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1)

		# use the centroid tracker to associate the (1) old object
		# centroids with (2) the newly computed object centroids
		objects = ct.update(rects)

		# loop over the tracked objects
		for (objectID, centroid) in objects.items():
			# check to see if a trackable object exists for the current
			# object ID
			to = trackableObjects.get(objectID, None)

			# if there is no existing trackable object, create one
			if to is None:
				to = TrackableObject(objectID, centroid)

			# otherwise, there is a trackable object so we can utilize it
			# to determine direction
			else:
				# the difference between the y-coordinate of the *current*
				# centroid and the mean of *previous* centroids will tell
				# us in which direction the object is moving (negative for
				# 'up' and positive for 'down')
				if vertical_direction == 1:
					y = [c[1] for c in to.centroids]
					#print(y)
					#direction = centroid[1] - np.mean(y)
					direction =  0
					to.centroids.append(centroid)
					#print(to.centroids)
					direction_all=[]
					if len(y) >= 40:
						# sum  of xi - mean(xi-1)
						#try
							#direction_all=[]
						for index,i in enumerate(y[-41:]):
							prev_mean= np.mean(y[:index+1])
							direc= i - prev_mean
							direction_all.append(direc)
						if all([x > 0 for x in direction_all]):
							direction = 1
						elif all([x < 0 for x in direction_all]):
							direction = -1
						else:
							direction = 0
						#except
				else:
					y = [c[0] for c in to.centroids]
					#print(y)
					#direction = centroid[1] - np.mean(y)
					direction =  0
					to.centroids.append(centroid)
					#print(to.centroids)
					direction_all=[]
					if len(y) >= 40:
						# sum  of xi - mean(xi-1)
						#try
							#direction_all=[]
						for index,i in enumerate(y[-41:]):
							prev_mean= np.mean(y[:index+1])
							direc= i - prev_mean
							direction_all.append(direc)
						if all([x > 0 for x in direction_all]):
							# right
							direction = 1
						elif all([x < 0 for x in direction_all]):
							#left
							direction = -1
						else:
							direction = 0

				# check to see if the object has been counted or not
				if not to.counted:
					if centroid[0] < iterlist[0][0] or centroid[0] > iterlist[-1][0]:
						pass
					elif m == 1000000001 and (centroid[1] < iterlist[0][1] or centroid[1] > iterlist[-1][1]):
						pass
					if m < 0 and vertical_direction == 1:
						# if the direction is negative (indicating the object
						# is moving up) AND the centroid is above the center
						# line, count the object
						# H is between 0 and 500 the over the value the upper it will be, the higher the value, the lower it will be.
						#if direction < 0 and centroid[1] < int(round(H * 0.66)):
						#print(str(centroid))
						if direction < 0:
							for i in iterlist:
								if centroid[0] > i[0] and centroid[1] < i[1]:

									totalUp += 1
									empty.append(totalUp)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going up' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'up':
										check_exceed(x,frame)
									break

						# if the direction is positive (indicating the object
						# is moving down) AND the centroid is below the
						# center line, count the object
						#elif direction > 0 and centroid[1] > int(round(H * 0.66)):
						elif direction > 0:
							for i in iterlist:
								if centroid[0] < i[0] and centroid[1] > i[1]:
									totalDown += 1
									empty1.append(totalDown)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going down' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'down':
										check_exceed(x,frame)
									break
									#print(empty1[-1])
									# if the people limit exceeds over threshold, send an email alert
					elif m == 0 and vertical_direction == 1:

						if direction < 0:
							for i in iterlist:
								if centroid[1] < i[1]:

									totalUp += 1
									empty.append(totalUp)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going up' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'up':
										check_exceed(x,frame)
									break

						elif direction > 0:
							for i in iterlist:
								if centroid[1] > i[1]:
									totalDown += 1
									empty1.append(totalDown)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going down' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'down':
										check_exceed(x,frame)
									break

					elif 0 < m < 1000000000 and vertical_direction == 1:

						if direction < 0:
							for i in iterlist:
								if centroid[0] < i[0] and centroid[1] < i[1]:

									totalUp += 1
									empty.append(totalUp)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going up' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'up':
										check_exceed(x,frame)
									break

						elif direction > 0:
							for i in iterlist:
								if centroid[0] > i[0] and centroid[1] > i[1]:
									totalDown += 1
									empty1.append(totalDown)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going down' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'down':
										check_exceed(x,frame)
									break

					elif m < 0 and vertical_direction == 0:

						# if the direction is negative (indicating the object
						# is moving LEFT) AND the centroid is on the left side
						# line, count the object

						if direction < 0:
							for i in iterlist:
								if centroid[0] < i[0] and centroid[1] > i[1]:

									totalUp += 1
									empty.append(totalUp)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going left' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'left':
										check_exceed(x,frame)
									break

						# if the direction is positive (indicating the object
						# is moving RIGHT) AND the centroid is on the the side
						#  line, count the object
						elif direction > 0:
							for i in iterlist:
								if centroid[0] > i[0] and centroid[1] < i[1]:
									totalDown += 1
									empty1.append(totalDown)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going right' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'right':
										check_exceed(x,frame)
									break

					elif m >= 1000000000 and vertical_direction == 0:
						# m is infinite/ vertical line
						if direction < 0:
							for i in iterlist:
								if centroid[0] < i[0]:

									totalUp += 1
									empty.append(totalUp)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going left' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'left':
										check_exceed(x,frame)
									break

						elif direction > 0:
							for i in iterlist:
								if centroid[0] > i[0]:
									totalDown += 1
									empty1.append(totalDown)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going right' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'right':
										check_exceed(x,frame)
									break

					elif 0 < m < 1000000000 and vertical_direction == 0:

						if direction < 0:
							for i in iterlist:
								if centroid[0] < i[0] and centroid[1] < i[1]:

									totalUp += 1
									empty.append(totalUp)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going left' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'left':
										check_exceed(x,frame)
									break

						elif direction > 0:
							for i in iterlist:
								if centroid[0] > i[0] and centroid[1] > i[1]:
									totalDown += 1
									empty1.append(totalDown)
									to.counted = True
									print('ID '+ str(to.objectID) + ' going right' + ' direction : ' + str(direction) + ' centroid : ' + str(centroid) + ' pixcel compared to : ' + str(i[0]) + ' ' + str(i[1]))
									if enter_direction == 'right':
										check_exceed(x,frame)
									break

					x = []
					# compute the sum of total people inside
					if enter_direction == 'down' or enter_direction == 'right':
						x.append(len(empty1)-len(empty))
					else:
						x.append(len(empty)-len(empty1))
					#print("Total people inside:", x)

			# store the trackable object in our dictionary
			trackableObjects[objectID] = to

			#print(peoplechangelist)
			# draw both the ID of the object and the centroid of the
			# object on the output frame
			text = "ID {}".format(objectID)
			cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10),
				cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
			cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1)

		# construct a tuple of information we will be displaying on the
		if enter_direction == 'down' or enter_direction == 'right':
			info = [
			("Exit", totalUp),
			("Enter", totalDown),
			("Status", status),
			]
		else:
			info = [
			("Exit", totalDown),
			("Enter", totalUp),
			("Status", status),
			]

		info2 = [
		("Total people inside", x),
		]
		if config.people_change == True:
                        #if len(peoplechangelist) > 0:
			peoplechangelist.append(x)

		try:
			assert objectID
			assert centroid
			text = "ID {}".format(objectID)
			cv2.putText(frame, text, (centroid[0] - 10, centroid[1] - 10),
				cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
			cv2.circle(frame, (centroid[0], centroid[1]), 4, (255, 255, 255), -1)
		except (AssertionError,ValueError,NameError):
			pass
		try:
			if int(info2[0][1][0]) >= config.Threshold:
				cv2.putText(frame, "-ALERT: People limit exceeded-", (10, frame.shape[0] - 80),
					cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 255), 2)
				if config.ALERT:
					print("[INFO] Sending email alert..")
					Mailer().send(config.MAIL)
					print("[INFO] Alert sent")
		except IndexError:
			pass
		# Display the output
		for (i, (k, v)) in enumerate(info):
			text = "{}: {}".format(k, v)
			cv2.putText(frame, text, (10, H - ((i * 20) + 20)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2)

		for (i, (k, v)) in enumerate(info2):
			text = "{}: {}".format(k, v)
			cv2.putText(frame, text, (265, H - ((i * 20) + 60)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)

		# Initiate a simple log to save data at end of the day
		if config.Log:
			try:
				timeinxmins
			except NameError:
				timeinxmins=datetime.datetime.now() + config.timedel

			if datetime.datetime.now() >= timeinxmins:
				#data={'櫃位地點':config.cam_place,'People Enter':info[1][1],'People Exit':info[0][1],'Current People Inside':info2[0][1],'Date':datetime.datetime.now()}
				#df=pd.DataFrame(data=data)
				timeinxmins=datetime.datetime.now() + config.timedel
				cam_place=str(args["camera"])
				excel_name=f"./summary/{cam_place} summary.xlsx"
				if exists(excel_name):
					#with pd.ExcelWriter(excel_name,mode='a')  as writer:
					#append_df_to_excel(excel_name, df,header=None, index=False)
					data_converter(info[1][1],info[0][1],excel_name)
				else:
					create_summary(info[1][1],info[0][1],excel_name)
				print('summary exported!')

		# check to see if we should write the frame to disk
		if writer is not None:
			writer.write(frame)

		# show the output frame
		cv2.imshow("Real-Time Monitoring/Analysis Window", frame)
		key = cv2.waitKey(1) & 0xFF

		# if the `q` key was pressed, break from the loop
		if key == ord("q"):
			break

		# increment the total number of frames processed thus far and
		# then update the FPS counter
		totalFrames += 1
		fps.update()

		if config.Timer:
			# Automatic timer to stop the live stream. Set to 8 hours (28800s).
			t1 = time.time()
			num_seconds=(t1-t0)
			if num_seconds > 28800:
				break
	if config.Scheduler:
			if datetime.datetime.now() >= tmr :
				print('renew program')
				raise ValueError
	# stop the timer and display FPS information
	fps.stop()
	print("[INFO] elapsed time: {:.2f}".format(fps.elapsed()))
	print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

	# # if we are not using a video file, stop the camera video stream
	# if not args.get("input", False):
	# 	vs.stop()
	#
	# # otherwise, release the video file pointer
	# else:
	# 	vs.release()

	# issue 15
	if config.Thread:
		vs.release()

	# close any open windows
	cv2.destroyAllWindows()

##learn more about different schedules here: https://pypi.org/project/schedule/
if config.Scheduler:
    ##Runs for every 1 second
    schedule.every(1).seconds.do(run)
    global tmr

    ##Runs at every day (9:00 am). You can change it.
    #schedule.every().day.at("9:00").do(run)
    while 1:
        tmr=datetime.datetime.now()
        try:
            tmr=tmr.replace(day=tmr.day + 1, hour=0, minute=0, second=0, microsecond=0)
            #tmr=tmr.replace(day=tmr.day, hour=tmr.hour, minute=tmr.minute + 1, second=0, microsecond=0)
        except ValueError:
            try:
                tmr=tmr.replace(month=tmr.month + 1, day= 1,hour=0, minute=0, second=0, microsecond=0)
            except ValueError:
                tmr=tmr.replace(year= tmr.year + 1 ,month= 1, day= 1,hour=0, minute=0, second=0, microsecond=0)
        print(tmr)
        print(datetime.datetime.now())
        try:
            schedule.run_pending()

            if datetime.datetime.now() >= tmr:
                print('renew program')
                raise ValueError

        except:
            print('schedule error')
            continue
else:
    run()


text:
import dgl
import sys
import random
import time
import numpy as np
from multiprocessing import Process, Manager
from scipy import sparse as spsp
import mxnet as mx
import backend as F
import unittest
import dgl.function as fn
import traceback
from numpy.testing import assert_almost_equal

num_nodes = 100
num_edges = int(num_nodes * num_nodes * 0.1)
rand_port = random.randint(5000, 8000)
print('run graph store with port ' + str(rand_port), file=sys.stderr)

def check_array_shared_memory(g, worker_id, arrays):
    if worker_id == 0:
        for i, arr in enumerate(arrays):
            arr[0] = i
        g._sync_barrier(60)
    else:
        g._sync_barrier(60)
        for i, arr in enumerate(arrays):
            assert_almost_equal(arr[0].asnumpy(), i)

def create_graph_store(graph_name):
    for _ in range(10):
        try:
            g = dgl.contrib.graph_store.create_graph_from_store(graph_name, "shared_mem",
                                                                port=rand_port)
            return g
        except ConnectionError as e:
            traceback.print_exc()
            time.sleep(1)
    return None

def check_init_func(worker_id, graph_name, return_dict):
    time.sleep(3)
    print("worker starts")
    np.random.seed(0)
    csr = (spsp.random(num_nodes, num_nodes, density=0.1, format='csr') != 0).astype(np.int64)

    # Verify the graph structure loaded from the shared memory.
    try:
        g = create_graph_store(graph_name)
        if g is None:
            return_dict[worker_id] = -1
            return

        src, dst = g.all_edges()
        coo = csr.tocoo()
        assert F.array_equal(dst, F.tensor(coo.row))
        assert F.array_equal(src, F.tensor(coo.col))
        assert F.array_equal(g.nodes[0].data['feat'], F.tensor(np.arange(10), dtype=np.float32))
        assert F.array_equal(g.edges[0].data['feat'], F.tensor(np.arange(10), dtype=np.float32))
        g.init_ndata('test4', (g.number_of_nodes(), 10), 'float32')
        g.init_edata('test4', (g.number_of_edges(), 10), 'float32')
        g._sync_barrier(60)
        check_array_shared_memory(g, worker_id, [g.nodes[:].data['test4'], g.edges[:].data['test4']])

        data = g.nodes[:].data['test4']
        g.set_n_repr({'test4': mx.nd.ones((1, 10)) * 10}, u=[0])
        assert_almost_equal(data[0].asnumpy(), np.squeeze(g.nodes[0].data['test4'].asnumpy()))

        data = g.edges[:].data['test4']
        g.set_e_repr({'test4': mx.nd.ones((1, 10)) * 20}, edges=[0])
        assert_almost_equal(data[0].asnumpy(), np.squeeze(g.edges[0].data['test4'].asnumpy()))

        g.destroy()
        return_dict[worker_id] = 0
    except Exception as e:
        return_dict[worker_id] = -1
        g.destroy()
        print(e, file=sys.stderr)
        traceback.print_exc()

def server_func(num_workers, graph_name):
    print("server starts")
    np.random.seed(0)
    csr = (spsp.random(num_nodes, num_nodes, density=0.1, format='csr') != 0).astype(np.int64)

    g = dgl.contrib.graph_store.create_graph_store_server(csr, graph_name, "shared_mem", num_workers,
                                                          False, edge_dir="in", port=rand_port)
    assert num_nodes == g._graph.number_of_nodes()
    assert num_edges == g._graph.number_of_edges()
    g.ndata['feat'] = mx.nd.arange(num_nodes * 10).reshape((num_nodes, 10))
    g.edata['feat'] = mx.nd.arange(num_edges * 10).reshape((num_edges, 10))
    g.run()

def test_init():
    manager = Manager()
    return_dict = manager.dict()
    serv_p = Process(target=server_func, args=(2, 'test_graph1'))
    work_p1 = Process(target=check_init_func, args=(0, 'test_graph1', return_dict))
    work_p2 = Process(target=check_init_func, args=(1, 'test_graph1', return_dict))
    serv_p.start()
    work_p1.start()
    work_p2.start()
    serv_p.join()
    work_p1.join()
    work_p2.join()
    for worker_id in return_dict.keys():
        assert return_dict[worker_id] == 0, "worker %d fails" % worker_id

def check_compute_func(worker_id, graph_name, return_dict):
    time.sleep(3)
    print("worker starts")
    try:
        g = create_graph_store(graph_name)
        if g is None:
            return_dict[worker_id] = -1
            return

        g._sync_barrier(60)
        in_feats = g.nodes[0].data['feat'].shape[1]

        # Test update all.
        g.update_all(fn.copy_src(src='feat', out='m'), fn.sum(msg='m', out='preprocess'))
        adj = g.adjacency_matrix()
        tmp = mx.nd.dot(adj, g.nodes[:].data['feat'])
        assert_almost_equal(g.nodes[:].data['preprocess'].asnumpy(), tmp.asnumpy())
        g._sync_barrier(60)
        check_array_shared_memory(g, worker_id, [g.nodes[:].data['preprocess']])

        # Test apply nodes.
        data = g.nodes[:].data['feat']
        g.apply_nodes(func=lambda nodes: {'feat': mx.nd.ones((1, in_feats)) * 10}, v=0)
        assert_almost_equal(data[0].asnumpy(), np.squeeze(g.nodes[0].data['feat'].asnumpy()))

        # Test apply edges.
        data = g.edges[:].data['feat']
        g.apply_edges(func=lambda edges: {'feat': mx.nd.ones((1, in_feats)) * 10}, edges=0)
        assert_almost_equal(data[0].asnumpy(), np.squeeze(g.edges[0].data['feat'].asnumpy()))

        g.init_ndata('tmp', (g.number_of_nodes(), 10), 'float32')
        data = g.nodes[:].data['tmp']
        # Test pull
        g.pull(1, fn.copy_src(src='feat', out='m'), fn.sum(msg='m', out='tmp'))
        assert_almost_equal(data[1].asnumpy(), np.squeeze(g.nodes[1].data['preprocess'].asnumpy()))

        # Test send_and_recv
        in_edges = g.in_edges(v=2)
        g.send_and_recv(in_edges, fn.copy_src(src='feat', out='m'), fn.sum(msg='m', out='tmp'))
        assert_almost_equal(data[2].asnumpy(), np.squeeze(g.nodes[2].data['preprocess'].asnumpy()))

        g.destroy()
        return_dict[worker_id] = 0
    except Exception as e:
        return_dict[worker_id] = -1
        g.destroy()
        print(e, file=sys.stderr)
        traceback.print_exc()

def test_compute():
    manager = Manager()
    return_dict = manager.dict()
    serv_p = Process(target=server_func, args=(2, 'test_graph3'))
    work_p1 = Process(target=check_compute_func, args=(0, 'test_graph3', return_dict))
    work_p2 = Process(target=check_compute_func, args=(1, 'test_graph3', return_dict))
    serv_p.start()
    work_p1.start()
    work_p2.start()
    serv_p.join()
    work_p1.join()
    work_p2.join()
    for worker_id in return_dict.keys():
        assert return_dict[worker_id] == 0, "worker %d fails" % worker_id

def check_sync_barrier(worker_id, graph_name, return_dict):
    time.sleep(3)
    print("worker starts")
    try:
        g = create_graph_store(graph_name)
        if g is None:
            return_dict[worker_id] = -1
            return

        if worker_id == 1:
            g.destroy()
            return_dict[worker_id] = 0
            return

        start = time.time()
        try:
            g._sync_barrier(10)
        except TimeoutError as e:
            # this is very loose.
            print("timeout: " + str(abs(time.time() - start)), file=sys.stderr)
            assert 5 < abs(time.time() - start) < 15
        g.destroy()
        return_dict[worker_id] = 0
    except Exception as e:
        return_dict[worker_id] = -1
        g.destroy()
        print(e, file=sys.stderr)
        traceback.print_exc()

def test_sync_barrier():
    manager = Manager()
    return_dict = manager.dict()
    serv_p = Process(target=server_func, args=(2, 'test_graph4'))
    work_p1 = Process(target=check_sync_barrier, args=(0, 'test_graph4', return_dict))
    work_p2 = Process(target=check_sync_barrier, args=(1, 'test_graph4', return_dict))
    serv_p.start()
    work_p1.start()
    work_p2.start()
    serv_p.join()
    work_p1.join()
    work_p2.join()
    for worker_id in return_dict.keys():
        assert return_dict[worker_id] == 0, "worker %d fails" % worker_id

if __name__ == '__main__':
    test_init()
    test_sync_barrier()
    test_compute()

max_stars_repo_name: baharefatemi/dgl

max_issues_repo_name: baharefatemi/dgl

max_forks_repo_name: baharefatemi/dgl

reason: import numpy,from numpy,from scipy