Statistiques
| Révision :

root / TrouNoir / TrouNoir.py @ 212

Historique | Voir | Annoter | Télécharger (23,66 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
import time,string
30
from numpy.random import randint as nprnd
31
import sys
32
import getopt
33
import matplotlib.pyplot as plt
34
from socket import gethostname
35

    
36
def DictionariesAPI():
37
    PhysicsList={'Einstein':0,'Newton':1}
38
    return(PhysicsList)
39

    
40
BlobOpenCL= """
41

42
#define PI (float)3.14159265359
43
#define nbr 256
44

45
#define EINSTEIN 0
46
#define NEWTON 1
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
#if PHYSICS == NEWTON
68
float g(float u,float m,float b)
69
{
70
  return (-u);
71
}
72
#else
73
float g(float u,float m,float b)
74
{
75
  return (3.e0f*m/b*pow(u,2)-u);
76
}
77
#endif
78

79
void calcul(float *us,float *vs,float up,float vp,
80
            float h,float m,float b)
81
{
82
  float c0,c1,c2,c3,d0,d1,d2,d3;
83

84
  c0=h*f(vp);
85
  c1=h*f(vp+c0/2.);
86
  c2=h*f(vp+c1/2.);
87
  c3=h*f(vp+c2);
88
  d0=h*g(up,m,b);
89
  d1=h*g(up+d0/2.,m,b);
90
  d2=h*g(up+d1/2.,m,b);
91
  d3=h*g(up+d2,m,b);
92

93
  *us=up+(c0+2.*c1+2.*c2+c3)/6.;
94
  *vs=vp+(d0+2.*d1+2.*d2+d3)/6.;
95
}
96

97
void rungekutta(float *ps,float *us,float *vs,
98
                float pp,float up,float vp,
99
                float h,float m,float b)
100
{
101
  calcul(us,vs,up,vp,h,m,b);
102
  *ps=pp+h;
103
}
104

105
float decalage_spectral(float r,float b,float phi,
106
                         float tho,float m)
107
{
108
  return (sqrt(1-3*m/r)/(1+sqrt(m/pow(r,3))*b*sin(tho)*sin(phi)));
109
}
110

111
float spectre(float rf,int q,float b,float db,
112
             float h,float r,float m,float bss)
113
{
114
  float flx;
115

116
  flx=exp(q*log(r/m))*pow(rf,4)*b*db*h;
117
  return(flx);
118
}
119

120
float spectre_cn(float rf32,float b32,float db32,
121
                 float h32,float r32,float m32,float bss32)
122
{
123
  
124
#define MYFLOAT double
125

126
  MYFLOAT rf=(MYFLOAT)(rf32);
127
  MYFLOAT b=(MYFLOAT)(b32);
128
  MYFLOAT db=(MYFLOAT)(db32);
129
  MYFLOAT h=(MYFLOAT)(h32);
130
  MYFLOAT r=(MYFLOAT)(r32);
131
  MYFLOAT m=(MYFLOAT)(m32);
132
  MYFLOAT bss=(MYFLOAT)(bss32);
133

134
  MYFLOAT flx;
135
  MYFLOAT nu_rec,nu_em,qu,temp_em,flux_int;
136
  int fi,posfreq;
137

138
#define planck 6.62e-34
139
#define k 1.38e-23
140
#define c2 9.e16
141
#define temp 3.e7
142
#define m_point 1.
143

144
#define lplanck (log(6.62)-34.*log(10.))
145
#define lk (log(1.38)-23.*log(10.))
146
#define lc2 (log(9.)+16.*log(10.))
147

148
  MYFLOAT v=1.-3./r;
149

150
  qu=1./sqrt((1.-3./r)*r)*(sqrt(r)-sqrt(6.)+sqrt(3.)/2.*log((sqrt(r)+sqrt(3.))/(sqrt(r)-sqrt(3.))* 0.17157287525380988 ));
151

152
  temp_em=temp*sqrt(m)*exp(0.25*log(m_point)-0.75*log(r)-0.125*log(v)+0.25*log(fabs(qu)));
153

154
  flux_int=0.;
155
  flx=0.;
156

157
  for (fi=0;fi<nbr;fi++)
158
    {
159
      nu_em=bss*(MYFLOAT)fi/(MYFLOAT)nbr;
160
      nu_rec=nu_em*rf;
161
      posfreq=(int)(nu_rec*(MYFLOAT)nbr/bss);
162
      if ((posfreq>0)&&(posfreq<nbr))
163
        {
164
          // Initial version
165
          // flux_int=2.*planck/c2*pow(nu_em,3)/(exp(planck*nu_em/(k*temp_em))-1.);
166
          // Version with log used
167
          //flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.);
168
          // flux_int*=pow(rf,3)*b*db*h;
169
          //flux_int*=exp(3.*log(rf))*b*db*h;
170
          flux_int=2.*exp(lplanck-lc2+3.*log(nu_em))/(exp(exp(lplanck-lk+log(nu_em/temp_em)))-1.)*exp(3.*log(rf))*b*db*h;
171

172
          flx+=flux_int;
173
        }
174
    }
175

176
  return((float)(flx));
177
}
178

179
void impact(float phi,float r,float b,float tho,float m,
180
            float *zp,float *fp,
181
            int q,float db,
182
            float h,int raie)
183
{
184
  float flx,rf,bss;
185

186
  rf=decalage_spectral(r,b,phi,tho,m);
187

188
  if (raie==0)
189
    {
190
      bss=1.e19;
191
      flx=spectre_cn(rf,b,db,h,r,m,bss);
192
    }
193
  else
194
    { 
195
      bss=2.;
196
      flx=spectre(rf,q,b,db,h,r,m,bss);
197
    }
198
  
199
  *zp=1./rf;
200
  *fp=flx;
201

202
}
203

204
__kernel void EachPixel(__global float *zImage,__global float *fImage,
205
                        float Mass,float InternalRadius,
206
                        float ExternalRadius,float Angle,
207
                        int Line)
208
{
209
   uint xi=(uint)get_global_id(0);
210
   uint yi=(uint)get_global_id(1);
211
   uint sizex=(uint)get_global_size(0);
212
   uint sizey=(uint)get_global_size(1);
213

214
   // Perform trajectory for each pixel, exit on hit
215

216
  float m,rs,ri,re,tho;
217
  int q,raie;
218

219
  m=Mass;
220
  rs=2.*m;
221
  ri=InternalRadius;
222
  re=ExternalRadius;
223
  tho=Angle;
224
  q=-2;
225
  raie=Line;
226

227
  float d,bmx,db,b,h;
228
  float rp[2048];
229
  float phi,thi,phd,php,nr,r;
230
  int nh;
231
  float zp,fp;
232

233
  // Autosize for image
234
  bmx=1.25*re;
235
  b=0.;
236

237
  h=4.e0f*PI/(float)2048;
238

239
  // set origin as center of image
240
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
241
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
242
  // angle extracted from cylindric symmetry
243
  phi=atanp(x,y);
244
  phd=atanp(cos(phi)*sin(tho),cos(tho));
245

246
  float up,vp,pp,us,vs,ps;
247

248
  // impact parameter
249
  b=sqrt(x*x+y*y)*(float)2.e0f/(float)sizex*bmx;
250
  // step of impact parameter;
251
//  db=bmx/(float)(sizex/2);
252
  db=bmx/(float)(sizex);
253

254
  up=0.;
255
  vp=1.;
256
      
257
  pp=0.;
258
  nh=0;
259

260
  rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);
261
    
262
  rp[nh]=fabs(b/us);
263

264
  int ExitOnImpact=0;
265

266
  do
267
  {
268
     nh++;
269
     pp=ps;
270
     up=us;
271
     vp=vs;
272
     rungekutta(&ps,&us,&vs,pp,up,vp,h,m,b);          
273
     rp[nh]=fabs(b/us);
274
     ExitOnImpact = ((fmod(pp,PI)<fmod(phd,PI))&&(fmod(ps,PI)>fmod(phd,PI)))&&(rp[nh]>ri)&&(rp[nh]<re)?1:0;          
275

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

278
  if (ExitOnImpact==1) {
279
     impact(phi,rp[nh-1],b,tho,m,&zp,&fp,q,db,h,raie);
280
  }
281
  else
282
  {
283
     zp=0.;
284
     fp=0.;
285
  }
286

287
  barrier(CLK_GLOBAL_MEM_FENCE);
288

289
  zImage[yi+sizex*xi]=(float)zp;
290
  fImage[yi+sizex*xi]=(float)fp;  
291
}
292

293
__kernel void Pixel(__global float *zImage,__global float *fImage,
294
                    __global float *Trajectories,__global int *IdLast,
295
                    uint ImpactParameter,uint TrackPoints,
296
                    float Mass,float InternalRadius,
297
                    float ExternalRadius,float Angle,
298
                    int Line)
299
{
300
   uint xi=(uint)get_global_id(0);
301
   uint yi=(uint)get_global_id(1);
302
   uint sizex=(uint)get_global_size(0);
303
   uint sizey=(uint)get_global_size(1);
304

305
   // Perform trajectory for each pixel
306

307
  float m,rs,ri,re,tho;
308
  int q,raie;
309

310
  m=Mass;
311
  rs=2.*m;
312
  ri=InternalRadius;
313
  re=ExternalRadius;
314
  tho=Angle;
315
  q=-2;
316
  raie=Line;
317

318
  float d,bmx,db,b,h;
319
  float phi,thi,phd,php,nr,r;
320
  int nh;
321
  float zp=0,fp=0;
322

323
  // Autosize for image, 25% greater than external radius
324
  bmx=1.25*re;
325

326
  // Angular step of integration
327
  h=4.e0f*PI/(float)TrackPoints;
328

329
  // Step of Impact Parameter
330
  db=bmx/(2.e0*(float)ImpactParameter);
331

332
  // set origin as center of image
333
  float x=(float)xi-(float)(sizex/2)+(float)5e-1f;
334
  float y=(float)yi-(float)(sizey/2)+(float)5e-1f;
335

336
  // angle extracted from cylindric symmetry
337
  phi=atanp(x,y);
338
  phd=atanp(cos(phi)*sin(tho),cos(tho));
339

340
  // Real Impact Parameter
341
  b=sqrt(x*x+y*y)*bmx/(float)ImpactParameter;
342

343
  // Integer Impact Parameter
344
  uint bi=(uint)sqrt(x*x+y*y);
345

346
  int HalfLap=0,ExitOnImpact=0,ni;
347

348
  if (bi<ImpactParameter)
349
  {
350
    do
351
    {
352
      php=phd+(float)HalfLap*PI;
353
      nr=php/h;
354
      ni=(int)nr;
355

356
      if (ni<IdLast[bi])
357
      {
358
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
359
      }
360
      else
361
      {
362
        r=Trajectories[bi*TrackPoints+ni];
363
      }
364
           
365
      if ((r<=re)&&(r>=ri))
366
      {
367
        ExitOnImpact=1;
368
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
369
      }
370
              
371
      HalfLap++;
372
    } while ((HalfLap<=2)&&(ExitOnImpact==0));
373

374
  }
375

376
  barrier(CLK_GLOBAL_MEM_FENCE);
377

378
  zImage[yi+sizex*xi]=zp;
379
  fImage[yi+sizex*xi]=fp;
380
}
381

382
__kernel void Circle(__global float *Trajectories,__global int *IdLast,
383
                     __global float *zImage,__global float *fImage,
384
                     int TrackPoints,
385
                     float Mass,float InternalRadius,
386
                     float ExternalRadius,float Angle,
387
                     int Line)
388
{
389
   // Integer Impact Parameter ID 
390
   int bi=get_global_id(0);
391
   // Integer points on circle
392
   int i=get_global_id(1);
393
   // Integer Impact Parameter Size (half of image)
394
   int bmaxi=get_global_size(0);
395
   // Integer Points on circle
396
   int imx=get_global_size(1);
397

398
   // Perform trajectory for each pixel
399

400
  float m,rs,ri,re,tho;
401
  int q,raie;
402

403
  m=Mass;
404
  rs=2.*m;
405
  ri=InternalRadius;
406
  re=ExternalRadius;
407
  tho=Angle;
408
  raie=Line;
409

410
  float bmx,db,b,h;
411
  float phi,thi,phd;
412
  int nh;
413
  float zp=0,fp=0;
414

415
  // Autosize for image
416
  bmx=1.25*re;
417

418
  // Angular step of integration
419
  h=4.e0f*PI/(float)TrackPoints;
420

421
  // impact parameter
422
  b=(float)bi/(float)bmaxi*bmx;
423
  db=bmx/(2.e0*(float)bmaxi);
424

425
  phi=2.*PI/(float)imx*(float)i;
426
  phd=atanp(cos(phi)*sin(tho),cos(tho));
427
  int yi=(int)((float)bi*sin(phi))+bmaxi;
428
  int xi=(int)((float)bi*cos(phi))+bmaxi;
429

430
  int HalfLap=0,ExitOnImpact=0,ni;
431
  float php,nr,r;
432

433
  do
434
  {
435
     php=phd+(float)HalfLap*PI;
436
     nr=php/h;
437
     ni=(int)nr;
438

439
     if (ni<IdLast[bi])
440
     {
441
        r=(Trajectories[bi*TrackPoints+ni+1]-Trajectories[bi*TrackPoints+ni])*(nr-ni*1.)+Trajectories[bi*TrackPoints+ni];
442
     }
443
     else
444
     {
445
        r=Trajectories[bi*TrackPoints+ni];
446
     }
447
           
448
     if ((r<=re)&&(r>=ri))
449
     {
450
        ExitOnImpact=1;
451
        impact(phi,r,b,tho,m,&zp,&fp,q,db,h,raie);
452
     }
453
              
454
     HalfLap++;
455
  } while ((HalfLap<=2)&&(ExitOnImpact==0));
456
  
457
  zImage[yi+2*bmaxi*xi]=zp;
458
  fImage[yi+2*bmaxi*xi]=fp;  
459

460
  barrier(CLK_GLOBAL_MEM_FENCE);
461

462
}
463

464
__kernel void Trajectory(__global float *Trajectories,
465
                         __global int *IdLast,int TrackPoints,
466
                         float Mass,float InternalRadius,
467
                         float ExternalRadius,float Angle,
468
                         int Line)
469
{
470
  // Integer Impact Parameter ID 
471
  int bi=get_global_id(0);
472
  // Integer Impact Parameter Size (half of image)
473
  int bmaxi=get_global_size(0);
474

475
  // Perform trajectory for each pixel
476

477
  float m,rs,ri,re,tho;
478
  int raie,q;
479

480
  m=Mass;
481
  rs=2.*m;
482
  ri=InternalRadius;
483
  re=ExternalRadius;
484
  tho=Angle;
485
  q=-2;
486
  raie=Line;
487

488
  float d,bmx,db,b,h;
489
  float phi,thi,phd,php,nr,r;
490
  int nh;
491
  float zp,fp;
492

493
  // Autosize for image
494
  bmx=1.25*re;
495

496
  // Angular step of integration
497
  h=4.e0f*PI/(float)TrackPoints;
498

499
  // impact parameter
500
  b=(float)bi/(float)bmaxi*bmx;
501

502
  float up,vp,pp,us,vs,ps;
503

504
  up=0.;
505
  vp=1.;
506
      
507
  pp=0.;
508
  nh=0;
509

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

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

527
  } while ((bvus>=rs)&&(bvus<=bvus0));
528

529
  IdLast[bi]=nh;
530

531
  barrier(CLK_GLOBAL_MEM_FENCE);
532
 
533
}
534
"""
535

    
536
# def ImageOutput(sigma,prefix):
537
#     from PIL import Image
538
#     Max=sigma.max()
539
#     Min=sigma.min()
540
    
541
#     # Normalize value as 8bits Integer
542
#     SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
543
#     image = Image.fromarray(SigmaInt)
544
#     image.save("%s.jpg" % prefix)
545

    
546
def ImageOutput(sigma,prefix,Colors):
547
    import matplotlib.pyplot as plt
548
    if Colors == 'Red2Yellow':
549
        plt.imsave("%s.png" % prefix, sigma, cmap='afmhot')
550
    else:
551
        plt.imsave("%s.png" % prefix, sigma, cmap='Greys_r')
552

    
553
def BlackHoleCL(zImage,fImage,InputCL):
554

    
555
    kernel_params = {}
556

    
557
    print(InputCL)
558

    
559
    Device=InputCL['Device']
560
    GpuStyle=InputCL['GpuStyle']
561
    VariableType=InputCL['VariableType']
562
    Size=InputCL['Size']
563
    Mass=InputCL['Mass']
564
    InternalRadius=InputCL['InternalRadius']
565
    ExternalRadius=InputCL['ExternalRadius']
566
    Angle=InputCL['Angle']
567
    Method=InputCL['Method']
568
    TrackPoints=InputCL['TrackPoints']
569
    Physics=InputCL['Physics']
570

    
571
    PhysicsList=DictionariesAPI()
572
    
573
    if InputCL['BlackBody']:
574
        # Spectrum is Black Body one
575
        Line=0
576
    else:
577
        # Spectrum is Monochromatic Line one
578
        Line=1
579

    
580
    Trajectories=numpy.zeros((InputCL['Size']/2,InputCL['TrackPoints']),
581
                              dtype=numpy.float32)
582
    IdLast=numpy.zeros(InputCL['Size']/2,dtype=numpy.int32)
583

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

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

    
603
    
604
    #    BlackHoleCL = cl.Program(ctx,KERNEL_CODE.substitute(kernel_params)).build()
605

    
606
    BuildOptions="-cl-mad-enable -DPHYSICS=%i " % (PhysicsList[Physics])
607

    
608
    BlackHoleCL = cl.Program(ctx,BlobOpenCL).build(options = BuildOptions)
609
    
610
    # Je recupere les flag possibles pour les buffers
611
    mf = cl.mem_flags
612

    
613
    TrajectoriesCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=Trajectories)
