1 /*  aggList.c  */
2 
3 #include "../spoolesMPI.h"
4 
5 /*--------------------------------------------------------------------*/
6 /*
7    -----------------------------------------------
8    create, initialize and return a ChvList object
9    to deal with aggregate chevrons
10 
11    created  -- 98may21, cca
12    modified -- 98jul31, cca
13       now uses IVL_MPI_alltoall()
14    -----------------------------------------------
15 */
16 ChvList *
FrontMtx_MPI_aggregateList(FrontMtx * frontmtx,IV * frontOwnersIV,int stats[],int msglvl,FILE * msgFile,int tag,MPI_Comm comm)17 FrontMtx_MPI_aggregateList (
18    FrontMtx   *frontmtx,
19    IV         *frontOwnersIV,
20    int        stats[],
21    int        msglvl,
22    FILE       *msgFile,
23    int        tag,
24    MPI_Comm   comm
25 ) {
26 char      *mark ;
27 ChvList   *aggList ;
28 int       count, ierr, ii, jproc, J, K, myid, nfront, nproc, size ;
29 int       *aggcounts, *frontOwners, *head, *indices, *link, *list,
30           *updated, *vtxToFront ;
31 IVL       *recvIVL, *symbfacIVL, *sendIVL ;
32 /*
33    ---------------
34    check the input
35    ---------------
36 */
37 if (  frontmtx == NULL || frontOwnersIV == NULL ) {
38    fprintf(stderr,
39            "\n fatal error in FrontMtx_MPI_aggregateList(%p,%p,%p)"
40            "\n bad input\n", frontmtx, frontOwnersIV, comm) ;
41    exit(-1) ;
42 }
43 if ( tag < 0 || tag > maxTagMPI(comm) ) {
44    fprintf(stderr, "\n fatal error in FrontMtx_MPI_aggregateList()"
45            "\n tag = %d, tag_bound = %d", tag, maxTagMPI(comm)) ;
46    exit(-1) ;
47 }
48 MPI_Comm_rank(comm, &myid) ;
49 MPI_Comm_size(comm, &nproc) ;
50 symbfacIVL = frontmtx->symbfacIVL ;
51 vtxToFront = ETree_vtxToFront(frontmtx->frontETree) ;
52 IV_sizeAndEntries(frontOwnersIV, &nfront, &frontOwners) ;
53 if ( msglvl > 1 ) {
54    fprintf(msgFile,
55            "\n\n inside FrontMtx_aggListMPI, myid = %d, nproc = %d",
56            myid, nproc) ;
57    fflush(msgFile) ;
58 }
59 /*
60    ----------------------------------------------------
61    mark all fronts that are supported by an owned front
62    collect lists of updated fronts by owning processor
63    ----------------------------------------------------
64 */
65 mark = CVinit(nfront, 'N') ;
66 head = IVinit(nproc,  -1) ;
67 link = IVinit(nfront, -1) ;
68 for ( J = 0 ; J < nfront ; J++ ) {
69    jproc = frontOwners[J] ;
70    if ( jproc == myid ) {
71       IVL_listAndSize(symbfacIVL, J, &size, &indices) ;
72       for ( ii = 0 ; ii < size ; ii++ ) {
73          K = vtxToFront[indices[ii]] ;
74          if ( mark[K] == 'N' ) {
75             mark[K] = 'Y' ;
76             jproc   = frontOwners[K] ;
77             link[K] = head[jproc] ;
78             head[jproc] = K ;
79             if ( msglvl > 1 ) {
80                fprintf(msgFile, "\n front %d supported", K) ;
81                fflush(msgFile) ;
82             }
83          }
84       }
85    }
86 }
87 /*
88    -------------------------
89    set up the sendIVL object
90    -------------------------
91 */
92 list = IVinit(nfront, -1) ;
93 sendIVL = IVL_new() ;
94 IVL_init1(sendIVL, IVL_CHUNKED, nproc) ;
95 for ( jproc = 0 ; jproc < nproc ; jproc++ ) {
96    for ( K = head[jproc], count = 0 ; K != -1 ; K = link[K] ) {
97       list[count++] = K ;
98    }
99    IVL_setList(sendIVL, jproc, count, list) ;
100 }
101 if ( msglvl > 2 ) {
102    fprintf(msgFile, "\n\n send IVL for aggregate lists") ;
103    IVL_writeForHumanEye(sendIVL, msgFile) ;
104    fflush(msgFile) ;
105 }
106 /*
107    ----------------------
108    get the recvIVL object
109    ----------------------
110 */
111 recvIVL = IVL_MPI_alltoall(sendIVL, NULL,
112                            stats, msglvl, msgFile, tag, comm) ;
113 if ( msglvl > 2 ) {
114    fprintf(msgFile, "\n\n receive IVL for aggregate lists") ;
115    IVL_writeForHumanEye(recvIVL, msgFile) ;
116    fflush(msgFile) ;
117 }
118 /*
119    -------------------------
120    fill the aggcounts vector
121    -------------------------
122 */
123 aggcounts = IVinit(nfront, 0) ;
124 for ( jproc = 0 ; jproc < nproc ; jproc++ ) {
125    if ( jproc != myid ) {
126       IVL_listAndSize(recvIVL, jproc, &count, &updated) ;
127       for ( ii = 0 ; ii < count ; ii++ ) {
128          aggcounts[updated[ii]]++ ;
129       }
130    }
131 }
132 if ( msglvl > 1 ) {
133    fprintf(msgFile, "\n aggcounts") ;
134    IVfp80(msgFile, nfront, aggcounts, 80, &ierr) ;
135    fflush(msgFile) ;
136 }
137 /*
138    -----------------------------------------
139    create and initialize the ChvList object
140    -----------------------------------------
141 */
142 aggList = ChvList_new() ;
143 ChvList_init(aggList, nfront, aggcounts, 0, NULL) ;
144 /*
145    ------------------------
146    free the working storage
147    ------------------------
148 */
149 IVfree(aggcounts) ;
150 IVfree(head) ;
151 IVfree(link) ;
152 IVfree(list) ;
153 CVfree(mark) ;
154 IVL_free(sendIVL) ;
155 IVL_free(recvIVL) ;
156 
157 return(aggList) ; }
158 
159 /*--------------------------------------------------------------------*/
160