def run_phase()

in main.py [0:0]


def run_phase(phase, loader, model, optimizer, criterion, epoch, args, cfg, logger, tb_writter):
    from utils import metrics_utils
    logger.add_line('\n{}: Epoch {}'.format(phase, epoch))
    batch_time = metrics_utils.AverageMeter('Time', ':6.3f', window_size=100)
    data_time = metrics_utils.AverageMeter('Data', ':6.3f', window_size=100)
    loss_meter = metrics_utils.AverageMeter('Loss', ':.3e')
    loss_meter_npid1 = metrics_utils.AverageMeter('Loss_npid1', ':.3e')
    loss_meter_npid2 = metrics_utils.AverageMeter('Loss_npid2', ':.3e')
    loss_meter_cmc1 = metrics_utils.AverageMeter('Loss_cmc1', ':.3e')
    loss_meter_cmc2 = metrics_utils.AverageMeter('Loss_cmc2', ':.3e')
    progress = utils.logger.ProgressMeter(len(loader), [batch_time, data_time, loss_meter, loss_meter_npid1, loss_meter_npid2, loss_meter_cmc1, loss_meter_cmc2], phase=phase, epoch=epoch, logger=logger, tb_writter=tb_writter)

    # switch to train mode
    model.train(phase == 'train')

    end = time.time()
    device = args.gpu if args.gpu is not None else 0
    for i, sample in enumerate(loader):
        # measure data loading time
        data_time.update(time.time() - end)

        if phase == 'train':
            embedding = model(sample)
        else:
            with torch.no_grad():
                embedding = model(sample)

        # compute loss
        loss, loss_debug = criterion(embedding)
        loss_meter.update(loss.item(), embedding[0].size(0))
        loss_meter_npid1.update(loss_debug[0].item(), embedding[0].size(0))
        loss_meter_npid2.update(loss_debug[1].item(), embedding[0].size(0))
        loss_meter_cmc1.update(loss_debug[2].item(), embedding[0].size(0))
        loss_meter_cmc2.update(loss_debug[3].item(), embedding[0].size(0))

        # compute gradient and do SGD step during training
        if phase == 'train':
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        # measure elapsed time
        batch_time.update(time.time() - end)
        end = time.time()

        # print to terminal and tensorboard
        step = epoch * len(loader) + i
        if (i+1) % cfg['print_freq'] == 0 or i == 0 or i+1 == len(loader):
            progress.display(i+1)

    # Sync metrics across all GPUs and print final averages
    if args.multiprocessing_distributed:
        progress.synchronize_meters(args.gpu)
        progress.display(len(loader)*args.world_size)

    if tb_writter is not None:
        for meter in progress.meters:
            tb_writter.add_scalar('{}-epoch/{}'.format(phase, meter.name), meter.avg, epoch)