Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
parallel.py
Go to the documentation of this file.
1 # Andrew Gloster
2 # Summer 2016
3 # Python Version of Communication Model Implementation
4 # Functions relating to full communication and computation model
5 
6 #------------------------------------
7 # Import relevant modules
8 #------------------------------------
9 
10 import matplotlib.pyplot as plt
11 import numpy as np
12 
13 #------------------------------------
14 # Import relevant main functions
15 #------------------------------------
16 
17 from functions_main import Find_Topologies
18 from functions_main import Partition
19 from functions_main import Find_Nektar_Files
20 from functions_main import Parse_Nektar_Output
21 
22 #------------------------------------
23 # Import the required class
24 #------------------------------------
25 
26 from class_topology import Topology
27 
28 #------------------------------------
29 # New Function
30 #------------------------------------
31 
32 # Function to run the full communication model
33 def Run_Parallel_Model(Parallelisation, Scheme, Mesh_File, Num_Modes, P, Num_Constants, Fit, BW_Node_To_Node, LAT_Node_To_Node, BW_Socket_To_Socket,
34  LAT_Socket_To_Socket, BW_Core_To_Core, LAT_Core_To_Core, Num_Core_Per_Socket, Num_Sock_Per_Node, PROC_TOT, Pressure, Velocity_1, Velocity_2,
35  Velocity_3):
36 
37  # Find possible topologies when running in hybrid
38  if (Parallelisation is 'Hybrid_Socket' or Parallelisation is 'Hybrid_Node'):
39  (PROC_XY, PROC_Z) = Find_Topologies(PROC_TOT, Num_Modes)
40 
41  # Modal parallelisation values
42  if (Parallelisation is 'Modal'):
43  PROC_Z = [2, 4, 5, 8, 10, 20]
44  PROC_XY = [1, 1, 1, 1, 1, 1]
45 
46  # Elemental parallelisation values
47  if (Parallelisation is 'Elemental'):
48  PROC_Z = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
49  PROC_XY = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
50 
51 #------------------------------------
52 # Topology Class Input and Results
53 #------------------------------------
54 
55  Pairwise = []
56  Allreduce = []
57  Alltoall = []
58 
59  Communication = []
60  Serial = []
61 
62  Serial_Pairwise = []
63  Serial_Allreduce = []
64  Serial_Alltoall = []
65 
66  Total = []
67 
68  for i in range(0, len(PROC_Z)):
69 
70  # Set the communication count to 0
71  Communication_Count = 0.0
72 
73  # Create class instance with basic input
74  Simulation = Topology(PROC_Z[i], PROC_XY[i], Num_Core_Per_Socket, Num_Sock_Per_Node, Scheme)
75 
76  # Find the partition for the number of PROC_XY input
77  (Num_Element_Msg, Num_Elements) = Partition(Mesh_File, PROC_XY[i])
78 
79  # Input the benchmarked communication data
80  Simulation.Input_Communication(BW_Node_To_Node, LAT_Node_To_Node, BW_Socket_To_Socket, LAT_Socket_To_Socket, BW_Core_To_Core, LAT_Core_To_Core)
81 
82  # Distribute the modes and elements
83  Simulation.Distribute_Modes(Num_Modes);
84  Simulation.Distribute_Elements(Num_Element_Msg, Num_Elements);
85 
86  # Read in the CG iterations
87  Simulation.CG_Iterations(Pressure, Velocity_1, Velocity_2, Velocity_3)
88 
89  # Input P to genererate the data sizes
90  Simulation.Data_Size(P)
91 
92  # Input the fit from the serial model
93  Simulation.Hardware_Constant(Num_Constants, Fit)
94 
95  # Count pairwise exchange
96  Pairwise.append(Simulation.Communication_Pairwise_Exchange())
97  Communication_Count += Pairwise[i]
98 
99  # Count Allreduce
100  Allreduce.append(Simulation.Communication_Allreduce())
101  Communication_Count += Allreduce[i]
102 
103  # Count Alltoall
104  Alltoall.append(Simulation.Communication_Alltoall())
105  Communication_Count += Alltoall[i]
106 
107  # Count Serial
108  Serial.append(Simulation.Serial_Compute())
109 
110  # Count Serial with each type of communication
111  Serial_Pairwise.append(Serial[i] + Pairwise[i])
112  Serial_Allreduce.append(Serial[i] + Allreduce[i])
113  Serial_Alltoall.append(Serial[i] + Alltoall[i])
114 
115  # Record the total communication
116  Communication.append(Communication_Count)
117 
118  # Calculate the total length of a time step
119  Total.append(Communication[i] + Serial[i])
120 
121  if (Parallelisation == 'Hybrid'):
122  fig, ax = plt.subplots()
123  ax.plot(PROC_Z, Total, label = 'Model')
124  ax.set_xlabel('$ R_Z $')
125  ax.set_ylabel('Timestep (s)')
126  ax.set_title('Length of Single Timestep: Model')
127  plt.legend(loc=1)
128  fig.savefig("Output/Figures/Model_Hybrid.png")
129 
130  if (Parallelisation == 'Modal'):
131  fig, ax = plt.subplots()
132  ax.plot(PROC_Z, Total, label = 'Model')
133  ax.set_xlabel('$ R_Z $')
134  ax.set_ylabel('Timestep (s)')
135  ax.set_title('Length of Single Timestep: Model')
136  plt.legend(loc=1)
137  fig.savefig("Output/Figures/Model_Modal.png")
138 
139  if (Parallelisation == 'Elemental'):
140  fig, ax = plt.subplots()
141  ax.plot(PROC_XY, Total, label = 'Model')
142  ax.set_xlabel('$ R_{XY} $')
143  ax.set_ylabel('Timestep (s)')
144  ax.set_title('Length of Single Timestep: Model')
145  plt.legend(loc=1)
146  fig.savefig("Output/Figures/Model_Elemental.png")
147 
148  return(PROC_Z, PROC_XY, Total)
149 
150 # Run a series of plots showing outputs of the model vs data
151 def Run_Parallel_Comparison(Loc_Parallel_Timing_Files, Parallelisation, PROC_Z, PROC_XY, Total):
152 
153  if (Parallelisation is 'Modal'):
154  Timings_Fin = {}
155  Data = []
156 
157  (Nektar_Modes_Fin, Timing_Files_Fin) = Find_Nektar_Files(Loc_Parallel_Timing_Files)
158 
159  for i in range(0, len(Timing_Files_Fin)):
160  Data.append(np.mean(Parse_Nektar_Output(Loc_Parallel_Timing_Files + Timing_Files_Fin[i]))/10)
161 
162  # Calculate the mean, standard deviation and variance of the difference between the data and the fitted model
163  difference = []
164 
165  for i in range(0, len(Timing_Files_Fin)):
166  difference.append(abs(Data[i] - Total[i]))
167 
168  mean_diff = np.mean(difference)
169  std_dev_diff = np.std(difference)
170  var_diff = np.var(difference)
171 
172  # Print these results for the user to see
173  print('The mean of the differences between the Data and the Model is ' + str(mean_diff))
174  print('The standard deviation of the differences between the Data and the Model is ' + str(std_dev_diff))
175  print('The variance of the differences between the Data and the Model is ' + str(var_diff))
176 
177  fig, ax = plt.subplots()
178  ax.plot(PROC_Z, Data, label = 'Data')
179  ax.plot(PROC_Z, Total, label = 'Model')
180  ax.set_xlabel('$ R_Z $')
181  ax.set_ylabel('Timestep (s)')
182  ax.set_title('Length of Single Timestep: Model vs Data')
183  plt.legend(loc=1)
184  fig.savefig("Output/Figures/Mode_Full.png")
185 
186  if (Parallelisation is 'Elemental'):
187  Timings_Fin = {}
188  Data = []
189 
190  (Nektar_Modes_Fin, Timing_Files_Fin) = Find_Nektar_Files(Loc_Parallel_Timing_Files)
191 
192  for i in range(0, len(Timing_Files_Fin)):
193  Data.append(np.mean(Parse_Nektar_Output(Loc_Parallel_Timing_Files + Timing_Files_Fin[i]))/10)
194 
195  # Calculate the mean, standard deviation and variance of the difference between the data and the fitted model
196  difference = []
197 
198  for i in range(0, len(Timing_Files_Fin)):
199  difference.append(abs(Data[i] - Total[i]))
200 
201  mean_diff = np.mean(difference)
202  std_dev_diff = np.std(difference)
203  var_diff = np.var(difference)
204 
205  # Print these results for the user to see
206  print('The mean of the differences between the Data and the Model is ' + str(mean_diff))
207  print('The standard deviation of the differences between the Data and the Model is ' + str(std_dev_diff))
208  print('The variance of the differences between the Data and the Model is ' + str(var_diff))
209 
210  fig, ax = plt.subplots()
211  ax.plot(PROC_XY, Data, label = 'Data')
212  ax.plot(PROC_XY, Total, label = 'Model')
213  ax.set_xlabel('$ R_{XY} $')
214  ax.set_ylabel('Timestep (s)')
215  ax.set_title('Length of Single Timestep: Model vs Data')
216  plt.legend(loc=1)
217  fig.savefig("Output/Figures/Element_Full.png")
218 
219  if (Parallelisation is 'Hybrid_Socket' or Parallelisation is 'Hybrid_Node'):
220  Data = []
221 
222  (Nektar_Modes_Fin, Timing_Files_Fin) = Find_Nektar_Files(Loc_Parallel_Timing_Files)
223 
224  for i in range(0, len(Timing_Files_Fin)):
225  Data.append(np.mean(Parse_Nektar_Output(Loc_Parallel_Timing_Files + Timing_Files_Fin[i]))/10)
226 
227  # Calculate the mean, standard deviation and variance of the difference between the data and the fitted model
228  difference = []
229 
230  for i in range(0, len(Timing_Files_Fin)):
231  difference.append(abs(Data[i] - Total[i]))
232 
233  mean_diff = np.mean(difference)
234  std_dev_diff = np.std(difference)
235  var_diff = np.var(difference)
236 
237  # Print these results for the user to see
238  print('The mean of the differences between the Data and the Model is ' + str(mean_diff))
239  print('The standard deviation of the differences between the Data and the Model is ' + str(std_dev_diff))
240  print('The variance of the differences between the Data and the Model is ' + str(var_diff))
241 
242  fig, ax = plt.subplots()
243  ax.plot(PROC_Z, Data, label = 'Data')
244  ax.plot(PROC_Z, Total, label = 'Model')
245  ax.set_xlabel('$ R_Z $')
246  ax.set_ylabel('Timestep (s)')
247  ax.set_title('Length of Single Timestep: Model vs Data')
248  plt.legend(loc=1)
249  fig.savefig("Output/Figures/Hybrid_Full.png")
def Parse_Nektar_Output
def Run_Parallel_Comparison
Definition: parallel.py:151
def Run_Parallel_Model
Definition: parallel.py:35