ergo
matInclude.h
Go to the documentation of this file.
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