Kernels
drbh HF Staff commited on
Commit
974cb16
·
verified ·
1 Parent(s): 4a365cf

fix: update bench to produce timing

Browse files
Files changed (1) hide show
  1. benchmark.py +78 -21
benchmark.py CHANGED
@@ -5,20 +5,43 @@
5
  # "kernels"
6
  # ]
7
  # ///
 
 
 
 
8
  import torch
9
  from kernels import get_kernel
10
 
11
- # Setup
12
- torch.manual_seed(42)
13
- activation = get_kernel("kernels-community/activation")
14
- device = torch.device("cuda")
15
 
16
- # Create test tensor for SwiGLU (SiLU and Mul)
17
- # Input has shape (num_tokens, 2 * hidden_dim)
18
- num_tokens, hidden_dim = 128, 512
19
- input_tensor = torch.randn(
20
- num_tokens, 2 * hidden_dim, device=device, dtype=torch.float16
21
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
 
24
  # Reference implementation: SwiGLU computes silu(x[:d]) * x[d:]
@@ -27,16 +50,50 @@ def reference_silu_and_mul(x):
27
  return torch.nn.functional.silu(x[..., :d]) * x[..., d:]
28
 
29
 
30
- out_ref = reference_silu_and_mul(input_tensor)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- # Custom kernel SwiGLU
33
- out_shape = input_tensor.shape[:-1] + (hidden_dim,)
34
- out_kernel = torch.empty(out_shape, dtype=input_tensor.dtype, device=device)
35
- out_kernel = activation.silu_and_mul(out_kernel, input_tensor)
36
 
37
- print(f"Reference output: {out_ref.shape}")
38
- print(f"Kernel output: {out_kernel.shape}")
39
- print(f"Outputs close: {torch.allclose(out_kernel, out_ref, atol=1e-3, rtol=1e-3)}")
40
- # Reference output: torch.Size([128, 512])
41
- # Kernel output: torch.Size([128, 512])
42
- # Outputs close: True
 
5
  # "kernels"
6
  # ]
7
  # ///
8
+ import argparse
9
+ import json
10
+ import time
11
+
12
  import torch
13
  from kernels import get_kernel
14
 
 
 
 
 
15
 
16
+ def run_benchmark(kernel_fn, out_tensor, input_tensor, iterations: int, warmup: int) -> dict:
17
+ """Benchmark a kernel function."""
18
+
19
+ # Warmup phase (not measured)
20
+ for _ in range(warmup):
21
+ kernel_fn(out_tensor, input_tensor)
22
+ torch.cuda.synchronize()
23
+
24
+ # Benchmark phase
25
+ times_ms = []
26
+ for _ in range(iterations):
27
+ start = time.perf_counter()
28
+ kernel_fn(out_tensor, input_tensor)
29
+ torch.cuda.synchronize()
30
+ end = time.perf_counter()
31
+ times_ms.append((end - start) * 1000)
32
+
33
+ # Calculate statistics
34
+ mean_ms = sum(times_ms) / len(times_ms)
35
+ variance = sum((t - mean_ms) ** 2 for t in times_ms) / len(times_ms)
36
+ std_ms = variance ** 0.5
37
+
38
+ return {
39
+ "mean_ms": round(mean_ms, 4),
40
+ "std_ms": round(std_ms, 4),
41
+ "min_ms": round(min(times_ms), 4),
42
+ "max_ms": round(max(times_ms), 4),
43
+ "iterations": iterations,
44
+ }
45
 
46
 
47
  # Reference implementation: SwiGLU computes silu(x[:d]) * x[d:]
 
50
  return torch.nn.functional.silu(x[..., :d]) * x[..., d:]
51
 
52
 
53
+ def main():
54
+ parser = argparse.ArgumentParser(description="Benchmark activation kernel")
55
+ parser.add_argument("--iterations", type=int, default=100, help="Number of iterations")
56
+ parser.add_argument("--warmup", type=int, default=10, help="Number of warmup iterations")
57
+ args = parser.parse_args()
58
+
59
+ # Setup
60
+ torch.manual_seed(42)
61
+ activation = get_kernel("kernels-community/activation")
62
+ device = torch.device("cuda")
63
+
64
+ # Create test tensor for SwiGLU (SiLU and Mul)
65
+ # Input has shape (num_tokens, 2 * hidden_dim)
66
+ num_tokens, hidden_dim = 128, 512
67
+ input_tensor = torch.randn(
68
+ num_tokens, 2 * hidden_dim, device=device, dtype=torch.float16
69
+ )
70
+
71
+ # Reference output for correctness check
72
+ out_ref = reference_silu_and_mul(input_tensor)
73
+
74
+ # Custom kernel SwiGLU
75
+ out_shape = input_tensor.shape[:-1] + (hidden_dim,)
76
+ out_kernel = torch.empty(out_shape, dtype=input_tensor.dtype, device=device)
77
+ out_kernel = activation.silu_and_mul(out_kernel, input_tensor)
78
+
79
+ # Correctness check
80
+ print(f"Reference output: {out_ref.shape}")
81
+ print(f"Kernel output: {out_kernel.shape}")
82
+ print(f"Outputs close: {torch.allclose(out_kernel, out_ref, atol=1e-3, rtol=1e-3)}")
83
+
84
+ # Run benchmark
85
+ timing_results = run_benchmark(
86
+ activation.silu_and_mul,
87
+ out_kernel,
88
+ input_tensor,
89
+ args.iterations,
90
+ args.warmup
91
+ )
92
+
93
+ # Output JSON to stdout (required protocol)
94
+ output = {"timing_results": timing_results}
95
+ print(json.dumps(output))
96
 
 
 
 
 
97
 
98
+ if __name__ == "__main__":
99
+ main()