reduceSend :: SendFrom v => Comm
              -> Rank -- ^ Rank of the root process
              -> Operation -- ^ Reduction operation
              -> v -- ^ Value supplied by this process
              -> IO ()
reduceSend comm root op sendVal = do
  sendFrom sendVal $ \sendPtr sendElements sendType ->
    Internal.reduce (castPtr sendPtr) nullPtr sendElements sendType op root comm

{-| Obtain result of reduction initiated by 'reduceSend'. Note that root process supplies value for reduction as well.
-}
reduceSend :: SendFrom v => Comm
              -> Rank -- ^ Rank of the root process
              -> Operation -- ^ Reduction operation
              -> v -- ^ Value supplied by this process
              -> IO ()
reduceSend comm root op sendVal = do
  sendFrom sendVal $ \sendPtr sendElements sendType ->
    Internal.reduce (castPtr sendPtr) nullPtr sendElements sendType op root comm

{-| Obtain result of reduction initiated by 'reduceSend'. Note that root process supplies value for reduction as well.
-}
reduceSend comm root op sendVal = do
  sendFrom sendVal $ \sendPtr sendElements sendType ->
    Internal.reduce (castPtr sendPtr) nullPtr sendElements sendType op root comm

{-| Obtain result of reduction initiated by 'reduceSend'. Note that root process supplies value for reduction as well.
-}