4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * Green Red Orange Magenta Azure Cyan Skyblue
29 static char *SRCID_main_c
= "$Id$";
48 static void mem_init(void)
55 if ((p
=malloc(avail
))==NULL
)
56 fatal_error(errno
,"mem init");
65 static int get_pid(FILE *log
,int left
,int right
,int *pid
,int *nprocs
)
67 * The ring of processors is only defined by the interconnection
68 * via the supplied communication channels (left and right). Thus
69 * it is not defined what the (hardware) processor id's are in the
70 * ring. To be independent of the processor id assignment (to allow
71 * procesor switching without modifying a processor id) this routine
72 * determines the processor id and the number of processors. On entry
73 * pid needs to be set to an unique value in the system and nprocs
74 * needs to be set to the maximum number of processors in the system.
75 * The lowest pid in the ring will then get the value 0 assigned. The
76 * rest is then assigned by incrementing processor id's to the right
77 * until the ring is closed. The function returns 1 in case it succeeded
78 * in determining the values for pid and nprocs, else it returns 0. If
79 * the hardware does not implement a ring structure this will hang the
83 int i
,pids
[MAXPROC
],min_index
,min_pid
,send_pid
,receive_pid
;
91 fprintf(log
,"Sending: %d\n",send_pid
);
93 gmx_tx(left
,record(send_pid
));
94 gmx_rx(right
,record(receive_pid
));
98 fprintf(log
,"Received: %d\n",receive_pid
);
100 if (send_pid
<min_pid
) {
104 pids
[(*nprocs
)++]=send_pid
;
105 send_pid
=receive_pid
;
106 } while (receive_pid
!=*pid
);
109 fprintf(log
,"min_index=%d\n",min_index
);
110 fprintf(log
,"nprocs =%d\n",*nprocs
);
111 fprintf(log
,"pid =%d\n",*pid
);
114 for (i
=min_index
; (*pid
)!=pids
[i
%(*nprocs
)]; i
++)
116 (*pid
)=(i
-min_index
+(*nprocs
))%(*nprocs
);
118 fprintf(log
,"min_index=%d\n",min_index
);
119 fprintf(log
,"nprocs =%d\n",*nprocs
);
120 fprintf(log
,"pid =%d\n",*pid
);
121 for (i
=0; i
<(*nprocs
); i
++) {
122 fprintf(log
,"%d translated %d --> %d",
123 i
,pids
[i
],(i
-min_index
+(*nprocs
))%(*nprocs
));
132 char *par_fn(char *base
,int ftp
,t_commrec
*cr
)
134 static char buf
[256];
136 /* Copy to buf, and strip extension */
138 buf
[strlen(base
)-4] = '\0';
140 /* Add processor info */
142 sprintf(buf
+strlen(buf
),"%d",cr
->pid
);
145 /* Add extension again */
146 strcat(buf
,(ftp
== efTPX
) ? "tpr" : (ftp
== efENX
) ? "edr" : ftp2ext(ftp
));
151 void open_log(char *lognm
,t_commrec
*cr
)
158 /* Communicate the filename for logfile */
159 if (cr
->nprocs
> 1) {
161 len
= strlen(lognm
)+1;
162 gmx_txs(cr
->right
,record(len
));
163 gmx_rxs(cr
->left
,record(testlen
));
167 gmx_txs(cr
->right
,lognm
,len
);
168 gmx_rxs(cr
->left
,lognm
,len
);
170 fatal_error(0,"Communication error on PROC 0!");
174 gmx_rxs(cr
->left
,record(len
));
177 gmx_txs(cr
->right
,record(len
));
179 gmx_rxs(cr
->left
,lognm
,len
);
180 gmx_txs(cr
->right
,lognm
,len
);
186 /* Since log always ends with '.log' let's use this info */
187 buf
= par_fn(lognm
,efLOG
,cr
);
188 stdlog
= ffopen(buf
,"w");
190 /* Get some machine parameters */
191 host
= getenv("HOST");
197 fprintf(stdlog
,"Log file opened: pid %d, nprocs = %d, host = %s, process = %d\n",
198 cr
->pid
,cr
->nprocs
,host
? host
: "unknown",pid
);
203 static void comm_args(t_commrec
*cr
,int *argc
,char ***argv
)
206 char **argv_tmp
=NULL
,*buf
;
213 snew(argv_tmp
,*argc
+1);
214 fprintf(stderr
,"PID=%d argc=%d\n",cr
->pid
,*argc
);
215 for(i
=0; (i
<*argc
); i
++) {
217 len
= strlen((*argv
)[i
])+1;
218 gmx_txs(cr
->right
,&len
,sizeof(len
));
219 gmx_rxs(cr
->left
,&len
,sizeof(len
));
220 gmx_txs(cr
->right
,(*argv
)[i
],len
);
222 gmx_rxs(cr
->left
,buf
,len
);
223 if (strcmp(buf
,(*argv
)[i
]) != 0)
224 fatal_error(0,"Communicating argv[%d]=%s\n",i
,(*argv
)[i
]);
228 gmx_rxs(cr
->left
,&len
,sizeof(len
));
229 gmx_txs(cr
->right
,&len
,sizeof(len
));
230 snew(argv_tmp
[i
],len
);
231 gmx_rxs(cr
->left
,argv_tmp
[i
],len
);
232 gmx_txs(cr
->right
,argv_tmp
[i
],len
);
236 argv_tmp
[*argc
] = NULL
;
242 t_commrec
*init_par(int *argc
,char ***argv_ptr
)
252 /* Get the number of processors.
253 * This is useless for newer MPI versions.
255 for(i
=0; (argv
[i
] != NULL
); i
++) {
256 if (strcmp(argv
[i
],"-np")==0)
258 cr
->nprocs
=atoi(argv
[i
+1]);
264 if (getenv("MPI_ENVIRONMENT") == NULL
)
268 cr
->pid
=mpiio_setup(argc
,argv
,&cr
->nprocs
);
273 if (cr
->nprocs
> 1) {
276 cr
->pid
=pvmio_setup(argv
,cr
->nprocs
);
278 cr
->pid
=gmx_cpu_id();
288 if (!PAR(cr
) && (cr
->pid
!= 0))
289 fatal_error(0,"(!PAR(cr) && (cr->pid != 0))");
292 gmx_left_right(cr
->nprocs
,cr
->pid
,&cr
->left
,&cr
->right
);
294 fprintf(stderr
,"Going to initialise network\n");
299 fprintf(stderr
,"Initialised network\n");
300 fprintf(stderr
,"Getting new processor id's\n");
302 if (get_pid(stderr
,cr
->left
,cr
->right
,&cr
->pid
,&cr
->nprocs
)==0)
303 fatal_error(0,"could not get pid & nprocs from ring topology");
305 fprintf(stderr
,"Got new processor id's\n");
306 fprintf(stderr
,"nprocs=%d, pid=%d\n",cr
->nprocs
,cr
->pid
);
312 /* Communicate arguments if parallel */
314 comm_args(cr
,argc
,argv_ptr
);