Nektar++
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
10import matplotlib.pyplot as plt
11import numpy as np
12
13#------------------------------------
14# Import relevant main functions
15#------------------------------------
16
17from functions_main import Find_Topologies
18from functions_main import Partition
19from functions_main import Find_Nektar_Files
20from functions_main import Parse_Nektar_Output
21
22#------------------------------------
23# Import the required class
24#------------------------------------
25
26from class_topology import Topology
27
28#------------------------------------
29# New Function
30#------------------------------------
31
32# Function to run the full communication model
33def 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
151def 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(Input_Filename, Skip_Steps)
def Partition(Input_Filename, PROC_XY)
def Find_Topologies(PROC_TOT, Num_Modes)
def Find_Nektar_Files(Input_Filename)
def Run_Parallel_Comparison(Loc_Parallel_Timing_Files, Parallelisation, PROC_Z, PROC_XY, Total)
Definition: parallel.py:151
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, 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, Velocity_3)
Definition: parallel.py:35
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298