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, MPIU_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: PetscErrorCode PetscSetDisplay(void)
100: {
101: PetscMPIInt size, rank;
102: PetscBool flag, singlehost = PETSC_FALSE;
103: char display[sizeof(PetscDisplay)];
104: const char *str;
106: PetscFunctionBegin;
107: PetscCall(PetscOptionsGetString(NULL, NULL, "-display", PetscDisplay, sizeof(PetscDisplay), &flag));
108: if (flag) PetscFunctionReturn(PETSC_SUCCESS);
110: PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
111: PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
113: PetscCall(PetscWorldIsSingleHost(&singlehost));
115: str = getenv("DISPLAY");
116: if (!str) str = ":0.0";
117: #if defined(PETSC_HAVE_X)
118: flag = PETSC_FALSE;
119: PetscCall(PetscOptionsGetBool(NULL, NULL, "-x_virtual", &flag, NULL));
120: if (flag) {
121: /* this is a crude hack, but better than nothing */
122: PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "pkill -15 Xvfb", "r", NULL));
123: PetscCall(PetscSleep(1));
124: PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "Xvfb :15 -screen 0 1600x1200x24", "r", NULL));
125: PetscCall(PetscSleep(5));
126: str = ":15";
127: }
128: #endif
129: if (str[0] != ':' || singlehost) {
130: PetscCall(PetscStrncpy(display, str, sizeof(display)));
131: } else if (rank == 0) {
132: PetscCall(PetscGetHostName(display, sizeof(display)));
133: PetscCall(PetscStrlcat(display, str, sizeof(display)));
134: }
135: PetscCallMPI(MPI_Bcast(display, sizeof(display), MPI_CHAR, 0, PETSC_COMM_WORLD));
136: PetscCall(PetscMemcpy(PetscDisplay, display, sizeof(PetscDisplay)));
138: PetscDisplay[sizeof(PetscDisplay) - 1] = 0;
139: PetscFunctionReturn(PETSC_SUCCESS);
140: }
142: /*@C
143: PetscGetDisplay - Gets the X windows display variable for all processors.
145: Input Parameter:
146: . n - length of string display
148: Output Parameter:
149: . display - the display string
151: Options Database Keys:
152: + -display <display> - sets the display to use
153: - -x_virtual - forces use of a X virtual display Xvfb that will not display anything but -draw_save will still work. Xvfb is automatically
154: started up in PetscSetDisplay() with this option
156: Level: advanced
158: .seealso: `PETSC_DRAW_X`, `PetscDrawOpenX()`
159: @*/
160: PetscErrorCode PetscGetDisplay(char display[], size_t n)
161: {
162: PetscFunctionBegin;
163: PetscCall(PetscStrncpy(display, PetscDisplay, n));
164: PetscFunctionReturn(PETSC_SUCCESS);
165: }