1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
import mpiunittest as unittest
from mpi4py import MPI
try:
import cffi
except ImportError:
cffi = None
@unittest.skipIf(cffi is None, "cffi")
class TestCFFI(unittest.TestCase):
#
mpitypes = [
MPI.Datatype,
MPI.Request,
MPI.Info,
MPI.Errhandler,
MPI.Session,
MPI.Group,
MPI.Win,
MPI.Op,
MPI.File,
MPI.Message,
MPI.Comm,
]
objects = [
MPI.DATATYPE_NULL,
MPI.INT,
MPI.DOUBLE,
MPI.REQUEST_NULL,
MPI.INFO_NULL,
MPI.INFO_ENV,
MPI.ERRHANDLER_NULL,
MPI.ERRORS_RETURN,
MPI.ERRORS_ARE_FATAL,
MPI.GROUP_NULL,
MPI.GROUP_EMPTY,
MPI.WIN_NULL,
MPI.OP_NULL,
MPI.SUM,
MPI.MIN,
MPI.MAX,
MPI.FILE_NULL,
MPI.MESSAGE_NULL,
MPI.MESSAGE_NO_PROC,
MPI.COMM_NULL,
MPI.COMM_SELF,
MPI.COMM_WORLD,
]
def testHandleAddress(self):
ffi = cffi.FFI()
typemap = {
ffi.sizeof("int"): "int",
ffi.sizeof("void*"): "void*",
}
def typename(t):
return t.__name__.rsplit(".", 1)[-1]
for tp in self.mpitypes:
handle_t = typemap[MPI._sizeof(tp)]
mpi_t = "MPI_" + typename(tp)
ffi.cdef(f"typedef {handle_t} {mpi_t};")
for obj in self.objects:
if isinstance(obj, MPI.Comm):
mpi_t = "MPI_Comm"
else:
mpi_t = "MPI_" + typename(type(obj))
oldobj = obj
newobj = type(obj)()
handle_old = ffi.cast(mpi_t + "*", MPI._addressof(oldobj))
handle_new = ffi.cast(mpi_t + "*", MPI._addressof(newobj))
handle_new[0] = handle_old[0]
self.assertEqual(oldobj, newobj)
def testHandleValue(self):
ffi = cffi.FFI()
typemap = {
ffi.sizeof("uint32_t"): "uint32_t",
ffi.sizeof("uint64_t"): "uint64_t",
}
for obj in self.objects:
uintptr_t = typemap[MPI._sizeof(obj)]
handle = ffi.cast(uintptr_t + "*", MPI._addressof(obj))[0]
self.assertEqual(handle, MPI._handleof(obj))
if __name__ == "__main__":
unittest.main()
|