FW-GLM-5-1 · popcorn · pop_l123_st_gpt
correct 30_broadcast_masked_from_row0.py
model
FW-GLM-5-1
turns / max
1 / 1
tool calls
1
tokens (total)
12441
wall clock
346.4s
truncated
yes
backend
cuda fp32
variant
popcorn
runtime
0.01 μs
ref runtime
0.01 μs
speedup
1.10x
started
2026-05-11T09:52:31Z
timingkernelbench.timing
kernel runtime
0.01 μs
ref runtime
0.01 μs
speedup
1.10x
kernel mean / median / std
0.01 / — / 1.68e-04 μs
ref mean / median / std
0.01 / — / 7.42e-04 μs
numerical precisioneval_kernel_against_ref
max abs error
0.00
mean abs error
0.00
max rel error
0.00
mean rel error
0.00
gpu memoryextended_metrics.measure_memory
kernel peak
33.01 MB
ref peak
33.01 MB
kernel / ref
1.00x
kernel launches / fusiontorch.profiler
kernel launches
3
ref launches
11
fusion ratio (ref / kernel)
3.67x
total cuda time
62 μs
SOL (speed-of-light)nsight_hardware_counters
SOL score (0–1)
7.000e-04
dram util %
0.1%
compute util %
0.0%
bottleneck
unknown
dominant pipe
None
arithmetic intensity
—
ridge point
20.00
roofline / occupancynsight_hardware_counters
dram bandwidth
2.50 GB/s
dram util %
0.1%
fp32 tflops
—
fp32 util %
—
fp16 tflops
—
occupancy %
11.0%
bottleneck
unknown
dominant pipe %
—
arithmetic intensity
—
ridge point
20.00
L1 hit %
—
L2 hit %
98.7%
ld sectors / req
5.18
st sectors / req
—
regs / thread
32
smem / block
1024 B
block size
256
peak bw
3350.00 GB/s
peak fp32 tflops
67.00
peak fp16 tflops
1979.00
warp stalls (top 5)nsight
long_scoreboard
1231.8%
short_scoreboard
167.0%
reference PyTorch source (the prompt the agent sees)
"""
Simulated broadcast of row 0 into masked columns for all rows: where mask[j] is True,
every row matches x[0, j]; elsewhere keep x[b, j].
"""

import torch
import torch.nn as nn

from kernelbench.distributed_collectives import default_device

B = 18
D = 44

# Fixed mask (not all True, not all False)
_MASK = torch.tensor(
    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1],
    dtype=torch.bool,
)


class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.register_buffer("row_mask", _MASK.clone(), persistent=False)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        m = self.row_mask.to(device=x.device).view(1, D).expand(B, D)
        row0 = x[0:1].expand(B, D)
        return torch.where(m, row0, x)


def get_inputs():
    dev = default_device()
    return [torch.randn(popcorn_pri.jitter_int(B), D, device=dev)]


def get_init_inputs():
    return []
