1*10167291SKenneth E. Jansen #include <stdio.h>
2*10167291SKenneth E. Jansen #include <stdlib.h>
3*10167291SKenneth E. Jansen #include <string.h>
4*10167291SKenneth E. Jansen #include <assert.h>
5*10167291SKenneth E. Jansen
6*10167291SKenneth E. Jansen #include <mpi.h>
7*10167291SKenneth E. Jansen
8*10167291SKenneth E. Jansen #include "common_c.h"
9*10167291SKenneth E. Jansen
10*10167291SKenneth E. Jansen #include "FCMangle.h"
11*10167291SKenneth E. Jansen
12*10167291SKenneth E. Jansen //commu_int.f
13*10167291SKenneth E. Jansen #define commu_int FortranCInterface_GLOBAL_(commu_int, COMMU_INT)
14*10167291SKenneth E. Jansen void commu_int(int* global, int* ilwork, int* n, char* code);
15*10167291SKenneth E. Jansen
16*10167291SKenneth E. Jansen #define gen_ncorp FortranCInterface_GLOBAL_(gen_ncorp, GEN_NCORP)
17*10167291SKenneth E. Jansen
18*10167291SKenneth E. Jansen // KEJ changed ncorp_t to lcorp_t (used for on proc numbering
19*10167291SKenneth E. Jansen // and introduced gcorp_t for global numbering
20*10167291SKenneth E. Jansen typedef int lcorp_t;
21*10167291SKenneth E. Jansen #define NCORP_MPI_T MPI_INTEGER
22*10167291SKenneth E. Jansen typedef long long int gcorp_t;
23*10167291SKenneth E. Jansen
24*10167291SKenneth E. Jansen static lcorp_t count_owned(int* ilwork, int nlwork,gcorp_t* ncorp_tmp, int* num_nodes);
25*10167291SKenneth E. Jansen static lcorp_t count_local(int* ilwork, int nlwork,gcorp_t* ncorp_tmp, int* num_nodes);
26*10167291SKenneth E. Jansen
27*10167291SKenneth E. Jansen
gen_ncorp(gcorp_t * ncorp,int * ilwork,lcorp_t * nilwork_f,int * num_nodes)28*10167291SKenneth E. Jansen void gen_ncorp(gcorp_t* ncorp, int* ilwork, lcorp_t* nilwork_f, int* num_nodes)
29*10167291SKenneth E. Jansen {
30*10167291SKenneth E. Jansen int part;
31*10167291SKenneth E. Jansen int num_parts;
32*10167291SKenneth E. Jansen int i;
33*10167291SKenneth E. Jansen lcorp_t nilwork = *nilwork_f;
34*10167291SKenneth E. Jansen lcorp_t owned;
35*10167291SKenneth E. Jansen lcorp_t local;
36*10167291SKenneth E. Jansen lcorp_t* owner_counts;
37*10167291SKenneth E. Jansen gcorp_t local_start_id;
38*10167291SKenneth E. Jansen gcorp_t gid;
39*10167291SKenneth E. Jansen
40*10167291SKenneth E. Jansen MPI_Comm_rank(MPI_COMM_WORLD, &part);
41*10167291SKenneth E. Jansen MPI_Comm_size(MPI_COMM_WORLD, &num_parts);
42*10167291SKenneth E. Jansen
43*10167291SKenneth E. Jansen memset(ncorp, 0, sizeof(gcorp_t)*(*num_nodes));
44*10167291SKenneth E. Jansen owned = count_owned(ilwork, nilwork, ncorp, num_nodes);
45*10167291SKenneth E. Jansen local = count_local(ilwork, nilwork, ncorp, num_nodes);
46*10167291SKenneth E. Jansen conpar.iownnodes = owned+local;
47*10167291SKenneth E. Jansen #ifdef PRINT_EVERYTHING
48*10167291SKenneth E. Jansen printf("%d: %d local only nodes\n", part, local);
49*10167291SKenneth E. Jansen printf("%d: %d owned nodes\n", part, owned);
50*10167291SKenneth E. Jansen #endif
51*10167291SKenneth E. Jansen assert( owned <= *num_nodes );
52*10167291SKenneth E. Jansen assert( owned+local <= *num_nodes );
53*10167291SKenneth E. Jansen
54*10167291SKenneth E. Jansen owner_counts = (lcorp_t*) malloc(sizeof(lcorp_t)*num_parts);
55*10167291SKenneth E. Jansen memset(owner_counts, 0, sizeof(lcorp_t)*num_parts);
56*10167291SKenneth E. Jansen owner_counts[part] = owned+local;
57*10167291SKenneth E. Jansen #ifdef PRINT_EVERYTHING
58*10167291SKenneth E. Jansen for(i=0;i<num_parts;i++)
59*10167291SKenneth E. Jansen {
60*10167291SKenneth E. Jansen printf("%d,", owner_counts[i]);
61*10167291SKenneth E. Jansen }
62*10167291SKenneth E. Jansen printf("\n");
63*10167291SKenneth E. Jansen #endif
64*10167291SKenneth E. Jansen MPI_Allgather(MPI_IN_PLACE, 1, NCORP_MPI_T, owner_counts,
65*10167291SKenneth E. Jansen 1, NCORP_MPI_T, MPI_COMM_WORLD);
66*10167291SKenneth E. Jansen #ifdef PRINT_EVERYTHING
67*10167291SKenneth E. Jansen for(i=0;i<num_parts;i++)
68*10167291SKenneth E. Jansen {
69*10167291SKenneth E. Jansen printf("%d,", owner_counts[i]);
70*10167291SKenneth E. Jansen }
71*10167291SKenneth E. Jansen printf("\n");
72*10167291SKenneth E. Jansen #endif
73*10167291SKenneth E. Jansen local_start_id=0;
74*10167291SKenneth E. Jansen for(i=0;i<part;i++) //TODO: MPI_Exscan()?
75*10167291SKenneth E. Jansen {
76*10167291SKenneth E. Jansen // global so needs long long
77*10167291SKenneth E. Jansen local_start_id += owner_counts[i];
78*10167291SKenneth E. Jansen }
79*10167291SKenneth E. Jansen local_start_id++; //Fortran numbering
80*10167291SKenneth E. Jansen #ifdef PRINT_EVERYTHING
81*10167291SKenneth E. Jansen printf("%d: %d\n", part, local_start_id);
82*10167291SKenneth E. Jansen #endif
83*10167291SKenneth E. Jansen // global so needs long long
84*10167291SKenneth E. Jansen gid = local_start_id;
85*10167291SKenneth E. Jansen if(gid<0) printf("part,gid, %d %ld",part,gid);
86*10167291SKenneth E. Jansen assert(gid>=0);
87*10167291SKenneth E. Jansen for(i=0;i<*num_nodes;i++) //assign owned node's numbers
88*10167291SKenneth E. Jansen {
89*10167291SKenneth E. Jansen //if shared, owned 1
90*10167291SKenneth E. Jansen //if shared, slave -1
91*10167291SKenneth E. Jansen //if local only, 0
92*10167291SKenneth E. Jansen if(ncorp[i] == 1)
93*10167291SKenneth E. Jansen {
94*10167291SKenneth E. Jansen // global so needs long long
95*10167291SKenneth E. Jansen ncorp[i]=gid;
96*10167291SKenneth E. Jansen assert(ncorp[i]>=0);
97*10167291SKenneth E. Jansen
98*10167291SKenneth E. Jansen // global so needs long long
99*10167291SKenneth E. Jansen gid++;
100*10167291SKenneth E. Jansen continue;
101*10167291SKenneth E. Jansen }
102*10167291SKenneth E. Jansen if(ncorp[i] == 0)
103*10167291SKenneth E. Jansen {
104*10167291SKenneth E. Jansen ncorp[i] = gid;
105*10167291SKenneth E. Jansen assert(ncorp[i]>=0);
106*10167291SKenneth E. Jansen gid++;
107*10167291SKenneth E. Jansen continue;
108*10167291SKenneth E. Jansen }
109*10167291SKenneth E. Jansen if(ncorp[i] == -1)
110*10167291SKenneth E. Jansen {
111*10167291SKenneth E. Jansen ncorp[i] = 0; //commu() adds, so zero slaves
112*10167291SKenneth E. Jansen }
113*10167291SKenneth E. Jansen
114*10167291SKenneth E. Jansen }
115*10167291SKenneth E. Jansen //char code[] = "out";
116*10167291SKenneth E. Jansen //int ione = 1;
117*10167291SKenneth E. Jansen //commu_int(ncorp, ilwork, &ione, code);
118*10167291SKenneth E. Jansen
119*10167291SKenneth E. Jansen }
120*10167291SKenneth E. Jansen
count_local(int * ilwork,int nlwork,gcorp_t * ncorp_tmp,int * num_nodes)121*10167291SKenneth E. Jansen static lcorp_t count_local(int* ilwork, int nlwork,gcorp_t* ncorp_tmp, int* num_nodes)
122*10167291SKenneth E. Jansen {
123*10167291SKenneth E. Jansen int i;
124*10167291SKenneth E. Jansen lcorp_t num_local = 0;
125*10167291SKenneth E. Jansen for(i=0;i<*num_nodes;i++)
126*10167291SKenneth E. Jansen {
127*10167291SKenneth E. Jansen if(ncorp_tmp[i] == 0)
128*10167291SKenneth E. Jansen num_local++; //nodes away from part boundary
129*10167291SKenneth E. Jansen assert(!(ncorp_tmp[i] < -1 || ncorp_tmp[i] > 1));
130*10167291SKenneth E. Jansen }
131*10167291SKenneth E. Jansen return(num_local);
132*10167291SKenneth E. Jansen }
count_owned(int * ilwork,int nlwork,gcorp_t * ncorp_tmp,int * num_nodes)133*10167291SKenneth E. Jansen static lcorp_t count_owned(int* ilwork, int nlwork,gcorp_t* ncorp_tmp, int* num_nodes)
134*10167291SKenneth E. Jansen {
135*10167291SKenneth E. Jansen int numtask = ilwork[0];
136*10167291SKenneth E. Jansen int itkbeg = 0; //task offset
137*10167291SKenneth E. Jansen int owned = 0;
138*10167291SKenneth E. Jansen int i,j,k;
139*10167291SKenneth E. Jansen for(i=0;i<numtask;i++)
140*10167291SKenneth E. Jansen {
141*10167291SKenneth E. Jansen int itag = ilwork[itkbeg+1]; //mpi tag
142*10167291SKenneth E. Jansen int iacc = ilwork[itkbeg+2]; //0 for slave, 1 for master
143*10167291SKenneth E. Jansen assert(iacc >= 0 && iacc <= 1);
144*10167291SKenneth E. Jansen int iother = ilwork[itkbeg+3]-1; //other rank (see ctypes.f for off by one)
145*10167291SKenneth E. Jansen int numseg = ilwork[itkbeg+4]; //number of segments
146*10167291SKenneth E. Jansen for(j=0;j<numseg;j++)
147*10167291SKenneth E. Jansen {
148*10167291SKenneth E. Jansen int isgbeg = ilwork[itkbeg+5+(j*2)]; //first idx of seg
149*10167291SKenneth E. Jansen int lenseg = ilwork[itkbeg+6+(j*2)]; //length of seg
150*10167291SKenneth E. Jansen assert(iacc == 0 || iacc == 1);
151*10167291SKenneth E. Jansen if(iacc)
152*10167291SKenneth E. Jansen {
153*10167291SKenneth E. Jansen for(k=0;k<lenseg;k++)
154*10167291SKenneth E. Jansen {
155*10167291SKenneth E. Jansen if(ncorp_tmp[isgbeg-1+k] == 0)
156*10167291SKenneth E. Jansen owned++;
157*10167291SKenneth E. Jansen //make sure we're not both master and slave
158*10167291SKenneth E. Jansen assert(ncorp_tmp[isgbeg-1+k] != -1);
159*10167291SKenneth E. Jansen ncorp_tmp[isgbeg-1+k] = 1;
160*10167291SKenneth E. Jansen assert(isgbeg-1+k < *num_nodes);
161*10167291SKenneth E. Jansen }
162*10167291SKenneth E. Jansen assert(owned <= *num_nodes);
163*10167291SKenneth E. Jansen }
164*10167291SKenneth E. Jansen else
165*10167291SKenneth E. Jansen {
166*10167291SKenneth E. Jansen for(k=0;k<lenseg;k++)
167*10167291SKenneth E. Jansen {
168*10167291SKenneth E. Jansen ncorp_tmp[isgbeg-1+k] = -1;
169*10167291SKenneth E. Jansen assert(isgbeg-1+k < *num_nodes);
170*10167291SKenneth E. Jansen }
171*10167291SKenneth E. Jansen }
172*10167291SKenneth E. Jansen //ncorp_tmp init'd to 0
173*10167291SKenneth E. Jansen //if shared, owned 1
174*10167291SKenneth E. Jansen //if shared, slave -1
175*10167291SKenneth E. Jansen //if local only, 0
176*10167291SKenneth E. Jansen
177*10167291SKenneth E. Jansen assert(itkbeg+6+(j*2) < nlwork);
178*10167291SKenneth E. Jansen }
179*10167291SKenneth E. Jansen itkbeg+= 4+2*numseg;
180*10167291SKenneth E. Jansen }
181*10167291SKenneth E. Jansen return(owned);
182*10167291SKenneth E. Jansen }
183