1 2 #include <petscsys.h> 3 4 /*@C 5 PetscOptionsGetenv - Gets an environmental variable, broadcasts to all 6 processors in communicator from MPI rank zero 7 8 Collective 9 10 Input Parameters: 11 + comm - communicator to share variable 12 . name - name of environmental variable 13 - len - amount of space allocated to hold variable 14 15 Output Parameters: 16 + flag - if not NULL tells if variable found or not 17 - env - value of variable 18 19 Level: advanced 20 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 26 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 30 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; 37 38 PetscFunctionBegin; 39 /* first check options database */ 40 PetscCall(PetscStrncmp(name, "PETSC_", 6, &spetsc)); 41 42 PetscCall(PetscStrcpy(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)); 55 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, len, MPI_CHAR, 0, comm)); 64 if (flag) *flag = flg; 65 } 66 } else { 67 PetscCall(PetscOptionsHasName(NULL, NULL, work, flag)); 68 } 69 PetscFunctionReturn(0); 70 } 71 72 /* 73 PetscSetDisplay - Tries to set the X Windows display variable for all processors. 74 The variable `PetscDisplay` contains the X Windows display variable. 75 76 */ 77 static char PetscDisplay[256]; 78 79 static PetscErrorCode PetscWorldIsSingleHost(PetscBool *onehost) 80 { 81 char hostname[256], roothostname[256]; 82 PetscMPIInt localmatch, allmatch; 83 PetscBool flag; 84 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)); 90 91 localmatch = (PetscMPIInt)flag; 92 93 PetscCall(MPIU_Allreduce(&localmatch, &allmatch, 1, MPI_INT, MPI_LAND, PETSC_COMM_WORLD)); 94 95 *onehost = (PetscBool)allmatch; 96 PetscFunctionReturn(0); 97 } 98 99 PetscErrorCode PetscSetDisplay(void) 100 { 101 PetscMPIInt size, rank; 102 PetscBool flag, singlehost = PETSC_FALSE; 103 char display[sizeof(PetscDisplay)]; 104 const char *str; 105 106 PetscFunctionBegin; 107 PetscCall(PetscOptionsGetString(NULL, NULL, "-display", PetscDisplay, sizeof(PetscDisplay), &flag)); 108 if (flag) PetscFunctionReturn(0); 109 110 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 111 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 112 113 PetscCall(PetscWorldIsSingleHost(&singlehost)); 114 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 -9 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))); 137 138 PetscDisplay[sizeof(PetscDisplay) - 1] = 0; 139 PetscFunctionReturn(0); 140 } 141 142 /*@C 143 PetscGetDisplay - Gets the X windows display variable for all processors. 144 145 Input Parameters: 146 . n - length of string display 147 148 Output Parameters: 149 . display - the display string 150 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 155 156 Level: advanced 157 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(0); 165 } 166