Line data Source code
1 : /*
2 : * Copyright (c) 2010-2014: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 : #include <stack>
33 : #include <cstdlib>
34 : #include <string>
35 : #include "ug.h"
36 : #include "common/error.h"
37 : #include "common/log.h"
38 : #include "common/util/path_provider.h"
39 : #include "common/util/os_info.h"
40 : #include "common/profiler/profiler.h"
41 : #include "common/profiler/profile_node.h"
42 :
43 : #include "common/profiler/memtracker.h"
44 :
45 : #ifdef UG_PARALLEL
46 : #include "pcl/pcl.h"
47 : #endif
48 : #ifdef UG_BRIDGE
49 : #include "bridge/bridge.h"
50 : #endif
51 : #ifdef UG_PLUGINS
52 : #include "common/util/plugin_util.h"
53 : #endif
54 :
55 :
56 : /** Current ug version */
57 : // ATTENTION: Please do not change the ug-version on your own!
58 : // If you changed something that requires a new version number, please contact
59 : // sreiter@gcsc.uni-frankfurt.de (for the moment...)
60 : // See docs/ug4/additional_pages/releases.doxygen for information on the different releases.
61 : std::string gUGVersionString("4.0.2");
62 :
63 :
64 : /** Tells whether profile-output is desired on exit.*/
65 : // only visible in this file!
66 : static bool outputProfileStats = false;
67 :
68 :
69 : namespace ug
70 : {
71 :
72 : static bool s_abortRun = false;
73 :
74 :
75 0 : UG_API std::string UGGetVersionString()
76 : {
77 0 : return gUGVersionString;
78 : }
79 :
80 :
81 : /**
82 : * init app, script and data paths
83 : */
84 1 : bool InitPaths(const char* argv0)
85 : {
86 : PROFILE_FUNC();
87 : //The method currently only works if the path is explicitly specified
88 : //during startup or if UG4_ROOT is defined.
89 :
90 : // extract the application path.
91 1 : char* ug4Root = getenv("UG4_ROOT");
92 1 : const char* pathSep = GetPathSeparator();
93 :
94 1 : std::string strRoot = "";
95 :
96 1 : if(ug4Root){
97 : strRoot = ug4Root;
98 : }
99 : else{
100 0 : std::string tPath = argv0;
101 : size_t pos = tPath.find_last_of(pathSep);
102 :
103 0 : if (pos != std::string::npos)
104 0 : tPath = tPath.substr(0, pos);
105 : else
106 : tPath = ".";
107 :
108 0 : strRoot = tPath + pathSep + "..";
109 : }
110 :
111 1 : if(!PathProvider::has_path(ROOT_PATH))
112 1 : PathProvider::set_path(ROOT_PATH, strRoot);
113 1 : if(!PathProvider::has_path(BIN_PATH))
114 3 : PathProvider::set_path(BIN_PATH, strRoot + pathSep + "bin");
115 1 : if(!PathProvider::has_path(SCRIPT_PATH))
116 3 : PathProvider::set_path(SCRIPT_PATH, strRoot + pathSep + "ugcore" + pathSep + "scripts");
117 1 : if(!PathProvider::has_path(PLUGIN_PATH))
118 2 : PathProvider::set_path(PLUGIN_PATH, strRoot + pathSep
119 1 : + "bin" + pathSep + "plugins");
120 1 : if(!PathProvider::has_path(APPS_PATH))
121 3 : PathProvider::set_path(APPS_PATH, strRoot + pathSep + "apps");
122 :
123 : // log the paths
124 : UG_DLOG(MAIN, 1, "app path set to: " << PathProvider::get_path(BIN_PATH) <<
125 : std::endl << "script path set to: " << PathProvider::get_path(SCRIPT_PATH) <<
126 : std::endl);
127 : /*
128 : if(!script::FileExists(PathProvider::get_path(BIN_PATH).c_str()) ||
129 : !script::FileExists(PathProvider::get_path(SCRIPT_PATH).c_str()) ||
130 : !script::FileExists(PathProvider::get_path(DATA_PATH).c_str()))
131 : {
132 : UG_LOG("WARNING: paths were not initialized correctly.\n");
133 : return false;
134 : }
135 : */
136 1 : return true;
137 : }
138 :
139 :
140 : /**
141 : * init app, script and data paths for a given root path
142 : */
143 0 : void SetRootPath(const std::string& strRoot)
144 : {
145 : PROFILE_FUNC();
146 0 : const char* pathSep = GetPathSeparator();
147 :
148 0 : PathProvider::set_path(ROOT_PATH, strRoot);
149 0 : PathProvider::set_path(BIN_PATH, strRoot + pathSep + "bin");
150 0 : PathProvider::set_path(SCRIPT_PATH, strRoot + pathSep + "ugcore" + pathSep + "scripts");
151 0 : PathProvider::set_path(PLUGIN_PATH, strRoot + pathSep + "bin" + pathSep + "plugins");
152 0 : PathProvider::set_path(APPS_PATH, strRoot + pathSep + "apps");
153 0 : }
154 :
155 : /**
156 : * init app, script and data paths for a given root path
157 : */
158 0 : void SetRootPath(const char* c_strRoot)
159 : {
160 0 : std::string strRoot(c_strRoot);
161 0 : SetRootPath(strRoot);
162 0 : }
163 :
164 : /**
165 : * init script path
166 : */
167 0 : void SetScriptPath(const std::string& strScript)
168 : {
169 : PROFILE_FUNC();
170 0 : PathProvider::set_path(SCRIPT_PATH, strScript);
171 0 : }
172 :
173 : /**
174 : * init script path
175 : */
176 0 : void SetScriptPath(const char* c_strScript)
177 : {
178 0 : std::string strScript(c_strScript);
179 0 : SetScriptPath(strScript);
180 0 : }
181 :
182 : /**
183 : * init apps path
184 : */
185 0 : void SetAppsPath(const std::string& strApps)
186 : {
187 : PROFILE_FUNC();
188 0 : PathProvider::set_path(APPS_PATH, strApps);
189 0 : }
190 :
191 : /**
192 : * init apps path
193 : */
194 0 : void SetAppsPath(const char* c_strApps)
195 : {
196 0 : std::string strApps(c_strApps);
197 0 : SetAppsPath(strApps);
198 0 : }
199 :
200 : /**
201 : * init plugin path
202 : */
203 0 : void SetPluginPath(const std::string& strPlugin)
204 : {
205 : PROFILE_FUNC();
206 0 : PathProvider::set_path(PLUGIN_PATH, strPlugin);
207 0 : }
208 :
209 : /**
210 : * init plugin path
211 : */
212 0 : void SetPluginPath(const char* c_strPlugin)
213 : {
214 0 : std::string strPlugin(c_strPlugin);
215 0 : SetPluginPath(strPlugin);
216 0 : }
217 :
218 : ////////////////////////////////////////////////////////////////////////
219 : /// initializes ug
220 : /** This method should be called at the beginning of main(...).
221 : * If ug has been compiled for parallel use (UG_PARALLEL is defined)
222 : * then this method will internally call pcl::Init.
223 : */
224 1 : int UGInit(int *argcp, char ***argvp, int parallelOutputProcRank)
225 : {
226 : PROFILE_FUNC();
227 : bool success = true;
228 :
229 : static bool firstCall = true;
230 1 : if (firstCall) {
231 1 : firstCall = false;
232 :
233 : #ifdef UG_PARALLEL
234 : pcl::Init(argcp, argvp);
235 : GetLogAssistant().set_output_process(parallelOutputProcRank);
236 : #endif
237 :
238 1 : success &= InitPaths((*argvp)[0]);
239 :
240 : #ifdef UG_BRIDGE
241 : try{
242 1 : bridge::InitBridge();
243 : }
244 0 : catch(UGError& err)
245 : {
246 : success &= false;
247 : UG_LOG("ERROR in UGInit: InitBridge failed!\n");
248 0 : }
249 : #endif
250 :
251 1 : if(UGInitPlugins() == false)
252 : {
253 : success &= false;
254 : UG_LOG("ERROR in UGInit: LoadPlugins failed!\n");
255 : }
256 : }
257 :
258 : // convert boolean success == true to int = 0.
259 1 : return !success;
260 : }
261 :
262 1 : int UGFinalizeNoPCLFinalize()
263 : {
264 1 : EnableMemTracker(false);
265 1 : ug::GetLogAssistant().flush_error_log();
266 :
267 1 : if (outputProfileStats) {
268 : UG_LOG(std::endl);
269 : // output the profiled data.
270 : PROFILER_UPDATE();
271 :
272 0 : if(GetLogAssistant().is_output_process()) {
273 : UG_LOG("\n");
274 : #ifdef UG_PROFILER
275 : UG_LOG(ug::GetProfileNode(NULL)->call_tree());
276 : #else
277 : PROFILER_OUTPUT();
278 : #endif
279 : }
280 :
281 : #ifdef UG_PROFILER
282 : //Shiny::ProfileManager::instance.destroy();
283 : #endif
284 : }
285 1 : return 0;
286 : }
287 : ////////////////////////////////////////////////////////////////////////
288 : /// finalizes ug
289 : /** If ug has been compiled for parallel use (UG_PARALLEL is defined)
290 : * then this method will internally call pcl::Finalize.
291 : */
292 1 : int UGFinalize()
293 : {
294 1 : UGFinalizeNoPCLFinalize();
295 :
296 : #ifdef UG_PARALLEL
297 : pcl::Finalize();
298 : #endif
299 :
300 1 : return 0;
301 : }
302 :
303 0 : void UGForceExit()
304 : {
305 : UG_LOG("--- ABORTING UG EXECUTION ---\n");
306 :
307 : #ifdef UG_PLUGINS
308 : // ? UnloadPlugins();
309 : #endif
310 :
311 0 : UGFinalizeNoPCLFinalize();
312 :
313 : #ifdef UG_PARALLEL
314 : if(pcl::NumProcs() > 1){
315 : // pcl::Abort will terminate execution
316 : pcl::Abort();
317 : // !!! this point is not reached !!!
318 : }
319 : #endif
320 :
321 0 : throw(SoftAbort("Exit forced by call to UGForceExit"));
322 : }
323 :
324 0 : void UGOutputProfileStatsOnExit(bool bEnable)
325 : {
326 0 : outputProfileStats = bEnable;
327 0 : }
328 :
329 :
330 : #ifdef UG_PLUGINS
331 1 : bool UGInitPlugins()
332 : {
333 3 : return LoadPlugins(PathProvider::get_path(PLUGIN_PATH).c_str(), "ug4/", bridge::GetUGRegistry());
334 : }
335 : #else
336 : bool UGInitPlugins()
337 : {
338 : return true;
339 : }
340 : #endif
341 :
342 :
343 0 : void AbortRun()
344 : {
345 0 : s_abortRun = true;
346 0 : }
347 :
348 0 : void ClearAbortRunFlag()
349 : {
350 0 : s_abortRun = false;
351 0 : }
352 :
353 0 : void TerminateAbortedRun()
354 : {
355 0 : if(s_abortRun == true){
356 0 : s_abortRun = false;
357 0 : UGForceExit();
358 : }
359 0 : }
360 :
361 : } //end of namespace ug
|