              :refer [PseudoFunctor Foldable fmap! fold foldmap]]
             [uncomplicate.neanderthal
              [protocols :refer :all]
-             [core :refer [transfer! copy!]]]
+             [core :refer [transfer! copy! mrows ncols]]]
             [uncomplicate.clojurecl.core :refer [Releaseable]])
   (:import [java.nio ByteBuffer DirectByteBuffer]
            [clojure.lang IFn IFn$D IFn$DD IFn$LD IFn$DDD IFn$LDD IFn$DDDD

                                                 (.entry ^RealVector z i)
                                                 (.entry ^RealVector v i))))
           acc))))))


;; ================== map/reduce functions =====================================


           (vector-fmap* f (.row x i))))
       x))
  ([^Matrix x f ^Matrix y]
   (if (check-matrix-dimensions x y)
     (do (if (column-major? x)
           (dotimes [i (.ncols x)]
             (vector-fmap* f (.col x i) (.col y i)))
           (dotimes [i (.mrows x)]
             (vector-fmap* f (.row x i) (.row y i))))
         x)
     (throw (IllegalArgumentException. FITTING_DIMENSIONS_MATRIX_MSG))))
  ([^Matrix x f ^Matrix y ^Matrix z]
   (if (check-matrix-dimensions x y z)
     (do (if (column-major? x)
           (dotimes [i (.ncols x)]
             (vector-fmap* f (.col x i) (.col y i) (.col z i)))
           (dotimes [i (.mrows x)]
             (vector-fmap* f (.row x i) (.row y i) (.row z i))))
         x)
     (throw (IllegalArgumentException. FITTING_DIMENSIONS_MATRIX_MSG))))
  ([^Matrix x f ^Matrix y ^Matrix z ^Matrix v]
   (if (check-matrix-dimensions x y z v)
     (do (if (column-major? x)
           (dotimes [i (.ncols x)]
             (vector-fmap* f (.col x i) (.col y i) (.col z i) (.col v i)))
           (dotimes [i (.mrows x)]
             (vector-fmap* f (.row x i) (.row y i) (.row z i) (.col v i))))
         x)
     (throw (IllegalArgumentException. FITTING_DIMENSIONS_MATRIX_MSG))))
  ([x f y z w ws]
   (throw (UnsupportedOperationException. "Matrix fmap support up to 4 matrices."))))

