qmpi.f90 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105
  1. # 0 "<stdin>"
  2. # 0 "<built-in>"
  3. # 0 "<command-line>"
  4. # 1 "/usr/include/stdc-predef.h" 1 3 4
  5. # 17 "/usr/include/stdc-predef.h" 3 4
  6. # 2 "<command-line>" 2
  7. # 1 "<stdin>"
  8. # 11 "<stdin>"
  9. module qmpi
  10. !
  11. ! A module defining a minimalist interface to a subset of MPI.
  12. ! The first five primitives can in theory be used to parallelize
  13. ! any program. The module hides type specification, communicators,
  14. ! explicit error handling, the need to give explicit buffer size etc.
  15. ! Also provided are a few interfaces for often used broadcast and
  16. ! reduction operations
  17. !
  18. ! © Helge Avlesen <avle@ii.uib.no>, para//ab
  19. !
  20. ! primitives: (optional arguments in brackets)
  21. !
  22. ! subroutine start_mpi()
  23. ! starts the mpi subsystem. all processesors are assigned a number (myid).
  24. ! the number of processors is numproc.
  25. ! subroutine stop_mpi()
  26. ! stops the mpi subsystem
  27. ! subroutine barrier([label])
  28. ! syncronization point for all processors. optionally prints a label on
  29. ! the master processor (0).
  30. ! subroutine send(data, target [,tag])
  31. ! send object data to processor number target, tag is an optional integer
  32. ! that defaults to 0. (if multiple messages are exchanged between a
  33. ! pair of processors, a unique tag must be used for each exhange)
  34. ! subroutine receive(data, source [,tag])
  35. ! get object data from processor source, tag is optional and as for send
  36. ! MPI will fail if the size of the object received is different from what
  37. ! was sent.
  38. !
  39. ! The rest of the routines are included for convenience, they can be
  40. ! also be implemented using the above subroutines.
  41. !
  42. ! subroutine broadcast(data [,root])
  43. ! broadcast data (any type) from processor root (default=0) to all
  44. ! other processors.
  45. ! subroutine mbroadcast(data [,data2,data3,data4,data5,data6] [,root])
  46. ! broadcast up to 6 scalar variables of the same type, to all processors
  47. ! from processor root (default=0)
  48. ! subroutine reduce(type, data [,data2,data3,data4,data5,data6] [,root] )
  49. ! reduce the scalar data, optionally also data2-data6, return result
  50. ! on all processes. the operation can currently be of type 'sum', 'mul',
  51. ! 'min' or 'max' i.e. a sum or a product. data-data6 must be of the
  52. ! same type. if integer root is present, only return result on that
  53. ! processor (faster)
  54. !
  55. ! Example: a program that sends a real from processor 0 to processor 1
  56. ! use qmpi
  57. ! real data
  58. ! call start_mpi
  59. ! data=myid
  60. ! if(myid==0) call send(data, 1)
  61. ! if(myid==1) then
  62. ! call receive(data, 0)
  63. ! print *,'hello, I am',myid,'got ',data,'from process 0'
  64. ! end if
  65. ! call stop_mpi
  66. ! end
  67. !
  68. ! More advanced usage example: to send a derived type from 0 to 1;
  69. ! pack it in a string (could be packed into any array), send, receive, unpack.
  70. !
  71. ! type(any_type) var1
  72. ! character, allocatable :: buffer(:)
  73. ! ...
  74. ! N=size(transfer(var1,(/'x'/)))) !! compute size of type once
  75. ! allocate(buffer(N))
  76. ! if(myid==0)then
  77. ! buffer = transfer(var1,buffer)
  78. ! call send(buffer,1)
  79. ! end if
  80. ! if(myid==1)then
  81. ! call receive(buffer,0)
  82. ! var1 = transfer(buffer,var1)
  83. ! end if
  84. ! ...
  85. !
  86. include 'mpif.h'
  87. integer, public :: qmpi_proc_num, qmpi_num_proc, ierr, errorcode, mpistatus(mpi_status_size)
  88. logical, public :: master=.false., slave=.false.
  89. ! some kinds. could use selected_real_kind(..) for this instead of hard coding
  90. integer, parameter :: dp=8, sp=4, long=8, short=2
  91. interface send
  92. module procedure &
  93. qmpi_send_real4, &
  94. qmpi_send_real4_1d, &
  95. qmpi_send_real4_2d, &
  96. qmpi_send_real4_3d, &
  97. qmpi_send_real4_4d, &
  98. qmpi_send_real8, &
  99. qmpi_send_real8_1d, &
  100. qmpi_send_real8_2d, &
  101. qmpi_send_real8_3d, &
  102. qmpi_send_real8_4d, &
  103. qmpi_send_integer4, &
  104. qmpi_send_integer4_1d, &
  105. qmpi_send_integer4_2d, &
  106. qmpi_send_integer4_3d, &
  107. qmpi_send_integer4_4d, &
  108. qmpi_send_integer8, &
  109. qmpi_send_integer8_1d, &
  110. qmpi_send_integer8_2d, &
  111. qmpi_send_integer8_3d, &
  112. qmpi_send_integer8_4d, &
  113. qmpi_send_string, &
  114. qmpi_send_character_1d,&
  115. qmpi_send_logical
  116. end interface
  117. interface receive
  118. module procedure &
  119. qmpi_recv_real4, &
  120. qmpi_recv_real4_1d, &
  121. qmpi_recv_real4_2d, &
  122. qmpi_recv_real4_3d, &
  123. qmpi_recv_real4_4d, &
  124. qmpi_recv_real8, &
  125. qmpi_recv_real8_1d, &
  126. qmpi_recv_real8_2d, &
  127. qmpi_recv_real8_3d, &
  128. qmpi_recv_real8_4d, &
  129. qmpi_recv_integer4, &
  130. qmpi_recv_integer4_1d, &
  131. qmpi_recv_integer4_2d, &
  132. qmpi_recv_integer4_3d, &
  133. qmpi_recv_integer4_4d, &
  134. qmpi_recv_integer8, &
  135. qmpi_recv_integer8_1d, &
  136. qmpi_recv_integer8_2d, &
  137. qmpi_recv_integer8_3d, &
  138. qmpi_recv_integer8_4d, &
  139. qmpi_recv_string, &
  140. qmpi_recv_character_1d,&
  141. qmpi_recv_logical
  142. end interface
  143. interface reduce
  144. module procedure &
  145. qmpi_integer_reduction, &
  146. qmpi_integer8_reduction,&
  147. qmpi_real_reduction, &
  148. qmpi_real8_reduction
  149. end interface
  150. interface broadcast
  151. module procedure &
  152. qmpi_broadcast_logical, &
  153. qmpi_broadcast_string, &
  154. qmpi_broadcast_stringarr,&
  155. qmpi_broadcast_integer4, &
  156. qmpi_broadcast_integer4_array1d, &
  157. qmpi_broadcast_integer4_array2d, &
  158. qmpi_broadcast_integer8, &
  159. qmpi_broadcast_integer8_array1d, &
  160. qmpi_broadcast_integer8_array2d, &
  161. qmpi_broadcast_real4, &
  162. qmpi_broadcast_real4_array1d, &
  163. qmpi_broadcast_real4_array2d, &
  164. qmpi_broadcast_real4_array3d, &
  165. qmpi_broadcast_real4_array4d, &
  166. qmpi_broadcast_real8, &
  167. qmpi_broadcast_real8_array1d, &
  168. qmpi_broadcast_real8_array2d, &
  169. qmpi_broadcast_real8_array3d, &
  170. qmpi_broadcast_real8_array4d
  171. end interface
  172. interface mbroadcast
  173. module procedure &
  174. qmpi_broadcast_logicals, &
  175. qmpi_broadcast_real4s, &
  176. qmpi_broadcast_real8s, &
  177. qmpi_broadcast_integer4s, &
  178. qmpi_broadcast_integer8s
  179. end interface
  180. contains
  181. subroutine start_mpi()
  182. !
  183. ! initialize the core MPI subsystem
  184. ! this routine should be called as the first statement in the program.
  185. ! MPI does not specify what happen before MPI_init and after mpi_finalize
  186. !
  187. implicit none
  188. call mpi_init(ierr)
  189. call mpi_comm_size(mpi_comm_world, qmpi_num_proc, ierr)
  190. call mpi_comm_rank(mpi_comm_world, qmpi_proc_num, ierr)
  191. master=.false.
  192. if(qmpi_proc_num==0) master=.true.
  193. if(qmpi_proc_num>0) slave=.true.
  194. print*,'Inne i start_mpi: qmpi_proc_num =',qmpi_proc_num,' master =',master
  195. if(master) then
  196. write(*,'(a,i0,a)') 'MPI started with ',qmpi_num_proc,' processors'
  197. end if
  198. end subroutine start_mpi
  199. subroutine stop_mpi()
  200. implicit none
  201. call mpi_finalize(ierr)
  202. stop
  203. end subroutine stop_mpi
  204. subroutine barrier(label)
  205. ! makes all processes sync at this point, optionally print a label
  206. implicit none
  207. character(*), optional :: label
  208. call mpi_barrier(mpi_comm_world, ierr)
  209. if(master.and.present(label)) print *,'---barrier---',label,'---------'
  210. end subroutine barrier
  211. subroutine qmpi_send_logical(data, target, tag)
  212. implicit none
  213. logical data
  214. integer target, counter, given_tag
  215. integer, optional :: tag
  216. given_tag=0
  217. if(present(tag)) given_tag=tag
  218. counter=1
  219. call mpi_send(data, counter, mpi_logical, target, given_tag, mpi_comm_world, ierr)
  220. if(ierr.ne.0)then
  221. print *,'error send_logical count=',counter,'tag=',given_tag
  222. stop
  223. end if
  224. end subroutine qmpi_send_logical
  225. subroutine qmpi_send_string(data, target, tag)
  226. implicit none
  227. character(*) data
  228. integer target, counter, given_tag
  229. integer, optional :: tag
  230. given_tag=0
  231. if(present(tag)) given_tag=tag
  232. counter=len(data)
  233. call mpi_send(data, counter, mpi_character, target, given_tag, mpi_comm_world, ierr)
  234. if(ierr.ne.0)then
  235. print *,'error send_string count=',counter,'tag=',given_tag
  236. stop
  237. end if
  238. end subroutine qmpi_send_string
  239. subroutine qmpi_send_character_1d(data, target, tag)
  240. implicit none
  241. character data(:)
  242. integer target, counter, given_tag
  243. integer, optional :: tag
  244. given_tag=0
  245. if(present(tag)) given_tag=tag
  246. counter=size(data)
  247. call mpi_send(data, counter, mpi_character, target, given_tag, mpi_comm_world, ierr)
  248. if(ierr.ne.0)then
  249. print *,'error send_character_1d count=',counter,'tag=',given_tag
  250. stop
  251. end if
  252. end subroutine qmpi_send_character_1d
  253. subroutine qmpi_recv_character_1d(data, target, tag)
  254. implicit none
  255. character data(:)
  256. integer target, counter, given_tag
  257. integer, optional :: tag
  258. given_tag=0
  259. if(present(tag)) given_tag=tag
  260. counter=size(data)
  261. call mpi_recv(data, counter, mpi_character, target, given_tag, mpi_comm_world, mpistatus, ierr)
  262. if(ierr.ne.0)then
  263. print *,'error recv_character_1d count=',counter,'tag=',given_tag
  264. stop
  265. end if
  266. end subroutine qmpi_recv_character_1d
  267. subroutine qmpi_send_integer4(data, target, tag)
  268. implicit none
  269. integer(sp) data
  270. integer target, counter, given_tag
  271. integer, optional :: tag
  272. given_tag=0
  273. if(present(tag)) given_tag=tag
  274. counter=1
  275. call mpi_send(data, counter, mpi_integer, target, given_tag, mpi_comm_world, ierr)
  276. if(ierr.ne.0)then
  277. print *,'error send_integer4 count=',counter,'tag=',given_tag
  278. stop
  279. end if
  280. end subroutine qmpi_send_integer4
  281. subroutine qmpi_send_integer4_1d(data, target, tag)
  282. implicit none
  283. integer(sp) data(:)
  284. integer target, counter, given_tag
  285. integer, optional :: tag
  286. given_tag=0
  287. if(present(tag)) given_tag=tag
  288. counter=size(data)
  289. call mpi_send(data, counter, mpi_integer, target, given_tag, mpi_comm_world, ierr)
  290. if(ierr.ne.0)then
  291. print *,'error send_integer4_1d count=',counter,'tag=',given_tag
  292. stop
  293. end if
  294. end subroutine qmpi_send_integer4_1d
  295. subroutine qmpi_send_integer4_2d(data, target, tag)
  296. implicit none
  297. integer(sp) data(:,:)
  298. integer target, counter, given_tag
  299. integer, optional :: tag
  300. given_tag=0
  301. if(present(tag)) given_tag=tag
  302. counter=size(data,1)*size(data,2)
  303. call mpi_send(data, counter, mpi_integer, target, given_tag, mpi_comm_world, ierr)
  304. if(ierr.ne.0)then
  305. print *,'error send_integer4_2d count=',counter,'tag=',given_tag
  306. stop
  307. end if
  308. end subroutine qmpi_send_integer4_2d
  309. subroutine qmpi_send_integer4_3d(data, target, tag)
  310. implicit none
  311. integer(sp) data(:,:,:)
  312. integer target, counter, given_tag
  313. integer, optional :: tag
  314. given_tag=0
  315. if(present(tag)) given_tag=tag
  316. counter=size(data,1)*size(data,2)*size(data,3)
  317. call mpi_send(data, counter, mpi_integer, target, given_tag, mpi_comm_world, ierr)
  318. if(ierr.ne.0)then
  319. print *,'error send_integer4_3d count=',counter,'tag=',given_tag
  320. stop
  321. end if
  322. end subroutine qmpi_send_integer4_3d
  323. subroutine qmpi_send_integer4_4d(data, target, tag)
  324. implicit none
  325. integer(sp) data(:,:,:,:)
  326. integer target, counter, given_tag
  327. integer, optional :: tag
  328. given_tag=0
  329. if(present(tag)) given_tag=tag
  330. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  331. call mpi_send(data, counter, mpi_integer, target, given_tag, mpi_comm_world, ierr)
  332. if(ierr.ne.0)then
  333. print *,'error send_integer4_4d count=',counter,'tag=',given_tag
  334. stop
  335. end if
  336. end subroutine qmpi_send_integer4_4d
  337. subroutine qmpi_send_integer8(data, target, tag)
  338. implicit none
  339. integer(long) data
  340. integer target, counter, given_tag
  341. integer, optional :: tag
  342. given_tag=0
  343. if(present(tag)) given_tag=tag
  344. counter=1
  345. call mpi_send(data, counter, mpi_integer8, target, given_tag, mpi_comm_world, ierr)
  346. if(ierr.ne.0)then
  347. print *,'error send_integer8 count=',counter,'tag=',given_tag
  348. stop
  349. end if
  350. end subroutine qmpi_send_integer8
  351. subroutine qmpi_send_integer8_1d(data, target, tag)
  352. implicit none
  353. integer(long) data(:)
  354. integer target, counter, given_tag
  355. integer, optional :: tag
  356. given_tag=0
  357. if(present(tag)) given_tag=tag
  358. counter=size(data)
  359. call mpi_send(data, counter, mpi_integer8, target, given_tag, mpi_comm_world, ierr)
  360. if(ierr.ne.0)then
  361. print *,'error send_integer8_1d count=',counter,'tag=',given_tag
  362. stop
  363. end if
  364. end subroutine qmpi_send_integer8_1d
  365. subroutine qmpi_send_integer8_2d(data, target, tag)
  366. implicit none
  367. integer(long) data(:,:)
  368. integer target, counter, given_tag
  369. integer, optional :: tag
  370. given_tag=0
  371. if(present(tag)) given_tag=tag
  372. counter=size(data,1)*size(data,2)
  373. call mpi_send(data, counter, mpi_integer8, target, given_tag, mpi_comm_world, ierr)
  374. if(ierr.ne.0)then
  375. print *,'error send_integer8_2d count=',counter,'tag=',given_tag
  376. stop
  377. end if
  378. end subroutine qmpi_send_integer8_2d
  379. subroutine qmpi_send_integer8_3d(data, target, tag)
  380. implicit none
  381. integer(8) data(:,:,:)
  382. integer target, counter, given_tag
  383. integer, optional :: tag
  384. given_tag=0
  385. if(present(tag)) given_tag=tag
  386. counter=size(data,1)*size(data,2)*size(data,3)
  387. call mpi_send(data, counter, mpi_integer8, target, given_tag, mpi_comm_world, ierr)
  388. if(ierr.ne.0)then
  389. print *,'error send_integer8_3d count=',counter,'tag=',given_tag
  390. stop
  391. end if
  392. end subroutine qmpi_send_integer8_3d
  393. subroutine qmpi_send_integer8_4d(data, target, tag)
  394. implicit none
  395. integer(8) data(:,:,:,:)
  396. integer target, counter, given_tag
  397. integer, optional :: tag
  398. given_tag=0
  399. if(present(tag)) given_tag=tag
  400. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  401. call mpi_send(data, counter, mpi_integer8, target, given_tag, mpi_comm_world, ierr)
  402. if(ierr.ne.0)then
  403. print *,'error send_integer8_4d count=',counter,'tag=',given_tag
  404. stop
  405. end if
  406. end subroutine qmpi_send_integer8_4d
  407. subroutine qmpi_send_real4(data, target, tag)
  408. implicit none
  409. real(sp) data
  410. integer target
  411. integer, optional :: tag
  412. integer counter, given_tag
  413. given_tag=0
  414. if(present(tag)) given_tag=tag
  415. counter=1
  416. call mpi_send(data, counter, mpi_real, target, given_tag, mpi_comm_world, ierr)
  417. if(ierr.ne.0)then
  418. print *,'error send_real4 count=',counter,'tag=',given_tag
  419. stop
  420. end if
  421. end subroutine qmpi_send_real4
  422. subroutine qmpi_send_real8(data, target, tag)
  423. implicit none
  424. real(dp) data
  425. integer target
  426. integer, optional :: tag
  427. integer counter, given_tag
  428. given_tag=0
  429. if(present(tag)) given_tag=tag
  430. counter=1
  431. call mpi_send(data, counter, mpi_double_precision, target, given_tag, mpi_comm_world, ierr)
  432. if(ierr.ne.0)then
  433. print *,'error send_real8 count=',counter,'tag=',given_tag
  434. stop
  435. end if
  436. end subroutine qmpi_send_real8
  437. subroutine qmpi_send_real4_1d(data, target, tag)
  438. implicit none
  439. real(sp) data(:)
  440. integer target
  441. integer, optional :: tag
  442. integer counter, given_tag
  443. given_tag=0
  444. if(present(tag)) given_tag=tag
  445. counter=size(data)
  446. call mpi_send(data, counter, mpi_real, target, given_tag, mpi_comm_world, ierr)
  447. if(ierr.ne.0)then
  448. print *,'error send_real4_1d count=',counter,'tag=',given_tag
  449. stop
  450. end if
  451. end subroutine qmpi_send_real4_1d
  452. subroutine qmpi_send_real8_1d(data, target, tag)
  453. implicit none
  454. real(dp) data(:)
  455. integer target
  456. integer, optional :: tag
  457. integer counter, given_tag
  458. given_tag=0
  459. if(present(tag)) given_tag=tag
  460. counter=size(data)
  461. call mpi_send(data, counter, mpi_double_precision, target, given_tag, mpi_comm_world, ierr)
  462. if(ierr.ne.0)then
  463. print *,'error send_real8_1d count=',counter,'tag=',given_tag
  464. stop
  465. end if
  466. end subroutine qmpi_send_real8_1d
  467. subroutine qmpi_send_real4_2d(data, target, tag)
  468. implicit none
  469. real(sp) data(:,:)
  470. integer target
  471. integer, optional :: tag
  472. integer counter, given_tag
  473. given_tag=0
  474. if(present(tag)) given_tag=tag
  475. counter=size(data,1)*size(data,2)
  476. call mpi_send(data, counter, mpi_real, target, given_tag, mpi_comm_world, ierr)
  477. if(ierr.ne.0)then
  478. print *,'error send_real4_2d count=',counter,'tag=',given_tag
  479. stop
  480. end if
  481. end subroutine qmpi_send_real4_2d
  482. subroutine qmpi_send_real8_2d(data, target, tag)
  483. implicit none
  484. real(dp) data(:,:)
  485. integer target
  486. integer, optional :: tag
  487. integer counter, given_tag
  488. given_tag=0
  489. if(present(tag)) given_tag=tag
  490. counter=size(data,1)*size(data,2)
  491. call mpi_send(data, counter, mpi_double_precision, target, given_tag, mpi_comm_world, ierr)
  492. if(ierr.ne.0)then
  493. print *,'error send_real8_2d count=',counter,'tag=',given_tag
  494. stop
  495. end if
  496. end subroutine qmpi_send_real8_2d
  497. subroutine qmpi_send_real4_3d(data, target, tag)
  498. implicit none
  499. real(sp) data(:,:,:)
  500. integer target
  501. integer, optional :: tag
  502. integer counter, given_tag
  503. given_tag=0
  504. if(present(tag)) given_tag=tag
  505. counter=size(data,1)*size(data,2)*size(data,3)
  506. call mpi_send(data, counter, mpi_real, target, given_tag, mpi_comm_world, ierr)
  507. if(ierr.ne.0)then
  508. print *,'error send_real4_3d count=',counter,'tag=',given_tag
  509. stop
  510. end if
  511. end subroutine qmpi_send_real4_3d
  512. subroutine qmpi_send_real8_3d(data, target, tag)
  513. implicit none
  514. real(dp) data(:,:,:)
  515. integer target
  516. integer, optional :: tag
  517. integer counter, given_tag
  518. given_tag=0
  519. if(present(tag)) given_tag=tag
  520. counter=size(data,1)*size(data,2)*size(data,3)
  521. call mpi_send(data, counter, mpi_double_precision, target, given_tag, mpi_comm_world, ierr)
  522. if(ierr.ne.0)then
  523. print *,'error send_real8_3d count=',counter,'tag=',given_tag
  524. stop
  525. end if
  526. end subroutine qmpi_send_real8_3d
  527. subroutine qmpi_send_real4_4d(data, target, tag)
  528. implicit none
  529. real(sp) data(:,:,:,:)
  530. integer target
  531. integer, optional :: tag
  532. integer counter, given_tag
  533. given_tag=0
  534. if(present(tag)) given_tag=tag
  535. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  536. call mpi_send(data, counter, mpi_real, target, given_tag, mpi_comm_world, ierr)
  537. if(ierr.ne.0)then
  538. print *,'error send_real4_4d count=',counter,'tag=',given_tag
  539. stop
  540. end if
  541. end subroutine qmpi_send_real4_4d
  542. subroutine qmpi_send_real8_4d(data, target, tag)
  543. implicit none
  544. real(dp) data(:,:,:,:)
  545. integer target
  546. integer, optional :: tag
  547. integer counter, given_tag
  548. given_tag=0
  549. if(present(tag)) given_tag=tag
  550. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  551. call mpi_send(data, counter, mpi_double_precision, target, given_tag, mpi_comm_world, ierr)
  552. if(ierr.ne.0)then
  553. print *,'error send_real8_4d count=',counter,'tag=',given_tag
  554. stop
  555. end if
  556. end subroutine qmpi_send_real8_4d
  557. subroutine qmpi_recv_integer4(data, source, tag)
  558. implicit none
  559. integer(sp) data
  560. integer source, counter, given_tag
  561. integer, optional :: tag
  562. given_tag=0
  563. if(present(tag)) given_tag=tag
  564. counter=1
  565. call mpi_recv(data, counter, mpi_integer, source, given_tag, mpi_comm_world, mpistatus, ierr)
  566. if(ierr.ne.0)then
  567. print *,'error recv_integer4_1d count=',counter,'tag=',given_tag
  568. stop
  569. end if
  570. end subroutine qmpi_recv_integer4
  571. subroutine qmpi_recv_integer4_1d(data, source, tag)
  572. implicit none
  573. integer(sp) data(:)
  574. integer source, counter, given_tag
  575. integer, optional :: tag
  576. given_tag=0
  577. if(present(tag)) given_tag=tag
  578. counter=size(data)
  579. call mpi_recv(data, counter, mpi_integer, source, given_tag, mpi_comm_world, mpistatus, ierr)
  580. if(ierr.ne.0)then
  581. print *,'error recv_integer4_1d count=',counter,'tag=',given_tag
  582. stop
  583. end if
  584. end subroutine qmpi_recv_integer4_1d
  585. subroutine qmpi_recv_integer4_2d(data, source, tag)
  586. implicit none
  587. integer(sp) data(:,:)
  588. integer source, counter, given_tag
  589. integer, optional :: tag
  590. given_tag=0
  591. if(present(tag)) given_tag=tag
  592. counter=size(data,1)*size(data,2)
  593. call mpi_recv(data, counter, mpi_integer, source, given_tag, mpi_comm_world, mpistatus, ierr)
  594. if(ierr.ne.0)then
  595. print *,'error recv_integer4_2d count=',counter,'tag=',given_tag
  596. stop
  597. end if
  598. end subroutine qmpi_recv_integer4_2d
  599. subroutine qmpi_recv_integer4_3d(data, source, tag)
  600. implicit none
  601. integer(sp) data(:,:,:)
  602. integer source, counter, given_tag
  603. integer, optional :: tag
  604. given_tag=0
  605. if(present(tag)) given_tag=tag
  606. counter=size(data,1)*size(data,2)*size(data,3)
  607. call mpi_recv(data, counter, mpi_integer, source, given_tag, mpi_comm_world, mpistatus, ierr)
  608. if(ierr.ne.0)then
  609. print *,'error recv_integer4_3d count=',counter,'tag=',given_tag
  610. stop
  611. end if
  612. end subroutine qmpi_recv_integer4_3d
  613. subroutine qmpi_recv_integer4_4d(data, source, tag)
  614. implicit none
  615. integer(sp) data(:,:,:,:)
  616. integer source, counter, given_tag
  617. integer, optional :: tag
  618. given_tag=0
  619. if(present(tag)) given_tag=tag
  620. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  621. call mpi_recv(data, counter, mpi_integer, source, given_tag, mpi_comm_world, mpistatus, ierr)
  622. if(ierr.ne.0)then
  623. print *,'error recv_integer4_4d count=',counter,'tag=',given_tag
  624. stop
  625. end if
  626. end subroutine qmpi_recv_integer4_4d
  627. subroutine qmpi_recv_integer8(data, source, tag)
  628. implicit none
  629. integer(long) data
  630. integer source, counter, given_tag
  631. integer, optional :: tag
  632. given_tag=0
  633. if(present(tag)) given_tag=tag
  634. counter=1
  635. call mpi_recv(data, counter, mpi_integer8, source, given_tag, mpi_comm_world, mpistatus, ierr)
  636. if(ierr.ne.0)then
  637. print *,'error recv_integer8 count=',counter,'tag=',given_tag
  638. stop
  639. end if
  640. end subroutine qmpi_recv_integer8
  641. subroutine qmpi_recv_integer8_1d(data, source, tag)
  642. implicit none
  643. integer(long) data(:)
  644. integer source, counter, given_tag
  645. integer, optional :: tag
  646. given_tag=0
  647. if(present(tag)) given_tag=tag
  648. counter=size(data)
  649. call mpi_recv(data, counter, mpi_integer8, source, given_tag, mpi_comm_world, mpistatus, ierr)
  650. if(ierr.ne.0)then
  651. print *,'error recv_integer8_1d count=',counter,'tag=',given_tag
  652. stop
  653. end if
  654. end subroutine qmpi_recv_integer8_1d
  655. subroutine qmpi_recv_integer8_2d(data, source, tag)
  656. implicit none
  657. integer(long) data(:,:)
  658. integer source, counter, given_tag
  659. integer, optional :: tag
  660. given_tag=0
  661. if(present(tag)) given_tag=tag
  662. counter=size(data,1)*size(data,2)
  663. call mpi_recv(data, counter, mpi_integer8, source, given_tag, mpi_comm_world, mpistatus, ierr)
  664. if(ierr.ne.0)then
  665. print *,'error recv_integer8_2d count=',counter,'tag=',given_tag
  666. stop
  667. end if
  668. end subroutine qmpi_recv_integer8_2d
  669. subroutine qmpi_recv_integer8_3d(data, source, tag)
  670. implicit none
  671. integer(8) data(:,:,:)
  672. integer source, counter, given_tag
  673. integer, optional :: tag
  674. given_tag=0
  675. if(present(tag)) given_tag=tag
  676. counter=size(data,1)*size(data,2)*size(data,3)
  677. call mpi_recv(data, counter, mpi_integer8, source, given_tag, mpi_comm_world, mpistatus, ierr)
  678. if(ierr.ne.0)then
  679. print *,'error recv_integer8_3d count=',counter,'tag=',given_tag
  680. stop
  681. end if
  682. end subroutine qmpi_recv_integer8_3d
  683. subroutine qmpi_recv_integer8_4d(data, source, tag)
  684. implicit none
  685. integer(8) data(:,:,:,:)
  686. integer source, counter, given_tag
  687. integer, optional :: tag
  688. given_tag=0
  689. if(present(tag)) given_tag=tag
  690. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  691. call mpi_recv(data, counter, mpi_integer8, source, given_tag, mpi_comm_world, mpistatus, ierr)
  692. if(ierr.ne.0)then
  693. print *,'error recv_integer8_4d count=',counter,'tag=',given_tag
  694. stop
  695. end if
  696. end subroutine qmpi_recv_integer8_4d
  697. subroutine qmpi_recv_real4(data, source, tag)
  698. implicit none
  699. real(sp) data
  700. integer source
  701. integer, optional :: tag
  702. integer counter, given_tag
  703. given_tag=0
  704. if(present(tag)) given_tag=tag
  705. counter=1
  706. call mpi_recv(data, counter, mpi_real, source, given_tag, mpi_comm_world, mpistatus, ierr)
  707. if(ierr.ne.0)then
  708. print *,'error recv_real4 count=',counter,'tag=',given_tag
  709. stop
  710. end if
  711. end subroutine qmpi_recv_real4
  712. subroutine qmpi_recv_real8(data, source, tag)
  713. implicit none
  714. real(dp) data
  715. integer source
  716. integer, optional :: tag
  717. integer counter, given_tag
  718. given_tag=0
  719. if(present(tag)) given_tag=tag
  720. counter=1
  721. call mpi_recv(data, counter, mpi_double_precision, source, given_tag, mpi_comm_world, mpistatus, ierr)
  722. if(ierr.ne.0)then
  723. print *,'error recv_real8 count=',counter,'tag=',given_tag
  724. stop
  725. end if
  726. end subroutine qmpi_recv_real8
  727. subroutine qmpi_recv_real4_1d(data, source, tag)
  728. implicit none
  729. real(sp) data(:)
  730. integer source
  731. integer, optional :: tag
  732. integer counter, given_tag
  733. given_tag=0
  734. if(present(tag)) given_tag=tag
  735. counter=size(data)
  736. call mpi_recv(data, counter, mpi_real, source, given_tag, mpi_comm_world, mpistatus, ierr)
  737. if(ierr.ne.0)then
  738. print *,'error recv_real4_1d count=',counter,'tag=',given_tag
  739. stop
  740. end if
  741. end subroutine qmpi_recv_real4_1d
  742. subroutine qmpi_recv_real8_1d(data, source, tag)
  743. implicit none
  744. real(dp) data(:)
  745. integer source
  746. integer, optional :: tag
  747. integer counter, given_tag
  748. given_tag=0
  749. if(present(tag)) given_tag=tag
  750. counter=size(data)
  751. call mpi_recv(data, counter, mpi_double_precision, source, given_tag, mpi_comm_world, mpistatus, ierr)
  752. if(ierr.ne.0)then
  753. print *,'error recv_real8_1d count=',counter,'tag=',given_tag
  754. stop
  755. end if
  756. end subroutine qmpi_recv_real8_1d
  757. subroutine qmpi_recv_real4_2d(data, source, tag)
  758. implicit none
  759. real(sp) data(:,:)
  760. integer source
  761. integer, optional :: tag
  762. integer counter, given_tag
  763. given_tag=0
  764. if(present(tag)) given_tag=tag
  765. counter=size(data,1)*size(data,2)
  766. call mpi_recv(data, counter, mpi_real, source, given_tag, mpi_comm_world, mpistatus, ierr)
  767. if(ierr.ne.0)then
  768. print *,'error recv_real4_2d count=',counter,'tag=',given_tag
  769. stop
  770. end if
  771. end subroutine qmpi_recv_real4_2d
  772. subroutine qmpi_recv_real8_2d(data, source, tag)
  773. implicit none
  774. real(dp) data(:,:)
  775. integer source
  776. integer, optional :: tag
  777. integer counter, given_tag
  778. given_tag=0
  779. if(present(tag)) given_tag=tag
  780. counter=size(data,1)*size(data,2)
  781. call mpi_recv(data, counter, mpi_double_precision, source, given_tag, mpi_comm_world, mpistatus, ierr)
  782. if(ierr.ne.0)then
  783. print *,'error recv_real8_2d count=',counter,'tag=',given_tag
  784. stop
  785. end if
  786. end subroutine qmpi_recv_real8_2d
  787. subroutine qmpi_recv_real4_3d(data, source, tag)
  788. implicit none
  789. real(sp) data(:,:,:)
  790. integer source
  791. integer, optional :: tag
  792. integer counter, given_tag
  793. given_tag=0
  794. if(present(tag)) given_tag=tag
  795. counter=size(data,1)*size(data,2)*size(data,3)
  796. call mpi_recv(data, counter, mpi_real, source, given_tag, mpi_comm_world, mpistatus, ierr)
  797. if(ierr.ne.0)then
  798. print *,'error recv_real4_3d count=',counter,'tag=',given_tag
  799. stop
  800. end if
  801. end subroutine qmpi_recv_real4_3d
  802. subroutine qmpi_recv_real8_3d(data, source, tag)
  803. implicit none
  804. real(dp) data(:,:,:)
  805. integer source
  806. integer, optional :: tag
  807. integer counter, given_tag
  808. given_tag=0
  809. if(present(tag)) given_tag=tag
  810. counter=size(data,1)*size(data,2)*size(data,3)
  811. call mpi_recv(data, counter, mpi_double_precision, source, given_tag, mpi_comm_world, mpistatus, ierr)
  812. if(ierr.ne.0)then
  813. print *,'error recv_real8_3d count=',counter,'tag=',given_tag
  814. stop
  815. end if
  816. end subroutine qmpi_recv_real8_3d
  817. subroutine qmpi_recv_real4_4d(data, source, tag)
  818. implicit none
  819. real(sp) data(:,:,:,:)
  820. integer source
  821. integer, optional :: tag
  822. integer counter, given_tag
  823. given_tag=0
  824. if(present(tag)) given_tag=tag
  825. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  826. call mpi_recv(data, counter, mpi_real, source, given_tag, mpi_comm_world, mpistatus, ierr)
  827. if(ierr.ne.0)then
  828. print *,'error recv_real4_4d count=',counter,'tag=',given_tag
  829. stop
  830. end if
  831. end subroutine qmpi_recv_real4_4d
  832. subroutine qmpi_recv_real8_4d(data, source, tag)
  833. implicit none
  834. real(dp) data(:,:,:,:)
  835. integer source
  836. integer, optional :: tag
  837. integer counter, given_tag
  838. given_tag=0
  839. if(present(tag)) given_tag=tag
  840. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  841. call mpi_recv(data, counter, mpi_double_precision, source, given_tag, mpi_comm_world, mpistatus, ierr)
  842. if(ierr.ne.0)then
  843. print *,'error recv_real8_4d count=',counter,'tag=',given_tag
  844. stop
  845. end if
  846. end subroutine qmpi_recv_real8_4d
  847. subroutine qmpi_recv_logical(data, target, tag)
  848. implicit none
  849. logical data
  850. integer target, counter, given_tag
  851. integer, optional :: tag
  852. given_tag=0
  853. if(present(tag)) given_tag=tag
  854. counter=1
  855. call mpi_recv(data, counter, mpi_logical, target, given_tag, mpi_comm_world, mpistatus, ierr)
  856. if(ierr.ne.0)then
  857. print *,'error recv_logical count=',counter,'tag=',given_tag
  858. stop
  859. end if
  860. end subroutine qmpi_recv_logical
  861. subroutine qmpi_recv_string(data, target, tag)
  862. implicit none
  863. character(*) data
  864. integer target, counter, given_tag
  865. integer, optional :: tag
  866. given_tag=0
  867. if(present(tag)) given_tag=tag
  868. counter=len(data)
  869. call mpi_recv(data, counter, mpi_character, target, given_tag, mpi_comm_world, mpistatus, ierr)
  870. if(ierr.ne.0)then
  871. print *,'error recv_string count=',counter,'tag=',given_tag
  872. stop
  873. end if
  874. end subroutine qmpi_recv_string
  875. subroutine qmpi_broadcast_string(string,root)
  876. !
  877. ! send string out to all processes. if not given
  878. ! process 0 will be used as the sender - root otherwise.
  879. !
  880. implicit none
  881. character(len=*) string
  882. integer, optional :: root
  883. integer counter,boss
  884. counter=len(string)
  885. boss=0
  886. if(present(root)) then
  887. boss=root
  888. end if
  889. call mpi_bcast(string , counter, mpi_character, boss, mpi_comm_world ,ierr)
  890. end subroutine qmpi_broadcast_string
  891. subroutine qmpi_broadcast_stringarr(data,root)
  892. implicit none
  893. character(len=*) data(:)
  894. integer, optional :: root
  895. integer counter, boss
  896. counter=len(data(1))*size(data)
  897. boss=0
  898. if(present(root)) then
  899. boss=root
  900. end if
  901. call mpi_bcast(data, counter, mpi_character, boss, mpi_comm_world ,ierr)
  902. end subroutine qmpi_broadcast_stringarr
  903. subroutine qmpi_broadcast_real4(data,root)
  904. implicit none
  905. real(4) data
  906. integer, optional :: root
  907. integer counter,boss
  908. counter=1
  909. boss=0
  910. if(present(root)) boss=root
  911. call mpi_bcast(data , counter, mpi_real, boss, mpi_comm_world, ierr)
  912. end subroutine qmpi_broadcast_real4
  913. subroutine qmpi_broadcast_real8(data,root)
  914. implicit none
  915. real(8) data
  916. integer, optional :: root
  917. integer counter,boss
  918. counter=1
  919. boss=0
  920. if(present(root)) boss=root
  921. call mpi_bcast(data , counter, mpi_double_precision, boss, mpi_comm_world, ierr)
  922. end subroutine qmpi_broadcast_real8
  923. subroutine qmpi_broadcast_integer4(data,root)
  924. implicit none
  925. integer(4) data
  926. integer, optional :: root
  927. integer counter,boss
  928. counter=1
  929. boss=0
  930. if(present(root)) boss=root
  931. call mpi_bcast(data , counter, mpi_integer, boss, mpi_comm_world, ierr)
  932. end subroutine qmpi_broadcast_integer4
  933. subroutine qmpi_broadcast_integer8(data,root)
  934. implicit none
  935. integer(8) data
  936. integer, optional :: root
  937. integer counter,boss
  938. counter=1
  939. boss=0
  940. if(present(root)) boss=root
  941. call mpi_bcast(data , counter, mpi_integer8, boss, mpi_comm_world, ierr)
  942. end subroutine qmpi_broadcast_integer8
  943. subroutine qmpi_broadcast_logical(data, root)
  944. implicit none
  945. logical data
  946. integer, optional :: root
  947. integer counter,boss
  948. counter=1
  949. boss=0
  950. if(present(root)) boss=root
  951. call mpi_bcast(data , counter, mpi_logical, boss, mpi_comm_world, ierr)
  952. end subroutine qmpi_broadcast_logical
  953. subroutine qmpi_broadcast_integer4_array1d(data,root)
  954. implicit none
  955. integer(sp) data(:)
  956. integer, optional :: root
  957. integer counter,boss
  958. counter=size(data)
  959. boss=0
  960. if(present(root)) then
  961. boss=root
  962. end if
  963. call mpi_bcast(data , counter, mpi_integer, boss, mpi_comm_world ,ierr)
  964. end subroutine qmpi_broadcast_integer4_array1d
  965. subroutine qmpi_broadcast_integer8_array1d(data,root)
  966. implicit none
  967. integer(long) data(:)
  968. integer, optional :: root
  969. integer counter,boss
  970. counter=size(data)
  971. boss=0
  972. if(present(root)) then
  973. boss=root
  974. end if
  975. call mpi_bcast(data , counter, mpi_integer8, boss, mpi_comm_world ,ierr)
  976. end subroutine qmpi_broadcast_integer8_array1d
  977. subroutine qmpi_broadcast_integer4_array2d(data,root)
  978. implicit none
  979. integer(sp) data(:,:)
  980. integer, optional :: root
  981. integer counter,boss
  982. counter=size(data,1)*size(data,2)
  983. boss=0
  984. if(present(root)) then
  985. boss=root
  986. end if
  987. call mpi_bcast(data , counter, mpi_integer, boss, mpi_comm_world ,ierr)
  988. end subroutine qmpi_broadcast_integer4_array2d
  989. subroutine qmpi_broadcast_integer8_array2d(data,root)
  990. implicit none
  991. integer(long) data(:,:)
  992. integer, optional :: root
  993. integer counter,boss
  994. counter=size(data,1)*size(data,2)
  995. boss=0
  996. if(present(root)) then
  997. boss=root
  998. end if
  999. call mpi_bcast(data , counter, mpi_integer8, boss, mpi_comm_world ,ierr)
  1000. end subroutine qmpi_broadcast_integer8_array2d
  1001. subroutine qmpi_broadcast_real4_array1d(data,root)
  1002. implicit none
  1003. real(sp) data(:)
  1004. integer, optional :: root
  1005. integer counter, boss
  1006. counter=size(data)
  1007. boss=0
  1008. if(present(root)) then
  1009. boss=root
  1010. end if
  1011. call mpi_bcast(data , counter, mpi_real, boss, mpi_comm_world ,ierr)
  1012. end subroutine qmpi_broadcast_real4_array1d
  1013. subroutine qmpi_broadcast_real8_array1d(data,root)
  1014. implicit none
  1015. real(dp) data(:)
  1016. integer, optional :: root
  1017. integer counter, boss
  1018. counter=size(data)
  1019. boss=0
  1020. if(present(root)) then
  1021. boss=root
  1022. end if
  1023. call mpi_bcast(data , counter, mpi_double_precision, boss, mpi_comm_world ,ierr)
  1024. end subroutine qmpi_broadcast_real8_array1d
  1025. subroutine qmpi_broadcast_real4_array2d(data,root)
  1026. implicit none
  1027. real(sp) data(:,:)
  1028. integer, optional :: root
  1029. integer counter, boss
  1030. counter=size(data,1)*size(data,2)
  1031. boss=0
  1032. if(present(root)) then
  1033. boss=root
  1034. end if
  1035. call mpi_bcast(data, counter, mpi_real, boss, mpi_comm_world ,ierr)
  1036. end subroutine qmpi_broadcast_real4_array2d
  1037. subroutine qmpi_broadcast_real8_array2d(data,root)
  1038. implicit none
  1039. real(dp) data(:,:)
  1040. integer, optional :: root
  1041. integer counter, boss
  1042. counter=size(data,1)*size(data,2)
  1043. boss=0
  1044. if(present(root)) then
  1045. boss=root
  1046. end if
  1047. call mpi_bcast(data, counter, mpi_double_precision, boss, mpi_comm_world ,ierr)
  1048. end subroutine qmpi_broadcast_real8_array2d
  1049. subroutine qmpi_broadcast_real4_array3d(data,root)
  1050. implicit none
  1051. real(sp) data(:,:,:)
  1052. integer, optional :: root
  1053. integer counter, boss
  1054. counter=size(data,1)*size(data,2)*size(data,3)
  1055. boss=0
  1056. if(present(root)) then
  1057. boss=root
  1058. end if
  1059. call mpi_bcast(data , counter, mpi_real, boss, mpi_comm_world ,ierr)
  1060. end subroutine qmpi_broadcast_real4_array3d
  1061. subroutine qmpi_broadcast_real8_array3d(data,root)
  1062. implicit none
  1063. real(dp) data(:,:,:)
  1064. integer, optional :: root
  1065. integer counter, boss
  1066. counter=size(data,1)*size(data,2)*size(data,3)
  1067. boss=0
  1068. if(present(root)) then
  1069. boss=root
  1070. end if
  1071. call mpi_bcast(data , counter, mpi_double_precision, boss, mpi_comm_world ,ierr)
  1072. end subroutine qmpi_broadcast_real8_array3d
  1073. subroutine qmpi_broadcast_real4_array4d(data,root)
  1074. implicit none
  1075. real(sp) data(:,:,:,:)
  1076. integer, optional :: root
  1077. integer counter, boss
  1078. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  1079. boss=0
  1080. if(present(root)) then
  1081. boss=root
  1082. end if
  1083. call mpi_bcast(data , counter, mpi_real, boss, mpi_comm_world ,ierr)
  1084. end subroutine qmpi_broadcast_real4_array4d
  1085. subroutine qmpi_broadcast_real8_array4d(data,root)
  1086. implicit none
  1087. real(dp) data(:,:,:,:)
  1088. integer, optional :: root
  1089. integer counter, boss
  1090. counter=size(data,1)*size(data,2)*size(data,3)*size(data,4)
  1091. boss=0
  1092. if(present(root)) then
  1093. boss=root
  1094. end if
  1095. call mpi_bcast(data , counter, mpi_double_precision, boss, mpi_comm_world ,ierr)
  1096. end subroutine qmpi_broadcast_real8_array4d
  1097. subroutine qmpi_broadcast_real4s(a,b,c,d,e,f,root)
  1098. !
  1099. ! send a,b,c,d,e,f out to all processes. if not given
  1100. ! process 0 will be used as the sender - root otherwise.
  1101. !
  1102. implicit none
  1103. real(sp) a
  1104. real(sp), optional :: b,c,d,e,f
  1105. integer, optional :: root
  1106. integer counter,boss
  1107. real(sp) rbuff(6)
  1108. counter=0 ; boss=0
  1109. if(present(root)) then
  1110. boss=root
  1111. end if
  1112. ! if(present(a)) then
  1113. counter=counter+1
  1114. rbuff(counter)=a
  1115. ! end if
  1116. if(present(b)) then
  1117. counter=counter+1
  1118. rbuff(counter)=b
  1119. end if
  1120. if(present(c)) then
  1121. counter=counter+1
  1122. rbuff(counter)=c
  1123. end if
  1124. if(present(d)) then
  1125. counter=counter+1
  1126. rbuff(counter)=d
  1127. end if
  1128. if(present(e)) then
  1129. counter=counter+1
  1130. rbuff(counter)=e
  1131. end if
  1132. if(present(f)) then
  1133. counter=counter+1
  1134. rbuff(counter)=f
  1135. end if
  1136. call mpi_bcast(rbuff , counter, mpi_real, boss, mpi_comm_world ,ierr)
  1137. counter=1
  1138. a=rbuff(counter)
  1139. if(present(b)) then
  1140. counter=counter+1
  1141. b=rbuff(counter)
  1142. end if
  1143. if(present(c)) then
  1144. counter=counter+1
  1145. c=rbuff(counter)
  1146. end if
  1147. if(present(d)) then
  1148. counter=counter+1
  1149. d=rbuff(counter)
  1150. end if
  1151. if(present(e)) then
  1152. counter=counter+1
  1153. e=rbuff(counter)
  1154. end if
  1155. if(present(f)) then
  1156. counter=counter+1
  1157. f=rbuff(counter)
  1158. end if
  1159. end subroutine qmpi_broadcast_real4s
  1160. subroutine qmpi_broadcast_real8s(a,b,c,d,e,f,root)
  1161. !
  1162. ! send a,b,c,d,e,f out to all processes. if not given
  1163. ! process 0 will be used as the sender - root otherwise.
  1164. !
  1165. implicit none
  1166. real(dp) a
  1167. real(dp), optional :: b,c,d,e,f
  1168. integer, optional :: root
  1169. integer counter,boss
  1170. real(kind=8) rbuff(6)
  1171. boss=0
  1172. if(present(root)) then
  1173. boss=root
  1174. end if
  1175. counter=1
  1176. rbuff(counter)=a
  1177. if(present(b)) then
  1178. counter=counter+1
  1179. rbuff(counter)=b
  1180. end if
  1181. if(present(c)) then
  1182. counter=counter+1
  1183. rbuff(counter)=c
  1184. end if
  1185. if(present(d)) then
  1186. counter=counter+1
  1187. rbuff(counter)=d
  1188. end if
  1189. if(present(e)) then
  1190. counter=counter+1
  1191. rbuff(counter)=e
  1192. end if
  1193. if(present(f)) then
  1194. counter=counter+1
  1195. rbuff(counter)=f
  1196. end if
  1197. call mpi_bcast(rbuff , counter, mpi_double_precision, boss, mpi_comm_world ,ierr)
  1198. counter=1
  1199. a=rbuff(counter)
  1200. if(present(b)) then
  1201. counter=counter+1
  1202. b=rbuff(counter)
  1203. end if
  1204. if(present(c)) then
  1205. counter=counter+1
  1206. c=rbuff(counter)
  1207. end if
  1208. if(present(d)) then
  1209. counter=counter+1
  1210. d=rbuff(counter)
  1211. end if
  1212. if(present(e)) then
  1213. counter=counter+1
  1214. e=rbuff(counter)
  1215. end if
  1216. if(present(f)) then
  1217. counter=counter+1
  1218. f=rbuff(counter)
  1219. end if
  1220. end subroutine qmpi_broadcast_real8s
  1221. subroutine qmpi_broadcast_logicals(a,b,c,d,e,f,root)
  1222. !
  1223. ! send a,b,c,d,e,f out to all processes. if not given
  1224. ! process 0 will be used as the sender - root otherwise.
  1225. !
  1226. implicit none
  1227. logical a
  1228. logical, optional :: b,c,d,e,f
  1229. integer, optional :: root
  1230. integer counter,boss
  1231. logical lbuff(6)
  1232. boss=0
  1233. if(present(root)) then
  1234. boss=root
  1235. end if
  1236. counter=1
  1237. lbuff(counter)=a
  1238. if(present(b)) then
  1239. counter=counter+1
  1240. lbuff(counter)=b
  1241. end if
  1242. if(present(c)) then
  1243. counter=counter+1
  1244. lbuff(counter)=c
  1245. end if
  1246. if(present(d)) then
  1247. counter=counter+1
  1248. lbuff(counter)=d
  1249. end if
  1250. if(present(e)) then
  1251. counter=counter+1
  1252. lbuff(counter)=e
  1253. end if
  1254. if(present(f)) then
  1255. counter=counter+1
  1256. lbuff(counter)=f
  1257. end if
  1258. call mpi_bcast(lbuff , counter, mpi_logical, boss, mpi_comm_world ,ierr)
  1259. counter=1
  1260. a=lbuff(counter)
  1261. if(present(b)) then
  1262. counter=counter+1
  1263. b=lbuff(counter)
  1264. end if
  1265. if(present(c)) then
  1266. counter=counter+1
  1267. c=lbuff(counter)
  1268. end if
  1269. if(present(d)) then
  1270. counter=counter+1
  1271. d=lbuff(counter)
  1272. end if
  1273. if(present(e)) then
  1274. counter=counter+1
  1275. e=lbuff(counter)
  1276. end if
  1277. if(present(f)) then
  1278. counter=counter+1
  1279. f=lbuff(counter)
  1280. end if
  1281. end subroutine qmpi_broadcast_logicals
  1282. subroutine qmpi_broadcast_integer4s(a,b,c,d,e,f,root)
  1283. !
  1284. ! send a,b,c,d,e,f out to all processes. if not given
  1285. ! process 0 will be used as the sender - root otherwise.
  1286. !
  1287. implicit none
  1288. integer(sp) a
  1289. integer(sp), optional :: b,c,d,e,f,root
  1290. integer counter,boss
  1291. integer ibuff(6)
  1292. boss=0
  1293. if(present(root)) then
  1294. boss=root
  1295. end if
  1296. counter=1
  1297. ! if(present(a)) then
  1298. ! counter=counter+1
  1299. ibuff(counter)=a
  1300. ! end if
  1301. if(present(b)) then
  1302. counter=counter+1
  1303. ibuff(counter)=b
  1304. end if
  1305. if(present(c)) then
  1306. counter=counter+1
  1307. ibuff(counter)=c
  1308. end if
  1309. if(present(d)) then
  1310. counter=counter+1
  1311. ibuff(counter)=d
  1312. end if
  1313. if(present(e)) then
  1314. counter=counter+1
  1315. ibuff(counter)=e
  1316. end if
  1317. if(present(f)) then
  1318. counter=counter+1
  1319. ibuff(counter)=f
  1320. end if
  1321. call mpi_bcast(ibuff , counter, mpi_integer, boss, mpi_comm_world ,ierr)
  1322. counter=1
  1323. a=ibuff(counter)
  1324. if(present(b)) then
  1325. counter=counter+1
  1326. b=ibuff(counter)
  1327. end if
  1328. if(present(c)) then
  1329. counter=counter+1
  1330. c=ibuff(counter)
  1331. end if
  1332. if(present(d)) then
  1333. counter=counter+1
  1334. d=ibuff(counter)
  1335. end if
  1336. if(present(e)) then
  1337. counter=counter+1
  1338. e=ibuff(counter)
  1339. end if
  1340. if(present(f)) then
  1341. counter=counter+1
  1342. f=ibuff(counter)
  1343. end if
  1344. end subroutine qmpi_broadcast_integer4s
  1345. subroutine qmpi_broadcast_integer8s(a,b,c,d,e,f,root)
  1346. !
  1347. ! send a,b,c,d,e,f out to all processes. if not given
  1348. ! process 0 will be used as the sender - root otherwise.
  1349. !
  1350. implicit none
  1351. integer(long) a
  1352. integer(long), optional :: b,c,d,e,f,root
  1353. integer counter,boss
  1354. integer ibuff(6)
  1355. boss=0
  1356. if(present(root)) then
  1357. boss=root
  1358. end if
  1359. counter=1
  1360. ! if(present(a)) then
  1361. ! counter=counter+1
  1362. ibuff(counter)=a
  1363. ! end if
  1364. if(present(b)) then
  1365. counter=counter+1
  1366. ibuff(counter)=b
  1367. end if
  1368. if(present(c)) then
  1369. counter=counter+1
  1370. ibuff(counter)=c
  1371. end if
  1372. if(present(d)) then
  1373. counter=counter+1
  1374. ibuff(counter)=d
  1375. end if
  1376. if(present(e)) then
  1377. counter=counter+1
  1378. ibuff(counter)=e
  1379. end if
  1380. if(present(f)) then
  1381. counter=counter+1
  1382. ibuff(counter)=f
  1383. end if
  1384. call mpi_bcast(ibuff , counter, mpi_integer8, boss, mpi_comm_world ,ierr)
  1385. counter=1
  1386. a=ibuff(counter)
  1387. if(present(b)) then
  1388. counter=counter+1
  1389. b=ibuff(counter)
  1390. end if
  1391. if(present(c)) then
  1392. counter=counter+1
  1393. c=ibuff(counter)
  1394. end if
  1395. if(present(d)) then
  1396. counter=counter+1
  1397. d=ibuff(counter)
  1398. end if
  1399. if(present(e)) then
  1400. counter=counter+1
  1401. e=ibuff(counter)
  1402. end if
  1403. if(present(f)) then
  1404. counter=counter+1
  1405. f=ibuff(counter)
  1406. end if
  1407. end subroutine qmpi_broadcast_integer8s
  1408. subroutine qmpi_real_reduction(type,a,b,c,d,e,f,root)
  1409. !
  1410. ! perform a reduction of 'type' on each of the given arguments a - f.
  1411. ! if type is:
  1412. ! 'sum': for each argument, return the sum of the argument over all processors
  1413. ! 'mul': the product
  1414. ! 'min': the minimum value
  1415. ! 'max': the maximum value
  1416. ! root is an optional argument, if given only return the result on that processor (reduce)
  1417. ! the default is to return the result on all processors (allreduce)
  1418. !
  1419. implicit none
  1420. character(3) type
  1421. real(sp) a
  1422. real(sp), optional, intent(inout) :: b,c,d,e,f
  1423. integer, optional :: root
  1424. integer counter,boss
  1425. integer, parameter :: dp=8
  1426. real(dp) rbuff(6),globrbuff(6)
  1427. if( trim(type).ne.'sum' .and. trim(type).ne.'mul' .and. trim(type).ne.'min' .and. trim(type).ne.'max')then
  1428. print *,'qmpi.f90 reduce error: reduction of type ',type,'not supported'
  1429. stop
  1430. end if
  1431. boss=0
  1432. if(present(root)) boss=root
  1433. globrbuff(:)=0.0
  1434. counter=0
  1435. ! if(present(a)) then
  1436. counter=counter+1
  1437. rbuff(counter)=real(a,dp)
  1438. ! end if
  1439. if(present(b)) then
  1440. counter=counter+1
  1441. rbuff(counter)=real(b,dp)
  1442. end if
  1443. if(present(c)) then
  1444. counter=counter+1
  1445. rbuff(counter)=real(c,dp)
  1446. end if
  1447. if(present(d)) then
  1448. counter=counter+1
  1449. rbuff(counter)=real(d,dp)
  1450. end if
  1451. if(present(e)) then
  1452. counter=counter+1
  1453. rbuff(counter)=real(e,dp)
  1454. end if
  1455. if(present(f)) then
  1456. counter=counter+1
  1457. rbuff(counter)=real(f,dp)
  1458. end if
  1459. select case(type)
  1460. case('sum')
  1461. if(present(root))then
  1462. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_sum,boss,mpi_comm_world,ierr)
  1463. else
  1464. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_sum,mpi_comm_world,ierr)
  1465. end if
  1466. case('mul')
  1467. if(present(root))then
  1468. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_prod,boss,mpi_comm_world,ierr)
  1469. else
  1470. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_prod,mpi_comm_world,ierr)
  1471. end if
  1472. case('min')
  1473. if(present(root))then
  1474. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_min,boss,mpi_comm_world,ierr)
  1475. else
  1476. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_min,mpi_comm_world,ierr)
  1477. end if
  1478. case('max')
  1479. if(present(root))then
  1480. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_max,boss,mpi_comm_world,ierr)
  1481. else
  1482. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_max,mpi_comm_world,ierr)
  1483. end if
  1484. end select
  1485. counter=0
  1486. ! if(present(a)) then
  1487. counter=counter+1
  1488. a=globrbuff(counter)
  1489. ! end if
  1490. if(present(b)) then
  1491. counter=counter+1
  1492. b=globrbuff(counter)
  1493. end if
  1494. if(present(c)) then
  1495. counter=counter+1
  1496. c=globrbuff(counter)
  1497. end if
  1498. if(present(d)) then
  1499. counter=counter+1
  1500. d=globrbuff(counter)
  1501. end if
  1502. if(present(e)) then
  1503. counter=counter+1
  1504. e=globrbuff(counter)
  1505. end if
  1506. if(present(f)) then
  1507. counter=counter+1
  1508. f=globrbuff(counter)
  1509. end if
  1510. end subroutine qmpi_real_reduction
  1511. subroutine qmpi_real8_reduction(type,a,b,c,d,e,f,root)
  1512. !
  1513. ! perform a reduction of 'type' on each of the given arguments a - f.
  1514. ! if type is:
  1515. ! 'sum': for each argument, return the sum of the argument over all processors
  1516. ! 'mul': the product
  1517. ! 'min': the minimum value
  1518. ! 'max': the maximum value
  1519. ! root is an optional argument, if given only return the result on that processor (reduce)
  1520. ! the default is to return the result on all processors (allreduce)
  1521. !
  1522. implicit none
  1523. integer, parameter :: dp=8
  1524. character(3) type
  1525. real(dp) a
  1526. real(dp), optional, intent(inout) :: b,c,d,e,f
  1527. integer, optional :: root
  1528. integer counter,boss
  1529. real(dp) rbuff(6),globrbuff(6)
  1530. if( trim(type).ne.'sum' .and. trim(type).ne.'mul' .and. trim(type).ne.'min' .and. trim(type).ne.'max')then
  1531. print *,'qmpi.f90 reduce error: reduction of type ',type,'not supported'
  1532. stop
  1533. end if
  1534. boss=0
  1535. if(present(root))boss=root
  1536. globrbuff(:)=0.0
  1537. counter=0
  1538. ! if(present(a)) then
  1539. counter=counter+1
  1540. rbuff(counter)=a
  1541. ! end if
  1542. if(present(b)) then
  1543. counter=counter+1
  1544. rbuff(counter)=b
  1545. end if
  1546. if(present(c)) then
  1547. counter=counter+1
  1548. rbuff(counter)=c
  1549. end if
  1550. if(present(d)) then
  1551. counter=counter+1
  1552. rbuff(counter)=d
  1553. end if
  1554. if(present(e)) then
  1555. counter=counter+1
  1556. rbuff(counter)=e
  1557. end if
  1558. if(present(f)) then
  1559. counter=counter+1
  1560. rbuff(counter)=f
  1561. end if
  1562. select case(type)
  1563. case('sum')
  1564. if(present(root))then
  1565. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_sum,boss,mpi_comm_world,ierr)
  1566. else
  1567. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_sum,mpi_comm_world,ierr)
  1568. end if
  1569. case('mul')
  1570. if(present(root))then
  1571. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_prod,boss,mpi_comm_world,ierr)
  1572. else
  1573. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_prod,mpi_comm_world,ierr)
  1574. end if
  1575. case('min')
  1576. if(present(root))then
  1577. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_min,boss,mpi_comm_world,ierr)
  1578. else
  1579. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_min,mpi_comm_world,ierr)
  1580. end if
  1581. case('max')
  1582. if(present(root))then
  1583. call mpi_reduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_max,boss,mpi_comm_world,ierr)
  1584. else
  1585. call mpi_allreduce(rbuff,globrbuff,counter,mpi_double_precision,mpi_max,mpi_comm_world,ierr)
  1586. end if
  1587. end select
  1588. counter=0
  1589. ! if(present(a)) then
  1590. counter=counter+1
  1591. a=globrbuff(counter)
  1592. ! end if
  1593. if(present(b)) then
  1594. counter=counter+1
  1595. b=globrbuff(counter)
  1596. end if
  1597. if(present(c)) then
  1598. counter=counter+1
  1599. c=globrbuff(counter)
  1600. end if
  1601. if(present(d)) then
  1602. counter=counter+1
  1603. d=globrbuff(counter)
  1604. end if
  1605. if(present(e)) then
  1606. counter=counter+1
  1607. e=globrbuff(counter)
  1608. end if
  1609. if(present(f)) then
  1610. counter=counter+1
  1611. f=globrbuff(counter)
  1612. end if
  1613. end subroutine qmpi_real8_reduction
  1614. subroutine qmpi_integer_reduction(type,a,b,c,d,e,f,root)
  1615. !
  1616. ! perform a reduction of 'type' on each of the given arguments a - f.
  1617. ! if type is:
  1618. ! 'sum': for each argument, return the sum of the argument over all processors
  1619. ! 'mul': the product
  1620. ! 'min': the minimum value
  1621. ! 'max': the maximum value
  1622. ! root is an optional argument, if given only return the result on that processor (reduce)
  1623. ! the default is to return the result on all processors (allreduce)
  1624. !
  1625. implicit none
  1626. character(3) type
  1627. integer(sp) a
  1628. integer(sp), optional, intent(inout) :: b,c,d,e,f
  1629. integer, optional :: root
  1630. integer counter,boss
  1631. integer rbuff(6),globrbuff(6)
  1632. if( trim(type).ne.'sum' .and. trim(type).ne.'mul' .and. trim(type).ne.'min' .and. trim(type).ne.'max')then
  1633. print *,'qmpi.f90 reduce error: reduction of type ',type,'not supported'
  1634. stop
  1635. end if
  1636. boss=0
  1637. if(present(root))boss=root
  1638. globrbuff(:)=0
  1639. counter=0
  1640. !if(present(a)) then
  1641. counter=counter+1
  1642. rbuff(counter)=a
  1643. !end if
  1644. if(present(b)) then
  1645. counter=counter+1
  1646. rbuff(counter)=b
  1647. end if
  1648. if(present(c)) then
  1649. counter=counter+1
  1650. rbuff(counter)=c
  1651. end if
  1652. if(present(d)) then
  1653. counter=counter+1
  1654. rbuff(counter)=d
  1655. end if
  1656. if(present(e)) then
  1657. counter=counter+1
  1658. rbuff(counter)=e
  1659. end if
  1660. if(present(f)) then
  1661. counter=counter+1
  1662. rbuff(counter)=f
  1663. end if
  1664. select case(type)
  1665. case('sum')
  1666. if(present(root))then
  1667. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_sum,boss,mpi_comm_world,ierr)
  1668. else
  1669. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_sum,mpi_comm_world,ierr)
  1670. end if
  1671. case('mul')
  1672. if(present(root))then
  1673. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_prod,boss,mpi_comm_world,ierr)
  1674. else
  1675. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_prod,mpi_comm_world,ierr)
  1676. end if
  1677. case('min')
  1678. if(present(root))then
  1679. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_min,boss,mpi_comm_world,ierr)
  1680. else
  1681. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_min,mpi_comm_world,ierr)
  1682. end if
  1683. case('max')
  1684. if(present(root))then
  1685. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_max,boss,mpi_comm_world,ierr)
  1686. else
  1687. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER, mpi_max,mpi_comm_world,ierr)
  1688. end if
  1689. end select
  1690. counter=0
  1691. ! if(present(a)) then
  1692. counter=counter+1
  1693. a=globrbuff(counter)
  1694. ! end if
  1695. if(present(b)) then
  1696. counter=counter+1
  1697. b=globrbuff(counter)
  1698. end if
  1699. if(present(c)) then
  1700. counter=counter+1
  1701. c=globrbuff(counter)
  1702. end if
  1703. if(present(d)) then
  1704. counter=counter+1
  1705. d=globrbuff(counter)
  1706. end if
  1707. if(present(e)) then
  1708. counter=counter+1
  1709. e=globrbuff(counter)
  1710. end if
  1711. if(present(f)) then
  1712. counter=counter+1
  1713. f=globrbuff(counter)
  1714. end if
  1715. end subroutine qmpi_integer_reduction
  1716. subroutine qmpi_integer8_reduction(type,a,b,c,d,e,f,root)
  1717. !
  1718. ! perform a reduction of 'type' on each of the given arguments a - f.
  1719. ! if type is:
  1720. ! 'sum': for each argument, return the sum of the argument over all processors
  1721. ! 'mul': the product
  1722. ! 'min': the minimum value
  1723. ! 'max': the maximum value
  1724. ! root is an optional argument, if given only return the result on that processor (reduce)
  1725. ! the default is to return the result on all processors (allreduce)
  1726. !
  1727. implicit none
  1728. character(3) type
  1729. integer(long) a
  1730. integer(long), optional, intent(inout) :: b,c,d,e,f
  1731. integer, optional :: root
  1732. integer counter,boss
  1733. integer(long) rbuff(6),globrbuff(6)
  1734. if(len(type).ne.3)then
  1735. print *,'qmpi.f90 reduce error: type must be one of "mul","sum","min" or "max"'
  1736. stop
  1737. end if
  1738. if( trim(type).ne.'sum' .and. trim(type).ne.'mul' .and. trim(type).ne.'min' .and. trim(type).ne.'max')then
  1739. print *,'qmpi.f90 reduce error: reduction of type ',type,'not supported'
  1740. stop
  1741. end if
  1742. boss=0
  1743. if(present(root))boss=root
  1744. globrbuff(:)=0_dp
  1745. counter=0
  1746. ! if(present(a)) then
  1747. counter=counter+1
  1748. rbuff(counter)=a
  1749. ! end if
  1750. if(present(b)) then
  1751. counter=counter+1
  1752. rbuff(counter)=b
  1753. end if
  1754. if(present(c)) then
  1755. counter=counter+1
  1756. rbuff(counter)=c
  1757. end if
  1758. if(present(d)) then
  1759. counter=counter+1
  1760. rbuff(counter)=d
  1761. end if
  1762. if(present(e)) then
  1763. counter=counter+1
  1764. rbuff(counter)=e
  1765. end if
  1766. if(present(f)) then
  1767. counter=counter+1
  1768. rbuff(counter)=f
  1769. end if
  1770. select case(type)
  1771. case('sum')
  1772. if(present(root))then
  1773. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_sum,boss,mpi_comm_world,ierr)
  1774. else
  1775. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_sum,mpi_comm_world,ierr)
  1776. end if
  1777. case('mul')
  1778. if(present(root))then
  1779. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_prod,boss,mpi_comm_world,ierr)
  1780. else
  1781. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_prod,mpi_comm_world,ierr)
  1782. end if
  1783. case('min')
  1784. if(present(root))then
  1785. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_min,boss,mpi_comm_world,ierr)
  1786. else
  1787. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_min,mpi_comm_world,ierr)
  1788. end if
  1789. case('max')
  1790. if(present(root))then
  1791. call mpi_reduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_max,boss,mpi_comm_world,ierr)
  1792. else
  1793. call mpi_allreduce(rbuff,globrbuff,counter, MPI_INTEGER8, mpi_max,mpi_comm_world,ierr)
  1794. end if
  1795. end select
  1796. counter=1
  1797. a=globrbuff(counter)
  1798. if(present(b)) then
  1799. counter=counter+1
  1800. b=globrbuff(counter)
  1801. end if
  1802. if(present(c)) then
  1803. counter=counter+1
  1804. c=globrbuff(counter)
  1805. end if
  1806. if(present(d)) then
  1807. counter=counter+1
  1808. d=globrbuff(counter)
  1809. end if
  1810. if(present(e)) then
  1811. counter=counter+1
  1812. e=globrbuff(counter)
  1813. end if
  1814. if(present(f)) then
  1815. counter=counter+1
  1816. f=globrbuff(counter)
  1817. end if
  1818. end subroutine qmpi_integer8_reduction
  1819. ! later?
  1820. ! packing to reduce number of sends:
  1821. ! call pack(u)
  1822. ! call pack(eta(1,:))
  1823. ! call pack(v)
  1824. ! call send_pack(1)
  1825. ! ...
  1826. ! call receive_pack(0)
  1827. ! call unpack(u)
  1828. ! call unpack(eta(1,:)
  1829. !
  1830. end module qmpi