[mpich2-commits] r7654 - in mpich2/trunk/src/pm/hydra/ui: include mpich utils

balaji at mcs.anl.gov balaji at mcs.anl.gov
Mon Jan 3 07:05:20 CST 2011


Author: balaji
Date: 2011-01-03 07:05:20 -0600 (Mon, 03 Jan 2011)
New Revision: 7654

Modified:
   mpich2/trunk/src/pm/hydra/ui/include/ui.h
   mpich2/trunk/src/pm/hydra/ui/mpich/mpiexec.c
   mpich2/trunk/src/pm/hydra/ui/mpich/utils.c
   mpich2/trunk/src/pm/hydra/ui/utils/uiu.c
Log:
Allow users to redirect stdout/stderr to separate files. Fixes ticket
 #1131.

Modified: mpich2/trunk/src/pm/hydra/ui/include/ui.h
===================================================================
--- mpich2/trunk/src/pm/hydra/ui/include/ui.h	2011-01-03 13:04:35 UTC (rev 7653)
+++ mpich2/trunk/src/pm/hydra/ui/include/ui.h	2011-01-03 13:05:20 UTC (rev 7654)
@@ -9,6 +9,8 @@
 
 struct HYD_ui_info {
     char *prepend_regex;
+    char *outfile_regex;
+    char *errfile_regex;
 };
 
 extern struct HYD_ui_info HYD_ui_info;

Modified: mpich2/trunk/src/pm/hydra/ui/mpich/mpiexec.c
===================================================================
--- mpich2/trunk/src/pm/hydra/ui/mpich/mpiexec.c	2011-01-03 13:04:35 UTC (rev 7653)
+++ mpich2/trunk/src/pm/hydra/ui/mpich/mpiexec.c	2011-01-03 13:05:20 UTC (rev 7654)
@@ -109,7 +109,9 @@
     printf("    -ppn                             processes per node\n");
     printf("    -profile                         turn on internal profiling\n");
     printf("    -prepend-rank                    prepend rank to output\n");
-    printf("    -prepend-regex                  prepend regex to output\n");
+    printf("    -prepend-regex                   prepend regex to output\n");
+    printf("    -outfile-regex                   direct stdout to file\n");
+    printf("    -errfile-regex                   direct stderr to file\n");
     printf
         ("    -nameserver                      name server information (host:port format)\n");
     printf("    -disable-auto-cleanup            don't cleanup processes on error\n");

Modified: mpich2/trunk/src/pm/hydra/ui/mpich/utils.c
===================================================================
--- mpich2/trunk/src/pm/hydra/ui/mpich/utils.c	2011-01-03 13:04:35 UTC (rev 7653)
+++ mpich2/trunk/src/pm/hydra/ui/mpich/utils.c	2011-01-03 13:05:20 UTC (rev 7654)
@@ -280,19 +280,24 @@
 
 static HYD_status prepend_rank_fn(char *arg, char ***argv)
 {
-    return HYDU_set_str(arg, argv, &HYD_ui_info.prepend_regex, "[%r]");
+    return HYDU_set_str(arg, argv, &HYD_ui_info.prepend_regex, "[%r] ");
 }
 
-static void prepend_regex_help_fn(void)
+static void regex_info(void)
 {
-    printf("\n");
-    printf("-prepend-regex: Prepend this regular expression to stdout and stderr\n");
     printf("   Regular expressions can include:\n");
     printf("       %%r: Process rank\n");
     printf("       %%g: Process group ID\n");
     printf("       %%p: Proxy ID\n");
     printf("       %%h: Hostname\n");
+}
+
+static void prepend_regex_help_fn(void)
+{
     printf("\n");
+    printf("-prepend-regex: Prepend this regular expression to stdout and stderr\n");
+    regex_info();
+    printf("\n");
 }
 
 static HYD_status prepend_regex_fn(char *arg, char ***argv)
@@ -300,6 +305,30 @@
     return HYDU_set_str_and_incr(arg, argv, &HYD_ui_info.prepend_regex);
 }
 
