-- | Combination of 'reduceSend' / 'reduceRecv' and 'scatterSend' / 'scatterRecv': reduction result
-- is split and scattered among participating processes.
reduceScatter :: (SendFrom v, RecvInto v) =>
                 Comm -- ^ Communicator engaged in reduction/
                 -> Operation -- ^ Reduction operation
                 -> StorableArray Int CInt -- ^ Sizes of block distributed to each process
                 -> v -- ^ Value supplied by this process
                 -> v -- ^ Reduction result
                 -> IO ()
reduceScatter comm op counts sendVal recvVal =
  sendFrom sendVal $ \sendPtr _ sendType ->
    recvInto recvVal $ \recvPtr _ _ ->
      withStorableArray counts $ \countsPtr ->
      Internal.reduceScatter (castPtr sendPtr) (castPtr recvPtr) countsPtr sendType op comm
reduceScatter :: (SendFrom v, RecvInto v) =>
                 Comm -- ^ Communicator engaged in reduction/
                 -> Operation -- ^ Reduction operation
                 -> StorableArray Int CInt -- ^ Sizes of block distributed to each process
                 -> v -- ^ Value supplied by this process
                 -> v -- ^ Reduction result
                 -> IO ()
reduceScatter comm op counts sendVal recvVal =
  sendFrom sendVal $ \sendPtr _ sendType ->
    recvInto recvVal $ \recvPtr _ _ ->
      withStorableArray counts $ \countsPtr ->
      Internal.reduceScatter (castPtr sendPtr) (castPtr recvPtr) countsPtr sendType op comm
reduceScatter comm op counts sendVal recvVal =
  sendFrom sendVal $ \sendPtr _ sendType ->
    recvInto recvVal $ \recvPtr _ _ ->
      withStorableArray counts $ \countsPtr ->
      Internal.reduceScatter (castPtr sendPtr) (castPtr recvPtr) countsPtr sendType op comm