root/ompi/mca/io/romio321/romio/adio/common/system_hints.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ADIOI_Info_print_keyvals
  2. find_file
  3. file_to_info_all
  4. ADIOI_process_system_hints
  5. ADIOI_incorporate_system_hints

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- 
   2  * vim: ts=8 sts=4 sw=4 noexpandtab
   3  *
   4  *   Copyright (C) 2007 UChicago/Argonne LLC. 
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include <adio.h>
   9 
  10 #include <stdio.h>
  11 
  12 #ifdef HAVE_FCNTL_H
  13 #include <fcntl.h>
  14 #endif
  15 #ifdef HAVE_SYS_TYPES_H
  16 #include <sys/types.h>
  17 #endif
  18 #ifdef HAVE_STDLIB_H
  19 #include <stdlib.h>
  20 #endif
  21 #ifdef HAVE_STRING_H
  22 #include <string.h>
  23 #endif
  24 #ifdef HAVE_UNISTD_H
  25 #include <unistd.h>
  26 #endif
  27 #ifdef HAVE_IO_H
  28 #include <io.h>
  29 #endif
  30 
  31 /*#define SYSHINT_DEBUG 1  */
  32 
  33 #define ROMIO_HINT_DEFAULT_CFG "/etc/romio-hints"
  34 #define ROMIO_HINT_ENV_VAR "ROMIO_HINTS"
  35 
  36 /* debug function: a routine I want in the library to make my life easier when
  37  * using a source debugger.  Now optionally used in ADIO_Open. */
  38 void ADIOI_Info_print_keyvals(MPI_Info info)
  39 {
  40     int i, nkeys, flag;
  41     char key[MPI_MAX_INFO_KEY+1];
  42     char value[MPI_MAX_INFO_VAL+1];
  43 
  44     if (info == MPI_INFO_NULL)
  45         return;
  46 
  47     MPI_Info_get_nkeys(info, &nkeys);
  48 
  49     for (i=0; i<nkeys; i++) {
  50         MPI_Info_get_nthkey(info, i, key);
  51         ADIOI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag);
  52         printf("key = %-25s value = %-10s\n", key, value);
  53     }
  54     return;
  55 }
  56 
  57 /* if user set the environment variable, use its value to find the
  58  * file-of-hints.  Otherwise, we'll look for the default config file.  i.e. let
  59  * the user override systemwide hint processing */
  60 
  61 static int find_file(void)
  62 {
  63     int fd=-1;
  64     char * hintfile;
  65     
  66     hintfile = getenv(ROMIO_HINT_ENV_VAR);
  67     if(hintfile)
  68     fd = open(hintfile, O_RDONLY);
  69     if (fd < 0 )
  70         fd = open(ROMIO_HINT_DEFAULT_CFG, O_RDONLY);
  71 
  72     return fd;
  73 }
  74 
  75 /* parse the file-of-hints.  Format is zero or more lines of "<key> <value>\n".
  76  * A # in collumn zero is a comment and the line will be ignored.  Do our best
  77  * to ignore badly formed lines too. 
  78  *
  79  * The caller provides an 'info' object.  Each key-value pair found by the
  80  * parser will get added to the info object.  any keys already set will be left
  81  * alone on the assumption that the caller knows best. 
  82  *
  83  * because MPI-IO hints are optional, we can get away with limited error
  84  * reporting.
  85  *
  86  * for better scalability, the config file will be read on one processor and
  87  * broadcast to all others */
  88 static int file_to_info_all(int fd, MPI_Info info, int rank, MPI_Comm comm)
  89 {
  90     char *buffer, *token, *key, *val, *garbage;
  91     char *pos1=NULL, *pos2=NULL;
  92     int flag;
  93     ssize_t ret;
  94     int valuelen;
  95 
  96     /* assumption: config files will be small */
  97 #define HINTFILE_MAX_SIZE 1024*4
  98     buffer = (char *)ADIOI_Calloc(HINTFILE_MAX_SIZE, sizeof (char));
  99 
 100     if (rank == 0) {
 101         ret = read(fd, buffer, HINTFILE_MAX_SIZE);
 102         /* any error: bad/nonexistent fd, no perms, anything: set up a null
 103          * buffer and the subsequent string parsing will quit immediately */
 104         if (ret == -1)
 105             buffer[0] = '\0';
 106     }
 107     MPI_Bcast(buffer, HINTFILE_MAX_SIZE, MPI_BYTE, 0, comm);
 108 
 109     token = strtok_r(buffer, "\n", &pos1);
 110     if (token == NULL)
 111         goto fn_exit;
 112     do {
 113         if ( (key = strtok_r(token, " \t", &pos2)) == NULL) 
 114             /* malformed line: found no items */
 115             continue;
 116         if (token[0] == '#') 
 117             /* ignore '#'-delimited comments */
 118             continue;
 119         if ( (val = strtok_r(NULL, " \t", &pos2))  == NULL) 
 120             /* malformed line: found key without value */
 121             continue;
 122         if ( (garbage = strtok_r(NULL, " \t", &pos2)) != NULL) 
 123             /* malformed line: more than two items */
 124             continue;
 125             
 126 #ifdef SYSHINT_DEBUG
 127         printf("found: key=%s val=%s\n", key, val);
 128 #endif
 129         /* don't actually care what the value is. only want to know if key
 130          * exists: we leave it alone if so*/
 131         ADIOI_Info_get_valuelen(info, key, &valuelen, &flag);
 132         if (flag == 1) continue;
 133         ADIOI_Info_set(info, key, val);
 134     } while ((token = strtok_r(NULL, "\n", &pos1)) != NULL);
 135 
 136 fn_exit:
 137     ADIOI_Free(buffer);
 138     return 0;
 139 }
 140 
 141 void ADIOI_process_system_hints(ADIO_File fd, MPI_Info info)
 142 {
 143     int hintfd=-1, rank;
 144 
 145     MPI_Comm_rank(fd->comm, &rank);
 146     if (rank == 0) {
 147         hintfd = find_file();
 148     }
 149     /* hintfd only significant on rank 0.  -1 (on rank 0) means no hintfile found  */
 150     file_to_info_all(hintfd, info, rank, fd->comm);
 151 
 152     if (hintfd != -1)
 153         close(hintfd);
 154 }
 155 
 156 /* given 'info', incorporate any hints in 'sysinfo' that are not already set
 157  * into 'new_info'.  Caller must free 'new_info' later. */
 158 void ADIOI_incorporate_system_hints(MPI_Info info, 
 159         MPI_Info sysinfo, 
 160         MPI_Info *new_info) 
 161 {
 162     int i, nkeys_sysinfo, nkeys_info=0, flag=0; /* must initialize flag to 0 */
 163     int valuelen;
 164 
 165     char  val[MPI_MAX_INFO_VAL+1], key[MPI_MAX_INFO_KEY+1];
 166 
 167     if (sysinfo == MPI_INFO_NULL)
 168         nkeys_sysinfo = 0;
 169     else
 170         MPI_Info_get_nkeys(sysinfo, &nkeys_sysinfo);
 171 
 172     /* short-circuit: return immediately if no hints to process */
 173     if (info == MPI_INFO_NULL && nkeys_sysinfo == 0)  {
 174         *new_info = MPI_INFO_NULL;
 175         return;
 176     }
 177 
 178     if (info == MPI_INFO_NULL) 
 179         MPI_Info_create(new_info);
 180     else {
 181         /* tiny optimization: if 'info' has no keys, we can skip the check if a
 182          * hint is set: no keys means nothing has been set, and there's nothing
 183          * we might step on */
 184         MPI_Info_get_nkeys(info, &nkeys_info);
 185         MPI_Info_dup(info, new_info);
 186     }
 187 
 188     for (i=0; i<nkeys_sysinfo; i++) {
 189         MPI_Info_get_nthkey(sysinfo, i, key);
 190         /* don't care about the value, just want to know if hint set already*/
 191         if (info != MPI_INFO_NULL && nkeys_info)
 192             ADIOI_Info_get_valuelen(info, key, &valuelen, &flag);
 193         if (flag == 1) continue;  /* skip any hints already set by user */
 194         ADIOI_Info_get(sysinfo, key, MPI_MAX_INFO_VAL, val, &flag);
 195         ADIOI_Info_set(*new_info, key, val);
 196         flag = 0;
 197     }
 198 
 199     return;
 200 }
 201 
 202 

/* [<][>][^][v][top][bottom][index][help] */