Statistiques
| Révision :

root / Pi / MP / PiMP-unprotected.py @ 78

Historique | Voir | Annoter | Télécharger (7,29 ko)

1 7 equemene
#!/usr/bin/env python
2 7 equemene
3 7 equemene
# Version using Multiprocessing module
4 7 equemene
#
5 7 equemene
# Pi-by-MC
6 7 equemene
#
7 7 equemene
# CC BY-NC-SA 2013 : <emmanuel.quemener@ens-lyon.fr>
8 7 equemene
#
9 7 equemene
10 7 equemene
import getopt
11 7 equemene
import numpy
12 7 equemene
13 7 equemene
from random import random
14 7 equemene
# Multithread library call
15 7 equemene
from multiprocessing import Pool
16 7 equemene
17 7 equemene
# Common tools
18 7 equemene
import sys
19 7 equemene
import getopt
20 7 equemene
import time
21 7 equemene
import matplotlib.pyplot as plt
22 7 equemene
import math
23 7 equemene
from scipy.optimize import curve_fit
24 7 equemene
from socket import gethostname
25 7 equemene
26 7 equemene
# Predicted Amdahl Law (Reduced with s=1-p)
27 7 equemene
def AmdahlR(N, T1, p):
28 7 equemene
    return (T1*(1-p+p/N))
29 7 equemene
30 7 equemene
# Predicted Amdahl Law
31 7 equemene
def Amdahl(N, T1, s, p):
32 7 equemene
    return (T1*(s+p/N))
33 7 equemene
34 7 equemene
# Predicted Mylq Law with first order
35 7 equemene
def Mylq(N, T1,s,c,p):
36 7 equemene
    return (T1*(s+c*N+p/N))
37 7 equemene
38 7 equemene
# Predicted Mylq Law with second order
39 7 equemene
def Mylq2(N, T1,s,c1,c2,p):
40 7 equemene
    return (T1*(s+c1*N+c2*N*N+p/N))
41 7 equemene
42 7 equemene
def MainLoop(iterations):
43 7 equemene
44 7 equemene
    total=0
45 7 equemene
    # Absulute necessary to use xrange instead of range to avoid out of memory !
46 7 equemene
    for i in xrange(iterations):
47 7 equemene
        # Random access coordonate
48 7 equemene
        x,y=random(),random()
49 7 equemene
50 7 equemene
        if ((x*x+y*y) < 1.0):
51 7 equemene
            total+=1
52 7 equemene
53 7 equemene
    return(total)
54 7 equemene
55 7 equemene
def MetropolisMP(circle,iterations,steps,jobs):
56 7 equemene
57 7 equemene
    MyPi=numpy.zeros(steps)
58 7 equemene
    MyDuration=numpy.array([])
59 7 equemene
60 7 equemene
    # Define iterations to send to each node
61 7 equemene
    if iterations%jobs==0:
62 7 equemene
        iterationsMP=iterations/jobs
63 7 equemene
    else:
64 7 equemene
        iterationsMP=iterations/jobs+1
65 7 equemene
    print "%i iterations will be send to each core" % iterationsMP
66 7 equemene
67 7 equemene
    WorkItems=[]
68 7 equemene
    for i in xrange(0,jobs):
69 7 equemene
        WorkItems.append(iterationsMP)
70 7 equemene
71 7 equemene
    for i in xrange(steps):
72 7 equemene
        start=time.time()
73 7 equemene
        pool=Pool(processes=jobs)
74 7 equemene
        # Define the number of processes to be launched at a time
75 7 equemene
        # pool=Pool(processes=CORES)
76 7 equemene
        print "Start on %i processors..." % jobs
77 7 equemene
        # MAP: distribution of usecases T to be applied to MetropolisStrip
78 7 equemene
        # WorkLaunches=[ pool.apply_async(MainLoop,(wi,)) for wi in WorkItems ]
79 7 equemene
        # circle=[wl.get() for wl in WorkLaunches]
80 7 equemene
        circle=pool.map(MainLoop,WorkItems)
81 7 equemene
        MyDuration=numpy.append(MyDuration,time.time()-start)
82 7 equemene
        MyPi[i]=4.*float(numpy.sum(circle))/float(iterationsMP)/float(jobs)
83 7 equemene
84 7 equemene
    return(numpy.mean(MyDuration),numpy.median(MyDuration),numpy.std(MyDuration))
85 7 equemene
86 7 equemene
def FitAndPrint(N,D,Curves):
87 7 equemene
88 7 equemene
    try:
