Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 203

Historique | Voir | Annoter | Télécharger (23,64 ko)

1
#!/usr/bin/env python
2
#
3
# TrouNoir model using PyOpenCL 
4
#
5
# CC BY-NC-SA 2019 : <emmanuel.quemener@ens-lyon.fr> 
6
#
7
# Thanks to Andreas Klockner for PyOpenCL:
8
# http://mathema.tician.de/software/pyopencl
9
# 
10
# Original code programmed in Fortran 77 in mars 1994
11
# for Practical Work of Numerical Simulation
12
# DEA (old Master2) in astrophysics and spatial techniques in Meudon
13
# by Herve Aussel & Emmanuel Quemener
14
#
15
# Conversion in C done by Emmanuel Quemener in august 1997
16
# GPUfication in OpenCL under Python in july 2019
17
#
18
# Thanks to :
19
# 
20
# - Herve Aussel for his part of code of black body spectrum
21
# - Didier Pelat for his help to perform this work
22
# - Jean-Pierre Luminet for his article published in 1979
23
# - Numerical Recipies for Runge Kutta recipies
24
# - Luc Blanchet for his disponibility about my questions in General Relativity
25
# - Pierre Lena for his passion about science and vulgarisation
26

    
27
import pyopencl as cl
28
import numpy
29
from PIL import Image
30
import time,string
31
from numpy.random import randint as nprnd
32
import sys
33
import getopt
34
import matplotlib.pyplot as plt
35

    
36

    
37

    
38

    
39

    
40

    
41

    
42

    
43
KERNEL_CODE=string.Template("""
44

45
#define PI (float)3.14159265359
46
#define nbr 200
47

48
float atanp(float x,float y)
49
{
50
  float angle;
51

52
  angle=atan2(y,x);
53

54
  if (angle<0.e0f)
55
    {
56
      angle+=(float)2.e0f*PI;
57
    }
58

59
  return angle;
60
}
61

62
float f(float v)
63
{
64
  return v;
65
}
66

67
float g(float u,float m,float b)
68
{
69
  return (3.e0f*m/b*pow(u,2)-u);
70
}
71

72

73
void calcul(float *us,float *vs,float up,float vp,
74
            float h,float m,float b)
75
{
76
  float c0,c1,c2,c3,d0,d1,d2,d3;
77

78
  c0=h*f(vp);
79
  c1=h*f(vp+c0/2.);
80
  c2=h*f(vp+c1/2.);
81
  c3=h*f(vp+c2);
82
  d0=h*g(up,m,b);
83
  d1=h*g(up+d0/2.,m,b);
84
  d2=h*g(up+d1/2.,m,b);
85
  d3=h*g(up+d2,m,b);
86

87
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
88
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
89
}
90

91
void rungekutta(float *ps,float *us,float *vs,
92
                float pp,float up,float vp,
93
                float h,float m,float b)
94
{
95
  calcul(us,vs,up,vp,h,m,b);
96
  *ps=pp+h;
97
}
98

99
float decalage_spectral(float r,float b,float phi,
100
                         float tho,float m)
101
{
102
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
103
}
104

105
float spectre(float rf,int q,float b,float db,
106
             float h,float r,float m,float bss)
107
{
108
  float flx;
109

110
  flx=pow(r/m,q)*pow(rf,4)*b;
111
  return(flx);
112
}
113

114
float spectre_cn(float rf,float b,float db,float h,float r,float m,float bss)
115
{
116
  double flx;
117
  double nu_rec,nu_em,qu,v,temp,temp_em,flux_int,m_point,planck,c,k,psc2,psk;
118
  int fi,posfreq;
119

120
  planck=6.62e-34;
121
  k=1.38e-23;
122
  psk=5.38e-11;
123
  psc2=7.35e-51;
124
  temp=3.e7;
125
  m_point=1.e14;
126
  v=1.-3./r;
127

128
  qu=1./sqrt(1.-3./r)/sqrt(r)*(sqrt(r)-sqrt(6.)+sqrt(3.)/2.*log((sqrt(r)+sqrt(3.))/(sqrt(r)-sqrt(3.))*(sqrt(6.)-sqrt(3.))/(sqrt(6.)+sqrt(3.))));
129

130
  temp_em=temp*sqrt(m)*exp(0.25*log(m_point))*exp(-0.75*log(r))*exp(-0.125*log(v))*exp(0.25*log(qu));
131

132
  flux_int=0;
133
  flx=0;
134

135
  for (fi=0;fi<nbr;fi++)
136
    {
137
      nu_em=bss*(float)fi/(float)nbr;
138
      nu_rec=nu_em*rf; 
139
      posfreq=(int)(1./bss*nu_rec*(float)nbr);
140
      if ((posfreq>0)&&(posfreq<nbr))
141
        {
142
          //flux_int=2*planck/9.e16f*pow(nu_em,3)/(exp(planck*nu_em/k/temp_em)-1.)*pow(rf,3)*b*db*h;
143
          //flux_int=pow(nu_em,3)/(exp(planck*nu_em/k/temp_em)-1.)*pow(rf,3)*b;
144
          flux_int=2.*psc2*pow(nu_em,3)/(exp(psk*nu_em/temp_em)-1.)*pow(rf,3)*b;
145
          flx+=flux_int;
146
        }
147
    }
148
  //return(pow(rf,3)*b*temp_em);
149
  return((float)flx);
150
  return(flx);
151
}
152

153
void impact(float phi,float r,float b,float tho,float m,
154
            float *zp,float *fp,
155
            int q,float db,
156
            float h,int raie)
157
{
158
  float flx,rf,bss;
159

160
  rf=decalage_spectral(r,b,phi,tho,m);
161

162
  if (raie==0)
163
    {
164
      bss=2.;
165
      flx=spectre(rf,q,b,db,h,r,m,bss);
166
    }
167
  else
168
    {
169
      bss=1.e6;
170
      flx=spectre_cn(rf,b,db,h,r,m,bss);
171
    }
172
  
173
  *zp=1./rf;
174
  *fp=flx;
175

176
}
177

178
__kernel void EachPixel(__global float *zImage,__global float *fImage,
179
                        float Mass,float InternalRadius,
180
                        float ExternalRadius,float Angle,
181
                        float ObserverDistance,
182
                        int BlackBody,int AngularCamera)
183
{
184
   uint xi=(uint)get_global_id(0);
185
   uint yi=(uint)get_global_id(1);
186
   uint sizex=(uint)get_global_size(0);
187
   uint sizey=(uint)get_global_size(1);
188

189
   // Perform trajectory for each pixel, exit on hit
190

191
  float m,rs,ri,re,tho,ro;
192
  int q,dist,raie;
193

194
  m=Mass;
195
  rs=2.*m;
196
  ri=InternalRadius;
197
  re=ExternalRadius;
198
  ro=ObserverDistance;
199
  tho=Angle;
200
  q=-2;
201
  dist=AngularCamera;
202
  raie=BlackBody;
203

204
  float d,bmx,db,b,h;
205
  float rp[2048];
206
  float phi,thi,phd,php,nr,r;
207
  int nh;
208
  float zp,fp;
209

210
  // Autosize for image
211
  bmx=1.25*re;
212
  b=0.;
213

214
  h=4.e0f*PI/(float)2048;
215

216
  // set origin as center of image
217
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
218
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
219
  // angle extracted from cylindric symmetry
220
  phi=atanp(x,y);
221
  phd=atanp(cos(phi)*sin(tho),cos(tho));
222

223
  float up,vp,pp,us,vs,ps;
224

225
  // impact parameter
226
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
227
  // step of impact parameter;
228
  db=bmx/(float)(sizex/2);
229

230
  if (dist==1) 
231
  {
232
     up=0.;
233
     vp=1.;
234
  }
235
  else 
236
  {
237
     up=sin(thi);
238
     vp=cos(thi);
239
  }
240
      
241
  pp=0.;
242
  nh=0;
243

244
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
245
    
246
  rp[nh]=fabs(b/us);
247

248
  int ExitOnImpact=0;
249

250
  do
251
  {
252
     nh++;
253
     pp=ps;
254
     up=us;
255
     vp=vs;
256
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);          
257
     rp[nh]=fabs(b/us);
258
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rp[nh]>ri)&&(rp[nh]<re)?1:0;          
259

260
  } while ((rp[nh]>=rs)&&(rp[nh]<=rp[0])&&(ExitOnImpact==0));
261

262
  if (ExitOnImpact==1) {
263
     impact(phi,rp[nh-1],b,tho,m,&zp,&fp,q,db,h,raie);
264
  }
265
  else
266
  {
267
     zp=0.;
268
     fp=0.;
269
  }
270

271
  barrier(CLK_GLOBAL_MEM_FENCE);
272

273
  zImage[yi+sizex*xi]=(float)zp;
274
  fImage[yi+sizex*xi]=(float)fp;  
275
}
276

277
__kernel void Pixel(__global float *zImage,__global float *fImage,
278
                    __global float *Trajectories,__global int *IdLast,
279
                    uint ImpactParameter,uint TrackPoints,
280
                    float Mass,float InternalRadius,
281
                    float ExternalRadius,float Angle,
282
                    float ObserverDistance,
283
                    int BlackBody,int AngularCamera)
284
{
285
   uint xi=(uint)get_global_id(0);
286
   uint yi=(uint)get_global_id(1);
287
   uint sizex=(uint)get_global_size(0);
288
   uint sizey=(uint)get_global_size(1);
289

290
   // Perform trajectory for each pixel
291

292
  float m,rs,ri,re,tho,ro;
293
  int q,dist,raie;
294

295
  m=Mass;
296
  rs=2.*m;
297
  ri=InternalRadius;
298
  re=ExternalRadius;
299
  ro=ObserverDistance;
300
  tho=Angle;
301
  q=-2;
302
  dist=AngularCamera;
303
  raie=BlackBody;
304

305
  float d,bmx,db,b,h;
306
  float phi,thi,phd,php,nr,r;
307
  int nh;
308
  float zp=0,fp=0;
309

310
  // Autosize for image, 25% greater than externa radius
311
  bmx=1.25*re;
312

313
  // Angular step of integration
314
  h=4.e0f*PI/(float)TrackPoints;
315

316
  // Step of Impact Parameter
317
  db=bmx/(float)ImpactParameter;
318

319
  // set origin as center of image
320
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
321
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
322

323
  // angle extracted from cylindric symmetry
324
  phi=atanp(x,y);
325
  phd=atanp(cos(phi)*sin(tho),cos(tho));
326

327
  // Real Impact Parameter
328
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
329

330
  // Integer Impact Parameter
331
  uint bi=(uint)sqrt(x*x+y*y);
332

333
  int HalfLap=0,ExitOnImpact=0,ni;
334

335
  if (bi<ImpactParameter)
336
  {
337
    do
338
    {
339
      php=phd+(float)HalfLap*PI;
340
      nr=php/h;
341
      ni=(int)nr;
342

343
      if (ni<IdLast[bi])
344
      {
345
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
346
      }
347
      else
348
      {
349
        r=Trajectories[bi*TrackPoints+ni];
350
      }
351
           
352
      if ((r<=re)&&(r>=ri))
353
      {
354
        ExitOnImpact=1;
355
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
356
      }
357
              
358
      HalfLap++;
359
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
360

361
  }
362

363
  barrier(CLK_GLOBAL_MEM_FENCE);
364

365
  zImage[yi+sizex*xi]=zp;
366
  fImage[yi+sizex*xi]=fp;
367
}
368

369
__kernel void Circle(__global float *Trajectories,__global int *IdLast,
370
                     __global float *zImage,__global float *fImage,
371
                     int TrackPoints,
372
                     float Mass,float InternalRadius,
373
                     float ExternalRadius,float Angle,
374
                     float ObserverDistance,
375
                     int BlackBody,int AngularCamera)
376
{
377
   // Integer Impact Parameter ID 
378
   int bi=get_global_id(0);
379
   // Integer points on circle
380
   int i=get_global_id(1);
381
   // Integer Impact Parameter Size (half of image)
382
   int bmaxi=get_global_size(0);
383
   // Integer Points on circle
384
   int imx=get_global_size(1);
385

386
   // Perform trajectory for each pixel
387

388
  float m,rs,ri,re,tho,ro;
389
  int q,dist,raie;
390

391
  m=Mass;
392
  rs=2.*m;
393
  ri=InternalRadius;
394
  re=ExternalRadius;
395
  ro=ObserverDistance;
396
  tho=Angle;
397
  q=-2;
398
  dist=AngularCamera;
399
  raie=BlackBody;
400

401
  float bmx,db,b,h;
402
  float phi,thi,phd;
403
  int nh;
404
  float zp=0,fp=0;
405

406
  // Autosize for image
407
  bmx=1.25*re;
408

409
  // Angular step of integration
410
  h=4.e0f*PI/(float)TrackPoints;
411

412
  // impact parameter
413
  b=(float)bi/(float)bmaxi*bmx;
414
  db=bmx/(float)bmaxi;
415

416
  phi=2.*PI/(float)imx*(float)i;
417
  phd=atanp(cos(phi)*sin(tho),cos(tho));
418
  int yi=(int)((float)bi*sin(phi))+bmaxi;
419
  int xi=(int)((float)bi*cos(phi))+bmaxi;
420

421
  int HalfLap=0,ExitOnImpact=0,ni;
422
  float php,nr,r;
423

424
  do
425
  {
426
     php=phd+(float)HalfLap*PI;
427
     nr=php/h;
428
     ni=(int)nr;
429

430
     if (ni<IdLast[bi])
431
     {
432
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
433
     }
434
     else
435
     {
436
        r=Trajectories[bi*TrackPoints+ni];
437
     }
438
           
439
     if ((r<=re)&&(r>=ri))
440
     {
441
        ExitOnImpact=1;
442
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
443
     }
444
              
445
     HalfLap++;
446
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
447
  
448
  zImage[yi+2*bmaxi*xi]=zp;
449
  fImage[yi+2*bmaxi*xi]=fp;  
450

451
  barrier(CLK_GLOBAL_MEM_FENCE);
452

453
}
454

455
__kernel void Trajectory(__global float *Trajectories,
456
                         __global int *IdLast,int TrackPoints,
457
                         float Mass,float InternalRadius,
458
                         float ExternalRadius,float Angle,
459
                         float ObserverDistance,
460
                         int BlackBody,int AngularCamera)
461
{
462
  // Integer Impact Parameter ID 
463
  int bi=get_global_id(0);
464
  // Integer Impact Parameter Size (half of image)
465
  int bmaxi=get_global_size(0);
466

467
  // Perform trajectory for each pixel
468

469
  float m,rs,ri,re,tho,ro;
470
  int dist,raie,q;
471

472
  m=Mass;
473
  rs=2.*m;
474
  ri=InternalRadius;
475
  re=ExternalRadius;
476
  ro=ObserverDistance;
477
  tho=Angle;
478
  q=-2;
479
  dist=AngularCamera;
480
  raie=BlackBody;
481

482
  float d,bmx,db,b,h;
483
  float phi,thi,phd,php,nr,r;
484
  int nh;
485
  float zp,fp;
486

487
  // Autosize for image
488
  bmx=1.25*re;
489

490
  // Angular step of integration
491
  h=4.e0f*PI/(float)TrackPoints;
492

493
  // impact parameter
494
  b=(float)bi/(float)bmaxi*bmx;
495

496
  float up,vp,pp,us,vs,ps;
497

498
  if (dist==1) 
499
  {
500
     up=0.;
501
     vp=1.;
502
  }
503
  else 
504
  {
505
     thi=asin(b/ro);
506
     up=sin(thi);
507
     vp=cos(thi);
508
  }
509
      
510
  pp=0.;
511
  nh=0;
512

513
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
514
  
515
  // b versus us
516
  float bvus=fabs(b/us);
517
  float bvus0=bvus;
518
  Trajectories[bi*TrackPoints+nh]=bvus;
519

520
  do
521
  {
522
     nh++;
523
     pp=ps;
524
     up=us;
525
     vp=vs;
526
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
527
     bvus=fabs(b/us);
528
     Trajectories[bi*TrackPoints+nh]=bvus;
529

530
  } while ((bvus>=rs)&&(bvus<=bvus0));
531

532
  IdLast[bi]=nh;
533

534
  barrier(CLK_GLOBAL_MEM_FENCE);
535
 
536
}
537
""")
538

    
539
def ImageOutput(sigma,prefix):
540
    Max=sigma.max()
