Actual source code: pdisplay.c

  1: #include <petscsys.h>

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

  7:   Collective

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

 14:   Output Parameters:
 15: + flag - if not `NULL` indicates if the variable was found
 16: - env  - value of variable

 18:   Level: advanced

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

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

 30: .seealso: `PetscOptionsHasName()`
 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:   PetscFunctionBegin;
 39:   /* first check options database */
 40:   PetscCall(PetscStrncmp(name, "PETSC_", 6, &spetsc));

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

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

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

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

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

 85:   PetscFunctionBegin;
 86:   PetscCall(PetscGetHostName(hostname, sizeof(hostname)));
 87:   PetscCall(PetscMemcpy(roothostname, hostname, sizeof(hostname)));
 88:   PetscCallMPI(MPI_Bcast(roothostname, sizeof(roothostname), MPI_CHAR, 0, PETSC_COMM_WORLD));
 89:   PetscCall(PetscStrcmp(hostname, roothostname, &flag));

 91:   localmatch = (PetscMPIInt)flag;

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

 95:   *onehost = (PetscBool)allmatch;
 96:   PetscFunctionReturn(PETSC_SUCCESS);
 97: }

 99: /*@C
100:   PetscSetDisplay - Determine and set PETSc's X11 display string from the `-display` option, the `DISPLAY` environment variable, or the hostname of MPI rank 0 when running across multiple nodes

102:   Collective; No Fortran Support

104:   Level: developer

106:   Note:
107:   Called automatically by `PetscInitialize()` so that subsequent `PetscDraw` X11 windows have a usable display target.

109: .seealso: `PetscGetDisplay()`, `PetscDraw`, `PETSC_DRAW_X`
110: @*/
111: PetscErrorCode PetscSetDisplay(void)
112: {
113:   PetscMPIInt size, rank;
114:   PetscBool   flag, singlehost = PETSC_FALSE;
115:   char        display[sizeof(PetscDisplay)];
116:   const char *str;

118:   PetscFunctionBegin;
119:   PetscCall(PetscOptionsGetString(NULL, NULL, "-display", PetscDisplay, sizeof(PetscDisplay), &flag));
120:   if (flag) PetscFunctionReturn(PETSC_SUCCESS);

122:   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
123:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));

125:   PetscCall(PetscWorldIsSingleHost(&singlehost));

127:   str = getenv("DISPLAY");
128:   if (!str) str = ":0.0";
129: #if defined(PETSC_HAVE_X)
130:   flag = PETSC_FALSE;
131:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-x_virtual", &flag, NULL));
132:   if (flag) {
133:     /*  this is a crude hack, but better than nothing */
134:     PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "pkill -15 Xvfb", "r", NULL));
135:     PetscCall(PetscSleep(1));
136:     PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "Xvfb :15 -screen 0 1600x1200x24", "r", NULL));
137:     PetscCall(PetscSleep(5));
138:     str = ":15";
139:   }
140: #endif
141:   if (str[0] != ':' || singlehost) {
142:     PetscCall(PetscStrncpy(display, str, sizeof(display)));
143:   } else if (rank == 0) {
144:     PetscCall(PetscGetHostName(display, sizeof(display)));
145:     PetscCall(PetscStrlcat(display, str, sizeof(display)));
146:   }
147:   PetscCallMPI(MPI_Bcast(display, sizeof(display), MPI_CHAR, 0, PETSC_COMM_WORLD));
148:   PetscCall(PetscMemcpy(PetscDisplay, display, sizeof(PetscDisplay)));

150:   PetscDisplay[sizeof(PetscDisplay) - 1] = 0;
151:   PetscFunctionReturn(PETSC_SUCCESS);
152: }

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

157:   Input Parameter:
158: . n - length of string display

160:   Output Parameter:
161: . display - the display string

163:   Options Database Keys:
164: + -display display - sets the display to use
165: - -x_virtual       - forces use of a X virtual display Xvfb that will not display anything but -draw_save will still work. Xvfb is automatically
166:                 started up in PetscSetDisplay() with this option

168:   Level: advanced

170: .seealso: `PETSC_DRAW_X`, `PetscDrawOpenX()`
171: @*/
172: PetscErrorCode PetscGetDisplay(char display[], size_t n)
173: {
174:   PetscFunctionBegin;
175:   PetscCall(PetscStrncpy(display, PetscDisplay, n));
176:   PetscFunctionReturn(PETSC_SUCCESS);
177: }