1 2 #include <petscsys.h> 3 4 /*@C 5 PetscOptionsGetenv - Gets an environmental variable, broadcasts to all 6 processors in communicator from first. 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 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(0); 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 char hostname[256], roothostname[256]; 80 PetscMPIInt localmatch, allmatch; 81 PetscBool flag; 82 83 PetscFunctionBegin; 84 PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 85 PetscCall(PetscMemcpy(roothostname, hostname, sizeof(hostname))); 86 PetscCallMPI(MPI_Bcast(roothostname, sizeof(roothostname), MPI_CHAR, 0, PETSC_COMM_WORLD)); 87 PetscCall(PetscStrcmp(hostname, roothostname, &flag)); 88 89 localmatch = (PetscMPIInt)flag; 90 91 PetscCall(MPIU_Allreduce(&localmatch, &allmatch, 1, MPI_INT, MPI_LAND, PETSC_COMM_WORLD)); 92 93 *onehost = (PetscBool)allmatch; 94 PetscFunctionReturn(0); 95 } 96 97 PetscErrorCode PetscSetDisplay(void) { 98 PetscMPIInt size, rank; 99 PetscBool flag, singlehost = PETSC_FALSE; 100 char display[sizeof(PetscDisplay)]; 101 const char *str; 102 103 PetscFunctionBegin; 104 PetscCall(PetscOptionsGetString(NULL, NULL, "-display", PetscDisplay, sizeof(PetscDisplay), &flag)); 105 if (flag) PetscFunctionReturn(0); 106 107 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 108 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 109 110 PetscCall(PetscWorldIsSingleHost(&singlehost)); 111 112 str = getenv("DISPLAY"); 113 if (!str) str = ":0.0"; 114 #if defined(PETSC_HAVE_X) 115 flag = PETSC_FALSE; 116 PetscCall(PetscOptionsGetBool(NULL, NULL, "-x_virtual", &flag, NULL)); 117 if (flag) { 118 /* this is a crude hack, but better than nothing */ 119 PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "pkill -9 Xvfb", "r", NULL)); 120 PetscCall(PetscSleep(1)); 121 PetscCall(PetscPOpen(PETSC_COMM_WORLD, NULL, "Xvfb :15 -screen 0 1600x1200x24", "r", NULL)); 122 PetscCall(PetscSleep(5)); 123 str = ":15"; 124 } 125 #endif 126 if (str[0] != ':' || singlehost) { 127 PetscCall(PetscStrncpy(display, str, sizeof(display))); 128 } else if (rank == 0) { 129 PetscCall(PetscGetHostName(display, sizeof(display))); 130 PetscCall(PetscStrlcat(display, str, sizeof(display))); 131 } 132 PetscCallMPI(MPI_Bcast(display, sizeof(display), MPI_CHAR, 0, PETSC_COMM_WORLD)); 133 PetscCall(PetscMemcpy(PetscDisplay, display, sizeof(PetscDisplay))); 134 135 PetscDisplay[sizeof(PetscDisplay) - 1] = 0; 136 PetscFunctionReturn(0); 137 } 138 139 /* 140 PetscGetDisplay - Gets the display variable for all processors. 141 142 Input Parameters: 143 . n - length of string display 144 145 Output Parameters: 146 . display - the display string 147 148 Options Database: 149 + -display <display> - sets the display to use 150 - -x_virtual - forces use of a X virtual display Xvfb that will not display anything but -draw_save will still work. Xvfb is automatically 151 started up in PetscSetDisplay() with this option 152 153 */ 154 PetscErrorCode PetscGetDisplay(char display[], size_t n) { 155 PetscFunctionBegin; 156 PetscCall(PetscStrncpy(display, PetscDisplay, n)); 157 PetscFunctionReturn(0); 158 } 159