89 7 equemene
      coeffs_Amdahl, matcov_Amdahl = curve_fit(Amdahl, N, D)
90 7 equemene
91 7 equemene
      D_Amdahl=Amdahl(N,coeffs_Amdahl[0],coeffs_Amdahl[1],coeffs_Amdahl[2])
92 7 equemene
      coeffs_Amdahl[1]=coeffs_Amdahl[1]*coeffs_Amdahl[0]/D[0]
93 7 equemene
      coeffs_Amdahl[2]=coeffs_Amdahl[2]*coeffs_Amdahl[0]/D[0]
94 7 equemene
      coeffs_Amdahl[0]=D[0]
95 7 equemene
      print "Amdahl Normalized: T=%.2f(%.6f+%.6f/N)" % \
96 7 equemene
            (coeffs_Amdahl[0],coeffs_Amdahl[1],coeffs_Amdahl[2])
97 7 equemene
    except:
98 7 equemene
        print "Impossible to fit for Amdahl law : only %i elements" % len(D)
99 7 equemene
100 7 equemene
    try:
101 7 equemene
        coeffs_AmdahlR, matcov_AmdahlR = curve_fit(AmdahlR, N, D)
102 7 equemene
103 7 equemene
        D_AmdahlR=AmdahlR(N,coeffs_AmdahlR[0],coeffs_AmdahlR[1])
104 7 equemene
        coeffs_AmdahlR[1]=coeffs_AmdahlR[1]*coeffs_AmdahlR[0]/D[0]
105 7 equemene
        coeffs_AmdahlR[0]=D[0]
106 7 equemene
        print "Amdahl Reduced Normalized: T=%.2f(%.6f+%.6f/N)" % \
107 7 equemene
              (coeffs_AmdahlR[0],1-coeffs_AmdahlR[1],coeffs_AmdahlR[1])
108 7 equemene
    except:
109 7 equemene
        print "Impossible to fit for Reduced Amdahl law : only %i elements" % len(D)
110 7 equemene
111 7 equemene
    try:
112 7 equemene
        coeffs_Mylq, matcov_Mylq = curve_fit(Mylq, N, D)
113 7 equemene
114 7 equemene
        coeffs_Mylq[1]=coeffs_Mylq[1]*coeffs_Mylq[0]/D[0]
115 7 equemene
        coeffs_Mylq[2]=coeffs_Mylq[2]*coeffs_Mylq[0]/D[0]
116 7 equemene
        coeffs_Mylq[3]=coeffs_Mylq[3]*coeffs_Mylq[0]/D[0]
117 7 equemene
        coeffs_Mylq[0]=D[0]
118 7 equemene
        print "Mylq Normalized : T=%.2f(%.6f+%.6f*N+%.6f/N)" % (coeffs_Mylq[0],
119 7 equemene
                                                                coeffs_Mylq[1],
120 7 equemene
                                                                coeffs_Mylq[2],
121 7 equemene
                                                                coeffs_Mylq[3])
122 7 equemene
        D_Mylq=Mylq(N,coeffs_Mylq[0],coeffs_Mylq[1],coeffs_Mylq[2],
123 7 equemene
                    coeffs_Mylq[3])
124 7 equemene
    except:
125 7 equemene
        print "Impossible to fit for Mylq law : only %i elements" % len(D)
126 7 equemene
127 7 equemene
    if Curves:
128 7 equemene
        plt.xlabel("Number of Threads/work Items")
129 7 equemene
        plt.ylabel("Total Elapsed Time")
130 7 equemene
131 7 equemene
        Experience,=plt.plot(N,D,'ro')
132 7 equemene
        try:
133 7 equemene
            pAmdahl,=plt.plot(N,D_Amdahl,label="Loi de Amdahl")
134 7 equemene
            pMylq,=plt.plot(N,D_Mylq,label="Loi de Mylq")
135 7 equemene
        except:
136 7 equemene
            print "Fit curves seem not to be available"
137 7 equemene
138 7 equemene
        plt.legend()
139 7 equemene
        plt.show()
140 7 equemene
141 7 equemene
if __name__=='__main__':
142 7 equemene
143 7 equemene
    # Set defaults values
144 7 equemene
    # Iterations is integer
145 7 equemene
    Iterations=1000000
146 7 equemene
    # JobStart in first number of Jobs to explore
147 7 equemene
    JobStart=1
148 7 equemene
    # JobEnd is last number of Jobs to explore
149 7 equemene
    JobEnd=1
