from __future__ import annotations

from typing import Any, Optional

from typing_extensions import Literal

from ..._typing import Tensor
from ...framework import ParamAttr
from .. import Layer

Reduction = Literal["none", "sum", "mean"]
ReductionBatchMean = Literal[Reduction, "batchmean"]

class BCEWithLogitsLoss(Layer):
    weight: Any = ...
    reduction: Any = ...
    pos_weight: Any = ...
    name: Any = ...
    def __init__(
        self,
        weight: Optional[Tensor] = ...,
        reduction: Reduction = ...,
        pos_weight: Optional[Any] = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(self, logit: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class CrossEntropyLoss(Layer):
    weight: Any = ...
    reduction: Any = ...
    ignore_index: Any = ...
    soft_label: Any = ...
    axis: Any = ...
    use_softmax: Any = ...
    name: Any = ...
    def __init__(
        self,
        weight: Optional[Tensor] = ...,
        ignore_index: int = ...,
        reduction: Reduction = ...,
        soft_label: bool = ...,
        axis: int = ...,
        use_softmax: bool = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class HSigmoidLoss(Layer):
    weight: Any = ...
    bias: Any = ...
    def __init__(
        self,
        feature_size: int,
        num_classes: int,
        weight_attr: Optional[ParamAttr] = ...,
        bias_attr: Optional[ParamAttr | bool] = ...,
        is_custom: bool = ...,
        is_sparse: bool = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(
        self,
        input: Tensor,
        label: Tensor,
        path_table: Optional[Tensor] = ...,
        path_code: Optional[Tensor] = ...,
    ) -> Tensor: ...
    __call__ = forward

class MSELoss(Layer):
    reduction: Any = ...
    def __init__(self, reduction: Reduction = ...) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class L1Loss(Layer):
    reduction: Any = ...
    name: Any = ...
    def __init__(self, reduction: Reduction = ..., name: Optional[str] = ...) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class BCELoss(Layer):
    weight: Any = ...
    reduction: Any = ...
    name: Any = ...
    def __init__(
        self,
        weight: Optional[Tensor] = ...,
        reduction: Reduction = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class NLLLoss(Layer):
    def __init__(
        self,
        weight: Optional[Tensor] = ...,
        ignore_index: int = ...,
        reduction: Reduction = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class KLDivLoss(Layer):
    reduction: Any = ...
    def __init__(self, reduction: ReductionBatchMean = ...) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class MarginRankingLoss(Layer):
    margin: Any = ...
    reduction: Any = ...
    name: Any = ...
    def __init__(
        self,
        margin: float = ...,
        reduction: Reduction = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(self, input: Tensor, other: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class CTCLoss(Layer):
    blank: Any = ...
    reduction: Any = ...
    def __init__(self, blank: int = ..., reduction: Reduction = ...) -> None: ...
    def forward(
        self,
        log_probs: Tensor,
        labels: Tensor,
        input_lengths: Tensor,
        label_lengths: Tensor,
        norm_by_times: bool = ...,
    ) -> Tensor: ...
    __call__ = forward

class SmoothL1Loss(Layer):
    reduction: Any = ...
    delta: Any = ...
    name: Any = ...
    def __init__(
        self,
        reduction: Reduction = ...,
        delta: float = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward

class HingeEmbeddingLoss(Layer):
    margin: Any = ...
    reduction: Any = ...
    name: Any = ...
    def __init__(
        self,
        margin: float = ...,
        reduction: Reduction = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def forward(self, input: Tensor, label: Tensor) -> Tensor: ...
    __call__ = forward