+static void outfile_regex_help_fn(void)
+{
+    printf("\n");
+    printf("-outfile-regex: Send stdout to this file\n\n");
+    regex_info();
+}
+
+static HYD_status outfile_regex_fn(char *arg, char ***argv)
+{
+    return HYDU_set_str_and_incr(arg, argv, &HYD_ui_info.outfile_regex);
+}
+
+static void errfile_regex_help_fn(void)
+{
+    printf("\n");
+    printf("-errfile-regex: Send stderr to this file\n\n");
+    regex_info();
+}
+
+static HYD_status errfile_regex_fn(char *arg, char ***argv)
+{
+    return HYDU_set_str_and_incr(arg, argv, &HYD_ui_info.errfile_regex);
+}
+
 static void wdir_help_fn(void)
 {
     printf("\n");
@@ -933,6 +962,8 @@
     {"prepend-rank", prepend_rank_fn, prepend_rank_help_fn},
     {"l", prepend_rank_fn, prepend_rank_help_fn},
     {"prepend-regex", prepend_regex_fn, prepend_regex_help_fn},
+    {"outfile-regex", outfile_regex_fn, outfile_regex_help_fn},
+    {"errfile-regex", errfile_regex_fn, errfile_regex_help_fn},
     {"wdir", wdir_fn, wdir_help_fn},
     {"configfile", config_fn, config_help_fn},
 

Modified: mpich2/trunk/src/pm/hydra/ui/utils/uiu.c
===================================================================
--- mpich2/trunk/src/pm/hydra/ui/utils/uiu.c	2011-01-03 13:04:35 UTC (rev 7653)
+++ mpich2/trunk/src/pm/hydra/ui/utils/uiu.c	2011-01-03 13:05:20 UTC (rev 7654)
@@ -9,6 +9,12 @@
 #include "ui.h"
 #include "uiu.h"
 
+static struct stdoe_fd {
+    int fd;
+    char *regex;
+    struct stdoe_fd *next;
+} *stdoe_fd_list = NULL;
+
 void HYD_uiu_init_params(void)
 {
     HYDU_init_user_global(&HYD_server_info.user_global);
@@ -38,10 +44,16 @@
 #endif /* ENABLE_PROFILING */
 
     HYD_ui_info.prepend_regex = NULL;
+    HYD_ui_info.outfile_regex = NULL;
+    HYD_ui_info.errfile_regex = NULL;
+
+    stdoe_fd_list = NULL;
 }
 
 void HYD_uiu_free_params(void)
 {
+    struct stdoe_fd *tmp, *run;
+
     HYDU_finalize_user_global(&HYD_server_info.user_global);
 
     if (HYD_server_info.base_path)
@@ -71,6 +83,19 @@
     if (HYD_ui_info.prepend_regex)
         HYDU_FREE(HYD_ui_info.prepend_regex);
 
+    if (HYD_ui_info.outfile_regex)
+        HYDU_FREE(HYD_ui_info.outfile_regex);
+
+    if (HYD_ui_info.errfile_regex)
+        HYDU_FREE(HYD_ui_info.errfile_regex);
+
+    for (run = stdoe_fd_list; run;) {
+        close(run->fd);
+        tmp = run->next;
+        HYDU_FREE(run);
+        run = tmp;
+    }
+
     /* Re-initialize everything to default values */
     HYD_uiu_init_params();
 }
@@ -146,12 +171,11 @@
     return;
 }
 
