// File: kernel.cpp
// Reference-scalar depthwise conv2d.
// LLM target: replace this file with an optimised inner_conv2d_depthwise.
// All per-definition constants live in conv2d_depthwise_def:: (conv2d_depthwise.h).
#include "conv2d_depthwise.h"
using namespace conv2d_depthwise_def;

extern "C" void inner_conv2d_depthwise(
    const float* input, float* output,
    const float* weight, const float* bias,
    int N, int C, int H, int W, int H_out, int W_out)
{
    for (int n = 0; n < N; ++n) {
        const float* in_n  = input  + (long)n * C * H * W;
        float*       out_n = output + (long)n * C * H_out * W_out;
        for (int c = 0; c < C; ++c) {
            const float* in_c  = in_n  + (long)c * H * W;
            float*       out_c = out_n + (long)c * H_out * W_out;
            const float* w_c   = weight + (long)c * Kh * Kw;
            for (int oh = 0; oh < H_out; ++oh) {
                for (int ow = 0; ow < W_out; ++ow) {
                    float sum = bias[c];
                    for (int kh = 0; kh < Kh; ++kh) {
                        for (int kw = 0; kw < Kw; ++kw) {
                            int ih = oh * Sh - pad + kh * Dh;
                            int iw = ow * Sw - pad + kw * Dw;
                            if (ih >= 0 && ih < H && iw >= 0 && iw < W)
                                sum += in_c[ih * W + iw] * w_c[kh * Kw + kw];
                        }
                    }
                    out_c[oh * W_out + ow] = sum;
                }
            }
        }
    }
}