import torch
import torch.nn.functional as F
import torch.nn as nn


def binary_logistic_regression_loss(reg_score, label, threshold=0.5,
    ratio_range=(1.05, 21), eps=1e-05):
    """Binary Logistic Regression Loss."""
    label = label.view(-1)
    reg_score = reg_score.contiguous().view(-1)
    pmask = (label > threshold).float()
    num_positive = max(torch.sum(pmask), 1)
    num_entries = len(label)
    ratio = num_entries / num_positive
    ratio = min(max(ratio, ratio_range[0]), ratio_range[1])
    coef_0 = 0.5 * ratio / (ratio - 1)
    coef_1 = 0.5 * ratio
    loss = coef_1 * pmask * torch.log(reg_score + eps) + coef_0 * (1.0 - pmask
        ) * torch.log(1.0 - reg_score + eps)
    loss = -torch.mean(loss)
    return loss


class BMNLoss(nn.Module):
    """BMN Loss.

    From paper https://arxiv.org/abs/1907.09702,
    code https://github.com/JJBOY/BMN-Boundary-Matching-Network.
    It will calculate loss for BMN Model. This loss is a weighted sum of

        1) temporal evaluation loss based on confidence score of start and
        end positions.
        2) proposal evaluation regression loss based on confidence scores of
        candidate proposals.
        3) proposal evaluation classification loss based on classification
        results of candidate proposals.
    """

    @staticmethod
    def tem_loss(pred_start, pred_end, gt_start, gt_end):
        """Calculate Temporal Evaluation Module Loss.

        This function calculate the binary_logistic_regression_loss for start
        and end respectively and returns the sum of their losses.

        Args:
            pred_start (torch.Tensor): Predicted start score by BMN model.
            pred_end (torch.Tensor): Predicted end score by BMN model.
            gt_start (torch.Tensor): Groundtruth confidence score for start.
            gt_end (torch.Tensor): Groundtruth confidence score for end.

        Returns:
            torch.Tensor: Returned binary logistic loss.
        """
        loss_start = binary_logistic_regression_loss(pred_start, gt_start)
        loss_end = binary_logistic_regression_loss(pred_end, gt_end)
        loss = loss_start + loss_end
        return loss

    @staticmethod
    def pem_reg_loss(pred_score, gt_iou_map, mask,
        high_temporal_iou_threshold=0.7, low_temporal_iou_threshold=0.3):
        """Calculate Proposal Evaluation Module Regression Loss.

        Args:
            pred_score (torch.Tensor): Predicted temporal_iou score by BMN.
            gt_iou_map (torch.Tensor): Groundtruth temporal_iou score.
            mask (torch.Tensor): Boundary-Matching mask.
            high_temporal_iou_threshold (float): Higher threshold of
                temporal_iou. Default: 0.7.
            low_temporal_iou_threshold (float): Higher threshold of
                temporal_iou. Default: 0.3.

        Returns:
            torch.Tensor: Proposal evaluation regression loss.
        """
        u_hmask = (gt_iou_map > high_temporal_iou_threshold).float()
        u_mmask = ((gt_iou_map <= high_temporal_iou_threshold) & (
            gt_iou_map > low_temporal_iou_threshold)).float()
        u_lmask = ((gt_iou_map <= low_temporal_iou_threshold) & (gt_iou_map >
            0.0)).float()
        u_lmask = u_lmask * mask
        num_h = torch.sum(u_hmask)
        num_m = torch.sum(u_mmask)
        num_l = torch.sum(u_lmask)
        r_m = num_h / num_m
        u_smmask = torch.rand_like(gt_iou_map)
        u_smmask = u_mmask * u_smmask
        u_smmask = (u_smmask > 1.0 - r_m).float()
        r_l = num_h / num_l
        u_slmask = torch.rand_like(gt_iou_map)
        u_slmask = u_lmask * u_slmask
        u_slmask = (u_slmask > 1.0 - r_l).float()
        weights = u_hmask + u_smmask + u_slmask
        loss = F.mse_loss(pred_score * weights, gt_iou_map * weights)
        loss = 0.5 * torch.sum(loss * torch.ones_like(weights)) / torch.sum(
            weights)
        return loss

    @staticmethod
    def pem_cls_loss(pred_score, gt_iou_map, mask, threshold=0.9,
        ratio_range=(1.05, 21), eps=1e-05):
        """Calculate Proposal Evaluation Module Classification Loss.

        Args:
            pred_score (torch.Tensor): Predicted temporal_iou score by BMN.
            gt_iou_map (torch.Tensor): Groundtruth temporal_iou score.
            mask (torch.Tensor): Boundary-Matching mask.
            threshold (float): Threshold of temporal_iou for positive
                instances. Default: 0.9.
            ratio_range (tuple): Lower bound and upper bound for ratio.
                Default: (1.05, 21)
            eps (float): Epsilon for small value. Default: 1e-5

        Returns:
            torch.Tensor: Proposal evaluation classification loss.
        """
        pmask = (gt_iou_map > threshold).float()
        nmask = (gt_iou_map <= threshold).float()
        nmask = nmask * mask
        num_positive = max(torch.sum(pmask), 1)
        num_entries = num_positive + torch.sum(nmask)
        ratio = num_entries / num_positive
        ratio = torch.clamp(ratio, ratio_range[0], ratio_range[1])
        coef_0 = 0.5 * ratio / (ratio - 1)
        coef_1 = 0.5 * ratio
        loss_pos = coef_1 * torch.log(pred_score + eps) * pmask
        loss_neg = coef_0 * torch.log(1.0 - pred_score + eps) * nmask
        loss = -1 * torch.sum(loss_pos + loss_neg) / num_entries
        return loss

    def forward(self, pred_bm, pred_start, pred_end, gt_iou_map, gt_start,
        gt_end, bm_mask, weight_tem=1.0, weight_pem_reg=10.0,
        weight_pem_cls=1.0):
        """Calculate Boundary Matching Network Loss.

        Args:
            pred_bm (torch.Tensor): Predicted confidence score for boundary
                matching map.
            pred_start (torch.Tensor): Predicted confidence score for start.
            pred_end (torch.Tensor): Predicted confidence score for end.
            gt_iou_map (torch.Tensor): Groundtruth score for boundary matching
                map.
            gt_start (torch.Tensor): Groundtruth temporal_iou score for start.
            gt_end (torch.Tensor): Groundtruth temporal_iou score for end.
            bm_mask (torch.Tensor): Boundary-Matching mask.
            weight_tem (float): Weight for tem loss. Default: 1.0.
            weight_pem_reg (float): Weight for pem regression loss.
                Default: 10.0.
            weight_pem_cls (float): Weight for pem classification loss.
                Default: 1.0.

        Returns:
            tuple([torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]):
                (loss, tem_loss, pem_reg_loss, pem_cls_loss). Loss is the bmn
                loss, tem_loss is the temporal evaluation loss, pem_reg_loss is
                the proposal evaluation regression loss, pem_cls_loss is the
                proposal evaluation classification loss.
        """
        pred_bm_reg = pred_bm[:, 0].contiguous()
        pred_bm_cls = pred_bm[:, 1].contiguous()
        gt_iou_map = gt_iou_map * bm_mask
        pem_reg_loss = self.pem_reg_loss(pred_bm_reg, gt_iou_map, bm_mask)
        pem_cls_loss = self.pem_cls_loss(pred_bm_cls, gt_iou_map, bm_mask)
        tem_loss = self.tem_loss(pred_start, pred_end, gt_start, gt_end)
        loss = (weight_tem * tem_loss + weight_pem_reg * pem_reg_loss + 
            weight_pem_cls * pem_cls_loss)
        return loss, tem_loss, pem_reg_loss, pem_cls_loss


