Actual source code: pdisplay.c


  2: #include <petscsys.h>

  4: /*@C
  5:      PetscOptionsGetenv - Gets an environmental variable, broadcasts to all
  6:           processors in communicator from MPI rank zero

  8:      Collective

 10:    Input Parameters:
 11: +    comm - communicator to share variable
 12: .    name - name of environmental variable
 13: -    len - amount of space allocated to hold variable

 15:    Output Parameters:
 16: +    flag - if not NULL tells if variable found or not
 17: -    env - value of variable

 19:   Level: advanced

 21:    Notes:
 22:     You can also "set" the environmental variable by setting the options database value
 23:     -name "stringvalue" (with name in lower case). If name begins with PETSC_ this is
 24:     discarded before checking the database. For example, `PETSC_VIEWER_SOCKET_PORT` would
 25:     be given as -viewer_socket_port 9000

 27:     If comm does not contain the 0th process in the MPIEXEC it is likely on
 28:     many systems that the environmental variable will not be set unless you
 29:     put it in a universal location like a .chsrc file

 31: @*/
 32: PetscErrorCode PetscOptionsGetenv(MPI_Comm comm, const char name[], char env[], size_t len, PetscBool *flag)
 33: {
 34:   PetscMPIInt rank;
 35:   char       *str, work[256];
 36:   PetscBool   flg = PETSC_FALSE, spetsc;

 38:   /* first check options database */
 39:   PetscStrncmp(name, "PETSC_", 6, &spetsc);

 41:   PetscStrcpy(work, "-");
 42:   if (spetsc) {
 43:     PetscStrlcat(work, name + 6, sizeof(work));
 44:   } else {
 45:     PetscStrlcat(work, name, sizeof(work));
 46:   }
 47:   PetscStrtolower(work);
 48:   if (env) {
 49:     PetscOptionsGetString(NULL, NULL, work, env, len, &flg);
 50:     if (flg) {
 51:       if (flag) *flag = PETSC_TRUE;
 52:     } else { /* now check environment */
 53:       PetscArrayzero(env, len);

 55:       MPI_Comm_rank(comm, &rank);
 56:       if (rank == 0) {
 57:         str = getenv(name);
 58:         if (str) flg = PETSC_TRUE;
 59:         if (str && env) PetscStrncpy(env, str, len);
 60:       }
 61:       MPI_Bcast(&flg, 1, MPIU_BOOL, 0, comm);
 62:       MPI_Bcast(env, len, MPI_CHAR, 0, comm);
 63:       if (flag) *flag = flg;
 64:     }
 65:   } else {
 66:     PetscOptionsHasName(NULL, NULL, work, flag);
 67:   }
 68:   return 0;
 69: }

 71: /*
 72:      PetscSetDisplay - Tries to set the X Windows display variable for all processors.
 73:                        The variable `PetscDisplay` contains the X Windows display variable.

 75: */
 76: static char PetscDisplay[256];

 78: static PetscErrorCode PetscWorldIsSingleHost(PetscBool *onehost)
 79: {
 80:   char        hostname[256], roothostname[256];
 81:   PetscMPIInt localmatch, allmatch;
 82:   PetscBool   flag;

 84:   PetscGetHostName(hostname, sizeof(hostname));
 85:   PetscMemcpy(roothostname, hostname, sizeof(hostname));
 86:   MPI_Bcast(roothostname, sizeof(roothostname), MPI_CHAR, 0, PETSC_COMM_WORLD);
 87:   PetscStrcmp(hostname, roothostname, &flag);

 89:   localmatch = (PetscMPIInt)flag;

 91:   MPIU_Allreduce(&localmatch, &allmatch, 1, MPI_INT, MPI_LAND, PETSC_COMM_WORLD);

 93:   *onehost = (PetscBool)allmatch;
 94:   return 0;
 95: }

 97: PetscErrorCode PetscSetDisplay(void)
 98: {
 99:   PetscMPIInt size, rank;
100:   PetscBool   flag, singlehost = PETSC_FALSE;
101:   char        display[sizeof(PetscDisplay)];
102:   const char *str;

104:   PetscOptionsGetString(NULL, NULL, "-display", PetscDisplay, sizeof(PetscDisplay), &flag);
105:   if (flag) return 0;

107:   MPI_Comm_size(PETSC_COMM_WORLD, &size);
108:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);

110:   PetscWorldIsSingleHost(&singlehost);

112:   str = getenv("DISPLAY");
113:   if (!str) str = ":0.0";
114: #if defined(PETSC_HAVE_X)
115:   flag = PETSC_FALSE;
116:   PetscOptionsGetBool(NULL, NULL, "-x_virtual", &flag, NULL);
117:   if (flag) {
118:     /*  this is a crude hack, but better than nothing */
119:     PetscPOpen(PETSC_COMM_WORLD, NULL, "pkill -9 Xvfb", "r", NULL);
120:     PetscSleep(1);
121:     PetscPOpen(PETSC_COMM_WORLD, NULL, "Xvfb :15 -screen 0 1600x1200x24", "r", NULL);
122:     PetscSleep(5);
123:     str = ":15";
124:   }
125: #endif
126:   if (str[0] != ':' || singlehost) {
127:     PetscStrncpy(display, str, sizeof(display));
128:   } else if (rank == 0) {
129:     PetscGetHostName(display, sizeof(display));
130:     PetscStrlcat(display, str, sizeof(display));
131:   }
132:   MPI_Bcast(display, sizeof(display), MPI_CHAR, 0, PETSC_COMM_WORLD);
133:   PetscMemcpy(PetscDisplay, display, sizeof(PetscDisplay));

135:   PetscDisplay[sizeof(PetscDisplay) - 1] = 0;
136:   return 0;
137: }

139: /*@C
140:      PetscGetDisplay - Gets the X windows display variable for all processors.

142:   Input Parameters:
143: .   n - length of string display

145:   Output Parameters:
146: .   display - the display string

148:   Options Database Keys:
149: +  -display <display> - sets the display to use
150: -  -x_virtual - forces use of a X virtual display Xvfb that will not display anything but -draw_save will still work. Xvfb is automatically
151:                 started up in PetscSetDisplay() with this option

153:   Level: advanced

155: .seealso: `PETSC_DRAW_X`, `PetscDrawOpenX()`
156: @*/
157: PetscErrorCode PetscGetDisplay(char display[], size_t n)
158: {
159:   PetscStrncpy(display, PetscDisplay, n);
160:   return 0;
161: }