|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2011 Constantine Khroulev 00002 // 00003 // This file is part of PISM. 00004 // 00005 // PISM is free software; you can redistribute it and/or modify it under the 00006 // terms of the GNU General Public License as published by the Free Software 00007 // Foundation; either version 2 of the License, or (at your option) any later 00008 // version. 00009 // 00010 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY 00011 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00012 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00013 // details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with PISM; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 #include "PSExternal.hh" 00020 00021 // Note: EBM driver code should NOT use any PETSc calls! (The process running 00022 // this code does not initialize PETSc.) 00023 00024 EBM_driver::EBM_driver(MPI_Comm my_com) { 00025 inter_comm = my_com; 00026 command = "WILL BE INITIALIZED LATER"; 00027 } 00028 00029 int EBM_driver::run() { 00030 int ierr; 00031 int done = 0, 00032 wait_counter = 0, 00033 wait_message_counter = 1; 00034 00035 // Initialization: get the command. 00036 { 00037 char tmp[PETSC_MAX_PATH_LEN]; 00038 MPI_Recv(tmp, PETSC_MAX_PATH_LEN, MPI_CHAR, 0, TAG_EBM_COMMAND, inter_comm, NULL); 00039 command = tmp; 00040 } 00041 00042 while ( !done ) { 00043 MPI_Status status; 00044 int flag; 00045 MPI_Iprobe(0, MPI_ANY_TAG, inter_comm, &flag, &status); 00046 00047 if ( !flag ) { 00048 // no message 00049 double sleep_interval = 0.01, 00050 threshold = 3600, 00051 message_interval = 5; // print a message every 5 seconds 00052 struct timespec rq; 00053 rq.tv_sec = 0; 00054 rq.tv_nsec = (long)(sleep_interval*1e9); // convert to nanoseconds 00055 00056 if (wait_counter * sleep_interval > threshold) { 00057 fprintf(stderr, "ERROR: spent %1.1f minutes waiting for PISM... Giving up...\n", 00058 threshold / 60.0); 00059 00060 done = 1; 00061 continue; 00062 } 00063 00064 // waiting... 00065 if (sleep_interval * wait_counter / message_interval > wait_message_counter) { // 00066 fprintf(stderr, "EBM driver: Waiting for a message from PISM... (%1.1f seconds so far)\n", 00067 message_interval * wait_message_counter); 00068 wait_message_counter++; 00069 } 00070 nanosleep(&rq, 0); 00071 wait_counter++; 00072 continue; 00073 } 00074 00075 // we got a message; reset counters 00076 wait_counter = 0; 00077 wait_message_counter = 1; 00078 00079 switch (status.MPI_TAG) { 00080 case TAG_EBM_RUN: 00081 { 00082 double year; 00083 int ebm_status; 00084 MPI_Recv(&year, 1, MPI_DOUBLE, 0, TAG_EBM_RUN, inter_comm, NULL); 00085 00086 ierr = run_ebm(year); // no CHKERRQ(ierr) here 00087 00088 if (ierr != 0) { 00089 // the run failed 00090 ebm_status = EBM_STATUS_FAILED; 00091 done = 1; 00092 } else { 00093 // we're OK 00094 ebm_status = EBM_STATUS_READY; 00095 } 00096 00097 MPI_Send(&ebm_status, 1, MPI_INT, 0, TAG_EBM_STATUS, inter_comm); 00098 00099 break; 00100 } 00101 case TAG_EBM_STOP: 00102 { 00103 int tmp; 00104 MPI_Recv(&tmp, 1, MPI_INT, 0, TAG_EBM_STOP, inter_comm, NULL); 00105 done = 1; 00106 break; 00107 } 00108 default: 00109 { 00110 fprintf(stderr, "ERROR: Unknown message tag: %d\n", status.MPI_TAG); 00111 break; 00112 } 00113 } 00114 } // while (not done) 00115 00116 return 0; 00117 } 00118 00119 int EBM_driver::run_ebm(double year) { 00120 int ierr; 00121 00122 fprintf(stderr, "EBM driver: year = %1.1f. Running '%s'...\n", year, command.c_str()); 00123 00124 ierr = system(command.c_str()); 00125 00126 if (ierr != 0) { 00127 fprintf(stderr, "EBM driver: command exited with the return code %d\n", ierr); 00128 return ierr; 00129 } else { 00130 fprintf(stderr, "EBM driver: command executed succesfully.\n"); 00131 } 00132 00133 return 0; 00134 } 00135
1.7.3