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