541
    Min=sigma.min()
542
    
543
    # Normalize value as 8bits Integer
544
    SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
545
    image = Image.fromarray(SigmaInt)
546
    image.save("%s.jpg" % prefix)
547
    
548
def BlackHoleCL(zImage,fImage,InputCL):
549

    
550
    kernel_params = {}
551

    
552
    print(InputCL)
553

    
554
    Device=InputCL['Device']
555
    GpuStyle=InputCL['GpuStyle']
556
    VariableType=InputCL['VariableType']
557
    Size=InputCL['Size']
558
    Mass=InputCL['Mass']
559
    InternalRadius=InputCL['InternalRadius']
560
    ExternalRadius=InputCL['ExternalRadius']
561
    Angle=InputCL['Angle']
562
    ObserverDistance=InputCL['ObserverDistance']
563
    Method=InputCL['Method']
564
    TrackPoints=InputCL['TrackPoints']
565

    
566
    if InputCL['BlackBody']:
567
        BlackBody=0
568
    else:
569
        BlackBody=1
570

    
571
    if InputCL['AngularCamera']:
572
        AngularCamera=1
573
    else:
574
        AngularCamera=0
575
        
576
    Trajectories=numpy.zeros((InputCL['Size']/2,InputCL['TrackPoints']),
577
                              dtype=numpy.float32)
