Statistiques
| Révision :

root / Epidevomath / vector8.py @ 110

Historique | Voir | Annoter | Télécharger (5,21 ko)

1 109 equemene
import numpy as np
2 109 equemene
import pyopencl as cl
3 109 equemene
import pyopencl.array as cl_array
4 109 equemene
from numpy.random import randint as nprnd
5 109 equemene
6 109 equemene
deviceID = 0
7 109 equemene
platformID = 0
8 109 equemene
workGroup=(1,1)
9 109 equemene
10 109 equemene
N = 32768
11 109 equemene
MyData = np.zeros(N, dtype=cl_array.vec.float8)
12 109 equemene
13 109 equemene
dev = cl.get_platforms()[platformID].get_devices()[deviceID]
14 109 equemene
15 109 equemene
ctx = cl.Context([dev])
16 109 equemene
queue = cl.CommandQueue(ctx)
17 109 equemene
mf = cl.mem_flags
18 109 equemene
clData = cl.Buffer(ctx, mf.READ_WRITE, MyData.nbytes)
19 109 equemene
20 109 equemene
MyRoutines = cl.Program(ctx, """
21 109 equemene
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
22 109 equemene
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
23 109 equemene
#define MWC   (znew+wnew)
24 109 equemene
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
25 109 equemene
#define CONG  (jcong=69069*jcong+1234567)
26 109 equemene
#define KISS  ((MWC^CONG)+SHR3)
27 109 equemene

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

33 109 equemene
#define LENGTH 1.
34 109 equemene

35 109 equemene
#define PI 3.14159265359
36 109 equemene

37 109 equemene
#define SMALL_NUM 0.0000001
38 109 equemene

39 109 equemene
__kernel void SplutterSpace(__global float8* clData,
40 109 equemene
                               uint seed_z,uint seed_w)
41 109 equemene
{
42 109 equemene
    int gid = get_global_id(0);
43 109 equemene
    uint z=seed_z+(uint)gid;
44 109 equemene
    uint w=seed_w-(uint)gid;
45 109 equemene

46 109 equemene
    clData[gid].s01234567 = (float8) (MWCfp,MWCfp,MWCfp,0.,0.,0.,0.,0.);
47 109 equemene
}
48 109 equemene

49 109 equemene
__kernel void ExtendSegment(__global float8* clData,
50 109 equemene
                               uint seed_z,uint seed_w)
51 109 equemene
{
52 109 equemene
    int gid = get_global_id(0);
53 109 equemene
    uint z=seed_z+(uint)gid;
54 109 equemene
    uint w=seed_w-(uint)gid;
55 109 equemene

56 109 equemene
    float theta=MWCfp*PI;
57 109 equemene
    float phi=MWCfp*PI*2.;
58 109 equemene
    float sinTheta=sin(theta);
59 109 equemene
    clData[gid].s4=clData[gid].s0+LENGTH*sinTheta*cos(phi);
60 109 equemene
    clData[gid].s5=clData[gid].s1+LENGTH*sinTheta*sin(phi);
61 109 equemene
    clData[gid].s6=clData[gid].s2+LENGTH*cos(theta);
62 109 equemene

63 109 equemene
}
64 109 equemene

65 109 equemene
__kernel void EstimateLength(__global float8* clData,__global float* clSize)
66 109 equemene
{
67 109 equemene
    int gid = get_global_id(0);
68 109 equemene

69 109 equemene
    clSize[gid]=distance(clData[gid].lo,clData[gid].hi);
70 109 equemene
}
71 109 equemene

72 109 equemene
// Get from http://geomalgorithms.com/a07-_distance.html
73 109 equemene

74 109 equemene
__kernel void ShortestDistance(__global float8* clData,__global float* clDistance)
75 109 equemene
{
76 109 equemene
    int gidx = get_global_id(0);
77 109 equemene
    int ggsz = get_global_size(0);
78 109 equemene
    int gidy = get_global_id(1);
79 109 equemene

80 109 equemene
    float4   u = clData[gidx].hi - clData[gidx].lo;
81 109 equemene
    float4   v = clData[gidy].hi - clData[gidy].lo;
82 109 equemene
    float4   w = clData[gidx].lo - clData[gidy].lo;
83 109 equemene

84 109 equemene
    float    a = dot(u,u);         // always >= 0
85 109 equemene
    float    b = dot(u,v);
86 109 equemene
    float    c = dot(v,v);         // always >= 0
87 109 equemene
    float    d = dot(u,w);
88 109 equemene
    float    e = dot(v,w);
89 109 equemene

90 109 equemene
    float    D = a*c - b*b;        // always >= 0
91 109 equemene
    float    sc, sN, sD = D;       // sc = sN / sD, default sD = D >= 0
92 109 equemene
    float    tc, tN, tD = D;       // tc = tN / tD, default tD = D >= 0
93 109 equemene

94 109 equemene
    // compute the line parameters of the two closest points
95 109 equemene
    if (D < SMALL_NUM) { // the lines are almost parallel
96 109 equemene
        sN = 0.0;         // force using point P0 on segment S1
97 109 equemene
        sD = 1.0;         // to prevent possible division by 0.0 later
98 109 equemene
        tN = e;
99 109 equemene
        tD = c;
100 109 equemene
    }
101 109 equemene
    else {                 // get the closest points on the infinite lines
102 109 equemene
        sN = (b*e - c*d);
103 109 equemene
        tN = (a*e - b*d);
104 109 equemene
        if (sN < 0.0) {        // sc < 0 => the s=0 edge is visible
105 109 equemene
            sN = 0.0;
106 109 equemene
            tN = e;
107 109 equemene
            tD = c;
108 109 equemene
        }
109 109 equemene
        else if (sN > sD) {  // sc > 1  => the s=1 edge is visible
110 109 equemene
            sN = sD;
111 109 equemene
            tN = e + b;
112 109 equemene
            tD = c;
113 109 equemene
        }
114 109 equemene
    }
115 109 equemene

116 109 equemene
    if (tN < 0.0) {            // tc < 0 => the t=0 edge is visible
117 109 equemene
        tN = 0.0;
118 109 equemene
        // recompute sc for this edge
119 109 equemene
        if (-d < 0.0)
120 109 equemene
            sN = 0.0;
121 109 equemene
        else if (-d > a)
122 109 equemene
            sN = sD;
123 109 equemene
        else {
124 109 equemene
            sN = -d;
125 109 equemene
            sD = a;
126 109 equemene
        }
127 109 equemene
    }
128 109 equemene
    else if (tN > tD) {      // tc > 1  => the t=1 edge is visible
129 109 equemene
        tN = tD;
130 109 equemene
        // recompute sc for this edge
131 109 equemene
        if ((-d + b) < 0.0)
132 109 equemene
            sN = 0;
133 109 equemene
        else if ((-d + b) > a)
134 109 equemene
            sN = sD;
135 109 equemene
        else {
136 109 equemene
            sN = (-d +  b);
137 109 equemene
            sD = a;
138 109 equemene
        }
139 109 equemene
    }
140 109 equemene
    // finally do the division to get sc and tc
141 109 equemene
    sc = (fabs(sN) < SMALL_NUM ? 0.0 : sN / sD);
142 109 equemene
    tc = (fabs(tN) < SMALL_NUM ? 0.0 : tN / tD);
143 109 equemene

144 109 equemene
    // get the difference of the two closest points
145 109 equemene
    float4   dP = w + (sc * u) - (tc * v);  // =  S1(sc) - S2(tc)
146 109 equemene

147 109 equemene
    clDistance[ggsz*gidy+gidx]=length(dP);   // return the closest distance
148 109 equemene
}
149 109 equemene

150 109 equemene
 """).build()
