Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Abort if getline failed.
[simgrid.git] / examples / smpi / MM / param.c
1 /*!
2  * get the parameter specific to the process from a file
3  *
4  *
5  * Authors: Quintin Jean-Noël
6  */
7
8 #include "topo.h"
9 #include "param.h"
10 #include <string.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <mpi.h>
14 #include "xbt/log.h"
15 XBT_LOG_NEW_DEFAULT_CATEGORY(MM_param,
16                              "Messages specific for this msg example");
17
18 int match(const char *s, char p);
19 char** get_list_param(const char* input);
20 int match(const char *s, char p)
21 {
22   int c = 0;
23   while (*s != '\0') {
24     if (strncmp(s++, &p, 1)) continue;
25     c++;
26   }
27   return c;
28 }
29
30 char** get_list_param(const char* input){
31   if(input==NULL) return NULL;
32   char *line = strdup(input);
33   int size = match(line, ' ');
34   char **list_param = malloc(size*sizeof(char*));
35   char *pch = strtok (line," \t\n");
36   int i = 0;
37   while (pch != NULL)
38   {
39     if(strcmp(pch,"") != 0 ) {
40       list_param[i] = pch;
41       i++;
42     }
43     pch = strtok (NULL, " \t\n");
44   }
45   return list_param;
46 }
47
48 char** get_conf(MPI_Comm comm, const char * filename, int mynoderank)
49 {
50   if(filename == NULL) return NULL;
51   if(mynoderank == -1){
52     MPI_Comm comm_node;
53     split_comm_intra_node(comm, &comm_node, -1);
54     MPI_Comm_rank ( comm_node, &mynoderank );
55     MPI_Comm_free(&comm_node);
56   }
57   char name[MPI_MAX_PROCESSOR_NAME];
58   int len;
59   MPI_Get_processor_name(name, &len);
60   FILE* conf;
61   conf = fopen(filename, "r");
62   if (conf == NULL) {
63     XBT_DEBUG(
64               "Try to open the configuration file %s\n", filename);
65     perror("fopen");
66     return NULL;
67   }
68   char *machine_name = NULL;
69   size_t number = 0;
70   int err = 1;
71   int index = -1;
72
73
74   /* Try to find the line correponding to this processor */
75   while((err = getdelim(&machine_name, &number, ' ', conf)) != -1) {
76     while(err == 1){
77       err = getdelim(&machine_name, &number, ' ', conf);
78     }
79     if(err == -1) break;
80     XBT_DEBUG(
81               "read: %s cmp to %s\n", machine_name, name);
82     /* the first element is in machine_name
83        it's normally a processor name */
84     /* remove the delimiter before doing the comparison*/
85     machine_name[strlen(machine_name)-1] = 0;
86
87     if(strcmp(machine_name,name) == 0){
88       /* the machine name match */
89
90       /* try to get for which process with the index*/
91       char* char_index=NULL;
92       err = getdelim(&char_index, &number, ' ', conf);
93       while(err == 1){
94         err = getdelim(&char_index, &number, ' ', conf);
95       }
96       if(err == -1) break;
97
98       index=atoi(char_index);
99       XBT_DEBUG(
100                 "read: %d cmp to %d\n",
101                 index, mynoderank);
102
103       if(index == mynoderank){
104         /* we have found the good line
105          * we rebuild the line to get every information*/
106         char* line = NULL;
107         number = 0;
108         if (getline(&line,&number,conf) == -1)
109           xbt_die("Cannot get line");
110         char* line1 = NULL;
111         asprintf(&line1,"%s %s %s",name,char_index,line);
112         return get_list_param(line1);
113       }
114     }
115
116     /*prepare for the next line*/
117     free(machine_name);
118     machine_name = NULL;
119     number = 0;
120     err = getline(&machine_name, &number,  conf);
121     if (err >= 1) {
122       free(machine_name);
123       machine_name = NULL;
124       number = 0;
125     }
126
127   }
128   XBT_DEBUG(
129             "No configuration for %s %d\n", name, mynoderank );
130   return NULL;
131 }
132
133
134 char*** get_conf_all(char * filename, int * nb_process){
135   if(filename == NULL) return NULL;
136
137   char *** all_conf = NULL;
138   FILE* conf;
139   int nb_line = 0;
140   char *line = NULL;
141   size_t linecap = 0;
142   ssize_t linelen;
143
144   conf = fopen(filename, "r");
145   if (conf == NULL) {
146     XBT_DEBUG(
147               "Try to open the configuration file %s\n", filename);
148     perror("fopen");
149     return NULL;
150   }
151
152   while ((linelen = getline(&line, &linecap, conf)) > 0)
153     nb_line++;
154   fclose(conf);
155   conf = fopen(filename, "r");
156
157   all_conf = malloc(sizeof(char**) * nb_line);
158   /* Try to find the line correponding to this processor */
159   nb_line = 0;
160   while ((linelen = getline(&line, &linecap, conf)) > 0){
161     if (strcmp(line,"") == 0) continue; //Skip blank line
162     if (line[0] == '#') continue; //Skip comment line
163     all_conf[nb_line] = get_list_param(line);
164     nb_line++;
165   }
166   if(nb_process != NULL) *nb_process = nb_line;
167   return all_conf;
168 }
169
170
171 void print_conf(MPI_Comm comm, int rank, FILE* file, char * default_options){
172   char name[MPI_MAX_PROCESSOR_NAME];
173   int len;
174   MPI_Get_processor_name(name, &len);
175   if(file == NULL) file = stdout;
176
177   MPI_Comm comm_node;
178   split_comm_intra_node(comm, &comm_node, 0);
179
180   char ** names = get_names(comm);
181   int* index = get_index( comm,  comm_node);
182   MPI_Comm_free(&comm_node);
183   int size;
184   MPI_Comm_size(comm, &size);
185   int i=0;
186   if(rank == 0){
187     fprintf(file, "#processor_name index USER ARGS (like the cpu binding ...)\n");
188     for(i = 0; i < size; i++){
189       if(default_options != NULL)
190         fprintf(file, "%s %d %s\n", names[i],index[i],default_options);
191       else
192         fprintf(file, "%s %d\n", names[i],index[i]);
193     }
194   }
195   free(names);
196   free(index);
197   return;
198 }