SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pstrmr2.c
Go to the documentation of this file.
1#include "redist.h"
2/* $Id: pstrmr2.c,v 1.1.1.1 2000/02/15 18:04:09 susan Exp $
3 *
4 * some functions used by the pstrmr2d routine see file pstrmr.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 pstrmr2do_
11#define fortran_mr2dnew pstrmr2d_
12#elif defined(UpCase)
13#define fortran_mr2dnew PSTRMR2D
14#define fortran_mr2d PSTRMR2DO
15#define scopy_ SCOPY
16#define slacpy_ SLACPY
17#else
18#define fortran_mr2d pstrmr2do
19#define fortran_mr2dnew pstrmr2d
20#define scopy_ scopy
21#define slacpy_ slacpy
22#endif
23#define Clacpy Cstrlacpy
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 Csgesd2d();
70extern void Csgerv2d();
71/* lapack */
72void slacpy_();
73/* aux fonctions */
75extern void *mr2d_malloc();
76extern Int ppcm();
77extern Int localsize();
80extern void paramcheck();
81/* tools and others function */
82#define scanD0 strscanD0
83#define dispmat strdispmat
84#define setmemory strsetmemory
85#define freememory strfreememory
86#define scan_intervals strscan_intervals
87extern void scanD0();
88extern void dispmat();
89extern void setmemory();
90extern void freememory();
91extern Int scan_intervals();
92extern void Cpstrmr2do();
93extern void Cpstrmr2d();
94/* some defines for Cpstrmr2do */
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(float **adpointer, Int blocksize)
114{
115 assert(blocksize >= 0);
116 if (blocksize == 0) {
117 *adpointer = NULL;
118 return;
119 }
120 *adpointer = (float *) mr2d_malloc(
121 blocksize * sizeof(float));
122}
123/******************************************************************/
124/* Free the memory space after the malloc */
125void
126freememory(float *ptrtobefreed)
127{
128 if (ptrtobefreed == NULL)
129 return;
130 free((char *) ptrtobefreed);
131}
132/* extern functions for intersect() extern scopy_(); */
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(uplo, diag,
174 j, start, end,
175 action,
176 ptrsizebuff, pptrbuff, ptrblock,
177 m, n,
178 ma, ia, ja, templateheight0, templatewidth0,
179 mb, ib, jb, templateheight1, templatewidth1)
180 Int action, *ptrsizebuff;
181 Int j, start, end;
182 float **pptrbuff, *ptrblock;
183 Int templateheight0, templatewidth0;
184 Int templateheight1, templatewidth1;
185 MDESC *ma, *mb;
186 Int ia, ja, ib, jb, m, n;
187 char *uplo, *diag;
188/* Execute the action on the local memory for the current interval and
189 * increment pptrbuff and ptrsizebuff of the intervalsize */
190/* Notice that if the interval is contigous in the virtual matrice, it is
191 * also contigous in the real one ! */
192{
193 /* int un = 1; only when we use dcopy instead of memcpy */
194 float *ptrstart;
195 Int offset, nbline;
196 Int intervalsize;
197 assert(start < end);
198 assert(j >= 0 && j < n);
199 nbline =
200 insidemat(uplo, diag, start, j, m, n, &offset);
201 if (nbline <= 0)
202 return;
203 start += offset;
204 if (start >= end)
205 return;
206 intervalsize = min(end - start, nbline);
207 (*ptrsizebuff) += intervalsize;
208 switch (action) {
209 case SENDBUFF: /* fill buff with local elements to be sent */
210 ptrstart = ptrblock + localindice(start + ia, j + ja,
211 templateheight0, templatewidth0, ma);
212 memcpy((char *) (*pptrbuff), (char *) ptrstart,
213 intervalsize * sizeof(float));
214 /* scopy_(&intervalsize, (char *) (ptrstart), &un, (char *) (*pptrbuff),
215 * &un); */
216 (*pptrbuff) += intervalsize;
217 break;
218 case RECVBUFF: /* fill local memory with the values received */
219 ptrstart = ptrblock + localindice(start + ib, j + jb,
220 templateheight1, templatewidth1, mb);
221 memcpy((char *) ptrstart, (char *) (*pptrbuff),
222 intervalsize * sizeof(float));
223 /* scopy_(&intervalsize, (char *) (*pptrbuff), &un, (char *) (ptrstart),
224 * &un); */
225 (*pptrbuff) += intervalsize;
226 break;
227 case SIZEBUFF: /* computation of sizebuff */
228 break;
229 default:
230 printf("action is %d outside the scope of the case [0..2] !! \n ", action);
231 exit(0);
232 break;
233 }; /* switch (action) */
234}/* intersect() */
235/* scan_intervals: scans two distributions in one dimension, and compute the
236 * intersections on the local processor. result must be long enough to
237 * contains the result that are stocked in IDESC structure, the function
238 * returns the number of intersections found */
239Int
240scan_intervals(type, ja, jb, n, ma, mb, q0, q1, col0, col1,
241 result)
242 char type;
243 Int ja, jb, n, q0, q1, col0, col1;
244 MDESC *ma, *mb;
245 IDESC *result;
246{
247 Int offset, j0, j1, templatewidth0, templatewidth1, nbcol0, nbcol1;
248 Int l; /* local indice on the beginning of the interval */
249 assert(type == 'c' || type == 'r');
250 nbcol0 = (type == 'c' ? ma->nbcol : ma->nbrow);
251 nbcol1 = (type == 'c' ? mb->nbcol : mb->nbrow);
252 templatewidth0 = q0 * nbcol0;
253 templatewidth1 = q1 * nbcol1;
254 {
255 Int sp0 = (type == 'c' ? ma->spcol : ma->sprow);
256 Int sp1 = (type == 'c' ? mb->spcol : mb->sprow);
257 j0 = SHIFT(col0, sp0, q0) * nbcol0 - ja;
258 j1 = SHIFT(col1, sp1, q1) * nbcol1 - jb;
259 }
260 offset = 0;
261 l = 0;
262 /* a small check to verify that the submatrix begin inside the first block
263 * of the original matrix, this done by a sort of coordinate change at the
264 * beginning of the Cpstrmr2d */
265 assert(j0 + nbcol0 > 0);
266 assert(j1 + nbcol1 > 0);
267 while ((j0 < n) && (j1 < n)) {
268 Int end0, end1;
269 Int start, end;
270 end0 = j0 + nbcol0;
271 end1 = j1 + nbcol1;
272 if (end0 <= j1) {
273 j0 += templatewidth0;
274 l += nbcol0;
275 continue;
276 }
277 if (end1 <= j0) {
278 j1 += templatewidth1;
279 continue;
280 }
281 /* compute the raw intersection */
282 start = max(j0, j1);
283 start = max(start, 0);
284 /* the start is correct now, update the corresponding fields */
285 result[offset].gstart = start;
286 end = min(end0, end1);
287 if (end0 == end) {
288 j0 += templatewidth0;
289 l += nbcol0;
290 }
291 if (end1 == end)
292 j1 += templatewidth1;
293 /* throw the limit if they go out of the matrix */
294 end = min(end, n);
295 assert(end > start);
296 /* it is a bit tricky to see why the length is always positive after all
297 * this min and max, first we have the property that every interval
298 * considered is at least partly into the submatrix, second we arrive
299 * here only if the raw intersection is non-void, if we remove a limit
300 * that means the corresponding frontier is in both intervals which
301 * proove the final interval is non-void, clear ?? */
302 result[offset].len = end - start;
303 offset += 1;
304 } /* while */
305 return offset;
306}
307/*********************************************************************/
308/* Do the scanning of intervals and the requested action */
309void
310scanD0(uplo, diag, action, ptrbuff, ptrsizebuff,
311 m, n,
312 ma, ia, ja, p0, q0,
313 mb, ib, jb, p1, q1,
314 v_inter, vinter_nb,
315 h_inter, hinter_nb,
316 ptrblock)
317 Int action, /* # of the action done on the intersected intervals */
318 *ptrsizebuff; /* size of the communication ptrbuffer (chosen to be
319 * an output parameter in every cases) */
320 float *ptrbuff /* address of the communication ptrbuffer (a
321 * suffisant memory space is supposed to be allocated
322 before the call) */ , *ptrblock;
323 Int p0, q0, p1, q1;
324 IDESC *v_inter, *h_inter;
325 Int vinter_nb, hinter_nb;
326 Int m, n;
327 Int ia, ja, ib, jb;
328 MDESC *ma, *mb;
329 char *uplo, *diag;
330{/* Rmk: the a+au type addresses are strict bounds as a+au does not belong to
331 * the [a..a+au-1] interval of length au */
332 Int templateheight1, templatewidth1;
333 Int templateheight0, templatewidth0;
334 Int h, v; /* for scanning the intervals */
335 /* initializations */
336 templateheight1 = p1 * mb->nbrow;
337 templateheight0 = p0 * ma->nbrow;
338 templatewidth1 = q1 * mb->nbcol;
339 templatewidth0 = q0 * ma->nbcol;
340 /* we now will deal will logical grids, that's to say we change our
341 * numbering of processors so that (0,0) begin on logical processor (0,0) */
342 /* in case we will not enter the while loop */
343 (*ptrsizebuff) = 0;
344 for (h = 0; h < hinter_nb; h++)
345 for (v = 0; v < vinter_nb; v++) {
346 Int j;
347 for (j = 0; j < h_inter[h].len; j++)
348 intersect(uplo, diag, j + h_inter[h].gstart,
349 v_inter[v].gstart, v_inter[v].gstart + v_inter[v].len,
350 action, ptrsizebuff, &ptrbuff, ptrblock, m, n,
351 ma, ia, ja, templateheight0, templatewidth0,
352 mb, ib, jb, templateheight1, templatewidth1);
353 }
354}/* scanD0() */
#define Int
Definition Bconfig.h:22
Int memoryblocksize()
Int changeorigin()
#define freememory
Definition pstrmr2.c:85
#define scan_intervals
Definition pstrmr2.c:86
void Csgerv2d()
void Cpstrmr2do()
#define SHIFT(row, sprow, nbrow)
Definition pstrmr2.c:41
void Cblacs_gridexit()
#define max(A, B)
Definition pstrmr2.c:42
#define min(A, B)
Definition pstrmr2.c:43
void Cigsum2d()
#define static2
Definition pstrmr2.c:8
#define scanD0
Definition pstrmr2.c:82
Int Cblacs_pnum()
static2 Int insidemat(char *uplo, char *diag, Int i, Int j, Int m, Int n, Int *offset)
Definition pstrmr2.c:138
#define SIZEBUFF
Definition pstrmr2.c:97
#define Clacpy
Definition pstrmr2.c:23
void Cigamx2d()
void Cblacs_pinfo()
void Cblacs_pcoord()
void Cigamn2d()
Int localsize()
#define setmemory
Definition pstrmr2.c:84
void Cblacs_get()
void Cigerv2d()
void Cigebs2d()
#define dispmat
Definition pstrmr2.c:83
#define SENDBUFF
Definition pstrmr2.c:95
void paramcheck()
void Cblacs_setup()
#define RECVBUFF
Definition pstrmr2.c:96
void Cblacs_gridinit()
static2 void intersect(char *uplo, char *diag, Int j, Int start, Int end, Int action, Int *ptrsizebuff, float **pptrbuff, float *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 pstrmr2.c:173
void Cblacs_gridinfo()
void Csetpvmtids()
Int localindice()
void Cigesd2d()
#define slacpy_
Definition pstrmr2.c:21
void Cpstrmr2d()
Int ppcm()
void Cigebr2d()
void Cblacs_exit()
void * mr2d_malloc()
void Csgesd2d()
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