@unittest.skipUnless(os.getenv('BENCHMARK_TESTS', ''), 'no benchmarks')
def test_small_benchmark(self):
    N = 12
    H = 8
    L = 1000
    E = 32
    S = 1000
    k = 32
    C = 100
    I = 10
    B = 32
    Q = torch.randn(N, H, L, E).to(self.device)
    K = torch.randn(N, H, S, E).to(self.device)
    lengths = torch.full((N,), L).int().to(self.device)
    (groups, counts) = cluster_queries(Q, lengths, C, I, B)
    Q_grouped = aggregate(Q, groups, (1 / counts.float()))
    QK = torch.einsum('nhle,nhse->nhls', Q_grouped, K)
    (_, topk) = torch.topk(QK, k, dim=(- 1))
    topk = topk.contiguous()
    products = torch.zeros((N, H, L, k), dtype=torch.float32).to(self.device)
    products = clustered_sparse_dot_product(Q, K, topk, groups, counts, lengths)
    for i in range(1000):
        products = clustered_sparse_dot_product(Q, K, topk, groups, counts, lengths)
    torch.cuda.synchronize()
    s = torch.cuda.Event(enable_timing=True)
    e = torch.cuda.Event(enable_timing=True)
    s.record()
    products = clustered_sparse_dot_product(Q, K, topk, groups, counts, lengths)
    e.record()
    torch.cuda.synchronize()
    t_sc = s.elapsed_time(e)
    topk_broadcast = broadcast(topk.float(), groups, torch.ones_like(counts, dtype=torch.float32), torch.zeros((N, H, L, k), device=Q.device))
    for i in range(1000):
        products = sparse_dot_product(Q, K, topk_broadcast.long())
    torch.cuda.synchronize()
    s = torch.cuda.Event(enable_timing=True)
    e = torch.cuda.Event(enable_timing=True)
    s.record()
    products_s = sparse_dot_product(Q, K, topk_broadcast.long())
    e.record()
    torch.cuda.synchronize()
    t_s = s.elapsed_time(e)
    for i in range(1000):
        torch.einsum('nhle,nhse->nhls', Q, K)
    s = torch.cuda.Event(enable_timing=True)
    e = torch.cuda.Event(enable_timing=True)
    s.record()
    torch.einsum('nhle,nhse->nhls', Q, K)
    e.record()
    torch.cuda.synchronize()
    t_f = s.elapsed_time(e)
    print('Sparse_Clustered: {}, Sparse: {}, Full: {}'.format(t_sc, t_s, t_f))
@unittest.skipUnless(os.getenv('BENCHMARK_TESTS', ), 'no benchmarks')
def test_small_benchmark(self):
    N = 12
    H = 8
    L = 1000
    E = 32
    S = 1000
    k = 32
    C = 100
    I = 10
    B = 32
    Q = torch.randn(N, H, L, E).to(self.device)
    K = torch.randn(N, H, S, E).to(self.device)
    lengths = torch.full((N,), L).int().to(self.device)
    (groups, counts) = cluster_queries(Q, lengths, C, I, B)
    Q_grouped = aggregate(Q, groups, (1 / counts.float()))
    QK = torch.einsum('nhle,nhse->nhls', Q_grouped, K)
    (_, topk) = torch.topk(QK, k, dim=(- 1))
    topk = topk.contiguous()
    products = torch.zeros((N, H, L, k), dtype=torch.float32).to(self.device)
    products = clustered_sparse_dot_product(Q, K, topk, groups, counts, lengths)
    for i in range(1000):
        products = clustered_sparse_dot_product(Q, K, topk, groups, counts, lengths)
    torch.cuda.synchronize()
    s = torch.cuda.Event(enable_timing=True)
    e = torch.cuda.Event(enable_timing=True)
    s.record()
    products = clustered_sparse_dot_product(Q, K, topk, groups, counts, lengths)
    e.record()
    torch.cuda.synchronize()
    t_sc = s.elapsed_time(e)
    topk_broadcast = broadcast(topk.float(), groups, torch.ones_like(counts, dtype=torch.float32), torch.zeros((N, H, L, k), device=Q.device))
    for i in range(1000):
        products = sparse_dot_product(Q, K, topk_broadcast.long())
    torch.cuda.synchronize()
    s = torch.cuda.Event(enable_timing=True)
    e = torch.cuda.Event(enable_timing=True)
    s.record()
    products_s = sparse_dot_product(Q, K, topk_broadcast.long())
    e.record()
    torch.cuda.synchronize()
    t_s = s.elapsed_time(e)
    for i in range(1000):
        torch.einsum('nhle,nhse->nhls', Q, K)
    s = torch.cuda.Event(enable_timing=True)
    e = torch.cuda.Event(enable_timing=True)
    s.record()
    torch.einsum('nhle,nhse->nhls', Q, K)
    e.record()
    torch.cuda.synchronize()
    t_f = s.elapsed_time(e)
    print('Sparse_Clustered: {}, Sparse: {}, Full: {}'.format(t_sc, t_s, t_f))