-- | Combination of 'reduceSend' + 'reduceRecv' and 'scatterSend' + 'scatterRecv': reduction result
-- is split and scattered among participating processes.
--
-- See 'reduceScatter' if you want to be able to specify personal block size for each process.
--
-- Note that this function is not supported with OpenMPI 1.5
reduceScatterBlock :: (SendFrom v, RecvInto v) =>
                 Comm -- ^ Communicator engaged in reduction/
                 -> Operation -- ^ Reduction operation
                 -> Int -- ^ Size of the result block sent to each process
                 -> v -- ^ Value supplied by this process
                 -> v -- ^ Reduction result
                 -> IO ()
reduceScatterBlock comm op blocksize sendVal recvVal =
  sendFrom sendVal $ \sendPtr _ sendType ->
    recvInto recvVal $ \recvPtr _ _ ->
      Internal.reduceScatterBlock (castPtr sendPtr) (castPtr recvPtr) (fromIntegral blocksize :: CInt) sendType op comm
reduceScatterBlock :: (SendFrom v, RecvInto v) =>
                 Comm -- ^ Communicator engaged in reduction/
                 -> Operation -- ^ Reduction operation
                 -> Int -- ^ Size of the result block sent to each process
                 -> v -- ^ Value supplied by this process
                 -> v -- ^ Reduction result
                 -> IO ()
reduceScatterBlock comm op blocksize sendVal recvVal =
  sendFrom sendVal $ \sendPtr _ sendType ->
    recvInto recvVal $ \recvPtr _ _ ->
      Internal.reduceScatterBlock (castPtr sendPtr) (castPtr recvPtr) (fromIntegral blocksize :: CInt) sendType op comm
reduceScatterBlock comm op blocksize sendVal recvVal =
  sendFrom sendVal $ \sendPtr _ sendType ->
    recvInto recvVal $ \recvPtr _ _ ->
      Internal.reduceScatterBlock (castPtr sendPtr) (castPtr recvPtr) (fromIntegral blocksize :: CInt) sendType op comm