ExecutableSupport.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "ExecutableSupport.hpp"
00037
00038 #include "Version.hpp"
00039
00040 #include <iostream>
00041 #include <sstream>
00042 #ifdef _MSC_VER
00043 #include <windows.h>
00044
00045 #define GetCurrentTime() ChasteBuildInfo::GetCurrentTime()
00046 #define ChasteGetCurrentTime() GetCurrentTime()
00047 #else
00048 #include <sys/utsname.h>
00049 #define ChasteGetCurrentTime() ChasteBuildInfo::GetCurrentTime()
00050 #endif
00051 #include <hdf5.h>
00052 #include <parmetis.h>
00053
00054 #include <boost/foreach.hpp>
00055 typedef std::pair<std::string, std::string> StringPair;
00056
00057 #include "CommandLineArguments.hpp"
00058 #include "Exception.hpp"
00059 #include "PetscTools.hpp"
00060 #include "PetscException.hpp"
00061 #include "ChasteSerialization.hpp"
00062
00063 #ifdef CHASTE_VTK
00064 #define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the strstream deprecated warning for now (gcc4.3)
00065 #include <vtkVersion.h>
00066 #endif
00067
00068 #ifdef CHASTE_CVODE
00069 #include <sundials/sundials_config.h>
00070 #endif
00071
00072
00073
00074 #ifdef CHASTE_PARMETIS_REQUIRED
00075 # if PARMETIS_MAJOR_VERSION != CHASTE_PARMETIS_REQUIRED
00076 # error "Wrong ParMETIS version found: " #CHASTE_PARMETIS_REQUIRED " requested but " #PARMETIS_MAJOR_VERSION " present"
00077 # endif
00078 #endif
00079
00080 FileFinder ExecutableSupport::mOutputDirectory;
00081
00082 void ExecutableSupport::SetOutputDirectory(const std::string& rOutputDirectory)
00083 {
00084 if (FileFinder::IsAbsolutePath(rOutputDirectory))
00085 {
00086 mOutputDirectory.SetPath(rOutputDirectory, RelativeTo::Absolute);
00087 }
00088 else
00089 {
00090 mOutputDirectory.SetPath(rOutputDirectory, RelativeTo::ChasteTestOutput);
00091 }
00092 }
00093
00094 void ExecutableSupport::InitializePetsc(int* pArgc, char*** pArgv)
00095 {
00096
00097 CommandLineArguments::Instance()->p_argc = pArgc;
00098 CommandLineArguments::Instance()->p_argv = pArgv;
00099
00100 PETSCEXCEPT(PetscInitialize(pArgc, pArgv, PETSC_NULL, PETSC_NULL));
00101
00102 if (!mOutputDirectory.IsPathSet())
00103 {
00104 #define COVERAGE_IGNORE
00105
00106 mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00107 #undef COVERAGE_IGNORE
00108 }
00109 }
00110
00111 void ExecutableSupport::ShowCopyright()
00112 {
00113
00114 std::stringstream provenance_msg;
00115 provenance_msg << "This version of Chaste was compiled on:\n";
00116 provenance_msg << ChasteBuildInfo::GetBuildTime() << " by " << ChasteBuildInfo::GetBuilderUnameInfo() << " (uname)\n";
00117 provenance_msg << "from revision number " << ChasteBuildInfo::GetRevisionNumber() << " with build type " << ChasteBuildInfo::GetBuildInformation() << ".\n\n";
00118
00119
00120 if (PetscTools::AmMaster())
00121 {
00122 std::cout << ChasteBuildInfo::GetLicenceText() << std::endl;
00123
00124
00125 std::cout << provenance_msg.str() << std::flush;
00126 }
00127 }
00128
00129 void ExecutableSupport::ShowParallelLaunching()
00130 {
00131 if (PetscTools::IsParallel())
00132 {
00133
00134 PetscTools::BeginRoundRobin();
00135 std::cout << "Chaste launched on process " << PetscTools::GetMyRank()
00136 << " of " << PetscTools::GetNumProcs() << "." << std::endl << std::flush;
00137 PetscTools::EndRoundRobin();
00138 }
00139 }
00140
00141 void ExecutableSupport::WriteMachineInfoFile(std::string fileBaseName)
00142 {
00143 if (!mOutputDirectory.IsPathSet())
00144 {
00145 #define COVERAGE_IGNORE
00146
00147 mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00148 #undef COVERAGE_IGNORE
00149 }
00150 OutputFileHandler out_file_handler(mOutputDirectory, false);
00151 std::stringstream file_name;
00152 file_name << fileBaseName << "_" << PetscTools::GetMyRank() << ".txt";
00153 out_stream out_file = out_file_handler.OpenOutputFile(file_name.str());
00154 *out_file << "Process " << PetscTools::GetMyRank() << " of "
00155 << PetscTools::GetNumProcs() << "." << std::endl << std::flush;
00156
00157 #ifdef _MSC_VER
00158
00159
00160
00161 *out_file << "uname sysname = " << "Microsoft Windows" << std::endl;
00162 #define INFO_BUFFER_SIZE 32767
00163 TCHAR info_buffer[INFO_BUFFER_SIZE];
00164 DWORD buffer_char_count = INFO_BUFFER_SIZE;
00165 if(!GetComputerName(info_buffer, &buffer_char_count))
00166 *out_file << "uname nodename = " << "Windows machine name is unknown" << std::endl;
00167 else
00168 *out_file << "uname nodename = " << info_buffer << std::endl;
00169
00170 OSVERSIONINFOEX os_info;
00171 ZeroMemory(&os_info, sizeof(OSVERSIONINFO));
00172 os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00173
00174 GetVersionEx((OSVERSIONINFO*) &os_info);
00175
00176
00177 if(os_info.dwMajorVersion < 6)
00178 {
00179 *out_file << "uname release = " << "Microsoft Windows Server 2003 R2 (or earlier)" << std::endl;
00180 }
00181 else {
00182
00183 if(os_info.dwMajorVersion > 6)
00184 {
00185 *out_file << "uname release = " << "Microsoft Windows (Later than Microsoft Windows 8)" << std::endl;
00186 }
00187 else
00188 {
00189 if(os_info.dwMinorVersion == 2)
00190 {
00191 if(os_info.wProductType == VER_NT_WORKSTATION)
00192 *out_file << "uname release = " << "Microsoft Windows 8" << std::endl;
00193 else
00194 *out_file << "uname release = " << "Microsoft Windows Server 2012" << std::endl;
00195 }
00196 else if(os_info.dwMinorVersion == 1)
00197 {
00198 if(os_info.wProductType == VER_NT_WORKSTATION)
00199 *out_file << "uname release = " << "Microsoft Windows 7" << std::endl;
00200 else
00201 *out_file << "uname release = " << "Microsoft Windows Server 2008 R2" << std::endl;
00202 }
00203 else if(os_info.dwMinorVersion == 0)
00204 {
00205 if(os_info.wProductType == VER_NT_WORKSTATION)
00206 *out_file << "uname release = " << "Microsoft Windows Server 2008" << std::endl;
00207 else
00208 *out_file << "uname release = " << "Microsoft Windows Vista" << std::endl;
00209 }
00210 }
00211 }
00212 *out_file << "uname version = " << os_info.dwMajorVersion << "." << os_info.dwMinorVersion << std::endl;
00213
00214
00215
00216 SYSTEM_INFO sys_info;
00217 GetSystemInfo(&sys_info);
00218 switch (sys_info.wProcessorArchitecture)
00219 {
00220 case PROCESSOR_ARCHITECTURE_AMD64:
00221 *out_file << "uname machine = " << "x64 (AMD or Intel)" << std::endl;
00222 break;
00223 case PROCESSOR_ARCHITECTURE_ARM:
00224 *out_file << "uname machine = " << "ARM" << std::endl;
00225 break;
00226 case PROCESSOR_ARCHITECTURE_IA64:
00227 *out_file << "uname machine = " << "Intel Itanium-based" << std::endl;
00228 break;
00229 case PROCESSOR_ARCHITECTURE_INTEL:
00230 *out_file << "uname machine = " << "x86" << std::endl;
00231 break;
00232 case PROCESSOR_ARCHITECTURE_UNKNOWN:
00233 *out_file << "uname machine = " << "Unknown Architecture" << std::endl;
00234 break;
00235 default:
00236 *out_file << "uname machine = " << "Other Architecture. Code = " << sys_info.wProcessorArchitecture << std::endl;
00237 break;
00238 }
00239
00240 *out_file << "\nInformation on number and type of processors:" << std::endl;
00241 *out_file << sys_info.dwNumberOfProcessors;
00242 *out_file << "\nInformation on processor caches, in the same order as above:" << std::endl;
00243 *out_file << "Unknown" << std::endl;
00244
00245
00246 MEMORYSTATUSEX mem_status;
00247 mem_status.dwLength = sizeof (mem_status);
00248 GlobalMemoryStatusEx (&mem_status);
00249 *out_file << "\nInformation on system memory:" << std::endl;
00250 *out_file << mem_status.ullTotalPhys/1024 << " kB" << std::endl;
00251 #else
00252 struct utsname uts_info;
00253 uname(&uts_info);
00254
00255 *out_file << "uname sysname = " << uts_info.sysname << std::endl << std::flush;
00256 *out_file << "uname nodename = " << uts_info.nodename << std::endl << std::flush;
00257 *out_file << "uname release = " << uts_info.release << std::endl << std::flush;
00258 *out_file << "uname version = " << uts_info.version << std::endl << std::flush;
00259 *out_file << "uname machine = " << uts_info.machine << std::endl << std::flush;
00260 char buffer[100];
00261 FILE* system_info;
00262
00263 #ifdef __APPLE__
00264 *out_file << "\nInformation on number and type processors, and cache and memory sizes (in bytes)\n";
00265 system_info = popen("sysctl hw.ncpu hw.physicalcpu machdep.cpu.brand_string hw.l1icachesize hw.l1dcachesize hw.l2cachesize hw.l3cachesize hw.memsize", "r");
00266 while ( fgets(buffer, 100, system_info) != NULL )
00267 {
00268 *out_file << buffer;
00269 }
00270 fclose(system_info);
00271 #else
00272
00273 *out_file << "\nInformation on number and type of processors:\n";
00274 system_info = popen("grep ^model.name /proc/cpuinfo", "r");
00275 while ( fgets(buffer, 100, system_info) != NULL )
00276 {
00277 *out_file << buffer;
00278 }
00279 fclose(system_info);
00280
00281 *out_file << "\nInformation on processor caches, in the same order as above:\n";
00282 system_info = popen("grep ^cache.size /proc/cpuinfo", "r");
00283 while ( fgets(buffer, 100, system_info) != NULL )
00284 {
00285 *out_file << buffer;
00286 }
00287 fclose(system_info);
00288
00289 *out_file << "\nInformation on system memory:\n";
00290 system_info = popen("grep ^MemTotal /proc/meminfo", "r");
00291 while ( fgets(buffer, 100, system_info) != NULL )
00292 {
00293 *out_file << buffer;
00294 }
00295 fclose(system_info);
00296 #endif //end of __APPLE__ not defined
00297 #endif //end of _MSC_VER not defined
00298
00299 out_file->close();
00300 }
00301
00302 void ExecutableSupport::WriteProvenanceInfoFile()
00303 {
00304 if (!mOutputDirectory.IsPathSet())
00305 {
00306 #define COVERAGE_IGNORE
00307
00308 mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00309 #undef COVERAGE_IGNORE
00310 }
00311 OutputFileHandler out_file_handler(mOutputDirectory, false);
00312 out_stream out_file = out_file_handler.OpenOutputFile("provenance_info_", PetscTools::GetMyRank(), ".txt");
00313
00314
00315 std::stringstream provenance_msg;
00316 provenance_msg << "This version of Chaste was compiled on:\n";
00317 provenance_msg << ChasteBuildInfo::GetBuildTime() << " by " << ChasteBuildInfo::GetBuilderUnameInfo() << " (uname)\n";
00318 provenance_msg << "from revision number " << ChasteBuildInfo::GetRevisionNumber() << " with build type " << ChasteBuildInfo::GetBuildInformation() << ".\n\n";
00319 *out_file << provenance_msg.str();
00320
00321 std::string output;
00322 GetBuildInfo(output);
00323 *out_file << output;
00324
00325 out_file->close();
00326 }
00327
00328 void ExecutableSupport::GetBuildInfo(std::string& rInfo)
00329 {
00330 std::stringstream output;
00331 output << "<ChasteBuildInfo>\n";
00332
00333 output << "\t<ProvenanceInfo>\n";
00334 output << "\t\t<VersionString>"<< ChasteBuildInfo::GetVersionString() << "</VersionString> <!-- build specific -->\n";
00335 output << "\t\t<IsWorkingCopyModified>"<< ChasteBuildInfo::IsWorkingCopyModified() << "</IsWorkingCopyModified>\n";
00336 output << "\t\t<BuildInformation>"<< ChasteBuildInfo::GetBuildInformation() << "</BuildInformation>\n";
00337 output << "\t\t<BuildTime>"<< ChasteBuildInfo::GetBuildTime() << "</BuildTime>\n";
00338 output << "\t\t<CurrentTime>"<< ChasteGetCurrentTime() << "</CurrentTime>\n";
00339 output << "\t\t<BuilderUnameInfo>"<< ChasteBuildInfo::GetBuilderUnameInfo() << "</BuilderUnameInfo>\n";
00340 output << "\t\t<Projects>\n";
00341 BOOST_FOREACH(const StringPair& r_project_version, ChasteBuildInfo::rGetProjectVersions())
00342 {
00343 #define COVERAGE_IGNORE
00344
00345 output<< "\t\t\t<Name>" << r_project_version.first << "</Name><Version>"
00346 << r_project_version.second << "</Version>\n";
00347 #undef COVERAGE_IGNORE
00348 }
00349 output << "\t\t</Projects>\n";
00350 output << "\t</ProvenanceInfo>\n";
00351
00352 output << "\t<Compiler>\n";
00353 output << "\t\t<NameAndVersion>" << ChasteBuildInfo::GetCompilerType() << ", version " << ChasteBuildInfo::GetCompilerVersion() << "</NameAndVersion>\n" ;
00354 output << "\t\t<Flags>" << ChasteBuildInfo::GetCompilerFlags() << "</Flags>\n" ;
00355 output << "\t</Compiler>\n";
00356
00357 output << "\t<Libraries>\n";
00358
00359 output << "\t\t<CompiledIn>\n";
00360 output << "\t\t\t<PETSc>" << PETSC_VERSION_MAJOR << "." << PETSC_VERSION_MINOR << "." << PETSC_VERSION_SUBMINOR << "</PETSc>\n";
00361 output << "\t\t\t<Boost>" << BOOST_VERSION / 100000 << "." << BOOST_VERSION / 100 % 1000 << "." << BOOST_VERSION % 100 << "</Boost>\n";
00362 output << "\t\t\t<HDF5>" << H5_VERS_MAJOR << "." << H5_VERS_MINOR << "." << H5_VERS_RELEASE << "</HDF5>\n";
00363 output << "\t\t\t<Parmetis>" << PARMETIS_MAJOR_VERSION << "." << PARMETIS_MINOR_VERSION;
00364 #ifdef PARMETIS_SUBMINOR_VERSION // they only added this in v4.? !!
00365 output << "." << PARMETIS_SUBMINOR_VERSION;
00366 #endif
00367 output << "</Parmetis>" << std::endl;
00368 output << "\t\t</CompiledIn>\n";
00369
00370 output << "\t\t<Binaries>\n";
00371 output << "\t\t\t<XSD>" << ChasteBuildInfo::GetXsdVersion() << "</XSD>\n";
00372 output << "\t\t</Binaries>\n";
00373
00374 output << "\t\t<Optional>\n";
00375 #ifdef CHASTE_VTK
00376 output << "\t\t\t<VTK>" << VTK_MAJOR_VERSION << "." << VTK_MINOR_VERSION << "</VTK>\n";
00377 #else
00378 output << "\t\t\t<VTK>no</VTK>\n";
00379 #endif
00380
00381 #ifdef CHASTE_CVODE
00382 output << "\t\t\t<SUNDIALS>" << SUNDIALS_PACKAGE_VERSION << "</SUNDIALS> <!-- includes Cvode of a different version number --> \n";
00383 #else
00384 output << "\t\t\t<SUNDIALS>no</SUNDIALS>\n";
00385 #endif
00386 output << "\t\t</Optional>\n";
00387
00388 output << "\t</Libraries>\n";
00389
00390 output << "</ChasteBuildInfo>" << std::endl;
00391 rInfo = output.str();
00392 }
00393
00394 void ExecutableSupport::StandardStartup(int* pArgc, char*** pArgv)
00395 {
00396 InitializePetsc(pArgc, pArgv);
00397 ShowCopyright();
00398 ShowParallelLaunching();
00399 }
00400
00401 void ExecutableSupport::PrintError(const std::string& rMessage, bool masterOnly)
00402 {
00403 if (!masterOnly || PetscTools::AmMaster())
00404 {
00405
00406 std::cerr << rMessage << std::endl;
00407 }
00408
00409
00410 if (!mOutputDirectory.IsPathSet())
00411 {
00412 #define COVERAGE_IGNORE
00413
00414 mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00415 #undef COVERAGE_IGNORE
00416 }
00417 OutputFileHandler out_file_handler(mOutputDirectory, false);
00418 out_stream out_file = out_file_handler.OpenOutputFile("chaste_errors_", PetscTools::GetMyRank(), ".txt", std::ios::out | std::ios::app);
00419 *out_file << rMessage << std::endl;
00420 out_file->close();
00421 }
00422
00423 void ExecutableSupport::Print(const std::string& rMessage)
00424 {
00425 if (PetscTools::AmMaster())
00426 {
00427
00428 std::cout << rMessage << std::endl << std::flush;
00429 }
00430 }
00431
00432 void ExecutableSupport::FinalizePetsc()
00433 {
00434
00435 PetscFinalize();
00436 }