QDP++
qdp_scalarsite_sse_blas_double.h
Go to the documentation of this file.
1// $Id: qdp_scalarsite_sse_blas_double.h,v 1.8 2009-07-14 20:08:42 bjoo Exp $
2
8
9
10#ifndef QDP_SCALARSITE_SSE_BLAS_DOUBLE_H
11#define QDP_SCALARSITE_SSE_BLAS_DOUBLE_H
12
13#include "qdp_dispatch.h"
14
24
25namespace QDP {
26
27 namespace ThreadReductions{
28 extern REAL64* norm2_results;
30
31 }
32
33// Types needed for the expression templates.
34// Bugger Staggered! For Wilson, Ns=4 is nice and cache line
35// aligned on a 64byte line (4 vectors=>12 complex=24 doubles.
36
39
40
42// Threading evaluates
43//
44// by Xu Guo, EPCC, 6 October, 2008
47// the wrappers for the functions to be threaded
48
49#include "qdp_dispatch.h"
51
52
53// #define DEBUG_BLAS
54// TVec is the LatticeFermion from qdp_dwdefs.h with the OLattice<> stripped
55// from around it
57// TScalar is the usual Real, with the OScalar<> stripped from it
58//
59// THis is simply to make the code more readable, and reduces < < s and > >s
60// in the template arguments
61
62// d += Scalar*Vec
63
64template<>
65inline
67 const OpAddAssign& op,
69 Reference< QDPType< DScal, OScalar < DScal > > >,
71 OLattice< DVec > > &rhs,
72 const Subset& s)
73{
74
75#ifdef DEBUG_BLAS
76 QDPIO::cout << "y += a*x" << endl;
77#endif
78
79 const OLattice< DVec >& x = static_cast<const OLattice< DVec > &>(rhs.expression().right());
80 const OScalar< DScal >& a = static_cast<const OScalar< DScal > &> (rhs.expression().left());
81
82 REAL64 ar = a.elem().elem().elem().elem();
83 REAL64* aptr = &ar;
84
85 if( s.hasOrderedRep() ) {
86 REAL64* xptr = (REAL64 *)&(x.elem(s.start()).elem(0).elem(0).real());
87 REAL64* yptr = &(d.elem(s.start()).elem(0).elem(0).real());
88
89 int total_n_4vec = s.end()-s.start()+1;
97
98 //int n_4vec = (s.end()-s.start()+1);
99 //vaxpy4(yptr, aptr, xptr, n_4vec);
101 else {
102 const int* tab = s.siteTable().slice();
103
104 int totalSize = s.numSiteTable();
105
106 unordered_sse_vaxOpy4_double_user_arg arg(x, d, aptr, 1, tab, vaxpy4);
107
109
111 // Original code
113 /*
114 for(int j=0; j < s.numSiteTable(); j++) {
115 int i=tab[j];
116 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
117 REAL64* yptr = &(d.elem(i).elem(0).elem(0).real());
118 vaxpy4(yptr, aptr, xptr, 1);
119 }*/
120 }
123// d -= Scalar*Vec
124template<>
125inline
127 const OpSubtractAssign& op,
129 Reference< QDPType< DScal, OScalar < DScal > > >,
132 const Subset& s)
135#ifdef DEBUG_BLAS
136 QDPIO::cout << "y -= a*x" << endl;
137#endif
138
139 const OLattice< DVec >& x = static_cast<const OLattice< DVec > &>(rhs.expression().right());
140 const OScalar< DScal >& a = static_cast<const OScalar< DScal > &> (rhs.expression().left());
141
142 // - sign as y -= ax <=> y = y-ax = -ax + y = axpy with -a
143 REAL64 ar = -( a.elem().elem().elem().elem());
144 REAL64* aptr = &ar;
145 if( s.hasOrderedRep() ) {
146 REAL64* xptr = (REAL64 *)&(x.elem(s.start()).elem(0).elem(0).real());
147 REAL64* yptr = &(d.elem(s.start()).elem(0).elem(0).real());
148
149 int total_n_4vec = s.end()-s.start()+1;
150
151 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
152
154
156 // Original code
158
159 //int n_4vec = (s.end()-s.start()+1);
160 //vaxpy4(yptr, aptr, xptr, n_4vec);
161 }
162 else {
163 const int* tab = s.siteTable().slice();
164
165 int totalSize = s.numSiteTable();
166
167 unordered_sse_vaxOpy4_double_user_arg arg(x, d, aptr, 1, tab, vaxpy4);
168
170
171 ////////////////
172 // Original code
174 /*
175 for(int j=0; j < s.numSiteTable(); j++) {
176 int i=tab[j];
177 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
178 REAL64* yptr = &(d.elem(i).elem(0).elem(0).real());
179 vaxpy4(yptr, aptr, xptr, 1);
180 }*/
181 }
182
183}
184
185
186// z = ax + y
187template<>
188inline
190 const OpAssign &op,
191 const QDPExpr<
198 const Subset& s)
199{
200
201#ifdef DEBUG_BLAS
202 QDPIO::cout << "z = a*x + y" << endl;
203#endif
205 // Peel the stuff out of the expression
206 // y is the right side of rhs
207 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().right());
209 // ax is the left side of rhs and is in a binary node
210 typedef BinaryNode<OpMultiply,
214 // get the binary node
215 const BN &mulNode = static_cast<const BN&> (rhs.expression().left());
216
217 // get a and x out of the bynary node
218 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.left());
219 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.right());
220 // Set pointers
221 REAL64 ar = a.elem().elem().elem().elem();
222 REAL64 *aptr = (REAL64 *)&ar;
223
224 if( s.hasOrderedRep() ) {
225
226 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
227 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
228 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
229 // int n_4vec = (s.end()-s.start()+1);
230
231 int total_n_4vec = s.end()-s.start()+1;
232
233 if( zptr == yptr ) {
234 // y = ax + y => AXPY
235
236 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
237
241 // Original code
243 //vaxpy4(yptr,aptr,xptr, n_4vec);
244 }
245 else {
246 // z = ax + y => AXPYZ
247 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxpyz4};
250
252 // Original code
254 //vaxpyz4(zptr, aptr, xptr, yptr, n_4vec);
255 }
256 }
257 else {
258 const int* tab = s.siteTable().slice();
259
260 int totalSize = s.numSiteTable();
261
262 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, aptr, 1, tab, vaxpyz4);
263
265
267 // Original code
269 /*
270 for(int j=0; j < s.numSiteTable(); j++) {
271 int i=tab[j];
272 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
273 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
274 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
276 vaxpyz4(zptr, aptr, xptr, yptr, 1);
277 }*/
280
281}
282
283
284// Vec = Vec + Scal*Vec
285template<>
286inline
288 const OpAssign &op,
289 const QDPExpr<
295 OLattice< DVec > > &rhs,
296 const Subset& s)
297{
298#ifdef DEBUG_BLAS
299 QDPIO::cout << "z = y + a*x" << endl;
300#endif
301
302
303 // Peel the stuff out of the expression
304
305 // y is the left side of rhs
306 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().left());
308 // ax is the right side of rhs and is in a binary node
309 typedef BinaryNode<OpMultiply,
312
313 // get the binary node
314 const BN &mulNode = static_cast<const BN&> (rhs.expression().right());
315
316 // get a and x out of the bynary node
317 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.left());
318 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.right());
319 // Set pointers
320 REAL64 ar = a.elem().elem().elem().elem();
321 REAL64 *aptr = (REAL64 *)&ar;
322 if( s.hasOrderedRep() ) {
323 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
324 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
325 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
326
327 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
328 //int n_4vec = (s.end()-s.start()+1);
329
330 int total_n_4vec = s.end()-s.start()+1;
331
332 if( zptr == yptr ) {
333 // y = y + ax
334 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
335
337
339 // Original code
341 //vaxpy4(yptr,aptr,xptr, n_4vec);
342 }
343 else {
344
345
346 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxpyz4};
347
349
351 // Original code
353 //vaxpyz4(zptr, aptr, xptr, yptr, n_4vec);
354 }
357 else {
358 const int* tab = s.siteTable().slice();
359
360 int totalSize = s.numSiteTable();
361
363
365
367 // Original code
369 /*
370
371 for(int j=0; j < s.numSiteTable(); j++) {
372 int i=tab[j];
373 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
374 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
375 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
376 vaxpyz4(zptr, aptr, xptr, yptr, 1);
377 }*/
379
380}
381
382// Vec = Scalar*Vec - Vec
383template<>
384inline
386 const OpAssign &op,
387 const QDPExpr<
393 OLattice< DVec > > &rhs,
394 const Subset& s)
395{
396#ifdef DEBUG_BLAS
397 QDPIO::cout << "z = a*x - y" << endl;
398#endif
399
400
401 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().right());
402
403 // ax is the left side of rhs and is in a binary node
404 typedef BinaryNode<OpMultiply,
407
408 // get the binary node
409 const BN &mulNode = static_cast<const BN&> (rhs.expression().left());
410
411 // get a and x out of the bynary node
412 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.left());
413 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.right());
414 // Set pointers
415 REAL64 ar = a.elem().elem().elem().elem();
416 REAL64 *aptr = (REAL64 *)&ar;
417 if( s.hasOrderedRep() ) {
418 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
419 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
420 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
421
422
423 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
424 //int n_4vec = (s.end()-s.start()+1);
425
426 int total_n_4vec = s.end()-s.start()+1;
427
428 if( zptr == yptr ) {
429
430 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxmy4};
431
433
435 // Original code
437 //vaxmy4(yptr,aptr,xptr, n_4vec);
438 }
439 else {
440
441 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxmyz4};
442
444
446 // Original code
448 // vaxmyz4(zptr, aptr, xptr, yptr, n_4vec);
449 }
450
451 }
452 else {
453 const int* tab = s.siteTable().slice();
454
455 int totalSize = s.numSiteTable();
456
457 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, aptr, 1, tab, vaxmyz4);
458
460
462 // Original code
464 /*
465 for(int j=0; j < s.numSiteTable(); j++) {
466 int i=tab[j];
467 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
468 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
469 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
470 vaxmyz4(zptr, aptr, xptr, yptr, 1);
471 }*/
472 }
473
474}
475
476
477template<>
478inline
480 const OpAssign &op,
481 const QDPExpr<
487 OLattice< DVec > > &rhs,
488 const Subset& s)
489{
490#ifdef DEBUG_BLAS
491 QDPIO::cout << "z = y - a*x" << endl;
492#endif
493
494 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().left());
495
496 // ax is the right side of rhs and is in a binary node
497 typedef BinaryNode<OpMultiply,
500
501 // get the binary node
502 const BN &mulNode = static_cast<const BN&> (rhs.expression().right());
503
504 // get a and x out of the bynary node
505 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.left());
506 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.right());
507 // Set pointers etc.
508
509 // -ve sign as y - ax = -ax + y = axpy with -a.
510 REAL64 ar = -a.elem().elem().elem().elem();
511 REAL64 *aptr = (REAL64 *)&ar;
512 if( s.hasOrderedRep() ) {
513
514 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
515 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
516 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
517
518
519 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
520 //int n_4vec = (s.end()-s.start()+1);
521
522 int total_n_4vec = s.end()-s.start()+1;
523
524 if( zptr == yptr ) {
525
526 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
527
529
531 // Original code
533 //vaxpy4(yptr,aptr,xptr, n_4vec);
534 }
535 else {
536
537 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxpyz4};
538
540
542 // Original code
544 //vaxpyz4(zptr, aptr, xptr, yptr, n_4vec);
545 }
546 }
547 else {
548 const int* tab = s.siteTable().slice();
549
550 int totalSize = s.numSiteTable();
551
552 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, aptr, 1, tab, vaxpyz4);
553
555
557 // Original code
559 /*
560 for(int j=0; j < s.numSiteTable(); j++) {
561 int i=tab[j];
562 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
563 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
564 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
565 vaxpyz4(zptr, aptr, xptr, yptr, 1);
566 }*/
567 }
568
569}
570
571// Vec += Vec * Scalar (AXPY)
572template<>
573inline
575 const OpAddAssign& op,
578 Reference< QDPType< DScal, OScalar < DScal > > > >,
579 OLattice< DVec > > &rhs,
580 const Subset& s)
581{
582
583#ifdef DEBUG_BLAS
584 QDPIO::cout << "y += x*a" << endl;
585#endif
586
587 const OLattice< DVec >& x = static_cast<const OLattice< DVec > &>(rhs.expression().left());
588 const OScalar< DScal >& a = static_cast<const OScalar< DScal > &> (rhs.expression().right());
589
590 REAL64 ar = a.elem().elem().elem().elem();
591 REAL64* aptr = &ar;
592
593 if( s.hasOrderedRep() ) {
594 REAL64* xptr = (REAL64 *)&(x.elem(s.start()).elem(0).elem(0).real());
595 REAL64* yptr = &(d.elem(s.start()).elem(0).elem(0).real());
596 // cout << "Specialised axpy a ="<< ar << endl;
597
598 int total_n_4vec = s.end()-s.start()+1;
599
600 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
601
603
605 // Original code
607 //int n_4vec = (s.end()-s.start()+1);
608 //vaxpy4(yptr, aptr, xptr, n_4vec);
609 }
610 else {
611 const int* tab = s.siteTable().slice();
612
613 int totalSize = s.numSiteTable();
614
615 unordered_sse_vaxOpy4_double_user_arg arg(x, d, aptr, 1, tab, vaxpy4);
616
618
620 // Original code
622 /*
623 for(int j=0; j < s.numSiteTable(); j++) {
624 int i=tab[j];
625 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
626 REAL64* yptr = &(d.elem(i).elem(0).elem(0).real());
627
628 vaxpy4(yptr, aptr, xptr, 1);
629 }*/
630 }
631
632
633}
634
635
636// Vec -= Vec *Scalar
637template<>
638inline
640 const OpSubtractAssign& op,
643 Reference< QDPType< DScal, OScalar < DScal > > > >,
644 OLattice< DVec > > &rhs,
645 const Subset& s)
646{
647
648#ifdef DEBUG_BLAS
649 QDPIO::cout << "y -= x*a" << endl;
650#endif
651
652 const OLattice< DVec >& x = static_cast<const OLattice< DVec > &>(rhs.expression().left());
653 const OScalar< DScal >& a = static_cast<const OScalar< DScal > &> (rhs.expression().right());
654
655 // - sign as y -= ax <=> y = y-ax = -ax + y = axpy with -a
656 REAL64 ar = -( a.elem().elem().elem().elem());
657 REAL64* aptr = &ar;
658
659 if( s.hasOrderedRep() ) {
660 REAL64* xptr = (REAL64 *)&(x.elem(s.start()).elem(0).elem(0).real());
661 REAL64* yptr = &(d.elem(s.start()).elem(0).elem(0).real());
662
663 int total_n_4vec = s.end()-s.start()+1;
664
665 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
666
668
670 // Original code
672 //int n_4vec = (s.end()-s.start()+1);
673 //vaxpy4(yptr, aptr, xptr, n_4vec);
674 }
675 else {
676 const int* tab = s.siteTable().slice();
677
678 int totalSize = s.numSiteTable();
679
680 unordered_sse_vaxOpy4_double_user_arg arg(x, d, aptr, 1, tab, vaxpy4);
681
683
685 // Original code
687 /*
688 for(int j=0; j < s.numSiteTable(); j++) {
689 int i=tab[j];
690 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
691 REAL64* yptr = &(d.elem(i).elem(0).elem(0).real());
692
693 vaxpy4(yptr, aptr, xptr, 1);
694 }*/
695 }
696
697}
698
699
700// Vec = Vec *Scalar + Vec (AXPY)
701template<>
702inline
704 const OpAssign &op,
705 const QDPExpr<
711 OLattice< DVec > > &rhs,
712 const Subset& s)
713{
714
715#ifdef DEBUG_BLAS
716 QDPIO::cout << "z = x*a + y" << endl;
717#endif
718
719 // Peel the stuff out of the expression
720 // y is the right side of rhs
721 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().right());
722
723 // ax is the right side of rhs and is in a binary node
724 typedef BinaryNode<OpMultiply,
727
728 // get the binary node
729 const BN &mulNode = static_cast<const BN&> (rhs.expression().left());
730
731 // get a and x out of the bynary node
732 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.right());
733 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.left());
734 // Set pointers
735 REAL64 ar = a.elem().elem().elem().elem();
736 REAL64 *aptr = (REAL64 *)&ar;
737 if( s.hasOrderedRep() ) {
738
739 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
740 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
741 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
742
743
744 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
745 //int n_4vec = (s.end()-s.start()+1);
746
747 int total_n_4vec = s.end()-s.start()+1;
748
749 if( zptr == yptr ) {
750
751 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
752
754
756 // Original code
758 //vaxpy4(yptr,aptr,xptr, n_4vec);
759 }
760 else {
761
762 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxpyz4};
763
765
767 // Original code
769 //vaxpyz4(zptr, aptr, xptr, yptr, n_4vec);
770 }
771
772 }
773 else {
774 const int* tab = s.siteTable().slice();
775
776 int totalSize = s.numSiteTable();
777
778 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, aptr, 1, tab, vaxpyz4);
779
781
783 // Original code
785 /*
786 for(int j=0; j < s.numSiteTable(); j++) {
787 int i=tab[j];
788
789 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
790 REAL64* yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
791 REAL64* zptr = (REAL64 *) &(d.elem(i).elem(0).elem(0).real());
792 vaxpyz4(zptr, aptr, xptr, yptr, 1);
793 }*/
794 }
795
796}
797
798
799// Vec = Vec + Vec * Scalar (AXPY)
800template<>
801inline
803 const OpAssign &op,
804 const QDPExpr<
810 OLattice< DVec > > &rhs,
811 const Subset& s)
812{
813#ifdef DEBUG_BLAS
814 QDPIO::cout << "z = y + x*a" << endl;
815#endif
816
817
818 // Peel the stuff out of the expression
819
820 // y is the left side of rhs
821 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().left());
822
823 // ax is the right side of rhs and is in a binary node
824 typedef BinaryNode<OpMultiply,
827
828 // get the binary node
829 const BN &mulNode = static_cast<const BN&> (rhs.expression().right());
830
831 // get a and x out of the bynary node
832 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.right());
833 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.left());
834 // Set pointers
835 REAL64 ar = a.elem().elem().elem().elem();
836 REAL64 *aptr = (REAL64 *)&ar;
837
838 if( s.hasOrderedRep() ) {
839 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
840 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
841 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
842
843 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
844 //int n_4vec = (s.end()-s.start()+1);
845
846 int total_n_4vec = s.end()-s.start()+1;
847
848 if( zptr == yptr ) {
849
850 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
851
853
855 // Original code
857 //vaxpy4(yptr,aptr,xptr, n_4vec);
858 }
859 else {
860 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxpyz4};
861
863
865 // Original code
867 //vaxpyz4(zptr, aptr, xptr, yptr, n_4vec);
868 }
869
870
871 }
872 else {
873 const int* tab = s.siteTable().slice();
874
875 int totalSize = s.numSiteTable();
876
877 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, aptr, 1, tab, vaxpyz4);
878
880
882 // Original code
884 /*
885 for(int j=0; j < s.numSiteTable(); j++) {
886 int i=tab[j];
887
888 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
889 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
890 REAL64* zptr = (REAL64 *)&(d.elem(i).elem(0).elem(0).real());
891 vaxpyz4(zptr, aptr, xptr, yptr, 1);
892 }*/
893 }
894
895}
896
897
898// Vec = Vec*Scalar - Vec (AXMY)
899template<>
900inline
902 const OpAssign &op,
903 const QDPExpr<
909 OLattice< DVec > > &rhs,
910 const Subset& s)
911{
912#ifdef DEBUG_BLAS
913 QDPIO::cout << "z = x*a - y" << endl;
914#endif
915
916 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().right());
917
918
919 typedef BinaryNode<OpMultiply,
922
923 // get the binary node
924 const BN &mulNode = static_cast<const BN&> (rhs.expression().left());
925
926 // get a and x out of the bynary node
927 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.right());
928 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.left());
929 // Set pointers
930 REAL64 ar = a.elem().elem().elem().elem();
931 REAL64 *aptr = (REAL64 *)&ar;
932
933 if( s.hasOrderedRep() ) {
934 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
935 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
936 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
937
938
939 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
940 //int n_4vec = (s.end()-s.start()+1);
941
942 int total_n_4vec = s.end()-s.start()+1;
943
944 if( zptr == yptr ) {
945
946 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxmy4};
947
949
951 // Original code
953 //vaxmy4(yptr,aptr,xptr, n_4vec);
954 }
955 else {
956
957 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxmyz4};
958
960
962 // Original code
964 //vaxmyz4(zptr, aptr, xptr, yptr, n_4vec);
965 }
966
967
968 }
969 else {
970 const int* tab = s.siteTable().slice();
971
972 int totalSize = s.numSiteTable();
973
974 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, aptr, 1, tab, vaxmyz4);
975
977
979 // Original code
981 /*
982 for(int j=0; j < s.numSiteTable(); j++) {
983 int i=tab[j];
984
985 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
986 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
987 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
988 vaxmyz4(zptr, aptr, xptr, yptr, 1);
989 }*/
990 }
991
992}
993
994
995// Vec = Vec - Vec*Scalar (AXPY with -Scalar)
996template<>
997inline
999 const OpAssign &op,
1000 const QDPExpr<
1006 OLattice< DVec > > &rhs,
1007 const Subset& s)
1008{
1009#ifdef DEBUG_BLAS
1010 QDPIO::cout << "z = y - x*a" << endl;
1011#endif
1012
1013 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&> (rhs.expression().left());
1014
1015 typedef BinaryNode<OpMultiply,
1018
1019 // get the binary node
1020 const BN &mulNode = static_cast<const BN&> (rhs.expression().right());
1021
1022 // get a and x out of the bynary node
1023 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode.right());
1024 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode.left());
1025 // Set pointers etc.
1026
1027 // -ve sign as y - ax = -ax + y = axpy with -a.
1028 REAL64 ar = -a.elem().elem().elem().elem();
1029 REAL64 *aptr = (REAL64 *)&ar;
1030
1031 if( s.hasOrderedRep() ) {
1032
1033 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1034 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
1035 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1036
1037
1038 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1039 //int n_4vec = (s.end()-s.start()+1);
1040
1041 int total_n_4vec = s.end()-s.start()+1;
1042
1043 if( zptr == yptr ) {
1044
1045 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, aptr, xptr, vaxpy4};
1046
1048
1050 // Original code
1052 //vaxpy4(yptr,aptr,xptr, n_4vec);
1053 }
1054 else {
1055
1056 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, aptr, xptr, yptr, vaxpyz4};
1057
1059
1061 // Original code
1063 //vaxpyz4(zptr, aptr, xptr, yptr, n_4vec);
1064 }
1065
1066 }
1067 else {
1068 const int* tab = s.siteTable().slice();
1069
1070 int totalSize = s.numSiteTable();
1071
1072 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, aptr, 1, tab, vaxpyz4);
1073
1075
1077 // Original code
1079 /*
1080 for(int j=0; j < s.numSiteTable(); j++) {
1081 int i=tab[j];
1082
1083 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
1084 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
1085 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
1086 vaxpyz4(zptr, aptr, xptr, yptr, 1);
1087 }*/
1088 }
1089
1090}
1091
1092
1093template<>
1094inline
1096 const OpAssign &op,
1097 const QDPExpr<
1101 OLattice< DVec > > &rhs,
1102 const Subset& s)
1103{
1104#ifdef DEBUG_BLAS
1105 cout << "BJ: v+v " << endl;
1106#endif
1107
1108 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(rhs.expression().left());
1109 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(rhs.expression().right());
1110
1111 REAL64 one = 1;
1112
1113 if( s.hasOrderedRep() ) {
1114 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1115 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
1116 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1117
1118
1119 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1120 //int n_4vec = (s.end()-s.start()+1);
1121
1122 int total_n_4vec = s.end()-s.start()+1;
1123
1124 if( zptr == yptr ) {
1125
1126 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, &one, xptr, vaxpy4};
1127
1129
1131 // Original code
1133 //vaxpy4(yptr,&one,xptr, n_4vec);
1134 }
1135 else {
1136
1137 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, &one, xptr, yptr, vaxpyz4};
1138
1140
1142 // Original code
1144 //vaxpyz4(zptr, &one, xptr, yptr, n_4vec);
1145 }
1146
1147 }
1148 else {
1149 const int* tab = s.siteTable().slice();
1150
1151 int totalSize = s.numSiteTable();
1152
1153 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, &one, 1, tab, vaxpyz4);
1154
1156
1158 // Original code
1160 /*
1161 for(int j=0; j < s.numSiteTable(); j++) {
1162 int i=tab[j];
1163
1164 REAL64* xptr = (REAL64 *)&(x.elem(i).elem(0).elem(0).real());
1165 REAL64* yptr = (REAL64 *)&(y.elem(i).elem(0).elem(0).real());
1166 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
1167 vaxpyz4(zptr,&one, xptr, yptr, 1);
1168 }*/
1169 }
1170
1171
1172}
1173
1174template<>
1175inline
1177 const OpAssign &op,
1178 const QDPExpr<
1182 OLattice< DVec > > &rhs,
1183 const Subset& s)
1184{
1185#ifdef DEBUG_BLAS
1186 cout << "BJ: v-v " << endl;
1187#endif
1188
1189 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(rhs.expression().left());
1190 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(rhs.expression().right());
1191 REAL64 one=1;
1192
1193 if( s.hasOrderedRep() ) {
1194
1195 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1196 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
1197 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1198
1199 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1200 //int n_4vec = (s.end()-s.start()+1);
1201
1202 int total_n_4vec = s.end()-s.start()+1;
1203
1204 if( zptr == yptr ) {
1205
1206 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, &one, xptr, vaxmy4};
1207
1209
1211 // Original code
1213 //vaxmy4(yptr,&one,xptr, n_4vec);
1214 }
1215 else {
1216
1217 ordered_sse_vaxOpyz4_double_user_arg arg = {zptr, &one, xptr, yptr, vaxmyz4};
1218
1220
1222 // Original code
1224 //vaxmyz4(zptr, &one, xptr, yptr, n_4vec);
1225 }
1226
1227 }
1228 else {
1229 const int* tab = s.siteTable().slice();
1230
1231 int totalSize = s.numSiteTable();
1232
1233 unordered_sse_vaxOpyz4_double_user_arg arg(x, y, d, &one, 1, tab, vaxmyz4);
1234
1236
1238 // Original code
1240 /*
1241 for(int j=0; j < s.numSiteTable(); j++) {
1242 int i=tab[j];
1243 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
1244 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
1245 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
1246
1247 vaxmyz4(zptr,&one, xptr, yptr, 1);
1248
1249 }*/
1250 }
1251
1252}
1253
1254
1255// Vec = Scal * Vec
1256template<>
1257inline
1259 const OpAssign &op,
1260 const QDPExpr<
1264 OLattice< DVec > > &rhs,
1265 const Subset& s)
1266{
1267#ifdef DEBUG_BLAS
1268 cout << "BJ: v = a*v " << endl;
1269#endif
1270 const OLattice< DVec > &x = static_cast<const OLattice< DVec >&>(rhs.expression().right());
1271 const OScalar< DScal > &a = static_cast<const OScalar< DScal >&>(rhs.expression().left());
1272
1273 REAL64 ar = a.elem().elem().elem().elem();
1274 REAL64 *aptr = &ar;
1275
1276 if( s.hasOrderedRep() ) {
1277
1278 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1279 REAL64 *zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1280
1281 /*int total_n_4vec = s.end()-s.start()+1;
1282
1283 ordered_sse_vscal4_double_user_arg arg = {zptr,aptr,xptr};
1284
1285 dispatch_to_threads(total_n_4vec, arg, ordered_sse_vscal4_double_evaluate_function);
1286 */
1288 // Original code
1290 int n_4vec = (s.end()-s.start()+1);
1291 vscal4(zptr, aptr, xptr, n_4vec);
1292 }
1293 else {
1294 const int* tab = s.siteTable().slice();
1295 /*
1296 int totalSize = s.numSiteTable();
1297
1298 unordered_sse_vscal4_double_user_arg arg = {x, d, aptr, 1, tab};
1299
1300 dispatch_to_threads(totalSize, arg, unordered_sse_vscal4_double_evaluate_function);
1301 */
1303 // Original code
1305
1306 for(int j=0; j < s.numSiteTable(); j++) {
1307 int i=tab[j];
1308 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
1309 REAL64 *zptr = &(d.elem(i).elem(0).elem(0).real());
1310
1311
1312 vscal4(zptr, aptr, xptr, 1);
1313 }
1314 }
1315
1316}
1317
1318
1319template<>
1320inline
1322 const OpAssign &op,
1323 const QDPExpr<
1327 OLattice< DVec > > &rhs,
1328 const Subset& s)
1329{
1330#ifdef DEBUG_BLAS
1331 cout << "BJ: v = v*a " << endl;
1332#endif
1333
1334 const OLattice< DVec > &x = static_cast<const OLattice< DVec >&>(rhs.expression().left());
1335 const OScalar< DScal > &a = static_cast<const OScalar< DScal >&>(rhs.expression().right());
1336
1337 REAL64 ar = a.elem().elem().elem().elem();
1338 REAL64 *aptr = &ar;
1339
1340 if( s.hasOrderedRep() ) {
1341 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1342 REAL64 *zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1343
1344 int total_n_4vec = s.end()-s.start()+1;
1345
1346 ordered_sse_vscal4_double_user_arg arg = {zptr,aptr,xptr};
1347
1349
1351 // Original code
1353 //int n_4vec = (s.end()-s.start()+1);
1354 //vscal4(zptr, aptr, xptr, n_4vec);
1355 }
1356 else {
1357 const int* tab = s.siteTable().slice();
1358
1359 int totalSize = s.numSiteTable();
1360
1361 unordered_sse_vscal4_double_user_arg arg(x, d, aptr, 1, tab);
1362
1364
1366 // Original code
1368 /* for(int j=0; j < s.numSiteTable(); j++) {
1369 int i=tab[j];
1370 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
1371 REAL64 *zptr = &(d.elem(i).elem(0).elem(0).real());
1372
1373 vscal4(zptr, aptr, xptr, 1);
1374 }*/
1375 }
1376}
1377
1378
1379// v *= a
1380template<>
1381inline
1383 const OpMultiplyAssign &op,
1384 const QDPExpr<
1387 OScalar< DScal > > &rhs,
1388 const Subset& s)
1389{
1390 const OScalar< DScal >& a = static_cast< const OScalar<DScal >&>(rhs.expression().child());
1391
1392
1393#ifdef DEBUG_BLAS
1394 QDPIO::cout << "BJ: v *= a, a = " << a << endl;
1395#endif
1396
1397 REAL64 ar = a.elem().elem().elem().elem();
1398 if( s.hasOrderedRep() ) {
1399
1400 REAL64* xptr = &(d.elem(s.start()).elem(0).elem(0).real());
1401 REAL64* zptr = xptr;
1402
1403 int total_n_4vec = s.end()-s.start()+1;
1404
1405 ordered_sse_vscal4_double_user_arg arg = {zptr, &ar, xptr};
1406
1408
1410 // Original code
1412 //int n_4vec = (s.end()-s.start()+1);
1413 //vscal4(zptr,&ar, xptr, n_4vec);
1414 }
1415 else {
1416 const int* tab = s.siteTable().slice();
1417
1418 int totalSize = s.numSiteTable();
1419
1420 unordered_sse_vscal4_double_user_arg arg(d, d, &ar, 1, tab);
1421
1423
1425 // Original code
1427 /*
1428 for(int j=0; j < s.numSiteTable(); j++) {
1429 int i=tab[j];
1430
1431 REAL64* xptr = &(d.elem(i).elem(0).elem(0).real());
1432 REAL64* zptr = xptr;
1433
1434 vscal4(zptr,&ar, xptr, 1);
1435 }*/
1436 }
1437}
1438
1439// v /= a
1440template<>
1441inline
1443 const OpDivideAssign &op,
1444 const QDPExpr<
1447 OScalar< DScal > > &rhs,
1448 const Subset& s)
1449{
1450 const OScalar< DScal >& a = static_cast< const OScalar<DScal >&>(rhs.expression().child());
1451
1452
1453#ifdef DEBUG_BLAS
1454 QDPIO::cout << "BJ: v /= a, a = " << a << endl;
1455#endif
1456
1457 REAL64 ar = (REAL64)1/a.elem().elem().elem().elem();
1458 if( s.hasOrderedRep() ) {
1459 REAL64* xptr = &(d.elem(s.start()).elem(0).elem(0).real());
1460 REAL64* zptr = xptr;
1461
1462 int total_n_4vec = s.end()-s.start()+1;
1463
1464 ordered_sse_vscal4_double_user_arg arg = {zptr, &ar, xptr};
1465
1467
1469 // Original code
1471 //int n_4vec = (s.end()-s.start()+1);
1472 //vscal4(zptr,&ar, xptr, n_4vec);
1473 }
1474 else {
1475 const int* tab = s.siteTable().slice();
1476
1477 int totalSize = s.numSiteTable();
1478
1479 unordered_sse_vscal4_double_user_arg arg(d, d, &ar, 1, tab);
1480
1482
1484 // Original code
1486 /*
1487 for(int j=0; j < s.numSiteTable(); j++) {
1488 int i=tab[j];
1489
1490 REAL64* xptr = &(d.elem(i).elem(0).elem(0).real());
1491 REAL64* zptr = xptr;
1492
1493 vscal4(zptr,&ar, xptr, 1);
1494 }*/
1495 }
1496}
1497
1498
1499// v += v
1500template<>
1501inline
1503 const OpAddAssign &op,
1504 const QDPExpr<
1507 OLattice< DVec > > &rhs,
1508 const Subset& s)
1509{
1510 const OLattice< DVec >& x = static_cast< const OLattice<DVec >&>(rhs.expression().child());
1511
1512
1513
1514#ifdef DEBUG_BLAS
1515 QDPIO::cout << "BJ: v += v" << endl;
1516#endif
1517 REAL64 one = 1;
1518
1519 if( s.hasOrderedRep() ) {
1520
1521
1522 REAL64 *xptr = (REAL64 *)(&x.elem(s.start()).elem(0).elem(0).real());
1523 REAL64 *yptr = (REAL64 *)(&d.elem(s.start()).elem(0).elem(0).real());
1524
1525 int total_n_4vec = s.end()-s.start()+1;
1526
1527 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, &one, xptr, vaxpy4};
1528
1530
1532 // Original code
1534 //int n_4vec = (s.end() - s.start()+1);
1535 //vaxpy4(yptr, &one, xptr,n_4vec);
1536 }
1537 else {
1538 const int* tab = s.siteTable().slice();
1539
1540 int totalSize = s.numSiteTable();
1541
1542 unordered_sse_vaxOpy4_double_user_arg arg(x, d, &one, 1, tab, vaxpy4);
1543
1545
1547 // Original code
1549 /*
1550 for(int j=0; j < s.numSiteTable(); j++) {
1551 int i=tab[j];
1552
1553 REAL64 *xptr = (REAL64 *)(&x.elem(i).elem(0).elem(0).real());
1554 REAL64 *yptr = (REAL64 *)(&d.elem(i).elem(0).elem(0).real());
1555
1556 vaxpy4(yptr, &one, xptr,1);
1557
1558 }*/
1559 }
1560
1561}
1562
1563
1564// v -= v
1565template<>
1566inline
1568 const OpSubtractAssign &op,
1569 const QDPExpr<
1572 OLattice< DVec > > &rhs,
1573 const Subset& s)
1574{
1575 const OLattice< DVec >& x = static_cast< const OLattice<DVec >&>(rhs.expression().child());
1576
1577
1578
1579#ifdef DEBUG_BLAS
1580 QDPIO::cout << "BJ: v -= v" << endl;
1581#endif
1582 REAL64 mone = (REAL64)-1;
1583
1584 if( s.hasOrderedRep() ) {
1585
1586 REAL64 *xptr = (REAL64 *)(&x.elem(s.start()).elem(0).elem(0).real());
1587 REAL64 *yptr = (REAL64 *)(&d.elem(s.start()).elem(0).elem(0).real());
1588
1589 int total_n_4vec = s.end()-s.start()+1;
1590
1591 ordered_sse_vaxOpy4_double_user_arg arg = {yptr, &mone, xptr, vaxpy4};
1592
1594
1596 // Original code
1598 //int n_4vec = (s.end() - s.start()+1);
1599 //vaxpy4(yptr, &mone, xptr, n_4vec);
1600 }
1601 else {
1602 const int* tab = s.siteTable().slice();
1603
1604 int totalSize = s.numSiteTable();
1605
1606 unordered_sse_vaxOpy4_double_user_arg arg(x, d, &mone, 1, tab, vaxpy4);
1607
1609
1611 // Original code
1613 /*
1614 for(int j=0; j < s.numSiteTable(); j++) {
1615 int i=tab[j];
1616 REAL64 *xptr = (REAL64 *)(&x.elem(i).elem(0).elem(0).real());
1617 REAL64 *yptr = (REAL64 *)(&d.elem(i).elem(0).elem(0).real());
1618
1619 vaxpy4(yptr, &mone, xptr, 1);
1620
1621 }*/
1622 }
1623
1624}
1625
1626
1627// z = ax + by
1628template<>
1629inline
1631 const OpAssign &op,
1632 const QDPExpr<
1640 OLattice< DVec > > &rhs,
1641 const Subset& s)
1642{
1643
1644#ifdef DEBUG_BLAS
1645 QDPIO::cout << "z = a*x + b*y" << endl;
1646#endif
1647
1648 // Peel the stuff out of the expression
1649 // y is the right side of rhs
1650
1651 // ax is the left side of rhs and is in a binary node
1652 typedef BinaryNode<OpMultiply,
1655
1656 // get the binary node
1657 const BN &mulNode1 = static_cast<const BN&> (rhs.expression().left());
1658 const BN &mulNode2 = static_cast<const BN&> (rhs.expression().right());
1659
1660 // get a and x out of the binary node
1661 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.left());
1662 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.right());
1663
1664 // get b and y out of the binary node
1665 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.left());
1666 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.right());
1667
1668
1669 // Set pointers
1670 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
1671 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
1672
1673 if( s.hasOrderedRep() ) {
1674 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1675 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
1676 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1677
1678 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1679 //int n_4vec = (s.end()-s.start()+1);
1680
1681 int total_n_4vec = s.end()-s.start()+1;
1682
1683 if( zptr == yptr ) {
1684
1685 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr,bptr, vaxpby4};
1686
1688
1690 // Original code
1692 //vaxpby4(yptr, aptr, xptr, bptr, n_4vec);
1693 }
1694 else {
1695
1696 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxpbyz4};
1697
1699
1701 // Original code
1703 //vaxpbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
1704 }
1705
1706
1707
1708 }
1709 else {
1710 const int* tab = s.siteTable().slice();
1711
1712 int totalSize = s.numSiteTable();
1713
1714 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxpbyz4);
1715
1717
1719 // Original code
1721 /*
1722 for(int j=0; j < s.numSiteTable(); j++) {
1723 int i=tab[j];
1724 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
1725 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
1726 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
1727
1728 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1729 vaxpbyz4(zptr, aptr, xptr, bptr, yptr, 1);
1730
1731 }*/
1732 }
1733
1734}
1735
1736
1737// z = xa + by
1738template<>
1739inline
1741 const OpAssign &op,
1742 const QDPExpr<
1750 OLattice< DVec > > &rhs,
1751 const Subset& s)
1752{
1753
1754#ifdef DEBUG_BLAS
1755 QDPIO::cout << "z = x*a + b*y" << endl;
1756#endif
1757
1758 // Peel the stuff out of the expression
1759 // y is the right side of rhs
1760
1761 // ax is the left side of rhs and is in a binary node
1762 typedef BinaryNode<OpMultiply,
1765
1766 typedef BinaryNode<OpMultiply,
1769
1770
1771
1772 // get the binary node
1773 const BN1 &mulNode1 = static_cast<const BN1&> (rhs.expression().left());
1774 const BN2 &mulNode2 = static_cast<const BN2&> (rhs.expression().right());
1775
1776 // get a and x out of the binary node
1777 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.left());
1778
1779 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.right());
1780
1781 // get b and y out of the binary node
1782 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.left());
1783 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.right());
1784
1785
1786 // Set pointers
1787 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
1788 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
1789
1790 if( s.hasOrderedRep() ) {
1791 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1792 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
1793 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1794
1795
1796 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1797 //int n_4vec = (s.end()-s.start()+1);
1798
1799 int total_n_4vec = s.end()-s.start()+1;
1800
1801 if( zptr == yptr ) {
1802
1803 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr,bptr, vaxpby4};
1804
1806
1808 // Original code
1810 //vaxpby4(yptr, aptr, xptr, bptr, n_4vec);
1811 }
1812 else {
1813 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxpbyz4};
1814
1816
1818 // Original code
1820 //vaxpbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
1821 }
1822
1823
1824 }
1825 else {
1826 const int* tab = s.siteTable().slice();
1827
1828 int totalSize = s.numSiteTable();
1829
1830 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxpbyz4);
1831
1833
1835 // Original code
1837 /*
1838 for(int j=0; j < s.numSiteTable(); j++) {
1839 int i=tab[j];
1840
1841 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
1842 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
1843 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
1844
1845 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1846 vaxpbyz4(zptr, aptr, xptr, bptr, yptr, 1);
1847
1848 }*/
1849 }
1850}
1851
1852// z = ax + yb
1853template<>
1854inline
1856 const OpAssign &op,
1857 const QDPExpr<
1865 OLattice< DVec > > &rhs,
1866 const Subset& s)
1867{
1868
1869#ifdef DEBUG_BLAS
1870 QDPIO::cout << "z = a*x + y*b" << endl;
1871#endif
1872
1873 // Peel the stuff out of the expression
1874 // y is the right side of rhs
1875
1876 // type of a*x
1877 typedef BinaryNode<OpMultiply,
1880
1881 // type of y*b
1882 typedef BinaryNode<OpMultiply,
1885
1886
1887
1888 // get the binary nodes
1889 // a*x node
1890 const BN1 &mulNode1 = static_cast<const BN1&> (rhs.expression().left());
1891
1892 // y*b node
1893 const BN2 &mulNode2 = static_cast<const BN2&> (rhs.expression().right());
1894
1895 // get a and x out of the binary node
1896 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.left());
1897
1898 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.right());
1899
1900
1901 // get b and y out of the binary node
1902 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.left());
1903
1904 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.right());
1905
1906
1907 // Set pointers
1908 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
1909 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
1910
1911 if( s.hasOrderedRep() ) {
1912 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
1913 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
1914 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
1915
1916
1917 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1918 //int n_4vec = (s.end()-s.start()+1);
1919
1920 int total_n_4vec = s.end()-s.start()+1;
1921
1922 if( zptr == yptr ) {
1923
1924 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr, bptr, vaxpby4};
1925
1927
1929 // Original code
1931 //vaxpby4(yptr, aptr, xptr, bptr, n_4vec);
1932 }
1933 else {
1934 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxpbyz4};
1935
1937
1939 // Original code
1941 //vaxpbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
1942 }
1943
1944
1945 }
1946 else {
1947 const int* tab = s.siteTable().slice();
1948
1949 int totalSize = s.numSiteTable();
1950
1951 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxpbyz4);
1952
1954
1956 // Original code
1958 /*
1959
1960 for(int j=0; j < s.numSiteTable(); j++) {
1961 int i=tab[j];
1962
1963 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
1964 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
1965 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
1966
1967 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
1968
1969 vaxpbyz4(zptr, aptr, xptr, bptr, yptr, 1);
1970
1971 }
1972 */
1973
1974 }
1975}
1976
1977// z = xa + yb
1978template<>
1979inline
1981 const OpAssign &op,
1982 const QDPExpr<
1990 OLattice< DVec > > &rhs,
1991 const Subset& s)
1992{
1993
1994#ifdef DEBUG_BLAS
1995 QDPIO::cout << "z = x*a + y*b" << endl;
1996#endif
1997
1998 // Peel the stuff out of the expression
1999 // y is the right side of rhs
2000
2001 // ax is the left side of rhs and is in a binary node
2002 typedef BinaryNode<OpMultiply,
2005
2006 // get the binary node
2007 const BN &mulNode1 = static_cast<const BN&> (rhs.expression().left());
2008 const BN &mulNode2 = static_cast<const BN&> (rhs.expression().right());
2009
2010 // get a and x out of the binary node
2011 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.left());
2012 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.right());
2013
2014 // get b and y out of the binary node
2015 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.left());
2016
2017 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.right());
2018
2019 // Set pointers
2020 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
2021 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
2022
2023 if( s.hasOrderedRep() ) {
2024 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
2025 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
2026 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
2027
2028
2029 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2030 //int n_4vec = (s.end()-s.start()+1);
2031 int total_n_4vec = s.end()-s.start()+1;
2032
2033 if( zptr == yptr ) {
2034
2035 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr, bptr, vaxpby4};
2036
2038
2040 // Original code
2042 //vaxpby4(yptr, aptr, xptr, bptr, n_4vec);
2043 }
2044 else {
2045 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxpbyz4};
2046
2048
2050 // Original code
2052 //vaxpbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
2053 }
2054
2055
2056 }
2057 else {
2058 const int* tab = s.siteTable().slice();
2059
2060 int totalSize = s.numSiteTable();
2061
2062 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxpbyz4);
2063
2065
2067 // Original code
2069 /*
2070 for(int j=0; j < s.numSiteTable(); j++) {
2071 int i=tab[j];
2072
2073 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
2074 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
2075 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
2076
2077 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2078 vaxpbyz4(zptr, aptr, xptr, bptr, yptr, 1);
2079
2080 }
2081
2082 */
2083
2084 }
2085}
2086
2087
2088// z = ax - by
2089template<>
2090inline
2092 const OpAssign &op,
2093 const QDPExpr<
2101 OLattice< DVec > > &rhs,
2102 const Subset& s)
2103{
2104
2105#ifdef DEBUG_BLAS
2106 QDPIO::cout << "z = a*x - b*y" << endl;
2107#endif
2108
2109 // Peel the stuff out of the expression
2110 // y is the right side of rhs
2111
2112 // ax is the left side of rhs and is in a binary node
2113 typedef BinaryNode<OpMultiply,
2116
2117 // get the binary node
2118 const BN &mulNode1 = static_cast<const BN&> (rhs.expression().left());
2119 const BN &mulNode2 = static_cast<const BN&> (rhs.expression().right());
2120
2121 // get a and x out of the binary node
2122 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.left());
2123 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.right());
2124
2125 // get b and y out of the binary node
2126 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.left());
2127 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.right());
2128
2129
2130 // Set pointers
2131 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
2132 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
2133
2134 if( s.hasOrderedRep() ) {
2135 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
2136 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
2137 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
2138
2139
2140 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2141 //int n_4vec = (s.end()-s.start()+1);
2142
2143 int total_n_4vec = s.end()-s.start()+1;
2144
2145 if( zptr == yptr ) {
2146
2147 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr, bptr, vaxmby4};
2148
2150
2152 // Original code
2154 //vaxmby4(yptr, aptr, xptr, bptr, n_4vec);
2155 }
2156 else {
2157 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxmbyz4};
2158
2160
2162 // Original code
2164 //vaxmbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
2165 }
2166
2167
2168 }
2169 else {
2170 const int* tab = s.siteTable().slice();
2171
2172 int totalSize = s.numSiteTable();
2173
2174 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxmbyz4);
2175
2177
2179 // Original code
2181 /*
2182 for(int j=0; j < s.numSiteTable(); j++) {
2183 int i=tab[j];
2184
2185 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
2186 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
2187 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
2188
2189 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2190 vaxmbyz4(zptr, aptr, xptr, bptr, yptr, 1);
2191
2192 }
2193
2194 */
2195 }
2196}
2197
2198
2199// z = xa - by
2200template<>
2201inline
2203 const OpAssign &op,
2204 const QDPExpr<
2212 OLattice< DVec > > &rhs,
2213 const Subset& s)
2214{
2215
2216#ifdef DEBUG_BLAS
2217 QDPIO::cout << "z = x*a - b*y" << endl;
2218#endif
2219
2220 // Peel the stuff out of the expression
2221 // y is the right side of rhs
2222
2223 // ax is the left side of rhs and is in a binary node
2224 typedef BinaryNode<OpMultiply,
2227
2228 typedef BinaryNode<OpMultiply,
2231
2232
2233
2234 // get the binary node
2235 const BN1 &mulNode1 = static_cast<const BN1&> (rhs.expression().left());
2236 const BN2 &mulNode2 = static_cast<const BN2&> (rhs.expression().right());
2237
2238 // get a and x out of the binary node
2239 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.left());
2240
2241 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.right());
2242
2243 // get b and y out of the binary node
2244 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.left());
2245 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.right());
2246
2247
2248 // Set pointers
2249 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
2250 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
2251
2252 if( s.hasOrderedRep() ) {
2253 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
2254 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
2255 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
2256
2257
2258 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2259 //int n_4vec = (s.end()-s.start()+1);
2260
2261 int total_n_4vec = s.end()-s.start()+1;
2262
2263 if( zptr == yptr ) {
2264
2265 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr, bptr, vaxmby4};
2266
2268
2270 // Original code
2272 //vaxmby4(yptr, aptr, xptr, bptr, n_4vec);
2273 }
2274 else {
2275 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxmbyz4};
2276
2278
2280 // Original code
2282 //vaxmbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
2283 }
2284
2285
2286 }
2287 else {
2288 const int* tab = s.siteTable().slice();
2289
2290 int totalSize = s.numSiteTable();
2291
2292 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxmbyz4);
2293
2295
2297 // Original code
2299 /*
2300 for(int j=0; j < s.numSiteTable(); j++) {
2301 int i=tab[j];
2302
2303 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
2304 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
2305 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
2306
2307 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2308 vaxmbyz4(zptr, aptr, xptr, bptr, yptr, 1);
2309
2310 }
2311
2312 */
2313 }
2314}
2315
2316// z = ax - yb
2317template<>
2318inline
2320 const OpAssign &op,
2321 const QDPExpr<
2329 OLattice< DVec > > &rhs,
2330 const Subset& s)
2331{
2332
2333#ifdef DEBUG_BLAS
2334 QDPIO::cout << "z = a*x - y*b" << endl;
2335#endif
2336
2337 // Peel the stuff out of the expression
2338 // y is the right side of rhs
2339
2340 // type of a*x
2341 typedef BinaryNode<OpMultiply,
2344
2345 // type of y*b
2346 typedef BinaryNode<OpMultiply,
2349
2350
2351
2352 // get the binary nodes
2353 // a*x node
2354 const BN1 &mulNode1 = static_cast<const BN1&> (rhs.expression().left());
2355
2356 // y*b node
2357 const BN2 &mulNode2 = static_cast<const BN2&> (rhs.expression().right());
2358
2359 // get a and x out of the binary node
2360 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.left());
2361
2362 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.right());
2363
2364
2365 // get b and y out of the binary node
2366 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.left());
2367
2368 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.right());
2369
2370
2371 // Set pointers
2372 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
2373 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
2374
2375 if( s.hasOrderedRep() ) {
2376 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
2377 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
2378 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
2379
2380
2381 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2382 //int n_4vec = (s.end()-s.start()+1);
2383
2384 int total_n_4vec = s.end()-s.start()+1;
2385
2386 if( zptr == yptr ) {
2387
2388 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr, bptr, vaxmby4};
2389
2391
2393 // Original code
2395 //vaxmby4(yptr, aptr, xptr, bptr, n_4vec);
2396 }
2397 else {
2398 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxmbyz4};
2399
2401
2403 // Original code
2405 //vaxmbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
2406 }
2407
2408
2409 }
2410 else {
2411 const int* tab = s.siteTable().slice();
2412
2413 int totalSize = s.numSiteTable();
2414
2415 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxmbyz4);
2416
2418
2420 // Original code
2422 /*
2423
2424 for(int j=0; j < s.numSiteTable(); j++) {
2425 int i=tab[j];
2426
2427 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
2428 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
2429 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
2430
2431 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2432 vaxmbyz4(zptr, aptr, xptr, bptr, yptr, 1);
2433
2434 }
2435
2436 */
2437
2438 }
2439}
2440
2441// z = xa - yb
2442template<>
2443inline
2445 const OpAssign &op,
2446 const QDPExpr<
2454 OLattice< DVec > > &rhs,
2455 const Subset& s)
2456{
2457
2458#ifdef DEBUG_BLAS
2459 QDPIO::cout << "z = x*a - y*b" << endl;
2460#endif
2461
2462 // Peel the stuff out of the expression
2463 // y is the right side of rhs
2464
2465 // ax is the left side of rhs and is in a binary node
2466 typedef BinaryNode<OpMultiply,
2469
2470 // get the binary node
2471 const BN &mulNode1 = static_cast<const BN&> (rhs.expression().left());
2472 const BN &mulNode2 = static_cast<const BN&> (rhs.expression().right());
2473
2474 // get a and x out of the binary node
2475 const OLattice< DVec >& x = static_cast<const OLattice< DVec >&>(mulNode1.left());
2476 const OScalar< DScal >& a = static_cast<const OScalar< DScal >&>(mulNode1.right());
2477
2478 // get b and y out of the binary node
2479 const OLattice< DVec >& y = static_cast<const OLattice< DVec >&>(mulNode2.left());
2480
2481 const OScalar< DScal >& b = static_cast<const OScalar< DScal >&>(mulNode2.right());
2482
2483 // Set pointers
2484 REAL64 *aptr = (REAL64 *)&(a.elem().elem().elem().elem());
2485 REAL64 *bptr = (REAL64 *)&(b.elem().elem().elem().elem());
2486 if( s.hasOrderedRep() ) {
2487
2488 REAL64 *xptr = (REAL64 *) &(x.elem(s.start()).elem(0).elem(0).real());
2489 REAL64 *yptr = (REAL64 *) &(y.elem(s.start()).elem(0).elem(0).real());
2490 REAL64* zptr = &(d.elem(s.start()).elem(0).elem(0).real());
2491
2492
2493 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2494 //int n_4vec = (s.end()-s.start()+1);
2495
2496 int total_n_4vec = s.end()-s.start()+1;
2497
2498 if( zptr == yptr ) {
2499
2500 ordered_sse_vaxOpby4_double_user_arg arg = {yptr, aptr, xptr, bptr, vaxmby4};
2501
2503
2505 // Original code
2507 //vaxmby4(yptr, aptr, xptr, bptr, n_4vec);
2508 }
2509 else {
2510 ordered_sse_vaxOpbyz4_double_user_arg arg = {zptr, aptr, xptr, bptr, yptr, vaxmbyz4};
2511
2513
2515 // Original code
2517 //vaxmbyz4(zptr, aptr, xptr, bptr, yptr, n_4vec);
2518 }
2519
2520
2521 }
2522 else {
2523 const int* tab = s.siteTable().slice();
2524
2525 int totalSize = s.numSiteTable();
2526
2527 unordered_sse_vaxOpbyz4_double_user_arg arg(x, y, d, aptr, bptr, 1, tab, vaxmbyz4);
2528
2530
2532 // Original code
2534 /*
2535 for(int j=0; j < s.numSiteTable(); j++) {
2536 int i=tab[j];
2537
2538 REAL64 *xptr = (REAL64 *) &(x.elem(i).elem(0).elem(0).real());
2539 REAL64 *yptr = (REAL64 *) &(y.elem(i).elem(0).elem(0).real());
2540 REAL64* zptr = &(d.elem(i).elem(0).elem(0).real());
2541
2542 // Get the no of 3vecs. s.start() and s.end() are inclusive so add +1
2543 vaxmbyz4(zptr, aptr, xptr, bptr, yptr, 1);
2544
2545 }
2546
2547 */
2548
2549 }
2550}
2551
2552
2553
2554// Global norm squared of a vector...
2555template<>
2558{
2559#ifdef DEBUG_BLAS
2560 QDPIO::cout << "Using BJ sumsq" << endl;
2561#endif
2562
2563 if ( s.hasOrderedRep() ) {
2564
2565#ifdef DEBUG_BLAS
2566 QDPIO::cout << "BJ sumsq " << endl;
2567#endif
2568
2570 int n4vec = s.end()-s.start()+1;
2571
2572 arg.vptr = (REAL64*)&(s1.elem(s.start()).elem(0).elem(0).real());
2574 arg.func = local_sumsq4;
2576 REAL64 lsum=arg.results[0];
2577 for(int i=1; i < qdpNumThreads(); i++) {
2578 lsum += arg.results[i];
2579 }
2582 return gsum;
2583
2584#if 0
2585 const REAL64 *s1ptr = &(s1.elem(s.start()).elem(0).elem(0).real());
2586
2587 // Has Type OScalar< PScalar < PScalar < RScalar < REAL64 > > > >
2588
2589 REAL64 lsum; // local_sumsq4 zeros this
2590 int n_4vec = (s.end() - s.start() + 1);
2591 local_sumsq4(&lsum,(REAL64 *)s1ptr, n_4vec);
2594 return gsum;
2595#endif
2596 }
2597 else {
2598
2599 // Has Type OScalar< PScalar < PScalar < RScalar < REAL64 > > > >
2600 REAL64 lsum =(REAL64)0;
2601 REAL64 ltmp =(REAL64)0;
2602
2603 const int* tab=s.siteTable().slice();
2604 for(int j=0; j < s.numSiteTable(); j++) {
2605 int i=tab[j];
2606 REAL64* s1ptr = (REAL64 *)&(s1.elem(i).elem(0).elem(0).real());
2607 local_sumsq4(&ltmp,s1ptr,1);
2608 lsum +=ltmp;
2609 }
2610
2613 return gsum;
2614 }
2615}
2616
2617
2618template<>
2621{
2622#ifdef DEBUG_BLAS
2623 QDPIO::cout << "Using BJ sumsq all" << endl;
2624#endif
2626 int n4vec = all.end()-all.start()+1;
2627
2628 arg.vptr = (REAL64*)&(s1.elem(all.start()).elem(0).elem(0).real());
2629 arg.func = local_sumsq4;
2631
2632
2634
2635 // Sum partial results
2636 REAL64 lsum=arg.results[0];
2637 for(int i=1; i < qdpNumThreads(); i++) {
2638 lsum += arg.results[i];
2639 }
2642 return gsum;
2643
2644#if 0
2645 int n_4vec = (all.end() - all.start() + 1);
2646 const REAL64 *s1ptr = &(s1.elem(all.start()).elem(0).elem(0).real());
2647
2648
2649
2650 REAL64 lsum = (REAL64)0;
2651 local_sumsq4(&lsum, (REAL64 *)s1ptr, n_4vec);
2654 return gsum;
2655#endif
2656}
2657
2658
2659
2660template<>
2661inline BinaryReturn< OLattice<DVec>, OLattice<DVec>, FnInnerProduct>::Type_t
2663 const QDPType< DVec, OLattice<DVec> > &v2)
2664{
2665#ifdef DEBUG_BLAS
2666 QDPIO::cout << "BJ: innerProduct all" << endl;
2667#endif
2669 int n4vec = all.end()-all.start()+1;
2670 arg.xptr = (REAL64*)&(v1.elem(all.start()).elem(0).elem(0).real());
2671 arg.yptr = (REAL64*)&(v2.elem(all.start()).elem(0).elem(0).real());
2672 arg.func = local_vcdot4;
2674
2676 REAL64 ip[2] = { arg.results[0],arg.results[1] };
2677
2678 for( int i=1; i < qdpNumThreads(); i++) {
2679 ip[0] += arg.results[2*i];
2680 ip[1] += arg.results[2*i+1];
2681 }
2682
2684
2685 // This BinaryReturn has Type_t
2686 // OScalar<OScalar<OScalar<RComplex<PScalar<REAL64> > > > >
2688
2689 lprod.elem().elem().elem().real() = ip[0];
2690 lprod.elem().elem().elem().imag() = ip[1];
2691
2692
2693 return lprod;
2694#if 0
2695 // This BinaryReturn has Type_t
2696 // OScalar<OScalar<OScalar<RComplex<PScalar<REAL64> > > > >
2698 // Inner product is accumulated internally in DOUBLE
2699 REAL64 ip[2];
2700 ip[0]=0;
2701 ip[1]=0;
2702
2703 // Length of subset
2704 unsigned long n_4vec = (all.end() - all.start() + 1);
2705
2706 // Call My CDOT
2707 local_vcdot4(&(ip[0]),
2708 (REAL64 *)&(v1.elem(all.start()).elem(0).elem(0).real()),
2709 (REAL64 *)&(v2.elem(all.start()).elem(0).elem(0).real()),
2710 n_4vec);
2711
2712
2713 // Global sum -- still on a vector of doubles
2715
2716 // Downcast (and possibly lose precision) here
2717 lprod.elem().elem().elem().real() = ip[0];
2718 lprod.elem().elem().elem().imag() = ip[1];
2719
2720 // Return
2721 return lprod;
2722#endif
2723
2724}
2725
2726template<>
2727inline BinaryReturn< OLattice<DVec>, OLattice<DVec>, FnInnerProduct>::Type_t
2729 const QDPType< DVec, OLattice<DVec> > &v2,
2730 const Subset& s)
2731{
2732
2733 if( s.hasOrderedRep() ) {
2734#ifdef DEBUG_BLAS
2735 QDPIO::cout << "BJ: innerProduct s" << endl;
2736#endif
2738 int n4vec = s.end()-s.start()+1;
2739 arg.xptr = (REAL64*)&(v1.elem(s.start()).elem(0).elem(0).real());
2740 arg.yptr = (REAL64*)&(v2.elem(s.start()).elem(0).elem(0).real());
2741 arg.func = local_vcdot4;
2743
2745 REAL64 ip[2] = { arg.results[0],arg.results[1] };
2746
2747 for( int i=1; i < qdpNumThreads(); i++) {
2748 ip[0] += arg.results[2*i];
2749 ip[1] += arg.results[2*i+1];
2750 }
2751
2753
2754 // This BinaryReturn has Type_t
2755 // OScalar<OScalar<OScalar<RComplex<PScalar<REAL64> > > > >
2757
2758 lprod.elem().elem().elem().real() = ip[0];
2759 lprod.elem().elem().elem().imag() = ip[1];
2760
2761
2762 return lprod;
2763
2764#if 0
2765 ip[0] = 0;
2766 ip[1] = 0;
2767
2768 unsigned long n_4vec = (s.end() - s.start() + 1);
2769 local_vcdot4(&(ip[0]),
2770 (REAL64 *)&(v1.elem(s.start()).elem(0).elem(0).real()),
2771 (REAL64 *)&(v2.elem(s.start()).elem(0).elem(0).real()),
2772 n_4vec);
2773
2774
2775#endif
2776
2777
2778 }
2779 else {
2780
2782 REAL64 ip[2], ip_tmp[2];
2783 ip[0] = 0;
2784 ip[1] = 0;
2785
2786 const int *tab = s.siteTable().slice();
2787 for(int j=0; j < s.numSiteTable(); j++) {
2788
2789 int i=tab[j];
2790
2791 local_vcdot4(&(ip_tmp[0]),
2792 (REAL64 *)&(v1.elem(i).elem(0).elem(0).real()),
2793 (REAL64 *)&(v2.elem(i).elem(0).elem(0).real()),
2794 1);
2795
2796 ip[0] += ip_tmp[0];
2797 ip[1] += ip_tmp[1];
2798 }
2799
2801
2802 lprod.elem().elem().elem().real() = ip[0];
2803 lprod.elem().elem().elem().imag() = ip[1];
2804
2805
2806 return lprod;
2807
2808 }
2809}
2810
2811
2812// Inner Product Real
2813template<>
2814inline
2815BinaryReturn< OLattice<DVec>, OLattice<DVec>, FnInnerProductReal>::Type_t
2817 const QDPType< DVec, OLattice<DVec> > &v2)
2818{
2819#ifdef DEBUG_BLAS
2820 QDPIO::cout << "BJ: innerProductReal all" << endl;
2821#endif
2822
2823 // This BinaryReturn has Type_t
2824 // OScalar<OScalar<OScalar<RScalar<PScalar<REAL64> > > > >
2826 // Inner product is accumulated internally in DOUBLE
2827 REAL64 ip_re=0;
2828
2829 // Length of subset
2830 unsigned long n_4vec = (all.end() - all.start() + 1);
2831
2832 // Call My CDOT
2833 local_vcdot_real4(&ip_re,
2834 (REAL64 *)&(v1.elem(all.start()).elem(0).elem(0).real()),
2835 (REAL64 *)&(v2.elem(all.start()).elem(0).elem(0).real()),
2836 n_4vec);
2837
2838 // Global sum
2840
2841 // Whether CDOT did anything or not ip_re and ip_im should
2842 // now be right. Assign them to the ReturnType
2843 lprod.elem().elem().elem().elem() = ip_re;
2844
2845
2846 // Return
2847 return lprod;
2848}
2849
2850
2851template<>
2852inline
2853BinaryReturn< OLattice<DVec>, OLattice<DVec>, FnInnerProductReal>::Type_t
2855 const QDPType< DVec, OLattice<DVec> > &v2,
2856 const Subset& s)
2857{
2858 if( s.hasOrderedRep() ) {
2859#ifdef DEBUG_BLAS
2860 QDPIO::cout << "BJ: innerProductReal s" << endl;
2861#endif
2862
2863 // This BinaryReturn has Type_t
2864 // OScalar<OScalar<OScalar<RScalar<PScalar<REAL64> > > > >
2866 REAL64 ip_re=0;
2867
2868 unsigned long n_4vec = (s.end() - s.start() + 1);
2869 local_vcdot_real4(&ip_re,
2870 (REAL64 *)&(v1.elem(s.start()).elem(0).elem(0).real()),
2871 (REAL64 *)&(v2.elem(s.start()).elem(0).elem(0).real()),
2872 n_4vec);
2873
2875 lprod.elem().elem().elem().elem() = ip_re;
2876
2877
2878 return lprod;
2879 }
2880 else {
2881
2882
2884 REAL64 ip_re=0, ip_re_tmp;
2885
2886
2887 const int *tab = s.siteTable().slice();
2888 for(int j=0; j < s.numSiteTable(); j++) {
2889
2890 int i=tab[j];
2891
2892 local_vcdot_real4(&ip_re_tmp,
2893 (REAL64 *)&(v1.elem(i).elem(0).elem(0).real()),
2894 (REAL64 *)&(v2.elem(i).elem(0).elem(0).real()),
2895 1);
2896
2897 ip_re += ip_re_tmp;
2898 }
2900 lprod.elem().elem().elem().elem() = ip_re;
2901 return lprod;
2902 }
2903}
2904
2905
2906template<>
2909{
2910#ifdef DEBUG_BLAS
2911 QDPIO::cout << "Using SSE multi1d sumsq all" << endl;
2912#endif
2913
2914 int n_4vec = (all.end() - all.start() + 1);
2915 REAL64 ltmp = 0;
2916 for(int n=0; n < s1.size(); ++n)
2917 {
2918 const REAL64* s1ptr = &(s1[n].elem(all.start()).elem(0).elem(0).real());
2919
2920 // I am relying on this being a Double here
2921 REAL64 lltmp=0;
2922 local_sumsq4(&lltmp, (REAL64*)s1ptr, n_4vec);
2923
2924 ltmp += lltmp;
2925 }
2926
2929 return lsum;
2930}
2931
2932
2933template<>
2934inline BinaryReturn< OLattice<DVec>, OLattice<DVec>, FnInnerProduct>::Type_t
2936 const multi1d< OLattice<DVec> > &v2)
2937{
2938#ifdef DEBUG_BLAS
2939 QDPIO::cout << "BJ: multi1d innerProduct all" << endl;
2940#endif
2941
2942 // This BinaryReturn has Type_t
2943 // OScalar<OScalar<OScalar<RComplex<PScalar<REAL64> > > > >
2945
2946 // Inner product is accumulated internally in DOUBLE
2947 REAL64 ip[2];
2948 ip[0]=0;
2949 ip[1]=0;
2950
2951 // Length of subset
2952 unsigned long n_4vec = (all.end() - all.start() + 1);
2953
2954 for(int n=0; n < v1.size(); ++n)
2955 {
2956 REAL64 iip[2];
2957 iip[0]=0;
2958 iip[1]=0;
2959
2960 // Call My CDOT
2961 local_vcdot4(&(iip[0]),
2962 (REAL64 *)&(v1[n].elem(all.start()).elem(0).elem(0).real()),
2963 (REAL64 *)&(v2[n].elem(all.start()).elem(0).elem(0).real()),
2964 n_4vec);
2965
2966 ip[0] += iip[0];
2967 ip[1] += iip[1];
2968 }
2969
2970 // Global sum -- still on a vector of doubles
2972
2973 // Downcast (and possibly lose precision) here
2974 lprod.elem().elem().elem().real() = ip[0];
2975 lprod.elem().elem().elem().imag() = ip[1];
2976
2977 // Return
2978 return lprod;
2979}
2980
2981
2982
2983// Inner Product Real
2984template<>
2985inline
2986BinaryReturn< OLattice<DVec>, OLattice<DVec>, FnInnerProductReal>::Type_t
2988 const multi1d< OLattice<DVec> > &v2)
2989{
2990#ifdef DEBUG_BLAS
2991 QDPIO::cout << "BJ: innerProductReal(multi1d) all" << endl;
2992#endif
2993
2994 // This BinaryReturn has Type_t
2995 // OScalar<OScalar<OScalar<RScalar<PScalar<REAL64> > > > >
2997 // Inner product is accumulated internally in DOUBLE
2998 REAL64 ip_re=0;
2999
3000 // Length of subset
3001 unsigned long n_4vec = (all.end() - all.start() + 1);
3002
3003 for(int n=0; n < v1.size(); ++n)
3004 {
3005 REAL64 iip_re=0;
3006
3007 // Call My CDOT
3008 local_vcdot_real4(&iip_re,
3009 (REAL64 *)&(v1[n].elem(all.start()).elem(0).elem(0).real()),
3010 (REAL64 *)&(v2[n].elem(all.start()).elem(0).elem(0).real()),
3011 n_4vec);
3012
3013 ip_re += iip_re;
3014 }
3015
3016 // Global sum
3018
3019 // Whether CDOT did anything or not ip_re and ip_im should
3020 // now be right. Assign them to the ReturnType
3021 lprod.elem().elem().elem().elem() = ip_re;
3022
3023
3024 // Return
3025 return lprod;
3026}
3027
3028
3029} // namespace QDP;
3030
3031
3032#endif // guard
3033
Outer grid Lattice type.
Definition qdp_outer.h:264
T & elem(int i)
Definition qdp_outer.h:400
Outer grid Scalar class *‍/.
Definition qdp_outer.h:37
Primitive Scalar.
Primitive spin Vector class.
Expression class for QDP.
Definition qdp_qdpexpr.h:16
QDPType - major type class/container for all QDP objects.
Definition qdp_qdptype.h:29
Subsets - controls how lattices are looped.
Definition qdp_subset.h:39
int end() const
Definition qdp_subset.h:81
const multi1d< int > & siteTable() const
Definition qdp_subset.h:83
int numSiteTable() const
Definition qdp_subset.h:84
bool hasOrderedRep() const
Definition qdp_subset.h:79
int start() const
Definition qdp_subset.h:80
Container for a multi-dimensional 1D array.
Definition qdp_multi.h:25
const T * slice() const
Return ref to a column slice.
Definition qdp_multi.h:225
double REAL64
BinaryReturn< C1, C2, FnInnerProductReal >::Type_t innerProductReal(const QDPType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
OScalar = innerProductReal(adj(source1)*source2).
UnaryReturn< C, FnNorm2 >::Type_t norm2(const QDPType< T, C > &s1)
OScalar = norm2(trace(adj(source)*source)).
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
OScalar = innerProduct(adj(source1)*source2).
void evaluate(OLattice< DCol > &d, const OpAssign &op, const QDPExpr< BinaryNode< OpMultiply, Reference< QDPType< DCol, OLattice< DCol > > >, Reference< QDPType< DCol, OLattice< DCol > > > >, OLattice< DCol > > &rhs, const Subset &s)
Subset all
Default all subset.
Definition qdp_subset.cc:16
StandardOutputStream cout
Definition qdp_stdio.cc:21
void globalSum(T &dest)
Sum across all nodes.
void globalSumArray(unsigned int *dest, int len)
Wrapper to get a functional unsigned global sum.
Yet another random number generator.
void unordered_sse_vaxOpbyz4_double_evaluate_function(int lo, int hi, int myId, unordered_sse_vaxOpbyz4_double_user_arg *a)
MakeReturn< UnaryNode< FnReal, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnReal >::Type_t >::Expression_t real(const QDPExpr< T1, C1 > &l)
Definition qdp.h:4972
void dispatch_to_threads(int numSiteTable, Arg a, void(*func)(int, int, int, Arg *))
PScalar< PScalar< RScalar< REAL64 > > > DScal
void vaxpy4(REAL64 *Out, REAL64 *scalep, REAL64 *InScale, int n_4spin)
void vscal4(REAL64 *z, REAL64 *a, REAL64 *x, int n_4spin)
void vaxpby4(REAL64 *y, REAL64 *a, REAL64 *x, REAL64 *b, int n_4vec)
void ordered_sse_vaxOpy4_double_evaluate_function(int lo, int hi, int myId, ordered_sse_vaxOpy4_double_user_arg *a)
void vaxmyz4(REAL64 *Out, REAL64 *scalep, REAL64 *InScale, REAL64 *Add, int n_4vec)
void vaxmy4(REAL64 *Out, REAL64 *scalep, REAL64 *InScale, int n_4spin)
void ordered_sse_vaxOpyz4_double_evaluate_function(int lo, int hi, int myId, ordered_sse_vaxOpyz4_double_user_arg *a)
void ordered_sse_vscal4_double_evaluate_function(int lo, int hi, int myId, ordered_sse_vscal4_double_user_arg *a)
void ordered_sse_vaxOpby4_double_evaluate_function(int lo, int hi, int myId, ordered_sse_vaxOpby4_double_user_arg *a)
void ordered_sse_vaxOpbyz4_double_evaluate_function(int lo, int hi, int myId, ordered_sse_vaxOpbyz4_double_user_arg *a)
void local_vcdot_real4(REAL64 *sum, REAL64 *y, REAL64 *x, int n_4spin)
void local_sumsq4(REAL64 *sum, REAL64 *vecptr, int n_4spin)
void vaxpyz4(REAL64 *Out, REAL64 *scalep, REAL64 *InScale, REAL64 *Add, int n_4vec)
void local_vcdot4(REAL64 *sum, REAL64 *y, REAL64 *x, int n_4spin)
void unordered_sse_vaxOpyz4_double_evaluate_function(int lo, int hi, int myId, unordered_sse_vaxOpyz4_double_user_arg *a)
void vaxmby4(REAL64 *y, REAL64 *a, REAL64 *x, REAL64 *b, int n_4vec)
void ordered_inner_product_double_func(int lo, int hi, int myId, ordered_inner_product_double_user_arg *a)
void unordered_sse_vaxOpy4_double_evaluate_function(int lo, int hi, int myId, unordered_sse_vaxOpy4_double_user_arg *a)
void vaxpbyz4(REAL64 *z, REAL64 *a, REAL64 *x, REAL64 *b, REAL64 *y, int n_4vec)
PSpinVector< PColorVector< RComplex< REAL64 >, 3 >, 4 > DVec
void unordered_sse_vscal4_double_evaluate_function(int lo, int hi, int myId, unordered_sse_vscal4_double_user_arg *a)
int qdpNumThreads()
void vaxmbyz4(REAL64 *z, REAL64 *a, REAL64 *x, REAL64 *b, REAL64 *y, int n_4vec)
void ordered_norm_double_func(int lo, int hi, int myId, ordered_norm_double_user_arg *a)
void unordered_sse_vaxOpy4_double_evaluate_function(int lo, int hi, int myId, unordered_sse_vaxOpy4_double_user_arg *a)
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
Generic Scalar VAXPY routine.
void(* func)(REAL64 *, REAL64 *, REAL64 *, int)