def get_inputs():
    return [torch.rand([4, 4, 4, 4]), torch.rand([4, 4, 4, 4]), torch.rand(
        [4, 4, 4, 4]), torch.rand([4, 4, 4, 4]), torch.rand([4, 4, 4, 4]),
        torch.rand([4, 4, 4, 4]), torch.rand([4, 4, 4, 4])]


def get_init_inputs():
    return [[], {}]

import torch
from torch import device
import triton
import triton.language as tl
from torch._inductor.runtime.triton_heuristics import grid
from torch._C import _cuda_getCurrentRawStream as get_raw_stream
from torch._inductor.runtime import triton_helpers
from torch._inductor.runtime.triton_helpers import math as tl_math
import torch.nn.functional as F
import torch.nn as nn
assert_size_stride = torch._C._dynamo.guards.assert_size_stride
empty_strided_cuda = torch._C._dynamo.guards._empty_strided_cuda


@triton.jit
def triton_per_fused__to_copy_add_bitwise_and_clamp_clone_div_gt_le_log_mean_mse_loss_mul_neg_ones_like_reciprocal_rsub_sub_sum_0(
    in_out_ptr0, in_out_ptr1, in_out_ptr2, in_out_ptr3, in_ptr0, in_ptr1,
    in_ptr2, in_ptr3, in_ptr4, in_ptr5, in_ptr6, in_ptr7, out_ptr12, xnumel,
    rnumel):
    XBLOCK: tl.constexpr = 1
    RBLOCK: tl.constexpr = 256
    xoffset = tl.program_id(0) * XBLOCK
    tl.full([1], xoffset, tl.int32)
    tl.full([RBLOCK], True, tl.int1)
    rindex = tl.arange(0, RBLOCK)[:]
    tl.full([RBLOCK], True, tl.int1)
    r0 = rindex
    r1 = rindex % 16
    r2 = rindex // 16 % 4
    tmp0 = tl.load(in_ptr0 + r0, None)
    tmp19 = tl.load(in_ptr1 + r0, None)
    tmp36 = tl.load(in_ptr2 + r0, None)
    tmp37 = tl.load(in_ptr3 + r0, None)
    tmp62 = tl.load(in_ptr4 + r0, None)
    tmp69 = tl.load(in_out_ptr0 + r0, None)
    tmp76 = tl.load(in_ptr5 + (r1 + 64 * r2), None, eviction_policy=
        'evict_last')
    tmp110 = tl.load(in_ptr5 + (16 + r1 + 64 * r2), None, eviction_policy=
        'evict_last')
    tmp126 = tl.load(in_ptr6 + r0, None)
    tmp139 = tl.load(in_ptr7 + r0, None)
    tmp1 = 0.5
    tmp2 = tmp0 > tmp1
    tmp3 = tmp2.to(tl.float32)
    tmp4 = tl.broadcast_to(tmp3, [RBLOCK])
    tmp6 = triton_helpers.promote_to_tensor(tl.sum(tmp4, 0))
    tmp7 = 1.0
    tmp8 = triton_helpers.maximum(tmp6, tmp7)
    tmp9 = tl.full([1], 1, tl.int32)
    tmp10 = tmp9 / tmp8
    tmp11 = 256.0
    tmp12 = tmp10 * tmp11
    tmp13 = 1.05
    tmp14 = triton_helpers.maximum(tmp12, tmp13)
    tmp15 = 21.0
    tmp16 = triton_helpers.minimum(tmp14, tmp15)
    tmp17 = tmp16 * tmp1
    tmp18 = tmp17 * tmp3
    tmp20 = 1e-05
    tmp21 = tmp19 + tmp20
    tmp22 = tl_math.log(tmp21)
    tmp23 = tmp18 * tmp22
    tmp24 = tmp16 - tmp7
    tmp25 = tmp17 / tmp24
    tmp26 = tmp7 - tmp3
    tmp27 = tmp25 * tmp26
    tmp28 = tmp7 - tmp19
    tmp29 = tmp28 + tmp20
    tmp30 = tl_math.log(tmp29)
    tmp31 = tmp27 * tmp30
    tmp32 = tmp23 + tmp31
    tmp33 = tl.broadcast_to(tmp32, [RBLOCK])
    tmp35 = triton_helpers.promote_to_tensor(tl.sum(tmp33, 0))
    tmp38 = tmp36 * tmp37
    tmp39 = 0.7
    tmp40 = tmp38 > tmp39
    tmp41 = tmp40.to(tl.float32)
    tmp42 = tl.broadcast_to(tmp41, [RBLOCK])
    tmp44 = triton_helpers.promote_to_tensor(tl.sum(tmp42, 0))
    tmp45 = tmp38 <= tmp39
    tmp46 = 0.3
    tmp47 = tmp38 > tmp46
    tmp48 = tmp45 & tmp47
    tmp49 = tmp48.to(tl.float32)
    tmp50 = tl.broadcast_to(tmp49, [RBLOCK])
    tmp52 = triton_helpers.promote_to_tensor(tl.sum(tmp50, 0))
    tmp53 = tmp38 <= tmp46
    tmp54 = 0.0
    tmp55 = tmp38 > tmp54
    tmp56 = tmp53 & tmp55
    tmp57 = tmp56.to(tl.float32)
    tmp58 = tmp57 * tmp37
    tmp59 = tl.broadcast_to(tmp58, [RBLOCK])
    tmp61 = triton_helpers.promote_to_tensor(tl.sum(tmp59, 0))
    tmp63 = tmp49 * tmp62
    tmp64 = tmp44 / tmp52
    tmp65 = tmp7 - tmp64
    tmp66 = tmp63 > tmp65
    tmp67 = tmp66.to(tl.float32)
    tmp68 = tmp41 + tmp67
    tmp70 = tmp58 * tmp69
    tmp71 = tmp44 / tmp61
    tmp72 = tmp7 - tmp71
    tmp73 = tmp70 > tmp72
    tmp74 = tmp73.to(tl.float32)
    tmp75 = tmp68 + tmp74
    tmp77 = tmp76 * tmp75
    tmp78 = tmp38 * tmp75
    tmp79 = tmp77 - tmp78
    tmp80 = tmp79 * tmp79
    tmp81 = tl.broadcast_to(tmp80, [RBLOCK])
    tmp83 = triton_helpers.promote_to_tensor(tl.sum(tmp81, 0))
    tmp84 = 0.9
    tmp85 = tmp38 > tmp84
    tmp86 = tmp85.to(tl.float32)
    tmp87 = tl.broadcast_to(tmp86, [RBLOCK])
    tmp89 = triton_helpers.promote_to_tensor(tl.sum(tmp87, 0))
    tmp90 = tmp38 <= tmp84
    tmp91 = tmp90.to(tl.float32)
    tmp92 = tmp91 * tmp37
    tmp93 = tl.broadcast_to(tmp92, [RBLOCK])
    tmp95 = triton_helpers.promote_to_tensor(tl.sum(tmp93, 0))
    tmp96 = tl.broadcast_to(tmp75, [RBLOCK])
    tmp98 = triton_helpers.promote_to_tensor(tl.sum(tmp96, 0))
    tmp99 = tmp83 / tmp11
    tmp100 = tmp99 * tmp7
    tmp101 = tl.broadcast_to(tmp100, [RBLOCK])
    tmp103 = triton_helpers.promote_to_tensor(tl.sum(tmp101, 0))
    tmp104 = triton_helpers.maximum(tmp89, tmp7)
    tmp105 = tmp104 + tmp95
    tmp106 = tmp105 / tmp104
    tmp107 = triton_helpers.maximum(tmp106, tmp13)
    tmp108 = triton_helpers.minimum(tmp107, tmp15)
    tmp109 = tmp108 * tmp1
    tmp111 = tmp110 + tmp20
    tmp112 = tl_math.log(tmp111)
    tmp113 = tmp109 * tmp112
    tmp114 = tmp113 * tmp86
    tmp115 = tmp108 - tmp7
    tmp116 = tmp109 / tmp115
    tmp117 = tmp7 - tmp110
    tmp118 = tmp117 + tmp20
    tmp119 = tl_math.log(tmp118)
    tmp120 = tmp116 * tmp119
    tmp121 = tmp120 * tmp92
    tmp122 = tmp114 + tmp121
    tmp123 = tl.broadcast_to(tmp122, [RBLOCK])
    tmp125 = triton_helpers.promote_to_tensor(tl.sum(tmp123, 0))
    tmp127 = tmp126 > tmp1
    tmp128 = tmp127.to(tl.float32)
    tmp129 = tl.broadcast_to(tmp128, [RBLOCK])
    tmp131 = triton_helpers.promote_to_tensor(tl.sum(tmp129, 0))
    tmp132 = triton_helpers.maximum(tmp131, tmp7)
    tmp133 = tmp9 / tmp132
    tmp134 = tmp133 * tmp11
    tmp135 = triton_helpers.maximum(tmp134, tmp13)
    tmp136 = triton_helpers.minimum(tmp135, tmp15)
    tmp137 = tmp136 * tmp1
    tmp138 = tmp137 * tmp128
    tmp140 = tmp139 + tmp20
    tmp141 = tl_math.log(tmp140)
    tmp142 = tmp138 * tmp141
    tmp143 = tmp136 - tmp7
    tmp144 = tmp137 / tmp143
    tmp145 = tmp7 - tmp128
    tmp146 = tmp144 * tmp145
    tmp147 = tmp7 - tmp139
    tmp148 = tmp147 + tmp20
    tmp149 = tl_math.log(tmp148)
    tmp150 = tmp146 * tmp149
    tmp151 = tmp142 + tmp150
    tmp152 = tl.broadcast_to(tmp151, [RBLOCK])
    tmp154 = triton_helpers.promote_to_tensor(tl.sum(tmp152, 0))
    tmp155 = tmp35 / tmp11
    tmp156 = -tmp155
    tmp157 = tmp154 / tmp11
    tmp158 = -tmp157
    tmp159 = tmp156 + tmp158
    tmp160 = tmp103 * tmp1
    tmp161 = tmp160 / tmp98
    tmp162 = -1.0
    tmp163 = tmp125 * tmp162
    tmp164 = tmp163 / tmp105
    tmp165 = tmp159 * tmp7
    tmp166 = 10.0
    tmp167 = tmp161 * tmp166
    tmp168 = tmp165 + tmp167
    tmp169 = tmp164 * tmp7
    tmp170 = tmp168 + tmp169
    tl.debug_barrier()
    tl.store(in_out_ptr2 + tl.full([1], 0, tl.int32), tmp159, None)
    tl.debug_barrier()
    tl.store(in_out_ptr1 + tl.full([1], 0, tl.int32), tmp161, None)
    tl.debug_barrier()
    tl.store(in_out_ptr3 + tl.full([1], 0, tl.int32), tmp164, None)
    tl.store(out_ptr12 + tl.full([1], 0, tl.int32), tmp170, None)


