~ubuntu-branches/ubuntu/saucy/nwchem/saucy

« back to all changes in this revision

Viewing changes to src/tools/ga-4-3/tcgmsg/ipcv4.0/parallel.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2012-02-09 20:02:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120209200241-jgk03qfsphal4ug2
Tags: 6.1-1
* New upstream release.

[ Michael Banck ]
* debian/patches/02_makefile_flags.patch: Updated.
* debian/patches/02_makefile_flags.patch: Use internal blas and lapack code.
* debian/patches/02_makefile_flags.patch: Define GCC4 for LINUX and LINUX64
  (Closes: #632611 and LP: #791308).
* debian/control (Build-Depends): Added openssh-client.
* debian/rules (USE_SCALAPACK, SCALAPACK): Removed variables (Closes:
  #654658).
* debian/rules (LIBDIR, USE_MPIF4, ARMCI_NETWORK): New variables.
* debian/TODO: New file.
* debian/control (Build-Depends): Removed libblas-dev, liblapack-dev and
  libscalapack-mpi-dev.
* debian/patches/04_show_testsuite_diff_output.patch: New patch, shows the
  diff output for failed tests.
* debian/patches/series: Adjusted.
* debian/testsuite: Optionally run all tests if "all" is passed as option.
* debian/rules: Run debian/testsuite with "all" if DEB_BUILD_OPTIONS
  contains "checkall".

[ Daniel Leidert ]
* debian/control: Used wrap-and-sort. Added Vcs-Svn and Vcs-Browser fields.
  (Priority): Moved to extra according to policy section 2.5.
  (Standards-Version): Bumped to 3.9.2.
  (Description): Fixed a typo.
* debian/watch: Added.
* debian/patches/03_hurd-i386_define_path_max.patch: Added.
  - Define MAX_PATH if not defines to fix FTBFS on hurd.
* debian/patches/series: Adjusted.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Header: /tmp/hpctools/ga/tcgmsg/ipcv4.0/parallel.c,v 1.22 2005-02-22 18:47:02 manoj Exp $ */
 
2
 
 
3
#include <stdio.h>
 
4
#ifdef SEQUENT
 
5
#include <strings.h>
 
6
#else
 
7
#include <string.h>
 
8
#endif
 
9
#include <sys/types.h>
 
10
#include <unistd.h> 
 
11
#include <sys/stat.h>
 
12
#include <sys/socket.h>
 
13
#include <netdb.h>
 
14
#if defined(SUN) || defined(ALLIANT) || defined(ENCORE) || defined(SEQUENT) || \
 
15
    defined(AIX) || defined(NEXT)    || defined(LINUX)
 
16
#include <sys/wait.h>
 
17
#endif
 
18
 
 
19
#include "sndrcvP.h"
 
20
#include "cluster.h"
 
21
#include "sndrcv.h"
 
22
#include "signals.h"
 
23
#include "sockets.h"
 
24
 
 
25
extern char *getenv();
 
26
#if defined(ULTRIX) || defined(SGI) || defined(NEXT) || defined(HPUX) || \
 
27
    defined(KSR)    || defined(DECOSF)
 
28
extern void *malloc();
 
29
#else
 
30
#include <stdlib.h>
 
31
#endif
 
32
 
 
33
#if !(defined(SGI) || defined(LINUX))
 
34
extern char *strdup();
 
35
#endif
 
36
 
 
37
extern void NextValueServer();
 
38
extern void Error();
 
39
extern int WaitAll(long nchild);
 
40
 
 
41
#if (defined(SUN) && !defined(SOLARIS))
 
42
    extern char *sprintf();
 
43
#endif
 
44
 
 
45
 
 
46
static char *ProcgrpFile(argc, argv)
 
47
     int argc;
 
48
     char **argv;
 
49
/*
 
50
  Find the name of the procgrp file from
 
51
 
 
52
  1) the first argument on the command line with .p appended
 
53
  2) as 1) but also prepending $HOME/pdir/
 
54
  2) the translation of the environmental variable PROCGRP
 
55
  3) the file PROCGRP in the current directory
 
56
*/
 
57
{
 
58
  char *tmp, *home;
 
59
  int len;
 
60
  struct stat buf;
 
61
 
 
62
  if (argc > 1) {
 
63
    len = strlen(argv[1]);
 
64
    tmp = malloc((unsigned) (len+3) );
 
65
    (void) strcpy(tmp, argv[1]);
 
66
    (void) strcpy(tmp+len, ".p");
 
67
 
 
68
    if (stat(tmp, &buf) == 0)     /* try ./arg1.p */
 
69
      return tmp;
 
70
    else
 
71
      (void) free(tmp);
 
72
    
 
73
    if ( (home = getenv("HOME")) != (char *) NULL ) {
 
74
      tmp = malloc((unsigned) (strlen(home) + len + 9));
 
75
      (void) strcpy(tmp, home);
 
76
      (void) strcpy(tmp+strlen(home),"/pdir/");
 
77
      (void) strcpy(tmp+strlen(home)+6,argv[1]);
 
78
      (void) strcpy(tmp+strlen(home)+6+len,".p");
 
79
 
 
80
(void) printf("tmp = %s\n",tmp);
 
81
 
 
82
      if (stat(tmp, &buf) == 0)     /* try $HOME/pdir/arg1.p */
 
83
        return tmp;
 
84
      else
 
85
        (void) free(tmp);
 
86
    }
 
87
  }
 
88
 
 
89
  if ( (tmp = getenv("PROCGRP")) != (char *) NULL )
 
90
    if (stat(tmp, &buf) == 0)
 
91
      return tmp;
 
92
 
 
93
  return strdup("PROCGRP");
 
94
}
 
95
  
 
96
static void SkipPastEOL(fp)
 
97
  FILE *fp;
 
98
/*
 
99
  Read past first newline character
 
100
*/
 
101
{
 
102
  int test;
 
103
 
 
104
   while ( (char) (test = getc(fp)) != '\n')
 
105
     if (test == EOF)
 
106
       break;
 
107
}
 
108
 
 
109
static char *GetProcgrp(filename, len_procgrp)
 
110
     char *filename;
 
111
     long *len_procgrp;
 
112
/*
 
113
  Read the entire contents of the PROCGRP into a NULL terminated
 
114
  character string. Be lazy and read the file twice, first to
 
115
  count the number of characters (ftell cannot be beleived?).
 
116
*/
 
117
{
 
118
  FILE *file;
 
119
  char *tmp, *procgrp;
 
120
  int status;
 
121
 
 
122
  if ( (file = fopen(filename,"r")) == (FILE *) NULL ) {
 
123
    (void) fprintf(stderr,"Master: PROCGRP = %s\n",filename);
 
124
    Error("Master: failed to open PROCGRP", (long) 0);
 
125
  }
 
126
 
 
127
  *len_procgrp = 0;
 
128
  while ( (status = getc(file)) != EOF) {
 
129
    if (status == '#')
 
130
      SkipPastEOL(file);
 
131
    else
 
132
      (*len_procgrp)++;
 
133
  }
 
134
 
 
135
  (*len_procgrp)++;
 
136
 
 
137
  if ( (tmp = procgrp = malloc((unsigned) *len_procgrp)) == (char *) NULL )
 
138
    Error("GetProcgrp: failed in malloc",  (long) *len_procgrp);
 
139
 
 
140
  (void) fseek(file, 0L, (int) 0);   /* Seek to beginning of file */
 
141
 
 
142
  while ( (status = getc(file)) != EOF) {
 
143
    if (status == '#')
 
144
      SkipPastEOL(file);
 
145
    else
 
146
      *tmp++ = (char) status;
 
147
  }
 
148
  
 
149
  *tmp = '\0';
 
150
 
 
151
  if ( (int) (tmp - procgrp + 1) != *len_procgrp )
 
152
    Error("GetProcgrp: screwup dimensioning procgrp",  (long) *len_procgrp);
 
153
 
 
154
  (void) fclose(file);
 
155
 
 
156
  return procgrp;
 
157
}
 
158
 
 
159
char *Canonical(name)
 
160
    char *name;
 
161
/*
 
162
  Use gethostbyname and return the canonicalized name.
 
163
*/
 
164
{
 
165
  struct hostent *host;
 
166
 
 
167
  if ( (host = gethostbyname(name)) != (struct hostent *) NULL )
 
168
    return strdup(host->h_name);
 
169
  else
 
170
    return (char *) NULL;
 
171
}
 
172
 
 
173
static long RemoteCreate(remote_hostname, remote_username, 
 
174
                         remote_executable, argc, argv,
 
175
                         n_clus, n_proc, clus_id, proc_id)
 
176
     char *remote_hostname;
 
177
     char *remote_username;
 
178
     char *remote_executable;
 
179
     int argc;
 
180
     char **argv;
 
181
     long n_clus;
 
182
     long n_proc;
 
183
     long clus_id;
 
184
     long proc_id;
 
185
/*
 
186
  Using rsh create a process on remote_hostname running the
 
187
  executable in the remote file remote_executable. Through
 
188
  arguments pass it my hostname and the port number of a socket
 
189
  to conenct on. Also propagate the arguments which this program
 
190
  was invoked with.
 
191
 
 
192
  Listen for a connection to be established. The return value of
 
193
  RemoteCreate is the filedescriptor of the socket connecting the 
 
194
  processes together. 
 
195
 
 
196
  Rsh should ensure that the standard output of the remote
 
197
  process is connected to the local standard output and that
 
198
  local interrupts are propagated to the remote process.
 
199
 */
 
200
{
 
201
  char  local_hostname[256], c_port[8];
 
202
  char  c_n_clus[8], c_n_proc[8], c_clus_id[8], c_proc_id[8];
 
203
  char  *argv2[256];
 
204
  int sock, port, i, pid;
 
205
  char *tmp;
 
206
 
 
207
  /* Create and bind socket to wild card internet name */
 
208
 
 
209
  CreateSocketAndBind(&sock, &port);
 
210
 
 
211
  /* create remote process using rsh passing master hostname and
 
212
     port as arguments */
 
213
 
 
214
  if (gethostname(local_hostname, 256) || strlen(local_hostname) == 0)
 
215
    Error("RemoteCreate: gethostname failed", (long) 0);
 
216
 
 
217
  (void) sprintf(c_port, "%d", port);
 
218
  (void) sprintf(c_n_clus, "%ld", n_clus);
 
219
  (void) sprintf(c_n_proc, "%ld", n_proc);
 
220
  (void) sprintf(c_clus_id, "%ld", clus_id);
 
221
  (void) sprintf(c_proc_id, "%ld", proc_id);
 
222
 
 
223
  (void) printf(" Creating: host=%s, user=%s,\n\
 
224
           file=%s, port=%s\n",
 
225
                remote_hostname, remote_username, remote_executable, 
 
226
                c_port);
 
227
 
 
228
  pid = fork();
 
229
  if (pid == 0) {
 
230
    /* In child process */
 
231
 
 
232
      sleep(1); /* So that parallel can make the sockets */
 
233
 
 
234
#ifndef SUN
 
235
    if (proc_id != 0)           /* Close all uneeded files */
 
236
      (void) fclose(stdin);
 
237
#ifdef SPARC64_GP
 
238
    for (i=3; i<62; i++)
 
239
#else
 
240
    for (i=3; i<64; i++)
 
241
#endif
 
242
      (void) close(i);
 
243
#endif
 
244
 
 
245
    /* Overlay the desired executable */
 
246
 
 
247
    if (strcmp(remote_hostname, local_hostname) != 0) {
 
248
      argv2[0      ] = "rsh";
 
249
      argv2[1      ] = remote_hostname;
 
250
      argv2[2      ] = "-l";
 
251
      argv2[3      ] = remote_username;
 
252
      argv2[4      ] = "-n";
 
253
      argv2[5      ] = remote_executable;
 
254
      argv2[6      ] = " ";
 
255
      for (i=2; i<argc; i++)
 
256
        argv2[i+5] = argv[i];
 
257
      argv2[argc+5 ] = "-master";
 
258
      argv2[argc+6 ] = local_hostname;
 
259
      argv2[argc+7 ] = c_port;
 
260
      argv2[argc+8 ] = c_n_clus;
 
261
      argv2[argc+9 ] = c_n_proc;
 
262
      argv2[argc+10] = c_clus_id;
 
263
      argv2[argc+11] = c_proc_id;
 
264
      argv2[argc+12] = (char *) NULL;
 
265
 
 
266
      if ( (tmp = getenv("TCGRSH")) != (char *) NULL )
 
267
        (void) execv(tmp,argv2);
 
268
      else 
 
269
#ifdef SGI
 
270
      (void) execv("/usr/bsd/rsh",argv2);
 
271
#endif
 
272
#ifdef HPUX
 
273
      (void) execv("/usr/bin/remsh",argv2);
 
274
#endif
 
275
#if defined(LINUX)
 
276
      (void) execv("/usr/bin/rsh",argv2);
 
277
#endif
 
278
#if !defined(SGI) && !defined(HPUX) && !defined(LINUX)
 
279
      (void) execv("/usr/ucb/rsh",argv2);
 
280
#endif
 
281
    }
 
282
    else {
 
283
      argv2[0     ] = remote_executable;
 
284
      for (i=1; i<(argc-1); i++) /* Don't copy the .p file name over */
 
285
        argv2[i] = argv[i+1];
 
286
      argv2[i+0] = "-master";
 
287
      argv2[i+1] = Canonical(local_hostname);
 
288
      argv2[i+2] = c_port;
 
289
      argv2[i+3] = c_n_clus;
 
290
      argv2[i+4] = c_n_proc;
 
291
      argv2[i+5] = c_clus_id;
 
292
      argv2[i+6] = c_proc_id;
 
293
      argv2[i+7] = (char *) NULL;
 
294
 
 
295
      (void) execv(remote_executable, argv2);
 
296
    }
 
297
    
 
298
    Error("RemoteCreate: in child after execv", (long) -1);
 
299
  }
 
300
  else if (pid > 0)
 
301
    SR_pids[SR_numchild++] = pid;
 
302
  else
 
303
    Error("RemoteCreate: failed forking process", (long) pid);
 
304
 
 
305
  /* accept one connection */
 
306
 
 
307
  return ListenAndAccept(sock);
 
308
}
 
309
 
 
310
int main(argc, argv)
 
311
     int argc;
 
312
     char **argv;
 
313
/*
 
314
  This is the master process of the cluster network.
 
315
 
 
316
  a) read the procgrp file. This is found by trying in turn:
 
317
     
 
318
          1) the first argument on the command line with .p appended
 
319
          2) the translation of the environmental variable PROCGRP
 
320
          3) the file PROCGRP in the current directory
 
321
 
 
322
  b) create the remote processes specified in this file, connecting
 
323
     to them via sockets and pass them the entire contents of the
 
324
     PROCGRP file in ascii
 
325
 
 
326
  c) Navigate messages to establish connections between the remote
 
327
     processes
 
328
 
 
329
  d) wait for all the children to finish and exit with the appropriate
 
330
     status
 
331
*/
 
332
{
 
333
  char  hostname[256];     /* Me */
 
334
  char *filename;          /* The name of PROCGRP file */
 
335
  char *procgrp;           /* The contents of PROCGRP */
 
336
  long len_procgrp;        /* The length of PROCGRP */
 
337
  long i, j, node, type, lenbuf, status=0, sync=1;
 
338
 
 
339
  /* Initialize all the globals */
 
340
 
 
341
  InitGlobal();
 
342
 
 
343
  /* Set up handler for SIGINT  and SIGCHLD */
 
344
 
 
345
  TrapSigint();
 
346
  TrapSigchld();
 
347
  TrapSigterm();
 
348
 
 
349
  /* on Solaris parallel gets SIGSEGV interrupted while polling  in NxtVal */
 
350
#ifdef SOLARIS
 
351
  TrapSigsegv();
 
352
#endif
 
353
 
 
354
  /* Generate a name for the PROCGRP file */
 
355
 
 
356
  filename = ProcgrpFile(argc, argv);
 
357
  if (DEBUG_)
 
358
    (void) printf("PROCGRP = %s\n",filename);
 
359
 
 
360
  /* Read in the entire contents of the PROCGRP file */
 
361
 
 
362
  procgrp = GetProcgrp(filename, &len_procgrp);
 
363
 
 
364
  /* Parse the procgrp info filling in the ClusterInfo structure and
 
365
     computing the number of clusters */
 
366
  
 
367
  if (gethostname(hostname, sizeof hostname) || strlen(hostname) == 0)
 
368
    Error("parallel: gethostname failed?", (long) sizeof hostname);
 
369
 
 
370
  InitClusInfo(procgrp, hostname);
 
371
 
 
372
  if (DEBUG_)
 
373
    PrintClusInfo();
 
374
 
 
375
  /* I am the master process so I have the highest ids */
 
376
 
 
377
  SR_proc_id = SR_n_proc;
 
378
 
 
379
  /* Now create the remote cluster master processes */
 
380
 
 
381
  for (i=0; i<SR_n_clus; i++) {
 
382
    node = SR_clus_info[i].masterid;
 
383
    SR_proc_info[node].sock = RemoteCreate(SR_clus_info[i].hostname,
 
384
                                           SR_clus_info[i].user,
 
385
                                           SR_clus_info[i].image,
 
386
                                           argc, argv,
 
387
                                           SR_n_clus,
 
388
                                           SR_n_proc,
 
389
                                           i,
 
390
                                           node);
 
391
    type = TYPE_BEGIN | MSGINT;
 
392
    lenbuf = sizeof(long);
 
393
    SND_(&type, (char *) &len_procgrp, &lenbuf, &node, &sync);
 
394
    type = TYPE_BEGIN | MSGCHR;
 
395
    SND_(&type, procgrp, &len_procgrp, &node, &sync);
 
396
  }
 
397
 
 
398
  /* Now have to route messages between the cluster masters as they connect */
 
399
 
 
400
  for (i=1; i< SR_n_clus; i++)
 
401
    for (j=0; j < i; j++)
 
402
      RemoteConnect(SR_clus_info[i].masterid, 
 
403
                    SR_clus_info[j].masterid,
 
404
                    NODEID_());
 
405
 
 
406
  /* Now for the next value service I need to connect to everyone else */
 
407
 
 
408
  for (i=0; i < SR_n_clus; i++)
 
409
    for (j=1; j<SR_clus_info[i].nslave; j++)
 
410
      RemoteConnect(SR_proc_id,
 
411
                    SR_clus_info[i].masterid+j,
 
412
                    SR_clus_info[i].masterid);
 
413
 
 
414
  /* Since we only using sockets we can block in select when waiting for a message */
 
415
  SR_using_shmem = 0;
 
416
  SR_nsock = 0;
 
417
  for (i=0; i<(SR_n_proc+1); i++) {
 
418
    if (SR_proc_info[i].sock >= 0) {
 
419
      SR_socks[SR_nsock] = SR_proc_info[i].sock;
 
420
      SR_socks_proc[SR_nsock] = i;
 
421
      SR_nsock++;
 
422
    }
 
423
  }
 
424
 
 
425
  /* Provide the next value service ... exit gracefully when get termination
 
426
     message from everyone or detect error */
 
427
 
 
428
  NextValueServer();
 
429
 
 
430
  /* Now wait patiently for everything to finish, then close all
 
431
     sockets and return */
 
432
 
 
433
  status = WaitAll(SR_n_clus);
 
434
 
 
435
  if (SR_error)
 
436
    status = 1;
 
437
 
 
438
  ShutdownAll();
 
439
 
 
440
  return status;
 
441
}