614
    zImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=zImage)
615
    fImageCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=fImage)
616
    IdLastCL = cl.Buffer(ctx, mf.WRITE_ONLY | mf.COPY_HOST_PTR, hostbuf=IdLast)
617
    
618
    start_time=time.time() 
619

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

    
680
    zMaxPosition=numpy.where(zImage[:,:]==zImage.max())
681
    fMaxPosition=numpy.where(fImage[:,:]==fImage.max())
682
    print("Z max @(%i,%i) : %f" % (zMaxPosition[0],zMaxPosition[1],zImage.max()))
683
    print("Flux max @(%i,%i) : %f\n" % (fMaxPosition[0],fMaxPosition[1],fImage.max()))
684
    zImageCL.release()
685
    fImageCL.release()
686

    
687
    TrajectoriesCL.release()
688
    IdLastCL.release()
689

    
690
    return(elapsed)
691

    
692
if __name__=='__main__':
693
        
694
    GpuStyle = 'OpenCL'
695
    Mass = 1.
696
    # Internal Radius 3 times de Schwarzschild Radius
697
    InternalRadius=6.*Mass
698
    #
699
    ExternalRadius=12.
700
    #
701
    # Angle with normal to disc 10 degrees
702
    Angle = numpy.pi/180.*(90.-10.)
