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` indicates if the variable was found 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 `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; 36 37 PetscFunctionBegin; 38 /* first check options database */ 39 PetscCall(PetscStrncmp(name, "PETSC_", 6, &spetsc)); 40 41 PetscCall(PetscStrcpy(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)); 54 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 } 70 71 /* 72 PetscSetDisplay - Tries to set the X Windows display variable for all processors. 73 The variable `PetscDisplay` contains the X Windows display variable. 74 75 */ 76 static char PetscDisplay[256]; 77 78 static PetscErrorCode PetscWorldIsSingleHost(PetscBool *onehost) 79 { 80 char hostname[256], roothostname[256]; 81 PetscMPIInt localmatch, allmatch; 82 PetscBool flag; 83 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)); 89 90 localmatch = (PetscMPIInt)flag; 91 92 PetscCall(MPIU_Allreduce(&localmatch, &allmatch, 1, MPI_INT, MPI_LAND, PETSC_COMM_WORLD)); 93 94 *onehost = (PetscBool)allmatch; 95 PetscFunctionReturn(PETSC_SUCCESS); 96 } 97 98 PetscErrorCode PetscSetDisplay(void) 99 { 100 PetscMPIInt size, rank; 101 PetscBool flag, singlehost = PETSC_FALSE; 102 char display[sizeof(PetscDisplay)]; 103 const char *str; 104 105 PetscFunctionBegin; 106 PetscCall(PetscOptionsGetString(NULL, NULL, "-display", PetscDisplay, sizeof(PetscDisplay), &flag)); 107 if (flag) PetscFunctionReturn(PETSC_SUCCESS); 108 109 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 110 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 111 112 PetscCall(PetscWorldIsSingleHost(&singlehost)); 113 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))); 136 137 PetscDisplay[sizeof(PetscDisplay) - 1] = 0; 138 PetscFunctionReturn(PETSC_SUCCESS); 139 } 140 141 /*@C 142 PetscGetDisplay - Gets the X windows display variable for all processors. 143 144 Input Parameters: 145 . n - length of string display 146 147 Output Parameters: 148 . display - the display string 149 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 154 155 Level: advanced 156 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 } 165