578
    IdLast=numpy.zeros(InputCL['Size']/2,dtype=numpy.int32)
579

    
580
    # Je detecte un peripherique GPU dans la liste des peripheriques
581
    Id=0
582
    HasXPU=False
583
    for platform in cl.get_platforms():
584
        for device in platform.get_devices():
585
            if Id==Device:
586
                XPU=device
587
                print "CPU/GPU selected: ",device.name.lstrip()
588
                HasXPU=True
589
            Id+=1
590

    
591
    if HasXPU==False:
592
        print "No XPU #%i found in all of %i devices, sorry..." % (Device,Id-1)
593
        sys.exit()                
594
        
595
    ctx = cl.Context([XPU])
596
    queue = cl.CommandQueue(ctx,
597
                            properties=cl.command_queue_properties.PROFILING_ENABLE)
598

    
599
    BlackHoleCL = cl.Program(ctx,KERNEL_CODE.substitute(kernel_params)).build()
600
    
601
    # Je recupere les flag possibles pour les buffers
602
    mf = cl.mem_flags
603

    
604
    print(zImage)
605
    
606
    TrajectoriesCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=Trajectories)
607
    zImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=zImage)
608
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
609
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
610
    IdLastCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=IdLast)
611
    
612
    start_time=time.time() 
