HermesCommon  3.0
api.cpp
1 // This file is part of Hermes2D
2 //
3 // Copyright (c) 2009 hp-FEM group at the University of Nevada, Reno (UNR).
4 // Email: hpfem-group@unr.edu, home page: http://www.hpfem.org/.
5 //
6 // Hermes2D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published
8 // by the Free Software Foundation; either version 2 of the License,
9 // or (at your option) any later version.
10 //
11 // Hermes2D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with Hermes2D; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 #include "api.h"
21 #include "config.h"
22 
23 #include "callstack.h"
24 #include "common.h"
25 #include "exceptions.h"
26 #include "matrix.h"
28 #if defined __GNUC__ && defined HAVE_BFD
29 #include <signal.h>
30 #include "third_party/backtrace.c"
31 #endif
32 namespace Hermes
33 {
34 #if defined __GNUC__ && defined HAVE_BFD
35  void hdl(int sig, siginfo_t *siginfo, void *context)
36  {
37  printf("Signal handler exception caught, Signal [number, error_number, code]: [%i, %i, %i].\n.", siginfo->si_signo, siginfo->si_errno, siginfo->si_code);
38 
39  void *array[100];
40  size_t size;
41 
42  // get void*'s for all entries on the stack
43  size = backtrace(array, 100);
44 
45  // print out all the frames to stderr
46  Hermes::backtrace_symbols_fd(array, size, 0);
47 
48  throw Hermes::Exceptions::Exception("signal caught");
49  }
50 #endif
51 
52  Api::Parameter::Parameter(int default_val)
53  {
54  this->default_val = default_val;
55  this->user_set = false;
56  }
57 
58  Api::Api()
59  {
60 #if defined __GNUC__ && defined HAVE_BFD
61  act.sa_sigaction = &hdl;
62  act.sa_flags = SA_SIGINFO;
63  sigaction(SIGSEGV, &this->act, 0);
64 #endif
65 
66  // Insert parameters.
67  this->parameters.insert(std::pair<HermesCommonApiParam, Parameter*>(Hermes::numThreads, new Parameter(NUM_THREADS)));
68  this->parameters.insert(std::pair<HermesCommonApiParam, Parameter*>(Hermes::matrixSolverType, new Parameter(SOLVER_UMFPACK)));
69  this->parameters.insert(std::pair<HermesCommonApiParam, Parameter*>(Hermes::directMatrixSolverType, new Parameter(SOLVER_UMFPACK)));
70 #ifdef _DEBUG
71  this->parameters.insert(std::pair<HermesCommonApiParam, Parameter*>(Hermes::showInternalWarnings, new Parameter(1)));
72 #else
73  this->parameters.insert(std::pair<HermesCommonApiParam, Parameter*>(Hermes::showInternalWarnings, new Parameter(0)));
74 #endif
75  this->parameters.insert(std::pair<HermesCommonApiParam, Parameter*>(Hermes::useAccelerators, new Parameter(1)));
76  this->parameters.insert(std::pair<HermesCommonApiParam, Parameter*>(Hermes::checkMeshesOnLoad, new Parameter(1)));
77 
78  // Set handlers.
79 #ifdef WITH_PARALUTION
80  this->setter_handlers.insert(std::pair<HermesCommonApiParam, typename Api::SetterHandler>(Hermes::numThreads, &ParalutionInitialization::set_threads_paralution));
81  this->value_setter_handlers.insert(std::pair<std::pair<HermesCommonApiParam, int>, typename Api::SetterHandler>(std::pair<HermesCommonApiParam, int>(Hermes::matrixSolverType, SOLVER_PARALUTION_ITERATIVE), &ParalutionInitialization::init_paralution));
82  this->value_setter_handlers.insert(std::pair<std::pair<HermesCommonApiParam, int>, typename Api::SetterHandler>(std::pair<HermesCommonApiParam, int>(Hermes::matrixSolverType, SOLVER_PARALUTION_AMG), &ParalutionInitialization::init_paralution));
83  this->change_handlers.insert(std::pair<std::pair<HermesCommonApiParam, int>, typename Api::SetterHandler>(std::pair<HermesCommonApiParam, int>(Hermes::matrixSolverType, SOLVER_PARALUTION_ITERATIVE), &ParalutionInitialization::deinit_paralution));
84  this->change_handlers.insert(std::pair<std::pair<HermesCommonApiParam, int>, typename Api::SetterHandler>(std::pair<HermesCommonApiParam, int>(Hermes::matrixSolverType, SOLVER_PARALUTION_AMG), &ParalutionInitialization::deinit_paralution));
85 #endif
86 
87  // Initialize TCMalloc (this line also serves for TCMalloc not to be linker-optimized out).
88 #ifdef WITH_TC_MALLOC
89  ::tc_set_new_mode(1);
90 #endif
91  }
92 
93  Api::~Api()
94  {
95  // Call the change_handlers upon exit.
96  for (std::map<HermesCommonApiParam, Parameter*>::iterator param_iterator = this->parameters.begin(); param_iterator != this->parameters.end(); param_iterator++)
97  {
98  std::map<std::pair<HermesCommonApiParam, int>, SetterHandler>::iterator change_handler_iterator = this->change_handlers.find(std::pair<HermesCommonApiParam, int>(param_iterator->first, param_iterator->second->user_set ? param_iterator->second->user_val : param_iterator->second->default_val));
99  if (change_handler_iterator != this->change_handlers.end())
100  change_handler_iterator->second();
101  }
102 
103  for (std::map<HermesCommonApiParam, Parameter*>::const_iterator it = this->parameters.begin(); it != this->parameters.end(); ++it)
104  delete it->second;
105  }
106 
107  int Api::get_integral_param_value(HermesCommonApiParam param)
108  {
109  if (this->parameters.empty())
110  {
111  Hermes::Api temp_api;
112  return temp_api.get_integral_param_value(param);
113  }
114  if (this->parameters.find(param) == parameters.end())
115  throw Hermes::Exceptions::Exception("Wrong Hermes::Api parameter name:%i", param);
116  if (this->parameters.find(param)->second->user_set)
117  return this->parameters.find(param)->second->user_val;
118  else
119  return this->parameters.find(param)->second->default_val;
120  }
121 
122  void Api::set_integral_param_value(HermesCommonApiParam param, int value)
123  {
124  if (this->parameters.find(param) == parameters.end())
125  throw Hermes::Exceptions::Exception("Wrong Hermes::Api parameter name:%i", param);
126 
127  // If already set, we might have to call some custom handler.
128  if (this->parameters.find(param)->second->user_set)
129  {
130  std::map<std::pair<HermesCommonApiParam, int>, SetterHandler>::iterator change_handler_iterator = this->change_handlers.find(std::pair<HermesCommonApiParam, int>(param, this->parameters.find(param)->second->user_val));
131  if (change_handler_iterator != this->change_handlers.end())
132  {
133  change_handler_iterator->second();
134  }
135  }
136  this->parameters.find(param)->second->user_set = true;
137  this->parameters.find(param)->second->user_val = value;
138 
139  // And now we might have to call some handler of the new_ value setting.
140  // First - generic.
141  std::map<HermesCommonApiParam, SetterHandler>::iterator setter_handler_iterator = this->setter_handlers.find(param);
142  if (setter_handler_iterator != this->setter_handlers.end())
143  {
144  setter_handler_iterator->second();
145  }
146 
147  // Second - specific.
148  std::map<std::pair<HermesCommonApiParam, int>, SetterHandler>::iterator value_setter_handler_iterator = this->value_setter_handlers.find(std::pair<HermesCommonApiParam, int>(param, this->parameters.find(param)->second->user_val));
149  if (value_setter_handler_iterator != this->value_setter_handlers.end())
150  {
151  value_setter_handler_iterator->second();
152  }
153  }
154 
155 #if defined(WIN32) || defined(_WINDOWS)
156  __declspec(dllexport) Hermes::Api HermesCommonApi;
157 #else
159 #endif
160 }
API Class containing settings for the whole HermesCommon.
Definition: api.h:44
General namespace for the Hermes library.
Exception interface Basically a std::exception, but with a constructor with string and with print_msg...
Definition: exceptions.h:49
Main Hermes API.
std::map< std::pair< HermesCommonApiParam, int >, SetterHandler > value_setter_handlers
Definition: api.h:84
PARALUTION solver interface.
void(* SetterHandler)()
Definition: api.h:54
std::map< HermesCommonApiParam, Parameter * > parameters
Definition: api.h:73
std::map< HermesCommonApiParam, SetterHandler > setter_handlers
Definition: api.h:79
HERMES_COMMON_API Hermes::Api HermesCommonApi
Global instance used inside Hermes which is also accessible to users.
Definition: api.cpp:158
std::map< std::pair< HermesCommonApiParam, int >, SetterHandler > change_handlers
Definition: api.h:90
File containing functionality for investigating call stack.
File containing definition of exceptions classes.
Basic matrix classes and operations.
HermesCommonApiParam
Enumeration of potential keys in the Api::parameters storage.
Definition: api.h:33
File containing common definitions, and basic global enums etc. for HermesCommon. ...
Parameter(int default_val)
Definition: api.cpp:52