Statistiques
| Révision :

root / NBody / NBody.py @ 136

Historique | Voir | Annoter | Télécharger (14,47 ko)

1 128 equemene
#!/usr/bin/env python3
2 136 equemene
# -*- coding: utf-8 -*-
3 116 equemene
"""
4 116 equemene
Demonstrateur OpenCL d'interaction NCorps
5 116 equemene

6 116 equemene
Emmanuel QUEMENER <emmanuel.quemener@ens-lyon.fr> CeCILLv2
7 116 equemene
"""
8 116 equemene
import getopt
9 116 equemene
import sys
10 116 equemene
import time
11 116 equemene
import numpy as np
12 116 equemene
import pyopencl as cl
13 116 equemene
import pyopencl.array as cl_array
14 116 equemene
from numpy.random import randint as nprnd
15 116 equemene
16 132 equemene
def DictionariesAPI():
17 132 equemene
    Marsaglia={'CONG':0,'SHR3':1,'MWC':2,'KISS':3}
18 132 equemene
    Computing={'FP32':0,'FP64':1}
19 132 equemene
    return(Marsaglia,Computing)
20 132 equemene
21 116 equemene
BlobOpenCL= """
22 116 equemene
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
23 116 equemene
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
24 116 equemene
#define MWC   (znew+wnew)
25 116 equemene
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
26 116 equemene
#define CONG  (jcong=69069*jcong+1234567)
27 116 equemene
#define KISS  ((MWC^CONG)+SHR3)
28 116 equemene

29 116 equemene
#define MWCfp MWC * 2.328306435454494e-10f
30 116 equemene
#define KISSfp KISS * 2.328306435454494e-10f
31 116 equemene
#define SHR3fp SHR3 * 2.328306435454494e-10f
32 116 equemene
#define CONGfp CONG * 2.328306435454494e-10f
33 116 equemene

34 132 equemene
#define TFP32 0
35 132 equemene
#define TFP64 1
36 132 equemene

37 116 equemene
#define LENGTH 1.
38 116 equemene

39 116 equemene
#define PI 3.14159265359
40 116 equemene

41 116 equemene
#define SMALL_NUM 0.000000001
42 116 equemene

43 132 equemene
#if TYPE == TFP32
44 132 equemene
#define MYFLOAT4 float4
45 132 equemene
#define MYFLOAT8 float8
46 132 equemene
#define MYFLOAT float
47 132 equemene
#else
48 135 equemene
#pragma OPENCL EXTENSION cl_khr_fp64: enable
49 132 equemene
#define MYFLOAT4 double4
50 132 equemene
#define MYFLOAT8 double8
51 132 equemene
#define MYFLOAT double
52 132 equemene
#endif
53 132 equemene

54 132 equemene
MYFLOAT4 Interaction(MYFLOAT4 m,MYFLOAT4 n)
55 116 equemene
{
56 136 equemene
    // return((n-m)/(MYFLOAT)pow(distance(n,m),2));
57 132 equemene
    return((n-m)/(MYFLOAT)pow(distance(n,m),2));
58 116 equemene
}
59 116 equemene

60 133 equemene
MYFLOAT PairPotential(MYFLOAT4 m,MYFLOAT4 n)
61 133 equemene
{
62 133 equemene
    return((MYFLOAT)-1./distance(n,m));
63 133 equemene
}
64 133 equemene

65 120 equemene
// Elements from : http://doswa.com/2009/01/02/fourth-order-runge-kutta-numerical-integration.html
66 120 equemene

67 133 equemene

68 132 equemene
MYFLOAT8 AtomicRungeKutta(__global MYFLOAT8* clDataIn,int gid,MYFLOAT dt)
69 116 equemene
{
70 133 equemene
    MYFLOAT4 x0=(MYFLOAT4)clDataIn[gid].lo;
71 133 equemene
    MYFLOAT4 v0=(MYFLOAT4)clDataIn[gid].hi;
72 133 equemene
    MYFLOAT4 a0=(MYFLOAT4)(0.,0.,0.,0.);
73 133 equemene
    int N = get_global_size(0);
74 133 equemene

75 133 equemene
    for (int i=0;i<N;i++)
76 121 equemene
    {
77 121 equemene
        if (gid != i)
78 121 equemene
        a0+=Interaction(x0,clDataIn[i].lo);
79 121 equemene
    }
80 121 equemene

81 132 equemene
    MYFLOAT4 x1=x0+v0*(MYFLOAT)0.5*dt;
82 132 equemene
    MYFLOAT4 v1=v0+a0*(MYFLOAT)0.5*dt;
83 133 equemene
    MYFLOAT4 a1=(MYFLOAT4)(0.,0.,0.,0.);
84 133 equemene
    for (int i=0;i<N;i++)
85 121 equemene
    {
86 121 equemene
        if (gid != i)
87 121 equemene
        a1+=Interaction(x1,clDataIn[i].lo);
88 121 equemene
    }
89 121 equemene

90 132 equemene
    MYFLOAT4 x2=x0+v1*(MYFLOAT)0.5*dt;
91 132 equemene
    MYFLOAT4 v2=v0+a1*(MYFLOAT)0.5*dt;
92 133 equemene
    MYFLOAT4 a2=(MYFLOAT4)(0.,0.,0.,0.);
93 133 equemene
    for (int i=0;i<N;i++)
94 121 equemene
    {
95 121 equemene
        if (gid != i)
96 121 equemene
        a2+=Interaction(x2,clDataIn[i].lo);
97 121 equemene
    }
98 121 equemene

99 132 equemene
    MYFLOAT4 x3=x0+v2*dt;
100 132 equemene
    MYFLOAT4 v3=v0+a2*dt;
101 133 equemene
    MYFLOAT4 a3=(MYFLOAT)(0.,0.,0.,0.);
102 133 equemene
    for (int i=0;i<N;i++)
103 121 equemene
    {
104 121 equemene
        if (gid != i)
105 121 equemene
        a3+=Interaction(x3,clDataIn[i].lo);
106 121 equemene
    }
107 121 equemene

108 132 equemene
    MYFLOAT4 xf=x0+dt*(v0+(MYFLOAT)2.*(v1+v2)+v3)/(MYFLOAT)6.;
109 132 equemene
    MYFLOAT4 vf=v0+dt*(a0+(MYFLOAT)2.*(a1+a2)+a3)/(MYFLOAT)6.;
110 121 equemene

111 132 equemene
    return((MYFLOAT8)(xf.s0,xf.s1,xf.s2,xf.s3,vf.s0,vf.s1,vf.s2,vf.s3));
112 121 equemene
}
113 121 equemene

114 121 equemene
// Elements from : http://doswa.com/2009/01/02/fourth-order-runge-kutta-numerical-integration.html
115 121 equemene

116 132 equemene
MYFLOAT8 AtomicRungeKutta2(__global MYFLOAT8* clDataIn,int gid,MYFLOAT dt)
117 121 equemene
{
118 132 equemene
    MYFLOAT4 x[4],v[4],a[4],xf,vf;
119 133 equemene
    int N=get_global_size(0);
120 116 equemene

121 118 equemene
    x[0]=clDataIn[gid].lo;
122 118 equemene
    v[0]=clDataIn[gid].hi;
123 118 equemene
    a[0]=(0.,0.,0.,0.);
124 133 equemene

125 133 equemene
    for (int i=0;i<N;i++)
126 116 equemene
    {
127 116 equemene
        if (gid != i)
128 118 equemene
        a[0]+=Interaction(x[0],clDataIn[i].lo);
129 116 equemene
    }
130 118 equemene

131 132 equemene
    x[1]=x[0]+v[0]*(MYFLOAT)0.5*dt;
132 132 equemene
    v[1]=v[0]+a[0]*(MYFLOAT)0.5*dt;
133 118 equemene
    a[1]=(0.,0.,0.,0.);
134 133 equemene
    for (int i=0;i<N;i++)
135 116 equemene
    {
136 116 equemene
        if (gid != i)
137 118 equemene
        a[1]+=Interaction(x[1],clDataIn[i].lo);
138 116 equemene
    }
139 118 equemene

140 132 equemene
    x[2]=x[0]+v[1]*(MYFLOAT)0.5*dt;
141 132 equemene
    v[2]=v[0]+a[1]*(MYFLOAT)0.5*dt;
142 118 equemene
    a[2]=(0.,0.,0.,0.);
143 133 equemene
    for (int i=0;i<N;i++)
144 116 equemene
    {
145 116 equemene
        if (gid != i)
146 118 equemene
        a[2]+=Interaction(x[2],clDataIn[i].lo);
147 116 equemene
    }
148 118 equemene

149 118 equemene
    x[3]=x[0]+v[2]*dt;
150 118 equemene
    v[3]=v[0]+a[2]*dt;
151 118 equemene
    a[3]=(0.,0.,0.,0.);
152 133 equemene
    for (int i=0;i<N;i++)
153 116 equemene
    {
154 116 equemene
        if (gid != i)
155 118 equemene
        a[3]+=Interaction(x[3],clDataIn[i].lo);
156 116 equemene
    }
157 116 equemene

158 132 equemene
    xf=x[0]+dt*(v[0]+(MYFLOAT)2.*(v[1]+v[2])+v[3])/(MYFLOAT)6.;
159 132 equemene
    vf=v[0]+dt*(a[0]+(MYFLOAT)2.*(a[1]+a[2])+a[3])/(MYFLOAT)6.;
160 119 equemene

161 132 equemene
    return((MYFLOAT8)(xf.s0,xf.s1,xf.s2,xf.s3,vf.s0,vf.s1,vf.s2,vf.s3));
162 119 equemene
}
163 119 equemene

164 132 equemene
MYFLOAT8 AtomicEuler(__global MYFLOAT8* clDataIn,int gid,MYFLOAT dt)
165 119 equemene
{
166 132 equemene
    MYFLOAT4 x,v,a,xf,vf;
167 119 equemene

168 119 equemene
    x=clDataIn[gid].lo;
169 119 equemene
    v=clDataIn[gid].hi;
170 119 equemene
    a=(0.,0.,0.,0.);
171 119 equemene
    for (int i=0;i<get_global_size(0);i++)
172 119 equemene
    {
173 119 equemene
        if (gid != i)
174 119 equemene
        a+=Interaction(x,clDataIn[i].lo);
175 119 equemene
    }
176 133 equemene

177 119 equemene
    vf=v+dt*a;
178 133 equemene
    xf=x+dt*vf;
179 118 equemene

180 132 equemene
    return((MYFLOAT8)(xf.s0,xf.s1,xf.s2,xf.s3,vf.s0,vf.s1,vf.s2,vf.s3));
181 116 equemene
}
182 116 equemene

183 132 equemene
__kernel void SplutterPoints(__global MYFLOAT8* clData, MYFLOAT box, MYFLOAT velocity,
184 116 equemene
                               uint seed_z,uint seed_w)
185 116 equemene
{
186 116 equemene
    int gid = get_global_id(0);
187 133 equemene
    MYFLOAT N = (MYFLOAT) get_global_size(0);
188 116 equemene
    uint z=seed_z+(uint)gid;
189 116 equemene
    uint w=seed_w-(uint)gid;
190 133 equemene

191 132 equemene
    MYFLOAT theta=MWCfp*PI;
192 133 equemene
    MYFLOAT phi=MWCfp*PI*(MYFLOAT)2.;
193 132 equemene
    MYFLOAT sinTheta=sin(theta);
194 133 equemene
    clData[gid].s01234567 = (MYFLOAT8) (box*(MYFLOAT)(MWCfp-0.5),box*(MYFLOAT)(MWCfp-0.5),box*(MYFLOAT)(MWCfp-0.5),0.,0.,0.,0.,0.);
195 133 equemene
    MYFLOAT v=sqrt(N*(MYFLOAT)2./distance(clData[gid].lo,(MYFLOAT4) (0.,0.,0.,0.)));
196 133 equemene
    clData[gid].s4=v*sinTheta*cos(phi);
197 133 equemene
    clData[gid].s5=v*sinTheta*sin(phi);
198 133 equemene
    clData[gid].s6=v*cos(theta);
199 116 equemene
}
200 116 equemene

201 132 equemene
__kernel void RungeKutta(__global MYFLOAT8* clData,MYFLOAT h)
202 116 equemene
{
203 116 equemene
    int gid = get_global_id(0);
204 116 equemene

205 132 equemene
    MYFLOAT8 clDataGid=AtomicRungeKutta(clData,gid,h);
206 116 equemene
    barrier(CLK_GLOBAL_MEM_FENCE);
207 121 equemene
    clData[gid]=clDataGid;
208 116 equemene
}
209 116 equemene

210 132 equemene
__kernel void Euler(__global MYFLOAT8* clData,MYFLOAT h)
211 116 equemene
{
212 116 equemene
    int gid = get_global_id(0);
213 116 equemene

214 132 equemene
    MYFLOAT8 clDataGid=AtomicEuler(clData,gid,h);
215 116 equemene
    barrier(CLK_GLOBAL_MEM_FENCE);
216 121 equemene
    clData[gid]=clDataGid;
217 116 equemene
}
218 133 equemene

219 133 equemene
__kernel void Potential(__global MYFLOAT8* clData,__global MYFLOAT* clPotential)
220 133 equemene
{
221 133 equemene
    int gid = get_global_id(0);
222 133 equemene

223 133 equemene
    MYFLOAT potential=0.;
224 133 equemene
    MYFLOAT4 x=clData[gid].lo;
225 133 equemene

226 133 equemene
    for (int i=0;i<get_global_size(0);i++)
227 133 equemene
    {
228 133 equemene
        if (gid != i)
229 133 equemene
        potential+=PairPotential(x,clData[i].lo);
230 133 equemene
    }
231 133 equemene

232 133 equemene
    barrier(CLK_GLOBAL_MEM_FENCE);
233 133 equemene
    clPotential[gid]=(MYFLOAT)0.5*potential;
234 133 equemene
}
235 133 equemene

236 133 equemene
__kernel void Kinetic(__global MYFLOAT8* clData,__global MYFLOAT* clKinetic)
237 133 equemene
{
238 133 equemene
    int gid = get_global_id(0);
239 133 equemene

240 133 equemene
    clKinetic[gid]=(MYFLOAT)0.5*(pow(clData[gid].s4,2)+pow(clData[gid].s5,2)+pow(clData[gid].s6,2));
241 133 equemene
}
242 116 equemene
"""
243 116 equemene
244 133 equemene
def Energy(MyData):
245 133 equemene
    return(sum(pow(MyData,2)))
