ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkFFTWGlobalConfiguration.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 #ifndef __itkFFTWGlobalConfiguration_h
00019 #define __itkFFTWGlobalConfiguration_h
00020 
00021 #include "itkObject.h"
00022 //NOTE:  Need to have at least one itk include before
00023 //       the next defines in order to have USE_FFTWF,USE_FFTWD defined
00024 #if defined(USE_FFTWF) || defined(USE_FFTWD)
00025 
00026 #include "itkSimpleFastMutexLock.h"
00027 
00028 #include "itksys/SystemTools.hxx"
00029 #include "itksys/SystemInformation.hxx"
00030 #include "fftw3.h"
00031 #include <algorithm>
00032 #include <cctype>
00033 
00034 //* The fftw utilities help control the various strategies
00035 //available for controlling optimizations for the FFTW library.
00036 //
00037 //Environmental variables:
00038 //ITK_FFTW_PLAN_RIGOR   - Defines how agressive the generation of
00039 //                             wisdom should be.
00040 //ITK_FFTW_READ_WISDOM_CACHE  - Defines if a wisdom file cache should
00041 //                              be read if found.  (it is "On" by default)
00042 //ITK_FFTW_WRITE_WISDOM_CACHE  - Defines if generated wisdom file cache
00043 //                               should be written (it is "Off" by default)
00044 //ITK_FFTW_WISDOM_CACHE_BASE - Defines the base directory where the
00045 //                             fftw wisdom cache will be placed,
00046 //                             this is intended to be used with auto-
00047 //                             generated cache file names
00048 //ITK_FFTW_WISDOM_CACHE_FILE - Defines the full name of the cache
00049 //                             file to be generated.  If this is
00050 //                             set, then ITK_FFTW_WISDOM_CACHE_BASE
00051 //                             is ignored.
00052 //
00053 // The above behaviors can also be controlled by the application.
00054 //
00055 
00056 namespace itk
00057 {
00062 #ifdef _WIN32
00063 #define FFTWPathSep "\\"
00064 #else
00065 #define FFTWPathSep "/"
00066 #endif
00067 
00068 class ITK_EXPORT WisdomFilenameGeneratorBase
00069 {
00070   public:
00071     //The baseCacheDirectory from which to build the cache heirarchy
00072     virtual std::string GenerateWisdomFilename(const std::string baseCacheDirectory) const = 0;
00073     WisdomFilenameGeneratorBase() {};
00074     virtual ~WisdomFilenameGeneratorBase() {};
00075   private:
00076 };
00077 
00078 class ITK_EXPORT ManualWisdomFilenameGenerator: public WisdomFilenameGeneratorBase
00079 {
00080   public:
00081     ManualWisdomFilenameGenerator(const std::string wfn): m_WisdomFilename(wfn) { };
00082     void SetWisdomFilename(const std::string wfn)
00083       {
00084       this->m_WisdomFilename=wfn;
00085       }
00086     virtual std::string GenerateWisdomFilename(const std::string itkNotUsed(baseCacheDirectory) ) const
00087       {
00088        return this->m_WisdomFilename;
00089       }
00090   private:
00091     std::string m_WisdomFilename;
00092 };
00093 
00094 class ITK_EXPORT SimpleWisdomFilenameGenerator: public WisdomFilenameGeneratorBase
00095 {
00096   public:
00097     virtual std::string GenerateWisdomFilename(const std::string baseCacheDirectory) const
00098       {
00099        return baseCacheDirectory+FFTWPathSep+".itksimple.wisdom";
00100       }
00101 };
00102 
00103 class ITK_EXPORT HostnameWisdomFilenameGenerator: public WisdomFilenameGeneratorBase
00104 {
00105   public:
00106     virtual std::string GenerateWisdomFilename(const std::string baseCacheDirectory) const
00107       {
00108 
00109       itksys::SystemInformation hostInfo;
00110       hostInfo.RunOSCheck();
00111       return baseCacheDirectory+FFTWPathSep + ".itkwisdomfftw"+FFTWPathSep+".itk_"+hostInfo.GetHostname()+".wisdom";
00112       }
00113 };
00114 
00115 class ITK_EXPORT HardwareWisdomFilenameGenerator: public WisdomFilenameGeneratorBase
00116 {
00117 public:
00118     HardwareWisdomFilenameGenerator():
00119       m_UseOSName(true),
00120       m_UseOSRelease(false),
00121       m_UseOSVersion(false),
00122       m_UseOSPlatform(true),
00123       m_UseOSBitSize(true),
00124       m_UseNumberOfProcessors(true),
00125       m_UseVendorString(true),
00126       m_UseVendorID(false),
00127       m_UseTypeID(true),
00128       m_UseFamilyID(true),
00129       m_UseModelID(true),
00130       m_UseSteppingCode(true)
00131     {}
00132 
00133     virtual std::string GenerateWisdomFilename(const std::string baseCacheDirectory) const
00134       {
00135       //Now build the hardware string by system interogation
00136       itksys::SystemInformation hardwareInfo;
00137       hardwareInfo.RunCPUCheck();
00138       hardwareInfo.RunOSCheck();
00139       hardwareInfo.RunMemoryCheck();
00140       std::stringstream OSD("");
00141 
00142       if( this->m_UseOSName )
00143         {
00144         OSD << hardwareInfo.GetOSName() << "_";
00145         }
00146       if( this->m_UseOSRelease )
00147         {
00148         OSD << hardwareInfo.GetOSRelease() << "_";
00149         }
00150       if( this->m_UseOSVersion )
00151         {
00152         OSD << hardwareInfo.GetOSVersion() << "_";
00153         }
00154       if( this->m_UseOSPlatform )
00155         {
00156         OSD << hardwareInfo.GetOSPlatform() << "_";
00157         }
00158       if( this->m_UseOSBitSize )
00159         {
00160         const char * const bitsizeString=( hardwareInfo.Is64Bits() ) ? "64_":"32_";
00161         OSD << bitsizeString;
00162         }
00163       if( this->m_UseNumberOfProcessors )
00164         {
00165         OSD << hardwareInfo.GetNumberOfLogicalCPU() <<"x"<< hardwareInfo.GetNumberOfPhysicalCPU() << "_";
00166         }
00167       if( this->m_UseVendorString )
00168         {
00169         OSD << hardwareInfo.GetVendorString() << "_";
00170         }
00171       if( this->m_UseVendorID )
00172         {
00173         OSD << hardwareInfo.GetVendorID() << "_";
00174         }
00175       if( this->m_UseTypeID )
00176         {
00177         OSD << hardwareInfo.GetTypeID() << "_";
00178         }
00179       if( this->m_UseFamilyID )
00180         {
00181         OSD << hardwareInfo.GetFamilyID() << "_";
00182         }
00183       if( this->m_UseModelID )
00184         {
00185         OSD << hardwareInfo.GetModelID() << "_";
00186         }
00187       if( this->m_UseSteppingCode )
00188         {
00189         OSD << hardwareInfo.GetSteppingCode();
00190         }
00191       OSD << ".wisdom";
00192       std::string noSpaceStr=OSD.str();
00193       //Now remove spaces
00194       noSpaceStr.erase(std::remove_if(noSpaceStr.begin(), noSpaceStr.end(),::isspace), noSpaceStr.end());
00195       return baseCacheDirectory + FFTWPathSep + ".itkwisdomfftw" + FFTWPathSep + noSpaceStr;
00196       }
00197     void SetUseOSName(const bool flag) { this->m_UseOSName=flag; }
00198     void SetUseOSRelease(const bool flag) { this->m_UseOSRelease=flag; }
00199     void SetUseOSVersion(const bool flag) { this->m_UseOSVersion=flag; }
00200     void SetUseOSPlatform(const bool flag) { this->m_UseOSPlatform=flag; }
00201     void SetUseOSBitSize(const bool flag) { this->m_UseOSBitSize=flag; }
00202     void SetUseNumberOfProcessors(const bool flag) { this->m_UseNumberOfProcessors=flag; }
00203     void SetUseVendorString(const bool flag) { this->m_UseVendorString=flag; }
00204     void SetUseTypeID(const bool flag) { this->m_UseTypeID=flag; }
00205     void SetUseFamilyID(const bool flag) { this->m_UseFamilyID=flag; }
00206     void SetUseModelID(const bool flag) { this->m_UseModelID=flag; }
00207     void SetUseSteppingCode(const bool flag) { this->m_UseSteppingCode=flag; }
00208 
00209     bool GetUseOSName() const { return this->m_UseOSName; }
00210     bool GetUseOSRelease() const { return this->m_UseOSRelease; }
00211     bool GetUseOSVersion() const { return this->m_UseOSVersion; }
00212     bool GetUseOSPlatform() const { return this->m_UseOSPlatform; }
00213     bool GetUseOSBitSize() const { return this->m_UseOSBitSize; }
00214     bool GetUseNumberOfProcessors() const { return this->m_UseNumberOfProcessors; }
00215     bool GetUseVendorString() const { return this->m_UseVendorString; }
00216     bool GetUseTypeID() const { return this->m_UseTypeID; }
00217     bool GetUseFamilyID() const { return this->m_UseFamilyID; }
00218     bool GetUseModelID() const { return this->m_UseModelID; }
00219     bool GetUseSteppingCode() const { return this->m_UseSteppingCode; }
00220 private:
00221     bool m_UseOSName;
00222     bool m_UseOSRelease;
00223     bool m_UseOSVersion;
00224     bool m_UseOSPlatform;
00225     bool m_UseOSBitSize;
00226     bool m_UseNumberOfProcessors;
00227     bool m_UseVendorString;
00228     bool m_UseVendorID;
00229     bool m_UseTypeID;
00230     bool m_UseFamilyID;
00231     bool m_UseModelID;
00232     bool m_UseSteppingCode;
00233 };
00234 
00253 class ITK_EXPORT FFTWGlobalConfiguration: public Object
00254 {
00255 public:
00256 
00258   typedef FFTWGlobalConfiguration    Self;
00259   typedef Object                     Superclass;
00260   typedef SmartPointer< Self >       Pointer;
00261   typedef SmartPointer< const Self > ConstPointer;
00262 
00264   itkTypeMacro(FFTWGlobalConfiguration, Object);
00265 
00269   static void Lock();
00270   static void Unlock();
00272 
00277   static void SetNewWisdomAvailable( const bool & v )
00278   {
00279     GetInstance()->m_NewWisdomAvailable = v;
00280   }
00281   static bool GetNewWisdomAvailable()
00282   {
00283     return GetInstance()->m_NewWisdomAvailable;
00284   }
00286 
00295   static void SetPlanRigor( const int & v )
00296   {
00297     // use that method to check the value
00298     GetPlanRigorName( v );
00299     GetInstance()->m_PlanRigor = v;
00300   }
00302 
00303   static int GetPlanRigor()
00304   {
00305     return GetInstance()->m_PlanRigor;
00306   }
00307   static void SetPlanRigor( const std::string & name )
00308   {
00309     SetPlanRigor( GetPlanRigorValue( name ) );
00310   }
00311 
00313   static int GetPlanRigorValue( const std::string & name );
00314 
00316   static std::string GetPlanRigorName( const int & value );
00317 
00325   static void SetReadWisdomCache( const bool & v )
00326   {
00327     GetInstance()->m_ReadWisdomCache = v;
00328   }
00329 
00330   static bool GetReadWisdomCache()
00331   {
00332     return GetInstance()->m_ReadWisdomCache;
00333   }
00334 
00342   static void SetWriteWisdomCache( const bool & v )
00343   {
00344     GetInstance()->m_WriteWisdomCache = v;
00345   }
00346 
00347   static bool GetWriteWisdomCache()
00348   {
00349     return GetInstance()->m_WriteWisdomCache;
00350   }
00351 
00359   static void SetWisdomCacheBase( const std::string & v )
00360   {
00361     GetInstance()->m_WisdomCacheBase = v;
00362   }
00363 
00364   static std::string GetWisdomCacheBase()
00365   {
00366     return GetInstance()->m_WisdomCacheBase;
00367   }
00368 
00381   static void SetWisdomFilenameGenerator( WisdomFilenameGeneratorBase *wfg);
00382 
00396   static std::string GetWisdomFileDefaultBaseName();
00397 
00399   static bool ImportWisdomFileDouble( const std::string &fname );
00400   static bool ExportWisdomFileDouble( const std::string &fname );
00402 
00404   static bool ImportWisdomFileFloat( const std::string &fname );
00405   static bool ExportWisdomFileFloat( const std::string &fname );
00407 
00409   static bool ImportDefaultWisdomFileDouble();
00410   static bool ExportDefaultWisdomFileDouble();
00412 
00414   static bool ImportDefaultWisdomFileFloat();
00415   static bool ExportDefaultWisdomFileFloat();
00417 
00418 private:
00419   FFTWGlobalConfiguration(); //This will process env variables
00420   ~FFTWGlobalConfiguration(); //This will write cache file if requested.
00421 
00423   static Pointer GetInstance();
00424 
00429   itkFactorylessNewMacro(Self);
00430 
00431   FFTWGlobalConfiguration(const Self &); //purposely not implemented
00432   void operator=(const Self &); //purposely not implemented
00433 
00434   static Pointer                m_Instance;
00435   static SimpleFastMutexLock    m_CreationLock;
00436 
00437   SimpleFastMutexLock           m_Lock;
00438   bool                          m_NewWisdomAvailable;
00439   int                           m_PlanRigor;
00440   bool                          m_WriteWisdomCache;
00441   bool                          m_ReadWisdomCache;
00442   std::string                   m_WisdomCacheBase;
00443   //m_WriteWisdomCache Controls the behavior of default
00444   //wisdom file creation policies.
00445   WisdomFilenameGeneratorBase * m_WisdomFilenameGenerator;
00446 };
00447 }
00448 #endif
00449 #endif
00450