turn 0 · FINAL · 1 tool call(s) · 346.4s turn · 104.4s LLM · tokens in=1,187 · out=11,254 · total=12,441 · 20,089 chars (click to expand)
turn 0346.4s turn · 104.4s LLM · 242.0s tools · tokens in=1,187 · out=11,254 · total=12,441 · FINAL · reasoning clipped
reasoning
reasoning (truncated 22079 chars): Let me analyze this task: 1. The model takes an input tensor `x` of shape `(B, D)` where `B=18` and `D=44` 2. It has a fixed boolean mask `_MASK` of length `D=44` 3. The forward pass: - Creates a mask `m` of shape `(B, D)` by expanding the row_mask - Creates `row0` by expanding `x[0:1]` to shape `(B, D)` - Returns `torch.where(m, row0, x)` - which means for each position where mask is True, use value from row 0, otherwise use value from x So the output is: - For column j where mask[j] is True: all rows get x[0, j] - For column j where mask[j] is False: each row i gets x[i, j] This is a simple operation that can be optimized with a CUDA kernel. Let me write a kernel that: 1. Takes the input tensor x 2. Takes the mask 3. For each element, if mask[j] is True, output x[0, j], else output x[i, j] The key optimization here is to avoid the overhead of creating the expanded mask and expanded row0 tensors, and instead directly compute the result. Let me write the kernel: ```python import torch import torch.nn as nn from torch.utils.cpp_extension import load_inline # Define the CUDA kernel cuda_source = """ __global__ void masked_broadcast_kernel( const float* __restrict__ x, const bool* __restrict__ mask, float* __restrict__ output, int B, int D ) { int idx = blockIdx.x * blockDim.x + threadIdx.x; int total = B * D; if (idx < total) { int row = idx / D; int col = idx % D; if (mask[col]) { output[idx] = x[col]; // x[0, col] } else { output[idx] = x[idx]; // x[row, col] } } } torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask) { int B = x.size(0); int D = x.size(1); auto output = torch::empty_like(x); int total = B * D; int threads = 256; int blocks = (total + threads - 1) / threads; masked_broadcast_kernel<<<blocks, threads>>>( x.data_ptr<float>(), mask.data_ptr<bool>(), output.data_ptr<float>(), B, D ); return output; } """ cpp_source = """ torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask); """ # Load the extension masked_broadcast_extension = load_inline( name='masked_broadcast', cpp_sources=cpp_source, cuda_sources=cuda_source, functions=['masked_broadcast_cuda'], extra_cuda_cflags=['-O3'], ) B = 18 D = 44 _MASK = torch.tensor( [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1], dtype=torch.bool, ) class ModelNew(nn.Module): def __init__(self): super().__init__() self.register_buffer("row_mask", _MASK.clone(), persistent=False) def forward(self, x: torch.Tensor) -> torch.Tensor: return masked_broadcast_extension.masked_broadcast_cuda(x, self.row_mask) ``` Wait, let me think about optimization more carefully. The problem size is quite small (B=18, D=44, total=792 elements). This is a very small problem, so the overhead of kernel launch might be significant compared to the actual computation. Let me think about optimizations: 1. Use shared memory for the first row and mask - but with such small sizes, this might not help much 2. Coalesced memory access - we're accessing contiguous elements in memory, which is good 3. Vectorized loads/stores - could use float4 to load/store 4 elements at a time Actually, with such a small problem (792 elements), a single warp (32 threads) or even a single thread block could handle the entire problem. Let me think about this... Actually, the PyTorch reference creates several intermediate tensors: 1. `self.row_mask.to(device=x.device)` - moves mask to device (but it's already there probably) 2. `.view(1, D).expand(B, D)` - creates an expanded view (not a copy) 3. `x[0:1].expand(B, D)` - creates an expanded view (not a copy) 4. `torch.where(m, row0, x)` - this is where the actual computation happens The `torch.where` operation is essentially doing the same thing as my kernel. The question is whether my kernel can be faster. For such small sizes, the overhead of Python function calls and tensor operations might be significant. A custom kernel might be faster because it does everything in one kernel launch. Let me also consider if we can vectorize the loads/stores. Since D=44 is not a multiple of 4, we can't perfectly vectorize, but we can still use vectorized loads for most elements. Let me write an optimized version: ```python import torch import torch.nn as nn from torch.utils.cpp_extension import load_inline B = 18 D = 44 _MASK = torch.tensor( [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1], dtype=torch.bool, ) cuda_source = """ __global__ void masked_broadcast_kernel( const float* __restrict__ x, const bool* __restrict__ mask, float* __restrict__ output, int B, int D ) { const int total = B * D; int idx = blockIdx.x * blockDim.x + threadIdx.x; const int stride = blockDim.x * gridDim.x; // Process multiple elements per thread for better throughput for (int i = idx; i < total; i += stride) { const int row = i / D; const int col = i % D; // Use branch-free selection const float val = mask[col] ? x[col] : x[i]; output[i] = val; } } torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask) { TORCH_CHECK(x.dim() == 2, "Input must be 2D"); const int B = x.size(0); const int D = x.size(1); auto output = torch::empty_like(x); const int total = B * D; const int threads = 256; const int blocks = (total + threads - 1) / threads; masked_broadcast_kernel<<<blocks, threads>>>( x.data_ptr<float>(), mask.data_ptr<bool>(), output.data_ptr<float>(), B, D ); return output; } """ cpp_source = "torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask);" masked_broadcast_ext = load_inline( name='masked_broadcast_ext', cpp_sources=cpp_source, cuda_sources=cuda_source, functions=['masked_broadcast_cuda'], extra_cuda_cflags=['-O3', '--use_fast_math'], ) class ModelNew(nn.Module): def __init__(self): super().__init__() self.register_buffer("row_mask", _MASK.clone(), persistent=False) def forward(self, x: torch.Tensor) -> torch.Tensor: return masked_broadcast_ext.masked_broadcast_cuda(x, self.row_mask) ``` Actually, let me think more carefully. The problem is very small (792 elements). With 256 threads per block, we only need 4 blocks. The GPU will be severely underutilized. Let me consider a different approach - using shared memory to cache the mask and first row: ```python import torch import torch.nn as nn from torch.utils.cpp_extension import load_inline B = 18 D = 44 _MASK = torch.tensor( [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1], dtype=torch.bool, ) cuda_source = """ __global__ void masked_broadcast_kernel( const float* __restrict__ x, const bool* __restrict__ mask, float* __restrict__ output, int B, int D ) { // Shared memory for mask and first row extern __shared__ char smem[]; bool* s_mask = (bool*)smem; float* s_row0 = (float*)(smem + D * sizeof(bool)); // Load mask and first row into shared memory if (threadIdx.x < D) { s_mask[threadIdx.x] = mask[threadIdx.x]; s_row0[threadIdx.x] = x[threadIdx.x]; } __syncthreads(); // Process elements const int total = B * D; for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < total; i += blockDim.x * gridDim.x) { const int col = i % D; output[i] = s_mask[col] ? s_row0[col] : x[i]; } } torch::Tensor masked_broadcast ...[ omitted 22079 characters ]... tc. Within a warp of 32 threads: - Threads 0-31: access mask[0] to mask[31] - Threads 32-63: access mask[32] to mask[43] (11 threads) and mask[0] to mask[19] (21 threads) So there's some overlap within a warp. The mask values are being accessed by multiple threads, which could benefit from shared memory or L1 cache. Actually, L1 cache should handle this well. The mask is only 44 bytes, which fits easily in L1 cache. So shared memory might not provide much benefit. Let me stick with my current implementation and submit it. Actually, I want to add one more optimization - using `__ldg` for read-only memory access: ```cpp output[i] = mask[col] ? __ldg(&x[col]) : __ldg(&x[i]); ``` The `__ldg` intrinsic loads data through the read-only data cache (texture cache), which can be faster for data that is only read. However, `x` is used both for reading and potentially writing (via output), so using `__ldg` might not help much. Actually, output is a separate tensor, not x, so x is read-only. Let me try using `__ldg`: ```cpp output[i] = mask[col] ? __ldg(&x[col]) : __ldg(&x[i]); ``` But wait, I already have `const float* __restrict__ x`, which should already allow the compiler to use the read-only cache. So `__ldg` might not provide additional benefit. Let me just submit my current implementation: ```python import torch import torch.nn as nn from torch.utils.cpp_extension import load_inline B = 18 D = 44 _MASK = torch.tensor( [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1], dtype=torch.bool, ) cuda_source = """ __global__ void masked_broadcast_kernel( const float* __restrict__ x, const bool* __restrict__ mask, float* __restrict__ output, const int B, const int D ) { const int total = B * D; const int idx = blockIdx.x * blockDim.x + threadIdx.x; const int stride = blockDim.x * gridDim.x; for (int i = idx; i < total; i += stride) { const int col = i % D; output[i] = mask[col] ? x[col] : x[i]; } } torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask) { const int B = x.size(0); const int D = x.size(1); auto output = torch::empty_like(x); const int total = B * D; const int threads = 256; const int blocks = (total + threads - 1) / threads; masked_broadcast_kernel<<<blocks, threads>>>( x.data_ptr<float>(), mask.data_ptr<bool>(), output.data_ptr<float>(), B, D ); return output; } """ cpp_source = "torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask);" masked_broadcast_ext = load_inline( name='masked_broadcast_ext', cpp_sources=cpp_source, cuda_sources=cuda_source, functions=['masked_broadcast_cuda'], extra_cuda_cflags=['-O3'], ) class ModelNew(nn.Module): def __init__(self): super().__init__() self.register_buffer("row_mask", _MASK.clone(), persistent=False) def forward(self, x: torch.Tensor) -> torch.Tensor: return masked_broadcast_ext.masked_broadcast_cuda(x, self.row_mask) ``` Let me submit this. Hmm, actually I want to try one more thing - using float4 for vectorized memory access. Let me write a version that processes 4 elements at a time: Actually, since D=44 is not a multiple of 4, handling the edge cases would add complexity. And the total size (792) is so small that vectorization might not provide much benefit. Let me just submit my current implementation. Actually, wait. I realized I should use `torch.zeros` or `torch.empty` instead of `torch.tensor` for the mask if I want it on GPU. But since the mask is registered as a buffer and will be moved to GPU when the model is moved, this should be fine. Let me also double-check the mask values: ``` [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1] ``` This is 44 values, which matches D=44. Good. OK, let me submit the implementation. Actually, one more thought - the `extern "C"` wrapper is not needed when using `load_inline` because it handles the function bindings automatically. Let me make sure my code is correct. The `functions` parameter in `load_inline` specifies the function names to expose. My function is `masked_broadcast_cuda`, which is correct. OK, I'm confident in my implementation. Let me submit it. Wait, I should also handle the case where the input might be on a different device than the mask. Let me add a `.to()` call: ```python def forward(self, x: torch.Tensor) -> torch.Tensor: mask = self.row_mask.to(device=x.device) return masked_broadcast_ext.masked_broadcast_cuda(x, mask) ``` Actually, looking at the reference code, it does `.to(device=x.device)` on the mask. So I should do the same to be safe. But wait, the `.to()` call might add overhead. Let me check if the mask is already on the same device... In PyTorch, when you register a buffer with `register_buffer`, it gets moved to the same device as the model when you call `.to(device)` or `.cuda()` on the model. So the mask should be on the same device as the model. But the input `x` might be on a different device than the model. In that case, we need to move the mask to the device of `x`. To match the reference behavior exactly, let me add the `.to()` call: ```python def forward(self, x: torch.Tensor) -> torch.Tensor: mask = self.row_mask.to(device=x.device) return masked_broadcast_ext.masked_broadcast_cuda(x, mask) ``` This ensures the mask is on the same device as the input, which matches the reference behavior. OK, let me submit the final implementation. Actually, I want to add a CUDA stream synchronization to ensure the kernel is complete before returning. But PyTorch handles this automatically when you return a tensor - the tensor is not "ready" until the kernel completes, but you can still use it in subsequent operations. So no explicit synchronization is needed. Let me submit: ```python import torch import torch.nn as nn from torch.utils.cpp_extension import load_inline B = 18 D = 44 _MASK = torch.tensor( [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1], dtype=torch.bool, ) cuda_source = """ __global__ void masked_broadcast_kernel( const float* __restrict__ x, const bool* __restrict__ mask, float* __restrict__ output, const int B, const int D ) { const int total = B * D; const int idx = blockIdx.x * blockDim.x + threadIdx.x; const int stride = blockDim.x * gridDim.x; for (int i = idx; i < total; i += stride) { const int col = i % D; output[i] = mask[col] ? x[col] : x[i]; } } torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask) { const int B = x.size(0); const int D = x.size(1); auto output = torch::empty_like(x); const int total = B * D; const int threads = 256; const int blocks = (total + threads - 1) / threads; masked_broadcast_kernel<<<blocks, threads>>>( x.data_ptr<float>(), mask.data_ptr<bool>(), output.data_ptr<float>(), B, D ); return output; } """ cpp_source = "torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask);" masked_broadcast_ext = load_inline( name='masked_broadcast_ext', cpp_sources=cpp_source, cuda_sources=cuda_source, functions=['masked_broadcast_cuda'], extra_cuda_cflags=['-O3'], ) class ModelNew(nn.Module): def __init__(self): super().__init__() self.register_buffer("row_mask", _MASK.clone(), persistent=False) def forward(self, x: torch.Tensor) -> torch.Tensor: mask = self.row_mask.to(device=x.device) return masked_broadcast_ext.masked_broadcast_cuda(x, mask) ``` This is my final implementation. Let me submit it.
call → submit_kernel
callsubmit_kernel { "kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\nB = 18\nD = 44\n\n_MASK = torch.tensor(\n [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1],\n dtype=torch.bool,\n)\n\ncuda_source = \"\"\"\n__global__ void masked_broadcast_kernel(\n const float* __restrict__ x,\n const bool* __restrict__ mask,\n float* __restrict__ output,\n const int B, const int D\n) {\n const int total = B * D;\n const int idx = blockIdx.x * blockDim.x + threadIdx.x;\n const int stride = blockDim.x * gridDim.x;\n \n for (int i = idx; i < total; i += stride) {\n const int col = i % D;\n output[i] = mask[col] ? x[col] : x[i];\n }\n}\n\ntorch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask) {\n const int B = x.size(0);\n const int D = x.size(1);\n \n auto output = torch::empty_like(x);\n \n const int total = B * D;\n const int threads = 256;\n const int blocks = (total + threads - 1) / threads;\n \n masked_broadcast_kernel<<<blocks, threads>>>(\n x.data_ptr<float>(),\n mask.data_ptr<bool>(),\n output.data_ptr<float>(),\n B, D\n );\n \n return output;\n}\n\"\"\"\n\ncpp_source = \"torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask);\"\n\nmasked_broadcast_ext = load_inline(\n name='masked_broadcast_ext',\n cpp_sources=cpp_source,\n cuda_sources=cuda_source,\n functions=['masked_broadcast_cuda'],\n extra_cuda_cflags=['-O3'],\n)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super().__init__()\n self.register_buffer(\"row_mask\", _MASK.clone(), persistent=False)\n \n def forward(self, x: torch.Tensor) -> torch.Tensor:\n mask = self.row_mask.to(device=x.device)\n return masked_broadcast_ext.masked_broadcast_cuda(x, mask)\n\n\ndef get_inputs():\n from kernelbench.distributed_collectives import default_device\n dev = default_device()\n g = torch.Generator(device=dev)\n g.manual_seed(13)\n return [torch.randn(B, D, device=dev, generator=g)]\n\n\ndef get_init_inputs():\n return []" }
result ← submit_kernel (ok)
oksubmit_kernel submit_kernel PASSED: (5 / 5) correctness trials all passed. Kernel runtime: 0.01 μs Runtime stats: mean=0.01μs median=?μs std=0.00μs Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00 Memory: 33.01 MB peak (ref: 33.01 MB, ratio: 1.0x) Kernel launches: 3 (ref: 11, fusion ratio: 3.6667) SOL score: 0.0007
final submitted kernel (80 lines, 2,137 chars) — full source, untruncated
import torch
import torch.nn as nn
from torch.utils.cpp_extension import load_inline

