def METHOD_NAME(model, loader, args, evaluator=None, log_suffix='',
             num_batch=1):
    # batch_time_m = AverageMeter()
    losses_m = AverageMeter()
    model.eval()
    # end = time.time()
    # last_idx = len(loader) - 1
    with torch.no_grad():
        for batch_idx, (input, target) in zip(range(num_batch), loader):
            # last_batch = batch_idx == last_idx
            output = model(input, target)
            loss = output['loss']
            if evaluator is not None:
                evaluator.add_predictions(output['detections'], target)
            if args.distributed:
                reduced_loss = reduce_tensor(loss.data, args.world_size)
            else:
                reduced_loss = loss.data
            torch.cuda.synchronize()
            losses_m.update(reduced_loss.item(), input.size(0))
            # batch_time_m.update(time.time() - end)
            # end = time.time()
            # if args.local_rank == 0 and (last_batch or batch_idx % args.log_interval == 0):
            #     log_name = 'Test' + log_suffix
            #     logging.info(
            #         '{0}: [{1:>4d}/{2}]  '
            #         'Time: {batch_time.val:.3f} ({batch_time.avg:.3f})  '
            #         'Loss: {loss.val:>7.4f} ({loss.avg:>6.4f})  '.format(
            #             log_name, batch_idx, last_idx, batch_time=batch_time_m, loss=losses_m))
    metrics = OrderedDict([('loss', losses_m.avg)])
    if evaluator is not None:
        metrics['map'] = evaluator.evaluate()
    return metric