iconv2dForward :: KernelProgram '[TensorCL [k, k, c1, c2],
                                  TensorCL [ow + k - 1, oh + k - 1, c1],
                                  MTensorCL [ow, oh, c2]]
iconv2dForward = compile $ \flt input output -> do
  ~[ox, oy, oc] <- traverse get_global_id [0, 1, 2]
  let [k, _, c1, c2] = dimsOf flt
  acc <- eval 0
  forEach 0 k $ \kx -> do
    forEach 0 k $ \ky -> do
      forEach 0 c1 $ \ic -> do
        acc .= acc + flt![kx, ky, ic, oc] * input![ox + kx, oy + ky, ic]
  output![ox, oy, oc] .= acc


iconv2dForward :: KernelProgram '[TensorCL [k, k, c1, c2],
                                  TensorCL [ow + k - 1, oh + k - 1, c1],
                                  MTensorCL [ow, oh, c2]]
iconv2dForward = compile $ \flt input output -> do
  ~[ox, oy, oc] <- traverse get_global_id [0, 1, 2]
  let [k, _, c1, c2] = dimsOf flt
  acc <- eval 0
  forEach 0 k $ \kx -> do
    forEach 0 k $ \ky -> do
      forEach 0 c1 $ \ic -> do
        acc .= acc + flt![kx, ky, ic, oc] * input![ox + kx, oy + ky, ic]
  output![ox, oy, oc] .= acc


iconv2dForward = compile $ \flt input output -> do
  ~[ox, oy, oc] <- traverse get_global_id [0, 1, 2]
  let [k, _, c1, c2] = dimsOf flt
  acc <- eval 0
  forEach 0 k $ \kx -> do
    forEach 0 k $ \ky -> do
      forEach 0 c1 $ \ic -> do
        acc .= acc + flt![kx, ky, ic, oc] * input![ox + kx, oy + ky, ic]
  output![ox, oy, oc] .= acc

