12 template<
typename AFIELD>
16 template<
typename AFIELD>
32 vout.
general(m_vl,
"%s: construction\n", class_name.c_str());
38 if (repr !=
"Dirac") {
39 vout.
crucial(
" Error at %s: unsupported gamma-matrix type: %s\n",
40 class_name.c_str(), repr.c_str());
54 m_Ndf = 2 * m_Nc * m_Nc;
65 m_Nstv = m_Nst /
VLEN;
67 if (
VLENX * m_Nxv != m_Nx) {
68 vout.
crucial(m_vl,
"%s: Nx must be multiple of VLENX.\n",
72 if (
VLENY * m_Nyv != m_Ny) {
73 vout.
crucial(m_vl,
"%s: Ny must be multiple of VLENY.\n",
88 for (
int mu = 0; mu < m_Ndim; ++mu) {
91 do_comm_any += do_comm[mu];
92 vout.
general(
" do_comm[%d] = %d\n", mu, do_comm[mu]);
95 m_bdsize.resize(m_Ndim);
97 m_bdsize[0] = m_Nvc * Nd2 * m_Ny * m_Nz * m_Nt;
98 m_bdsize[1] = m_Nvc * Nd2 * m_Nx * m_Nz * m_Nt;
99 m_bdsize[2] = m_Nvc * Nd2 * m_Nx * m_Ny * m_Nt;
100 m_bdsize[3] = m_Nvc * Nd2 * m_Nx * m_Ny * m_Nz;
108 #ifdef CHIRAL_ROTATION
109 params_ct.
set_string(
"gamma_matrix_type",
"Chiral");
115 set_parameters(params);
120 m_U.reset(
NDF, m_Nst, m_Ndim);
123 int NinF = 2 * m_Nc * m_Nd;
124 m_v2.reset(NinF, m_Nst, 1);
126 int Ndm2 = m_Nd * m_Nd / 2;
128 m_T.reset(
NDF * Ndm2, m_Nst, 1);
136 template<
typename AFIELD>
139 chsend_up.resize(m_Ndim);
140 chrecv_up.resize(m_Ndim);
141 chsend_dn.resize(m_Ndim);
142 chrecv_dn.resize(m_Ndim);
144 for (
int mu = 0; mu < m_Ndim; ++mu) {
145 size_t Nvsize = m_bdsize[mu] *
sizeof(
real_t);
147 chsend_dn[mu].send_init(Nvsize, mu, -1);
148 chsend_up[mu].send_init(Nvsize, mu, 1);
150 chrecv_up[mu].recv_init(Nvsize, mu, 1);
151 chrecv_dn[mu].recv_init(Nvsize, mu, -1);
153 void *buf_up = (
void *)chsend_dn[mu].ptr();
154 chrecv_up[mu].recv_init(Nvsize, mu, 1, buf_up);
155 void *buf_dn = (
void *)chsend_up[mu].ptr();
156 chrecv_dn[mu].recv_init(Nvsize, mu, -1, buf_dn);
159 if (do_comm[mu] == 1) {
160 chset_send.append(chsend_up[mu]);
161 chset_send.append(chsend_dn[mu]);
162 chset_recv.append(chrecv_up[mu]);
163 chset_recv.append(chrecv_dn[mu]);
170 template<
typename AFIELD>
180 template<
typename AFIELD>
191 vout.
crucial(m_vl,
"Error at %s: input parameter not found.\n",
199 #ifdef CHIRAL_ROTATION
200 params_csw.
set_string(
"gamma_matrix_type",
"Chiral");
202 m_fopr_csw->set_parameters(params_csw);
207 template<
typename AFIELD>
210 const std::vector<int> bc)
212 assert(bc.size() == m_Ndim);
221 m_boundary.resize(m_Ndim);
222 for (
int mu = 0; mu < m_Ndim; ++mu) {
223 m_boundary[mu] = bc[mu];
227 vout.
general(m_vl,
"%s: set parameters\n", class_name.c_str());
228 vout.
general(m_vl,
" gamma-matrix type = %s\n", m_repr.c_str());
231 for (
int mu = 0; mu < m_Ndim; ++mu) {
232 vout.
general(m_vl,
" boundary[%d] = %2d\n", mu, m_boundary[mu]);
240 template<
typename AFIELD>
243 params.
set_double(
"hopping_parameter",
double(m_CKs));
244 params.
set_double(
"clover_coefficient",
double(m_csw));
246 params.
set_string(
"gamma_matrix_type", m_repr);
253 template<
typename AFIELD>
258 vout.
detailed(m_vl,
"%s: set_config is called: num_threads = %d\n",
259 class_name.c_str(), nth);
267 vout.
detailed(m_vl,
"%s: set_config finished\n", class_name.c_str());
272 template<
typename AFIELD>
285 template<
typename AFIELD>
292 if (ith == 0) m_conf = u;
300 m_fopr_csw->set_config(u);
302 #ifdef CHIRAL_ROTATION
311 template<
typename AFIELD>
326 const int Nin =
NDF *
ND * 2;
328 m_fopr_csw->set_mode(
"D");
330 int ith, nth, is, ns;
331 set_threadtask_mult(ith, nth, is, ns, m_Nst);
333 for (
int id = 0;
id < m_Nd / 2; ++id) {
334 for (
int ic = 0; ic < m_Nc; ++ic) {
338 for (
int site = is; site < ns; ++site) {
339 m_w1.set_r(ic,
id, site, 0, 1.0);
343 m_fopr_csw->mult(m_w2, m_w1);
346 for (
int site = is; site < ns; ++site) {
347 for (
int ic2 = 0; ic2 < m_Nc; ++ic2) {
348 real_t vt_r = m_w2.cmp_r(ic2, 0, site, 0);
349 real_t vt_i = m_w2.cmp_i(ic2, 0, site, 0);
350 int in = ic2 +
NC * (ic +
NC * (
id + 0));
351 int idx_r = index.idx(2 * in, Nin, site, 0);
352 int idx_i = index.idx(2 * in + 1, Nin, site, 0);
353 m_T.set(idx_r, vt_r);
354 m_T.set(idx_i, vt_i);
357 for (
int ic2 = 0; ic2 < m_Nc; ++ic2) {
358 real_t vt_r = m_w2.cmp_r(ic2, 1, site, 0);
359 real_t vt_i = m_w2.cmp_i(ic2, 1, site, 0);
360 int in = ic2 +
NC * (ic +
NC * (
id + 4));
361 int idx_r = index.idx(2 * in, Nin, site, 0);
362 int idx_i = index.idx(2 * in + 1, Nin, site, 0);
363 m_T.set(idx_r, vt_r);
364 m_T.set(idx_i, vt_i);
367 for (
int ic2 = 0; ic2 < m_Nc; ++ic2) {
368 real_t vt_r = -m_w2.cmp_r(ic2, 2, site, 0);
369 real_t vt_i = -m_w2.cmp_i(ic2, 2, site, 0);
370 int in = ic2 +
NC * (ic +
NC * (
id + 2));
371 int idx_r = index.idx(2 * in, Nin, site, 0);
372 int idx_i = index.idx(2 * in + 1, Nin, site, 0);
373 m_T.set(idx_r, vt_r);
374 m_T.set(idx_i, vt_i);
377 for (
int ic2 = 0; ic2 < m_Nc; ++ic2) {
378 real_t vt_r = -m_w2.cmp_r(ic2, 3, site, 0);
379 real_t vt_i = -m_w2.cmp_i(ic2, 3, site, 0);
380 int in = ic2 +
NC * (ic +
NC * (
id + 6));
381 int idx_r = index.idx(2 * in, Nin, site, 0);
382 int idx_i = index.idx(2 * in + 1, Nin, site, 0);
383 m_T.set(idx_r, vt_r);
384 m_T.set(idx_i, vt_i);
392 real_t kappaR = 1.0 / m_CKs;
400 template<
typename AFIELD>
412 const int Nin =
NDF *
ND * 2;
414 m_fopr_csw->set_mode(
"D");
416 int ith, nth, is, ns;
417 set_threadtask_mult(ith, nth, is, ns, m_Nst);
420 constexpr
int idx[72] = {
421 0, -1, 6, 7, 16, 17, 28, 29, 24, 25, 34, 35,
422 -1, -1, 1, -1, 12, 13, 18, 19, 32, 33, 26, 27,
423 -1, -1, -1, -5, 2, -1, 8, 9, 20, 21, 30, 31,
424 -1, -1, -1, -1, -1, -1, 3, -1, 14, 15, 22, 23,
425 -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, 10, 11,
426 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1,
429 for (
int id = 0;
id < m_Nd / 2; ++id) {
430 for (
int ic = 0; ic < m_Nc; ++ic) {
434 for (
int site = is; site < ns; ++site) {
435 m_w1.set_r(ic,
id, site, 0, 1.0);
436 m_w1.set_r(ic,
id + 2, site, 0, 1.0);
440 m_fopr_csw->mult(m_w2, m_w1);
443 for (
int site = is; site < ns; ++site) {
444 for (
int id2 = 0; id2 < m_Nd; ++id2) {
445 for (
int ic2 = 0; ic2 < m_Nc; ++ic2) {
446 real_t vt_r = 0.5 * m_w2.cmp_r(ic2, id2, site, 0);
447 real_t vt_i = 0.5 * m_w2.cmp_i(ic2, id2, site, 0);
448 int i = ic2 + m_Nc * (id2 % 2);
449 int j = ic + m_Nc * id;
450 int ij = m_Nc * 2 * i + j;
451 int in_r =
idx[2 * ij];
452 int in_i =
idx[2 * ij + 1];
454 in_r += 36 * (id2 / 2);
455 int idx_r = index.idx(in_r, Nin, site, 0);
456 m_T.set(idx_r, vt_r);
459 in_i += 36 * (id2 / 2);
460 int idx_i = index.idx(in_i, Nin, site, 0);
461 m_T.set(idx_i, vt_i);
471 real_t kappaR = 1.0 / m_CKs;
479 template<
typename AFIELD>
490 template<
typename AFIELD>
501 template<
typename AFIELD>
509 }
else if (mu == 1) {
511 }
else if (mu == 2) {
513 }
else if (mu == 3) {
516 vout.
crucial(m_vl,
"%s: mult_up for %d direction is undefined.",
517 class_name.c_str(), mu);
524 template<
typename AFIELD>
532 }
else if (mu == 1) {
534 }
else if (mu == 2) {
536 }
else if (mu == 3) {
539 vout.
crucial(m_vl,
"%s: mult_dn for %d direction is undefined.",
540 class_name.c_str(), mu);
547 template<
typename AFIELD>
553 if (ith == 0) m_mode = mode;
560 template<
typename AFIELD>
568 template<
typename AFIELD>
573 }
else if (m_mode ==
"DdagD") {
575 }
else if (m_mode ==
"Ddag") {
577 }
else if (m_mode ==
"H") {
580 vout.
crucial(m_vl,
"%s: mode undefined.\n", class_name.c_str());
587 template<
typename AFIELD>
592 }
else if (m_mode ==
"DdagD") {
594 }
else if (m_mode ==
"Ddag") {
596 }
else if (m_mode ==
"H") {
599 vout.
crucial(m_vl,
"%s: mode undefined.\n", class_name.c_str());
606 template<
typename AFIELD>
615 template<
typename AFIELD>
626 template<
typename AFIELD>
636 template<
typename AFIELD>
653 template<
typename AFIELD>
659 int ith, nth, is, ns;
660 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
664 for (
int site = is; site < ns; ++site) {
665 for (
int ic = 0; ic <
NC; ++ic) {
666 for (
int id = 0;
id <
ND2; ++id) {
667 int idx1 = 2 * (
id +
ND * ic) +
NVCD * site;
668 load_vec(
wt, &wp[
VLEN * idx1], 2);
669 save_vec(&vp[
VLEN * idx1],
wt, 2);
672 for (
int id =
ND2;
id <
ND; ++id) {
673 int idx1 = 2 * (
id +
ND * ic) +
NVCD * site;
674 load_vec(
wt, &wp[
VLEN * idx1], 2);
676 save_vec(&vp[
VLEN * idx1],
wt, 2);
686 template<
typename AFIELD>
691 int ith, nth, is, ns;
692 set_threadtask(ith, nth, is, ns, m_Nstv);
696 for (
int site = is; site < ns; ++site) {
706 for (
int jd = 0; jd <
ND2; ++jd) {
707 for (
int id = 0;
id <
ND; ++id) {
708 int ig =
VLEN *
NDF * (site + m_Nstv * (
id +
ND * jd));
709 load_vec(ut, &u[ig],
NDF);
710 for (
int ic = 0; ic <
NC; ++ic) {
712 int id2 = (
id +
ND2) %
ND;
713 mult_ctv(wt1, &ut[ic2], &v1v[2 *
id],
NC);
714 mult_ctv(wt2, &ut[ic2], &v1v[2 * id2],
NC);
715 int icd1 = 2 * (jd +
ND * ic);
716 int icd2 = 2 * (jd +
ND2 +
ND * ic);
717 axpy_vec(&v2v[icd1],
real_t(1.0), wt1, 2);
718 axpy_vec(&v2v[icd2],
real_t(1.0), wt2, 2);
731 template<
typename AFIELD>
743 if (do_comm_any > 0) {
744 if (ith == 0) chset_recv.start();
756 buf1_zp, buf1_zm, buf1_tp, buf1_tm,
757 up, v1, &m_boundary[0], m_Nsize, do_comm);
761 if (ith == 0) chset_send.start();
764 #ifdef CHIRAL_ROTATION
766 m_CKs, &m_boundary[0], m_Nsize, do_comm);
769 m_CKs, &m_boundary[0], m_Nsize, do_comm);
772 if (do_comm_any > 0) {
773 if (ith == 0) chset_recv.wait();
787 buf2_xp, buf2_xm, buf2_yp, buf2_ym,
788 buf2_zp, buf2_zm, buf2_tp, buf2_tm,
789 m_CKs, &m_boundary[0], m_Nsize, do_comm);
791 if (ith == 0) chset_send.wait();
799 template<
typename AFIELD>
818 aypx(-m_CKs, vp, wp);
825 template<
typename AFIELD>
834 template<
typename AFIELD>
837 int ith, nth, is, ns;
838 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
842 for (
int site = is; site < ns; ++site) {
845 aypx_vec(a, vt,
wt,
NVCD);
852 template<
typename AFIELD>
855 int ith, nth, is, ns;
856 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
861 for (
int site = is; site < ns; ++site) {
868 template<
typename AFIELD>
873 int ith, nth, is, ns;
874 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
885 if (do_comm[0] > 0) {
886 for (
int site = is; site < ns; ++site) {
887 int ix = site % m_Nxv;
888 int iyzt = site / m_Nxv;
899 chrecv_up[0].start();
900 chsend_dn[0].start();
907 for (
int site = is; site < ns; ++site) {
908 int ix = site % m_Nxv;
909 int iyzt = site / m_Nxv;
912 clear_vec(v2v,
NVCD);
916 if ((
ix < m_Nxv - 1) || (do_comm[0] == 0)) {
917 int nei =
ix + 1 + m_Nxv *
iyzt;
918 if (
ix == m_Nxv - 1) nei = 0 + m_Nxv *
iyzt;
936 template<
typename AFIELD>
941 int ith, nth, is, ns;
942 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
953 if (do_comm[0] > 0) {
954 for (
int site = is; site < ns; ++site) {
955 int ix = site % m_Nxv;
956 int iyzt = site / m_Nxv;
957 if (
ix == m_Nxv - 1) {
967 chrecv_dn[0].start();
968 chsend_up[0].start();
975 for (
int site = is; site < ns; ++site) {
976 int ix = site % m_Nxv;
977 int iyzt = site / m_Nxv;
982 clear_vec(v2v,
NVCD);
984 if ((
ix > 0) || (do_comm[0] == 0)) {
985 int nei =
ix - 1 + m_Nxv *
iyzt;
986 if (
ix == 0) nei = m_Nxv - 1 + m_Nxv *
iyzt;
993 shift_vec0_xfw(uL, &u[
VLEN *
NDF * site],
NDF);
1006 template<
typename AFIELD>
1010 int Nxy = m_Nxv * m_Nyv;
1012 int ith, nth, is, ns;
1013 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
1022 if (do_comm[1] > 0) {
1023 for (
int site = is; site < ns; ++site) {
1024 int ix = site % m_Nxv;
1025 int iy = (site / m_Nxv) % m_Nyv;
1026 int izt = site / Nxy;
1037 chrecv_up[1].start();
1038 chsend_dn[1].start();
1039 chrecv_up[1].wait();
1040 chsend_dn[1].wait();
1046 for (
int site = is; site < ns; ++site) {
1047 int ix = site % m_Nxv;
1048 int iy = (site / m_Nxv) % m_Nyv;
1049 int izt = site / Nxy;
1052 clear_vec(v2v,
NVCD);
1056 if ((
iy < m_Nyv - 1) || (do_comm[1] == 0)) {
1057 int iy2 = (
iy + 1) % m_Nyv;
1058 int nei =
ix + m_Nxv * (iy2 + m_Nyv *
izt);
1076 template<
typename AFIELD>
1080 int Nxy = m_Nxv * m_Nyv;
1082 int ith, nth, is, ns;
1083 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
1092 if (do_comm[1] > 0) {
1093 for (
int site = is; site < ns; ++site) {
1094 int ix = site % m_Nxv;
1095 int iy = (site / m_Nxv) % m_Nyv;
1096 int izt = site / Nxy;
1097 if (
iy == m_Nyv - 1) {
1108 chrecv_dn[1].start();
1109 chsend_up[1].start();
1110 chrecv_dn[1].wait();
1111 chsend_up[1].wait();
1117 for (
int site = is; site < ns; ++site) {
1118 int ix = site % m_Nxv;
1119 int iy = (site / m_Nxv) % m_Nyv;
1120 int izt = site / Nxy;
1123 clear_vec(v2v,
NVCD);
1128 if ((
iy != 0) || (do_comm[
idir] == 0)) {
1129 int iy2 = (
iy - 1 + m_Nyv) % m_Nyv;
1130 int nei =
ix + m_Nxv * (iy2 + m_Nyv *
izt);
1137 shift_vec0_yfw(uL, &u[
VLEN *
NDF * site],
NDF);
1150 template<
typename AFIELD>
1154 int Nxy = m_Nxv * m_Nyv;
1156 int ith, nth, is, ns;
1157 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
1166 if (do_comm[2] > 0) {
1167 for (
int site = is; site < ns; ++site) {
1168 int ixy = site % Nxy;
1169 int iz = (site / Nxy) % m_Nz;
1170 int it = site / (Nxy * m_Nz);
1181 chrecv_up[2].start();
1182 chsend_dn[2].start();
1183 chrecv_up[2].wait();
1184 chsend_dn[2].wait();
1190 for (
int site = is; site < ns; ++site) {
1191 int ixy = site % Nxy;
1192 int iz = (site / Nxy) % m_Nz;
1193 int it = site / (Nxy * m_Nz);
1196 clear_vec(v2v,
NVCD);
1198 if ((
iz != m_Nz - 1) || (do_comm[2] == 0)) {
1199 int iz2 = (
iz + 1) % m_Nz;
1200 int nei =
ixy + Nxy * (iz2 + m_Nz *
it);
1215 template<
typename AFIELD>
1219 int Nxy = m_Nxv * m_Nyv;
1221 int ith, nth, is, ns;
1222 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
1231 if (do_comm[2] > 0) {
1232 for (
int site = is; site < ns; ++site) {
1233 int ixy = site % Nxy;
1234 int iz = (site / Nxy) % m_Nz;
1235 int it = site / (Nxy * m_Nz);
1236 if (
iz == m_Nz - 1) {
1247 chrecv_dn[2].start();
1248 chsend_up[2].start();
1249 chrecv_dn[2].wait();
1250 chsend_up[2].wait();
1256 for (
int site = is; site < ns; ++site) {
1257 int ixy = site % Nxy;
1258 int iz = (site / Nxy) % m_Nz;
1259 int it = site / (Nxy * m_Nz);
1262 clear_vec(v2v,
NVCD);
1264 if ((
iz > 0) || (do_comm[2] == 0)) {
1265 int iz2 = (
iz - 1 + m_Nz) % m_Nz;
1266 int nei =
ixy + Nxy * (iz2 + m_Nz *
it);
1281 template<
typename AFIELD>
1285 int Nxyz = m_Nxv * m_Nyv * m_Nz;
1287 int ith, nth, is, ns;
1288 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
1297 if (do_comm[3] > 0) {
1298 for (
int site = is; site < ns; ++site) {
1299 int ixyz = site % Nxyz;
1300 int it = site / Nxyz;
1311 chrecv_up[3].start();
1312 chsend_dn[3].start();
1313 chrecv_up[3].wait();
1314 chsend_dn[3].wait();
1320 for (
int site = is; site < ns; ++site) {
1321 int ixyz = site % Nxyz;
1322 int it = site / Nxyz;
1325 clear_vec(v2v,
NVCD);
1327 if ((
it < m_Nt - 1) || (do_comm[3] == 0)) {
1328 int it2 = (
it + 1) % m_Nt;
1329 int nei =
ixyz + Nxyz * it2;
1345 template<
typename AFIELD>
1349 int Nxyz = m_Nxv * m_Nyv * m_Nz;
1351 int ith, nth, is, ns;
1352 set_threadtask_mult(ith, nth, is, ns, m_Nstv);
1361 if (do_comm[3] > 0) {
1362 for (
int site = is; site < ns; ++site) {
1363 int ixyz = site % Nxyz;
1364 int it = site / Nxyz;
1365 if (
it == m_Nt - 1) {
1375 chrecv_dn[3].start();
1376 chsend_up[3].start();
1377 chrecv_dn[3].wait();
1378 chsend_up[3].wait();
1383 for (
int site = is; site < ns; ++site) {
1384 int ixyz = site % Nxyz;
1385 int it = site / Nxyz;
1388 clear_vec(v2v,
NVCD);
1390 if ((
it > 0) || (do_comm[3] == 0)) {
1391 int it2 = (
it - 1 + m_Nt) % m_Nt;
1392 int nei =
ixyz + Nxyz * it2;
1407 template<
typename AFIELD>
1414 double flop_wilson, flop_clover, flop_site, flop;
1416 if (m_repr ==
"Dirac") {
1417 flop_wilson =
static_cast<double>(
1419 + 6 * (4 * m_Nc + 2)
1420 + 2 * (4 * m_Nc + 1)));
1423 flop_clover =
static_cast<double>(
1425 + 2 * (2 * (m_Nc * m_Nd - 1) + 1)
1428 }
else if (m_repr ==
"Chiral") {
1429 flop_wilson =
static_cast<double>(
1430 m_Nc * m_Nd * (4 + 8 * (4 * m_Nc + 2)));
1432 flop_clover =
static_cast<double>(
1433 m_Nc * m_Nd * (2 * (2 * (m_Nc * m_Nd - 1) + 1)
1436 vout.
crucial(m_vl,
"%s: input repr is undefined.\n");
1440 flop_site = flop_wilson + flop_clover;
1442 flop = flop_site *
static_cast<double>(Lvol);
1443 if ((mode ==
"DdagD") || (mode ==
"DDdag")) flop *= 2.0;