m_ExchangeMaps.F90 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2. ! Math and Computer Science Division, Argonne National Laboratory !
  3. !-----------------------------------------------------------------------
  4. ! CVS m_ExchangeMaps.F90,v 1.19 2004-04-21 22:16:32 jacob Exp
  5. ! CVS MCT_2_8_0
  6. !BOP -------------------------------------------------------------------
  7. !
  8. ! !MODULE: m_ExchangeMaps - Exchange of Global Mapping Objects.
  9. !
  10. ! !DESCRIPTION:
  11. ! This module contains routines that support the exchange of domain
  12. ! decomposition descriptors (DDDs) between two MCT components. There is
  13. ! support for {\em handshaking} between the two components to determine
  14. ! the types of domain decomposition descriptors they employ, {\em loading}
  15. ! of data contained within domain decomposition descriptors, and {\em
  16. ! map exchange}, resulting in the creation of a remote component's domain
  17. ! decomposition descriptor for use by a local component. These routines
  18. ! are largely used by MCT's {\tt Router} to create intercomponent
  19. ! communications scheduler, and normally should not be used by an MCT
  20. ! user.
  21. !
  22. ! Currently, the types of map exchange supported by the public routine
  23. ! {\tt ExchangeMap()} are summarized in the table below. The first column
  24. ! lists the type of DDD used locally on the component invoking
  25. ! {\tt ExchangeMap()} (i.e., the input DDD). The second comlumn lists
  26. ! the DDD type used on the remote component (i.e., the output DDD).
  27. !\begin{table}[htbp]
  28. !\begin{center}
  29. !\begin{tabular}{|c|c|}
  30. !\hline
  31. !{\bf Local DDD Type} & {\bf Remote DDD Type} \\
  32. !\hline
  33. !{\tt GlobalMap} & {\tt GlobalSegMap} \\
  34. !\hline
  35. !{\tt GlobalSegMap} & {\tt GlobalSegMap} \\
  36. !\hline
  37. !\end{tabular}
  38. !\end{center}
  39. !\end{table}
  40. !
  41. ! Currently, we do not support intercomponent map exchange where a
  42. ! {\tt GlobalMap} is output. The rationale for this is that any {\tt GlobalMap}
  43. ! may always be expressed as a {\tt GlobalSegMap}.
  44. !
  45. ! !INTERFACE:
  46. module m_ExchangeMaps
  47. ! !USES:
  48. ! No external modules are used in the declaration section of this module.
  49. implicit none
  50. private ! except
  51. !
  52. ! !PUBLIC MEMBER FUNCTIONS:
  53. !
  54. public :: ExchangeMap
  55. interface ExchangeMap ; module procedure &
  56. ExGSMapGSMap_, & ! GlobalSegMap for GlobalSegMap
  57. ExGMapGSMap_
  58. end interface
  59. ! !SEE ALSO:
  60. ! The MCT module m_ConvertMaps for more information regarding the
  61. ! relationship between the GlobalMap and GlobalSegMap types.
  62. ! The MCT module m_Router to see where these services are used to
  63. ! create intercomponent communications schedulers.
  64. !
  65. ! !REVISION HISTORY:
  66. ! 3Feb01 - J.W. Larson <larson@mcs.anl.gov> - initial module
  67. ! 3Aug01 - E.T. Ong <eong@mcs.anl.gov> - in ExGSMapGSMap,
  68. ! call GlobalSegMap_init with actual shaped arrays
  69. ! for non-root processes to satisfy Fortran 90 standard.
  70. ! See comments in subroutine.
  71. ! 15Feb02 - R. Jacob <jacob@mcs.anl.gov> - use MCT_comm instead of
  72. ! MP_COMM_WORLD
  73. !EOP ___________________________________________________________________
  74. !
  75. character(len=*),parameter :: myname='MCT::m_ExchangeMaps'
  76. ! Map Handshaking Parameters: Map handshaking occurs via
  77. ! exchange of an array of INTEGER flags.
  78. ! Number of Handshaking Parameters; i.e.size of exhcanged parameters array
  79. integer, parameter :: NumHandshakePars = 4
  80. ! ComponentIDIndex defines the storage location of the flag
  81. ! signifying the component number in MCTWorld
  82. integer, parameter :: ComponentIDIndex = 1
  83. ! MapTypeIndex defines the storage location in the handshake array
  84. ! of the type of map offered for exchange
  85. integer, parameter :: MapTypeIndex = 2
  86. ! NumMapTypes is the number of legitimate MapTypeIndex Values:
  87. integer, parameter :: NumMapTypes = 2
  88. ! Recognized MapTypeIndex Values:
  89. integer, parameter :: GlobalMapFlag = 1
  90. integer, parameter :: GlobalSegMapFlag = 2
  91. ! GsizeIndex defines the location of the grid size (number of points)
  92. ! for the map. This size is
  93. integer, parameter :: GsizeIndex = 3
  94. ! NumSegIndex defines the location of the number of segments in the
  95. ! map. For a GlobalMap, this is the number of processes in the map.
  96. ! For a GlobalSegMap, this is the number of global segments (ngseg).
  97. integer, parameter :: NumSegIndex = 4
  98. contains
  99. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  100. ! Math and Computer Science Division, Argonne National Laboratory !
  101. !BOP -------------------------------------------------------------------
  102. !
  103. ! !IROUTINE: MapHandshake_ - Exchange Map descriptors.
  104. !
  105. ! !DESCRIPTION:
  106. ! This routine takes input Map descriptors stored in the {\tt INTEGER}
  107. ! array {\tt LocalMapPars}, the local communicator on which this map is
  108. ! defined ({\tt LocalComm}), and the remote component ID
  109. ! {\tt RemoteCompID}, and effects an exchange of map descriptors with
  110. ! the remote component, which are returned in the {\tt INTEGER} array
  111. ! {\tt RemoteMapPars}.
  112. !
  113. ! {\bf N.B.: } The values present in {\tt LocalMapPars} need to be valid
  114. ! only on the root of {\tt LocalComm}. Likewise, the returned values in
  115. ! {\tt RemoteMapPars} will be valid on the root of {\tt LocalComm}.
  116. !
  117. ! !INTERFACE:
  118. subroutine MapHandshake_(LocalMapPars, LocalComm, RemoteCompID, &
  119. RemoteMapPars)
  120. !
  121. ! !USES:
  122. !
  123. use m_mpif90
  124. use m_die, only : MP_perr_die
  125. use m_stdio
  126. use m_MCTWorld, only : ThisMCTWorld
  127. use m_MCTWorld, only : ComponentRootRank
  128. implicit none
  129. !
  130. ! !INPUT PARAMETERS:
  131. !
  132. integer, intent(in) :: LocalMapPars(NumHandshakePars)
  133. integer, intent(in) :: LocalComm
  134. integer, intent(in) :: RemoteCompID
  135. !
  136. ! !OUTPUT PARAMETERS:
  137. !
  138. integer, intent(out) :: RemoteMapPars(NumHandshakePars)
  139. ! !REVISION HISTORY:
  140. ! 6Feb01 - J.W. Larson <larson@mcs.anl.gov> - API specification.
  141. ! 20Apr01 - R.L. Jacob <jacob@mcs.anl.gov> - add status argument
  142. ! to MPI_RECV
  143. !EOP ___________________________________________________________________
  144. character(len=*),parameter :: myname_=myname//'::MapHandshake_'
  145. integer :: ierr, myID, RemoteRootID, SendTag, RecvTag
  146. integer,dimension(MP_STATUS_SIZE) :: status
  147. call MP_COMM_RANK(LocalComm, myID, ierr)
  148. if(ierr /= 0) call MP_perr_die(myname_,'call MP_COMM_RANK()',ierr)
  149. RemoteRootID = ComponentRootRank(RemoteCompID, ThisMCTWorld)
  150. if(myID == 0) then ! I am the root on LocalComm
  151. ! Compute send/receive tags:
  152. SendTag = 10 * LocalMapPars(ComponentIDIndex) + RemoteCompID
  153. RecvTag = LocalMapPars(ComponentIDIndex) + 10 * RemoteCompID
  154. ! Post send to RemoteRootID:
  155. call MPI_SEND(LocalMapPars, NumHandshakePars, MP_INTEGER, &
  156. RemoteRootID, SendTag, ThisMCTWorld%MCT_comm, ierr)
  157. if(ierr /= 0) call MP_perr_die(myname_,'call MPI_SEND()',ierr)
  158. ! Post receive from RemoteRootID:
  159. call MPI_RECV(RemoteMapPars, NumHandshakePars, MP_INTEGER, &
  160. RemoteRootID, RecvTag, ThisMCTWorld%MCT_comm, status, ierr)
  161. if(ierr /= 0) call MP_perr_die(myname_,'call MPI_RECV()',ierr)
  162. endif ! if(myID == 0)
  163. end subroutine MapHandshake_
  164. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  165. ! Math and Computer Science Division, Argonne National Laboratory !
  166. !BOP -------------------------------------------------------------------
  167. !
  168. ! !IROUTINE: LoadGlobalMapPars_ - Load GlobalMap descriptors.
  169. !
  170. ! !DESCRIPTION:
  171. ! This routine takes an input {\tt GlobalMap} variable {\tt Gmap}, and
  172. ! loads its descriptors the output {\tt INTEGER} array {\tt MapPars}.
  173. ! The dimensions of this array, and loading order are all defined in
  174. ! the declaration section of this module.
  175. !
  176. ! !INTERFACE:
  177. subroutine LoadGlobalMapPars_(GMap, MapPars)
  178. !
  179. ! !USES:
  180. !
  181. use m_mpif90
  182. use m_die
  183. use m_stdio
  184. use m_GlobalMap, only : GlobalMap
  185. use m_GlobalMap, only : GlobalMap_comp_id => comp_id
  186. use m_GlobalMap, only : GlobalMap_gsize => gsize
  187. ! use m_GlobalMap, only : GlobalMap_nprocs => nprocs
  188. implicit none
  189. !
  190. ! !INPUT PARAMETERS:
  191. !
  192. type(GlobalMap), intent(in) :: GMap
  193. !
  194. ! !OUTPUT PARAMETERS:
  195. !
  196. integer, intent(out) :: MapPars(NumHandshakePars)
  197. ! !REVISION HISTORY:
  198. ! 6Feb01 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
  199. !EOP ___________________________________________________________________
  200. character(len=*),parameter :: myname_=myname//'::LoadGlobalMapPars_'
  201. MapPars(ComponentIDIndex) = GlobalMap_comp_id(GMap)
  202. MapPars(MapTypeIndex) = GlobalMapFlag
  203. MapPars(GsizeIndex) = GlobalMap_gsize(GMap)
  204. ! MapPars(NumSegIndex) = GlobalMap_nprocs(GSMap)
  205. end subroutine LoadGlobalMapPars_
  206. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  207. ! Math and Computer Science Division, Argonne National Laboratory !
  208. !BOP -------------------------------------------------------------------
  209. !
  210. ! !IROUTINE: LoadGlobalSegMapPars_ - Load GlobalSegMap descriptors.
  211. !
  212. ! !DESCRIPTION:
  213. ! This routine takes an input {\tt GlobalSegMap} variable {\tt Gmap}, and
  214. ! loads its descriptors the output {\tt INTEGER} array {\tt MapPars}.
  215. ! The dimensions of this array, and loading order are all defined in
  216. ! the declaration section of this module.
  217. !
  218. ! !INTERFACE:
  219. subroutine LoadGlobalSegMapPars_(GSMap, MapPars)
  220. !
  221. ! !USES:
  222. !
  223. use m_mpif90
  224. use m_die
  225. use m_stdio
  226. use m_GlobalSegMap, only : GlobalSegMap
  227. use m_GlobalSegMap, only : GlobalSegMap_comp_id => comp_id
  228. use m_GlobalSegMap, only : GlobalSegMap_gsize => gsize
  229. use m_GlobalSegMap, only : GlobalSegMap_ngseg => ngseg
  230. implicit none
  231. !
  232. ! !INPUT PARAMETERS:
  233. !
  234. type(GlobalSegMap), intent(in) :: GSMap
  235. !
  236. ! !OUTPUT PARAMETERS:
  237. !
  238. integer, intent(out) :: MapPars(NumHandshakePars)
  239. ! !REVISION HISTORY:
  240. ! 6Feb01 - J.W. Larson <larson@mcs.anl.gov> - Initial version.
  241. !EOP ___________________________________________________________________
  242. character(len=*),parameter :: myname_=myname//'::LoadGlobalSegMapPars_'
  243. MapPars(ComponentIDIndex) = GlobalSegMap_comp_id(GSMap)
  244. MapPars(MapTypeIndex) = GlobalSegMapFlag
  245. MapPars(GsizeIndex) = GlobalSegMap_gsize(GSMap)
  246. MapPars(NumSegIndex) = GlobalSegMap_ngseg(GSMap)
  247. end subroutine LoadGlobalSegMapPars_
  248. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  249. ! Math and Computer Science Division, Argonne National Laboratory !
  250. !BOP -------------------------------------------------------------------
  251. !
  252. ! !IROUTINE: ExGSMapGSMap_ - Trade of GlobalSegMap structures.
  253. !
  254. ! !DESCRIPTION:
  255. ! This routine effects the exchange between two components of their
  256. ! data decomposition descriptors, each of which is a {\tt GlobalSegMap}.
  257. ! The component invoking this routine provides its domain decomposition
  258. ! in the form of the input {\tt GlobalSegMap} argument {\tt LocalGSMap}.
  259. ! The component with which map exchange takes place is specified by the
  260. ! MCT integer component identification number defined by the input
  261. ! {\tt INTEGER} argument {\tt RemoteCompID}. The
  262. ! !INTERFACE:
  263. subroutine ExGSMapGSMap_(LocalGSMap, LocalComm, RemoteGSMap, &
  264. RemoteCompID, ierr)
  265. !
  266. ! !USES:
  267. !
  268. use m_mpif90
  269. use m_die
  270. use m_stdio
  271. use m_GlobalSegMap, only : GlobalSegMap
  272. use m_GlobalSegMap, only : GlobalSegMap_init => init
  273. use m_MCTWorld, only : ThisMCTWorld
  274. use m_MCTWorld, only : ComponentRootRank
  275. implicit none
  276. ! !INPUT PARAMETERS:
  277. type(GlobalSegMap), intent(in) :: LocalGSMap ! Local GlobalSegMap
  278. integer, intent(in) :: LocalComm ! Local Communicator
  279. integer , intent(in) :: RemoteCompID ! Remote component id
  280. ! !OUTPUT PARAMETERS:
  281. type(GlobalSegMap), intent(out) :: RemoteGSMap ! Remote GlobalSegMap
  282. integer, intent(out) :: ierr ! Error Flag
  283. ! !REVISION HISTORY:
  284. ! 3Feb01 - J.W. Larson <larson@mcs.anl.gov> - API specification.
  285. ! 7Feb01 - J.W. Larson <larson@mcs.anl.gov> - First full version.
  286. ! 20Apr01 - R.L. Jacob <jacob@mcs.anl.gov> - add status argument
  287. ! to MPI_RECV
  288. ! 25Apr01 - R.L. Jacob <jacob@mcs.anl.gov> - set SendTag and
  289. ! RecvTag values
  290. ! 3May01 - R.L. Jacob <jacob@mcs.anl.gov> - change MPI_SEND to
  291. ! MPI_ISEND to avoid possible buffering problems seen
  292. ! on IBM SP.
  293. !EOP ___________________________________________________________________
  294. character(len=*),parameter :: myname_=myname//'::ExGSMapGSMap_'
  295. ! root ID on local communicator:
  296. integer, parameter :: root = 0
  297. ! Storage for local and remote map descriptors:
  298. integer :: LocalMapPars(NumHandshakePars)
  299. integer :: RemoteMapPars(NumHandshakePars)
  300. ! Send and Receive Buffers
  301. integer, dimension(:), allocatable :: SendBuf
  302. integer, dimension(:), allocatable :: RecvBuf
  303. ! Send and Receive Tags
  304. integer :: SendTag, RecvTag
  305. ! Storage arrays for Remote GlobalSegMap data:
  306. integer, dimension(:), allocatable :: start, length, pe_loc
  307. integer :: myID, ngseg, remote_root,req
  308. integer :: local_ngseg, remote_ngseg
  309. integer,dimension(MP_STATUS_SIZE) :: status,wstatus
  310. ! Determine rank on local communicator:
  311. call MP_COMM_RANK(LocalComm, myID, ierr)
  312. if(ierr /= 0) call MP_perr_die(myname_,'call MP_COMM_RANK()',ierr)
  313. ! If the root, exchange map handshake descriptors,
  314. ! and information needed to initialize the remote map
  315. ! on the local communicator.
  316. if(myID == root) then
  317. call LoadGlobalSegMapPars_(LocalGSMap, LocalMapPars)
  318. call MapHandshake_(LocalMapPars, LocalComm, RemoteCompID, &
  319. RemoteMapPars)
  320. ! Consistency Checks between LocalMapPars and RemoteMapPars:
  321. if(LocalMapPars(MapTypeIndex) /= RemoteMapPars(MapTypeIndex)) then
  322. ierr = 2
  323. write(stderr,*) myname_,":: MCTERROR, Map Type mismatch ", &
  324. "LocalMap Type = ",LocalMapPars(MapTypeIndex)," RemoteMap Type = ", &
  325. RemoteMapPars(MapTypeIndex)
  326. call die(myname_,'Map Type mismatch',ierr)
  327. endif
  328. if(LocalMapPars(GsizeIndex) /= RemoteMapPars(GsizeIndex)) then
  329. ierr = 3
  330. write(stderr,*) myname_,":: MCTERROR, Grid Size mismatch ", &
  331. "LocalMap Gsize = ",LocalMapPars(GsizeIndex)," RemoteMap Gsize = ", &
  332. RemoteMapPars(GsizeIndex)
  333. call die(myname_,'Map Grid Size mismatch',ierr)
  334. endif
  335. if(RemoteCompID /= RemoteMapPars(ComponentIDIndex)) then
  336. ierr = 4
  337. write(stderr,*) myname_,":: MCTERROR, Component ID mismatch ", &
  338. "RemoteCompID = ",RemoteCompID," RemoteMap CompID = ", &
  339. RemoteMapPars(ComponentIDIndex)
  340. call die(myname_,'Component ID mismatch',ierr)
  341. endif
  342. ! SendBuf will hold the arrays LocalGSMap%start, LocalGSMap%length,
  343. ! and LocalGSMap%pe_loc in that order.
  344. allocate(SendBuf(3*LocalMapPars(NumSegIndex)), stat=ierr)
  345. if(ierr /= 0) call die(myname_,'allocate(SendBuf...)',ierr)
  346. ! RecvBuf will hold the arrays RemoteGSMap%start, RemoteGSMap%length,
  347. ! and RemoteGSMap%pe_loc in that order.
  348. allocate(RecvBuf(3*RemoteMapPars(NumSegIndex)), stat=ierr)
  349. if(ierr /= 0) call die(myname_,'allocate(RecvBuf...)',ierr)
  350. ! Load SendBuf in the order described above:
  351. local_ngseg = LocalMapPars(NumSegIndex)
  352. SendBuf(1:local_ngseg) = &
  353. LocalGSMap%start(1:local_ngseg)
  354. SendBuf(local_ngseg+1:2*local_ngseg) = &
  355. LocalGSMap%length(1:local_ngseg)
  356. SendBuf(2*local_ngseg+1:3*local_ngseg) = &
  357. LocalGSMap%pe_loc(1:local_ngseg)
  358. ! Determine the remote component root:
  359. remote_root = ComponentRootRank(RemoteMapPars(ComponentIDIndex), &
  360. ThisMCTWorld)
  361. SendTag = 10 * LocalMapPars(ComponentIDIndex) + RemoteCompID
  362. RecvTag = LocalMapPars(ComponentIDIndex) + 10 * RemoteCompID
  363. ! Send off SendBuf to the remote component root:
  364. call MPI_ISEND(SendBuf(1), 3*LocalMapPars(NumSegIndex), MP_INTEGER, &
  365. remote_root, SendTag, ThisMCTWorld%MCT_comm, req, ierr)
  366. if(ierr /= 0) call MP_perr_die(myname_,'MPI_SEND(SendBuf...',ierr)
  367. ! Receive RecvBuf from the remote component root:
  368. call MPI_RECV(RecvBuf, 3*RemoteMapPars(NumSegIndex), MP_INTEGER, &
  369. remote_root, RecvTag, ThisMCTWorld%MCT_comm, status, ierr)
  370. if(ierr /= 0) call MP_perr_die(myname_,'MPI_Recv(RecvBuf...',ierr)
  371. call MPI_WAIT(req,wstatus,ierr)
  372. if(ierr /= 0) call MP_perr_die(myname_,'MPI_WAIT(SendBuf..',ierr)
  373. ! Allocate arrays start(:), length(:), and pe_loc(:)
  374. allocate(start(RemoteMapPars(NumSegIndex)), &
  375. length(RemoteMapPars(NumSegIndex)), &
  376. pe_loc(RemoteMapPars(NumSegIndex)), stat=ierr)
  377. if(ierr /= 0) call die(myname_,'allocate(start...',ierr)
  378. ! Unpack RecvBuf into arrays start(:), length(:), and pe_loc(:)
  379. remote_ngseg = RemoteMapPars(NumSegIndex)
  380. start(1:remote_ngseg) = RecvBuf(1:remote_ngseg)
  381. length(1:remote_ngseg) = &
  382. RecvBuf(remote_ngseg+1:2*remote_ngseg)
  383. pe_loc(1:remote_ngseg) = &
  384. RecvBuf(2*remote_ngseg+1:3*remote_ngseg)
  385. endif ! if(myID == root)
  386. ! Non-root processes call GlobalSegMap_init with start,
  387. ! length, and pe_loc, although these arguments are
  388. ! not used in the subroutine. Since these correspond to dummy
  389. ! shaped array arguments in GlobalSegMap_init, the Fortran 90
  390. ! standard dictates that the actual arguments must contain
  391. ! complete shape information. Therefore, these array arguments
  392. ! must be allocated on all processes.
  393. if(myID /= root) then
  394. allocate(start(1), length(1), pe_loc(1), stat=ierr)
  395. if(ierr /= 0) call die(myname_,'non-root allocate(start...',ierr)
  396. endif
  397. ! Initialize the Remote GlobalSegMap RemoteGSMap
  398. call GlobalSegMap_init(RemoteGSMap, RemoteMapPars(NumSegIndex), &
  399. start, length, pe_loc, root, LocalComm, &
  400. RemoteCompID, RemoteMapPars(GsizeIndex))
  401. ! Deallocate allocated arrays
  402. deallocate(start, length, pe_loc, stat=ierr)
  403. if(ierr /= 0) then
  404. call die(myname_,'deallocate(start...',ierr)
  405. endif
  406. ! Deallocate allocated arrays on the root:
  407. if(myID == root) then
  408. deallocate(SendBuf, RecvBuf, stat=ierr)
  409. if(ierr /= 0) then
  410. call die(myname_,'deallocate(SendBuf...',ierr)
  411. endif
  412. endif ! if(myID == root)
  413. end subroutine ExGSMapGSMap_
  414. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  415. ! Math and Computer Science Division, Argonne National Laboratory !
  416. !BOP -------------------------------------------------------------------
  417. !
  418. ! !IROUTINE: ExGMapGSMap_ - Trade of GlobalMap for GlobalSegMap.
  419. !
  420. ! !DESCRIPTION:
  421. ! This routine allows a component to report its domain decomposition
  422. ! using a {\tt GlobalMap} (the input argument {\tt LocalGMap}), and
  423. ! receive the domain decomposition of a remote component in the form
  424. ! of a {\tt GlobalSegMap} (the output argument {\tt RemoteGSMap}. The
  425. ! component with which map exchange occurs is defined by its component
  426. ! ID number (the input {\tt INTEGER} argument {\tt RemoteCompID}).
  427. ! Currently, this operation is implemented as an exchange of maps between
  428. ! the root nodes of each component's communicator, and then propagated
  429. ! across the local component's communicator. This requires the user to
  430. ! provide the local communicator (the input {\tt INTEGER} argument
  431. ! {\tt LocalComm}). The success (failure) of this operation is reported
  432. ! in the zero (nonzero) value of the output {\tt INTEGER} argument
  433. ! {\tt ierr}.
  434. !
  435. ! !INTERFACE:
  436. subroutine ExGMapGSMap_(LocalGMap, LocalComm, RemoteGSMap, &
  437. RemoteCompID, ierr)
  438. !
  439. ! !USES:
  440. !
  441. use m_mpif90
  442. use m_die
  443. use m_stdio
  444. use m_GlobalMap, only : GlobalMap
  445. use m_GlobalSegMap, only : GlobalSegMap
  446. use m_GlobalSegMap, only : GlobalSegMap_init => init
  447. use m_GlobalSegMap, only : GlobalSegMap_clean => clean
  448. use m_ConvertMaps, only : GlobalMapToGlobalSegMap
  449. implicit none
  450. ! !INPUT PARAMETERS:
  451. type(GlobalMap), intent(in) :: LocalGMap ! Local GlobalMap
  452. integer, intent(in) :: LocalComm ! Local Communicator
  453. integer, intent(in) :: RemoteCompID ! Remote component id
  454. ! !OUTPUT PARAMETERS:
  455. type(GlobalSegMap), intent(out) :: RemoteGSMap ! Remote GlobalSegMap
  456. integer, intent(out) :: ierr ! Error Flag
  457. ! !REVISION HISTORY:
  458. ! 3Feb01 - J.W. Larson <larson@mcs.anl.gov> - API specification.
  459. ! 26Sep02 - J.W. Larson <larson@mcs.anl.gov> - Implementation.
  460. !EOP ___________________________________________________________________
  461. character(len=*),parameter :: myname_=myname//'::ExGMapGSMap_'
  462. type(GlobalSegMap) :: LocalGSMap
  463. ! Convert LocalGMap to a GlobalSegMap
  464. call GlobalMapToGlobalSegMap(LocalGMap, LocalGSMap)
  465. ! Exchange local decomposition in GlobalSegMap form with
  466. ! the remote component:
  467. call ExGSMapGSMap_(LocalGSMap, LocalComm, RemoteGSMap, &
  468. RemoteCompID, ierr)
  469. ! Destroy LocalGSMap
  470. call GlobalSegMap_clean(LocalGSMap)
  471. end subroutine ExGMapGSMap_
  472. end module m_ExchangeMaps