nf_redux_test.f90 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. ! StarPU --- Runtime system for heterogeneous multicore architectures.
  2. !
  3. ! Copyright (C) 2016-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. !
  5. ! StarPU is free software; you can redistribute it and/or modify
  6. ! it under the terms of the GNU Lesser General Public License as published by
  7. ! the Free Software Foundation; either version 2.1 of the License, or (at
  8. ! your option) any later version.
  9. !
  10. ! StarPU is distributed in the hope that it will be useful, but
  11. ! WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. !
  14. ! See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. !
  16. program main
  17. use iso_c_binding
  18. use fstarpu_mod
  19. use fstarpu_mpi_mod
  20. implicit none
  21. integer, target :: ret, np, i, j
  22. type(c_ptr) :: task_cl, task_rw_cl, task_red_cl, task_ini_cl
  23. character(kind=c_char,len=*), parameter :: name=C_CHAR_"task"//C_NULL_CHAR
  24. character(kind=c_char,len=*), parameter :: namered=C_CHAR_"task_red"//C_NULL_CHAR
  25. character(kind=c_char,len=*), parameter :: nameini=C_CHAR_"task_ini"//C_NULL_CHAR
  26. real(kind(1.d0)), target :: a1, a2, b1, b2
  27. integer(kind=8) :: tag, err
  28. type(c_ptr) :: a1hdl, a2hdl, b1hdl, b2hdl
  29. integer, target :: comm, comm_world, comm_w_rank, comm_size
  30. integer(c_int), target :: w_node
  31. call fstarpu_fxt_autostart_profiling(0)
  32. ret = fstarpu_init(c_null_ptr)
  33. ret = fstarpu_mpi_init(1)
  34. comm_world = fstarpu_mpi_world_comm()
  35. comm_w_rank = fstarpu_mpi_world_rank()
  36. comm_size = fstarpu_mpi_world_size()
  37. if (comm_size.ne.4) then
  38. write(*,'(" ")')
  39. write(*,'("This application is meant to run with 4 MPI")')
  40. stop 1
  41. end if
  42. err = fstarpu_mpi_barrier(comm_world)
  43. if(comm_w_rank.eq.0) then
  44. write(*,'(" ")')
  45. a1 = 1.0
  46. write(*,*) "init_a1", a1
  47. b1 = 0.5
  48. write(*,*) "init b1", b1
  49. end if
  50. if(comm_w_rank.eq.1) then
  51. write(*,'(" ")')
  52. a2 = 2.0
  53. write(*,*) "init_a2", a2
  54. b2 = 0.8
  55. write(*,*) "init b2", b2
  56. end if
  57. ! allocate and fill codelet structs
  58. task_cl = fstarpu_codelet_allocate()
  59. call fstarpu_codelet_set_name(task_cl, name)
  60. call fstarpu_codelet_add_cpu_func(task_cl, C_FUNLOC(cl_cpu_task))
  61. call fstarpu_codelet_add_buffer(task_cl, FSTARPU_REDUX)
  62. call fstarpu_codelet_add_buffer(task_cl, FSTARPU_R)
  63. ! allocate and reduction codelets
  64. task_red_cl = fstarpu_codelet_allocate()
  65. call fstarpu_codelet_set_name(task_red_cl, namered)
  66. call fstarpu_codelet_add_cpu_func(task_red_cl,C_FUNLOC(cl_cpu_task_red))
  67. call fstarpu_codelet_add_buffer(task_red_cl, FSTARPU_RW.ior.FSTARPU_COMMUTE)
  68. call fstarpu_codelet_add_buffer(task_red_cl, FSTARPU_R)
  69. task_ini_cl = fstarpu_codelet_allocate()
  70. call fstarpu_codelet_set_name(task_ini_cl, nameini)
  71. call fstarpu_codelet_add_cpu_func(task_ini_cl,C_FUNLOC(cl_cpu_task_ini))
  72. call fstarpu_codelet_add_buffer(task_ini_cl, FSTARPU_W)
  73. err = fstarpu_mpi_barrier(comm_world)
  74. tag = 0
  75. if(comm_w_rank.eq.0) then
  76. call fstarpu_variable_data_register(a1hdl, 0, c_loc(a1),c_sizeof(a1))
  77. call fstarpu_variable_data_register(b1hdl, 0, c_loc(b1),c_sizeof(b1))
  78. else
  79. call fstarpu_variable_data_register(a1hdl, -1, c_null_ptr,c_sizeof(a1))
  80. call fstarpu_variable_data_register(b1hdl, -1, c_null_ptr,c_sizeof(b1))
  81. end if
  82. call fstarpu_mpi_data_register(a1hdl,tag,0)
  83. call fstarpu_mpi_data_register(b1hdl, tag+1,0)
  84. tag = tag + 2
  85. if(comm_w_rank.eq.1) then
  86. call fstarpu_variable_data_register(a2hdl, 0, c_loc(a2),c_sizeof(a2))
  87. call fstarpu_variable_data_register(b2hdl, 0, c_loc(b2),c_sizeof(b2))
  88. else
  89. call fstarpu_variable_data_register(a2hdl, -1, c_null_ptr,c_sizeof(a2))
  90. call fstarpu_variable_data_register(b2hdl, -1, c_null_ptr,c_sizeof(b2))
  91. end if
  92. call fstarpu_mpi_data_register(a2hdl,tag,1)
  93. call fstarpu_mpi_data_register(b2hdl, tag+1, 1)
  94. tag = tag + 2
  95. call fstarpu_data_set_reduction_methods(a1hdl, task_red_cl,task_ini_cl)
  96. call fstarpu_data_set_reduction_methods(a2hdl, task_red_cl,task_ini_cl)
  97. err = fstarpu_mpi_barrier(comm_world)
  98. call fstarpu_fxt_start_profiling()
  99. w_node = 3
  100. comm = comm_world
  101. call fstarpu_mpi_task_insert( (/ c_loc(comm), &
  102. task_cl, &
  103. FSTARPU_REDUX, a1hdl, &
  104. FSTARPU_R, b1hdl, &
  105. FSTARPU_EXECUTE_ON_NODE, c_loc(w_node), &
  106. C_NULL_PTR /))
  107. w_node = 2
  108. comm = comm_world
  109. call fstarpu_mpi_task_insert( (/ c_loc(comm), &
  110. task_cl, &
  111. FSTARPU_REDUX, a2hdl, &
  112. FSTARPU_R, b2hdl, &
  113. FSTARPU_EXECUTE_ON_NODE, c_loc(w_node), &
  114. C_NULL_PTR /))
  115. call fstarpu_mpi_redux_data(comm_world, a1hdl)
  116. call fstarpu_mpi_redux_data(comm_world, a2hdl)
  117. ! write(*,*) "waiting all tasks ..."
  118. err = fstarpu_mpi_wait_for_all(comm_world)
  119. if(comm_w_rank.eq.0) then
  120. write(*,*) 'computed result ---> ',a1, "expected =",4.5
  121. end if
  122. if(comm_w_rank.eq.1) then
  123. write(*,*) 'computed result ---> ',a2, "expected=",5.8
  124. end if
  125. call fstarpu_data_unregister(a1hdl)
  126. call fstarpu_data_unregister(a2hdl)
  127. call fstarpu_data_unregister(b1hdl)
  128. call fstarpu_data_unregister(b2hdl)
  129. call fstarpu_fxt_stop_profiling()
  130. call fstarpu_codelet_free(task_cl)
  131. call fstarpu_codelet_free(task_red_cl)
  132. call fstarpu_codelet_free(task_ini_cl)
  133. err = fstarpu_mpi_shutdown()
  134. call fstarpu_shutdown()
  135. stop
  136. contains
  137. recursive subroutine cl_cpu_task (buffers, cl_args) bind(C)
  138. use iso_c_binding ! C interfacing module
  139. use fstarpu_mod ! StarPU interfacing module
  140. implicit none
  141. type(c_ptr), value, intent(in) :: buffers, cl_args ! cl_args is unused
  142. integer(c_int) :: ret, worker_id
  143. integer :: comm_rank
  144. integer, target :: i
  145. real(kind(1.d0)), pointer :: a, b
  146. real(kind(1.d0)) :: old_a
  147. worker_id = fstarpu_worker_get_id()
  148. comm_rank = fstarpu_mpi_world_rank()
  149. call c_f_pointer(fstarpu_variable_get_ptr(buffers, 0), a)
  150. call c_f_pointer(fstarpu_variable_get_ptr(buffers, 1), b)
  151. call nf_sleep(1.d0)
  152. old_a = a
  153. a = 3.0 + b
  154. write(*,*) "task (c_w_rank:",comm_rank,") from ",old_a,"to",a
  155. return
  156. end subroutine cl_cpu_task
  157. recursive subroutine cl_cpu_task_red (buffers, cl_args) bind(C)
  158. use iso_c_binding ! C interfacing module
  159. use fstarpu_mod ! StarPU interfacing module
  160. implicit none
  161. type(c_ptr), value, intent(in) :: buffers, cl_args ! cl_args is unused
  162. integer(c_int) :: ret
  163. integer, target :: comm_rank
  164. real(kind(1.d0)), pointer :: as, ad
  165. real(kind(1.d0)) :: old_ad
  166. comm_rank = fstarpu_mpi_world_rank()
  167. call c_f_pointer(fstarpu_variable_get_ptr(buffers, 0), ad)
  168. call c_f_pointer(fstarpu_variable_get_ptr(buffers, 1), as)
  169. old_ad = ad
  170. ad = ad + as
  171. call nf_sleep(1.d0)
  172. write(*,*) "red_cl (c_w_rank:",comm_rank,")",as, old_ad, ' ---> ',ad
  173. return
  174. end subroutine cl_cpu_task_red
  175. recursive subroutine cl_cpu_task_ini (buffers, cl_args) bind(C)
  176. use iso_c_binding ! C interfacing module
  177. use fstarpu_mod ! StarPU interfacing module
  178. implicit none
  179. type(c_ptr), value, intent(in) :: buffers, cl_args
  180. ! cl_args is unused
  181. integer(c_int) :: ret
  182. integer, target :: comm_rank
  183. real(kind(1.d0)), pointer :: a
  184. comm_rank = fstarpu_mpi_world_rank()
  185. call c_f_pointer(fstarpu_variable_get_ptr(buffers, 0), a)
  186. call nf_sleep(0.5d0)
  187. a = 0.0
  188. write(*,*) "ini_cl (c_w_rank:",comm_rank,")"
  189. return
  190. end subroutine cl_cpu_task_ini
  191. subroutine nf_sleep(t)
  192. implicit none
  193. integer :: t_start, t_end, t_rate
  194. real(kind(1.d0)) :: ta, t
  195. call system_clock(t_start)
  196. do
  197. call system_clock(t_end, t_rate)
  198. ta = real(t_end-t_start)/real(t_rate)
  199. if(ta.gt.t) return
  200. end do
  201. end subroutine nf_sleep
  202. end program main