1 #ifndef BDEF_H
2 #define BDEF_H 1
3 
4 /*
5  * Include the system dependant and user defined stuff
6  */
7 #include "Bconfig.h"
8 
9 /*
10  * Data type defining a scope for the BLACS
11  */
12 typedef struct bLaCsScOpE BLACSSCOPE;
13 struct bLaCsScOpE
14 {
15    MPI_Comm comm;
16    int ScpId, MaxId, MinId;
17    int Np, Iam;
18 };
19 /*
20  * Data type defining a context for the BLACS
21  */
22 typedef struct bLaCsCoNtExT BLACSCONTEXT;
23 struct bLaCsCoNtExT
24 {
25    BLACSSCOPE rscp, cscp, ascp, pscp; /* row, column, all, and pt2pt scopes */
26    BLACSSCOPE *scp;                   /* pointer to present scope */
27    int TopsRepeat;                    /* Use only repeatable topologies? */
28    int TopsCohrnt;                    /* Use only coherent topologies? */
29    int Nb_bs, Nr_bs;           /* for bcast general tree and multiring tops */
30    int Nb_co, Nr_co;           /* for combine general tree and multiring tops */
31 };
32 
33 /*
34  *  Define the fortran data types COMPLEX*8 (SCOMPLEX)
35  *  and COMPLEX*16 (DCOMPLEX).
36  */
37 typedef struct {double r, i;} DCOMPLEX;
38 typedef struct {float r, i;} SCOMPLEX;
39 
40 /*
41  *  These variables will be defined to be MPI datatypes for complex and double
42  *  complex if we are using the C interface to MPI.  If we use the fortran
43  *  interface, we need to declare the contants array.  I'm too lazy to declare
44  *  these guys external in every file that needs them.
45  */
46 #ifndef GlobalVars
47    extern int *BI_COMM_WORLD;
48 #endif
49 
50 /*
51  *  Definition of buffer type for BLACS' asynchronous operations
52  */
53 typedef struct bLaCbUfF BLACBUFF;
54 struct bLaCbUfF
55 {
56    char *Buff;             /* send/recv buffer */
57    int Len;                /* length of buffer in bytes */
58    int nAops;              /* number of asynchronous operations out of buff */
59    MPI_Request *Aops;   /* list of async. operations out of buff */
60    MPI_Datatype dtype;  /* data type of buffer */
61    int N;                  /* number of elements of data type in buff */
62    BLACBUFF *prev, *next;  /* pointer to the other BLACBUFF in queue */
63 };
64 
65 /*
66  * Pointer to the combine's vector-vector functions
67  */
68 typedef void (*VVFUNPTR)(int, char *, char *);
69 typedef void (*SDRVPTR)(BLACSCONTEXT *, int, int, BLACBUFF *);
70 
71 
72 #define BI_DistType                  unsigned short
73 #define BI_MpiDistType               MPI_UNSIGNED_SHORT
74 
75 #define BUFFALIGN    8      /* force all buffers to 8 byte alignment */
76 #define BANYNODE     MPI_ANY_SOURCE
77 #define PT2PTID      9976   /* TAG used for point to point */
78 #define NOTINCONTEXT -1  /* Indicates node called gridmap, but not in grid */
79 #define MAXNCTXT     10      /* initial guess at max # of contexts */
80 #define MAXNSYSCTXT  10   /* initial guess at max # of system context */
81 #define AOPDONE      MPI_REQUEST_NULL
82 #define BUFWAIT      120      /* Length of time to wait for emergency buff */
83 
84 /*
85  * Error codes
86  */
87 #define NORV 1          /* No receiver (only 1 proc in scoped op) */
88 #define NPOW2 2         /* Number of procs is not a power of 2 */
89 #define BADSCP 3        /* Scope not row, column or all */
90 
91 /*
92  * Data types
93  */
94 #define INTEGER   3
95 #define SINGLE    4
96 #define DOUBLE    6
97 #define COMPLEX8  5
98 #define COMPLEX16 7
99 
100 #define FULLCON 0      /* top is fully connected */
101 
102 /*
103  * Routine types
104  */
105 #define RT_SD    1
106 #define RT_RV    2
107 #define RT_BS    3
108 #define RT_BR    4
109 #define RT_COMB  5
110 
111 /*
112  * Legal WHAT values for BLACS_SET
113  */
114 #define SGET_SYSCONTXT    0
115 #define SGET_MSGIDS       1
116 #define SGET_DEBUGLVL     2
117 #define SGET_BLACSCONTXT 10
118 #define SGET_NR_BS       11
119 #define SGET_NB_BS       12
120 #define SGET_NR_CO       13
121 #define SGET_NB_CO       14
122 #define SGET_TOPSREPEAT  15
123 #define SGET_TOPSCOHRNT  16
124 
125 /*
126  * These are prototypes for error and warning functions -- I don't want
127  * to prototype them in each routine.
128  */
129 void BI_BlacsWarn(int ConTxt, int line, char *file, char *form, ...);
130 void BI_BlacsErr(int ConTxt, int line, char *file, char *form, ...);
131 int BI_ContxtNum(BLACSCONTEXT *ctxt);
132 
133 /*
134  * If we've got an ANSI standard C compiler, we can use void pointers...
135  */
136 #define BVOID void
137 
138 
139 /*
140  * ========================================================================
141  *     PREPROCESSOR MACRO FUNCTIONS USED FOR OPTIMIZATION & CONVENIENCE
142  * ========================================================================
143  */
144 
145 #define Mlowcase(C) ( ((C) > 64 && (C) < 91) ? (C) | 32 : (C) )
146 
147 /*
148  * Slightly modified gridinfo substitute
149  */
150 #define Mgridinfo(ctxt, Ng0, nprow0, npcol0, myrow0, mycol0)\
151 {\
152    (Ng0) = (ctxt)->ascp.Np;\
153    (nprow0) = (ctxt)->cscp.Np;\
154    (npcol0) = (ctxt)->rscp.Np;\
155    (myrow0) = (ctxt)->cscp.Iam;\
156    (mycol0) = (ctxt)->rscp.Iam;\
157 }
158 
159 /*
160  * These routines return coordinates based on nodes number, or node number
161  * based on coordinates.  Those routines with v after the M return virtual
162  * nodes numbers (i.e., in respect to the grid, not physical node numbers)
163  * based on grid coordinates, or grid coordinates based on virtual node numbers.
164  */
165 #define Mpcoord(ctxt, node, prow, pcol)\
166 {\
167    (prow) = (node) / (ctxt)->rscp.Np;\
168    (pcol) = (node) % (ctxt)->rscp.Np;\
169 }
170 #define Mvpcoord(ctxt, node, prow, pcol) \
171         Mpcoord((ctxt), (node), (prow), (pcol));
172 
173 #define Mkpnum(ctxt, prow, pcol)  ( (prow)*(ctxt)->rscp.Np+(pcol) )
174 #define Mvkpnum(ctxt, prow, pcol) ( (prow)*(ctxt)->rscp.Np+(pcol) )
175 
176 /*
177  * This macro returns scoped message ID's.
178  */
179 #define Mscopeid(ctxt) (ctxt)->scp->ScpId; \
180    if (++(ctxt)->scp->ScpId == (ctxt)->scp->MaxId) \
181       (ctxt)->scp->ScpId = (ctxt)->scp->MinId;
182 
183 /*
184  *  Get context, and check for validity if debug level is high
185  */
186 #if (BlacsDebugLvl > 0)
187 #define MGetConTxt(Context, ctxtptr)\
188 {\
189    extern BLACSCONTEXT **BI_MyContxts;\
190    extern int BI_MaxNCtxt;\
191    if ( ((Context) >= BI_MaxNCtxt) || ((Context) < 0) )\
192       BI_BlacsErr(-1, __LINE__, __FILE__, "Invalid context handle: %d",\
193                   (Context));\
194    else if (BI_MyContxts[(Context)] == NULL)\
195       BI_BlacsErr(-1, __LINE__, __FILE__, "Invalid context, handle=%d",\
196                   (Context));\
197    (ctxtptr) = BI_MyContxts[(Context)];\
198 }
199 #else
200 #define MGetConTxt(Context, ctxtptr)\
201 {\
202    extern BLACSCONTEXT **BI_MyContxts;\
203    (ctxtptr) = BI_MyContxts[(Context)];\
204 }
205 #endif
206 /*
207  * This macro handles MPI errors
208  */
209 #if(BlacsDebugLvl > 0)
210 #define Mmpierror(ierr, rout, ctxt, line, file) \
211 { \
212    if ( (ierr) != BI_MPI_SUCCESS )\
213       BI_BlacsErr(BI_ContxtNum((ctxt)), (line), (file), \
214                   "MPI error %d on call to %s", (ierr), (rout)); \
215 }
216 #else
217 #define Mmpierror(ierr, rout, ctxt, line, file)
218 #endif
219 /*
220  * A small macro useful for debugging
221  */
222 #define ErrPrint \
223 { \
224    extern int BI_Iam; \
225    fprintf(stderr, "%d: line %d of file %s\n", BI_Iam, __LINE__, __FILE__); \
226 }
227 
228 /*
229  * These macros allow for the funky function declarations and character handling
230  * needed on the CRAY to have a C routine callable from fortran
231  */
232 #define F_VOID_FUNC void
233 #define F_INT_FUNC  int
234 #define F_DOUBLE_FUNC double
235 
236 #if (INTFACE == C_CALL)
237 
238 #define F2C_CharTrans(c) *(c)
239 
240 #else
241 
242 #ifdef CRAY
243 #define F2C_CharTrans(c) *( _fcdtocp((c)) )
244 #define F_CHAR      _fcd
245 #else
246 #define F2C_CharTrans(c) *(c)
247 #define F_CHAR      char *
248 #endif
249 
250 #endif
251 
252 /*
253  *  These macros allow for accessing values and addresses of parameters, which
254  *  will be pointers if we're using fortran, and values if we're using C.
255  */
256 #if (INTFACE == C_CALL)
257 #define Mpval(para) (para)
258 #define Mpaddress(para) (&(para))
259 #define Mwalltime Cdwalltime00
260 #else
261 #define Mpval(para) (*(para))
262 #define Mpaddress(para) (para)
263 #define Mwalltime dwalltime00_
264 #endif
265 
266 /*
267  * Real and complex absolute values
268  */
269 #define Rabs(x) ( (x) < 0 ? (x) * -1 : (x) )
270 #define Cabs(z) ( (((z).i) < 0 ? ((z).i) * -1 : ((z).i)) + (((z).r) < 0 ? ((z).r) * -1 : ((z).r)) )
271 
272 /*
273  * Figures the length of packed trapezoidal matrix
274  */
275 #define trsize(diag, m, n, bytes, length)\
276 {\
277    if ( (diag) == 'u' ) (length) = 1;\
278    else (length) = 0;\
279    if ( (m) > (n) )\
280       (length) = ( (n) * ( (m) - (n) ) + ( (n)*(n) ) - ( (n)*(n) )/2 +\
281                    (n)/2 - (n) * (length) ) * (bytes);\
282    else\
283       (length) = ( (m) * ( (n) - (m) ) + ( (m)*(m) ) - ( (m)*(m) )/2 +\
284                    (m)/2 - (m) * (length) ) * (bytes);\
285 }
286 
287 /*
288  * These macros call the correct packing/unpacking routines
289  */
290 #define BI_cmvcopy(m, n, A, lda, buff) \
291         BI_smvcopy(2*(m), (n), (float *) (A), 2*(lda), (float *) (buff))
292 #define BI_cvmcopy(m, n, A, lda, buff) \
293         BI_svmcopy(2*(m), (n), (float *) (A), 2*(lda), (float *) (buff))
294 #define BI_zmvcopy(m, n, A, lda, buff) \
295         BI_dmvcopy(2*(m), (n), (double *) (A), 2*(lda), (double *) (buff))
296 #define BI_zvmcopy(m, n, A, lda, buff) \
297         BI_dvmcopy(2*(m), (n), (double *) (A), 2*(lda), (double *) (buff))
298 
299 /*
300  * This macro avoids freeing types when the zero-byte workaround was applied
301  */
302 #ifdef ZeroByteTypeBug
303 #define BI_MPI_TYPE_FREE(t) (*(t) != MPI_BYTE ? MPI_Type_free(t) : 0)
304 #else
305 #define BI_MPI_TYPE_FREE(t) MPI_Type_free(t)
306 #endif
307 
308 #if (FORTRAN_CALL_C == NOCHANGE)
309 /*
310  * These defines set up the naming scheme required to have a fortran
311  * routine call a C routine (which is what the BLACS are written in)
312  * for the following Fortran to C interface:
313  *           FORTRAN CALL               C DECLARATION
314  *           call dgebs2d(...)          void dgebs2d(...)
315  */
316 
317 /*
318  * Support routines
319  */
320 #define blacs_pinfo_                   blacs_pinfo
321 #define blacs_setup_                   blacs_setup
322 #define setpvmtids_                    setpvmtids
323 #define blacs_set_                     blacs_set
324 #define blacs_get_                     blacs_get
325 #define blacs_gridinit_                blacs_gridinit
326 #define blacs_gridmap_                 blacs_gridmap
327 #define ksendid_                       ksendid
328 #define krecvid_                       krecvid
329 #define kbsid_                         kbsid
330 #define kbrid_                         kbrid
331 #define blacs_freebuff_                blacs_freebuff
332 #define blacs_gridexit_                blacs_gridexit
333 #define blacs_abort_                   blacs_abort
334 #define blacs_exit_                    blacs_exit
335 #define blacs_gridinfo_                blacs_gridinfo
336 #define blacs_pnum_                    blacs_pnum
337 #define blacs_pcoord_                  blacs_pcoord
338 #define dcputime00_                    dcputime00
339 #define dwalltime00_                   dwalltime00
340 #define blacs_barrier_                 blacs_barrier
341 
342 /*
343  * Main, type dependent, routines
344  */
345 #define igesd2d_   igesd2d
346 #define igerv2d_   igerv2d
347 #define igebs2d_   igebs2d
348 #define igebr2d_   igebr2d
349 #define itrsd2d_   itrsd2d
350 #define itrrv2d_   itrrv2d
351 #define itrbs2d_   itrbs2d
352 #define itrbr2d_   itrbr2d
353 #define igsum2d_   igsum2d
354 #define igamx2d_   igamx2d
355 #define igamn2d_   igamn2d
356 #define sgesd2d_   sgesd2d
357 #define sgerv2d_   sgerv2d
358 #define sgebs2d_   sgebs2d
359 #define sgebr2d_   sgebr2d
360 #define strsd2d_   strsd2d
361 #define strrv2d_   strrv2d
362 #define strbs2d_   strbs2d
363 #define strbr2d_   strbr2d
364 #define sgsum2d_   sgsum2d
365 #define sgamx2d_   sgamx2d
366 #define sgamn2d_   sgamn2d
367 #define dgesd2d_   dgesd2d
368 #define dgerv2d_   dgerv2d
369 #define dgebs2d_   dgebs2d
370 #define dgebr2d_   dgebr2d
371 #define dtrsd2d_   dtrsd2d
372 #define dtrrv2d_   dtrrv2d
373 #define dtrbs2d_   dtrbs2d
374 #define dtrbr2d_   dtrbr2d
375 #define dgsum2d_   dgsum2d
376 #define dgamx2d_   dgamx2d
377 #define dgamn2d_   dgamn2d
378 #define cgesd2d_   cgesd2d
379 #define cgerv2d_   cgerv2d
380 #define cgebs2d_   cgebs2d
381 #define cgebr2d_   cgebr2d
382 #define ctrsd2d_   ctrsd2d
383 #define ctrrv2d_   ctrrv2d
384 #define ctrbs2d_   ctrbs2d
385 #define ctrbr2d_   ctrbr2d
386 #define cgsum2d_   cgsum2d
387 #define cgamx2d_   cgamx2d
388 #define cgamn2d_   cgamn2d
389 #define zgesd2d_   zgesd2d
390 #define zgerv2d_   zgerv2d
391 #define zgebs2d_   zgebs2d
392 #define zgebr2d_   zgebr2d
393 #define ztrsd2d_   ztrsd2d
394 #define ztrrv2d_   ztrrv2d
395 #define ztrbs2d_   ztrbs2d
396 #define ztrbr2d_   ztrbr2d
397 #define zgsum2d_   zgsum2d
398 #define zgamx2d_   zgamx2d
399 #define zgamn2d_   zgamn2d
400 
401 #elif (FORTRAN_CALL_C == UPCASE)
402 /*
403  * These defines set up the naming scheme required to have a fortran
404  * routine call a C routine (which is what the BLACS are written in)
405  * for the following Fortran to C interface:
406  *           FORTRAN CALL               C DECLARATION
407  *           call dgebs2d(...)          void DGEBS2D(...)
408  */
409 /*
410  * Support routines
411  */
412 #define blacs_pinfo_                   BLACS_PINFO
413 #define blacs_setup_                   BLACS_SETUP
414 #define setpvmtids_                    SETPVMTIDS
415 #define blacs_set_                     BLACS_SET
416 #define blacs_get_                     BLACS_GET
417 #define blacs_gridinit_                BLACS_GRIDINIT
418 #define blacs_gridmap_                 BLACS_GRIDMAP
419 #define ksendid_                       KSENDID
420 #define krecvid_                       KRECVID
421 #define kbsid_                         KBSID
422 #define kbrid_                         KBRID
423 #define blacs_freebuff_                BLACS_FREEBUFF
424 #define blacs_gridexit_                BLACS_GRIDEXIT
425 #define blacs_abort_                   BLACS_ABORT
426 #define blacs_exit_                    BLACS_EXIT
427 #define blacs_gridinfo_                BLACS_GRIDINFO
428 #define blacs_pnum_                    BLACS_PNUM
429 #define blacs_pcoord_                  BLACS_PCOORD
430 #define dcputime00_                    DCPUTIME00
431 #define dwalltime00_                   DWALLTIME00
432 #define blacs_barrier_                 BLACS_BARRIER
433 
434 /*
435  * Main, type dependent, routines
436  */
437 #define igesd2d_   IGESD2D
438 #define igerv2d_   IGERV2D
439 #define igebs2d_   IGEBS2D
440 #define igebr2d_   IGEBR2D
441 #define itrsd2d_   ITRSD2D
442 #define itrrv2d_   ITRRV2D
443 #define itrbs2d_   ITRBS2D
444 #define itrbr2d_   ITRBR2D
445 #define igsum2d_   IGSUM2D
446 #define igamx2d_   IGAMX2D
447 #define igamn2d_   IGAMN2D
448 #define sgesd2d_   SGESD2D
449 #define sgerv2d_   SGERV2D
450 #define sgebs2d_   SGEBS2D
451 #define sgebr2d_   SGEBR2D
452 #define strsd2d_   STRSD2D
453 #define strrv2d_   STRRV2D
454 #define strbs2d_   STRBS2D
455 #define strbr2d_   STRBR2D
456 #define sgsum2d_   SGSUM2D
457 #define sgamx2d_   SGAMX2D
458 #define sgamn2d_   SGAMN2D
459 #define dgesd2d_   DGESD2D
460 #define dgerv2d_   DGERV2D
461 #define dgebs2d_   DGEBS2D
462 #define dgebr2d_   DGEBR2D
463 #define dtrsd2d_   DTRSD2D
464 #define dtrrv2d_   DTRRV2D
465 #define dtrbs2d_   DTRBS2D
466 #define dtrbr2d_   DTRBR2D
467 #define dgsum2d_   DGSUM2D
468 #define dgamx2d_   DGAMX2D
469 #define dgamn2d_   DGAMN2D
470 #define cgesd2d_   CGESD2D
471 #define cgerv2d_   CGERV2D
472 #define cgebs2d_   CGEBS2D
473 #define cgebr2d_   CGEBR2D
474 #define ctrsd2d_   CTRSD2D
475 #define ctrrv2d_   CTRRV2D
476 #define ctrbs2d_   CTRBS2D
477 #define ctrbr2d_   CTRBR2D
478 #define cgsum2d_   CGSUM2D
479 #define cgamx2d_   CGAMX2D
480 #define cgamn2d_   CGAMN2D
481 #define zgesd2d_   ZGESD2D
482 #define zgerv2d_   ZGERV2D
483 #define zgebs2d_   ZGEBS2D
484 #define zgebr2d_   ZGEBR2D
485 #define ztrsd2d_   ZTRSD2D
486 #define ztrrv2d_   ZTRRV2D
487 #define ztrbs2d_   ZTRBS2D
488 #define ztrbr2d_   ZTRBR2D
489 #define zgsum2d_   ZGSUM2D
490 #define zgamx2d_   ZGAMX2D
491 #define zgamn2d_   ZGAMN2D
492 
493 #elif (FORTRAN_CALL_C == FCISF2C)
494 /*
495  * These defines set up the naming scheme required to have a fortran
496  * routine call a C routine (which is what the BLACS are written in)
497  * for systems where the fortran "compiler" is actually f2c (a fortran
498  * to C conversion utility).
499  */
500 /*
501  * Initialization routines
502  */
503 #define blacs_pinfo_    blacs_pinfo__
504 #define blacs_setup_    blacs_setup__
505 #define blacs_set_      blacs_set__
506 #define blacs_get_      blacs_get__
507 #define blacs_gridinit_ blacs_gridinit__
508 #define blacs_gridmap_  blacs_gridmap__
509 /*
510  * Destruction routines
511  */
512 #define blacs_freebuff_ blacs_freebuff__
513 #define blacs_gridexit_ blacs_gridexit__
514 #define blacs_abort_    blacs_abort__
515 #define blacs_exit_     blacs_exit__
516 /*
517  * Informational & misc.
518  */
519 #define blacs_gridinfo_ blacs_gridinfo__
520 #define blacs_pnum_     blacs_pnum__
521 #define blacs_pcoord_   blacs_pcoord__
522 #define blacs_barrier_  blacs_barrier__
523 
524 #endif
525 
526 
527 #endif
528