151 109 equemene
152 109 equemene
print 'Tous au meme endroit',MyData
153 109 equemene
154 109 equemene
MyRoutines.SplutterSpace(queue, (N,1), None, clData, numpy.uint32(nprnd(2**32)),numpy.uint32(nprnd(2**32)))
155 109 equemene
156 109 equemene
cl.enqueue_copy(queue, MyData, clData)
157 109 equemene
158 109 equemene
print 'Tous distribues',MyData
159 109 equemene
160 109 equemene
MyRoutines.ExtendSegment(queue, (N,1), None, clData,numpy.uint32(nprnd(2**32)),numpy.uint32(nprnd(2**32)))
161 109 equemene
162 109 equemene
cl.enqueue_copy(queue, MyData, clData)
163 109 equemene
164 109 equemene
print 'Tous avec leur extremite',MyData
165 109 equemene
166 109 equemene
MySize = np.zeros(len(MyData), dtype=numpy.float32)
167 109 equemene
clSize = cl.Buffer(ctx, mf.READ_WRITE, MySize.nbytes)
168 109 equemene
169 109 equemene
MyRoutines.EstimateLength(queue, (N,1), None, clData, clSize)
170 109 equemene
cl.enqueue_copy(queue, MySize, clSize)
171 109 equemene
172 109 equemene
print 'La distance de chacun avec son extremite',MySize
173 109 equemene
174 109 equemene
MyDistance = np.zeros(len(MyData)*len(MyData), dtype=numpy.float32)
175 109 equemene
clDistance = cl.Buffer(ctx, mf.READ_WRITE, MyDistance.nbytes)
176 109 equemene
177 109 equemene
MyRoutines.ShortestDistance(queue, (N,N), None, clData, clDistance)
178 109 equemene
cl.enqueue_copy(queue, MyDistance, clDistance)
179 109 equemene
180 109 equemene
MyDistance=numpy.reshape(MyDistance,(N,N))
181 109 equemene
182 109 equemene
print 'La distance de chacun',MyDistance