613

    
614
    print(Trajectories.shape)
615
    if Method=='EachPixel':
616
        CLLaunch=BlackHoleCL.EachPixel(queue,(zImage.shape[0],zImage.shape[1]),
617
                                       None,zImageCL,fImageCL,
618
                                       numpy.float32(Mass),
619
                                       numpy.float32(InternalRadius),
620
                                       numpy.float32(ExternalRadius),
621
                                       numpy.float32(Angle),
622
                                       numpy.float32(ObserverDistance),
623
                                       numpy.int32(BlackBody),
624
                                       numpy.int32(AngularCamera))
625
        CLLaunch.wait()
626
    elif Method=='TrajectoCircle':
627
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
628
                                        None,TrajectoriesCL,IdLastCL,
629
                                        numpy.uint32(Trajectories.shape[1]),
630
                                        numpy.float32(Mass),
631
                                        numpy.float32(InternalRadius),
632
                                        numpy.float32(ExternalRadius),
633
                                        numpy.float32(Angle),
634
                                        numpy.float32(ObserverDistance),
635
                                        numpy.int32(BlackBody),
636
                                        numpy.int32(AngularCamera))
637
        
638
        CLLaunch=BlackHoleCL.Circle(queue,(Trajectories.shape[0],
639
                                           zImage.shape[0]*4),None,
640
                                    TrajectoriesCL,IdLastCL,
641
                                    zImageCL,fImageCL,
642
                                    numpy.uint32(Trajectories.shape[1]),
643
                                    numpy.float32(Mass),
644
                                    numpy.float32(InternalRadius),
645
                                    numpy.float32(ExternalRadius),
646
                                    numpy.float32(Angle),
647
                                    numpy.float32(ObserverDistance),
648
                                    numpy.int32(BlackBody),
649
                                    numpy.int32(AngularCamera))