150 7 equemene
    # Redo is the times to redo the test to improve metrology
151 7 equemene
    Redo=1
152 7 equemene
    # OutMetrology is method for duration estimation : False is GPU inside
153 7 equemene
    OutMetrology=False
154 7 equemene
    # Curves is True to print the curves
155 7 equemene
    Curves=False
156 7 equemene
157 7 equemene
    try:
158 7 equemene
        opts, args = getopt.getopt(sys.argv[1:],"hoci:s:e:r:",["alu=","gpustyle=","parastyle=","iterations=","jobstart=","jobend=","redo=","device="])
159 7 equemene
    except getopt.GetoptError:
160 7 equemene
        print '%s -o (Out of Core Metrology) -c (Print Curves) -i <Iterations> -s <JobStart> -e <JobEnd> -r <RedoToImproveStats>' % sys.argv[0]
161 7 equemene
        sys.exit(2)
162 7 equemene
163 7 equemene
    for opt, arg in opts:
164 7 equemene
        if opt == '-h':
165 7 equemene
            print '%s -o (Out of Core Metrology) -c (Print Curves) -i <Iterations> -s <JobStart> -e <JobEnd> -r <RedoToImproveStats>' % sys.argv[0]
166 7 equemene
            sys.exit()
167 7 equemene
        elif opt == '-o':
168 7 equemene
            OutMetrology=True
169 7 equemene
        elif opt == '-c':
170 7 equemene
            Curves=True
171 7 equemene
        elif opt in ("-i", "--iterations"):
172 7 equemene
            Iterations = numpy.uint32(arg)
173 7 equemene
        elif opt in ("-s", "--jobstart"):
174 7 equemene
            JobStart = int(arg)
175 7 equemene
        elif opt in ("-e", "--jobend"):
176 7 equemene
            JobEnd = int(arg)
177 7 equemene
        elif opt in ("-r", "--redo"):
178 7 equemene
            Redo = int(arg)
179 7 equemene
180 7 equemene
    print "Iterations : %s" % Iterations
181 7 equemene
    print "Number of threads on start : %s" % JobStart
182 7 equemene
    print "Number of threads on end : %s" % JobEnd
183 7 equemene
    print "Number of redo : %s" % Redo
184 7 equemene
    print "Metrology done out : %r" % OutMetrology
185 7 equemene
186 7 equemene
    average=numpy.array([]).astype(numpy.float32)
187 7 equemene
    median=numpy.array([]).astype(numpy.float32)
188 7 equemene
    stddev=numpy.array([]).astype(numpy.float32)
189 7 equemene
190 7 equemene
    ExploredJobs=numpy.array([]).astype(numpy.uint32)
191 7 equemene
192 7 equemene
    Jobs=JobStart
193 7 equemene
194 7 equemene
    while Jobs <= JobEnd:
195 7 equemene
        avg,med,std=0,0,0
196 7 equemene
        ExploredJobs=numpy.append(ExploredJobs,Jobs)
197 7 equemene
        circle=numpy.zeros(Jobs).astype(numpy.uint32)
198 7 equemene
199 7 equemene
        if OutMetrology:
200 7 equemene
            duration=numpy.array([]).astype(numpy.float32)
201 7 equemene
            for i in range(Redo):
202 7 equemene
                start=time.time()
203 7 equemene
                MetropolisMP(circle,Iterations,Redo,Jobs)
204 7 equemene
                duration=numpy.append(duration,time.time()-start)
205 7 equemene
            avg=numpy.mean(duration)
206 7 equemene
            med=numpy.median(duration)
207 7 equemene
            std=numpy.std(duration)
208 7 equemene
        else:
209 7 equemene
            avg,med,std=MetropolisMP(circle,Iterations,Redo,Jobs)
210 7 equemene
211 7 equemene
        if (avg,med,std) != (0,0,0):
212 7 equemene
            print "avg,med,std",avg,med,std
213 7 equemene
            average=numpy.append(average,avg)
214 7 equemene
            median=numpy.append(median,med)
215 7 equemene
            stddev=numpy.append(stddev,std)
216 7 equemene
        else:
217 7 equemene
            print "Values seem to be wrong..."
218 7 equemene
        # THREADS*=2
219 7 equemene
        numpy.savez("Pi_%s_%i_%.8i_%s" % (JobStart,JobEnd,Iterations,gethostname()),(ExploredJobs,average,median,stddev))
220 7 equemene
        Jobs+=1
221 7 equemene
222 7 equemene
    FitAndPrint(ExploredJobs,median,Curves)