def compute_hist(images, labels): n_cl = 23 hist = np.zeros((n_cl, n_cl)) crossMats = list() for img_path, label_path in tqdm(zip(images, labels)): label = Image.open(label_path) label_array = np.array(label, dtype=np.int32) image = Image.open(img_path) image_array = np.array(image, dtype=np.int32) gtsz = label_array.shape imgsz = image_array.shape if not gtsz == imgsz: image = image.resize((gtsz[1], gtsz[0]), Image.ANTIALIAS) image_array = np.array(image, dtype=np.int32) hist += fast_hist(label_array, image_array, n_cl) cm = EM.calculate_confusion_matrix(label_array, image_array, n_cl) crossMats.append(cm) T_CM = np.sum(crossMats, axis=0) # np.savetxt("logs/UNet_10k/labelcrf_totalCM.csv", T_CM, fmt='%4i', delimiter=',') print(EM.calculate_eval_metrics_from_confusion_matrix(T_CM, n_cl)) return hist
def mode_visualize(sess, flags, test_dir, validation_dataset_reader, pred_annotation, image, annotation, training, num_classes): if not os.path.exists(test_dir): os.makedirs(test_dir) valid_images, valid_annotations = validation_dataset_reader.get_random_batch( flags.batch_size) pred = sess.run(pred_annotation, feed_dict={ image: valid_images, annotation: valid_annotations, training: False }) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred, axis=3) crossMats = list() for itr in range(flags.batch_size): print("Saved image: %d" % itr) # Eval metrics for this image prediction cm = EvalMetrics.calculate_confusion_matrix( valid_annotations[itr].astype(np.uint8), pred[itr].astype(np.uint8), num_classes) crossMats.append(cm) fig = plt.figure() pos = 240 + 1 plt.subplot(pos) plt.imshow(valid_images[itr].astype(np.uint8)) plt.axis('off') plt.title('Original') pos = 240 + 2 plt.subplot(pos) plt.imshow(valid_annotations[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('GT') pos = 240 + 3 plt.subplot(pos) plt.imshow(pred[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Prediction') plt.savefig(test_dir + "resultSum_" + str(itr)) plt.close('all') print(">>> Prediction results:") total_cm = np.sum(crossMats, axis=0) EvalMetrics.show_result(total_cm, num_classes)
def mode_visualize(sess, FLAGS, TEST_DIR, validation_dataset_reader, pred_annotation, image, annotation, keep_probability, NUM_OF_CLASSESS): if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) valid_images, valid_annotations = validation_dataset_reader.get_random_batch( FLAGS.batch_size) pred = sess.run( pred_annotation, feed_dict={ image: valid_images, annotation: valid_annotations, keep_probability: 1.0}) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred, axis=3) pixel = EM.AverageMeter() mean = EM.AverageMeter() miou = EM.AverageMeter() fwiou = EM.AverageMeter() for itr in range(FLAGS.batch_size): utils.save_image(valid_images[itr].astype( np.uint8), TEST_DIR, name="inp_" + str(5 + itr)) utils.save_image(valid_annotations[itr].astype( np.uint8) * 255 / 18, TEST_DIR, name="gt_" + str(5 + itr)) utils.save_image(pred[itr].astype( np.uint8) * 255 / 18, TEST_DIR, name="pred_" + str(5 + itr)) print("Saved image: %d" % itr) pa, ma, miu, fwiu = EM._calc_eval_metrics( valid_annotations[itr].astype( np.uint8), pred[itr].astype( np.uint8), NUM_OF_CLASSESS) pixel.update(pa) mean.update(ma) miou.update(miu) fwiou.update(fwiu) print('Pixel acc {pixel.val:.4f} ({pixel.avg:.4f})\t' 'Mean acc {mean.val:.4f} ({mean.avg:.4f})\t' 'Mean IoU {miou.val:.4f} ({miou.avg:.4f})\t' 'Frequency-weighted IoU {fwiou.val:.4f} ({fwiou.avg:.4f})'.format( pixel=pixel, mean=mean, miou=miou, fwiou=fwiou)) print(' * Pixel acc: {pixel.avg:.4f}, Mean acc: {mean.avg:.4f}, Mean IoU: {miou.avg:.4f}, Frequency-weighted IoU: {fwiou.avg:.4f}' .format(pixel=pixel, mean=mean, miou=miou, fwiou=fwiou))
def one_descent_step(Lgamma_step, Llambda_density_weight_step, Lsub_step, iteration, metrics): t0 = time.time() # metric for this iteration cur_metric = EvalMetrics.EvalMetrics( iteration, (Lgamma_step, Llambda_density_weight_step, Lsub_step)) cur_metric.gamma = model.gamma.data cur_metric.density_weight = model.density_weight.data metrics.append(cur_metric) pos = model.data_collections.pos[0] # move any out-of-bound cell back to placement region self.op_collections.move_boundary_op(pos) if torch.eq(model.density_weight, 0.0): model.initialize_density_weight(params, placedb) logging.info("density_weight = %.6E" % (model.density_weight.data)) optimizer.zero_grad() # t1 = time.time() cur_metric.evaluate(placedb, eval_ops, pos) model.overflow = cur_metric.overflow.data.clone() #logging.debug("evaluation %.3f ms" % ((time.time()-t1)*1000)) #t2 = time.time() # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in [ "sgd", "adam", "sgd_momentum", "sgd_nesterov" ]: obj, grad = model.obj_and_grad_fn(pos) cur_metric.objective = obj.data.clone() elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) # plot placement if params.plot_flag and iteration % 100 == 0: cur_pos = self.pos[0].data.clone().cpu().numpy() self.plot(params, placedb, iteration, cur_pos) t3 = time.time() optimizer.step() logging.info("optimizer step %.3f ms" % ((time.time() - t3) * 1000)) # nesterov has already computed the objective of the next step if optimizer_name.lower() == "nesterov": cur_metric.objective = optimizer.param_groups[0][ 'obj_k_1'][0].data.clone() # actually reports the metric before step logging.info(cur_metric) logging.info("full step %.3f ms" % ((time.time() - t0) * 1000))
def mode_new_test(sess, flags, save_dir, validation_dataset_reader, valid_records, pred_annotation, image, annotation, keep_probability, logits, num_classes): print(">>>>>>>>>>>>>>>>Test mode") start = time.time() if not os.path.exists(save_dir): os.makedirs(save_dir) validation_dataset_reader.reset_batch_offset(0) probability = tf.nn.softmax(logits=logits, axis=3) cross_mats = list() crf_cross_mats = list() # tf_pixel_acc_list = [] # tf_miou_list = [] # pixel_acc_op, pixel_acc_update_op = tf.metrics.accuracy(labels=annotation, predictions=pred_annotation) # mean_iou_op, mean_iou_update_op = tf.metrics.mean_iou(labels=annotation, predictions=pred_annotation, num_classes=num_classes) for itr1 in range(validation_dataset_reader.get_num_of_records() // flags.batch_size): valid_images, valid_annotations = validation_dataset_reader.next_batch( flags.batch_size) predprob, pred = sess.run([probability, pred_annotation], feed_dict={ image: valid_images, keep_probability: 1.0 }) # tf measures sess.run(tf.local_variables_initializer()) feed_dict = { image: valid_images, annotation: valid_annotations, keep_probability: 1.0 } # predprob, pred, _, __ = sess.run([probability, pred_annotation, pixel_acc_update_op, mean_iou_update_op], feed_dict=feed_dict) # tf_pixel_acc, tf_miou = sess.run([pixel_acc_op, mean_iou_op], feed_dict=feed_dict) # tf_pixel_acc_list.append(tf_pixel_acc) # tf_miou_list.append(tf_miou) np.set_printoptions(threshold=10) pred = np.squeeze(pred) predprob = np.squeeze(predprob) valid_annotations = np.squeeze(valid_annotations, axis=3) for itr2 in range(flags.batch_size): fig = plt.figure() pos = 240 + 1 plt.subplot(pos) plt.imshow(valid_images[itr2].astype(np.uint8)) plt.axis('off') plt.title('Original') pos = 240 + 2 plt.subplot(pos) # plt.imshow(valid_annotations[itr2].astype(np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.imshow(valid_annotations[itr2].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('GT') pos = 240 + 3 plt.subplot(pos) # plt.imshow(pred[itr2].astype(np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.imshow(pred[itr2].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Prediction') # Confusion matrix for this image prediction crossMat = EvalMetrics.calculate_confusion_matrix( valid_annotations[itr2].astype(np.uint8), pred[itr2].astype(np.uint8), num_classes) cross_mats.append(crossMat) np.savetxt(save_dir + "Crossmatrix" + str(itr1 * flags.batch_size + itr2) + ".csv", crossMat, fmt='%4i', delimiter=',') # Save input, gt, pred, crf_pred, sum figures for this image """ Generate CRF """ # 1. run CRF crfwithprobsoutput = denseCRF.crf_with_probs( valid_images[itr2].astype(np.uint8), predprob[itr2], num_classes) # 2. show result display crfwithprobspred = crfwithprobsoutput.astype(np.uint8) # -----------------------Save inp and masks---------------------- Utils.save_image(valid_images[itr2].astype(np.uint8), save_dir, name="inp_" + str(itr1 * flags.batch_size + itr2)) Utils.save_image(valid_annotations[itr2].astype(np.uint8), save_dir, name="gt_" + str(itr1 * flags.batch_size + itr2)) Utils.save_image(pred[itr2].astype(np.uint8), save_dir, name="pred_" + str(itr1 * flags.batch_size + itr2)) Utils.save_image(crfwithprobspred, save_dir, name="crf_" + str(itr1 * flags.batch_size + itr2)) # ----------------------Save visualized masks--------------------- Utils.save_visualized_image( valid_annotations[itr2].astype(np.uint8), save_dir, image_name="gt_" + str(itr1 * flags.batch_size + itr2), n_classes=num_classes) Utils.save_visualized_image(pred[itr2].astype(np.uint8), save_dir, image_name="pred_" + str(itr1 * flags.batch_size + itr2), n_classes=num_classes) Utils.save_visualized_image(crfwithprobspred, save_dir, image_name="crf_" + str(itr1 * flags.batch_size + itr2), n_classes=num_classes) # -------------------------------------------------- # Confusion matrix for this image prediction with crf prob_crf_crossMat = EvalMetrics.calculate_confusion_matrix( valid_annotations[itr2].astype(np.uint8), crfwithprobsoutput.astype(np.uint8), num_classes) crf_cross_mats.append(prob_crf_crossMat) np.savetxt(save_dir + "prob_crf_Crossmatrix" + str(itr1 * flags.batch_size + itr2) + ".csv", prob_crf_crossMat, fmt='%4i', delimiter=',') pos = 240 + 4 plt.subplot(pos) # plt.imshow(crfwithprobsoutput.astype(np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.imshow(crfwithprobsoutput.astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Prediction + CRF') plt.savefig(save_dir + "resultSum_" + str(itr1 * flags.batch_size + itr2)) plt.close('all') print("Saved image: %d" % (itr1 * flags.batch_size + itr2)) try: total_cm = np.sum(cross_mats, axis=0) np.savetxt(flags.logs_dir + "Crossmatrix.csv", total_cm, fmt='%4i', delimiter=',') # print("\n>>> Prediction results (TF functions):") # print("Pixel acc:", np.nanmean(tf_pixel_acc_list)) # print("mean IoU:", np.nanmean(tf_miou_list)) print("\n>>> Prediction results:") EvalMetrics.calculate_eval_metrics_from_confusion_matrix( total_cm, num_classes) # Prediction with CRF crf_total_cm = np.sum(crf_cross_mats, axis=0) np.savetxt(flags.logs_dir + "CRF_Crossmatrix.csv", crf_total_cm, fmt='%4i', delimiter=',') print("\n") print("\n>>> Prediction results (CRF):") EvalMetrics.calculate_eval_metrics_from_confusion_matrix( crf_total_cm, num_classes) except Exception as err: print(err) end = time.time() print("Testing time:", end - start, "seconds")
def mode_crftest(sess, FLAGS, TEST_DIR, validation_dataset_reader, valid_records, pred_annotation, image, annotation, keep_probability, logits, NUM_OF_CLASSES): accuracies = np.zeros( (validation_dataset_reader.get_num_of_records(), 3, 2)) nFailed = 0 validation_dataset_reader.reset_batch_offset(0) probability = tf.nn.softmax(logits=logits, axis=3) # the axis! for itr1 in range(validation_dataset_reader.get_num_of_records() // FLAGS.batch_size): valid_images, valid_annotations = validation_dataset_reader.next_batch( FLAGS.batch_size) predprob, pred = sess.run( [probability, pred_annotation], feed_dict={ image: valid_images, annotation: valid_annotations, keep_probability: 1.0 }) np.set_printoptions(threshold=10) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred) predprob = np.squeeze(predprob) # @TODO: convert np once not repeatedly for itr2 in range(FLAGS.batch_size): # 1. run CRF crfwithlabeloutput = denseCRF.crf_with_labels( valid_images[itr2].astype(np.uint8), pred[itr2].astype(np.uint8), NUM_OF_CLASSES) crfwithprobsoutput = denseCRF.crf_with_probs( valid_images[itr2].astype(np.uint8), predprob[itr2], NUM_OF_CLASSES) original = valid_images[itr2].astype(np.uint8) groundtruth = valid_annotations[itr2].astype(np.uint8) fcnpred = pred[itr2].astype(np.uint8) crfwithlabelpred = crfwithlabeloutput.astype(np.uint8) crfwithprobspred = crfwithprobsoutput.astype(np.uint8) # 2. Calculate confusion matrix between gtimage and prediction image and store to file pred_confusion_matrix = EvalMetrics.calculate_confusion_matrix( groundtruth, fcnpred, NUM_OF_CLASSES) crfwithlabelpred_confusion_matrix = EvalMetrics.calculate_confusion_matrix( groundtruth, crfwithlabelpred, NUM_OF_CLASSES) crfwithprobspred_confusion_matrix = EvalMetrics.calculate_confusion_matrix( groundtruth, crfwithprobspred, NUM_OF_CLASSES) accuracies[itr1 * FLAGS.batch_size + itr2][0] = EvalMetrics.calcuate_accuracy( pred_confusion_matrix, False) accuracies[itr1 * FLAGS.batch_size + itr2][1] = EvalMetrics.calcuate_accuracy( crfwithlabelpred_confusion_matrix, False) accuracies[itr1 * FLAGS.batch_size + itr2][2] = EvalMetrics.calcuate_accuracy( crfwithprobspred_confusion_matrix, True) T_full = 0.9 T_fgnd = 0.85 if accuracies[itr1 * FLAGS.batch_size + itr2][2][1] < T_full or accuracies[ itr1 * FLAGS.batch_size + itr2][2][0] < T_fgnd: nFailed += 1 print("Failed Image (%d-th): %d" % (nFailed, itr1 * FLAGS.batch_size + itr2)) # 4. saving result # now we have 0-index image filenum = str(itr1 * FLAGS.batch_size + itr2) Utils.save_image(original, FLAGS.logs_dir, name="in_" + filenum) Utils.save_image(groundtruth, TEST_DIR, name="gt_" + filenum) Utils.save_image(crfwithprobspred, TEST_DIR, name="crf_" + filenum) # ---End calculate cross matrix print("Saved image: %s" % filenum) np.save(FLAGS.logs_dir + "accuracy", accuracies)
def mode_test(sess, FLAGS, TEST_DIR, validation_dataset_reader, valid_records, pred_annotation, image, annotation, keep_probability, logits, NUM_OF_CLASSES): print(">>>>>>>>>>>>>>>>Test mode") start = time.time() if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) validation_dataset_reader.reset_batch_offset(0) crossMats = list() crf_crossMats = list() for itr1 in range(validation_dataset_reader.get_num_of_records() // FLAGS.batch_size): valid_images, valid_annotations = validation_dataset_reader.next_batch( FLAGS.batch_size) pred, logits1 = sess.run( [pred_annotation, logits], feed_dict={ image: valid_images, annotation: valid_annotations, keep_probability: 1.0 }) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred) print("logits shape:", logits1.shape) np.set_printoptions(threshold=np.inf) for itr2 in range(FLAGS.batch_size): fig = plt.figure() pos = 240 + 1 plt.subplot(pos) plt.imshow(valid_images[itr2].astype(np.uint8)) plt.axis('off') plt.title('Original') pos = 240 + 2 plt.subplot(pos) plt.imshow(valid_annotations[itr2].astype(np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.axis('off') plt.title('GT') pos = 240 + 3 plt.subplot(pos) plt.imshow(pred[itr2].astype(np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.axis('off') plt.title('Prediction') # Confusion matrix for this image prediction crossMat = EvalMetrics.calculate_confusion_matrix( valid_annotations[itr2].astype(np.uint8), pred[itr2].astype(np.uint8), NUM_OF_CLASSES) crossMats.append(crossMat) np.savetxt(TEST_DIR + "Crossmatrix" + str(itr1 * FLAGS.batch_size + itr2) + ".csv", crossMat, fmt='%4i', delimiter=',') # Save input, gt, pred, crf_pred, sum figures for this image # --------------------------------------------- Utils.save_image(valid_images[itr2].astype(np.uint8), TEST_DIR, name="inp_" + str(itr1 * FLAGS.batch_size + itr2)) Utils.save_image(valid_annotations[itr2].astype(np.uint8), TEST_DIR, name="gt_" + str(itr1 * FLAGS.batch_size + itr2)) Utils.save_image(pred[itr2].astype(np.uint8), TEST_DIR, name="pred_" + str(itr1 * FLAGS.batch_size + itr2)) # -------------------------------------------------- """ Generate CRF """ crfimage, crfoutput = denseCRF.crf( TEST_DIR + "inp_" + str(itr1 * FLAGS.batch_size + itr2) + ".png", TEST_DIR + "pred_" + str(itr1 * FLAGS.batch_size + itr2) + ".png", TEST_DIR + "crf_" + str(itr1 * FLAGS.batch_size + itr2) + ".png", NUM_OF_CLASSES, use_2d=True) # Confusion matrix for this image prediction with crf crf_crossMat = EvalMetrics.calculate_confusion_matrix( valid_annotations[itr2].astype(np.uint8), crfoutput.astype(np.uint8), NUM_OF_CLASSES) crf_crossMats.append(crf_crossMat) np.savetxt(TEST_DIR + "crf_Crossmatrix" + str(itr1 * FLAGS.batch_size + itr2) + ".csv", crf_crossMat, fmt='%4i', delimiter=',') pos = 240 + 4 plt.subplot(pos) plt.imshow(crfoutput.astype(np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.axis('off') plt.title('Prediction + CRF') plt.savefig(TEST_DIR + "resultSum_" + str(itr1 * FLAGS.batch_size + itr2)) plt.close('all') print("Saved image: %d" % (itr1 * FLAGS.batch_size + itr2)) try: total_cm = np.sum(crossMats, axis=0) np.savetxt(FLAGS.logs_dir + "Crossmatrix.csv", total_cm, fmt='%4i', delimiter=',') print(">>> Prediction results:") EvalMetrics.show_result(total_cm, NUM_OF_CLASSES) # Prediction with CRF crf_total_cm = np.sum(crf_crossMats, axis=0) np.savetxt(FLAGS.logs_dir + "CRF_Crossmatrix.csv", crf_total_cm, fmt='%4i', delimiter=',') print("\n") print(">>> Prediction results (CRF):") EvalMetrics.show_result(crf_total_cm, NUM_OF_CLASSES) except Exception as err: print(err) end = time.time() print("Testing time:", end - start, "seconds")
def mode_visualize_attention(sess, FLAGS, VIS_DIR, validation_dataset_reader, pred_annotation100, pred_annotation075, pred_annotation125, score_att_x_100, score_att_x_075, score_att_x_125, attn_output_test, pred_annotation_test_attention, image, annotation, keep_probability, NUM_OF_CLASSES): if not os.path.exists(VIS_DIR): os.makedirs(VIS_DIR) valid_images, valid_annotations = validation_dataset_reader.get_random_batch( FLAGS.batch_size) score_att_x_100 = tf.argmax(score_att_x_100, dimension=3) score_att_x_075 = tf.argmax(score_att_x_075, dimension=3) score_att_x_125 = tf.argmax(score_att_x_125, dimension=3) attn_out_100 = attn_output_test[:, :, :, 0] attn_out_075 = attn_output_test[:, :, :, 1] attn_out_125 = attn_output_test[:, :, :, 2] pred, pred100, pred075, pred125, score100, score075, score125, attn100, attn075, attn125 = sess.run( [ pred_annotation_test_attention, pred_annotation100, pred_annotation075, pred_annotation125, score_att_x_100, score_att_x_075, score_att_x_125, attn_out_100, attn_out_075, attn_out_125 ], feed_dict={ image: valid_images, annotation: valid_annotations, keep_probability: 1.0 }) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred, axis=3) pred100 = np.squeeze(pred100, axis=3) pred075 = np.squeeze(pred075, axis=3) pred125 = np.squeeze(pred125, axis=3) crossMats = list() for itr in range(FLAGS.batch_size): fig = plt.figure() pos = 240 + 1 plt.subplot(pos) plt.imshow(valid_images[itr].astype(np.uint8)) plt.axis('off') plt.title('Original') pos = 240 + 2 plt.subplot(pos) plt.imshow(valid_annotations[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('GT') pos = 240 + 3 plt.subplot(pos) plt.imshow(pred[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Prediction') pos = 240 + 4 plt.subplot(pos) plt.imshow(pred100[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('pred100') pos = 240 + 5 plt.subplot(pos) plt.imshow(pred075[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('pred075') pos = 240 + 6 plt.subplot(pos) plt.imshow(pred125[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('pred125') plt.savefig(VIS_DIR + "resultSum_" + str(itr)) plt.close('all') fig = plt.figure() pos = 240 + 1 plt.subplot(pos) plt.imshow(attn100[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Attention100') pos = 240 + 2 plt.subplot(pos) plt.imshow(attn075[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Attention075') pos = 240 + 3 plt.subplot(pos) plt.imshow(attn125[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Attention125') pos = 240 + 4 plt.subplot(pos) plt.imshow(score100[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('score100') pos = 240 + 5 plt.subplot(pos) plt.imshow(score075[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('score075') pos = 240 + 6 plt.subplot(pos) plt.imshow(score125[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('score125') plt.savefig(VIS_DIR + "resultScore_" + str(itr)) plt.close('all') print("Saved image: %d" % itr) # Eval metrics for this image prediction cm = EvalMetrics.calculate_confusion_matrix( valid_annotations[itr].astype(np.uint8), pred[itr].astype(np.uint8), NUM_OF_CLASSES) crossMats.append(cm) print(">>> Prediction results:") total_cm = np.sum(crossMats, axis=0) EvalMetrics.show_result(total_cm, NUM_OF_CLASSES)
def mode_visualize(sess, FLAGS, TEST_DIR, validation_dataset_reader, pred_annotation, image, annotation, keep_probability, NUM_OF_CLASSES): if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) valid_images, valid_annotations = validation_dataset_reader.get_random_batch( FLAGS.batch_size) pred = sess.run(pred_annotation, feed_dict={ image: valid_images, annotation: valid_annotations, keep_probability: 1.0 }) # pixel_acc_op, pixel_acc_update_op = tf.metrics.accuracy(labels=annotation, predictions=pred_annotation) # mean_iou_op, mean_iou_update_op = tf.metrics.mean_iou(labels=annotation, predictions=pred_annotation, num_classes=NUM_OF_CLASSES) # sess.run(tf.local_variables_initializer()) # feed_dict={image: valid_images, annotation: valid_annotations, keep_probability: 1.0} # sess.run( # [pixel_acc_update_op, mean_iou_update_op], # feed_dict=feed_dict) # pixel_acc, tf_miou = sess.run( # [pixel_acc_op, mean_iou_op], # feed_dict=feed_dict) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred, axis=3) crossMats = list() for itr in range(FLAGS.batch_size): Utils.save_image(valid_images[itr].astype(np.uint8), TEST_DIR, name="inp_" + str(itr)) Utils.save_image(valid_annotations[itr].astype(np.uint8) * 255 / NUM_OF_CLASSES, TEST_DIR, name="gt_" + str(itr)) Utils.save_image(pred[itr].astype(np.uint8) * 255 / NUM_OF_CLASSES, TEST_DIR, name="pred_" + str(itr)) fig = plt.figure() pos = 240 + 1 plt.subplot(pos) plt.imshow(valid_images[itr].astype(np.uint8)) plt.axis('off') plt.title('Original') pos = 240 + 2 plt.subplot(pos) plt.imshow(valid_annotations[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('GT') pos = 240 + 3 plt.subplot(pos) plt.imshow(pred[itr].astype(np.uint8), cmap=ListedColormap(label_colors_10k), norm=clothnorm_10k) plt.axis('off') plt.title('Prediction') plt.savefig(TEST_DIR + "resultSum_" + str(itr)) plt.close('all') print("Saved image: %d" % itr) # Eval metrics for this image prediction cm = EvalMetrics.calculate_confusion_matrix( valid_annotations[itr].astype(np.uint8), pred[itr].astype(np.uint8), NUM_OF_CLASSES) crossMats.append(cm) print(">>> Prediction results:") total_cm = np.sum(crossMats, axis=0) EvalMetrics.show_result(total_cm, NUM_OF_CLASSES)
def mode_test(sess, FLAGS, TEST_DIR, validation_dataset_reader, valid_records, pred_annotation, image, annotation, keep_probability, logits, NUM_OF_CLASSESS): print(">>>>>>>>>>>>>>>>Test mode") start = time.time() if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) crossMats = list() mIOU_all = list() mFWIOU_all = list() validation_dataset_reader.reset_batch_offset(0) PA_all = list() MPA_all = list() pixel = EM.AverageMeter() mean = EM.AverageMeter() miou = EM.AverageMeter() fwiou = EM.AverageMeter() for itr1 in range(validation_dataset_reader.get_num_of_records() // FLAGS.batch_size): valid_images, valid_annotations = validation_dataset_reader.next_batch( FLAGS.batch_size) pred, logits1 = sess.run([pred_annotation, logits], feed_dict={image: valid_images, annotation: valid_annotations, keep_probability: 1.0}) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred) print("logits shape:", logits1.shape) np.set_printoptions(threshold=np.inf) for itr2 in range(FLAGS.batch_size): try: fig = plt.figure() pos = 240 + 1 plt.subplot(pos) plt.imshow(valid_images[itr2].astype(np.uint8)) plt.axis('off') plt.title('Original') pos = 240 + 2 plt.subplot(pos) plt.imshow( valid_annotations[itr2].astype( np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.axis('off') plt.title('GT') pos = 240 + 3 plt.subplot(pos) plt.imshow( pred[itr2].astype( np.uint8), cmap=plt.get_cmap('nipy_spectral')) plt.axis('off') plt.title('Prediction') # Confusion matrix for this image crossMat = EM._calcCrossMat( valid_annotations[itr2].astype( np.uint8), pred[itr2].astype( np.uint8), NUM_OF_CLASSESS) crossMats.append(crossMat) # Eval metrics for this image pa, ma, miu, fwiu = EM._calc_eval_metrics( valid_annotations[itr2].astype( np.uint8), pred[itr2].astype( np.uint8), NUM_OF_CLASSESS) pixel.update(pa) mean.update(ma) miou.update(miu) fwiou.update(fwiu) PA_all.append(pa) MPA_all.append(ma) mIOU_all.append(miu) mFWIOU_all.append(fwiu) print('Test: [{0}/{1}]\t' 'Pixel acc {pixel.val:.4f} ({pixel.avg:.4f})\t' 'Mean acc {mean.val:.4f} ({mean.avg:.4f})\t' 'Mean IoU {miou.val:.4f} ({miou.avg:.4f})\t' 'Frequency-weighted IoU {fwiou.val:.4f} ({fwiou.avg:.4f})'.format((itr1 * FLAGS.batch_size + itr2), len(valid_records), pixel=pixel, mean=mean, miou=miou, fwiou=fwiou)) valid_annotations[itr2] = cv2.normalize( valid_annotations[itr2], None, 0, 255, cv2.NORM_MINMAX) np.savetxt(FLAGS.logs_dir + "Image/Crossmatrix" + str(itr1 * FLAGS.batch_size + itr2) + ".csv", crossMat, fmt='%4i', delimiter=',') # Save input, gt, pred, sum figures for this image plt.savefig(FLAGS.logs_dir + "Image/resultSum_" + str(itr1 * FLAGS.batch_size + itr2)) # --------------------------------------------- utils.save_image(valid_images[itr2].astype(np.uint8), FLAGS.logs_dir + "Image/", name="inp_" + str(itr1 * FLAGS.batch_size + itr2)) utils.save_image(valid_annotations[itr2].astype(np.uint8), FLAGS.logs_dir + "Image/", name="gt_" + str(itr1 * FLAGS.batch_size + itr2)) utils.save_image(pred[itr2].astype(np.uint8), FLAGS.logs_dir + "Image/", name="pred_" + str(itr1 * 2 + itr2)) plt.close('all') print("Saved image: %d" % (itr1 * FLAGS.batch_size + itr2)) except Exception as err: print(err) print(' * Pixel acc: {pixel.avg:.4f}, Mean acc: {mean.avg:.4f}, Mean IoU: {miou.avg:.4f}, Frequency-weighted IoU: {fwiou.avg:.4f}' .format(pixel=pixel, mean=mean, miou=miou, fwiou=fwiou)) try: np.savetxt( FLAGS.logs_dir + "Crossmatrix.csv", np.sum( crossMats, axis=0), fmt='%4i', delimiter=',') np.savetxt( FLAGS.logs_dir + "PixelAccuracies" + ".csv", PA_all, fmt='%4f', delimiter=',') np.savetxt( FLAGS.logs_dir + "MeanAccuracies" + ".csv", MPA_all, fmt='%4f', delimiter=',') np.savetxt( FLAGS.logs_dir + "mIoUs" + ".csv", mIOU_all, fmt='%4f', delimiter=',') np.savetxt( FLAGS.logs_dir + "mFWIoUs" + ".csv", mFWIOU_all, fmt='%4f', delimiter=',') except Exception as err: print(err) end = time.time() print("Testing time:", end - start, "seconds")
def __call__(self, params, placedb): """ @brief Top API to solve placement. @param params parameters @param placedb placement database """ iteration = 0 metrics = [] # global placement if params.global_place_flag: # global placement may run in multiple stages according to user specification for global_place_params in params.global_place_stages: if params.gpu: torch.cuda.synchronize() tt = time.time() # construct model and optimizer density_weight = metrics[-1].density_weight if metrics else 0.0 # construct placement model model = PlaceObj.PlaceObj( density_weight, params, placedb, self.data_collections, self.op_collections, global_place_params).to( self.data_collections.pos[0].device) optimizer_name = global_place_params["optimizer"] # determine optimizer if optimizer_name.lower() == "adam": optimizer = torch.optim.Adam(self.parameters(), lr=model.learning_rate) elif optimizer_name.lower() == "sgd": optimizer = torch.optim.SGD(self.parameters(), lr=model.learning_rate) elif optimizer_name.lower() == "sgd_momentum": optimizer = torch.optim.SGD(self.parameters(), lr=model.learning_rate, momentum=0.9, nesterov=False) elif optimizer_name.lower() == "sgd_nesterov": optimizer = torch.optim.SGD(self.parameters(), lr=model.learning_rate, momentum=0.9, nesterov=True) elif optimizer_name.lower() == "cg": optimizer = ConjugateGradientOptimizer.ConjugateGradientOptimizer( self.parameters(), lr=model.learning_rate) elif optimizer_name.lower() == "cgls": optimizer = ConjugateGradientOptimizer.ConjugateGradientOptimizer( self.parameters(), lr=model.learning_rate, line_search_fn=LineSearch.build_line_search_fn_armijo( model.obj_fn)) elif optimizer_name.lower() == "nesterov": optimizer = NesterovAcceleratedGradientOptimizer.NesterovAcceleratedGradientOptimizer( self.parameters(), lr=model.learning_rate, obj_and_grad_fn=model.obj_and_grad_fn, constraint_fn=self.op_collections.move_boundary_op, ) else: assert 0, "unknown optimizer %s" % (optimizer_name) logging.info("use %s optimizer" % (optimizer_name)) model.train() learning_rate = model.learning_rate # defining evaluation ops eval_ops = { #"wirelength" : self.op_collections.wirelength_op, #"density" : self.op_collections.density_op, "hpwl": self.op_collections.hpwl_op, "overflow": self.op_collections.density_overflow_op } if iteration == 0: if params.gp_noise_ratio > 0.0: logging.info("add %g%% noise" % (params.gp_noise_ratio * 100)) model.op_collections.noise_op( model.data_collections.pos[0], params.gp_noise_ratio) if params.gpu: torch.cuda.synchronize() logging.info("%s initialization takes %g seconds" % (optimizer_name, (time.time() - tt))) # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in { "sgd", "adam", "sgd_momentum", "sgd_nesterov", "cg" }: model.obj_and_grad_fn(model.data_collections.pos[0]) elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) for step in range(model.iteration): t0 = time.time() # metric for this iteration cur_metric = EvalMetrics.EvalMetrics(iteration) metrics.append(cur_metric) # move any out-of-bound cell back to placement region self.op_collections.move_boundary_op( model.data_collections.pos[0]) if torch.eq(model.density_weight, 0.0): model.initialize_density_weight(params, placedb) logging.info("density_weight = %.6E" % (model.density_weight.data)) optimizer.zero_grad() # t1 = time.time() cur_metric.evaluate(placedb, eval_ops, model.data_collections.pos[0]) #logging.debug("evaluation %.3f ms" % ((time.time()-t1)*1000)) #t2 = time.time() # update density weight # gradually reduce gamma to tradeoff smoothness and accuracy if len(metrics) > 1: model.op_collections.update_density_weight_op(metrics) model.op_collections.update_gamma_op( step, cur_metric.overflow) cur_metric.density_weight = model.density_weight.data cur_metric.gamma = model.gamma.data #logging.debug("update density weight %.3f ms" % ((time.time()-t2)*1000)) # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in [ "sgd", "adam", "sgd_momentum", "sgd_nesterov", "cg" ]: model.obj_and_grad_fn(model.data_collections.pos[0]) elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) # stopping criteria if iteration > 100 and ( (cur_metric.overflow < params.stop_overflow and cur_metric.hpwl > metrics[-2].hpwl) or cur_metric.max_density < 1.0): logging.debug( "stopping criteria: %d > 100 and (( %g < 0.1 and %g > %g ) or %g < 1.0)" % (iteration, cur_metric.overflow, cur_metric.hpwl, metrics[-2].hpwl, cur_metric.max_density)) break # update learning rate for param_group in optimizer.param_groups: param_group['lr'] = learning_rate logging.info(cur_metric) # plot placement if params.plot_flag and iteration % 100 == 0: cur_pos = self.pos[0].data.clone().cpu().numpy() self.plot(params, placedb, iteration, cur_pos) t3 = time.time() optimizer.step() logging.info("optimizer step %.3f ms" % ((time.time() - t3) * 1000)) iteration += 1 logging.info("full step %.3f ms" % ((time.time() - t0) * 1000)) logging.info("optimizer %s takes %.3f seconds" % (optimizer_name, time.time() - tt)) # legalization if params.legalize_flag: tt = time.time() self.pos[0].data.copy_( self.op_collections.greedy_legalize_op(self.pos[0])) logging.info("legalization takes %.3f seconds" % (time.time() - tt)) # detailed placement if params.detailed_place_flag: logging.warning("detailed placement NOT implemented yet, skipped") # save results cur_pos = self.pos[0].data.clone().cpu().numpy() # apply solution placedb.apply( params, cur_pos[0:placedb.num_movable_nodes], cur_pos[placedb.num_nodes:placedb.num_nodes + placedb.num_movable_nodes]) # plot placement if params.plot_flag: self.plot(params, placedb, iteration, cur_pos) return metrics
def mode_visualize(sess, FLAGS, TEST_DIR, validation_dataset_reader, pred_annotation, image, annotation, keep_probability, NUM_OF_CLASSES): if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) valid_images, valid_annotations = validation_dataset_reader.get_random_batch( FLAGS.batch_size) pred = sess.run(pred_annotation, feed_dict={ image: valid_images, annotation: valid_annotations, keep_probability: 1.0 }) # pixel_acc_op, pixel_acc_update_op = tf.metrics.accuracy(labels=annotation, predictions=pred_annotation) # mean_iou_op, mean_iou_update_op = tf.metrics.mean_iou(labels=annotation, predictions=pred_annotation, num_classes=NUM_OF_CLASSES) # sess.run(tf.local_variables_initializer()) # feed_dict={image: valid_images, annotation: valid_annotations, keep_probability: 1.0} # sess.run( # [pixel_acc_update_op, mean_iou_update_op], # feed_dict=feed_dict) # pixel_acc, tf_miou = sess.run( # [pixel_acc_op, mean_iou_op], # feed_dict=feed_dict) valid_annotations = np.squeeze(valid_annotations, axis=3) pred = np.squeeze(pred, axis=3) crossMats = list() crf_crossMats = list() for itr in range(FLAGS.batch_size): utils.save_image(valid_images[itr].astype(np.uint8), TEST_DIR, name="inp_" + str(itr)) utils.save_image(valid_annotations[itr].astype(np.uint8) * 255 / NUM_OF_CLASSES, TEST_DIR, name="gt_" + str(itr)) utils.save_image(pred[itr].astype(np.uint8) * 255 / NUM_OF_CLASSES, TEST_DIR, name="pred_" + str(itr)) print("Saved image: %d" % itr) # Eval metrics for this image prediction cm = EM._calcCrossMat(valid_annotations[itr].astype(np.uint8), pred[itr].astype(np.uint8), NUM_OF_CLASSES) crossMats.append(cm) """ Generate CRF """ crfimage, crfoutput = inference.crf( TEST_DIR + "inp_" + str(itr) + ".png", TEST_DIR + "pred_" + str(itr) + ".png", TEST_DIR + "crf_" + str(itr) + ".png", NUM_OF_CLASSES, use_2d=True) # Eval metrics for this image prediction with crf crf_cm = EM._calcCrossMat(valid_annotations[itr].astype(np.uint8), crfoutput.astype(np.uint8), NUM_OF_CLASSES) crf_crossMats.append(crf_cm) print(">>> Prediction results:") total_cm = np.sum(crossMats, axis=0) EM.show_result(total_cm, NUM_OF_CLASSES) print("\n") print(">>> Prediction results (CRF):") crf_total_cm = np.sum(crf_crossMats, axis=0) EM.show_result(crf_total_cm, NUM_OF_CLASSES)
def __call__(self, params, placedb): """ @brief Top API to solve placement. @param params parameters @param placedb placement database """ iteration = 0 all_metrics = [] # global placement if params.global_place_flag: # global placement may run in multiple stages according to user specification for global_place_params in params.global_place_stages: # we formulate each stage as a 3-nested optimization problem # f_gamma(g_density(h(x) ; density weight) ; gamma) # Lgamma Llambda Lsub # When optimizing an inner problem, the outer parameters are fixed. # This is a generalization to the eplace/RePlAce approach if params.gpu: torch.cuda.synchronize() tt = time.time() # construct model and optimizer density_weight = 0.0 # construct placement model model = PlaceObj.PlaceObj( density_weight, params, placedb, self.data_collections, self.op_collections, global_place_params).to( self.data_collections.pos[0].device) optimizer_name = global_place_params["optimizer"] # determine optimizer if optimizer_name.lower() == "adam": optimizer = torch.optim.Adam(self.parameters(), lr=0) elif optimizer_name.lower() == "sgd": optimizer = torch.optim.SGD(self.parameters(), lr=0) elif optimizer_name.lower() == "sgd_momentum": optimizer = torch.optim.SGD(self.parameters(), lr=0, momentum=0.9, nesterov=False) elif optimizer_name.lower() == "sgd_nesterov": optimizer = torch.optim.SGD(self.parameters(), lr=0, momentum=0.9, nesterov=True) elif optimizer_name.lower() == "nesterov": optimizer = NesterovAcceleratedGradientOptimizer.NesterovAcceleratedGradientOptimizer( self.parameters(), lr=0, obj_and_grad_fn=model.obj_and_grad_fn, constraint_fn=self.op_collections.move_boundary_op, ) else: assert 0, "unknown optimizer %s" % (optimizer_name) logging.info("use %s optimizer" % (optimizer_name)) model.train() # defining evaluation ops eval_ops = { #"wirelength" : self.op_collections.wirelength_op, #"density" : self.op_collections.density_op, #"objective" : model.obj_fn, "hpwl": self.op_collections.hpwl_op, "overflow": self.op_collections.density_overflow_op } if params.routability_opt_flag: eval_ops.update({ 'route_utilization': self.op_collections.route_utilization_map_op, 'pin_utilization': self.op_collections.pin_utilization_map_op }) # a function to initialize learning rate def initialize_learning_rate(pos): learning_rate = model.estimate_initial_learning_rate( pos, global_place_params["learning_rate"]) # update learning rate for param_group in optimizer.param_groups: param_group['lr'] = learning_rate.data if iteration == 0: if params.gp_noise_ratio > 0.0: logging.info("add %g%% noise" % (params.gp_noise_ratio * 100)) model.op_collections.noise_op( model.data_collections.pos[0], params.gp_noise_ratio) initialize_learning_rate(model.data_collections.pos[0]) # the state must be saved after setting learning rate initial_state = copy.deepcopy(optimizer.state_dict()) if params.gpu: torch.cuda.synchronize() logging.info("%s initialization takes %g seconds" % (optimizer_name, (time.time() - tt))) # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in { "sgd", "adam", "sgd_momentum", "sgd_nesterov" }: model.obj_and_grad_fn(model.data_collections.pos[0]) elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) # stopping criteria def Lgamma_stop_criterion(Lgamma_step, metrics): with torch.no_grad(): if len(metrics) > 1: cur_metric = metrics[-1][-1][-1] prev_metric = metrics[-2][-1][-1] if Lgamma_step > 100 and ( (cur_metric.overflow < params.stop_overflow and cur_metric.hpwl > prev_metric.hpwl) or cur_metric.max_density < params.target_density): logging.debug( "Lgamma stopping criteria: %d > 100 and (( %g < 0.1 and %g > %g ) or %g < 1.0)" % (Lgamma_step, cur_metric.overflow, cur_metric.hpwl, prev_metric.hpwl, cur_metric.max_density)) return True return False def Llambda_stop_criterion(Lgamma_step, Llambda_density_weight_step, metrics): with torch.no_grad(): if len(metrics) > 1: cur_metric = metrics[-1][-1] prev_metric = metrics[-2][-1] if (cur_metric.overflow < params.stop_overflow and cur_metric.hpwl > prev_metric.hpwl ) or cur_metric.max_density < 1.0: logging.debug( "Llambda stopping criteria: %d and (( %g < 0.1 and %g > %g ) or %g < 1.0)" % (Llambda_density_weight_step, cur_metric.overflow, cur_metric.hpwl, prev_metric.hpwl, cur_metric.max_density)) return True return False # use a moving average window for stopping criteria, for an example window of 3 # 0, 1, 2, 3, 4, 5, 6 # window2 # window1 moving_avg_window = max(min(model.Lsub_iteration // 2, 3), 1) def Lsub_stop_criterion(Lgamma_step, Llambda_density_weight_step, Lsub_step, metrics): with torch.no_grad(): if len(metrics) >= moving_avg_window * 2: cur_avg_obj = 0 prev_avg_obj = 0 for i in range(moving_avg_window): cur_avg_obj += metrics[-1 - i].objective prev_avg_obj += metrics[-1 - moving_avg_window - i].objective cur_avg_obj /= moving_avg_window prev_avg_obj /= moving_avg_window threshold = 0.999 if cur_avg_obj >= prev_avg_obj * threshold: logging.debug( "Lsub stopping criteria: %d and %g > %g * %g" % (Lsub_step, cur_avg_obj, prev_avg_obj, threshold)) return True return False def one_descent_step(Lgamma_step, Llambda_density_weight_step, Lsub_step, iteration, metrics): t0 = time.time() # metric for this iteration cur_metric = EvalMetrics.EvalMetrics( iteration, (Lgamma_step, Llambda_density_weight_step, Lsub_step)) cur_metric.gamma = model.gamma.data cur_metric.density_weight = model.density_weight.data metrics.append(cur_metric) pos = model.data_collections.pos[0] # move any out-of-bound cell back to placement region self.op_collections.move_boundary_op(pos) if torch.eq(model.density_weight, 0.0): model.initialize_density_weight(params, placedb) logging.info("density_weight = %.6E" % (model.density_weight.data)) optimizer.zero_grad() # t1 = time.time() cur_metric.evaluate(placedb, eval_ops, pos) model.overflow = cur_metric.overflow.data.clone() #logging.debug("evaluation %.3f ms" % ((time.time()-t1)*1000)) #t2 = time.time() # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in [ "sgd", "adam", "sgd_momentum", "sgd_nesterov" ]: obj, grad = model.obj_and_grad_fn(pos) cur_metric.objective = obj.data.clone() elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) # plot placement if params.plot_flag and iteration % 100 == 0: cur_pos = self.pos[0].data.clone().cpu().numpy() self.plot(params, placedb, iteration, cur_pos) t3 = time.time() optimizer.step() logging.info("optimizer step %.3f ms" % ((time.time() - t3) * 1000)) # nesterov has already computed the objective of the next step if optimizer_name.lower() == "nesterov": cur_metric.objective = optimizer.param_groups[0][ 'obj_k_1'][0].data.clone() # actually reports the metric before step logging.info(cur_metric) logging.info("full step %.3f ms" % ((time.time() - t0) * 1000)) Lgamma_metrics = all_metrics if params.routability_opt_flag: adjust_area_flag = True adjust_route_area_flag = params.adjust_nctugr_area_flag or params.adjust_rudy_area_flag adjust_pin_area_flag = params.adjust_pin_area_flag num_area_adjust = 0 Llambda_flat_iteration = 0 for Lgamma_step in range(model.Lgamma_iteration): Lgamma_metrics.append([]) Llambda_metrics = Lgamma_metrics[-1] for Llambda_density_weight_step in range( model.Llambda_density_weight_iteration): Llambda_metrics.append([]) Lsub_metrics = Llambda_metrics[-1] for Lsub_step in range(model.Lsub_iteration): one_descent_step(Lgamma_step, Llambda_density_weight_step, Lsub_step, iteration, Lsub_metrics) iteration += 1 # stopping criteria if Lsub_stop_criterion( Lgamma_step, Llambda_density_weight_step, Lsub_step, Lsub_metrics): break Llambda_flat_iteration += 1 # update density weight if Llambda_flat_iteration > 1: model.op_collections.update_density_weight_op( Llambda_metrics[-1][-1], Llambda_metrics[-2][-1] if len(Llambda_metrics) > 1 else Lgamma_metrics[-2][-1][-1], Llambda_flat_iteration) #logging.debug("update density weight %.3f ms" % ((time.time()-t2)*1000)) if Llambda_stop_criterion(Lgamma_step, Llambda_density_weight_step, Llambda_metrics): break # for routability optimization if params.routability_opt_flag and num_area_adjust < params.max_num_area_adjust and Llambda_metrics[ -1][-1].overflow < params.node_area_adjust_overflow: content = "routability optimization round %d: adjust area flags = (%d, %d, %d)" % ( num_area_adjust, adjust_area_flag, adjust_route_area_flag, adjust_pin_area_flag) pos = model.data_collections.pos[0] #cur_metric = EvalMetrics.EvalMetrics(iteration) #cur_metric.evaluate(placedb, { # "hpwl" : self.op_collections.hpwl_op, # "overflow" : self.op_collections.density_overflow_op, # "route_utilization" : self.op_collections.route_utilization_map_op, # "pin_utilization" : self.op_collections.pin_utilization_map_op, # }, # pos) #logging.info(cur_metric) route_utilization_map = None pin_utilization_map = None if adjust_route_area_flag: if params.adjust_nctugr_area_flag: route_utilization_map = model.op_collections.nctugr_congestion_map_op( pos) else: route_utilization_map = model.op_collections.route_utilization_map_op( pos) if params.plot_flag: path = "%s/%s" % (params.result_dir, params.design_name()) figname = "%s/plot/route%d.png" % ( path, num_area_adjust) os.system("mkdir -p %s" % (os.path.dirname(figname))) plt.imsave(figname, route_utilization_map.data.cpu( ).numpy().T, origin='lower') if adjust_pin_area_flag: pin_utilization_map = model.op_collections.pin_utilization_map_op( pos) if params.plot_flag: path = "%s/%s" % (params.result_dir, params.design_name()) figname = "%s/plot/pin%d.png" % ( path, num_area_adjust) os.system("mkdir -p %s" % (os.path.dirname(figname))) plt.imsave(figname, pin_utilization_map.data.cpu(). numpy().T, origin='lower') adjust_area_flag, adjust_route_area_flag, adjust_pin_area_flag = model.op_collections.adjust_node_area_op( pos, route_utilization_map, pin_utilization_map) content += " -> (%d, %d, %d)" % ( adjust_area_flag, adjust_route_area_flag, adjust_pin_area_flag) logging.info(content) if adjust_area_flag: num_area_adjust += 1 # restart Llambda model.op_collections.density_op.reset() model.op_collections.density_overflow_op.reset( ) model.op_collections.pin_utilization_map_op.reset( ) model.initialize_density_weight( params, placedb) model.density_weight.mul_( 0.1 / params.density_weight) logging.info("density_weight = %.6E" % (model.density_weight.data)) # load state to restart the optimizer optimizer.load_state_dict(initial_state) # must after loading the state initialize_learning_rate(pos) # increase iterations of the sub problem to slow down the search model.Lsub_iteration = model.routability_Lsub_iteration #cur_metric = EvalMetrics.EvalMetrics(iteration) #cur_metric.evaluate(placedb, { # "hpwl" : self.op_collections.hpwl_op, # "overflow" : self.op_collections.density_overflow_op, # "route_utilization" : self.op_collections.route_utilization_map_op, # "pin_utilization" : self.op_collections.pin_utilization_map_op, # }, # pos) #logging.info(cur_metric) break # gradually reduce gamma to tradeoff smoothness and accuracy model.op_collections.update_gamma_op( Lgamma_step, Llambda_metrics[-1][-1].overflow) model.op_collections.precondition_op.set_overflow( Llambda_metrics[-1][-1].overflow) if Lgamma_stop_criterion(Lgamma_step, Lgamma_metrics): break # update learning rate if optimizer_name.lower() in [ "sgd", "adam", "sgd_momentum", "sgd_nesterov", "cg" ]: if 'learning_rate_decay' in global_place_params: for param_group in optimizer.param_groups: param_group['lr'] *= global_place_params[ 'learning_rate_decay'] logging.info("optimizer %s takes %.3f seconds" % (optimizer_name, time.time() - tt)) # recover node size and pin offset for legalization, since node size is adjusted in global placement if params.routability_opt_flag: with torch.no_grad(): # convert lower left to centers self.pos[0][:placedb.num_movable_nodes].add_( self.data_collections. node_size_x[:placedb.num_movable_nodes] / 2) self.pos[0][placedb.num_nodes:placedb.num_nodes + placedb.num_movable_nodes].add_( self.data_collections. node_size_y[:placedb.num_movable_nodes] / 2) self.data_collections.node_size_x.copy_( self.data_collections.original_node_size_x) self.data_collections.node_size_y.copy_( self.data_collections.original_node_size_y) # use fixed centers as the anchor self.pos[0][:placedb.num_movable_nodes].sub_( self.data_collections. node_size_x[:placedb.num_movable_nodes] / 2) self.pos[0][placedb.num_nodes:placedb.num_nodes + placedb.num_movable_nodes].sub_( self.data_collections. node_size_y[:placedb.num_movable_nodes] / 2) self.data_collections.pin_offset_x.copy_( self.data_collections.original_pin_offset_x) self.data_collections.pin_offset_y.copy_( self.data_collections.original_pin_offset_y) else: cur_metric = EvalMetrics.EvalMetrics(iteration) all_metrics.append(cur_metric) cur_metric.evaluate(placedb, {"hpwl": self.op_collections.hpwl_op}, self.pos[0]) logging.info(cur_metric) # dump global placement solution for legalization if params.dump_global_place_solution_flag: self.dump(params, placedb, self.pos[0].cpu(), "%s.lg.pklz" % (params.design_name())) # plot placement if params.plot_flag: self.plot(params, placedb, iteration, self.pos[0].data.clone().cpu().numpy()) # legalization if params.legalize_flag: tt = time.time() self.pos[0].data.copy_(self.op_collections.legalize_op( self.pos[0])) logging.info("legalization takes %.3f seconds" % (time.time() - tt)) cur_metric = EvalMetrics.EvalMetrics(iteration) all_metrics.append(cur_metric) cur_metric.evaluate(placedb, {"hpwl": self.op_collections.hpwl_op}, self.pos[0]) logging.info(cur_metric) iteration += 1 # plot placement if params.plot_flag: self.plot(params, placedb, iteration, self.pos[0].data.clone().cpu().numpy()) # dump legalization solution for detailed placement if params.dump_legalize_solution_flag: self.dump(params, placedb, self.pos[0].cpu(), "%s.dp.pklz" % (params.design_name())) # detailed placement if params.detailed_place_flag: tt = time.time() self.pos[0].data.copy_( self.op_collections.detailed_place_op(self.pos[0])) logging.info("detailed placement takes %.3f seconds" % (time.time() - tt)) cur_metric = EvalMetrics.EvalMetrics(iteration) all_metrics.append(cur_metric) cur_metric.evaluate(placedb, {"hpwl": self.op_collections.hpwl_op}, self.pos[0]) logging.info(cur_metric) iteration += 1 # save results cur_pos = self.pos[0].data.clone().cpu().numpy() # apply solution placedb.apply( params, cur_pos[0:placedb.num_movable_nodes], cur_pos[placedb.num_nodes:placedb.num_nodes + placedb.num_movable_nodes]) # plot placement if params.plot_flag: self.plot(params, placedb, iteration, cur_pos) return all_metrics
def __call__(self, params, placedb): """ @brief Top API to solve placement. @param params parameters @param placedb placement database """ iteration = 0 all_metrics = [] # global placement if params.global_place_flag: # global placement may run in multiple stages according to user specification for global_place_params in params.global_place_stages: # we formulate each stage as a 3-nested optimization problem # f_gamma(g_density(h(x) ; density weight) ; gamma) # Lgamma Llambda Lsub # When optimizing an inner problem, the outer parameters are fixed. # This is a generalization to the eplace/RePlAce approach # As global placement may easily diverge, we record the position of best overflow best_metric = [None] best_pos = [None] if params.gpu: torch.cuda.synchronize() tt = time.time() # construct model and optimizer density_weight = 0.0 # construct placement model model = PlaceObj.PlaceObj( density_weight, params, placedb, self.data_collections, self.op_collections, global_place_params, ).to(self.data_collections.pos[0].device) optimizer_name = global_place_params["optimizer"] # determine optimizer if optimizer_name.lower() == "adam": optimizer = torch.optim.Adam(self.parameters(), lr=0) elif optimizer_name.lower() == "sgd": optimizer = torch.optim.SGD(self.parameters(), lr=0) elif optimizer_name.lower() == "sgd_momentum": optimizer = torch.optim.SGD(self.parameters(), lr=0, momentum=0.9, nesterov=False) elif optimizer_name.lower() == "sgd_nesterov": optimizer = torch.optim.SGD(self.parameters(), lr=0, momentum=0.9, nesterov=True) elif optimizer_name.lower() == "nesterov": optimizer = NesterovAcceleratedGradientOptimizer.NesterovAcceleratedGradientOptimizer( self.parameters(), lr=0, obj_and_grad_fn=model.obj_and_grad_fn, constraint_fn=self.op_collections.move_boundary_op, ) else: assert 0, "unknown optimizer %s" % (optimizer_name) logging.info("use %s optimizer" % (optimizer_name)) model.train() # defining evaluation ops eval_ops = { # "wirelength" : self.op_collections.wirelength_op, # "density" : self.op_collections.density_op, # "objective" : model.obj_fn, "hpwl": self.op_collections.hpwl_op, "overflow": self.op_collections.density_overflow_op, } if params.routability_opt_flag: eval_ops.update( { "route_utilization": self.op_collections.route_utilization_map_op, "pin_utilization": self.op_collections.pin_utilization_map_op, } ) if len(placedb.regions) > 0: eval_ops.update( { "density": self.op_collections.fence_region_density_merged_op, "overflow": self.op_collections.fence_region_density_overflow_merged_op, "goverflow": self.op_collections.density_overflow_op, } ) # a function to initialize learning rate def initialize_learning_rate(pos): learning_rate = model.estimate_initial_learning_rate( pos, global_place_params["learning_rate"] ) # update learning rate for param_group in optimizer.param_groups: param_group["lr"] = learning_rate.data if iteration == 0: if params.gp_noise_ratio > 0.0: logging.info("add %g%% noise" % (params.gp_noise_ratio * 100)) model.op_collections.noise_op(model.data_collections.pos[0], params.gp_noise_ratio) initialize_learning_rate(model.data_collections.pos[0]) # the state must be saved after setting learning rate initial_state = copy.deepcopy(optimizer.state_dict()) if params.gpu: torch.cuda.synchronize() logging.info("%s initialization takes %g seconds" % (optimizer_name, (time.time() - tt))) # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in {"sgd", "adam", "sgd_momentum", "sgd_nesterov"}: model.obj_and_grad_fn(model.data_collections.pos[0]) elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) # stopping criteria def Lgamma_stop_criterion(Lgamma_step, metrics, stop_mask=None): with torch.no_grad(): if len(metrics) > 1: cur_metric = metrics[-1][-1][-1] prev_metric = metrics[-2][-1][-1] ### update stop mask for each fence region # if(stop_mask is not None): # stop_mask.copy_(cur_metric.overflow < params.stop_overflow) if Lgamma_step > 100 and ( ### for fence region, the outer cell overflow decides the stopping of GP ( cur_metric.overflow[-1] < params.stop_overflow and cur_metric.hpwl > prev_metric.hpwl ) or cur_metric.max_density[-1] < params.target_density ): logging.debug( "Lgamma stopping criteria: %d > 100 and (( %g < 0.1 and %g > %g ) or %g < 1.0)" % ( Lgamma_step, cur_metric.overflow[-1], cur_metric.hpwl, prev_metric.hpwl, cur_metric.max_density[-1], ) ) return True if len(placedb.regions) > 0 and model.update_mask.sum() == 0: logging.debug("All regions stop updating, finish global placement") return True # a heuristic to detect divergence and stop early if len(metrics) > 50: cur_metric = metrics[-1][-1][-1] prev_metric = metrics[-50][-1][-1] # record HPWL and overflow increase, and check divergence if ( cur_metric.overflow[-1] > prev_metric.overflow[-1] and cur_metric.hpwl > best_metric[0].hpwl * 2 ): return True return False def Llambda_stop_criterion(Lgamma_step, Llambda_density_weight_step, metrics): with torch.no_grad(): if len(metrics) > 1: cur_metric = metrics[-1][-1] prev_metric = metrics[-2][-1] ### for fence regions, the outer cell overflow and max_density decides whether to stop if ( cur_metric.overflow[-1] < params.stop_overflow and cur_metric.hpwl > prev_metric.hpwl ) or cur_metric.max_density[-1] < 1.0: logging.debug( "Llambda stopping criteria: %d and (( %g < 0.1 and %g > %g ) or %g < 1.0)" % ( Llambda_density_weight_step, cur_metric.overflow[-1], cur_metric.hpwl, prev_metric.hpwl, cur_metric.max_density[-1], ) ) return True return False # use a moving average window for stopping criteria, for an example window of 3 # 0, 1, 2, 3, 4, 5, 6 # window2 # window1 moving_avg_window = max(min(model.Lsub_iteration // 2, 3), 1) def Lsub_stop_criterion(Lgamma_step, Llambda_density_weight_step, Lsub_step, metrics): with torch.no_grad(): if len(metrics) >= moving_avg_window * 2: cur_avg_obj = 0 prev_avg_obj = 0 for i in range(moving_avg_window): cur_avg_obj += metrics[-1 - i].objective prev_avg_obj += metrics[-1 - moving_avg_window - i].objective cur_avg_obj /= moving_avg_window prev_avg_obj /= moving_avg_window threshold = 0.999 if cur_avg_obj >= prev_avg_obj * threshold: logging.debug( "Lsub stopping criteria: %d and %g > %g * %g" % (Lsub_step, cur_avg_obj, prev_avg_obj, threshold) ) return True return False def one_descent_step( Lgamma_step, Llambda_density_weight_step, Lsub_step, iteration, metrics, stop_mask=None ): t0 = time.time() # metric for this iteration cur_metric = EvalMetrics.EvalMetrics( iteration, (Lgamma_step, Llambda_density_weight_step, Lsub_step) ) cur_metric.gamma = model.gamma.data cur_metric.density_weight = model.density_weight.data metrics.append(cur_metric) pos = model.data_collections.pos[0] # move any out-of-bound cell back to placement region self.op_collections.move_boundary_op(pos) # handle multiple density weights for multi-electric field if torch.eq(model.density_weight.mean(), 0.0): model.initialize_density_weight(params, placedb) if model.density_weight.size(0) == 1: logging.info("density_weight = %.6E" % (model.density_weight.data)) else: logging.info( "density_weight = [%s]" % ", ".join(["%.3E" % i for i in model.density_weight.cpu().numpy().tolist()]) ) optimizer.zero_grad() # t1 = time.time() cur_metric.evaluate(placedb, eval_ops, pos, model.data_collections) model.overflow = cur_metric.overflow.data.clone() # logging.debug("evaluation %.3f ms" % ((time.time()-t1)*1000)) # t2 = time.time() # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in ["sgd", "adam", "sgd_momentum", "sgd_nesterov"]: obj, grad = model.obj_and_grad_fn(pos) cur_metric.objective = obj.data.clone() elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) # plot placement if params.plot_flag and (iteration % 100 == 0 or iteration == 999): cur_pos = self.pos[0].data.clone().cpu().numpy() self.plot(params, placedb, iteration, cur_pos) #### stop updating fence regions that are marked stop, exclude the outer cell ! t3 = time.time() if model.update_mask is not None: pos_bk = pos.data.clone() optimizer.step() for region_id, fence_region_update_flag in enumerate(model.update_mask): if fence_region_update_flag == 0: ### don't update cell location in that region mask = self.op_collections.fence_region_density_ops[region_id].pos_mask pos.data.masked_scatter_(mask, pos_bk[mask]) else: optimizer.step() logging.info("optimizer step %.3f ms" % ((time.time() - t3) * 1000)) # nesterov has already computed the objective of the next step if optimizer_name.lower() == "nesterov": cur_metric.objective = optimizer.param_groups[0]["obj_k_1"][0].data.clone() # actually reports the metric before step logging.info(cur_metric) # record the best outer cell overflow if best_metric[0] is None or best_metric[0].overflow[-1] > cur_metric.overflow[-1]: best_metric[0] = cur_metric if best_pos[0] is None: best_pos[0] = self.pos[0].data.clone() else: best_pos[0].data.copy_(self.pos[0].data) logging.info("full step %.3f ms" % ((time.time() - t0) * 1000)) def check_plateau(x, window=10, threshold=0.001): if len(x) < window: return False x = x[-window:] return (np.max(x) - np.min(x)) / np.mean(x) < threshold def check_divergence(x, window=50, threshold=0.05): if len(x) < window or best_metric[0] is None: return False x = np.array(x[-window:]) overflow_mean = np.mean(x[:, 1]) overflow_diff = np.maximum(0, np.sign(x[1:, 1] - x[:-1, 1])).astype(np.float32) overflow_diff = np.sum(overflow_diff) / overflow_diff.shape[0] overflow_range = np.max(x[:, 1]) - np.min(x[:, 1]) wl_mean = np.mean(x[:, 0]) wl_ratio, overflow_ratio = (wl_mean - best_metric[0].hpwl.item()) / best_metric[ 0 ].hpwl.item(), ( overflow_mean - max(params.stop_overflow, best_metric[0].overflow.item()) ) / best_metric[ 0 ].overflow.item() if wl_ratio > threshold * 1.2: if overflow_ratio > threshold: logging.warn( f"Divergence detected: overflow increases too much than best overflow ({overflow_ratio:.4f} > {threshold:.4f})" ) return True elif overflow_range / overflow_mean < threshold: logging.warn( f"Divergence detected: overflow plateau ({overflow_range/overflow_mean:.4f} < {threshold:.4f})" ) return True elif overflow_diff > 0.6: logging.warn( f"Divergence detected: overflow fluctuate too frequently ({overflow_diff:.2f} > 0.6)" ) return True else: return False else: return False def entropy_injection( pos, placedb, shrink_factor=1, noise_intensity=1, mode="random", iteration=1 ): if mode == "random": # print(pos[: placedb.num_movable_nodes].mean()) xc = pos[: placedb.num_movable_nodes].data.mean() yc = pos.data[ placedb.num_nodes : placedb.num_nodes + placedb.num_movable_nodes ].mean() num_movable_nodes = placedb.num_movable_nodes num_nodes = placedb.num_nodes num_filler_nodes = placedb.num_filler_nodes num_fixed_nodes = num_nodes - num_movable_nodes - num_filler_nodes fixed_pos_x = pos.data[ num_movable_nodes : num_movable_nodes + num_fixed_nodes ].clone() fixed_pos_y = pos.data[ num_nodes + num_movable_nodes : num_nodes + num_movable_nodes + num_fixed_nodes ].clone() if shrink_factor != 1: pos.data[:num_nodes] = (pos.data[:num_nodes] - xc) * shrink_factor + xc pos.data[num_nodes:] = (pos.data[num_nodes:] - yc) * shrink_factor + yc if noise_intensity > 0.01: # pos.data.add_(noise_intensity * torch.rand(num_nodes*2, device=pos.device).sub_(0.5)) pos.data.add_(noise_intensity * torch.randn(num_nodes * 2, device=pos.device)) pos.data[num_movable_nodes : num_movable_nodes + num_fixed_nodes] = fixed_pos_x pos.data[ num_nodes + num_movable_nodes : num_nodes + num_movable_nodes + num_fixed_nodes ] = fixed_pos_y # print(pos[: placedb.num_movable_nodes].mean()) else: raise NotImplementedError Lgamma_metrics = all_metrics if params.routability_opt_flag: adjust_area_flag = True adjust_route_area_flag = params.adjust_nctugr_area_flag or params.adjust_rudy_area_flag adjust_pin_area_flag = params.adjust_pin_area_flag num_area_adjust = 0 Llambda_flat_iteration = 0 ### preparation for self-adaptive divergence check overflow_list = [1] divergence_list = [] min_perturb_interval = 50 stop_placement = 0 last_perturb_iter = -min_perturb_interval perturb_counter = 0 for Lgamma_step in range(model.Lgamma_iteration): Lgamma_metrics.append([]) Llambda_metrics = Lgamma_metrics[-1] for Llambda_density_weight_step in range(model.Llambda_density_weight_iteration): Llambda_metrics.append([]) Lsub_metrics = Llambda_metrics[-1] for Lsub_step in range(model.Lsub_iteration): ## divergence threshold should decrease as overflow decreases ## only detect divergence when overflow is relatively low but not too low if ( len(placedb.regions) == 0 and params.stop_overflow * 1.1 < overflow_list[-1] < params.stop_overflow * 4 and check_divergence( divergence_list, window=3, threshold=0.01 * overflow_list[-1] ) ): self.pos[0].data.copy_(best_pos[0].data) stop_placement = 1 logging.error( "possible DIVERGENCE detected, roll back to the best position recorded" ) one_descent_step( Lgamma_step, Llambda_density_weight_step, Lsub_step, iteration, Lsub_metrics ) if len(placedb.regions) == 0: overflow_list.append(Llambda_metrics[-1][-1].overflow.data.item()) divergence_list.append( [ Llambda_metrics[-1][-1].hpwl.data.item(), Llambda_metrics[-1][-1].overflow.data.item(), ] ) ## quadratic penalty and entropy injection if ( len(placedb.regions) == 0 and iteration - last_perturb_iter > min_perturb_interval and check_plateau(overflow_list, window=15, threshold=0.001) ): if overflow_list[-1] > 0.9: # stuck at high overflow model.quad_penalty = True model.density_factor *= 2 logging.info( f"Stuck at early stage. Turn on quadratic penalty with double density factor to accelerate convergence" ) if overflow_list[-1] > 0.95: # stuck at very high overflow noise_intensity = min( max(40 + (120 - 40) * (overflow_list[-1] - 0.95) * 10, 40), 90 ) entropy_injection( self.pos[0], placedb, shrink_factor=0.996, noise_intensity=noise_intensity, mode="random", ) logging.info( f"Stuck at very early stage. Turn on entropy injection with noise intensity = {noise_intensity} to help convergence" ) last_perturb_iter = iteration perturb_counter += 1 iteration += 1 # stopping criteria if Lsub_stop_criterion( Lgamma_step, Llambda_density_weight_step, Lsub_step, Lsub_metrics ): break Llambda_flat_iteration += 1 # update density weight if Llambda_flat_iteration > 1: model.op_collections.update_density_weight_op( Llambda_metrics[-1][-1], Llambda_metrics[-2][-1] if len(Llambda_metrics) > 1 else Lgamma_metrics[-2][-1][-1], Llambda_flat_iteration, ) # logging.debug("update density weight %.3f ms" % ((time.time()-t2)*1000)) if Llambda_stop_criterion(Lgamma_step, Llambda_density_weight_step, Llambda_metrics): break # for routability optimization if ( params.routability_opt_flag and num_area_adjust < params.max_num_area_adjust and Llambda_metrics[-1][-1].overflow < params.node_area_adjust_overflow ): content = ( "routability optimization round %d: adjust area flags = (%d, %d, %d)" % ( num_area_adjust, adjust_area_flag, adjust_route_area_flag, adjust_pin_area_flag, ) ) pos = model.data_collections.pos[0] route_utilization_map = None pin_utilization_map = None if adjust_route_area_flag: if params.adjust_nctugr_area_flag: route_utilization_map = model.op_collections.nctugr_congestion_map_op(pos) else: route_utilization_map = model.op_collections.route_utilization_map_op(pos) if params.plot_flag: path = "%s/%s" % (params.result_dir, params.design_name()) figname = "%s/plot/route%d.png" % (path, num_area_adjust) os.system("mkdir -p %s" % (os.path.dirname(figname))) plt.imsave( figname, route_utilization_map.data.cpu().numpy().T, origin="lower" ) if adjust_pin_area_flag: pin_utilization_map = model.op_collections.pin_utilization_map_op(pos) if params.plot_flag: path = "%s/%s" % (params.result_dir, params.design_name()) figname = "%s/plot/pin%d.png" % (path, num_area_adjust) os.system("mkdir -p %s" % (os.path.dirname(figname))) plt.imsave( figname, pin_utilization_map.data.cpu().numpy().T, origin="lower" ) ( adjust_area_flag, adjust_route_area_flag, adjust_pin_area_flag, ) = model.op_collections.adjust_node_area_op( pos, route_utilization_map, pin_utilization_map ) content += " -> (%d, %d, %d)" % ( adjust_area_flag, adjust_route_area_flag, adjust_pin_area_flag, ) logging.info(content) if adjust_area_flag: num_area_adjust += 1 # restart Llambda model.op_collections.density_op.reset() model.op_collections.density_overflow_op.reset() model.op_collections.pin_utilization_map_op.reset() model.initialize_density_weight(params, placedb) model.density_weight.mul_(0.1 / params.density_weight) logging.info("density_weight = %.6E" % (model.density_weight.data)) # load state to restart the optimizer optimizer.load_state_dict(initial_state) # must after loading the state initialize_learning_rate(pos) # increase iterations of the sub problem to slow down the search model.Lsub_iteration = model.routability_Lsub_iteration # reset best metric best_metric[0] = None best_pos[0] = None break # gradually reduce gamma to tradeoff smoothness and accuracy if len(placedb.regions) > 0 and Llambda_metrics[-1][-1].goverflow is not None: model.op_collections.update_gamma_op(Lgamma_step, Llambda_metrics[-1][-1].goverflow) elif len(placedb.regions) == 0 and Llambda_metrics[-1][-1].overflow is not None: model.op_collections.update_gamma_op(Lgamma_step, Llambda_metrics[-1][-1].overflow) else: model.op_collections.precondition_op.set_overflow(Llambda_metrics[-1][-1].overflow) if Lgamma_stop_criterion(Lgamma_step, Lgamma_metrics) or stop_placement == 1: break # update learning rate if optimizer_name.lower() in ["sgd", "adam", "sgd_momentum", "sgd_nesterov", "cg"]: if "learning_rate_decay" in global_place_params: for param_group in optimizer.param_groups: param_group["lr"] *= global_place_params["learning_rate_decay"] # in case of divergence, use the best metric # last_metric = all_metrics[-1][-1][-1] # if ( # last_metric.overflow[-1] > max(params.stop_overflow, best_metric[0].overflow[-1]) # and last_metric.hpwl > best_metric[0].hpwl # ): # all_metrics.append([best_metric]) logging.info("optimizer %s takes %.3f seconds" % (optimizer_name, time.time() - tt)) # recover node size and pin offset for legalization, since node size is adjusted in global placement if params.routability_opt_flag: with torch.no_grad(): # convert lower left to centers self.pos[0][: placedb.num_movable_nodes].add_( self.data_collections.node_size_x[: placedb.num_movable_nodes] / 2 ) self.pos[0][placedb.num_nodes : placedb.num_nodes + placedb.num_movable_nodes].add_( self.data_collections.node_size_y[: placedb.num_movable_nodes] / 2 ) self.data_collections.node_size_x.copy_(self.data_collections.original_node_size_x) self.data_collections.node_size_y.copy_(self.data_collections.original_node_size_y) # use fixed centers as the anchor self.pos[0][: placedb.num_movable_nodes].sub_( self.data_collections.node_size_x[: placedb.num_movable_nodes] / 2 ) self.pos[0][placedb.num_nodes : placedb.num_nodes + placedb.num_movable_nodes].sub_( self.data_collections.node_size_y[: placedb.num_movable_nodes] / 2 ) self.data_collections.pin_offset_x.copy_(self.data_collections.original_pin_offset_x) self.data_collections.pin_offset_y.copy_(self.data_collections.original_pin_offset_y) else: cur_metric = EvalMetrics.EvalMetrics(iteration) all_metrics.append(cur_metric) cur_metric.evaluate(placedb, {"hpwl": self.op_collections.hpwl_op}, self.pos[0]) logging.info(cur_metric) # dump global placement solution for legalization if params.dump_global_place_solution_flag: self.dump(params, placedb, self.pos[0].cpu(), "%s.lg.pklz" % (params.design_name())) # plot placement if params.plot_flag: self.plot(params, placedb, iteration, self.pos[0].data.clone().cpu().numpy()) # legalization if params.legalize_flag: tt = time.time() self.pos[0].data.copy_(self.op_collections.legalize_op(self.pos[0])) logging.info("legalization takes %.3f seconds" % (time.time() - tt)) cur_metric = EvalMetrics.EvalMetrics(iteration) all_metrics.append(cur_metric) cur_metric.evaluate(placedb, {"hpwl": self.op_collections.hpwl_op}, self.pos[0]) logging.info(cur_metric) iteration += 1 # plot placement if params.plot_flag: self.plot(params, placedb, iteration, self.pos[0].data.clone().cpu().numpy()) # dump legalization solution for detailed placement if params.dump_legalize_solution_flag: self.dump(params, placedb, self.pos[0].cpu(), "%s.dp.pklz" % (params.design_name())) # detailed placement if params.detailed_place_flag: tt = time.time() self.pos[0].data.copy_(self.op_collections.detailed_place_op(self.pos[0])) logging.info("detailed placement takes %.3f seconds" % (time.time() - tt)) cur_metric = EvalMetrics.EvalMetrics(iteration) all_metrics.append(cur_metric) cur_metric.evaluate(placedb, {"hpwl": self.op_collections.hpwl_op}, self.pos[0]) logging.info(cur_metric) iteration += 1 # save results cur_pos = self.pos[0].data.clone().cpu().numpy() # apply solution placedb.apply( params, cur_pos[0 : placedb.num_movable_nodes], cur_pos[placedb.num_nodes : placedb.num_nodes + placedb.num_movable_nodes], ) # plot placement if params.plot_flag: self.plot(params, placedb, iteration, cur_pos) return all_metrics
def one_descent_step( Lgamma_step, Llambda_density_weight_step, Lsub_step, iteration, metrics, stop_mask=None ): t0 = time.time() # metric for this iteration cur_metric = EvalMetrics.EvalMetrics( iteration, (Lgamma_step, Llambda_density_weight_step, Lsub_step) ) cur_metric.gamma = model.gamma.data cur_metric.density_weight = model.density_weight.data metrics.append(cur_metric) pos = model.data_collections.pos[0] # move any out-of-bound cell back to placement region self.op_collections.move_boundary_op(pos) # handle multiple density weights for multi-electric field if torch.eq(model.density_weight.mean(), 0.0): model.initialize_density_weight(params, placedb) if model.density_weight.size(0) == 1: logging.info("density_weight = %.6E" % (model.density_weight.data)) else: logging.info( "density_weight = [%s]" % ", ".join(["%.3E" % i for i in model.density_weight.cpu().numpy().tolist()]) ) optimizer.zero_grad() # t1 = time.time() cur_metric.evaluate(placedb, eval_ops, pos, model.data_collections) model.overflow = cur_metric.overflow.data.clone() # logging.debug("evaluation %.3f ms" % ((time.time()-t1)*1000)) # t2 = time.time() # as nesterov requires line search, we cannot follow the convention of other solvers if optimizer_name.lower() in ["sgd", "adam", "sgd_momentum", "sgd_nesterov"]: obj, grad = model.obj_and_grad_fn(pos) cur_metric.objective = obj.data.clone() elif optimizer_name.lower() != "nesterov": assert 0, "unsupported optimizer %s" % (optimizer_name) # plot placement if params.plot_flag and (iteration % 100 == 0 or iteration == 999): cur_pos = self.pos[0].data.clone().cpu().numpy() self.plot(params, placedb, iteration, cur_pos) #### stop updating fence regions that are marked stop, exclude the outer cell ! t3 = time.time() if model.update_mask is not None: pos_bk = pos.data.clone() optimizer.step() for region_id, fence_region_update_flag in enumerate(model.update_mask): if fence_region_update_flag == 0: ### don't update cell location in that region mask = self.op_collections.fence_region_density_ops[region_id].pos_mask pos.data.masked_scatter_(mask, pos_bk[mask]) else: optimizer.step() logging.info("optimizer step %.3f ms" % ((time.time() - t3) * 1000)) # nesterov has already computed the objective of the next step if optimizer_name.lower() == "nesterov": cur_metric.objective = optimizer.param_groups[0]["obj_k_1"][0].data.clone() # actually reports the metric before step logging.info(cur_metric) # record the best outer cell overflow if best_metric[0] is None or best_metric[0].overflow[-1] > cur_metric.overflow[-1]: best_metric[0] = cur_metric if best_pos[0] is None: best_pos[0] = self.pos[0].data.clone() else: best_pos[0].data.copy_(self.pos[0].data) logging.info("full step %.3f ms" % ((time.time() - t0) * 1000))
def main(): """Create the model and start the evaluation process.""" # Create queue coordinator. coord = tf.train.Coordinator() h, w = INPUT_SIZE # Load reader. with tf.name_scope("create_inputs"): reader = DataSetReader(IMAGE_DIR, LABEL_DIR, DATA_SET, INPUT_SIZE, False, False, False, coord, DATA_SET) # reader = DataSetReader(IMAGE_DIR, coord, DATA_SET) image = reader.image label = reader.label image_rev = tf.reverse(image, tf.stack([1])) image_list = reader.image_list label_list = reader.label_list image_batch_origin = tf.stack([image, image_rev]) image_batch = tf.image.resize_images(image_batch_origin, [int(h), int(w)]) image_batch075 = tf.image.resize_images( image_batch_origin, [int(h * 0.75), int(w * 0.75)]) image_batch125 = tf.image.resize_images( image_batch_origin, [int(h * 1.25), int(w * 1.25)]) # Create network. with tf.variable_scope('', reuse=False): net_100 = DeepLabV2Model({'data': image_batch}, is_training=False, n_classes=N_CLASSES) with tf.variable_scope('', reuse=True): net_075 = DeepLabV2Model({'data': image_batch075}, is_training=False, n_classes=N_CLASSES) with tf.variable_scope('', reuse=True): net_125 = DeepLabV2Model({'data': image_batch125}, is_training=False, n_classes=N_CLASSES) # parsing net parsing_out1_100 = net_100.layers['fc1_human'] parsing_out1_075 = net_075.layers['fc1_human'] parsing_out1_125 = net_125.layers['fc1_human'] parsing_out1 = tf.reduce_mean(tf.stack([ tf.image.resize_images(parsing_out1_100, tf.shape(image_batch_origin)[1:3, ]), tf.image.resize_images(parsing_out1_075, tf.shape(image_batch_origin)[1:3, ]), tf.image.resize_images(parsing_out1_125, tf.shape(image_batch_origin)[1:3, ]) ]), axis=0) raw_output = tf.reduce_mean(tf.stack([parsing_out1]), axis=0) head_output, tail_output = tf.unstack(raw_output, num=2, axis=0) tail_list = tf.unstack(tail_output, num=N_CLASSES, axis=2) tail_list_rev = [None] * N_CLASSES if DATA_SET == "LIP": for xx in range(14): tail_list_rev[xx] = tail_list[xx] tail_list_rev[14] = tail_list[15] tail_list_rev[15] = tail_list[14] tail_list_rev[16] = tail_list[17] tail_list_rev[17] = tail_list[16] tail_list_rev[18] = tail_list[19] tail_list_rev[19] = tail_list[18] elif DATA_SET == "10k": for xx in range(9): tail_list_rev[xx] = tail_list[xx] tail_list_rev[9] = tail_list[10] tail_list_rev[10] = tail_list[9] tail_list_rev[11] = tail_list[11] tail_list_rev[12] = tail_list[13] tail_list_rev[13] = tail_list[12] tail_list_rev[14] = tail_list[15] tail_list_rev[15] = tail_list[14] tail_list_rev[16] = tail_list[16] tail_list_rev[17] = tail_list[17] tail_output_rev = tf.stack(tail_list_rev, axis=2) tail_output_rev = tf.reverse(tail_output_rev, tf.stack([1])) raw_output_all = tf.reduce_mean(tf.stack([head_output, tail_output_rev]), axis=0) raw_output_all = tf.expand_dims(raw_output_all, dim=0) logits = raw_output_all raw_output_all = tf.argmax(raw_output_all, dimension=3) # Create 4-d tensor. prediction_all = tf.expand_dims(raw_output_all, dim=3) # Which variables to load. restore_var = tf.global_variables() # Set up tf session and initialize variables. config = tf.ConfigProto() config.gpu_options.allow_growth = True sess = tf.Session(config=config) init = tf.global_variables_initializer() sess.run(init) sess.run(tf.local_variables_initializer()) # Load weights. loader = tf.train.Saver(var_list=restore_var) if RESTORE_FROM is not None: if load(loader, sess, RESTORE_FROM): print(" [*] Load SUCCESS") else: print(" [!] Load failed...") # Start queue threads. threads = tf.train.start_queue_runners(coord=coord, sess=sess) cross_mats = list() crf_cross_mats = list() probability = tf.nn.softmax(logits=logits, axis=3) image_options = {'resize': True, 'resize_size': IMAGE_SIZE} validation_dataset_reader = BatchDatsetReader.BatchDatset( valid_records, image_options) validation_dataset_reader.reset_batch_offset(0) # Iterate over training steps. for step in range(NUM_STEPS): try: parsing_, probpred = sess.run([prediction_all, probability]) if step % 100 == 0: print('step {:d}'.format(step)) print(image_list[step]) img_split = image_list[step].split('/') # extra split for modified file readers img_split = img_split[-1].split('\\')[1] img_id = img_split[:-4] msk = decode_labels(parsing_, num_classes=N_CLASSES) parsing_im = Image.fromarray(msk[0]) parsing_im.save('{}/pred_{}_vis.png'.format(OUTPUT_DIR, img_id)) cv2.imwrite('{}/pred_{}.png'.format(OUTPUT_DIR, img_id), parsing_[0, :, :, 0]) try: inp, gt = validation_dataset_reader.next_batch(1) msk = decode_labels(gt, num_classes=N_CLASSES) parsing_im = Image.fromarray(msk[0]) parsing_im.save('{}/gt_{}_vis.png'.format(OUTPUT_DIR, img_id)) cv2.imwrite('{}/gt_{}.png'.format(OUTPUT_DIR, img_id), gt[0, :, :, 0]) inp = inp[0] gt = gt[0] gt = np.squeeze(gt, axis=2) # Confusion matrix for this image prediction crossMat = EvalMetrics.calculate_confusion_matrix( gt.astype(np.uint8), parsing_[0, :, :, 0].astype(np.uint8), N_CLASSES) cross_mats.append(crossMat) np.savetxt(OUTPUT_DIR + "Crossmatrix" + str(img_id) + ".csv", crossMat, fmt='%4i', delimiter=',') # Save input, gt, pred, crf_pred, sum figures for this image """ Generate CRF """ # 1. run CRF crfwithprobsoutput = denseCRF.crf_with_probs( inp.astype(np.uint8), probpred[0], N_CLASSES) # 2. show result display crfwithprobspred = crfwithprobsoutput.astype(np.uint8) crfwithprobspred_expanded = np.expand_dims(crfwithprobspred, axis=0) crfwithprobspred_expanded = np.expand_dims( crfwithprobspred_expanded, axis=3) msk = decode_labels(crfwithprobspred_expanded, num_classes=N_CLASSES) parsing_im = Image.fromarray(msk[0]) parsing_im.save('{}/crf_{}_vis.png'.format(OUTPUT_DIR, img_id)) cv2.imwrite('{}/crf_{}.png'.format(OUTPUT_DIR, img_id), crfwithprobspred) # Confusion matrix for this image prediction with crf prob_crf_crossMat = EvalMetrics.calculate_confusion_matrix( gt.astype(np.uint8), crfwithprobsoutput.astype(np.uint8), N_CLASSES) crf_cross_mats.append(prob_crf_crossMat) np.savetxt(OUTPUT_DIR + "crf_Crossmatrix" + str(img_id) + ".csv", prob_crf_crossMat, fmt='%4i', delimiter=',') except Exception as e: print(e) except Exception as err: print(err) try: total_cm = np.sum(cross_mats, axis=0) np.savetxt(OUTPUT_DIR + "Crossmatrix.csv", total_cm, fmt='%4i', delimiter=',') print("\n>>> Prediction results (Our functions):") EvalMetrics.calculate_eval_metrics_from_confusion_matrix( total_cm, N_CLASSES) print("\n>>> Prediction results (LIP functions):") EvalMetrics.show_result(total_cm, N_CLASSES) # Prediction with CRF crf_total_cm = np.sum(crf_cross_mats, axis=0) np.savetxt(OUTPUT_DIR + "CRF_Crossmatrix.csv", crf_total_cm, fmt='%4i', delimiter=',') print("\n") print(">>> Prediction results (CRF):") EvalMetrics.show_result(crf_total_cm, N_CLASSES) except Exception as err: print(err) coord.request_stop() coord.join(threads)