           (m/set-row! input-mat-view idx data-row))
         padded-input-matrix)
       (m/reshape interleaved-input-vector [height (* width num-channels)]))))
+
+
+(defn convolution-sequence
+  "Produce a sequence of views that allows performs a convolution over an input matrix"
+  [input-matrix output-width output-height k-width k-height stride-w stride-h num-channels]
+  (let [stride-h (long stride-h)
+        stride-w (long stride-w)
+        num-channels (long num-channels)
+        k-width (long k-width)
+        k-height (long k-height)
+        kernel-stride (* k-width num-channels)]
+      (for [^long output-y (range output-height)
+            ^long output-x (range output-width)]
+        (m/as-vector (m/submatrix input-matrix [[(* output-y stride-h) k-height]
+                                                [(* output-x stride-w num-channels) kernel-stride]])))))
 
 
 (defn create-convolution-rows




(defrecord Convolutional [weights bias width height padx pady k-width k-height
                          stride-w stride-h output weight-gradient bias-gradient]
    cp/PModule

        input-mat-stride (* (+ width (* 2 padx)) num-channels)
        kernel-stride (* k-width num-channels)]
    ;;I go ahead and create a contiguous matrix here because we will iterate over this many times
    (m/array :vectorz (convolution-sequence input-matrix output-width output-height k-width k-height
                                            stride-w stride-h num-channels))))

(defn convolution-forward
  [weights bias input-convolved-rows]
