9 print("Usage : %s datafile links latency bandwidth [size...]" % sys.argv[0])
10 print("where : datafile is a SkaMPI pingpong measurement log file");
11 print(" links is the number of links between nodes")
12 print(" latency is the nominal latency given in the platform file")
13 print(" bandwidth is the nominal bandwidth given in the platform file")
14 print(" size are segments limits")
17 ##-----------------------------------------
18 ## avg : return average of a list of values
19 ## param l list of values
20 ##-----------------------------------------
27 ##-------------------------------------------------
29 ## param X first data vector (..x_i..)
30 ## param Y second data vector (..x_i..)
31 ## = 1/n \Sum_{i=1}^n (x_i - avg(x)) * (y_i - avg(y))
32 ##--------------------------------------------------
34 assert len(X) == len(Y)
35 n = len(X) # n=len(X)=len(Y)
40 S_XY += (X[i] - avg_X) * (Y[i] - avg_Y)
43 ##---------------------------------------------------------------------
44 ## variance : variance
45 ## param X data vector ( ..x_i.. )
46 ## (S_X)^2 = (Sum ( x_i - avg(x) )^2 ) / n
47 ##---------------------------------------------------------------------
53 S_X2 += (X[i] - avg_X) ** 2
56 ##---------------------------------------------------------------------
57 ## calibrate : output correction factors, c_lat on latency, c_bw on bw
58 ## such that bandwidth * c_bw = bw_regr, latency * c_lat = lat_regr
59 ## where bw_regr and lat_regr are the values approximating experimental
62 ## param links number of links traversed during ping-pong
63 ## param latency as specified on command line, in s
64 ## param bandwidth as specified on command line, in Byte/s
65 ## param sizes vector of data sizes, in Bytes
66 ## param timings vector of time taken: timings[i] for sizes[i], in us
67 ##---------------------------------------------------------------------
68 def calibrate (links, latency, bandwidth, sizes, timings):
69 assert len(sizes) == len(timings)
72 # compute linear regression : find an affine form time = a*size+b
73 S_XY = cov(sizes, timings)
74 S_X2 = variance(sizes)
76 b = avg(timings) - a * avg(sizes)
77 # corresponding bandwith, in byte/s (was in byte/us in skampi dat)
79 # corresponding latency, in s (was in us in skampi dat)
81 print("\nregression: {0} * x + {1}".format(a,b))
82 print("corr_bw = bw_regr/bandwidth= {0}/{1}={2} lat_regr/(lat_xml*links)={3}/({4}*{5}))".format(bw_regr,bandwidth,bw_regr/bandwidth,lat_regr,latency,links))
83 # return linear regression result and corresponding correction factors c_bw,c_lat
84 return a,b, bw_regr/bandwidth, lat_regr/(latency*links)
87 ##---------------------------------------------------------------------
88 ## outputs a C formatted conditional return value for factor
90 ## param lb lower bound
91 ## param ub upper bound
92 ## param lb_included boolean to tell if bound is included (<=) or exclude (<)
93 ## param ub_included boolean to tell if bound is included (<=) or exclude (<)
94 ##---------------------------------------------------------------------
95 def c_code_print (lb,ub, retval, lb_included, ub_included):
104 print("\t /* case {0:.1f} KiB {1} size {2} {3:.1f} KiB */".format(lb_kib,lb_cmp,ub_cmp,ub_kib))
105 print("\t if ({0:d} {1} size && size {2} {3:d}) ".format(lb,lb_cmp,ub_cmp,ub))
106 print("\t return({0});" . format(retval))
109 ##-----------------------------------------------------------------------------------------------
111 ##-----------------------------------------------------------------------------------------------
112 links = int(sys.argv[2])
113 latency = float(sys.argv[3])
114 bandwidth = float(sys.argv[4])
115 skampidat = open(sys.argv[1], "r")
117 ## read data from skampi logs.
121 for line in skampidat:
123 if line[0] != '#' and len(l) >= 3: # is it a comment ?
126 #count= 8388608 8388608 144916.1 7.6 32 144916.1 143262.0
127 #("%s %d %d %f %f %d %f %f\n" % (countlbl, count, countn, time, stddev, iter, mini, maxi)
128 readdata.append( (int(l[1]),float(l[3]) / 2) ); # divide by 2 because of ping-pong measured
130 ## These may not be sorted so sort it by message size before processing.
131 sorteddata = sorted( readdata, key=lambda pair: pair[0])
132 sizes,timings= zip(*sorteddata)
135 ## adds message sizes of interest: if values are specified starting from the 6th command line arg
136 ## and these values are found as message sizes in te log file, add it to the limits list.
137 ## Each of these value si considered a potential inflexion point between two segments.
139 ## If no value specified, a single segment is considered from 1st to last message size logged.
141 if len(sys.argv) > 5:
142 for i in range(5, len(sys.argv)):
143 limits += [idx for idx in range(len(sizes)) if sizes[idx] == int(sys.argv[i])]
144 limits.append(len(sizes) - 1)
149 correc = calibrate(links, latency, bandwidth, sizes[low:lim + 1], timings[low:lim + 1])
151 # save interval [lb,ub] correction, regression line direction and origin
152 # and corresponding correction factors for bw and lat resp.
153 (dircoef,origin,factor_bw,factor_lat) = correc
154 factors.append( (sizes[low],sizes[lim], dircoef, origin, factor_bw,factor_lat) )
155 print("Segment [%d:%d] --Bandwidth factor=%g --Latency factor=%g " % (sizes[low], sizes[lim], factor_bw,factor_lat))
158 # now computes joining lines between segments
161 print("\n/**\n *------------------ <copy/paste C code snippet in surf/network.c> ----------------------")
162 print(" *\n * produced by: {0}\n *".format(' '.join(sys.argv)))
163 print(" *---------------------------------------------------------------------------------------\n **/")
165 # print correction factor for bandwidth for each segment
166 print("static double smpi_bandwidth_factor(double size)\n{")
167 for (lb,ub,a,b,factor_bw,factor_lat) in factors:
168 c_code_print(lb,ub,factor_bw,True,True)
170 # save ends and starts of segments
172 joinseg.append( (lb,timings[sizes.index(lb)]) )
174 joinseg.append( (ub,timings[sizes.index(ub)]) )
176 # print correction factor for bandwidth between segments
178 print("\n\t /* ..:: inter-segment corrections ::.. */");
181 (x0,y0) = joinseg[inx]
183 (x1,y1) = joinseg[inx]
185 # line eq. is y = (y1-y0)/(x0-x1) * x + (y0 x1 - y1 x0)/(x1-x0)
186 a = (y1-y0) / (x1-x0)
188 factor_join_bw = bw_join / bandwidth
189 #print("Joining points (%f,%f) -> (%f,%f) : line dir : a=%g\n" % (x0,y0,x1,y1,a))
190 c_code_print(x0,x1,factor_join_bw,False,False)
194 # print correction factor for latency for each segment
195 print("static double smpi_latency_factor(double size)\n{")
196 for (lb,ub,a,b,factor_bw,factor_lat) in factors:
197 c_code_print(lb,ub,factor_lat,True,True)
199 print("\n\t /* ..:: inter-segment corrections ::.. */");
201 (x0,y0) = joinseg.pop()
202 (x1,y1) = joinseg.pop()
203 # line eq. is y = (y0-y1)/(x0-x1) * x + (y0 x1 - y1 x0)/(x1-x0)
204 #print("(%f,%f) -> (%f,%f)\n" % (x0,y0,x1,y1))
205 b = 1e-6 * (y0*x1-y1*x0) / (x1-x0)
206 factor_join_lat = b / (latency*links)
207 c_code_print(x0,x1,factor_join_lat,False,False)
211 print("\n/**\n *------------------ <copy/paste C code snippet in surf/network.c> ----------------------\n **/")