-static HYD_status stdoe_cb(int fd, int pgid, int proxy_id, int rank, void *_buf, int buflen)
+static HYD_status resolve_regex_string(const char *regex, char **str, int pgid, int proxy_id,
+                                       int rank)
 {
-    int sent, closed, mark, i, offset;
-    char *buf = (char *) _buf;
-    char *prepend, *tprepend;
-    char *s_rank, *s_pgid, *s_proxy_id, *s_host, *s;
+    int offset, i;
+    char *tstr, *s_rank, *s_pgid, *s_proxy_id, *s_host, *s;
     struct HYD_pg *pg;
     struct HYD_proxy *proxy;
     char *tmp[HYD_NUM_TMP_STRINGS];
@@ -159,88 +183,139 @@
 
     HYDU_FUNC_ENTER();
 
-    if (HYD_ui_info.prepend_regex == NULL) {
-        status = HYDU_sock_write(fd, buf, buflen, &sent, &closed);
-        HYDU_ERR_POP(status, "unable to write data to stdout/stderr\n");
-        HYDU_ASSERT(!closed, status);
-    }
-    else {
-        tprepend = prepend = HYDU_strdup(HYD_ui_info.prepend_regex);
+    tstr = *str = HYDU_strdup(regex);
 
-        offset = 0;
-        i = 0;
-        do {
-            s_rank = strstr(prepend, "%r");
-            s_pgid = strstr(prepend, "%g");
-            s_proxy_id = strstr(prepend, "%p");
-            s_host = strstr(prepend, "%h");
+    offset = 0;
+    i = 0;
+    do {
+        s_rank = strstr(*str, "%r");
+        s_pgid = strstr(*str, "%g");
+        s_proxy_id = strstr(*str, "%p");
+        s_host = strstr(*str, "%h");
 
-            s = s_rank;
-            if (s == NULL || (s_pgid && s_pgid < s))
-                s = s_pgid;
-            if (s == NULL || (s_proxy_id && s_proxy_id < s))
-                s = s_proxy_id;
-            if (s == NULL || (s_host && s_host < s))
-                s = s_host;
+        s = s_rank;
+        if (s == NULL || (s_pgid && s_pgid < s))
+            s = s_pgid;
+        if (s == NULL || (s_proxy_id && s_proxy_id < s))
+            s = s_proxy_id;
+        if (s == NULL || (s_host && s_host < s))
+            s = s_host;
 
-            if (s)
-                *s = 0;
+        if (s)
+            *s = 0;
 
-            tmp[i++] = HYDU_strdup(prepend);
+        tmp[i++] = HYDU_strdup(*str);
 
-            if (s) {
-                if (s[1] == 'r') {
-                    HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
-                    MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%d", rank);
-                }
-                else if (s[1] == 'g') {
-                    HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
-                    MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%d", pgid);
-                }
-                else if (s[1] == 'p') {
-                    HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
-                    MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%d", proxy_id);
-                }
-                else if (s[1] == 'h') {
-                    for (pg = &HYD_server_info.pg_list; pg; pg = pg->next)
-                        if (pg->pgid == pgid)
-                            break;
-                    HYDU_ASSERT(pg, status);
+        if (s) {
+            if (s[1] == 'r') {
+                HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
+                MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%d", rank);
+            }
+            else if (s[1] == 'g') {
+                HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
+                MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%d", pgid);
+            }
+            else if (s[1] == 'p') {
+                HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
+                MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%d", proxy_id);
+            }
+            else if (s[1] == 'h') {
+                for (pg = &HYD_server_info.pg_list; pg; pg = pg->next)
+                    if (pg->pgid == pgid)
+                        break;
+                HYDU_ASSERT(pg, status);
 
-                    for (proxy = pg->proxy_list; proxy; proxy = proxy->next)
-                        if (proxy->proxy_id == proxy_id)
-                            break;
-                    HYDU_ASSERT(proxy, status);
+                for (proxy = pg->proxy_list; proxy; proxy = proxy->next)
+                    if (proxy->proxy_id == proxy_id)
+                        break;
+                HYDU_ASSERT(proxy, status);
 
-                    HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
-                    MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%s", proxy->node.hostname);
-                }
-                else {
-                    HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR,
-                                        "unrecognized prepend regex\n");
-                }
-                i++;
+                HYDU_MALLOC(tmp[i], char *, HYD_TMP_STRLEN, status);
+                MPL_snprintf(tmp[i], HYD_TMP_STRLEN, "%s", proxy->node.hostname);
+            }
+            else {
+                HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "unrecognized regex\n");
+            }
+            i++;
 
-                prepend = s + 2;
+            *str = s + 2;
+        }
+        else
+            *str = NULL;
+    } while (*str);
+
+    tmp[i++] = NULL;
+    status = HYDU_str_alloc_and_join(tmp, str);
+    HYDU_ERR_POP(status, "unable to join strings\n");
+    HYDU_free_strlist(tmp);
+
+  fn_exit:
+    HYDU_FUNC_EXIT();
+    return status;
+
+  fn_fail:
+    goto fn_exit;
+}
+
+static HYD_status stdoe_cb(int _fd, int pgid, int proxy_id, int rank, void *_buf, int buflen)
+{
+    int fd = _fd;
+    char *regex_resolve, *regex = NULL;
+    struct stdoe_fd *tmp, *run;
+    int sent, closed, mark, i;
+    char *buf = (char *) _buf, *prepend;
+    HYD_status status = HYD_SUCCESS;
+
+    HYDU_FUNC_ENTER();
+
+    regex = (_fd == STDOUT_FILENO) ? HYD_ui_info.outfile_regex :
+        (_fd == STDERR_FILENO) ? HYD_ui_info.errfile_regex : NULL;
+
+    if (regex) {
+        /* See if the regex already exists */
+        status = resolve_regex_string(regex, &regex_resolve, pgid, proxy_id, rank);
+
+        for (run = stdoe_fd_list; run; run = run->next)
+            if (!strcmp(run->regex, regex_resolve))
+                break;
+
+        if (run) {
+            fd = run->fd;
+            HYDU_FREE(regex_resolve);
+        }
+        else {
+            HYDU_MALLOC(tmp, struct stdoe_fd *, sizeof(struct stdoe_fd), status);
+            tmp->regex = regex_resolve;
+            tmp->fd = open(tmp->regex, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+            HYDU_ASSERT(tmp->fd >= 0, status);
+            tmp->next = NULL;
+
+            if (stdoe_fd_list == NULL)
+                stdoe_fd_list = tmp;
+            else {
+                for (run = stdoe_fd_list; run->next; run = run->next);
+                run->next = tmp;
             }
-            else
-                prepend = NULL;
-        } while (prepend);
 
-        tmp[i++] = NULL;
-        status = HYDU_str_alloc_and_join(tmp, &prepend);
-        HYDU_ERR_POP(status, "unable to join strings\n");
-        HYDU_free_strlist(tmp);
+            fd = tmp->fd;
+        }
+    }
 
+    if (HYD_ui_info.prepend_regex == NULL) {
+        status = HYDU_sock_write(fd, buf, buflen, &sent, &closed);
+        HYDU_ERR_POP(status, "unable to write data to stdout/stderr\n");
+        HYDU_ASSERT(!closed, status);
+    }
+    else {
+        status = resolve_regex_string(HYD_ui_info.prepend_regex, &prepend, pgid, proxy_id,
+                                      rank);
+        HYDU_ERR_POP(status, "error resolving regex\n");
+
         mark = 0;
         for (i = 0; i < buflen; i++) {
             if (buf[i] == '\n' || i == buflen - 1) {
-                if (fd == STDOUT_FILENO) {
-                    HYDU_dump_noprefix(stdout, "%s ", prepend);
-                }
-                else if (fd == STDERR_FILENO) {
-                    HYDU_dump_noprefix(stderr, "%s ", prepend);
-                }
+                status = HYDU_sock_write(fd, (const void *) prepend, strlen(prepend), &sent,
+                                         &closed);
                 status = HYDU_sock_write(fd, (const void *) &buf[mark], i - mark + 1,
                                          &sent, &closed);
                 HYDU_ERR_POP(status, "unable to write data to stdout/stderr\n");
@@ -249,7 +324,7 @@
             }
         }
 
-        HYDU_FREE(tprepend);
+        HYDU_FREE(prepend);
     }
 
   fn_exit:



More information about the mpich2-commits mailing list