703
    # Radiation of disc : BlackBody or Monochromatic
704
    BlackBody = False
705
    # Size of image
706
    Size=256
707
    # Variable Type
708
    VariableType='FP32'
709
    # ?
710
    q=-2
711
    # Method of resolution
712
    Method='TrajectoPixel'
713
    # Colors for output image
714
    Colors='Greyscale'
715
    # Physics
716
    Physics='Einstein'
717
    # No output as image
718
    NoImage = False
719
    
720
    HowToUse='%s -h [Help] -b [BlackBodyEmission] -n [NoImage] -p <Einstein/Newton> -s <SizeInPixels> -m <Mass> -i <DiscInternalRadius> -x <DiscExternalRadius> -a <AngleAboveDisc> -d <DeviceId> -c <Greyscale/Red2Yellow> -g <CUDA/OpenCL> -t <EachPixel/TrajectoCircle/TrajectoPixel> -v <FP32/FP64>'
721

    
722
    try:
723
        opts, args = getopt.getopt(sys.argv[1:],"hbns:m:i:x:a:d:g:v:t:c:p:",["blackbody","noimage","camera","size=","mass=","internal=","external=","angle=","device=","gpustyle=","variabletype=","method=","colors=","physics="])
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 ("-a", "--angle"):
781
            Angle = numpy.pi/180.*(90.-float(arg))