650
        CLLaunch.wait()
651
    else:
652
        CLLaunch=BlackHoleCL.Trajectory(queue,(Trajectories.shape[0],),
653
                                        None,TrajectoriesCL,IdLastCL,
654
                                        numpy.uint32(Trajectories.shape[1]),
655
                                        numpy.float32(Mass),
656
                                        numpy.float32(InternalRadius),
657
                                        numpy.float32(ExternalRadius),
658
                                        numpy.float32(Angle),
659
                                        numpy.float32(ObserverDistance),
660
                                        numpy.int32(BlackBody),
661
                                        numpy.int32(AngularCamera))
662
        
663
        CLLaunch=BlackHoleCL.Pixel(queue,(zImage.shape[0],
664
                                                  zImage.shape[1]),None,
665
                                   zImageCL,fImageCL,TrajectoriesCL,IdLastCL,
666
                                   numpy.uint32(Trajectories.shape[0]),
667
                                   numpy.uint32(Trajectories.shape[1]),
668
                                        numpy.float32(Mass),
669
                                        numpy.float32(InternalRadius),
670
                                        numpy.float32(ExternalRadius),
671
                                        numpy.float32(Angle),
672
                                        numpy.float32(ObserverDistance),
673
                                        numpy.int32(BlackBody),
674
                                        numpy.int32(AngularCamera))
