sdot :: Acc (Vector Float) -> Acc (Vector Float) -> Acc (Scalar Float)
sdot v1 v2 = foreignAcc foreignDPF pureDPF $ lift (v1, v2)
  where foreignDPF = CUDAForeignAcc "cudaDotProductF" cudaDotProductF
        
        pureDPF :: Acc (Vector Float, Vector Float) -> Acc (Scalar Float)
        pureDPF vs = let (u, v) = unlift vs
                     in fold (+) 0 $ zipWith (*) u v

-- | Execute the dot product of the two vectors using
--   CUBLAS in the CUDA backend if available, fallback to a "pure"
--   implementation otherwise:
--
--   >>> A.fold (+) 0 $ A.zipWith (*) v1 v2
sdot :: Acc (Vector Float) -> Acc (Vector Float) -> Acc (Scalar Float)
sdot v1 v2 = foreignAcc foreignDPF pureDPF $ lift (v1, v2)
  where foreignDPF = CUDAForeignAcc "cudaDotProductF" cudaDotProductF
        
        pureDPF :: Acc (Vector Float, Vector Float) -> Acc (Scalar Float)
        pureDPF vs = let (u, v) = unlift vs
                     in fold (+) 0 $ zipWith (*) u v

-- | Execute the dot product of the two vectors using
--   CUBLAS in the CUDA backend if available, fallback to a "pure"
--   implementation otherwise:
--
--   >>> A.fold (+) 0 $ A.zipWith (*) v1 v2
sdot v1 v2 = foreignAcc foreignDPF pureDPF $ lift (v1, v2)
  where foreignDPF = CUDAForeignAcc "cudaDotProductF" cudaDotProductF
        
        pureDPF :: Acc (Vector Float, Vector Float) -> Acc (Scalar Float)
        pureDPF vs = let (u, v) = unlift vs
                     in fold (+) 0 $ zipWith (*) u v

-- | Execute the dot product of the two vectors using
--   CUBLAS in the CUDA backend if available, fallback to a "pure"
--   implementation otherwise:
--
--   >>> A.fold (+) 0 $ A.zipWith (*) v1 v2