 
 ;; =============== Common vector macros and functions =======================
 
-(defn ^:private vector-equals [modl ^CUBlockVector x ^CUBlockVector y]
+(defn ^:private vector-equals [modl hstream ^CUBlockVector x ^CUBlockVector y]
   (let [cnt (.dim x)]
     (if (< 0 cnt)
       (with-release [equals-kernel (function modl "vector_equals")
                      eq-flag-buf (mem-alloc Integer/BYTES)]
         (memset! eq-flag-buf 0)
-        (launch! equals-kernel (grid-1d cnt)
+        (launch! equals-kernel (grid-1d cnt) hstream
                  (parameters cnt
                              (.buffer x) (.offset x) (.stride x)
                              (.buffer y) (.offset y) (.stride y)


;; =============== Common GE matrix macros and functions =======================

(defn ^:private ge-equals [modl ^CUGEMatrix a ^CUGEMatrix b]
  (if (< 0 (.count a))
    (with-release [equals-kernel (function modl (name-transp "ge_equals" a b))
                   eq-flag-buf (mem-alloc Integer/BYTES)]
      (memset! eq-flag-buf 0)
      (launch! equals-kernel (grid-2d (.sd a) (.fd a))
               (parameters (.sd a) (.fd a) (.buffer a) (.offset a) (.stride a)
                           (.buffer b) (.offset b) (.stride b) eq-flag-buf))
      (= 0 (aget ^ints (memcpy-host! eq-flag-buf (int-array 1)) 0)))
    (= 0 (.mrows b) (.ncols b))))

(defn ^:private ge-set [modl alpha ^CUGEMatrix a]
  (if (< 0 (.count a))
    (let [da (data-accessor a)]
      (with-release [ge-set-kernel (function modl "ge_set")]
        (launch! ge-set-kernel (grid-2d (.sd a) (.fd a))
                 (parameters (.sd a) (.fd a) alpha (.buffer a) (.offset a) (.stride a)))))))

(defmacro ^:private ge-swap [cublas-handle method modl a b]
  `(when (< 0 (.count ~a))
     (if (fits-buffer? ~a ~b)
       (let [da# (data-accessor ~a)]

    y)
  BlasPlus
  (subcopy [_ x y kx lx ky]
    (vector-subcopy modl hstream ^CUBlockVector x ^CUBlockVector y kx lx ky)
    y)
  (sum [_ x]
    (vector-sum modl hstream ^CUBlockVector x))
  (imax [_ x]
    (throw (UnsupportedOperationException. "TODO.")))
  (imin [this x]
    (throw (UnsupportedOperationException. "TODO.")))
  (set-all [_ alpha x]
    (vector-set modl hstream (float alpha) ^CUBlockVector x)
    x)
  (axpby [_ alpha x beta y]
    (vector-axpby modl hstream (float alpha) x (float beta) y)
    y))

(deftype DoubleGEEngine [cublas-handle modl hstream]
  BlockEngine
  (equals-block [_ a b]
    (ge-equals modl hstream a b))
  Blas
  (swap [_ a b]
    (ge-swap cublas-handle JCublas2/cublasDswap modl hstream ^CUGEMatrix a ^CUGEMatrix b)
    a)
  (copy [_ a b]
    (ge-am cublas-handle JCublas2/cublasDgeam (double 1) ^CUGEMatrix a (double 0) ^CUGEMatrix b)