246 133 equemene
247 116 equemene
if __name__=='__main__':
248 116 equemene
249 132 equemene
    # ValueType
250 132 equemene
    ValueType='FP32'
251 132 equemene
    class MyFloat(np.float32):pass
252 132 equemene
    clType=cl_array.vec.float8
253 116 equemene
    # Set defaults values
254 118 equemene
    np.set_printoptions(precision=2)
255 116 equemene
    # Id of Device : 1 is for first find !
256 120 equemene
    Device=1
257 116 equemene
    # Iterations is integer
258 133 equemene
    Number=4
259 116 equemene
    # Size of box
260 132 equemene
    SizeOfBox=MyFloat(1.)
261 116 equemene
    # Initial velocity of particules
262 132 equemene
    Velocity=MyFloat(1.)
263 116 equemene
    # Redo the last process
264 133 equemene
    Iterations=100
265 116 equemene
    # Step
266 133 equemene
    Step=MyFloat(0.01)
267 121 equemene
    # Method of integration
268 121 equemene
    Method='RungeKutta'
269 132 equemene
    # InitialRandom
270 132 equemene
    InitialRandom=False
271 132 equemene
    # RNG Marsaglia Method
272 132 equemene
    RNG='MWC'
273 133 equemene
    # CheckEnergies
