QDP++
qdp_parscalarvec_specific.cc
Go to the documentation of this file.
1
7
8
9#include "qdp.h"
10#include "qdp_util.h"
11#include "qmp.h"
12
13namespace QDP {
14
15//-----------------------------------------------------------------------------
16// IO routine solely for debugging. Only defined here
17template<class T>
18ostream& operator<<(ostream& s, const multi1d<T>& s1)
19{
20 for(int i=0; i < s1.size(); ++i)
21 s << " " << s1[i];
22
23 return s;
24}
25
26
27//-----------------------------------------------------------------------------
29void Map::make(const MapFunc& func)
30{
31#if QDP_DEBUG >= 3
32 QDP_info("Map::make");
33#endif
34 const int nodeSites = Layout::sitesOnNode();
35
36 //--------------------------------------
37 // Setup the communication index arrays
38 goffsets.resize(nodeSites);
39 srcnode.resize(nodeSites);
40 dstnode.resize(nodeSites);
41
42 const int my_node = Layout::nodeNumber();
43
44 // Loop over the sites on this node
45 for(int linear=0; linear < nodeSites; ++linear)
46 {
47 // Get the true lattice coord of this linear site index
48 multi1d<int> coord = Layout::siteCoords(my_node, linear);
49
50 // Source neighbor for this destination site
51 multi1d<int> fcoord = func(coord,+1);
52
53 // Destination neighbor receiving data from this site
54 // This functions as the inverse map
55 multi1d<int> bcoord = func(coord,-1);
56
57 int fnode = Layout::nodeNumber(fcoord);
58 int bnode = Layout::nodeNumber(bcoord);
59
60 // Source linear site and node
61 goffsets[linear] = Layout::linearSiteIndex(fcoord);
62 srcnode[linear] = fnode;
63
64 // Destination node
65 dstnode[linear] = bnode;
66
67#if QDP_DEBUG >= 3
68 QDP_info("linear=%d coord=%d %d %d %d fcoord=%d %d %d %d goffsets=%d",
69 linear,
70 coord[0], coord[1], coord[2], coord[3],
71 fcoord[0], fcoord[1], fcoord[2], fcoord[3],
72 goffsets[linear]);
73#endif
74 }
75
76#if QDP_DEBUG >= 3
77 {
78 for(int linear=0; linear < nodeSites; ++linear)
79 {
80 QDP_info("goffsets(%d) = %d",linear,goffsets(linear));
81 QDP_info("srcnode(%d) = %d",linear,srcnode(linear));
82 QDP_info("dstnode(%d) = %d",linear,dstnode(linear));
83 }
84 }
85#endif
86
87 // Return a list of the unique nodes in the list
88 // NOTE: my_node may be included as a unique node, so one extra
89 multi1d<int> srcenodes_tmp = uniquify_list(srcnode);
90 multi1d<int> destnodes_tmp = uniquify_list(dstnode);
91
92 // To simplify life, remove a possible occurance of my_node
93 // This may mean that the list could be empty afterwards, so that
94 // means mark offnodeP as false
95 int cnt_srcenodes = 0;
96 for(int i=0; i < srcenodes_tmp.size(); ++i)
97 if (srcenodes_tmp[i] != my_node)
98 ++cnt_srcenodes;
99
100 int cnt_destnodes = 0;
101 for(int i=0; i < destnodes_tmp.size(); ++i)
102 if (destnodes_tmp[i] != my_node)
103 ++cnt_destnodes;
104
105#if QDP_DEBUG >= 3
106 // Debugging
107 for(int i=0; i < srcenodes_tmp.size(); ++i)
108 QDP_info("srcenodes_tmp(%d) = %d",i,srcenodes_tmp[i]);
109
110 for(int i=0; i < destnodes_tmp.size(); ++i)
111 QDP_info("destnodes_tmp(%d) = %d",i,destnodes_tmp[i]);
112
113 QDP_info("cnt_srcenodes = %d", cnt_srcenodes);
114 QDP_info("cnt_destnodes = %d", cnt_destnodes);
115#endif
116
117
118 // A sanity check - both counts must be either 0 or non-zero
119 if (cnt_srcenodes > 0 && cnt_destnodes == 0)
120 QDP_error_exit("Map: some bizarre error - no dest nodes but have srce nodes");
121
122 if (cnt_srcenodes == 0 && cnt_destnodes > 0)
123 QDP_error_exit("Map: some bizarre error - no srce nodes but have dest nodes");
124
125 // If no srce/dest nodes, then we know no off-node communications
126 offnodeP = (cnt_srcenodes > 0) ? true : false;
127
128 //
129 // The rest of the routine is devoted to supporting off-node communications
130 // If there is not any communications, then return
131 //
132 if (! offnodeP)
133 {
134#if QDP_DEBUG >= 3
135 QDP_info("exiting Map::make");
136#endif
137 return;
138 }
139
140 // Finally setup the srce and dest nodes now without my_node
141 srcenodes.resize(cnt_srcenodes);
142 destnodes.resize(cnt_destnodes);
143
144 for(int i=0, j=0; i < srcenodes_tmp.size(); ++i)
145 if (srcenodes_tmp[i] != my_node)
146 srcenodes[j++] = srcenodes_tmp[i];
147
148 for(int i=0, j=0; i < destnodes_tmp.size(); ++i)
149 if (destnodes_tmp[i] != my_node)
150 destnodes[j++] = destnodes_tmp[i];
151
152#if QDP_DEBUG >= 3
153 // Debugging
154 for(int i=0; i < srcenodes.size(); ++i)
155 QDP_info("srcenodes(%d) = %d",i,srcenodes(i));
156
157 for(int i=0; i < destnodes.size(); ++i)
158 QDP_info("destnodes(%d) = %d",i,destnodes(i));
159#endif
160
161
162 // Run through the lists and find the number of each unique node
163 srcenodes_num.resize(srcenodes.size());
164 destnodes_num.resize(destnodes.size());
165
166 srcenodes_num = 0;
167 destnodes_num = 0;
168
169 for(int linear=0; linear < nodeSites; ++linear)
170 {
171 int this_node = srcnode[linear];
172 if (this_node != my_node)
173 for(int i=0; i < srcenodes_num.size(); ++i)
174 {
175 if (srcenodes[i] == this_node)
176 {
177 srcenodes_num[i]++;
178 break;
179 }
180 }
181
182 int that_node = dstnode[linear];
183 if (that_node != my_node)
184 for(int i=0; i < destnodes_num.size(); ++i)
185 {
186 if (destnodes[i] == that_node)
187 {
188 destnodes_num[i]++;
189 break;
190 }
191 }
192 }
193
194
195#if QDP_DEBUG >= 3
196 for(int i=0; i < destnodes.size(); ++i)
197 {
198 QDP_info("srcenodes(%d) = %d",i,srcenodes(i));
199 QDP_info("destnodes(%d) = %d",i,destnodes(i));
200 }
201
202 for(int i=0; i < destnodes_num.size(); ++i)
203 {
204 QDP_info("srcenodes_num(%d) = %d",i,srcenodes_num(i));
205 QDP_info("destnodes_num(%d) = %d",i,destnodes_num(i));
206 }
207#endif
208
209 // Implementation limitation in the Map::operator(). Only support
210 // a node sending data all to one node or no sending at all (offNodeP == false).
211 if (srcenodes.size() != 1)
212 QDP_error_exit("Map: for now only allow 1 destination node");
213
214 if (destnodes.size() != 1)
215 QDP_error_exit("Map: for now only allow receives from 1 node");
216
217
218 // Now make a small scatter array for the dest_buf so that when data
219 // is sent, it is put in an order the gather can pick it up
220 // If we allow multiple dest nodes, then soffsets here needs to be
221 // an array of arrays
222 soffsets.resize(destnodes_num[0]);
223
224 // Loop through sites on my *destination* node - here I assume all nodes have
225 // the same number of sites. Mimic the gather pattern needed on that node and
226 // set my scatter array to scatter into the correct site order
227 for(int i=0, si=0; i < nodeSites; ++i)
228 {
229 // Get the true lattice coord of this linear site index
230 multi1d<int> coord = Layout::siteCoords(destnodes[0], i);
231 multi1d<int> fcoord = func(coord,+1);
232 int fnode = Layout::nodeNumber(fcoord);
233 int fline = Layout::linearSiteIndex(fcoord);
234
235 if (fnode == my_node)
236 soffsets[si++] = fline;
237 }
238
239#if QDP_DEBUG >= 3
240 // Debugging
241 for(int i=0; i < soffsets.size(); ++i)
242 QDP_info("soffsets(%d) = %d",i,soffsets(i));
243#endif
244
245
246#if QDP_DEBUG >= 3
247 QDP_info("exiting Map::make");
248#endif
249}
250
251
252//------------------------------------------------------------------------
253// Message passing convenience routines
254//------------------------------------------------------------------------
255
256namespace QDPInternal
257{
259 void broadcast_str(std::string& result)
260 {
261 char *dd_tmp;
262 int lleng;
263
264 // Only primary node can grab string
265 if (Layout::primaryNode())
266 {
267 lleng = result.length();
268 }
269
270 // First must broadcast size of string
272
273 // Now every node can alloc space for string
274 dd_tmp = new char[lleng];
275 if( dd_tmp == 0x0 ) {
276 QDP_error_exit("Unable to allocate dd_tmp\n");
277 }
278
280 memcpy(dd_tmp, result.c_str(), lleng);
281
282 // Now broadcast char array out to all nodes
283 QDPInternal::broadcast((void *)dd_tmp, lleng);
284
285 // All nodes can now grab char array and make a string, but only
286 // need this on non-primary nodes
287 if (! Layout::primaryNode())
288 {
289 result.assign(dd_tmp, lleng);
290 }
291
292 // Clean-up and boogie
293 delete[] dd_tmp;
294 }
295
296
298 void route(void *buffer, int srce_node, int dest_node, int count)
299 {
300#if QDP_DEBUG >= 2
301 QDP_info("starting a route, count=%d, srcenode=%d destnode=%d",
302 count,srce_node,dest_node);
303#endif
304
305// QMP_route(buffer, count, srce_node, dest_node);
306 DML_route_bytes((char*)buffer, count, srce_node, dest_node);
307
308#if QDP_DEBUG >= 2
309 QDP_info("finished a route");
310#endif
311 }
312
314 void
315 sendToWait(void *send_buf, int dest_node, int count)
316 {
317#if QDP_DEBUG >= 2
318 QDP_info("starting a sendToWait, count=%d, destnode=%d", count,dest_node);
319#endif
320
321 QMP_msgmem_t request_msg = QMP_declare_msgmem(send_buf, count);
322 QMP_msghandle_t request_mh = QMP_declare_send_to(request_msg, dest_node, 0);
323
324 if (QMP_start(request_mh) != QMP_SUCCESS)
325 QDP_error_exit("sendToWait failed\n");
326
327 QMP_wait(request_mh);
328
329 QMP_free_msghandle(request_mh);
330 QMP_free_msgmem(request_msg);
331
332#if QDP_DEBUG >= 2
333 QDP_info("finished a sendToWait");
334#endif
335 }
336
338 void
339 recvFromWait(void *recv_buf, int srce_node, int count)
340 {
341#if QDP_DEBUG >= 2
342 QDP_info("starting a recvFromWait, count=%d, srcenode=%d", count, srce_node);
343#endif
344
345 QMP_msgmem_t request_msg = QMP_declare_msgmem(recv_buf, count);
346 QMP_msghandle_t request_mh = QMP_declare_receive_from(request_msg, srce_node, 0);
347
348 if (QMP_start(request_mh) != QMP_SUCCESS)
349 QDP_error_exit("recvFromWait failed\n");
350
351 QMP_wait(request_mh);
352
353 QMP_free_msghandle(request_mh);
354 QMP_free_msgmem(request_msg);
355
356#if QDP_DEBUG >= 2
357 QDP_info("finished a recvFromWait");
358#endif
359 }
360
361};
362
363
364
365//-----------------------------------------------------------------------
366// Compute simple NERSC-like checksum of a gauge field
367/*
368 * \ingroup io
369 *
370 * \param u gauge configuration ( Read )
371 *
372 * \return checksum
373 */
374
376 int mat_size)
377{
378 size_t size = sizeof(REAL32);
379 size_t su3_size = size*mat_size;
380 n_uint32_t checksum = 0; // checksum
381 const int nodeSites = Layout::sitesOnNode();
382
383 multi1d<multi1d<ColorMatrix> > sa(Nd); // extract gauge fields
384
385 for(int dd=0; dd<Nd; dd++) /* dir */
386 {
387 sa[dd].resize(nodeSites);
388 QDP_extract(sa[dd], u[dd], all);
389 }
390
391 char *chk_buf = new(nothrow) char[su3_size];
392 if( chk_buf == 0x0 ) {
393 QDP_error_exit("Unable to allocate chk_buf\n");
394 }
395
396 for(int linear=0; linear < nodeSites; ++linear)
397 {
398 for(int dd=0; dd<Nd; dd++) /* dir */
399 {
400 switch (mat_size)
401 {
402 case 12:
403 {
404 REAL32 su3[2][3][2];
405
406 for(int kk=0; kk<Nc; kk++) /* color */
407 for(int ii=0; ii<2; ii++) /* color */
408 {
409 Complex sitecomp = peekColor(sa[dd][linear],ii,kk);
410 su3[ii][kk][0] = toFloat(Real(real(sitecomp)));
411 su3[ii][kk][1] = toFloat(Real(imag(sitecomp)));
412 }
413
414 memcpy(chk_buf, &(su3[0][0][0]), su3_size);
415 }
416 break;
417
418 case 18:
419 {
420 REAL32 su3[3][3][2];
421
422 for(int kk=0; kk<Nc; kk++) /* color */
423 for(int ii=0; ii<Nc; ii++) /* color */
424 {
425 Complex sitecomp = peekColor(sa[dd][linear],ii,kk);
426 su3[ii][kk][0] = toFloat(Real(real(sitecomp)));
427 su3[ii][kk][1] = toFloat(Real(imag(sitecomp)));
428 }
429
430 memcpy(chk_buf, &(su3[0][0][0]), su3_size);
431 }
432 break;
433
434 default:
435 QDPIO::cerr << __func__ << ": unexpected size" << std::endl;
436 exit(1);
437 }
438
439 // Compute checksum
440 n_uint32_t* chk_ptr = (n_uint32_t*)chk_buf;
441 for(int i=0; i < mat_size*size/sizeof(n_uint32_t); ++i)
442 checksum += chk_ptr[i];
443 }
444 }
445
446 delete[] chk_buf;
447
448 // Get all nodes to contribute
449 QDPInternal::globalSumArray((unsigned int*)&checksum, 1); // g++ requires me to narrow the type to unsigned int
450
451 return checksum;
452}
453
454
455
456//-----------------------------------------------------------------------
457// Read a QCD archive file
458// Read a QCD (NERSC) Archive format gauge field
459/*
460 * \ingroup io
461 *
462 * \param cfg_in binary writer object ( Modify )
463 * \param u gauge configuration ( Modify )
464 */
465
466// This code looks like the scalar version...
467// Not fixed.
469 n_uint32_t& checksum, int mat_size, int float_size)
470{
471 ColorMatrix sitefield;
472 float su3[3][3][2];
473
474 checksum = 0;
475
476 // Find the location of each site and send to primary node
477 for(int site=0; site < Layout::vol(); ++site)
478 {
479 multi1d<int> coord = crtesn(site, Layout::lattSize());
480
481 for(int dd=0; dd<Nd; dd++) /* dir */
482 {
483 /* Read an fe variable and write it to the BE */
484 cfg_in.readArray((char *)&(su3[0][0][0]),sizeof(float), mat_size);
485 if (cfg_in.fail())
486 QDP_error_exit("Error reading configuration");
487
488 /* Reconstruct the third column if necessary */
489 if (mat_size == 12)
490 {
491 su3[2][0][0] = su3[0][1][0]*su3[1][2][0] - su3[0][1][1]*su3[1][2][1]
492 - su3[0][2][0]*su3[1][1][0] + su3[0][2][1]*su3[1][1][1];
493 su3[2][0][1] = su3[0][2][0]*su3[1][1][1] + su3[0][2][1]*su3[1][1][0]
494 - su3[0][1][0]*su3[1][2][1] - su3[0][1][1]*su3[1][2][0];
495
496 su3[2][1][0] = su3[0][2][0]*su3[1][0][0] - su3[0][2][1]*su3[1][0][1]
497 - su3[0][0][0]*su3[1][2][0] + su3[0][0][1]*su3[1][2][1];
498 su3[2][1][1] = su3[0][0][0]*su3[1][2][1] + su3[0][0][1]*su3[1][2][0]
499 - su3[0][2][0]*su3[1][0][1] - su3[0][2][1]*su3[1][0][0];
500
501 su3[2][2][0] = su3[0][0][0]*su3[1][1][0] - su3[0][0][1]*su3[1][1][1]
502 - su3[0][1][0]*su3[1][0][0] + su3[0][1][1]*su3[1][0][1];
503 su3[2][2][1] = su3[0][1][0]*su3[1][0][1] + su3[0][1][1]*su3[1][0][0]
504 - su3[0][0][0]*su3[1][1][1] - su3[0][0][1]*su3[1][1][0];
505 }
506
507 /* Copy into the big array */
508 for(int kk=0; kk<Nc; kk++) /* color */
509 {
510 for(int ii=0; ii<Nc; ii++) /* color */
511 {
512 Real re = su3[ii][kk][0];
513 Real im = su3[ii][kk][1];
514 Complex sitecomp = cmplx(re,im);
515 pokeColor(sitefield,sitecomp,ii,kk);
516
517 if (mat_size == 12)
518 {
519 /* If compressed ignore 3rd row for checksum */
520 if (ii < 2)
521 {
522 checksum += *(n_uint32_t*)(su3+(((ii)*3+kk)*2+0));
523 checksum += *(n_uint32_t*)(su3+(((ii)*3+kk)*2+1));
524 }
525 }
526 else
527 {
528 /* If uncompressed take everything for checksum */
529 checksum += *(n_uint32_t*)(su3+(((ii)*3+kk)*2+0));
530 checksum += *(n_uint32_t*)(su3+(((ii)*3+kk)*2+1));
531 }
532 }
533 }
534
535 pokeSite(u[dd], sitefield, coord);
536 }
537 }
538}
539
540
541
542//-----------------------------------------------------------------------
543// Write a QCD archive file
544// Write a QCD (NERSC) Archive format gauge field
545/*
546 * \ingroup io
547 *
548 * \param cfg_out binary writer object ( Modify )
549 * \param u gauge configuration ( Read )
550 */
552 int mat_size)
553{
554 ColorMatrix sitefield;
555 float su3[3][3][2];
556
557 // Find the location of each site and send to primary node
558 for(int site=0; site < Layout::vol(); ++site)
559 {
560 multi1d<int> coord = crtesn(site, Layout::lattSize());
561
562 for(int dd=0; dd<Nd; dd++) /* dir */
563 {
564 sitefield = peekSite(u[dd], coord);
565
566 if ( mat_size == 12 )
567 {
568 for(int kk=0; kk < Nc; kk++) /* color */
569 for(int ii=0; ii < Nc-1; ii++) /* color */
570 {
571 Complex sitecomp = peekColor(sitefield,ii,kk);
572 su3[ii][kk][0] = toFloat(Real(real(sitecomp)));
573 su3[ii][kk][1] = toFloat(Real(imag(sitecomp)));
574 }
575 }
576 else
577 {
578 for(int kk=0; kk < Nc; kk++) /* color */
579 for(int ii=0; ii < Nc; ii++) /* color */
580 {
581 Complex sitecomp = peekColor(sitefield,ii,kk);
582 su3[ii][kk][0] = toFloat(Real(real(sitecomp)));
583 su3[ii][kk][1] = toFloat(Real(imag(sitecomp)));
584 }
585 }
586
587 // Write a site variable
588 cfg_out.writeArrayPrimaryNode((char *)&(su3[0][0][0]),sizeof(float), mat_size);
589 }
590 }
591
592 if (cfg_out.fail())
593 QDP_error_exit("Error writing configuration");
594}
595
596} // namespace QDP;
Binary input base class.
Definition qdp_io.h:372
Binary writer base class.
Definition qdp_io.h:1010
MapFunc.
Definition qdp_map.h:32
void make(const MapFunc &func)
Actual constructor from a function object.
Container for a multi-dimensional 1D array.
Definition qdp_multi.h:25
int DML_route_bytes(char *buf, size_t size, int fromnode, int tonode)
OScalar< PScalar< PScalar< RComplex< REAL > > > > Complex
OScalar< PScalar< PColorMatrix< RComplex< REAL >, Nc > > > ColorMatrix
OScalar< PScalar< PScalar< RScalar< REAL > > > > Real
void QDP_extract(multi1d< OScalar< T > > &dest, const OLattice< T > &src, const Subset &s)
Copy data values from field src to array dest.
OLattice< T1 > & pokeSite(OLattice< T1 > &l, const OScalar< T1 > &r, const multi1d< int > &coord)
Insert site element.
OScalar< T1 > peekSite(const OScalar< T1 > &l, const multi1d< int > &coord)
Extract site element.
void readArchiv(BinaryReader &cfg_in, multi1d< LatticeColorMatrix > &u, n_uint32_t &checksum, int mat_size, int float_size)
Read a NERSC Gauge Connection Archive file.
TextWriter & operator<<(TextWriter &txt, const std::string &output)
Definition qdp_io.cc:283
void writeArchiv(BinaryWriter &cfg_out, const multi1d< LatticeColorMatrix > &u, int mat_size)
Writes a NERSC Gauge Connection Archive gauge configuration file.
float toFloat(const IScalar< T > &s)
QDP Real to float primitive in conversion routine.
Definition qdp_inner.h:1623
const int Nc
Definition qdp_params.h:25
const int Nd
Definition qdp_params.h:24
Subset all
Default all subset.
Definition qdp_subset.cc:16
unsigned int n_uint32_t
int nodeNumber()
Returns the node number of this node.
int linearSiteIndex(int site)
The linearized site index for the corresponding lexicographic site.
int sitesOnNode()
Subgrid lattice volume.
multi1d< int > siteCoords(int node, int index) QDP_CONST
Reconstruct the lattice coordinate from the node and site number.
const multi1d< int > & lattSize()
Virtual grid (problem grid) lattice size.
int vol()
Total lattice volume.
bool primaryNode()
Returns whether this is the primary node.
StandardOutputStream cerr
Definition qdp_stdio.cc:22
void broadcast(T &dest)
Broadcast from primary node to all other nodes.
void sendToWait(void *send_buf, int dest_node, int count)
Send to another node (wait).
void route(void *buffer, int srce_node, int dest_node, int count)
Route to another node (blocking).
void recvFromWait(void *recv_buf, int srce_node, int count)
Receive from another node (wait).
void broadcast_str(std::string &result)
Broadcast a string from primary node to all other nodes.
void globalSumArray(unsigned int *dest, int len)
Wrapper to get a functional unsigned global sum.
Yet another random number generator.
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
MakeReturn< UnaryNode< FnPeekColorMatrix, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, C1 >::Expression_t peekColor(const QDPExpr< T1, C1 > &l, int row, int col)
Definition qdp_newops.h:161
void QDP_error_exit(const char *format,...)
Simple error display and abort routine.
Definition qdp_util.cc:93
multi1d< int > uniquify_list(const multi1d< int > &ll)
Unique-ify a list.
Definition qdp_util.cc:128
C1 & pokeColor(QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r, int row, int col)
Definition qdp_newops.h:360
MakeReturn< BinaryNode< FnCmplx, typenameCreateLeaf< QDPType< T1, C1 > >::Leaf_t, typenameCreateLeaf< QDPExpr< T2, C2 > >::Leaf_t >, typenameBinaryReturn< C1, C2, FnCmplx >::Type_t >::Expression_t cmplx(const QDPType< T1, C1 > &l, const QDPExpr< T2, C2 > &r)
Definition qdp.h:2348
n_uint32_t computeChecksum(const multi1d< LatticeColorMatrix > &u, int mat_size)
Compute simple NERSC-like checksum of a gauge field.
MakeReturn< UnaryNode< FnImag, typenameCreateLeaf< QDPExpr< T1, C1 > >::Leaf_t >, typenameUnaryReturn< C1, FnImag >::Type_t >::Expression_t imag(const QDPExpr< T1, C1 > &l)
Definition qdp.h:4985
multi1d< int > crtesn(int ipos, const multi1d< int > &latt_size)
Decompose a lexicographic site into coordinates.
int QDP_info(const char *format,...)
Simple information display routine.
Definition qdp_util.cc:43
Primary include file for QDP.