def call(args):
    arg0_1, arg1_1, arg2_1, arg3_1, arg4_1, arg5_1, arg6_1 = args
    args.clear()
    assert_size_stride(arg0_1, (4, 4, 4, 4), (64, 16, 4, 1))
    assert_size_stride(arg1_1, (4, 4, 4, 4), (64, 16, 4, 1))
    assert_size_stride(arg2_1, (4, 4, 4, 4), (64, 16, 4, 1))
    assert_size_stride(arg3_1, (4, 4, 4, 4), (64, 16, 4, 1))
    assert_size_stride(arg4_1, (4, 4, 4, 4), (64, 16, 4, 1))
    assert_size_stride(arg5_1, (4, 4, 4, 4), (64, 16, 4, 1))
    assert_size_stride(arg6_1, (4, 4, 4, 4), (64, 16, 4, 1))
    with torch.cuda._DeviceGuard(0):
        torch.cuda.set_device(0)
        buf11 = torch.ops.aten.rand.default([4, 4, 4, 4], dtype=torch.
            float32, device=device(type='cuda', index=0), pin_memory=False)
        buf12 = buf11
        del buf11
        buf7 = torch.ops.aten.rand.default([4, 4, 4, 4], dtype=torch.
            float32, device=device(type='cuda', index=0), pin_memory=False)
        buf8 = buf7
        del buf7
        buf2 = empty_strided_cuda((), (), torch.float32)
        buf14 = buf12
        del buf12
        buf15 = empty_strided_cuda((), (), torch.float32)
        buf16 = buf15
        del buf15
        buf22 = empty_strided_cuda((), (), torch.float32)
        buf6 = buf2
        del buf2
        buf18 = buf16
        del buf16
        buf23 = buf22
        del buf22
        buf24 = empty_strided_cuda((), (), torch.float32)
        get_raw_stream(0)
        triton_per_fused__to_copy_add_bitwise_and_clamp_clone_div_gt_le_log_mean_mse_loss_mul_neg_ones_like_reciprocal_rsub_sub_sum_0[
            grid(1)](buf14, buf18, buf6, buf23, arg4_1, arg3_1, arg1_1,
            arg2_1, buf8, arg0_1, arg6_1, arg5_1, buf24, 1, 256, num_warps=
            2, num_stages=1)
        del arg0_1
        del arg1_1
        del arg2_1
        del arg3_1
        del arg4_1
        del arg5_1
        del arg6_1
        del buf14
        del buf8
    return buf24, buf6, buf18, buf23


