SIMD Illustration
The multiplication of a 9×9 complex matrix by a complex vector (see the scalar version) is written using SPU intrinsics as follows:
#define _su3_multiply(r,u,s) \
(r).c0.re= (u).c00.re*(s).c0.re-(u).c00.im*(s).c0.im \
+(u).c01.re*(s).c1.re-(u).c01.im*(s).c1.im \
+(u).c02.re*(s).c2.re-(u).c02.im*(s).c2.im; \
(r).c0.im= (u).c00.re*(s).c0.im+(u).c00.im*(s).c0.re \
+(u).c01.re*(s).c1.im+(u).c01.im*(s).c1.re \
+(u).c02.re*(s).c2.im+(u).c02.im*(s).c2.re; \
(r).c1.re= (u).c10.re*(s).c0.re-(u).c10.im*(s).c0.im \
+(u).c11.re*(s).c1.re-(u).c11.im*(s).c1.im \
+(u).c12.re*(s).c2.re-(u).c12.im*(s).c2.im; \
(r).c1.im= (u).c10.re*(s).c0.im+(u).c10.im*(s).c0.re \
+(u).c11.re*(s).c1.im+(u).c11.im*(s).c1.re \
+(u).c12.re*(s).c2.im+(u).c12.im*(s).c2.re; \
(r).c2.re= (u).c20.re*(s).c0.re-(u).c20.im*(s).c0.im \
+(u).c21.re*(s).c1.re-(u).c21.im*(s).c1.im \
+(u).c22.re*(s).c2.re-(u).c22.im*(s).c2.im; \
(r).c2.im= (u).c20.re*(s).c0.im+(u).c20.im*(s).c0.re \
+(u).c21.re*(s).c1.im+(u).c21.im*(s).c1.re \
+(u).c22.re*(s).c2.im+(u).c22.im*(s).c2.re;
#define _SPU_su3_multiply(r,u,s) \
v_r = (vector double *)&(r); \
v_u = (vector double *)&(u); \
v_s = (vector double *)&(s); \
v_a = v_s[0]; \
v_b = v_s[1]; \
v_c = v_s[2]; \
vv_a = spu_rlqwbyte(v_a, 8); \
vv_b = spu_rlqwbyte(v_b, 8); \
vv_c = spu_rlqwbyte(v_c, 8); \
v_a = spu_mul(v_a, v_i); \
v_b = spu_mul(v_b, v_i); \
v_c = spu_mul(v_c, v_i); \
v_d = spu_add(spu_add(spu_mul(v_u[0], v_a), spu_mul(v_u[1], v_b)), spu_mul(v_u[2], v_c)); \
vv_d = spu_add(spu_add(spu_mul(v_u[0], vv_a), spu_mul(v_u[1], vv_b)), spu_mul(v_u[2], vv_c)); \
v_e = (vector double){spu_extract(v_d,0),spu_extract(vv_d,1)}; \
v_f = (vector double){spu_extract(v_d,1),spu_extract(vv_d,0)}; \
v_r[0] = spu_add(v_e, v_f);\
v_d = spu_add(spu_add(spu_mul(v_u[3], v_a), spu_mul(v_u[4], v_b)), spu_mul(v_u[5], v_c)); \
vv_d = spu_add(spu_add(spu_mul(v_u[3], vv_a), spu_mul(v_u[4], vv_b)), spu_mul(v_u[5], vv_c)); \
v_e = (vector double){spu_extract(v_d,0),spu_extract(vv_d,1)}; \
v_f = (vector double){spu_extract(v_d,1),spu_extract(vv_d,0)}; \
v_r[1] = spu_add(v_e, v_f);\
v_d = spu_add(spu_add(spu_mul(v_u[6], v_a), spu_mul(v_u[7], v_b)), spu_mul(v_u[8], v_c)); \
vv_d = spu_add(spu_add(spu_mul(v_u[6], vv_a), spu_mul(v_u[7], vv_b)), spu_mul(v_u[8], vv_c)); \
v_e = (vector double){spu_extract(v_d,0),spu_extract(vv_d,1)}; \
v_f = (vector double){spu_extract(v_d,1),spu_extract(vv_d,0)}; \
v_r[2] = spu_add(v_e, v_f);
|