274 133 equemene
    CheckEnergies=False
275 134 equemene
    # Display samples in 3D
276 134 equemene
    GraphSamples=False
277 132 equemene
278 134 equemene
    HowToUse='%s -h [Help] -r [InitialRandom] -g [GraphSamples] -c [CheckEnergies] -d <DeviceId> -n <NumberOfParticules> -z <SizeOfBox> -v <Velocity> -s <Step> -i <Iterations> -m <RungeKutta|Euler> -t <FP32|FP64>'
279 116 equemene
280 116 equemene
    try:
281 134 equemene
        opts, args = getopt.getopt(sys.argv[1:],"rhgcd:n:z:v:i:s:m:t:",["random","graph","check","device=","number=","size=","velocity=","iterations=","step=","method=","valuetype="])
282 116 equemene
    except getopt.GetoptError:
283 128 equemene
        print(HowToUse % sys.argv[0])
284 116 equemene
        sys.exit(2)
285 116 equemene
286 116 equemene
    for opt, arg in opts:
287 116 equemene
        if opt == '-h':
288 128 equemene
            print(HowToUse % sys.argv[0])
289 116 equemene
290 128 equemene
            print("\nInformations about devices detected under OpenCL:")
291 116 equemene
            try:
292 132 equemene
                Id=0
