SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pitrmr2.c
Go to the documentation of this file.
1#include "redist.h"
2/* $Id: pitrmr2.c,v 1.1.1.1 2000/02/15 18:04:08 susan Exp $
3 *
4 * some functions used by the pitrmr2d routine see file pitrmr.c for more
5 * documentation.
6 *
7 * Created March 1993 by B. Tourancheau (See sccs for modifications). */
8#define static2 static
9#if defined(Add_) || defined(f77IsF2C)
10#define fortran_mr2d pitrmr2do_
11#define fortran_mr2dnew pitrmr2d_
12#elif defined(UpCase)
13#define fortran_mr2dnew PITRMR2D
14#define fortran_mr2d PITRMR2DO
15#define icopy_ ICOPY
16#define ilacpy_ ILACPY
17#else
18#define fortran_mr2d pitrmr2do
19#define fortran_mr2dnew pitrmr2d
20#define icopy_ icopy
21#define ilacpy_ ilacpy
22#endif
23#define Clacpy Citrlacpy
24void Clacpy();
25typedef struct {
26 Int desctype;
27 Int ctxt;
28 Int m;
29 Int n;
30 Int nbrow;
31 Int nbcol;
32 Int sprow;
33 Int spcol;
34 Int lda;
35} MDESC;
36#define BLOCK_CYCLIC_2D 1
37typedef struct {
38 Int gstart;
39 Int len;
40} IDESC;
41#define SHIFT(row,sprow,nbrow) ((row)-(sprow)+ ((row) >= (sprow) ? 0 : (nbrow)))
42#define max(A,B) ((A)>(B)?(A):(B))
43#define min(A,B) ((A)>(B)?(B):(A))
44#define DIVUP(a,b) ( ((a)-1) /(b)+1)
45#define ROUNDUP(a,b) (DIVUP(a,b)*(b))
46#ifdef MALLOCDEBUG
47#define malloc mymalloc
48#define free myfree
49#define realloc myrealloc
50#endif
51/* Cblacs */
52extern void Cblacs_pcoord();
54extern void Csetpvmtids();
55extern void Cblacs_get();
56extern void Cblacs_pinfo();
57extern void Cblacs_gridinfo();
58extern void Cblacs_gridinit();
59extern void Cblacs_exit();
60extern void Cblacs_gridexit();
61extern void Cblacs_setup();
62extern void Cigebs2d();
63extern void Cigebr2d();
64extern void Cigesd2d();
65extern void Cigerv2d();
66extern void Cigsum2d();
67extern void Cigamn2d();
68extern void Cigamx2d();
69extern void Cigesd2d();
70extern void Cigerv2d();
71/* lapack */
72void ilacpy_();
73/* aux fonctions */
75extern void *mr2d_malloc();
76extern Int ppcm();
77extern Int localsize();
80extern void paramcheck();
81/* tools and others function */
82#define scanD0 itrscanD0
83#define dispmat itrdispmat
84#define setmemory itrsetmemory
85#define freememory itrfreememory
86#define scan_intervals itrscan_intervals
87extern void scanD0();
88extern void dispmat();
89extern void setmemory();
90extern void freememory();
91extern Int scan_intervals();
92extern void Cpitrmr2do();
93extern void Cpitrmr2d();
94/* some defines for Cpitrmr2do */
95#define SENDBUFF 0
96#define RECVBUFF 1
97#define SIZEBUFF 2
98#if 0
99#define DEBUG
100#endif
101#ifndef DEBUG
102#define NDEBUG
103#endif
104#include <stdio.h>
105#include <stdlib.h>
106#include <string.h>
107#include <assert.h>
108#include <ctype.h>
109/* Created March 1993 by B. Tourancheau (See sccs for modifications). */
110/************************************************************************/
111/* Set the memory space with the malloc function */
112void
113setmemory(Int **adpointer, Int blocksize)
114{
115 assert(blocksize >= 0);
116 if (blocksize == 0) {
117 *adpointer = NULL;
118 return;
119 }
120 *adpointer = (Int *) mr2d_malloc(
121 blocksize * sizeof(Int));
122}
123/******************************************************************/
124/* Free the memory space after the malloc */
125void
126freememory(Int *ptrtobefreed)
127{
128 if (ptrtobefreed == NULL)
129 return;
130 free((char *) ptrtobefreed);
131}
132/* extern functions for intersect() extern icopy_(); */
133/**************************************************************/
134/* return the number of elements int the column after i and the distance of
135 * the first one from i, i,j can be negative out of borns, the number of
136 * elements returned can be negative (means 0) */
138insidemat(uplo, diag, i, j, m, n, offset)
139 Int m, n, i, j; /* coordonnees de depart, taille de la sous-matrice */
140 char *uplo, *diag;
141 Int *offset;
142{
143 /* tests outside mxn */
144 assert(j >= 0 && j < n);
145 assert(i >= 0);
146 if (toupper(*uplo) == 'U') {
147 Int nbline; /* number of lines in the j_th column */
148 Int virtualnbline; /* number of line if we were not limited by m */
149 *offset = 0;
150 virtualnbline = max(m - n, 0) + j + (toupper(*diag) == 'N');
151 nbline = min(virtualnbline, m);
152 return nbline - i;
153 } else {
154 Int firstline; /* first line in the j_th column */
155 Int diagcol; /* column where the diag begin */
156 Int virtualline; /* virtual first line if the matrix was extended with
157 * negative indices */
158 Int off;
159 diagcol = max(n - m, 0);;
160 virtualline = j - diagcol + (toupper(*diag) == 'U');
161 firstline = max(0, virtualline);
162 off = max(firstline - i, 0);
163 *offset = off;
164 i += off;
165 return m - i;
166 }
167}/* insidemat() */
168/********************************************************************/
169/* Execute an action on the local memories when an intersection occurs (the
170 * action can be the filling of the memory buffer, the count of the memory
171 * buffer size or the setting of the memory with the element received) */
172static2 void
173intersect(char *uplo, char *diag,
174 Int j, Int start, Int end,
175 Int action,
176 Int *ptrsizebuff, Int **pptrbuff, Int *ptrblock,
177 Int m, Int n,
178 MDESC *ma, Int ia, Int ja, Int templateheight0, Int templatewidth0,
179 MDESC *mb, Int ib, Int jb, Int templateheight1, Int templatewidth1)
180/* Execute the action on the local memory for the current interval and
181 * increment pptrbuff and ptrsizebuff of the intervalsize */
182/* Notice that if the interval is contigous in the virtual matrice, it is
183 * also contigous in the real one ! */
184{
185 /* int un = 1; only when we use dcopy instead of memcpy */
186 Int *ptrstart;
187 Int offset, nbline;
188 Int intervalsize;
189 assert(start < end);
190 assert(j >= 0 && j < n);
191 nbline =
192 insidemat(uplo, diag, start, j, m, n, &offset);
193 if (nbline <= 0)
194 return;
195 start += offset;
196 if (start >= end)
197 return;
198 intervalsize = min(end - start, nbline);
199 (*ptrsizebuff) += intervalsize;
200 switch (action) {
201 case SENDBUFF: /* fill buff with local elements to be sent */
202 ptrstart = ptrblock + localindice(start + ia, j + ja,
203 templateheight0, templatewidth0, ma);
204 memcpy((char *) (*pptrbuff), (char *) ptrstart,
205 intervalsize * sizeof(Int));
206 /* icopy_(&intervalsize, (char *) (ptrstart), &un, (char *) (*pptrbuff),
207 * &un); */
208 (*pptrbuff) += intervalsize;
209 break;
210 case RECVBUFF: /* fill local memory with the values received */
211 ptrstart = ptrblock + localindice(start + ib, j + jb,
212 templateheight1, templatewidth1, mb);
213 memcpy((char *) ptrstart, (char *) (*pptrbuff),
214 intervalsize * sizeof(Int));
215 /* icopy_(&intervalsize, (char *) (*pptrbuff), &un, (char *) (ptrstart),
216 * &un); */
217 (*pptrbuff) += intervalsize;
218 break;
219 case SIZEBUFF: /* computation of sizebuff */
220 break;
221 default:
222 printf("action is %d outside the scope of the case [0..2] !! \n ", action);
223 exit(0);
224 break;
225 }; /* switch (action) */
226}/* intersect() */
227/* scan_intervals: scans two distributions in one dimension, and compute the
228 * intersections on the local processor. result must be long enough to
229 * contains the result that are stocked in IDESC structure, the function
230 * returns the number of intersections found */
231Int
232scan_intervals(type, ja, jb, n, ma, mb, q0, q1, col0, col1,
233 result)
234 char type;
235 Int ja, jb, n, q0, q1, col0, col1;
236 MDESC *ma, *mb;
237 IDESC *result;
238{
239 Int offset, j0, j1, templatewidth0, templatewidth1, nbcol0, nbcol1;
240 Int l; /* local indice on the beginning of the interval */
241 assert(type == 'c' || type == 'r');
242 nbcol0 = (type == 'c' ? ma->nbcol : ma->nbrow);
243 nbcol1 = (type == 'c' ? mb->nbcol : mb->nbrow);
244 templatewidth0 = q0 * nbcol0;
245 templatewidth1 = q1 * nbcol1;
246 {
247 Int sp0 = (type == 'c' ? ma->spcol : ma->sprow);
248 Int sp1 = (type == 'c' ? mb->spcol : mb->sprow);
249 j0 = SHIFT(col0, sp0, q0) * nbcol0 - ja;
250 j1 = SHIFT(col1, sp1, q1) * nbcol1 - jb;
251 }
252 offset = 0;
253 l = 0;
254 /* a small check to verify that the submatrix begin inside the first block
255 * of the original matrix, this done by a sort of coordinate change at the
256 * beginning of the Cpitrmr2d */
257 assert(j0 + nbcol0 > 0);
258 assert(j1 + nbcol1 > 0);
259 while ((j0 < n) && (j1 < n)) {
260 Int end0, end1;
261 Int start, end;
262 end0 = j0 + nbcol0;
263 end1 = j1 + nbcol1;
264 if (end0 <= j1) {
265 j0 += templatewidth0;
266 l += nbcol0;
267 continue;
268 }
269 if (end1 <= j0) {
270 j1 += templatewidth1;
271 continue;
272 }
273 /* compute the raw intersection */
274 start = max(j0, j1);
275 start = max(start, 0);
276 /* the start is correct now, update the corresponding fields */
277 result[offset].gstart = start;
278 end = min(end0, end1);
279 if (end0 == end) {
280 j0 += templatewidth0;
281 l += nbcol0;
282 }
283 if (end1 == end)
284 j1 += templatewidth1;
285 /* throw the limit if they go out of the matrix */
286 end = min(end, n);
287 assert(end > start);
288 /* it is a bit tricky to see why the length is always positive after all
289 * this min and max, first we have the property that every interval
290 * considered is at least partly into the submatrix, second we arrive
291 * here only if the raw intersection is non-void, if we remove a limit
292 * that means the corresponding frontier is in both intervals which
293 * proove the final interval is non-void, clear ?? */
294 result[offset].len = end - start;
295 offset += 1;
296 } /* while */
297 return offset;
298}
299/*********************************************************************/
300/* Do the scanning of intervals and the requested action */
301void
302scanD0(uplo, diag, action, ptrbuff, ptrsizebuff,
303 m, n,
304 ma, ia, ja, p0, q0,
305 mb, ib, jb, p1, q1,
306 v_inter, vinter_nb,
307 h_inter, hinter_nb,
308 ptrblock)
309 Int action, /* # of the action done on the intersected intervals */
310 *ptrsizebuff; /* size of the communication ptrbuffer (chosen to be
311 * an output parameter in every cases) */
312 Int *ptrbuff /* address of the communication ptrbuffer (a suffisant memory
313 space is supposed to be allocated before the call) */ , *ptrblock;
314 Int p0, q0, p1, q1;
315 IDESC *v_inter, *h_inter;
316 Int vinter_nb, hinter_nb;
317 Int m, n;
318 Int ia, ja, ib, jb;
319 MDESC *ma, *mb;
320 char *uplo, *diag;
321{/* Rmk: the a+au type addresses are strict bounds as a+au does not belong to
322 * the [a..a+au-1] interval of length au */
323 Int templateheight1, templatewidth1;
324 Int templateheight0, templatewidth0;
325 Int h, v; /* for scanning the intervals */
326 /* initializations */
327 templateheight1 = p1 * mb->nbrow;
328 templateheight0 = p0 * ma->nbrow;
329 templatewidth1 = q1 * mb->nbcol;
330 templatewidth0 = q0 * ma->nbcol;
331 /* we now will deal will logical grids, that's to say we change our
332 * numbering of processors so that (0,0) begin on logical processor (0,0) */
333 /* in case we will not enter the while loop */
334 (*ptrsizebuff) = 0;
335 for (h = 0; h < hinter_nb; h++)
336 for (v = 0; v < vinter_nb; v++) {
337 Int j;
338 for (j = 0; j < h_inter[h].len; j++)
339 intersect(uplo, diag, j + h_inter[h].gstart,
340 v_inter[v].gstart, v_inter[v].gstart + v_inter[v].len,
341 action, ptrsizebuff, &ptrbuff, ptrblock, m, n,
342 ma, ia, ja, templateheight0, templatewidth0,
343 mb, ib, jb, templateheight1, templatewidth1);
344 }
345}/* scanD0() */
#define Int
Definition Bconfig.h:22
static2 void intersect(char *uplo, char *diag, Int j, Int start, Int end, Int action, Int *ptrsizebuff, Int **pptrbuff, Int *ptrblock, Int m, Int n, MDESC *ma, Int ia, Int ja, Int templateheight0, Int templatewidth0, MDESC *mb, Int ib, Int jb, Int templateheight1, Int templatewidth1)
Definition pitrmr2.c:173
Int memoryblocksize()
Int changeorigin()
#define freememory
Definition pitrmr2.c:85
#define scan_intervals
Definition pitrmr2.c:86
#define SHIFT(row, sprow, nbrow)
Definition pitrmr2.c:41
void Cblacs_gridexit()
#define max(A, B)
Definition pitrmr2.c:42
#define min(A, B)
Definition pitrmr2.c:43
void Cigsum2d()
#define ilacpy_
Definition pitrmr2.c:21
#define static2
Definition pitrmr2.c:8
#define scanD0
Definition pitrmr2.c:82
Int Cblacs_pnum()
void Cpitrmr2do()
static2 Int insidemat(char *uplo, char *diag, Int i, Int j, Int m, Int n, Int *offset)
Definition pitrmr2.c:138
#define SIZEBUFF
Definition pitrmr2.c:97
#define Clacpy
Definition pitrmr2.c:23
void Cigamx2d()
void Cblacs_pinfo()
void Cblacs_pcoord()
void Cigamn2d()
Int localsize()
#define setmemory
Definition pitrmr2.c:84
void Cblacs_get()
void Cigerv2d()
void Cigebs2d()
#define dispmat
Definition pitrmr2.c:83
void Cpitrmr2d()
#define SENDBUFF
Definition pitrmr2.c:95
void paramcheck()
void Cblacs_setup()
#define RECVBUFF
Definition pitrmr2.c:96
void Cblacs_gridinit()
void Cblacs_gridinfo()
void Csetpvmtids()
Int localindice()
void Cigesd2d()
Int ppcm()
void Cigebr2d()
void Cblacs_exit()
void * mr2d_malloc()
Int len
Definition pcgemr.c:177
Int gstart
Definition pctrmr.c:191
Int spcol
Definition pcgemr.c:171
Int nbcol
Definition pcgemr.c:169
Int sprow
Definition pcgemr.c:170
Int nbrow
Definition pcgemr.c:168