 
 
 
-(defrecord Convolutional [weights bias width height padx pady k-width k-height
-                          stride-w stride-h output weight-gradient bias-gradient]
+(defrecord Convolutional [weights bias weight-gradient bias-gradient
+                          conv-layer-config]
     cp/PModule
     (cp/calc [this input]
-      (let [input-convolved-rows (create-convolution-rows input width height k-width k-height
-                                                          padx pady stride-w stride-h)
+      (let [input-convolved-rows (create-convolution-rows input conv-layer-config)
             backpass-input (columnar-sum input-convolved-rows)
             output (convolution-forward weights bias input-convolved-rows)]
         [output backpass-input]))

  "Given the results of the linear backward pass we have an input gradient that is
a vector of k-width * k-height * num-channels.  We need to de-convolve this using opposite
  operation as we did when we convolved the input."
  [input-gradient width height k-width k-height padx pady stride-w stride-h]
  (let [width (long width)
        height (long height)
        k-width (long k-width)
        k-height (long k-height)
        padx (long padx)
        pady (long pady)
        stride-w (long stride-w)
        stride-h (long stride-h)
        num-channels (long (/ (long (first (m/shape input-gradient)))
                              (* k-width k-height)))
        input-matrix (m/zero-array :vectorz [(+ height (* 2 pady))
                                             (* (+ width (* 2 padx)) num-channels)])
        input-mat-view (m/submatrix input-matrix
                                    [[pady height]

    (reduce m/add! accumulator (rest rows))))



(defn create-conv-layer-config
  [width height kernel-width kernel-height padx pady stride-w stride-h num-channels]
  (let [width (long width)
        height (long height)
        kernel-width (long kernel-width)
        kernel-height (long kernel-height)
        padx (long padx)
        pady (long pady)
        stride-w (long stride-w)
        stride-h (long stride-h)
        num-channels (long num-channels)]
    { :width width
     :height height
     :k-width kernel-width
     :k-height kernel-height
     :padx padx
     :pady pady
     :stride-w stride-w
     :stride-h stride-h
     :num-channels num-channels}))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Convolution layer forward pass utility functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn create-padded-input-matrix
  [interleaved-input-vector {:keys [^long width ^long height ^long padx ^long pady
                                    ^long num-channels] :as conv-layer-config}]
  (let [has-padding (or (> padx 0) (> pady 0))]
    (if has-padding
      (let [padded-input-matrix (m/zero-array :vectorz [(+ height (* 2 pady))
                                                        (* (+ width (* 2 padx)) num-channels)])