293 116 equemene
                for platform in cl.get_platforms():
294 116 equemene
                    for device in platform.get_devices():
295 116 equemene
                        deviceType=cl.device_type.to_string(device.type)
296 128 equemene
                        print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip(),deviceType,device.name.lstrip()))
297 116 equemene
                        Id=Id+1
298 116 equemene
                sys.exit()
299 116 equemene
            except ImportError:
300 128 equemene
                print("Your platform does not seem to support OpenCL")
301 116 equemene
                sys.exit()
302 116 equemene
303 132 equemene
        elif opt in ("-t", "--valuetype"):
304 132 equemene
            if arg=='FP64':
305 132 equemene
                class MyFloat(np.float64): pass
306 132 equemene
                clType=cl_array.vec.double8
307 132 equemene
            else:
308 132 equemene
                class MyFloat(np.float32):pass
309 132 equemene
                clType=cl_array.vec.float8
310 132 equemene
            ValueType = arg
311 116 equemene
        elif opt in ("-d", "--device"):
312 116 equemene
            Device=int(arg)
313 121 equemene
        elif opt in ("-m", "--method"):
314 121 equemene
            Method=arg
315 116 equemene
        elif opt in ("-n", "--number"):
316 116 equemene
            Number=int(arg)
317 116 equemene
        elif opt in ("-z", "--size"):
