You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

mpi_comm.py 2.9 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. from ctypes import *
  2. import ctypes
  3. from hetu import ndarray
  4. import numpy as np
  5. import os
  6. from enum import Enum
  7. def _load_mpi_lib():
  8. """Load libary in build/lib."""
  9. curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
  10. lib_path = os.path.join(curr_path, '../../../build/lib/')
  11. path_to_so_file = os.path.join(lib_path, "lib_mpi_runtime_api.so")
  12. lib = CDLL(path_to_so_file, RTLD_LOCAL)
  13. return lib
  14. lib_mpi = _load_mpi_lib()
  15. class MPIDataType_t(Enum):
  16. MPI_Char = 0
  17. MPI_Int = 1
  18. MPI_Uint32 = 2
  19. MPI_Int64 = 3
  20. MPI_Uint64 = 4
  21. MPI_Float32 = 5
  22. MPI_Float64 = 6
  23. class MPIOp_t(Enum):
  24. MPI_OP_NULL = 0
  25. MPI_MAX = 1
  26. MPI_MIN = 2
  27. MPI_SUM = 3
  28. class MPI_Communicator():
  29. def __init__(self):
  30. '''
  31. mpicomm: the MPI communicator, to use in MPI_Bcast, MPI_Reduce, MPI_Scatter, etc
  32. ncclcomm: the NCCL communicator, to use in ncclAllReduce ...
  33. nRanks: the total number of MPI threads
  34. myRanks: the rank in all MPI threads
  35. localRank: the rank among the MPI threads in this device
  36. ncclId: ncclGetUniqueId should be called once when creating a communicator
  37. and the Id should be distributed to all ranks in the communicator before calling ncclCommInitRank.
  38. stream: the stream for NCCL communication
  39. '''
  40. self.mpicomm = c_int64(0)
  41. self.nRanks = c_int32(0)
  42. self.myRank = c_int32(0)
  43. self.MPI_Init()
  44. self.MPI_GetComm()
  45. self.MPI_Get_Comm_rank()
  46. self.MPI_Get_Comm_size()
  47. def MPI_Init(self):
  48. lib_mpi.MPIInit()
  49. def MPI_GetComm(self):
  50. lib_mpi.MPIGetComm(ctypes.byref(self.mpicomm))
  51. def MPI_Get_Comm_rank(self):
  52. lib_mpi.getMPICommRank(ctypes.byref(
  53. self.mpicomm), ctypes.byref(self.myRank))
  54. def MPI_Get_Comm_size(self):
  55. lib_mpi.getMPICommSize(ctypes.byref(
  56. self.mpicomm), ctypes.byref(self.nRanks))
  57. def rank(self):
  58. return self.myRank
  59. def size(self):
  60. return self.nRanks
  61. def DLArrayAllReduce(self, dlarray, datatype, reduceop):
  62. lib_mpi.dlarrayAllReduce(dlarray.handle, c_int(datatype.value), c_int(
  63. reduceop.value), ctypes.byref(self.mpicomm))
  64. def allReduce(self, arr):
  65. self.DLArrayAllReduce(arr, MPIDataType_t.MPI_Float32, MPIOp_t.MPI_SUM)
  66. def finish(self):
  67. lib_mpi.MPIFinalize()
  68. def mpi_communicator():
  69. '''
  70. '''
  71. return MPI_Communicator()
  72. # mpirun --allow-run-as-root -np 4 python2 mpi_comm.py
  73. if __name__ == "__main__":
  74. comm = mpi_communicator()
  75. comm.MPI_GetComm()
  76. print("rank = %d" % (comm.rank().value))
  77. arr = np.ones([10]) * comm.rank().value
  78. arr = ndarray.array(arr)
  79. comm.allReduce(arr)
  80. print(arr.asnumpy())
  81. comm.finish()