B = 18
D = 44

_MASK = torch.tensor(
    [1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1],
    dtype=torch.bool,
)

cuda_source = """
__global__ void masked_broadcast_kernel(
    const float* __restrict__ x,
    const bool* __restrict__ mask,
    float* __restrict__ output,
    const int B, const int D
) {
    const int total = B * D;
    const int idx = blockIdx.x * blockDim.x + threadIdx.x;
    const int stride = blockDim.x * gridDim.x;
    
    for (int i = idx; i < total; i += stride) {
        const int col = i % D;
        output[i] = mask[col] ? x[col] : x[i];
    }
}

torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask) {
    const int B = x.size(0);
    const int D = x.size(1);
    
    auto output = torch::empty_like(x);
    
    const int total = B * D;
    const int threads = 256;
    const int blocks = (total + threads - 1) / threads;
    
    masked_broadcast_kernel<<<blocks, threads>>>(
        x.data_ptr<float>(),
        mask.data_ptr<bool>(),
        output.data_ptr<float>(),
        B, D
    );
    
    return output;
}
"""

cpp_source = "torch::Tensor masked_broadcast_cuda(torch::Tensor x, torch::Tensor mask);"

masked_broadcast_ext = load_inline(
    name='masked_broadcast_ext',
    cpp_sources=cpp_source,
    cuda_sources=cuda_source,
    functions=['masked_broadcast_cuda'],
    extra_cuda_cflags=['-O3'],
)

class ModelNew(nn.Module):
    def __init__(self):
        super().__init__()
        self.register_buffer("row_mask", _MASK.clone(), persistent=False)
    
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        mask = self.row_mask.to(device=x.device)
        return masked_broadcast_ext.masked_broadcast_cuda(x, mask)


def get_inputs():
    from kernelbench.distributed_collectives import default_device
    dev = default_device()
    g = torch.Generator(device=dev)
    g.manual_seed(13)
    return [torch.randn(B, D, device=dev, generator=g)]


def get_init_inputs():
    return []