318 132 equemene
            SizeOfBox=MyFloat(arg)
319 116 equemene
        elif opt in ("-v", "--velocity"):
320 132 equemene
            Velocity=MyFloat(arg)
321 116 equemene
        elif opt in ("-s", "--step"):
322 132 equemene
            Step=MyFloat(arg)
323 120 equemene
        elif opt in ("-i", "--iterations"):
324 120 equemene
            Iterations=int(arg)
325 132 equemene
        elif opt in ("-r", "--random"):
326 132 equemene
            InitialRandom=True
327 133 equemene
        elif opt in ("-c", "--check"):
328 133 equemene
            CheckEnergies=True
329 134 equemene
        elif opt in ("-g", "--graph"):
330 134 equemene
            GraphSamples=True
331 134 equemene
332 132 equemene
    SizeOfBox=MyFloat(SizeOfBox)
333 132 equemene
    Velocity=MyFloat(Velocity)
334 132 equemene
    Step=MyFloat(Step)
335 132 equemene
336 128 equemene
    print("Device choosed : %s" % Device)
337 128 equemene
    print("Number of particules : %s" % Number)
338 128 equemene
    print("Size of Box : %s" % SizeOfBox)
339 128 equemene
    print("Initial velocity % s" % Velocity)
340 128 equemene
    print("Number of iterations % s" % Iterations)
341 128 equemene
    print("Step of iteration % s" % Step)
342 128 equemene
    print("Method of resolution % s" % Method)
343 133 equemene
    print("Initial Random for RNG Seed % s" % InitialRandom)
344 134 equemene
    print("Check for Energies % s" % CheckEnergies)
345 134 equemene
    print("Graph for Samples % s" % GraphSamples)
346 132 equemene
    print("ValueType is % s" % ValueType)
347 116 equemene
348 132 equemene
    # Create Numpy array of CL vector with 8 FP32
349 132 equemene
    MyData = np.zeros(Number, dtype=clType)
350 133 equemene
    MyPotential = np.zeros(Number, dtype=MyFloat)
351 133 equemene
    MyKinetic = np.zeros(Number, dtype=MyFloat)
