nbody_def.jl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. # StarPU --- Runtime system for heterogeneous multicore architectures.
  2. #
  3. # Copyright (C) 2020 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. #include("./nbody_display.jl")
  17. include("nbody.jl")
  18. function nbody_with_starpu(positions ::Matrix{Float64}, velocities ::Matrix{Float64}, accelerations ::Matrix{Float64}, masses ::Vector{Float64}, parameters ::Vector{Float64}, nbr_simulations ::Int64, nslices ::Int64, nbr_planets ::Int64)
  19. vert = StarpuDataFilter(STARPU_MATRIX_FILTER_VERTICAL_BLOCK, nslices)
  20. for i = 1:nbr_simulations
  21. @starpu_block let
  22. hPOS, hVEL, hACC, hPAR, hMA = starpu_data_register(positions,velocities,accelerations,parameters,masses)
  23. starpu_data_partition(hACC,vert)
  24. @starpu_sync_tasks for task in (1:nslices)
  25. @starpu_block let
  26. id = Int64[task-1]
  27. hID = starpu_data_register(id)
  28. @starpu_async_cl claccst(hPOS,hACC[task],hMA,hPAR,hID)
  29. end
  30. end
  31. starpu_data_partition(hPOS,vert)
  32. starpu_data_partition(hVEL,vert)
  33. @starpu_sync_tasks for task in (1:nslices)
  34. @starpu_async_cl clupdtst(hPOS[task],hVEL[task],hACC[task],hPAR)
  35. end
  36. end
  37. # pixels ::Array{Array{Int64}} = [[0,0,0] for i = 1:1000*1000]
  38. # graph_planets(pixels, positions, -4E8, 4E8, 1000, 1000, "PPM/nbody_st$(nbr_planets)_$i.ppm")
  39. end
  40. return nothing
  41. end
  42. function nbody_with_starpu_cpu(positions ::Matrix{Float64}, velocities ::Matrix{Float64}, accelerations ::Matrix{Float64}, masses ::Vector{Float64}, parameters ::Vector{Float64}, nbr_simulations ::Int64, nslices ::Int64)
  43. vert = StarpuDataFilter(STARPU_MATRIX_FILTER_VERTICAL_BLOCK, nslices)
  44. for i = 1:nbr_simulations
  45. @starpu_block let
  46. hPOS, hVEL, hACC, hPAR, hMA = starpu_data_register(positions,velocities,accelerations,parameters,masses)
  47. starpu_data_partition(hACC,vert)
  48. @starpu_sync_tasks for task in (1:nslices)
  49. id = Int64[task-1]
  50. hID = starpu_data_register(id)
  51. @starpu_async_cl clacccpu(hPOS,hACC[task],hMA,hPAR,hID)
  52. end
  53. starpu_data_partition(hPOS,vert)
  54. starpu_data_partition(hVEL,vert)
  55. @starpu_sync_tasks for task in (1:nslices)
  56. @starpu_async_cl clupdtcpu(hPOS[task],hVEL[task],hACC[task],hPAR)
  57. end
  58. end
  59. # pixels ::Array{Array{Int64}} = [[0,0,0] for i = 1:1000*1000]
  60. # graph_planets(pixels, positions, -4E8, 4E8, 1000, 1000, "PPM/nbody_cpu$i.ppm")
  61. end
  62. return nothing
  63. end
  64. function nbody_with_starpu_gpu(positions ::Matrix{Float64}, velocities ::Matrix{Float64}, accelerations ::Matrix{Float64}, masses ::Vector{Float64}, parameters ::Vector{Float64}, nbr_simulations ::Int64, nslices ::Int64)
  65. vert = StarpuDataFilter(STARPU_MATRIX_FILTER_VERTICAL_BLOCK, nslices)
  66. for i = 1:nbr_simulations
  67. @starpu_block let
  68. hPOS, hVEL, hACC, hPAR, hMA = starpu_data_register(positions,velocities,accelerations,parameters,masses)
  69. starpu_data_partition(hACC,vert)
  70. @starpu_sync_tasks for task in (1:nslices)
  71. id = Int64[task-1]
  72. hID = starpu_data_register(id)
  73. @starpu_async_cl claccgpu(hPOS,hACC[task],hMA,hPAR,hID)
  74. end
  75. starpu_data_partition(hPOS,vert)
  76. starpu_data_partition(hVEL,vert)
  77. @starpu_sync_tasks for task in (1:nslices)
  78. @starpu_async_cl clupdtgpu(hPOS[task],hVEL[task],hACC[task],hPAR)
  79. end
  80. end
  81. # pixels ::Array{Array{Int64}} = [[0,0,0] for i = 1:1000*1000]
  82. # graph_planets(pixels, positions, -4E8, 4E8, 1000, 1000, "PPM/nbody_gpu$i.ppm")
  83. end
  84. return nothing
  85. end
  86. # function display_times(starting_nbr_planets::Int64, step_nbr ::Int64, nbr_steps ::Int64, nbr_simulations::Int64, nb_tests ::Int64, nslices::Int64)
  87. # width = 1000
  88. # height = 1000
  89. # times_starpu ::Vector{Float64} = [0 for i = 1:nbr_steps+1]
  90. # times_julia ::Vector{Float64} = [0 for i = 1:nbr_steps+1]
  91. # for k = 0:nbr_steps
  92. # nbr_planets ::Int64 = starting_nbr_planets + k * step_nbr
  93. # println("Number of planets: $nbr_planets")
  94. # epsilon ::Float64 = 2.5E8
  95. # dt ::Float64 = 36000
  96. # G ::Float64 = 6.67408E-11
  97. # parameters ::Vector{Float64} = [G,dt,epsilon]
  98. # maxcoord ::Int64 = 2E8
  99. # mincoord ::Int64 = -2E8
  100. # positions ::Matrix{Float64} = zeros(2, nbr_planets)
  101. # velocities ::Matrix{Float64} = zeros(2, nbr_planets)
  102. # accelerations ::Matrix{Float64} = zeros(2,nbr_planets)
  103. # positionsjl ::Vector{Vector{Float64}} = [[0, 0] for i = 1:nbr_planets]
  104. # velocitiesjl ::Vector{Vector{Float64}} = [[0, 0] for i = 1:nbr_planets]
  105. # accelerationsjl ::Vector{Vector{Float64}} = [[0, 0] for i = 1:nbr_planets]
  106. # masses ::Vector{Float64} = [0 for i = 1:nbr_planets]
  107. # for i = 1:nbr_planets
  108. # mi ::Float64 = rand() * 5E22
  109. # ri = mi * 2.5E-15
  110. # angle ::Float64 = rand() * 2 * pi
  111. # distToCenter ::Float64 = rand() * 1.0E8 + 1.0E8
  112. # qix ::Float64 = cos(angle) * distToCenter
  113. # qiy ::Float64 = sin(angle) * distToCenter
  114. # vix ::Float64 = qiy * 4.0E-6
  115. # viy ::Float64 = -qix * 4.0E-6
  116. # masses[i] = mi
  117. # positions[1,i] = qix
  118. # positions[2,i] = qiy
  119. # positionsjl[i] = [qix, qiy]
  120. # velocities[1,i] = vix
  121. # velocities[2,i] = viy
  122. # velocitiesjl[i] = [vix, viy]
  123. # end
  124. # max_value = 4E8
  125. # min_value = -4E8
  126. # println("Starpu...")
  127. # tic()
  128. # for i = 1:nbr_simulations
  129. # nbody_with_starpu(positions, velocities, accelerations, masses, parameters, nslices)
  130. # end
  131. # t_starpu = toq()
  132. # println("No Starpu...")
  133. # tic()
  134. # for i = 1:nbr_simulations
  135. # nbody_jl(positionsjl, velocitiesjl, accelerationsjl, masses, epsilon, dt)
  136. # end
  137. # t_julia = toq()
  138. # times_starpu[k+1] = t_starpu
  139. # times_julia[k+1] = t_julia
  140. # end
  141. # open("./DAT/nbody.dat", "w") do f
  142. # for i = 0:nbr_steps
  143. # write(f, "$(starting_nbr_planets + i*step_nbr)")
  144. # write(f, " $(times_starpu[i+1])")
  145. # write(f, " $(times_julia[i+1])\n")
  146. # end
  147. # end
  148. # end
  149. function set_to_zero(A ::Array{<:Real,2})
  150. height,width = size(A)
  151. for i = 1:height
  152. for j = 1:width
  153. A[i,j] = 0
  154. end
  155. end
  156. end
  157. function median_times(nbr_tests ::Int64, nbr_planets ::Int64, nbr_simulations ::Int64, nslices ::Int64)
  158. ######################### INITIALIZATION #########################
  159. width ::Int64 = 1000
  160. height ::Int64 = 1000
  161. epsilon ::Float64 = 2.5E8
  162. dt ::Float64 = 3600
  163. G ::Float64 = 6.67408E-11
  164. parameters ::Vector{Float64} = [G,dt,epsilon]
  165. # Coordinate interval for the final display screen.
  166. maxcoord ::Int64 = 2E8
  167. mincoord ::Int64 = -2E8
  168. exec_times_st ::Vector{Float64} = [0 for i = 1:nbr_tests]
  169. exec_times_cpu ::Vector{Float64} = [0 for i = 1:nbr_tests]
  170. exec_times_gpu ::Vector{Float64} = [0 for i = 1:nbr_tests]
  171. # exec_times_jl ::Vector{Float64} = [0 for i = 1:nbr_tests]
  172. # Arrays used for each of the starpu-using functions.
  173. positions ::Matrix{Float64} = zeros(2, nbr_planets)
  174. velocities ::Matrix{Float64} = zeros(2, nbr_planets)
  175. accelerations_st ::Matrix{Float64} = zeros(2, nbr_planets)
  176. # Arrays used for the naive julia function.
  177. # positions_jl ::Vector{Vector{Float64}} = [[0, 0] for i = 1:nbr_planets]
  178. # velocities_jl ::Vector{Vector{Float64}} = [[0, 0] for i = 1:nbr_planets]
  179. # accelerations_jl ::Vector{Vector{Float64}} = [[0, 0] for i = 1:nbr_planets]
  180. masses ::Vector{Float64} = [0 for i = 1:nbr_planets]
  181. for k = 1:nbr_tests
  182. println("Test $k...")
  183. # Initializing the starpu and naive julia arrays with the same values.
  184. for i = 1:nbr_planets
  185. mi ::Float64 = rand() * 5E22
  186. ri = mi * 2.5E-15
  187. angle ::Float64 = rand() * 2 * pi
  188. distToCenter ::Float64 = rand() * 1.0E8 + 1.0E8
  189. qix ::Float64 = cos(angle) * distToCenter
  190. qiy ::Float64 = sin(angle) * distToCenter
  191. vix ::Float64 = qiy * 4.0E-6
  192. viy ::Float64 = -qix * 4.0E-6
  193. masses[i] = mi
  194. positions[1,i] = qix
  195. positions[2,i] = qiy
  196. #positions_jl[i] = [qix, qiy]
  197. velocities[1,i] = vix
  198. velocities[2,i] = viy
  199. #velocities_jl[i] = [vix, viy]
  200. end
  201. ######################### SIMULATION #########################
  202. # Using new arrays for the starpu functions, so we can keep in memory the initial values.
  203. positions_st ::Matrix{Float64} = copy(positions)
  204. velocities_st ::Matrix{Float64} = copy(velocities)
  205. set_to_zero(accelerations_st)
  206. tic()
  207. nbody_with_starpu(positions_st, velocities_st, accelerations_st, masses, parameters, nbr_simulations, nslices, nbr_planets)
  208. t_st = toq()
  209. # positions_st = copy(positions)
  210. # velocities_st = copy(velocities)
  211. # set_to_zero(accelerations_st)
  212. # tic()
  213. # nbody_with_starpu_cpu(positions_st, velocities_st, accelerations_st, masses, parameters, nbr_simulations, nslices)
  214. # t_cpu = toq()
  215. # positions_st = copy(positions)
  216. # velocities_st = copy(velocities)
  217. # set_to_zero(accelerations_st)
  218. # tic()
  219. # nbody_with_starpu_gpu(positions_st, velocities_st, accelerations_st, masses, parameters, nbr_simulations, nslices)
  220. # t_gpu = toq()
  221. #tic()
  222. #nbody_jl(positions_jl, velocities_jl, accelerations_jl, masses, nbr_simulations, epsilon, dt)
  223. #t_jl = toq()
  224. exec_times_st[k] = t_st
  225. # exec_times_cpu[k] = t_cpu
  226. # exec_times_gpu[k] = t_gpu
  227. #exec_times_jl[k] = t_jl
  228. end
  229. sort!(exec_times_st)
  230. # sort!(exec_times_cpu)
  231. # sort!(exec_times_gpu)
  232. #sort!(exec_times_jl)
  233. res ::Vector{Float64} = [exec_times_st[1 + div(nbr_tests-1,2)]]#, exec_times_cpu[1 + div(nbr_tests-1,2)], exec_times_gpu[1 + div(nbr_tests-1,2)]]#, exec_times_jl[1 + div(nbr_tests-1,2)]]
  234. return res
  235. end
  236. # Adds the median times of each function inside a .DAT file.
  237. function display_times(start_nbr ::Int64, step_nbr ::Int64, stop_nbr ::Int64, nbr_simulations ::Int64, nslices ::Int64, nbr_tests ::Int64)
  238. # mtc = map( (x->parse(Float64,x)), open("DAT/nbody_c_times.dat") do f
  239. # readlines(f)
  240. # end)
  241. mtjl = map( (x->parse(Float64,x)), open("../DAT/nbody_jl.dat") do f
  242. readlines(f)
  243. end)
  244. mtcstr = map( (x->parse(Float64,x)), open("../DAT/nbody_c_struct_times.dat") do f
  245. readlines(f)
  246. end)
  247. mtcarr = map( (x->parse(Float64,x)), open("../DAT/nbody_c_array_times.dat") do f
  248. readlines(f)
  249. end)
  250. i = 1;
  251. #open("./DAT/nbody_jl.dat", "w") do fjl
  252. open("../DAT/nbody_jl_array_times.dat", "w") do ft
  253. open("../DAT/nbody_speedups.dat", "w") do f
  254. for nbr_planets in (start_nbr : step_nbr : stop_nbr)
  255. println("$(nbr_planets) planets:")
  256. mt ::Vector{Float64} = median_times(nbr_tests, nbr_planets, nbr_simulations, nslices)
  257. println("C struct time: $(mtcstr[i])")
  258. println("C array time: $(mtcarr[i])")
  259. println("Starpujl time: $(mt[1])")
  260. # println("CPUjl time: $(mt[2])")
  261. # println("GPUjl time: $(mt[3])")
  262. println("Julia time: $(mtjl[i])")
  263. write(f, "$(nbr_planets) $(mtjl[i]/mt[1]) $(mtjl[i]/mtcstr[i]) $(mtjl[i]/mtcarr[i])\n")
  264. write(ft, "$(mt[1])\n")
  265. #write(fjl, "$(mt[4])\n")
  266. i = i + 1
  267. end
  268. end
  269. end
  270. #end
  271. end