Chaste Release::3.1
ExecutableSupport.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "ExecutableSupport.hpp"
00037 
00038 #include <iostream>
00039 #include <sstream>
00040 #include <sys/utsname.h> // For uname
00041 #include <hdf5.h>
00042 
00043 #include <boost/foreach.hpp>
00044 typedef std::pair<std::string, std::string> StringPair;
00045 
00046 #include "CommandLineArguments.hpp"
00047 #include "Exception.hpp"
00048 #include "PetscTools.hpp"
00049 #include "PetscException.hpp"
00050 #include "Version.hpp"
00051 #include "ChasteSerialization.hpp"
00052 
00053 #ifdef CHASTE_VTK
00054 #define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the strstream deprecated warning for now (gcc4.3)
00055 #include <vtkVersion.h>
00056 #endif
00057 
00058 #ifdef CHASTE_CVODE
00059 #include <sundials/sundials_config.h>
00060 #endif
00061 //#include <xsd/cxx/version.hxx>
00062 
00063 FileFinder ExecutableSupport::mOutputDirectory;
00064 
00065 void ExecutableSupport::SetOutputDirectory(const std::string& rOutputDirectory)
00066 {
00067     if (FileFinder::IsAbsolutePath(rOutputDirectory))
00068     {
00069         mOutputDirectory.SetPath(rOutputDirectory, RelativeTo::Absolute);
00070     }
00071     else
00072     {
00073         mOutputDirectory.SetPath(rOutputDirectory, RelativeTo::ChasteTestOutput);
00074     }
00075 }
00076 
00077 void ExecutableSupport::InitializePetsc(int* pArgc, char*** pArgv)
00078 {
00079     // Store the arguments in case other code needs them
00080     CommandLineArguments::Instance()->p_argc = pArgc;
00081     CommandLineArguments::Instance()->p_argv = pArgv;
00082     // Initialise PETSc
00083     PETSCEXCEPT(PetscInitialize(pArgc, pArgv, PETSC_NULL, PETSC_NULL));
00084     // Set default output folder
00085     if (!mOutputDirectory.IsPathSet())
00086     {
00087         mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00088     }
00089 }
00090 
00091 void ExecutableSupport::ShowCopyright()
00092 {
00093     // Compilation information
00094     std::stringstream provenance_msg;
00095     provenance_msg << "This version of Chaste was compiled on:\n";
00096     provenance_msg << ChasteBuildInfo::GetBuildTime() << " by " << ChasteBuildInfo::GetBuilderUnameInfo() << " (uname)\n";
00097     provenance_msg << "from revision number " << ChasteBuildInfo::GetRevisionNumber() << " with build type " << ChasteBuildInfo::GetBuildInformation() << ".\n\n";
00098 
00099     // Only show one copy of copyright/header
00100     if (PetscTools::AmMaster())
00101     {
00102         std::cout << ChasteBuildInfo::GetLicenceText() << std::endl;
00103 
00104         // Write provenance information to stdout
00105         std::cout << provenance_msg.str() << std::flush;
00106     }
00107 }
00108 
00109 void ExecutableSupport::ShowParallelLaunching()
00110 {
00111     if (PetscTools::IsParallel())
00112     {
00113         // Information to show that Chaste is being run in parallel
00114         PetscTools::BeginRoundRobin();
00115         std::cout << "Chaste launched on process " << PetscTools::GetMyRank()
00116             << " of " << PetscTools::GetNumProcs() << "." << std::endl << std::flush;
00117         PetscTools::EndRoundRobin();
00118     }
00119 }
00120 
00121 void ExecutableSupport::WriteMachineInfoFile(std::string fileBaseName)
00122 {
00123     if (!mOutputDirectory.IsPathSet()) mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00124     OutputFileHandler out_file_handler(mOutputDirectory, false);
00125     std::stringstream file_name;
00126     file_name << fileBaseName << "_" << PetscTools::GetMyRank() << ".txt";
00127     out_stream out_file = out_file_handler.OpenOutputFile(file_name.str());
00128     *out_file << "Process " << PetscTools::GetMyRank() << " of "
00129         << PetscTools::GetNumProcs() << "." << std::endl << std::flush;
00130 
00131     struct utsname uts_info;
00132     uname(&uts_info);
00133 
00134     *out_file << "uname sysname  = " << uts_info.sysname << std::endl << std::flush;
00135     *out_file << "uname nodename = " << uts_info.nodename << std::endl << std::flush;
00136     *out_file << "uname release  = " << uts_info.release << std::endl << std::flush;
00137     *out_file << "uname version  = " << uts_info.version << std::endl << std::flush;
00138     *out_file << "uname machine  = " << uts_info.machine << std::endl << std::flush;
00139     char buffer[100];
00140     FILE * system_info;
00141 
00142     *out_file << "\nInformation on number and type of processors:\n";
00143     system_info = popen("grep ^model.name /proc/cpuinfo", "r");
00144     while ( fgets(buffer, 100, system_info) != NULL )
00145     {
00146         *out_file << buffer;
00147     }
00148     fclose(system_info);
00149 
00150     *out_file << "\nInformation on processor caches, in the same order as above:\n";
00151     system_info = popen("grep ^cache.size /proc/cpuinfo", "r");
00152     while ( fgets(buffer, 100, system_info) != NULL )
00153     {
00154         *out_file << buffer;
00155     }
00156     fclose(system_info);
00157 
00158     *out_file << "\nInformation on system memory:\n";
00159     system_info = popen("grep ^MemTotal /proc/meminfo", "r");
00160     while ( fgets(buffer, 100, system_info) != NULL )
00161     {
00162         *out_file << buffer;
00163     }
00164     fclose(system_info);
00165 
00166     out_file->close();
00167 }
00168 
00169 void ExecutableSupport::WriteProvenanceInfoFile()
00170 {
00171     if (!mOutputDirectory.IsPathSet()) mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00172     OutputFileHandler out_file_handler(mOutputDirectory, false);
00173     out_stream out_file = out_file_handler.OpenOutputFile("provenance_info_", PetscTools::GetMyRank(), ".txt");
00174 
00175     // Compilation information
00176     std::stringstream provenance_msg;
00177     provenance_msg << "This version of Chaste was compiled on:\n";
00178     provenance_msg << ChasteBuildInfo::GetBuildTime() << " by " << ChasteBuildInfo::GetBuilderUnameInfo() << " (uname)\n";
00179     provenance_msg << "from revision number " << ChasteBuildInfo::GetRevisionNumber() << " with build type " << ChasteBuildInfo::GetBuildInformation() << ".\n\n";
00180     *out_file << provenance_msg.str();
00181 
00182     WriteLibraryInfo( out_file );
00183 
00184     out_file->close();
00185 }
00186 
00187 void ExecutableSupport::WriteLibraryInfo( out_stream &outFile )
00188 {
00189     *outFile << "<ChasteBuildInfo>\n";
00190 
00191     *outFile << "\t<ProvenanceInfo>\n";
00192     *outFile << "\t\t<VersionString>"<< ChasteBuildInfo::GetVersionString() << "</VersionString> <!-- build specific -->\n";
00193     *outFile << "\t\t<IsWorkingCopyModified>"<< ChasteBuildInfo::IsWorkingCopyModified() << "</IsWorkingCopyModified>\n";
00194     *outFile << "\t\t<BuildInformation>"<< ChasteBuildInfo::GetBuildInformation() << "</BuildInformation>\n";
00195     *outFile << "\t\t<BuildTime>"<< ChasteBuildInfo::GetBuildTime() << "</BuildTime>\n";
00196     *outFile << "\t\t<CurrentTime>"<< ChasteBuildInfo::GetCurrentTime() << "</CurrentTime>\n";
00197     *outFile << "\t\t<BuilderUnameInfo>"<< ChasteBuildInfo::GetBuilderUnameInfo() << "</BuilderUnameInfo>\n";
00198     *outFile << "\t\t<Projects>\n";
00199     BOOST_FOREACH(const StringPair& r_project_version, ChasteBuildInfo::rGetProjectVersions())
00200     {
00201 #define COVERAGE_IGNORE
00202         // No projects are checked out for continuous builds normally!
00203         *outFile << "\t\t\t<Name>" << r_project_version.first << "</Name><Version>"
00204                  << r_project_version.second << "</Version>\n";
00205 #undef COVERAGE_IGNORE
00206     }
00207     *outFile << "\t\t</Projects>\n";
00208     *outFile << "\t</ProvenanceInfo>\n";
00209 
00210     *outFile << "\t<Compiler>\n";
00211     *outFile << "\t\t<NameAndVersion>" << ChasteBuildInfo::GetCompilerType() << ", version " << ChasteBuildInfo::GetCompilerVersion() << "</NameAndVersion>\n" ;
00212     *outFile << "\t\t<Flags>" << ChasteBuildInfo::GetCompilerFlags() << "</Flags>\n" ;
00213     *outFile << "\t</Compiler>\n";
00214 
00215     *outFile << "\t<Libraries>\n";
00216 
00217     *outFile << "\t\t<CompiledIn>\n";
00218     *outFile << "\t\t\t<PETSc>" << PETSC_VERSION_MAJOR << "." << PETSC_VERSION_MINOR << "." << PETSC_VERSION_SUBMINOR << "</PETSc>\n";
00219     *outFile << "\t\t\t<Boost>" << BOOST_VERSION  / 100000 << "." << BOOST_VERSION / 100 % 1000 << "." << BOOST_VERSION % 100 << "</Boost>\n";
00220     *outFile << "\t\t\t<HDF5>" << H5_VERS_MAJOR <<  "." << H5_VERS_MINOR << "." << H5_VERS_RELEASE << "</HDF5>\n";
00221     *outFile << "\t\t</CompiledIn>\n";
00222 
00223     *outFile << "\t\t<Binaries>\n";
00224     *outFile << "\t\t\t<XSD>" <<  ChasteBuildInfo::GetXsdVersion() << "</XSD>\n";
00225     *outFile << "\t\t</Binaries>\n";
00226 
00227     *outFile << "\t\t<Optional>\n";
00228 #ifdef CHASTE_VTK
00229     *outFile << "\t\t\t<VTK>" << VTK_MAJOR_VERSION << "." << VTK_MINOR_VERSION << "</VTK>\n";
00230 #else
00231     *outFile << "\t\t\t<VTK>no</VTK>\n";
00232 #endif
00233 
00234 #ifdef CHASTE_CVODE
00235     *outFile << "\t\t\t<SUNDIALS>" << SUNDIALS_PACKAGE_VERSION << "</SUNDIALS> <!-- includes Cvode of a different version number --> \n";
00236 #else
00237     *outFile << "\t\t\t<SUNDIALS>no</SUNDIALS>\n";
00238 #endif
00239 
00240 #ifdef CHASTE_ADAPTIVITY
00241     *outFile << "\t\t\t<Adaptivity>yes</Adaptivity>\n";
00242 #else
00243     *outFile << "\t\t\t<Adaptivity>no</Adaptivity>\n";
00244 #endif
00245     *outFile << "\t\t</Optional>\n";
00246 
00247     *outFile << "\t</Libraries>\n";
00248 
00249     *outFile << "</ChasteBuildInfo>\n";
00250 }
00251 
00252 void ExecutableSupport::StandardStartup(int* pArgc, char*** pArgv)
00253 {
00254     InitializePetsc(pArgc, pArgv);
00255     ShowCopyright();
00256     ShowParallelLaunching();
00257 }
00258 
00259 void ExecutableSupport::PrintError(const std::string& rMessage, bool masterOnly)
00260 {
00261     if (!masterOnly || PetscTools::AmMaster())
00262     {
00263         // Write the error message to stderr
00264         std::cerr << rMessage << std::endl;
00265     }
00266 
00267     // Write the error message to file
00268     if (!mOutputDirectory.IsPathSet()) mOutputDirectory.SetPath("", RelativeTo::ChasteTestOutput);
00269     OutputFileHandler out_file_handler(mOutputDirectory, false);
00270     out_stream out_file = out_file_handler.OpenOutputFile("chaste_errors_", PetscTools::GetMyRank(), ".txt", std::ios::out | std::ios::app);
00271     *out_file << rMessage << std::endl;
00272     out_file->close();
00273 }
00274 
00275 void ExecutableSupport::Print(const std::string& rMessage)
00276 {
00277     if (PetscTools::AmMaster())
00278     {
00279         // Write the error message to stdout
00280         std::cout << rMessage << std::endl << std::flush;
00281     }
00282 }
00283 
00284 void ExecutableSupport::FinalizePetsc()
00285 {
00286     // Causes memory failure (and seg fault) in PETSc 3.2 with MPICH-1
00287     PetscFinalize();
00288 }