352 132 equemene
353 132 equemene
    Marsaglia,Computing=DictionariesAPI()
354 132 equemene
355 132 equemene
    # Scan the OpenCL arrays
356 132 equemene
    Id=0
357 116 equemene
    HasXPU=False
358 116 equemene
    for platform in cl.get_platforms():
359 116 equemene
        for device in platform.get_devices():
360 116 equemene
            if Id==Device:
361 116 equemene
                PlatForm=platform
362 116 equemene
                XPU=device
363 128 equemene
                print("CPU/GPU selected: ",device.name.lstrip())
364 116 equemene
                HasXPU=True
365 116 equemene
            Id+=1
366 116 equemene
367 116 equemene
    if HasXPU==False:
368 128 equemene
        print("No XPU #%i found in all of %i devices, sorry..." % (Device,Id-1))
369 116 equemene
        sys.exit()
370 116 equemene
371 132 equemene
    # Create Context
372 116 equemene
    try:
373 116 equemene
        ctx = cl.Context([XPU])
374 116 equemene
        queue = cl.CommandQueue(ctx,properties=cl.command_queue_properties.PROFILING_ENABLE)
375 116 equemene
    except:
376 128 equemene
        print("Crash during context creation")
377 116 equemene
378 132 equemene
    print(Marsaglia[RNG],Computing[ValueType])
379 132 equemene
    # Build all routines used for the computing
380 132 equemene
    MyRoutines = cl.Program(ctx, BlobOpenCL).build(options = "-cl-mad-enable -cl-fast-relaxed-math -DTRNG=%i -DTYPE=%i" % (Marsaglia[RNG],Computing[ValueType]))
381 119 equemene
382 119 equemene
# Initial forced values for exploration
383 118 equemene
#    MyData[0][0]=np.float32(-1.)
384 118 equemene
#    MyData[0][1]=np.float32(0.)
385 118 equemene
#    MyData[0][5]=np.float32(1.)
386 118 equemene
#    MyData[1][0]=np.float32(1.)
387 118 equemene
#    MyData[1][1]=np.float32(0.)
388 118 equemene
#    MyData[1][5]=np.float32(-1.)
389 116 equemene
390 116 equemene
    mf = cl.mem_flags
391 119 equemene
    clData = cl.Buffer(ctx, mf.READ_WRITE, MyData.nbytes)
392 133 equemene
    clPotential = cl.Buffer(ctx, mf.READ_WRITE, MyPotential.nbytes)
393 133 equemene
    clKinetic = cl.Buffer(ctx, mf.READ_WRITE, MyKinetic.nbytes)
394 119 equemene
    #clData = cl.Buffer(ctx, mf.WRITE_ONLY|mf.COPY_HOST_PTR,hostbuf=MyData)
395 116 equemene
396 134 equemene
    print('All particles superimposed.')
397 116 equemene
398 132 equemene
    print(SizeOfBox.dtype)
399 132 equemene
400 132 equemene
    # Set particles to RNG points
401 132 equemene
    if InitialRandom:
402 132 equemene
        MyRoutines.SplutterPoints(queue,(Number,1),None,clData,SizeOfBox,Velocity,np.uint32(nprnd(2**32)),np.uint32(nprnd(2**32)))
403 132 equemene
    else:
404 132 equemene
        MyRoutines.SplutterPoints(queue,(Number,1),None,clData,SizeOfBox,Velocity,np.uint32(110271),np.uint32(250173))
405 116 equemene
406 132 equemene
    print('All particules distributed')
407 119 equemene
408 133 equemene
    CLLaunch=MyRoutines.Potential(queue,(Number,1),None,clData,clPotential)
409 133 equemene
    CLLaunch.wait()
410 133 equemene
    if CheckEnergies:
411 133 equemene
        cl.enqueue_copy(queue,MyPotential,clPotential)
412 133 equemene
        CLLaunch=MyRoutines.Kinetic(queue,(Number,1),None,clData,clKinetic)
413 133 equemene
        CLLaunch.wait()
414 133 equemene
        cl.enqueue_copy(queue,MyKinetic,clKinetic)