675
        CLLaunch.wait()
676
    
677
    elapsed = time.time()-start_time
678
    print("Elapsed %f: " % elapsed)
679
    
680
    cl.enqueue_copy(queue,zImage,zImageCL).wait()
681
    cl.enqueue_copy(queue,fImage,fImageCL).wait()
682
    cl.enqueue_copy(queue,Trajectories,TrajectoriesCL).wait()
683
    cl.enqueue_copy(queue,IdLast,IdLastCL).wait()
684
    
685
    print(zImage.max())
686
    print(fImage.max())
687
    zImageCL.release()
688
    fImageCL.release()
689

    
690
    TrajectoriesCL.release()
691
    IdLastCL.release()
692

    
693
    return(elapsed)
694

    
695
if __name__=='__main__':
696
        
697
    GpuStyle = 'OpenCL'
698
    Mass = 1.
699
    # Internal Radius 3 times de Schwarzschild Radius
700
    InternalRadius=6.*Mass
701
    #
702
    ExternalRadius=12.
703
    #
704
    ObserverDistance=100.
705
    # Angle with normal to disc 10 degrees
706
    Angle = numpy.pi/180.*(90.-10.)
707
    # Radiation of disc : BlackBody or Monochromatic
708
    BlackBody = True
709
    # Camera : Angular Camera or plate with the size of camera
710
    AngularCamera = True
711
    # Size of image
712
    Size=256
713
    # Variable Type
714
    VariableType='FP32'
715
    # ?
716
    q=-2
717
    # Method of resolution
718
    Method='Trajecto'
719
          
720
    HowToUse='%s -h [Help] -b [BlackBodyEmission] -c [AngularCamera] -s <SizeInPixels> -m <Mass> -i <DiscInternalRadius> -x <DiscExternalRadius> -o <ObservatorDistance> -a <AngleAboveDisc> -d <DeviceId> -g <CUDA/OpenCL> -t <EachPixel/TrajecoCircle/TrajectoPixel> -v <FP32/FP64>'
721

    
722
    try:
723
        opts, args = getopt.getopt(sys.argv[1:],"hbcs:m:i:x:o:a:d:g:v:t:",["blackbody","camera","size=","mass=","internal=","external=","observer=","angle=","device=","gpustyle=","variabletype=","method="])
724
    except getopt.GetoptError:
725
        print(HowToUse % sys.argv[0])
726
        sys.exit(2)
727

    
728
    # List of Devices
729
    Devices=[]
730
    Alu={}
731
        
732
    for opt, arg in opts:
733
        if opt == '-h':
734
            print(HowToUse % sys.argv[0])
735
            
736
            print("\nInformations about devices detected under OpenCL API:")
737
            # For PyOpenCL import
738
            try:
739
                import pyopencl as cl
740
                Id=0
741
                for platform in cl.get_platforms():
742
                    for device in platform.get_devices():
743
                        #deviceType=cl.device_type.to_string(device.type)
744
                        deviceType="xPU"
745
                        print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip(),deviceType,device.name.lstrip()))
746
                        Id=Id+1
747
                        
748
            except:
749
                print("Your platform does not seem to support OpenCL")
750
                
751
            print("\nInformations about devices detected under CUDA API:")
752
                # For PyCUDA import
753
            try:
754
                import pycuda.driver as cuda
755
                cuda.init()
756
                for Id in range(cuda.Device.count()):
757
                    device=cuda.Device(Id)
758
                    print("Device #%i of type GPU : %s" % (Id,device.name()))
759
                print
760
            except:
761
                print("Your platform does not seem to support CUDA")
762
        
763
            sys.exit()
764
        
765
        elif opt in ("-d", "--device"):
766
#            Devices.append(int(arg))
767
            Device=int(arg)
