static void DepthwiseConvBackpropInputReference(const DepthwiseArgs& args,
                                                const T* out_backprop,
                                                const T* filter,
                                                T* in_backprop) {
  // Naive for loop as a reference point without concerns about performance.
  for (int b = 0; b < args.batch; ++b) {
    for (int in_r = 0; in_r < args.in_rows; ++in_r) {
      for (int in_c = 0; in_c < args.in_cols; ++in_c) {
        for (int in_d = 0; in_d < args.in_depth; ++in_d) {
          T sum = 0;
          const int stride = args.stride;
          const int out_d_start = in_d * args.depth_multiplier;
          const int out_d_end = out_d_start + args.depth_multiplier;

          for (int out_d = out_d_start; out_d < out_d_end; ++out_d) {
            const int out_r_start = std::max(
                0, (in_r - args.filter_rows + args.pad_rows + stride) / stride);
            const int out_r_end =
                std::min(args.out_rows - 1, (in_r + args.pad_rows) / stride);

            for (int out_r = out_r_start; out_r <= out_r_end; ++out_r) {
              const int out_c_start = std::max(
                  0,
                  (in_c - args.filter_cols + args.pad_cols + stride) / stride);
              const int out_c_end =
                  std::min(args.out_cols - 1, (in_c + args.pad_cols) / stride);

              for (int out_c = out_c_start; out_c <= out_c_end; ++out_c) {
                int f_r = in_r + args.pad_rows - out_r * stride;
                int f_c = in_c + args.pad_cols - out_c * stride;
                int filter_dm = out_d - out_d_start;
                int out_backprop_offset =
                    out_d +
                    args.out_depth *
                        (out_c + args.out_cols * (out_r + args.out_rows * b));
                int filter_offset =
                    filter_dm +
                    args.depth_multiplier *
                        (in_d + args.in_depth * (f_c + args.filter_cols * f_r));
                sum +=
                    out_backprop[out_backprop_offset] * filter[filter_offset];
              }
            }
          }

          int in_backprop_offset =
              in_d +
              args.in_depth * (in_c + args.in_cols * (in_r + args.in_rows * b));
          in_backprop[in_backprop_offset] = sum;
        }
      }
    }
  }
}
static void DepthwiseConvBackpropInputReference(const DepthwiseArgs& args,
                                                const T* out_backprop,
                                                const T* filter,
                                                T* in_backprop) {
   
  for (int b = 0; b < args.batch; ++b) {
    for (int in_r = 0; in_r < args.in_rows; ++in_r) {
      for (int in_c = 0; in_c < args.in_cols; ++in_c) {
        for (int in_d = 0; in_d < args.in_depth; ++in_d) {
          T sum = 0;
          const int stride = args.stride;
          const int out_d_start = in_d * args.depth_multiplier;
          const int out_d_end = out_d_start + args.depth_multiplier;

          for (int out_d = out_d_start; out_d < out_d_end; ++out_d) {
            const int out_r_start = std::max(
                0, (in_r - args.filter_rows + args.pad_rows + stride) / stride);
            const int out_r_end =
                std::min(args.out_rows - 1, (in_r + args.pad_rows) / stride);

            for (int out_r = out_r_start; out_r <= out_r_end; ++out_r) {
              const int out_c_start = std::max(
                  0,
                  (in_c - args.filter_cols + args.pad_cols + stride) / stride);
              const int out_c_end =
                  std::min(args.out_cols - 1, (in_c + args.pad_cols) / stride);

              for (int out_c = out_c_start; out_c <= out_c_end; ++out_c) {
                int f_r = in_r + args.pad_rows - out_r * stride;
                int f_c = in_c + args.pad_cols - out_c * stride;
                int filter_dm = out_d - out_d_start;
                int out_backprop_offset =
                    out_d +
                    args.out_depth *
                        (out_c + args.out_cols * (out_r + args.out_rows * b));
                int filter_offset =
                    filter_dm +
                    args.depth_multiplier *
                        (in_d + args.in_depth * (f_c + args.filter_cols * f_r));
                sum +=
                    out_backprop[out_backprop_offset] * filter[filter_offset];
              }
            }
          }

          int in_backprop_offset =
              in_d +
              args.in_depth * (in_c + args.in_cols * (in_r + args.in_rows * b));
          in_backprop[in_backprop_offset] = sum;
        }
      }
    }
  }
}