correct
12_Matmul_with_diagonal_matrices_.py
started
2026-05-02T17:21:29Z
timingkernelbench.timing
kernel mean / median / std
0.05 / — / 6.03e-04 μs
ref mean / median / std
0.06 / — / 7.46e-04 μs
numerical precisioneval_kernel_against_ref
gpu memoryextended_metrics.measure_memory
kernel launches / fusiontorch.profiler
fusion ratio (ref / kernel)
1.50x
SOL (speed-of-light)nsight_hardware_counters
roofline / occupancynsight_hardware_counters
dram bandwidth
2609.78 GB/s
warp stalls (top 5)nsight
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn
class Model(nn.Module):
"""
Simple model that performs a matrix multiplication of a diagonal matrix with another matrix.
C = diag(A) * B
"""
def __init__(self):
super(Model, self).__init__()
def forward(self, A, B):
"""
Performs the matrix multiplication.
Args:
A (torch.Tensor): A 1D tensor representing the diagonal of the diagonal matrix. Shape: (N,).
B (torch.Tensor): A 2D tensor representing the second matrix. Shape: (N, M).
Returns:
torch.Tensor: The result of the matrix multiplication. Shape: (N, M).
"""
# Logically equivalent to torch.diag(A) @ B
# more efficient as no need to materialize a full N×N matrix
return A.unsqueeze(1) * B
M = 4096
N = 4096
def get_inputs():
A = torch.rand(N)
B = torch.rand(N, M)
return [A, B]
def get_init_inputs():
return [] # No special initialization inputs neededturn 04.4s turn · 4.4s LLM · 0.0s tools
reasoning
**Optimizing code for scaling**
I need to produce code that optimizes element-wise row scaling for a 4096x4096 fp32 matrix. I’m thinking of using PyTorch's A.unsqueeze() and B as a fast torch mul kernel reference. Maybe I could implement a custom solution with vectorized float4. I need to define ModelNew without arguments and utilize load_inline. Lastly, I should gather the specifications before proceeding. It feels a bit complex, but I’m committed to getting this right!
call → get_gpu_specs
callget_gpu_specs
{}
result ← get_gpu_specs (ok)
okget_gpu_specs
GPU specs for NVIDIA H100 80GB HBM3:
total memory (runtime): 79.1 GB
spec entry: H100
GPU Architecture: Hopper
GPU Memory: 80GB
Memory Bandwidth: 3.35 TB/s
FP64 TFLOPS: 34
FP64 Tensor Core TFLOPS: 67
FP32 TFLOPS: 67
TF32 Tensor Core TFLOPS: 989 with sparsity
BFLOAT16 Tensore Core TFLOPS: 1979 with sparsity
FP16 Tensor Core TFLOPS: 1979 with sparsity
FP8 Tensor Core TFLOPS: 3958 with sparsity
INT8 Tensor Core TOPS: 3958 with sparsity
Register File Size: 64K 32-bit registers per SM
Maximum number of registers per thread: 255
Maximum number of thread blocks per SM: 32
Shared memory capacity per SM: 228 KB
Maximum shared memory per thread block: 227 KB
turn 1 · 1 tool call(s) · 13.1s turn · 13.1s LLM · 6,628 chars (click to expand)
turn 113.1s turn · 13.1s LLM · 0.0s tools
call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r\"\"\"\n#include <torch/extension.h>\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B);\n\"\"\"\n\ncuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void row_scale_vec4_kernel(const float* __restrict__ A,\n const float4* __restrict__ B4,\n float4* __restrict__ C4,\n int M4) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M4;\n for (int j = threadIdx.x; j < M4; j += blockDim.x) {\n float4 b = B4[base + j];\n b.x *= a; b.y *= a; b.z *= a; b.w *= a;\n C4[base + j] = b;\n }\n}\n\n__global__ void row_scale_scalar_kernel(const float* __restrict__ A,\n const float* __restrict__ B,\n float* __restrict__ C,\n int M) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M;\n for (int col = threadIdx.x; col < M; col += blockDim.x) {\n C[base + col] = a * B[base + col];\n }\n}\n\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B) {\n auto C = torch::empty_like(B);\n const int64_t N64 = B.size(0);\n const int64_t M64 = B.size(1);\n const int N = (int)N64;\n const int M = (int)M64;\n const int threads = 256;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if ((M & 3) == 0) {\n int M4 = M >> 2;\n row_scale_vec4_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(),\n reinterpret_cast<const float4*>(B.data_ptr<float>()),\n reinterpret_cast<float4*>(C.data_ptr<float>()),\n M4);\n } else {\n row_scale_scalar_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(), B.data_ptr<float>(), C.data_ptr<float>(), M);\n }\n return C;\n}\n\"\"\"\n\n_ext = load_inline(name=\"diag_mul_ext_v1\",\n cpp_sources=[cpp_src],\n cuda_sources=[cuda_src],\n functions=[\"diag_mul_cuda\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super(ModelNew, self).__init__()\n def forward(self, A, B):\n return _ext.diag_mul_cuda(A, B)\n"
}
result ← compile_kernel (fail)
failcompile_kernel
compile_kernel FAILED: RuntimeError.
RuntimeError: Error building extension 'diag_mul_ext_v1': [1/3] /opt/conda/bin/x86_64-conda-linux-gnu-c++ -MMD -MF main.o.d -DTORCH_EXTENSION_NAME=diag_mul_ext_v1 -DTORCH_API_INCLUDE_EXTENSION_H -isystem /scratch/tejas/PopcornBench/.venv/lib/python3.10/site-packages/torch/include -isystem /scratch/tejas/PopcornBench/.venv/lib/python3.10/site-packages/torch/include/torch/csrc/api/include -isystem /usr/local/cuda/include -isystem /home/prabhune/.local/share/uv/python/cpython-3.10-linux-x86_64-gnu/include/python3.10 -fPIC -std=c++17 -O3 -c /scratch/tejas/PopcornBench/runs/l12_default/original/gpt-5.5-priority/level_1_problem_12_cache/k_be326478034a/diag_mul_ext_v1/main.cpp -o main.o
[2/3] /usr/local/cuda/bin/nvcc -MD -MF cuda.cuda.o.d -ccbin /opt/conda/bin/x86_64-conda-linux-gnu-cc -DTORCH_EXTENSION_NAME=diag_mul_ext_v1 -DTORCH_API_INCLUDE_EXTENSION_H -isystem /scratch/tejas/PopcornBench/.venv/lib/python3.10/site-packages/torch/include -isystem /scratch/tejas/PopcornBench/.venv/lib/python3.10/site-packages/torch/include/torch/csrc/api/include -isystem /usr/local/cuda/include -isystem /home/prabhune/.local/share/uv/python/cpython-3.10-linux-x86_64-gnu/include/python3.10 -D__CUDA_NO_HALF_OPERATORS__ -D__CUDA_NO_HALF_CONVERSIONS__ -D__CUDA_NO_BFLOAT16_CONVERSIONS__ -D__CUDA_NO_HALF2_OPERATORS__ --expt-relaxed-constexpr -gencode=arch=compute_90,code=compute_90 -gencode=arch=compute_90,code=sm_90 --compiler-options '-fPIC' -O3 --use_fast_math -std=c++17 -c /scratch/tejas/PopcornBench/runs/l12_default/original/gpt-5.5-priority/level_1_problem_12_cache/k_be326478034a/diag_mul_ext_v1/cuda.cu -o cuda.cuda.o
FAILED: [code=2] cuda.cuda.o
/usr/local/cuda/bin/nvcc -MD -MF cuda.cuda.o.d -ccbin /opt/conda/bin/x86_64-conda-linux-gnu-cc -DTORCH_EXTENSION_NAME=diag_mul_ext_v1 -DTORCH_API_INCLUDE_EXTENSION_H -isystem /scratch/tejas/PopcornBench/.venv/lib/python3.10/site-packages/torch/include -isystem /scratch/tejas/PopcornBench/.venv/lib/python3.10/site-packages/torch/include/torch/csrc/api/include -isystem /usr/local/cuda/include -isystem /home/prabhune/.local/share/uv/python/cpython-3.10-linux-x86_64-gnu/include/python3.10 -D__CUDA_NO_HALF_OPERATORS__ -D__CUDA_NO_HALF_CONVERSIONS__ -D__CUDA_NO_BFLOAT16_CONVERSIONS__ -D__CUDA_NO_HALF2_OPERATORS__ --expt-relaxed-constexpr -gencode=arch=compute_90,code=compute_90 -gencode=arch=compute_90,code=sm_90 --compiler-options '-fPIC' -O3 --use_fast_math -std=c++17 -c /scratch/tejas/PopcornBench/runs/l12_default/original/gpt-5.5-priority/level_1_problem_12_cache/k_be326478034a/diag_mul_ext_v1/cuda.cu -o cuda.cuda.o
nvcc warning : incompatible redefinition for option 'compiler-bindir', the last value of this option was used
/scratch/tejas/PopcornBench/runs/l12_default/original/gpt-5.5-priority/level_1_problem_12_cache/k_be326478034a/diag_mul_ext_v1/cuda.cu(42): error: namespace "at::cuda" has no member "getCurrentCUDAStream"
cudaStream_t stream = at::cuda::getCurrentCUDAStream();
^
1 error detected in the compilation of "/scratch/tejas/PopcornBench/runs/l12_default/original/gpt-5.5-priority/level_1_problem_12_cache/k_be326478034a/diag_mul_ext_v1/cuda.cu".
ninja: build stopped: subcommand failed.
turn 25.5s turn · 5.5s LLM · 0.0s tools
call → compile_kernel
callcompile_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r\"\"\"\n#include <torch/extension.h>\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B);\n\"\"\"\n\ncuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void row_scale_vec4_kernel(const float* __restrict__ A,\n const float4* __restrict__ B4,\n float4* __restrict__ C4,\n int M4) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M4;\n for (int j = threadIdx.x; j < M4; j += blockDim.x) {\n float4 b = B4[base + j];\n b.x *= a; b.y *= a; b.z *= a; b.w *= a;\n C4[base + j] = b;\n }\n}\n\n__global__ void row_scale_scalar_kernel(const float* __restrict__ A,\n const float* __restrict__ B,\n float* __restrict__ C,\n int M) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M;\n for (int col = threadIdx.x; col < M; col += blockDim.x) {\n C[base + col] = a * B[base + col];\n }\n}\n\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B) {\n auto C = torch::empty_like(B);\n const int N = (int)B.size(0);\n const int M = (int)B.size(1);\n const int threads = 256;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if ((M & 3) == 0) {\n int M4 = M >> 2;\n row_scale_vec4_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(),\n reinterpret_cast<const float4*>(B.data_ptr<float>()),\n reinterpret_cast<float4*>(C.data_ptr<float>()),\n M4);\n } else {\n row_scale_scalar_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(), B.data_ptr<float>(), C.data_ptr<float>(), M);\n }\n return C;\n}\n\"\"\"\n\n_ext = load_inline(name=\"diag_mul_ext_v2\",\n cpp_sources=[cpp_src],\n cuda_sources=[cuda_src],\n functions=[\"diag_mul_cuda\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super(ModelNew, self).__init__()\n def forward(self, A, B):\n return _ext.diag_mul_cuda(A, B)\n"
}
result ← compile_kernel (ok)
okcompile_kernel
compile_kernel PASSED: kernel compiled without errors.
turn 38.1s turn · 8.1s LLM · 0.0s tools
call → run_correctness
callrun_correctness
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r\"\"\"\n#include <torch/extension.h>\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B);\n\"\"\"\n\ncuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void row_scale_vec4_kernel(const float* __restrict__ A,\n const float4* __restrict__ B4,\n float4* __restrict__ C4,\n int M4) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M4;\n for (int j = threadIdx.x; j < M4; j += blockDim.x) {\n float4 b = B4[base + j];\n b.x *= a; b.y *= a; b.z *= a; b.w *= a;\n C4[base + j] = b;\n }\n}\n\n__global__ void row_scale_scalar_kernel(const float* __restrict__ A,\n const float* __restrict__ B,\n float* __restrict__ C,\n int M) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M;\n for (int col = threadIdx.x; col < M; col += blockDim.x) {\n C[base + col] = a * B[base + col];\n }\n}\n\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B) {\n auto C = torch::empty_like(B);\n const int N = (int)B.size(0);\n const int M = (int)B.size(1);\n const int threads = 256;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if ((M & 3) == 0) {\n int M4 = M >> 2;\n row_scale_vec4_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(),\n reinterpret_cast<const float4*>(B.data_ptr<float>()),\n reinterpret_cast<float4*>(C.data_ptr<float>()),\n M4);\n } else {\n row_scale_scalar_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(), B.data_ptr<float>(), C.data_ptr<float>(), M);\n }\n return C;\n}\n\"\"\"\n\n_ext = load_inline(name=\"diag_mul_ext_v2c\",\n cpp_sources=[cpp_src],\n cuda_sources=[cuda_src],\n functions=[\"diag_mul_cuda\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super(ModelNew, self).__init__()\n def forward(self, A, B):\n return _ext.diag_mul_cuda(A, B)\n"
}
result ← run_correctness (ok)
okrun_correctness
run_correctness PASSED: (5 / 5) trials all matched the reference.
Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00
turn 418.6s turn · 18.6s LLM · 0.0s tools
reasoning
**Considering name collisions**
I'm thinking there might be an issue with name collisions when I compile my evaluator across different attempts. To avoid confusion, I should use unique names for each instance. The final name seems okay, but it’s probably a good idea to do a static check before I submit it just to be safe. I want to make sure everything is clear and won’t collide with anything else.
call → static_check
callstatic_check
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r\"\"\"\n#include <torch/extension.h>\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B);\n\"\"\"\n\ncuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void row_scale_vec4_kernel(const float* __restrict__ A,\n const float4* __restrict__ B4,\n float4* __restrict__ C4,\n int M4) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M4;\n for (int j = threadIdx.x; j < M4; j += blockDim.x) {\n float4 b = B4[base + j];\n b.x *= a; b.y *= a; b.z *= a; b.w *= a;\n C4[base + j] = b;\n }\n}\n\n__global__ void row_scale_scalar_kernel(const float* __restrict__ A,\n const float* __restrict__ B,\n float* __restrict__ C,\n int M) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M;\n for (int col = threadIdx.x; col < M; col += blockDim.x) {\n C[base + col] = a * B[base + col];\n }\n}\n\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B) {\n auto C = torch::empty_like(B);\n const int N = (int)B.size(0);\n const int M = (int)B.size(1);\n const int threads = 256;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if ((M & 3) == 0) {\n int M4 = M >> 2;\n row_scale_vec4_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(),\n reinterpret_cast<const float4*>(B.data_ptr<float>()),\n reinterpret_cast<float4*>(C.data_ptr<float>()),\n M4);\n } else {\n row_scale_scalar_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(), B.data_ptr<float>(), C.data_ptr<float>(), M);\n }\n return C;\n}\n\"\"\"\n\n_ext = load_inline(name=\"diag_mul_ext_final\",\n cpp_sources=[cpp_src],\n cuda_sources=[cuda_src],\n functions=[\"diag_mul_cuda\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super(ModelNew, self).__init__()\n def forward(self, A, B):\n return _ext.diag_mul_cuda(A, B)\n"
}
result ← static_check (ok)
okstatic_check
static_check PASSED: no violations or warnings detected.
turn 520.2s turn · 20.2s LLM · 0.0s tools · FINAL
call → submit_kernel
callsubmit_kernel
{
"kernel_code": "import torch\nimport torch.nn as nn\nfrom torch.utils.cpp_extension import load_inline\n\ncpp_src = r\"\"\"\n#include <torch/extension.h>\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B);\n\"\"\"\n\ncuda_src = r\"\"\"\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__global__ void row_scale_vec4_kernel(const float* __restrict__ A,\n const float4* __restrict__ B4,\n float4* __restrict__ C4,\n int M4) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M4;\n for (int j = threadIdx.x; j < M4; j += blockDim.x) {\n float4 b = B4[base + j];\n b.x *= a;\n b.y *= a;\n b.z *= a;\n b.w *= a;\n C4[base + j] = b;\n }\n}\n\n__global__ void row_scale_scalar_kernel(const float* __restrict__ A,\n const float* __restrict__ B,\n float* __restrict__ C,\n int M) {\n int row = blockIdx.x;\n float a = A[row];\n int base = row * M;\n for (int col = threadIdx.x; col < M; col += blockDim.x) {\n C[base + col] = a * B[base + col];\n }\n}\n\ntorch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B) {\n auto C = torch::empty_like(B);\n const int N = (int)B.size(0);\n const int M = (int)B.size(1);\n const int threads = 256;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream();\n if ((M & 3) == 0) {\n int M4 = M >> 2;\n row_scale_vec4_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(),\n reinterpret_cast<const float4*>(B.data_ptr<float>()),\n reinterpret_cast<float4*>(C.data_ptr<float>()),\n M4);\n } else {\n row_scale_scalar_kernel<<<N, threads, 0, stream>>>(\n A.data_ptr<float>(), B.data_ptr<float>(), C.data_ptr<float>(), M);\n }\n return C;\n}\n\"\"\"\n\n_ext = load_inline(name=\"diag_mul_ext_final\",\n cpp_sources=[cpp_src],\n cuda_sources=[cuda_src],\n functions=[\"diag_mul_cuda\"],\n extra_cflags=[\"-O3\"],\n extra_cuda_cflags=[\"-O3\", \"--use_fast_math\"],\n verbose=False)\n\nclass ModelNew(nn.Module):\n def __init__(self):\n super(ModelNew, self).__init__()\n\n def forward(self, A, B):\n return _ext.diag_mul_cuda(A, B)\n"
}
result ← submit_kernel (ok)
oksubmit_kernel
submit_kernel PASSED: (5 / 5) correctness trials all passed.
Kernel runtime: 0.05 μs
Runtime stats: mean=0.05μ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: 161.02 MB peak (ref: 161.02 MB, ratio: 1.0x)
Kernel launches: 2 (ref: 3, fusion ratio: 1.5)
SOL score: 0.779
final submitted kernel (80 lines, 2,477 chars) — full source, untruncated
import torch
import torch.nn as nn
from torch.utils.cpp_extension import load_inline
cpp_src = r"""
#include <torch/extension.h>
torch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B);
"""
cuda_src = r"""
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <cuda.h>
#include <cuda_runtime.h>
__global__ void row_scale_vec4_kernel(const float* __restrict__ A,
const float4* __restrict__ B4,
float4* __restrict__ C4,
int M4) {
int row = blockIdx.x;
float a = A[row];
int base = row * M4;
for (int j = threadIdx.x; j < M4; j += blockDim.x) {
float4 b = B4[base + j];
b.x *= a;
b.y *= a;
b.z *= a;
b.w *= a;
C4[base + j] = b;
}
}
__global__ void row_scale_scalar_kernel(const float* __restrict__ A,
const float* __restrict__ B,
float* __restrict__ C,
int M) {
int row = blockIdx.x;
float a = A[row];
int base = row * M;
for (int col = threadIdx.x; col < M; col += blockDim.x) {
C[base + col] = a * B[base + col];
}
}
torch::Tensor diag_mul_cuda(torch::Tensor A, torch::Tensor B) {
auto C = torch::empty_like(B);
const int N = (int)B.size(0);
const int M = (int)B.size(1);
const int threads = 256;
cudaStream_t stream = at::cuda::getCurrentCUDAStream();
if ((M & 3) == 0) {
int M4 = M >> 2;
row_scale_vec4_kernel<<<N, threads, 0, stream>>>(
A.data_ptr<float>(),
reinterpret_cast<const float4*>(B.data_ptr<float>()),
reinterpret_cast<float4*>(C.data_ptr<float>()),
M4);
} else {
row_scale_scalar_kernel<<<N, threads, 0, stream>>>(
A.data_ptr<float>(), B.data_ptr<float>(), C.data_ptr<float>(), M);
}
return C;
}
"""
_ext = load_inline(name="diag_mul_ext_final",
cpp_sources=[cpp_src],
cuda_sources=[cuda_src],
functions=["diag_mul_cuda"],
extra_cflags=["-O3"],
extra_cuda_cflags=["-O3", "--use_fast_math"],
verbose=False)
class ModelNew(nn.Module):
def __init__(self):
super(ModelNew, self).__init__()
def forward(self, A, B):
return _ext.diag_mul_cuda(A, B)