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` indicates if the variable was found
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 `MPI_COMM_WORLD` 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
30: @*/
31: PetscErrorCode PetscOptionsGetenv(MPI_Comm comm, const char name[], char env[], size_t len, PetscBool *flag)
32: {
33: PetscMPIInt rank;
34: char *str, work[256];
35: PetscBool flg = PETSC_FALSE, spetsc;
37: PetscFunctionBegin;
38: /* first check options database */
39: PetscCall(PetscStrncmp(name, "PETSC_", 6, &spetsc));
41: PetscCall(PetscStrncpy(work, "-", sizeof(work)));
42: if (spetsc) {
43: PetscCall(PetscStrlcat(work, name + 6, sizeof(work)));
44: } else {
45: PetscCall(PetscStrlcat(work, name, sizeof(work)));
46: }
47: PetscCall(PetscStrtolower(work));
48: if (env) {
49: PetscCall(PetscOptionsGetString(NULL, NULL, work, env, len, &flg));
50: if (flg) {
51: if (flag) *flag = PETSC_TRUE;
52: } else { /* now check environment */
53: PetscCall(PetscArrayzero(env, len));
55: PetscCallMPI(MPI_Comm_rank(comm, &rank));
56: if (rank == 0) {
57: str = getenv(name);
58: if (str) flg = PETSC_TRUE;
59: if (str && env) PetscCall(PetscStrncpy(env, str, len));
60: }
61: PetscCallMPI(MPI_Bcast(&flg, 1, MPIU_BOOL, 0, comm));
62: PetscCallMPI(MPI_Bcast(env, len, MPI_CHAR, 0, comm));
63: if (flag) *flag = flg;
64: }
65: } else {
66: PetscCall(PetscOptionsHasName(NULL, NULL, work, flag));
67: }
68: PetscFunctionReturn(PETSC_SUCCESS);
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: PetscFunctionBegin;
85: PetscCall(PetscGetHostName(hostname, sizeof(hostname)));
86: PetscCall(PetscMemcpy(roothostname, hostname, sizeof(hostname)));
87: PetscCallMPI(MPI_Bcast(roothostname, sizeof(roothostname), MPI_CHAR, 0, PETSC_COMM_WORLD));
88: PetscCall(PetscStrcmp(hostname, roothostname, &flag));
90: localmatch = (PetscMPIInt)flag;
92: PetscCall(MPIU_Allreduce(&localmatch, &allmatch, 1, MPI_INT, MPI_LAND, PETSC_COMM_WORLD));
94: *onehost = (PetscBool)allmatch;
95: PetscFunctionReturn(PETSC_SUCCESS);
96: }
98: PetscErrorCode PetscSetDisplay(void)
99: {
100: PetscMPIInt size, rank;
101: PetscBool flag, singlehost = PETSC_FALSE;
102: char display[sizeof(PetscDisplay)];
103: const char *str;
105: PetscFunctionBegin;
106: PetscCall(PetscOptionsGetString(NULL, NULL, "-display", PetscDisplay, sizeof(PetscDisplay), &flag));
107: if (flag) PetscFunctionReturn(PETSC_SUCCESS);
109: PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
110: PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
112: PetscCall(PetscWorldIsSingleHost(&singlehost));
114: str = getenv("DISPLAY");
115: if (!str) str = ":0.0";
116: #if defined(PETSC_HAVE_X)
117: flag = PETSC_FALSE;
118: PetscCall(PetscOptionsGetBool(NULL, NULL, "-x_virtual", &flag, NULL));
119: if (flag) {
120: /* this is a crude hack, but better than nothing */
121: PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "pkill -9 Xvfb", "r", NULL));
122: PetscCall(PetscSleep(1));
123: PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "Xvfb :15 -screen 0 1600x1200x24", "r", NULL));
124: PetscCall(PetscSleep(5));
125: str = ":15";
126: }
127: #endif
128: if (str[0] != ':' || singlehost) {
129: PetscCall(PetscStrncpy(display, str, sizeof(display)));
130: } else if (rank == 0) {
131: PetscCall(PetscGetHostName(display, sizeof(display)));
132: PetscCall(PetscStrlcat(display, str, sizeof(display)));
133: }
134: PetscCallMPI(MPI_Bcast(display, sizeof(display), MPI_CHAR, 0, PETSC_COMM_WORLD));
135: PetscCall(PetscMemcpy(PetscDisplay, display, sizeof(PetscDisplay)));
137: PetscDisplay[sizeof(PetscDisplay) - 1] = 0;
138: PetscFunctionReturn(PETSC_SUCCESS);
139: }
141: /*@C
142: PetscGetDisplay - Gets the X windows display variable for all processors.
144: Input Parameter:
145: . n - length of string display
147: Output Parameter:
148: . display - the display string
150: Options Database Keys:
151: + -display <display> - sets the display to use
152: - -x_virtual - forces use of a X virtual display Xvfb that will not display anything but -draw_save will still work. Xvfb is automatically
153: started up in PetscSetDisplay() with this option
155: Level: advanced
157: .seealso: `PETSC_DRAW_X`, `PetscDrawOpenX()`
158: @*/
159: PetscErrorCode PetscGetDisplay(char display[], size_t n)
160: {
161: PetscFunctionBegin;
162: PetscCall(PetscStrncpy(display, PetscDisplay, n));
163: PetscFunctionReturn(PETSC_SUCCESS);
164: }