      abort,
      Comm(), commWorld, commSelf,
      ComparisonResult (..),
-     Datatype, char, wchar, short, int, long, longLong, unsignedChar,
+     Datatype(), char, wchar, short, int, long, longLong, unsignedChar,
      unsignedShort, unsigned, unsignedLong, unsignedLongLong, float, double,
      longDouble, byte, packed,
      Errhandler, errorsAreFatal, errorsReturn,

commRemoteSize = {# call unsafe Comm_remote_size as commRemoteSize_ #} <$> fromComm
commCompare c1 c2 = {# call unsafe Comm_compare as commCompare_ #} (fromComm c1) (fromComm c2)
probe s t c = {# call Probe as probe_ #} s t (fromComm c)
send b cnt d r t c = {# call unsafe Send as send_ #} b cnt d r t (fromComm c)
bsend b cnt d r t c = {# call unsafe Bsend as bsend_ #} b cnt d r t (fromComm c)
ssend b cnt d r t c = {# call unsafe Ssend as ssend_ #} b cnt d r t (fromComm c)
rsend b cnt d r t c = {# call unsafe Rsend as rsend_ #} b cnt d r t (fromComm c)
recv b cnt d r t c = {# call unsafe Recv as recv_ #} b cnt d r t (fromComm c)
isend b cnt d r t c = {# call unsafe Isend as isend_ #} b cnt d r t (fromComm c)
ibsend b cnt d r t c = {# call unsafe Ibsend as ibsend_ #} b cnt d r t (fromComm c)
issend b cnt d r t c = {# call unsafe Issend as issend_ #} b cnt d r t (fromComm c)
irecv b cnt d r t c = {# call Irecv as irecv_ #} b cnt d r t (fromComm c)
bcast b cnt d r c = {# call unsafe Bcast as bcast_ #} b cnt d r (fromComm c)
barrier = {# call unsafe Barrier as barrier_ #} <$> fromComm
wait = {# call unsafe Wait as wait_ #}
waitall = {# call unsafe Waitall as waitall_ #}
test = {# call unsafe Test as test_ #}
cancel = {# call unsafe Cancel as cancel_ #}
scatter sb se st rb re rt r c = {# call unsafe Scatter as scatter_ #} sb se st rb re rt r (fromComm c)
gather sb se st rb re rt r c = {# call unsafe Gather as gather_ #} sb se st rb re rt r (fromComm c)
scatterv sb sc sd st rb re rt r c = {# call unsafe Scatterv as scatterv_ #} sb sc sd st rb re rt r (fromComm c)
gatherv sb se st rb rc rd rt r c = {# call unsafe Gatherv as gatherv_ #} sb se st rb rc rd rt r (fromComm c)
allgather sb se st rb re rt c = {# call unsafe Allgather as allgather_ #} sb se st rb re rt (fromComm c)
allgatherv sb se st rb rc rd rt c = {# call unsafe Allgatherv as allgatherv_ #} sb se st rb rc rd rt (fromComm c)
alltoall sb sc st rb rc rt c = {# call unsafe Alltoall as alltoall_ #} sb sc st rb rc rt (fromComm c)
alltoallv sb sc sd st rb rc rd rt c = {# call unsafe Alltoallv as alltoallv_ #} sb sc sd st rb rc rd rt (fromComm c)
-- Reduce, allreduce and reduceScatter could call back to Haskell
-- via user-defined ops, so they should be imported in "safe" mode
reduce sb rb se st o r c  = {# call Reduce as reduce_ #} sb rb se st o r (fromComm c)
allreduce sb rb se st o c = {# call Allreduce as allreduce_ #} sb rb se st o (fromComm c)
reduceScatter sb rb cnt t o c = {# call Reduce_scatter as reduceScatter_ #} sb rb cnt t o (fromComm c)
opCreate = {# call unsafe Op_create as opCreate_ #}
opFree = {# call unsafe Op_free as opFree_ #}
wtime = {# call unsafe Wtime as wtime_ #}

groupExcl g = {# call unsafe Group_excl as groupExcl_ #} (fromGroup g)
groupIncl g = {# call unsafe Group_incl as groupIncl_ #} (fromGroup g)
groupTranslateRanks g1 s r g2 = {# call unsafe Group_translate_ranks as groupTranslateRanks_ #} (fromGroup g1) s r (fromGroup g2)
typeSize = {# call unsafe Type_size as typeSize_ #} <$> fromDatatype
errorClass = {# call unsafe Error_class as errorClass_ #}
errorString = {# call unsafe Error_string as errorString_ #}
commSetErrhandler = {# call unsafe Comm_set_errhandler as commSetErrhandler_ #} <$> fromComm
