import torch


def project_filter(W, p):
    """
    Projects weights W to S={w: #filters(w) <= p%}

    Parameters
    ----------
    W: torch.Tensor
        The weight matrix
    p: float
        Percent of weights to prune. 0<=p<=100

    Returns
    -------
    Z: torch.Tensor
        Pruned weight matrix (detached)
    mask: torch.Tensor
        A boolean mask of pruned weights
    """
    N = W.shape[0]
    Z = W.clone().detach()
    Z = Z.view(N, -1)
    M = Z.shape[1]

    nz = torch.norm(Z, dim=1)
    p = int(p * nz.numel()) // 100
    v, _ = torch.kthvalue(nz, p)
    mask = (nz <= v).view(-1, 1).repeat(1, M)

    Z[mask] = 0
    Z = Z.view(W.shape)
    mask = mask.view(W.shape)
    return Z, mask