Chaste Commit::29c3c4ab2bee00ddd311a035a1e522c03cbe928a
ExecutableSupport.cpp
1/*
2
3Copyright (c) 2005-2026, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, are permitted provided that the following conditions are met:
14 * Redistributions of source code must retain the above copyright notice,
15 this list of conditions and the following disclaimer.
16 * Redistributions in binary form must reproduce the above copyright notice,
17 this list of conditions and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19 * Neither the name of the University of Oxford nor the names of its
20 contributors may be used to endorse or promote products derived from this
21 software without specific prior written permission.
22
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#include "ExecutableSupport.hpp"
37
38#include "Version.hpp"
39
40#include <iostream>
41#include <sstream>
42#include <sys/utsname.h> // For uname
43#define ChasteGetCurrentTime() ChasteBuildInfo::GetCurrentTime()
44#include <hdf5.h>
45#include <parmetis.h>
46
47
49#include "CommandLineArguments.hpp"
50#include "PetscException.hpp"
51#include "PetscSetupUtils.hpp"
52#include "PetscTools.hpp"
53
54#define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the strstream deprecated warning for now (gcc4.3)
55#include <vtkVersion.h>
56
57#include <sundials/sundials_config.h>
58
59//#include <xsd/cxx/version.hxx>
60#include <xercesc/util/XercesVersion.hpp>
61
62// Check whether the version of ParMETIS being used is the one we wanted
63#ifdef CHASTE_PARMETIS_REQUIRED
64#ifdef PARMETIS_MAJOR_VERSION
65#if PARMETIS_MAJOR_VERSION != CHASTE_PARMETIS_REQUIRED
66#error "Wrong ParMETIS version found: " #CHASTE_PARMETIS_REQUIRED " requested but " #PARMETIS_MAJOR_VERSION " present"
67#endif
68#endif
69#endif
70
71#ifndef PARMETIS_MAJOR_VERSION
72// If there's no PARMETIS then assume we have Scotch
73#include <scotch/ptscotch.h>
74#endif
75
77
78void ExecutableSupport::SetOutputDirectory(const std::string& rOutputDirectory)
79{
80 if (FileFinder::IsAbsolutePath(rOutputDirectory))
81 {
83 }
84 else
85 {
87 }
88}
89
90void ExecutableSupport::InitializePetsc(int* pArgc, char*** pArgv)
91{
92 // Store the arguments in case other code needs them
95 // Initialise PETSc
96 PETSCEXCEPT(PetscInitialize(pArgc, pArgv, CHASTE_PETSC_NULLPTR, CHASTE_PETSC_NULLPTR));
97 // Set default output folder
99 {
100 // LCOV_EXCL_START
101 //depends on order of calls. Extract to method?
103 // LCOV_EXCL_STOP
104 }
105}
106
108{
109 // Compilation information
110 std::stringstream provenance_msg;
111 provenance_msg << "This version of Chaste was compiled on:\n";
112 provenance_msg << ChasteBuildInfo::GetBuildTime() << " by " << ChasteBuildInfo::GetBuilderUnameInfo() << " (uname)\n";
113 provenance_msg << "from revision " << ChasteBuildInfo::GetChasteRevision().GetShortCommit() << " with build type " << ChasteBuildInfo::GetBuildInformation() << ".\n\n";
114
115 // Only show one copy of copyright/header
117 {
118 std::cout << ChasteBuildInfo::GetLicenceText() << std::endl;
119
120 // Write provenance information to stdout
121 std::cout << provenance_msg.str() << std::flush;
122 }
123}
124
126{
128 {
129 // Information to show that Chaste is being run in parallel
131 std::cout << "Chaste launched on process " << PetscTools::GetMyRank()
132 << " of " << PetscTools::GetNumProcs() << "." << std::endl
133 << std::flush;
135 }
136}
137
138void ExecutableSupport::WriteMachineInfoFile(std::string fileBaseName)
139{
141 {
142 // LCOV_EXCL_START
143 //depends on order of calls. Extract to method?
145 // LCOV_EXCL_STOP
146 }
147 OutputFileHandler out_file_handler(mOutputDirectory, false);
148 std::stringstream file_name;
149 file_name << fileBaseName << "_" << PetscTools::GetMyRank() << ".txt";
150 out_stream out_file = out_file_handler.OpenOutputFile(file_name.str());
151 *out_file << "Process " << PetscTools::GetMyRank() << " of "
152 << PetscTools::GetNumProcs() << "." << std::endl
153 << std::flush;
154
155 struct utsname uts_info;
156 uname(&uts_info);
157
158 *out_file << "uname sysname = " << uts_info.sysname << std::endl
159 << std::flush;
160 *out_file << "uname nodename = " << uts_info.nodename << std::endl
161 << std::flush;
162 *out_file << "uname release = " << uts_info.release << std::endl
163 << std::flush;
164 *out_file << "uname version = " << uts_info.version << std::endl
165 << std::flush;
166 *out_file << "uname machine = " << uts_info.machine << std::endl
167 << std::flush;
168 char buffer[100];
169 FILE* system_info;
170
171#ifdef __APPLE__
172 *out_file << "\nInformation on number and type processors, and cache and memory sizes (in bytes)\n";
173 system_info = popen("sysctl hw.ncpu hw.physicalcpu machdep.cpu.brand_string hw.l1icachesize hw.l1dcachesize hw.l2cachesize hw.l3cachesize hw.memsize", "r");
174 while (fgets(buffer, 100, system_info) != NULL)
175 {
176 *out_file << buffer;
177 }
178 pclose(system_info);
179#else
180 //GNU
181 *out_file << "\nInformation on number and type of processors:\n";
182 system_info = popen("grep ^model.name /proc/cpuinfo", "r");
183 while (fgets(buffer, 100, system_info) != nullptr)
184 {
185 *out_file << buffer;
186 }
187 pclose(system_info);
188
189 *out_file << "\nInformation on processor caches, in the same order as above:\n";
190 system_info = popen("grep ^cache.size /proc/cpuinfo", "r");
191 while (fgets(buffer, 100, system_info) != nullptr)
192 {
193 *out_file << buffer;
194 }
195 pclose(system_info);
196
197 *out_file << "\nInformation on system memory:\n";
198 system_info = popen("grep ^MemTotal /proc/meminfo", "r");
199 while (fgets(buffer, 100, system_info) != nullptr)
200 {
201 *out_file << buffer;
202 }
203 pclose(system_info);
204#endif //end of __APPLE__ not defined
205
206 out_file->close();
207}
208
210{
212 {
213 // LCOV_EXCL_START
214 //depends on order of calls. Extract to method?
216 // LCOV_EXCL_STOP
217 }
218 OutputFileHandler out_file_handler(mOutputDirectory, false);
219 out_stream out_file = out_file_handler.OpenOutputFile("provenance_info_", PetscTools::GetMyRank(), ".txt");
220
221 // Compilation information
222 std::stringstream provenance_msg;
223 provenance_msg << "This version of Chaste was compiled on:\n";
224 provenance_msg << ChasteBuildInfo::GetBuildTime() << " by " << ChasteBuildInfo::GetBuilderUnameInfo() << " (uname)\n";
225 provenance_msg << "from revision " << ChasteBuildInfo::GetChasteRevision().GetShortCommit() << " with build type " << ChasteBuildInfo::GetBuildInformation() << ".\n\n";
226 *out_file << provenance_msg.str();
227
228 std::string output;
229 GetBuildInfo(output);
230 *out_file << output;
231
232 out_file->close();
233}
234
235void ExecutableSupport::GetBuildInfo(std::string& rInfo)
236{
237 std::stringstream output;
238 output << "<ChasteBuildInfo>\n";
239
240 output << "\t<ProvenanceInfo>\n";
241 output << "\t\t<VersionString>" << ChasteBuildInfo::GetVersionString() << "</VersionString> <!-- build specific -->\n";
242 output << "\t\t<Revision>" << ChasteBuildInfo::GetChasteRevision().rGetCommit() << "</Revision>\n";
243 output << "\t\t<IsWorkingCopyModified>" << (ChasteBuildInfo::GetChasteRevision().IsModified() ? "True" : "False") << "</IsWorkingCopyModified>\n";
244 output << "\t\t<BuildInformation>" << ChasteBuildInfo::GetBuildInformation() << "</BuildInformation>\n";
245 output << "\t\t<BuildTime>" << ChasteBuildInfo::GetBuildTime() << "</BuildTime>\n";
246 output << "\t\t<CurrentTime>" << ChasteGetCurrentTime() << "</CurrentTime>\n";
247 output << "\t\t<BuilderUnameInfo>" << ChasteBuildInfo::GetBuilderUnameInfo() << "</BuilderUnameInfo>\n";
248 output << "\t\t<ChasteTestOutputDirectory>" << OutputFileHandler::GetChasteTestOutputDirectory() << "</ChasteTestOutputDirectory>\n";
249
250 output << "\t\t<Projects>\n";
251 {
252 for (const auto& r_project : ChasteBuildInfo::GetProjectRevisions())
253 {
254 // LCOV_EXCL_START
255 // No projects are checked out for continuous builds normally!
256 output << "\t\t\t<Project>" << std::endl;
257 output << "\t\t\t\t<Name>" << r_project.first << "</Name>" << std::endl;
258 output << "\t\t\t\t<Revision>" << r_project.second.rGetCommit() << "</Revision>" << std::endl;
259 output << "\t\t\t\t<IsWorkingCopyModified>" << (r_project.second.IsModified() ? "True" : "False") << "</IsWorkingCopyModified>" << std::endl;
260 output << "\t\t\t</Project>" << std::endl;
261 // LCOV_EXCL_STOP
262 }
263 }
264 output << "\t\t</Projects>\n";
265
266 output << "\t</ProvenanceInfo>\n";
267
268 output << "\t<Compiler>\n";
269 output << "\t\t<NameAndVersion>" << ChasteBuildInfo::GetCompilerType() << ", version " << ChasteBuildInfo::GetCompilerVersion() << "</NameAndVersion>\n";
270 output << "\t\t<Flags>" << ChasteBuildInfo::GetCompilerFlags() << "</Flags>\n";
271 output << "\t</Compiler>\n";
272
273 output << "\t<Libraries>\n";
274
275 output << "\t\t<CompiledIn>\n";
276 output << "\t\t\t<Boost>" << BOOST_VERSION / 100000 << "." << BOOST_VERSION / 100 % 1000 << "." << BOOST_VERSION % 100 << "</Boost>\n";
277 output << "\t\t\t<HDF5>" << H5_VERS_MAJOR << "." << H5_VERS_MINOR << "." << H5_VERS_RELEASE << "</HDF5>\n";
278 // Parmetis and PT-Scotch are alternatives (only one is ever compiled in), so are kept adjacent
279 // rather than in strict alphabetical order.
280#ifdef PARMETIS_MAJOR_VERSION
281 output << "\t\t\t<Parmetis>" << PARMETIS_MAJOR_VERSION << "." << PARMETIS_MINOR_VERSION;
282#ifdef PARMETIS_SUBMINOR_VERSION // they only added this in v4.? !!
283 output << "." << PARMETIS_SUBMINOR_VERSION;
284#endif
285 output << "</Parmetis>" << std::endl;
286#else //PARMETIS_MAJOR_VERSION
287 // Assume we have Scotch
288 output << "\t\t\t<Parmetis>[NONE]</Parmetis>" << std::endl;
289 output << "\t\t\t<PT-Scotch>" << SCOTCH_VERSION<<"."<<SCOTCH_RELEASE<<"."<<SCOTCH_PATCHLEVEL<<"</PT-Scotch>"<< std::endl;
290#endif //no PARMETIS_MAJOR_VERSION
291 output << "\t\t\t<PETSc>" << PETSC_VERSION_MAJOR << "." << PETSC_VERSION_MINOR << "." << PETSC_VERSION_SUBMINOR << "</PETSc>\n";
292 output << "\t\t\t<SUNDIALS>" << SUNDIALS_VERSION << "</SUNDIALS>\n";
293 output << "\t\t\t<VTK>" << VTK_MAJOR_VERSION << "." << VTK_MINOR_VERSION << "</VTK>\n";
294 output << "\t\t\t<Xerces>" << XERCES_FULLVERSIONDOT << "</Xerces>\n";
295
296 output << "\t\t</CompiledIn>\n";
297
298 output << "\t\t<Binaries>\n";
299 output << "\t\t\t<XSD>" << ChasteBuildInfo::GetXsdVersion() << "</XSD>\n";
300 output << "\t\t</Binaries>\n";
301
302 output << "\t</Libraries>\n";
303
304 output << "\t<ChasteCodegenVersion>" << ChasteBuildInfo::GetChasteCodegenVersion() << "</ChasteCodegenVersion>\n";
305
306 output << "</ChasteBuildInfo>" << std::endl;
307 rInfo = output.str();
308}
309
310void ExecutableSupport::StandardStartup(int* pArgc, char*** pArgv)
311{
312 InitializePetsc(pArgc, pArgv);
315}
316
318{
319 InitializePetsc(pArgc, pArgv);
321}
322
323void ExecutableSupport::PrintError(const std::string& rMessage, bool masterOnly)
324{
325 if (!masterOnly || PetscTools::AmMaster())
326 {
327 // Write the error message to stderr
328 std::cerr << rMessage << std::endl;
329 }
330
331 // Write the error message to file
333 {
334 // LCOV_EXCL_START
335 //depends on order of calls. Extract to method?
337 // LCOV_EXCL_STOP
338 }
339 OutputFileHandler out_file_handler(mOutputDirectory, false);
340 out_stream out_file = out_file_handler.OpenOutputFile("chaste_errors_", PetscTools::GetMyRank(), ".txt", std::ios::out | std::ios::app);
341 *out_file << rMessage << std::endl;
342 out_file->close();
343}
344
345void ExecutableSupport::Print(const std::string& rMessage)
346{
348 {
349 // Write the error message to stdout
350 std::cout << rMessage << std::endl
351 << std::flush;
352 }
353}
354
356{
357 // Causes memory failure (and seg fault) in PETSc 3.2 with MPICH-1
359}
#define CHASTE_PETSC_NULLPTR
A macro to define PETSc null pointer based on the PETSc version.
static const char * GetBuilderUnameInfo()
static const char * GetCompilerFlags()
static SourceRevision GetChasteRevision()
static const char * GetBuildTime()
static std::string GetChasteCodegenVersion()
static std::string GetVersionString()
static const char * GetBuildInformation()
static const char * GetCompilerVersion()
static const char * GetCompilerType()
static std::map< std::string, SourceRevision > GetProjectRevisions()
static const char * GetXsdVersion()
static std::string GetLicenceText()
static CommandLineArguments * Instance()
static void Print(const std::string &rMessage)
static void SetOutputDirectory(const std::string &rOutputDirectory)
static void GetBuildInfo(std::string &rInfo)
static void WriteMachineInfoFile(std::string fileBaseName)
static void ShowParallelLaunching()
static void ShowCopyright()
static FileFinder mOutputDirectory
static void StartupWithoutShowingCopyright(int *pArgc, char ***pArgv)
static void StandardStartup(int *pArgc, char ***pArgv)
static void FinalizePetsc()
static void WriteProvenanceInfoFile()
static void PrintError(const std::string &rMessage, bool masterOnly=false)
static void InitializePetsc(int *pArgc, char ***pArgv)
static bool IsAbsolutePath(const std::string &rPath)
virtual void SetPath(const std::string &rPath, RelativeTo::Value relativeTo)
bool IsPathSet() const
static std::string GetChasteTestOutputDirectory()
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
static void CommonFinalize()
static bool AmMaster()
static bool IsParallel()
static void EndRoundRobin()
static unsigned GetMyRank()
static void BeginRoundRobin()
static unsigned GetNumProcs()
const std::string & rGetCommit() const
bool IsModified() const
std::string GetShortCommit() const