def binary_logistic_regression_loss(reg_score, label, threshold=0.5,
    ratio_range=(1.05, 21), eps=1e-05):
    """Binary Logistic Regression Loss."""
    label = label.view(-1)
    reg_score = reg_score.contiguous().view(-1)
    pmask = (label > threshold).float()
    num_positive = max(torch.sum(pmask), 1)
    num_entries = len(label)
    ratio = num_entries / num_positive
    ratio = min(max(ratio, ratio_range[0]), ratio_range[1])
    coef_0 = 0.5 * ratio / (ratio - 1)
    coef_1 = 0.5 * ratio
    loss = coef_1 * pmask * torch.log(reg_score + eps) + coef_0 * (1.0 - pmask
        ) * torch.log(1.0 - reg_score + eps)
    loss = -torch.mean(loss)
    return loss


class BMNLossNew(nn.Module):
    """BMN Loss.

    From paper https://arxiv.org/abs/1907.09702,
    code https://github.com/JJBOY/BMN-Boundary-Matching-Network.
    It will calculate loss for BMN Model. This loss is a weighted sum of

        1) temporal evaluation loss based on confidence score of start and
        end positions.
        2) proposal evaluation regression loss based on confidence scores of
        candidate proposals.
        3) proposal evaluation classification loss based on classification
        results of candidate proposals.
    """

    @staticmethod
    def tem_loss(pred_start, pred_end, gt_start, gt_end):
        """Calculate Temporal Evaluation Module Loss.

        This function calculate the binary_logistic_regression_loss for start
        and end respectively and returns the sum of their losses.

        Args:
            pred_start (torch.Tensor): Predicted start score by BMN model.
            pred_end (torch.Tensor): Predicted end score by BMN model.
            gt_start (torch.Tensor): Groundtruth confidence score for start.
            gt_end (torch.Tensor): Groundtruth confidence score for end.

        Returns:
            torch.Tensor: Returned binary logistic loss.
        """
        loss_start = binary_logistic_regression_loss(pred_start, gt_start)
        loss_end = binary_logistic_regression_loss(pred_end, gt_end)
        loss = loss_start + loss_end
        return loss

    @staticmethod
    def pem_reg_loss(pred_score, gt_iou_map, mask,
        high_temporal_iou_threshold=0.7, low_temporal_iou_threshold=0.3):
        """Calculate Proposal Evaluation Module Regression Loss.

        Args:
            pred_score (torch.Tensor): Predicted temporal_iou score by BMN.
            gt_iou_map (torch.Tensor): Groundtruth temporal_iou score.
            mask (torch.Tensor): Boundary-Matching mask.
            high_temporal_iou_threshold (float): Higher threshold of
                temporal_iou. Default: 0.7.
            low_temporal_iou_threshold (float): Higher threshold of
                temporal_iou. Default: 0.3.

        Returns:
            torch.Tensor: Proposal evaluation regression loss.
        """
        u_hmask = (gt_iou_map > high_temporal_iou_threshold).float()
        u_mmask = ((gt_iou_map <= high_temporal_iou_threshold) & (
            gt_iou_map > low_temporal_iou_threshold)).float()
        u_lmask = ((gt_iou_map <= low_temporal_iou_threshold) & (gt_iou_map >
            0.0)).float()
        u_lmask = u_lmask * mask
        num_h = torch.sum(u_hmask)
        num_m = torch.sum(u_mmask)
        num_l = torch.sum(u_lmask)
        r_m = num_h / num_m
        u_smmask = torch.rand_like(gt_iou_map)
        u_smmask = u_mmask * u_smmask
        u_smmask = (u_smmask > 1.0 - r_m).float()
        r_l = num_h / num_l
        u_slmask = torch.rand_like(gt_iou_map)
        u_slmask = u_lmask * u_slmask
        u_slmask = (u_slmask > 1.0 - r_l).float()
        weights = u_hmask + u_smmask + u_slmask
        loss = F.mse_loss(pred_score * weights, gt_iou_map * weights)
        loss = 0.5 * torch.sum(loss * torch.ones_like(weights)) / torch.sum(
            weights)
        return loss

    @staticmethod
    def pem_cls_loss(pred_score, gt_iou_map, mask, threshold=0.9,
        ratio_range=(1.05, 21), eps=1e-05):
        """Calculate Proposal Evaluation Module Classification Loss.

        Args:
            pred_score (torch.Tensor): Predicted temporal_iou score by BMN.
            gt_iou_map (torch.Tensor): Groundtruth temporal_iou score.
            mask (torch.Tensor): Boundary-Matching mask.
            threshold (float): Threshold of temporal_iou for positive
                instances. Default: 0.9.
            ratio_range (tuple): Lower bound and upper bound for ratio.
                Default: (1.05, 21)
            eps (float): Epsilon for small value. Default: 1e-5

        Returns:
            torch.Tensor: Proposal evaluation classification loss.
        """
        pmask = (gt_iou_map > threshold).float()
        nmask = (gt_iou_map <= threshold).float()
        nmask = nmask * mask
        num_positive = max(torch.sum(pmask), 1)
        num_entries = num_positive + torch.sum(nmask)
        ratio = num_entries / num_positive
        ratio = torch.clamp(ratio, ratio_range[0], ratio_range[1])
        coef_0 = 0.5 * ratio / (ratio - 1)
        coef_1 = 0.5 * ratio
        loss_pos = coef_1 * torch.log(pred_score + eps) * pmask
        loss_neg = coef_0 * torch.log(1.0 - pred_score + eps) * nmask
        loss = -1 * torch.sum(loss_pos + loss_neg) / num_entries
        return loss

    def forward(self, input_0, input_1, input_2, input_3, input_4, input_5,
        input_6):
        arg0_1 = input_0
        arg1_1 = input_1
        arg2_1 = input_2
        arg3_1 = input_3
        arg4_1 = input_4
        arg5_1 = input_5
        arg6_1 = input_6
        output = call([arg0_1, arg1_1, arg2_1, arg3_1, arg4_1, arg5_1, arg6_1])
        return output[0], output[1], output[2], output[3]