782
        elif opt in ("-b", "--blackbody"):
783
            BlackBody = True
784
        elif opt in ("-n", "--noimage"):
785
            NoImage = True
786
        elif opt in ("-t", "--method"):
787
            Method = arg
788
        elif opt in ("-c", "--colors"):
789
            Colors = arg
790
        elif opt in ("-p", "--physics"):
791
            Physics = arg
792

    
793
    print("Device Identification selected : %s" % Device)
794
    print("GpuStyle used : %s" % GpuStyle)
795
    print("VariableType : %s" % VariableType)
796
    print("Size : %i" % Size)
797
    print("Mass : %f" % Mass)
798
    print("Internal Radius : %f" % InternalRadius)
799
    print("External Radius : %f" % ExternalRadius)
800
    print("Angle with normal of (in radians) : %f" % Angle)
801
    print("Black Body Disc Emission (monochromatic instead) : %s" % BlackBody)
802
    print("Method of resolution : %s" % Method)
803
    print("Colors for output images : %s" % Colors)
804
    print("Physics used for Trajectories : %s" % Physics)
805

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

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

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

    
841
#    print(Devices,Alu)
842

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

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

    
864
    Hostname=gethostname()
865
    Date=time.strftime("%Y%m%d_%H%M%S")
866
    ImageInfo="%s_Device%i_%s_%s" % (Method,Device,Hostname,Date)
867
    
868
    
869
    if not NoImage:
870
        ImageOutput(zImage,"TrouNoirZ_%s" % ImageInfo,Colors)
871
        ImageOutput(fImage,"TrouNoirF_%s" % ImageInfo,Colors)