gpt-5.5-priority · original · l123_single_gpt
correct 54_conv_standard_3D__square_input__square_kernel.py
model
gpt-5.5-priority
turns / max
1 / 1
tool calls
1
tokens (total)
0
wall clock
—
truncated
no
backend
cuda fp32
variant
original
runtime
6.01 μs
ref runtime
1.87 μs
speedup
0.31x
started
2026-05-05T01:10:25Z
timingkernelbench.timing
kernel runtime
6.01 μs
ref runtime
1.87 μs
speedup
0.31x
kernel mean / median / std
6.01 / — / 0.93 μs
ref mean / median / std
1.87 / — / 0.24 μ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
1012.01 MB
ref peak
1012.01 MB
kernel / ref
1.00x
kernel launches / fusiontorch.profiler
kernel launches
2
ref launches
4
fusion ratio (ref / kernel)
2.00x
total cuda time
31 μs
energyNVML (pynvml)
kernel mJ / run
3300.10
ref mJ / run
1180.70
ratio (ref / kernel)
0.36x
avg power
558.76 W
ref avg power
640.72 W
SOL (speed-of-light)nsight_hardware_counters
SOL score (0–1)
0.212
dram util %
21.2%
compute util %
20.7%
bottleneck
memory-bound
dominant pipe
FP32
arithmetic intensity
—
ridge point
20.00
roofline / occupancynsight_hardware_counters
dram bandwidth
711.56 GB/s
dram util %
21.2%
fp32 tflops
—
fp32 util %
—
fp16 tflops
—
occupancy %
49.5%
bottleneck
memory-bound
dominant pipe %
20.7%
arithmetic intensity
—
ridge point
20.00
L1 hit %
—
L2 hit %
69.7%
ld sectors / req
4.95
st sectors / req
—
regs / thread
64
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
mio_throttle
663.6%
long_scoreboard
282.4%
short_scoreboard
45.0%
reference PyTorch source (the prompt the agent sees)
import torch
import torch.nn as nn

