ergo
|
00001 /* Ergo, version 3.2, a program for linear scaling electronic structure 00002 * calculations. 00003 * Copyright (C) 2012 Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek. 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * Primary academic reference: 00019 * KohnâSham Density Functional Theory Electronic Structure Calculations 00020 * with Linearly Scaling Computational Time and Memory Usage, 00021 * Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek, 00022 * J. Chem. Theory Comput. 7, 340 (2011), 00023 * <http://dx.doi.org/10.1021/ct100611z> 00024 * 00025 * For further information about Ergo, see <http://www.ergoscf.org>. 00026 */ 00027 00036 #ifndef MAT_MATINCLUDE 00037 #define MAT_MATINCLUDE 00038 #include <iostream> 00039 #include <vector> 00040 #include <fstream> 00041 #include <ios> 00042 #include <cassert> 00043 #include <ctime> 00044 #include <limits> 00045 00046 #ifdef _OPENMP 00047 #include <omp.h> 00048 #endif 00049 00050 #include "Failure.h" 00051 #include "DebugPolicies.h" 00052 #include "SizesAndBlocks.h" 00053 00054 #ifdef _OPENMP 00055 #define MAT_OMP_INIT enum omp_failType {noFail = 0, standardFail, matFail}; \ 00056 volatile omp_failType omp_fail = noFail; \ 00057 std::exception omp_exce; \ 00058 Failure omp_matFail; \ 00059 omp_set_nested(true); 00060 // if (omp_fail == noFail) { 00061 #define MAT_OMP_START try { 00062 #define MAT_OMP_END } \ 00063 catch(Failure & omp_fail_caught) { \ 00064 omp_fail = matFail; omp_matFail = omp_fail_caught; } \ 00065 catch(std::exception & omp_exce_caught) { \ 00066 omp_fail = standardFail; omp_exce = omp_exce_caught; } 00067 #define MAT_OMP_FINALIZE if(omp_fail) \ 00068 { std::cerr<<"Exception was thrown in OpenMP parallel region\n"; \ 00069 switch (omp_fail) { \ 00070 case standardFail: throw omp_exce; break; \ 00071 case matFail: throw omp_matFail; break; \ 00072 default: throw Failure("Odd error in omp parallel loop\n");} \ 00073 } 00074 #else 00075 #define MAT_OMP_INIT 00076 #define MAT_OMP_START 00077 #define MAT_OMP_END 00078 #define MAT_OMP_FINALIZE 00079 #endif 00080 00081 namespace mat{ 00082 class Params { 00083 protected: 00084 #ifdef _OPENMP 00085 static unsigned int nProcs; 00086 static unsigned int matrixParallelLevel; 00087 #endif 00088 public: 00089 static unsigned int getNProcs() { 00090 #ifdef _OPENMP 00091 if (nProcs == 0) 00092 throw Failure("mat::Params::getNProcs(): nProcs == 0 Forgot to call setNProcs()?"); 00093 return nProcs; 00094 #else 00095 return 1; 00096 #endif 00097 } 00098 static void setNProcs(unsigned int const nP) { 00099 #ifdef _OPENMP 00100 nProcs = nP; 00101 #endif 00102 } 00103 static unsigned int getMatrixParallelLevel() { 00104 #ifdef _OPENMP 00105 if (matrixParallelLevel == 0) 00106 throw Failure("mat::Params::getMatrixParallelLevel(): matrixParallelLevel == 0 Forgot to call setMatrixParallelLevel()?"); 00107 return matrixParallelLevel; 00108 #else 00109 return 0; 00110 #endif 00111 } 00112 static void setMatrixParallelLevel(unsigned int const mPL) { 00113 #ifdef _OPENMP 00114 matrixParallelLevel = mPL; 00115 #endif 00116 } 00117 }; 00118 00119 00120 00121 enum property {zero, ful}; 00122 enum normType {frobNorm, euclNorm, mixedNorm}; 00123 normType getNormType(const char* normStr); 00124 std::string getNormTypeString(normType nType); 00125 00126 00127 template<typename Treal> 00128 inline static Treal getRelPrecision() { 00129 throw Failure("getPrecision() : The used type is not supported by" 00130 " getPrecision() "); 00131 } 00132 template<> 00133 inline long double getRelPrecision<long double>() { 00134 return std::numeric_limits<long double>::epsilon(); 00135 } 00136 template<> 00137 inline double getRelPrecision<double>() { 00138 return std::numeric_limits<double>::epsilon(); 00139 } 00140 template<> 00141 inline float getRelPrecision<float>() { 00142 return std::numeric_limits<float>::epsilon(); 00143 } 00144 00145 class Time { 00146 static double get_wall_seconds(); 00147 double ticTime; 00148 public: 00149 Time(); 00150 void tic(); 00151 float toc(); 00152 }; 00153 00154 class MemUsage { 00155 private: 00156 static int getNumberFromBuffer(const char* buffer, const char* s); 00157 public: 00158 struct Values { 00159 float res; 00160 float virt; 00161 float peak; 00162 Values() : res(0), virt(0), peak(0) { } 00163 }; 00164 static void getMemUsage(Values & values); 00165 }; 00166 00167 } /* end namespace mat */ 00168 #endif