768
        elif opt in ("-g", "--gpustyle"):
769
            GpuStyle = arg
770
        elif opt in ("-v", "--variabletype"):
771
            VariableType = arg
772
        elif opt in ("-s", "--size"):
773
            Size = int(arg)
774
        elif opt in ("-m", "--mass"):
775
            Mass = float(arg)
776
        elif opt in ("-i", "--internal"):
777
            InternalRadius = float(arg)
778
        elif opt in ("-e", "--external"):
779
            ExternalRadius = float(arg)
780
        elif opt in ("-o", "--observer"):
781
            ObserverDistance = float(arg)
782
        elif opt in ("-a", "--angle"):
783
            Angle = numpy.pi/180.*(90.-float(arg))
784
        elif opt in ("-b", "--blackbody"):
785
            BlackBody = True
786
        elif opt in ("-c", "--camera"):
787
            AngularCamera = True
788
        elif opt in ("-t", "--method"):
789
            Method = arg
790

    
791
    print("Device Identification selected : %s" % Device)
792
    print("GpuStyle used : %s" % GpuStyle)
793
    print("VariableType : %s" % VariableType)
794
    print("Size : %i" % Size)
795
    print("Mass : %f" % Mass)
796
    print("Internal Radius : %f" % InternalRadius)
797
    print("External Radius : %f" % ExternalRadius)
798
    print("Observer Distance : %f" % ObserverDistance)
799
    print("Angle with normal of (in radians) : %f" % Angle)
800
    print("Black Body Disc Emission (monochromatic instead) : %s" % BlackBody)
801
    print("Angular Camera (dimension of object instead) : %s" % AngularCamera)
802
    print("Method of resolution : %s" % Method)
803

    
804
    if GpuStyle=='CUDA':
805
        print("\nSelection of CUDA device") 
806
        try:
807
            # For PyCUDA import
808
            import pycuda.driver as cuda
809
            
810
            cuda.init()
811
            for Id in range(cuda.Device.count()):
812
                device=cuda.Device(Id)
813
                print("Device #%i of type GPU : %s" % (Id,device.name()))
814
                if Id in Devices:
815
                    Alu[Id]='GPU'
816
            
817
        except ImportError:
818
            print("Platform does not seem to support CUDA")
819

    
820
    if GpuStyle=='OpenCL':
821
        print("\nSelection of OpenCL device") 
822
        try:
823
            # For PyOpenCL import
824
            import pyopencl as cl
825
            Id=0
826
            for platform in cl.get_platforms():
827
                for device in platform.get_devices():
828
                    #deviceType=cl.device_type.to_string(device.type)
829
                    deviceType="xPU"
830
                    print("Device #%i from %s of type %s : %s" % (Id,platform.vendor.lstrip().rstrip(),deviceType,device.name.lstrip().rstrip()))
831

    
832
                    if Id in Devices:
833
                    # Set the Alu as detected Device Type
834
                        Alu[Id]=deviceType
835
                    Id=Id+1
836
        except ImportError:
837
            print("Platform does not seem to support OpenCL")
838

    
839
#    print(Devices,Alu)
840

    
841
#    MyImage=numpy.where(numpy.random.zeros(Size,Size)>0,1,-1).astype(numpy.float32)
842
    TrackPoints=2048
843
    zImage=numpy.zeros((Size,Size),dtype=numpy.float32)
844
    fImage=numpy.zeros((Size,Size),dtype=numpy.float32)
845

    
846
    InputCL={}
847
    InputCL['Device']=Device
848
    InputCL['GpuStyle']=GpuStyle
849
    InputCL['VariableType']=VariableType
850
    InputCL['Size']=Size
851
    InputCL['Mass']=Mass
852
    InputCL['InternalRadius']=InternalRadius
853
    InputCL['ExternalRadius']=ExternalRadius
854
    InputCL['ObserverDistance']=ObserverDistance
855
    InputCL['Angle']=Angle
856
    InputCL['BlackBody']=BlackBody
857
    InputCL['AngularCamera']=AngularCamera
858
    InputCL['Method']=Method
859
    InputCL['TrackPoints']=TrackPoints
860
    
861
    duration=BlackHoleCL(zImage,fImage,InputCL)
862

    
863
    ImageOutput(zImage,"TrouNoirZ_%s" % Method)
864
    ImageOutput(fImage,"TrouNoirF_%s" % Method)