class Model(nn.Module):
    """
    Performs a standard 3D convolution operation with square input and square kernel.

    Args:
        in_channels (int): Number of channels in the input tensor.
        out_channels (int): Number of channels produced by the convolution.
        kernel_size (int): Size of the square convolution kernel.
        stride (int, optional): Stride of the convolution. Defaults to 1.
        padding (int, optional): Padding applied to the input. Defaults to 0.
        dilation (int, optional): Spacing between kernel elements. Defaults to 1.
        groups (int, optional): Number of blocked connections from input channels to output channels. Defaults to 1.
        bias (bool, optional): If `True`, adds a learnable bias to the output. Defaults to `False`.
    """
    def __init__(self, in_channels: int, out_channels: int, kernel_size: int, stride: int = 1, padding: int = 0, dilation: int = 1, groups: int = 1, bias: bool = False):
        super(Model, self).__init__()
        self.conv3d = nn.Conv3d(in_channels, out_channels, (kernel_size, kernel_size, kernel_size), stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)
        
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Performs the 3D convolution.

        Args:
            x (torch.Tensor): Input tensor of shape (batch_size, in_channels, depth, width, height).

        Returns:
            torch.Tensor: Output tensor of shape (batch_size, out_channels, depth_out, width_out, height_out).
        """
        return self.conv3d(x)

# Test code
batch_size = 16
in_channels = 3
out_channels = 64
kernel_size = 3
depth = 64
width = 64
height = 64

def get_inputs():
    x = torch.rand(batch_size, in_channels, depth, width, height)
    return [x]

def get_init_inputs():
    return [in_channels, out_channels, kernel_size]  # Provide in_channels, out_channels, kernel_size for initialization
turn 0 · FINAL · 1 tool call(s) · 83.3s turn · 83.3s LLM · 10,666 chars (click to expand)
turn 083.3s turn · 83.3s 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\n_cpp_src = r'''\n#include <torch/extension.h>\n\ntorch::Tensor conv3d_forward_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n int64_t stride, int64_t padding, int64_t dilation, int64_t groups);\n\ntorch::Tensor conv3d_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n int64_t stride, int64_t padding, int64_t dilation, int64_t groups) {\n return conv3d_forward_cuda(x, weight, bias, stride, padding, dilation, groups);\n}\n'''\n\n_cuda_src = r'''\n#include <torch/extension.h>\n#include <ATen/cuda/CUDAContext.h>\n#include <c10/cuda/CUDAException.h>\n#include <cuda.h>\n#include <cuda_runtime.h>\n\n__constant__ float c_weight[8192];\n__constant__ float c_bias[1024];\n\n__global__ __launch_bounds__(256, 4)\nvoid conv3d_k3_c3_kernel(const float* __restrict__ x, float* __restrict__ y,\n int N, int OC, int D, int H, int W,\n int Do, int Ho, int Wo, int has_bias, int total) {\n const int S = Do * Ho * Wo;\n const int HW = H * W;\n const int stride_grid = blockDim.x * gridDim.x;\n for (int idx = blockIdx.x * blockDim.x + threadIdx.x; idx < total; idx += stride_grid) {\n int t = idx;\n const int s = t % S; t /= S;\n const int oc = t % OC;\n const int n = t / OC;\n\n int r = s;\n const int ow = r % Wo; r /= Wo;\n const int oh = r % Ho;\n const int od = r / Ho;\n\n const float* base0 = x + ((n * 3) * D + od) * HW + oh * W + ow;\n const float* base1 = base0 + D * HW;\n const float* base2 = base1 + D * HW;\n const int wo = oc * 81;\n float acc = 0.0f;\n\n #pragma unroll\n for (int kd = 0; kd < 3; ++kd) {\n const int zoff = kd * HW;\n #pragma unroll\n for (int kh = 0; kh < 3; ++kh) {\n const int off = zoff + kh * W;\n const float x00 = base0[off + 0];\n const float x01 = base0[off + 1];\n const float x02 = base0[off + 2];\n const int w0 = wo + kd * 9 + kh * 3;\n acc = fmaf(x00, c_weight[w0 + 0], acc);\n acc = fmaf(x01, c_weight[w0 + 1], acc);\n acc = fmaf(x02, c_weight[w0 + 2], acc);\n }\n }\n #pragma unroll\n for (int kd = 0; kd < 3; ++kd) {\n const int zoff = kd * HW;\n #pragma unroll\n for (int kh = 0; kh < 3; ++kh) {\n const int off = zoff + kh * W;\n const float x00 = base1[off + 0];\n const float x01 = base1[off + 1];\n const float x02 = base1[off + 2];\n const int w0 = wo + 27 + kd * 9 + kh * 3;\n acc = fmaf(x00, c_weight[w0 + 0], acc);\n acc = fmaf(x01, c_weight[w0 + 1], acc);\n acc = fmaf(x02, c_weight[w0 + 2], acc);\n }\n }\n #pragma unroll\n for (int kd = 0; kd < 3; ++kd) {\n const int zoff = kd * HW;\n #pragma unroll\n for (int kh = 0; kh < 3; ++kh) {\n const int off = zoff + kh * W;\n const float x00 = base2[off + 0];\n const float x01 = base2[off + 1];\n const float x02 = base2[off + 2];\n const int w0 = wo + 54 + kd * 9 + kh * 3;\n acc = fmaf(x00, c_weight[w0 + 0], acc);\n acc = fmaf(x01, c_weight[w0 + 1], acc);\n acc = fmaf(x02, c_weight[w0 + 2], acc);\n }\n }\n if (has_bias) acc += c_bias[oc];\n y[idx] = acc;\n }\n}\n\n__global__ __launch_bounds__(256, 3)\nvoid conv3d_generic_kernel(const float* __restrict__ x, const float* __restrict__ wgt,\n const float* __restrict__ bias, float* __restrict__ y,\n int N, int C, int D, int H, int W, int OC, int K,\n int stride, int pad, int dil, int groups,\n int Do, int Ho, int Wo, int has_bias, long long total) {\n const int S = Do * Ho * Wo;\n const int Cg = C / groups;\n const int Og = OC / groups;\n const int HW = H * W;\n const long long step = (long long)blockDim.x * gridDim.x;\n for (long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x; idx < total; idx += step) {\n long long t = idx;\n int s = (int)(t % S); t /= S;\n int oc = (int)(t % OC);\n int n = (int)(t / OC);\n int r = s;\n int ow = r % Wo; r /= Wo;\n int oh = r % Ho;\n int od = r / Ho;\n int g = oc / Og;\n float acc = 0.0f;\n for (int icg = 0; icg < Cg; ++icg) {\n int ic = g * Cg + icg;\n for (int kd = 0; kd < K; ++kd) {\n int id = od * stride - pad + kd * dil;\n if ((unsigned)id >= (unsigned)D) continue;\n for (int kh = 0; kh < K; ++kh) {\n int ih = oh * stride - pad + kh * dil;\n if ((unsigned)ih >= (unsigned)H) continue;\n for (int kw = 0; kw < K; ++kw) {\n int iw = ow * stride - pad + kw * dil;\n if ((unsigned)iw >= (unsigned)W) continue;\n float xv = x[((n * C + ic) * D + id) * HW + ih * W + iw];\n float wv = wgt[(((oc * Cg + icg) * K + kd) * K + kh) * K + kw];\n acc = fmaf(xv, wv, acc);\n }\n }\n }\n }\n if (has_bias) acc += bias[oc];\n y[idx] = acc;\n }\n}\n\ntorch::Tensor conv3d_forward_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,\n int64_t stride64, int64_t padding64, int64_t dilation64, int64_t groups64) {\n const int N = (int)x.size(0);\n const int C = (int)x.size(1);\n const int D = (int)x.size(2);\n const int H = (int)x.size(3);\n const int W = (int)x.size(4);\n const int OC = (int)weight.size(0);\n const int K = (int)weight.size(2);\n const int stride = (int)stride64;\n const int pad = (int)padding64;\n const int dil = (int)dilation64;\n const int groups = (int)groups64;\n const int Do = (D + 2 * pad - dil * (K - 1) - 1) / stride + 1;\n const int Ho = (H + 2 * pad - dil * (K - 1) - 1) / stride + 1;\n const int Wo = (W + 2 * pad - dil * (K - 1) - 1) / stride + 1;\n auto y = torch::empty({N, OC, Do, Ho, Wo}, x.options());\n const int has_bias = (bias.numel() != 0);\n const int threads = 256;\n cudaStream_t stream = at::cuda::getCurrentCUDAStream().stream();\n\n if (C == 3 && K == 3 && stride == 1 && pad == 0 && dil == 1 && groups == 1 && weight.numel() <= 8192 && OC <= 1024) {\n size_t bytes = (size_t)weight.numel() * sizeof(float);\n C10_CUDA_CHECK(cudaMemcpyToSymbolAsync(c_weight, weight.data_ptr<float>(), bytes, 0, cudaMemcpyDeviceToDevice, stream));\n if (has_bias) {\n C10_CUDA_CHECK(cudaMemcpyToSymbolAsync(c_bias, bias.data_ptr<float>(), (size_t)OC * sizeof(float), 0, cudaMemcpyDeviceToDevice, stream));\n }\n int total = N * OC * Do * Ho * Wo;\n int blocks = (total + threads - 1) / threads;\n if (blocks > 65535) blocks = 65535;\n conv3d_k3_c3_kernel<<<blocks, threads, 0, stream>>>(x.data_ptr<float>(), y.data_ptr<float>(), N, OC, D, H, W, Do, Ho, Wo, has_bias, total);\n } else {\n long long total = (long long)N * OC * Do * Ho * Wo;\n int blocks = (int)((total + threads - 1) / threads);\n if (blocks > 65535) blocks = 65535;\n const float* bptr = has_bias ? bias.data_ptr<float>() : nullptr;\n conv3d_generic_kernel<<<blocks, threads, 0, stream>>>(x.data_ptr<float>(), weight.data_ptr<float>(), bptr, y.data_ptr<float>(),\n N, C, D, H, W, OC, K, stride, pad, dil, groups, Do, Ho, Wo, has_bias, total);\n }\n C10_CUDA_KERNEL_LAUNCH_CHECK();\n return y;\n}\n'''\n\n_ext = load_inline(\n name='conv3d_direct_k3c3_ext_v1',\n cpp_sources=_cpp_src,\n cuda_sources=_cuda_src,\n functions=['conv3d_forward'],\n extra_cflags=['-O3'],\n extra_cuda_cflags=['-O3', '--use_fast_math'],\n with_cuda=True,\n verbose=False,\n)\n\nclass ModelNew(nn.Module):\n def __init__(self, in_channels: int, out_channels: int, kernel_size: int, stride: int = 1, padding: int = 0, dilation: int = 1, groups: int = 1, bias: bool = False):\n super(ModelNew, self).__init__()\n self.conv3d = nn.Conv3d(in_channels, out_channels, (kernel_size, kernel_size, kernel_size), stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)\n self._stride = stride\n self._padding = padding\n self._dilation = dilation\n self._groups = groups\n\n def forward(self, x: torch.Tensor) -> torch.Tensor:\n # Inputs in the benchmark are contiguous CUDA fp32 tensors; keep the module state_dict-compatible with nn.Conv3d.\n b = self.conv3d.bias\n if b is None:\n b = torch.empty(0, device=x.device, dtype=x.dtype)\n return _ext.conv3d_forward(x.contiguous(), self.conv3d.weight.contiguous(), b, self._stride, self._padding, self._dilation, self._groups)\n" }
result ← submit_kernel (ok)
oksubmit_kernel submit_kernel PASSED: (5 / 5) correctness trials all passed. Kernel runtime: 6.01 μs Runtime stats: mean=6.01μs median=?μs std=0.93μs Numerical precision: max_abs_err=0.00e+00 mean_abs_err=0.00e+00 max_rel_err=0.00e+00 Memory: 1012.01 MB peak (ref: 1012.01 MB, ratio: 1.0x) Kernel launches: 2 (ref: 4, fusion ratio: 2.0) Energy: 3300.1 mJ/run (ref: 1180.7 mJ, ratio: 0.3578x) SOL score: 0.2124
final submitted kernel (216 lines, 9,214 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 conv3d_forward_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,
                                  int64_t stride, int64_t padding, int64_t dilation, int64_t groups);

torch::Tensor conv3d_forward(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,
                             int64_t stride, int64_t padding, int64_t dilation, int64_t groups) {
    return conv3d_forward_cuda(x, weight, bias, stride, padding, dilation, groups);
}
'''

_cuda_src = r'''
#include <torch/extension.h>
#include <ATen/cuda/CUDAContext.h>
#include <c10/cuda/CUDAException.h>
#include <cuda.h>
#include <cuda_runtime.h>

__constant__ float c_weight[8192];
__constant__ float c_bias[1024];

__global__ __launch_bounds__(256, 4)
void conv3d_k3_c3_kernel(const float* __restrict__ x, float* __restrict__ y,
                         int N, int OC, int D, int H, int W,
                         int Do, int Ho, int Wo, int has_bias, int total) {
    const int S = Do * Ho * Wo;
    const int HW = H * W;
    const int stride_grid = blockDim.x * gridDim.x;
    for (int idx = blockIdx.x * blockDim.x + threadIdx.x; idx < total; idx += stride_grid) {
        int t = idx;
        const int s = t % S;  t /= S;
        const int oc = t % OC;
        const int n = t / OC;

        int r = s;
        const int ow = r % Wo; r /= Wo;
        const int oh = r % Ho;
        const int od = r / Ho;

        const float* base0 = x + ((n * 3) * D + od) * HW + oh * W + ow;
        const float* base1 = base0 + D * HW;
        const float* base2 = base1 + D * HW;
        const int wo = oc * 81;
        float acc = 0.0f;

        #pragma unroll
        for (int kd = 0; kd < 3; ++kd) {
            const int zoff = kd * HW;
            #pragma unroll
            for (int kh = 0; kh < 3; ++kh) {
                const int off = zoff + kh * W;
                const float x00 = base0[off + 0];
                const float x01 = base0[off + 1];
                const float x02 = base0[off + 2];
                const int w0 = wo + kd * 9 + kh * 3;
                acc = fmaf(x00, c_weight[w0 + 0], acc);
                acc = fmaf(x01, c_weight[w0 + 1], acc);
                acc = fmaf(x02, c_weight[w0 + 2], acc);
            }
        }
        #pragma unroll
        for (int kd = 0; kd < 3; ++kd) {
            const int zoff = kd * HW;
            #pragma unroll
            for (int kh = 0; kh < 3; ++kh) {
                const int off = zoff + kh * W;
                const float x00 = base1[off + 0];
                const float x01 = base1[off + 1];
                const float x02 = base1[off + 2];
                const int w0 = wo + 27 + kd * 9 + kh * 3;
                acc = fmaf(x00, c_weight[w0 + 0], acc);
                acc = fmaf(x01, c_weight[w0 + 1], acc);
                acc = fmaf(x02, c_weight[w0 + 2], acc);
            }
        }
        #pragma unroll
        for (int kd = 0; kd < 3; ++kd) {
            const int zoff = kd * HW;
            #pragma unroll
            for (int kh = 0; kh < 3; ++kh) {
                const int off = zoff + kh * W;
                const float x00 = base2[off + 0];
                const float x01 = base2[off + 1];
                const float x02 = base2[off + 2];
                const int w0 = wo + 54 + kd * 9 + kh * 3;
                acc = fmaf(x00, c_weight[w0 + 0], acc);
                acc = fmaf(x01, c_weight[w0 + 1], acc);
                acc = fmaf(x02, c_weight[w0 + 2], acc);
            }
        }
        if (has_bias) acc += c_bias[oc];
        y[idx] = acc;
    }
}

__global__ __launch_bounds__(256, 3)
void conv3d_generic_kernel(const float* __restrict__ x, const float* __restrict__ wgt,
                           const float* __restrict__ bias, float* __restrict__ y,
                           int N, int C, int D, int H, int W, int OC, int K,
                           int stride, int pad, int dil, int groups,
                           int Do, int Ho, int Wo, int has_bias, long long total) {
    const int S = Do * Ho * Wo;
    const int Cg = C / groups;
    const int Og = OC / groups;
    const int HW = H * W;
    const long long step = (long long)blockDim.x * gridDim.x;
    for (long long idx = (long long)blockIdx.x * blockDim.x + threadIdx.x; idx < total; idx += step) {
        long long t = idx;
        int s = (int)(t % S); t /= S;
        int oc = (int)(t % OC);
        int n = (int)(t / OC);
        int r = s;
        int ow = r % Wo; r /= Wo;
        int oh = r % Ho;
        int od = r / Ho;
        int g = oc / Og;
        float acc = 0.0f;
        for (int icg = 0; icg < Cg; ++icg) {
            int ic = g * Cg + icg;
            for (int kd = 0; kd < K; ++kd) {
                int id = od * stride - pad + kd * dil;
                if ((unsigned)id >= (unsigned)D) continue;
                for (int kh = 0; kh < K; ++kh) {
                    int ih = oh * stride - pad + kh * dil;
                    if ((unsigned)ih >= (unsigned)H) continue;
                    for (int kw = 0; kw < K; ++kw) {
                        int iw = ow * stride - pad + kw * dil;
                        if ((unsigned)iw >= (unsigned)W) continue;
                        float xv = x[((n * C + ic) * D + id) * HW + ih * W + iw];
                        float wv = wgt[(((oc * Cg + icg) * K + kd) * K + kh) * K + kw];
                        acc = fmaf(xv, wv, acc);
                    }
                }
            }
        }
        if (has_bias) acc += bias[oc];
        y[idx] = acc;
    }
}

torch::Tensor conv3d_forward_cuda(torch::Tensor x, torch::Tensor weight, torch::Tensor bias,
                                  int64_t stride64, int64_t padding64, int64_t dilation64, int64_t groups64) {
    const int N = (int)x.size(0);
    const int C = (int)x.size(1);
    const int D = (int)x.size(2);
    const int H = (int)x.size(3);
    const int W = (int)x.size(4);
    const int OC = (int)weight.size(0);
    const int K = (int)weight.size(2);
    const int stride = (int)stride64;
    const int pad = (int)padding64;
    const int dil = (int)dilation64;
    const int groups = (int)groups64;
    const int Do = (D + 2 * pad - dil * (K - 1) - 1) / stride + 1;
    const int Ho = (H + 2 * pad - dil * (K - 1) - 1) / stride + 1;
    const int Wo = (W + 2 * pad - dil * (K - 1) - 1) / stride + 1;
    auto y = torch::empty({N, OC, Do, Ho, Wo}, x.options());
    const int has_bias = (bias.numel() != 0);
    const int threads = 256;
    cudaStream_t stream = at::cuda::getCurrentCUDAStream().stream();

    if (C == 3 && K == 3 && stride == 1 && pad == 0 && dil == 1 && groups == 1 && weight.numel() <= 8192 && OC <= 1024) {
        size_t bytes = (size_t)weight.numel() * sizeof(float);
        C10_CUDA_CHECK(cudaMemcpyToSymbolAsync(c_weight, weight.data_ptr<float>(), bytes, 0, cudaMemcpyDeviceToDevice, stream));
        if (has_bias) {
            C10_CUDA_CHECK(cudaMemcpyToSymbolAsync(c_bias, bias.data_ptr<float>(), (size_t)OC * sizeof(float), 0, cudaMemcpyDeviceToDevice, stream));
        }
        int total = N * OC * Do * Ho * Wo;
        int blocks = (total + threads - 1) / threads;
        if (blocks > 65535) blocks = 65535;
        conv3d_k3_c3_kernel<<<blocks, threads, 0, stream>>>(x.data_ptr<float>(), y.data_ptr<float>(), N, OC, D, H, W, Do, Ho, Wo, has_bias, total);
    } else {
        long long total = (long long)N * OC * Do * Ho * Wo;
        int blocks = (int)((total + threads - 1) / threads);
        if (blocks > 65535) blocks = 65535;
        const float* bptr = has_bias ? bias.data_ptr<float>() : nullptr;
        conv3d_generic_kernel<<<blocks, threads, 0, stream>>>(x.data_ptr<float>(), weight.data_ptr<float>(), bptr, y.data_ptr<float>(),
            N, C, D, H, W, OC, K, stride, pad, dil, groups, Do, Ho, Wo, has_bias, total);
    }
    C10_CUDA_KERNEL_LAUNCH_CHECK();
    return y;
}
'''

_ext = load_inline(
    name='conv3d_direct_k3c3_ext_v1',
    cpp_sources=_cpp_src,
    cuda_sources=_cuda_src,
    functions=['conv3d_forward'],
    extra_cflags=['-O3'],
    extra_cuda_cflags=['-O3', '--use_fast_math'],
    with_cuda=True,
    verbose=False,
)

class ModelNew(nn.Module):
    def __init__(self, in_channels: int, out_channels: int, kernel_size: int, stride: int = 1, padding: int = 0, dilation: int = 1, groups: int = 1, bias: bool = False):
        super(ModelNew, self).__init__()
        self.conv3d = nn.Conv3d(in_channels, out_channels, (kernel_size, kernel_size, kernel_size), stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)
        self._stride = stride
        self._padding = padding
        self._dilation = dilation
        self._groups = groups

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # Inputs in the benchmark are contiguous CUDA fp32 tensors; keep the module state_dict-compatible with nn.Conv3d.
        b = self.conv3d.bias
        if b is None:
            b = torch.empty(0, device=x.device, dtype=x.dtype)
        return _ext.conv3d_forward(x.contiguous(), self.conv3d.weight.contiguous(), b, self._stride, self._padding, self._dilation, self._groups)