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 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 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 } 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