415 133 equemene
        # print(np.sum(MyPotential)+2*np.sum(MyKinetic),np.sum(MyPotential),np.sum(MyKinetic),MyPotential,MyKinetic)
416 133 equemene
        print(np.sum(MyPotential)+2*np.sum(MyKinetic),np.sum(MyPotential),np.sum(MyKinetic))
417 133 equemene
418 134 equemene
    if GraphSamples:
419 134 equemene
        cl.enqueue_copy(queue, MyData, clData)
420 134 equemene
        t0=np.array([[MyData[0][0],MyData[0][1],MyData[0][2]]])
421 134 equemene
        t1=np.array([[MyData[1][0],MyData[1][1],MyData[1][2]]])
422 134 equemene
        tL=np.array([[MyData[-1][0],MyData[-1][1],MyData[-1][2]]])
423 116 equemene
424 116 equemene
    time_start=time.time()
425 128 equemene
    for i in range(Iterations):
426 132 equemene
        if Method=="RungeKutta":
427 132 equemene
            CLLaunch=MyRoutines.RungeKutta(queue,(Number,1),None,clData,Step)
428 121 equemene
        else:
429 132 equemene
            CLLaunch=MyRoutines.Euler(queue,(Number,1),None,clData,Step)
430 118 equemene
        CLLaunch.wait()
431 133 equemene
        if CheckEnergies:
432 133 equemene
            CLLaunch=MyRoutines.Potential(queue,(Number,1),None,clData,clPotential)
433 133 equemene
            CLLaunch.wait()
434 133 equemene
            cl.enqueue_copy(queue,MyPotential,clPotential)
435 133 equemene
            CLLaunch=MyRoutines.Kinetic(queue,(Number,1),None,clData,clKinetic)
436 133 equemene
            CLLaunch.wait()
437 133 equemene
            cl.enqueue_copy(queue,MyKinetic,clKinetic)
438 133 equemene
            # print(np.sum(MyPotential)+2*np.sum(MyKinetic),np.sum(MyPotential),np.sum(MyKinetic),MyPotential,MyKinetic)
439 133 equemene
            print(np.sum(MyPotential)+2*np.sum(MyKinetic),np.sum(MyPotential),np.sum(MyKinetic))
440 133 equemene
441 134 equemene
        if GraphSamples:
442 134 equemene
            cl.enqueue_copy(queue, MyData, clData)
443 134 equemene
            t0=np.append(t0,[MyData[0][0],MyData[0][1],MyData[0][2]])
444 134 equemene
            t1=np.append(t1,[MyData[1][0],MyData[1][1],MyData[1][2]])
445 134 equemene
            tL=np.append(tL,[MyData[-1][0],MyData[-1][1],MyData[-1][2]])
446 128 equemene
    print("\nDuration on %s for each %s" % (Device,(time.time()-time_start)/Iterations))
447 135 equemene
448 135 equemene
    if GraphSamples:
449 135 equemene
        t0=np.transpose(np.reshape(t0,(Iterations+1,3)))
450 135 equemene
        t1=np.transpose(np.reshape(t1,(Iterations+1,3)))
451 135 equemene
        tL=np.transpose(np.reshape(tL,(Iterations+1,3)))
452 118 equemene
453 135 equemene
        import matplotlib.pyplot as plt
454 135 equemene
        from mpl_toolkits.mplot3d import Axes3D
455 119 equemene
456 135 equemene
        fig = plt.figure()
457 135 equemene
        ax = fig.gca(projection='3d')
458 135 equemene
        ax.scatter(t0[0],t0[1],t0[2], marker='^',color='blue')
459 135 equemene
        ax.scatter(t1[0],t1[1],t1[2], marker='o',color='red')
460 135 equemene
        ax.scatter(tL[0],tL[1],tL[2], marker='D',color='green')
461 135 equemene
462 135 equemene
        ax.set_xlabel('X Label')
463 135 equemene
        ax.set_ylabel('Y Label')
464 135 equemene
        ax.set_zlabel('Z Label')
465 135 equemene
466 135 equemene
        plt.show()
467 119 equemene
468 119 equemene
    clData.release()
469 133 equemene
    clKinetic.release()
470 133 equemene
    clPotential.release()