diff --git a/src/TNL/Devices/CudaDeviceInfo.cpp b/src/TNL/Devices/CudaDeviceInfo.cpp
index 3a4fc166741651c9a0837a60c8142d3d9f449e57..45199ecda1fa986dc68d0fd5386b06c09e8b7ecc 100644
--- a/src/TNL/Devices/CudaDeviceInfo.cpp
+++ b/src/TNL/Devices/CudaDeviceInfo.cpp
@@ -11,6 +11,7 @@
 #ifndef HAVE_CUDA
 
 #include <TNL/Devices/CudaDeviceInfo.h>
+#include <TNL/Logger.h>
 
 namespace TNL {
 namespace Devices {   
@@ -106,6 +107,12 @@ getCudaCores( int deviceNum )
    return 0;
 }
 
+void
+CudaDeviceInfo::
+writeDeviceInfo( Logger& logger )
+{
+}
+
 } // namespace Devices
 } // namespace TNL
 
diff --git a/src/TNL/Devices/CudaDeviceInfo.cu b/src/TNL/Devices/CudaDeviceInfo.cu
index 9f9e77235f2d70227542eb9790b7459778bf6751..84096561dcb11de412828b07e43403132af493f4 100644
--- a/src/TNL/Devices/CudaDeviceInfo.cu
+++ b/src/TNL/Devices/CudaDeviceInfo.cu
@@ -13,6 +13,7 @@
 #include <unordered_map>
 
 #include <TNL/Devices/CudaDeviceInfo.h>
+#include <TNL/Logger.h>
 
 namespace TNL {
 namespace Devices {
@@ -158,6 +159,35 @@ getCudaCores( int deviceNum )
            CudaDeviceInfo::getCudaCoresPerMultiprocessors( deviceNum );
 }
 
+void
+CudaDeviceInfo::
+writeDeviceInfo( Logger& logger )
+{
+   logger.writeParameter< String >( "CUDA GPU info", String("") );
+   // TODO: Printing all devices does not make sense until TNL can actually
+   //       use more than one device for computations. Printing only the active
+   //       device for now...
+//   int devices = getNumberOfDevices();
+//   writeParameter< int >( "Number of devices", devices, 1 );
+//   for( int i = 0; i < devices; i++ )
+//   {
+//      logger.writeParameter< int >( "Device no.", i, 1 );
+      int i = getActiveDevice();
+      logger.writeParameter< String >( "Name", getDeviceName( i ), 2 );
+      String deviceArch = String( getArchitectureMajor( i ) ) + "." +
+                              String( getArchitectureMinor( i ) );
+      logger.writeParameter< String >( "Architecture", deviceArch, 2 );
+      logger.writeParameter< int >( "CUDA cores", getCudaCores( i ), 2 );
+      double clockRate = ( double ) getClockRate( i ) / 1.0e3;
+      logger.writeParameter< double >( "Clock rate (in MHz)", clockRate, 2 );
+      double globalMemory = ( double ) getGlobalMemory( i ) / 1.0e9;
+      logger.writeParameter< double >( "Global memory (in GB)", globalMemory, 2 );
+      double memoryClockRate = ( double ) getMemoryClockRate( i ) / 1.0e3;
+      logger.writeParameter< double >( "Memory clock rate (in Mhz)", memoryClockRate, 2 );
+      logger.writeParameter< bool >( "ECC enabled", getECCEnabled( i ), 2 );
+//   }
+}
+
 } // namespace Devices
 } // namespace TNL
 
diff --git a/src/TNL/Devices/CudaDeviceInfo.h b/src/TNL/Devices/CudaDeviceInfo.h
index 545556d837a7f4c826cfdbfa154d726a56db9b09..b658e917703f8d97a7caca76c8055a845670506d 100644
--- a/src/TNL/Devices/CudaDeviceInfo.h
+++ b/src/TNL/Devices/CudaDeviceInfo.h
@@ -15,6 +15,9 @@
 #include <TNL/String.h>
 
 namespace TNL {
+
+class Logger;
+
 namespace Devices {
 
 class CudaDeviceInfo
@@ -47,8 +50,8 @@ class CudaDeviceInfo
 
       static int getCudaCores( int deviceNum );
 
+      static void writeDeviceInfo( Logger& logger );
 };
 
 } // namespace Devices
 } // namespace TNL
-
diff --git a/src/TNL/Devices/Host.cpp b/src/TNL/Devices/Host.cpp
index a4a40e96af43b1cbd96493bc3a0c14aec43e4b30..db56392bcb6ad8218e7f3a45f3d1173eae541d94 100644
--- a/src/TNL/Devices/Host.cpp
+++ b/src/TNL/Devices/Host.cpp
@@ -20,9 +20,11 @@
 #include <omp.h>
 #endif
 
+#include <TNL/tnlConfig.h>
 #include <TNL/Devices/Host.h>
 #include <TNL/Config/ConfigDescription.h>
 #include <TNL/Config/ParameterContainer.h>
+#include <TNL/Logger.h>
 
 namespace TNL {
 namespace Devices {   
@@ -90,6 +92,8 @@ Host::getCurrentTime( const char* format )
 int
 Host::getNumberOfProcessors( void )
 {
+   if( numberOfProcessors == 0 )
+      parseCPUInfo();
    return numberOfProcessors;
 }
 
@@ -103,18 +107,24 @@ Host::getOnlineCPUs( void )
 int
 Host::getNumberOfCores( int cpu_id )
 {
+   if( CPUCores == 0 )
+      parseCPUInfo();
    return CPUCores;
 }
 
 int
 Host::getNumberOfThreads( int cpu_id )
 {
+   if( CPUThreads == 0 )
+      parseCPUInfo();
    return CPUThreads;
 }
 
 String
 Host::getCPUModelName( int cpu_id )
 {
+   if( CPUModelName == "" )
+      parseCPUInfo();
    return CPUModelName;
 }
 
@@ -157,6 +167,35 @@ Host::getCPUCacheSizes( int cpu_id )
    return sizes;
 }
 
+void
+Host::
+writeDeviceInfo( Logger& logger )
+{
+   logger.writeParameter< String >( "Host name:", getHostname() );
+   logger.writeParameter< String >( "System:", getSystemName() );
+   logger.writeParameter< String >( "Release:", getSystemRelease() );
+   logger.writeParameter< String >( "Architecture:", getArchitecture() );
+   logger.writeParameter< char* >( "TNL Compiler:", ( char* ) TNL_CPP_COMPILER_NAME );
+   // FIXME: generalize for multi-socket systems, here we consider only the first found CPU
+   const int cpu_id = 0;
+   const int threads = getNumberOfThreads( cpu_id );
+   const int cores = getNumberOfCores( cpu_id );
+   int threadsPerCore = 0;
+   if( cores > 0 )
+      threadsPerCore = threads / cores;
+   logger.writeParameter< String >( "CPU info", String("") );
+   logger.writeParameter< String >( "Model name:", getCPUModelName( cpu_id ), 1 );
+   logger.writeParameter< int >( "Cores:", cores, 1 );
+   logger.writeParameter< int >( "Threads per core:", threadsPerCore, 1 );
+   logger.writeParameter< String >( "Max clock rate (in MHz):", getCPUMaxFrequency( cpu_id ) / 1000, 1 );
+   CacheSizes cacheSizes = getCPUCacheSizes( cpu_id );
+   String cacheInfo = String( cacheSizes.L1data ) + ", "
+                       + String( cacheSizes.L1instruction ) + ", "
+                       + String( cacheSizes.L2 ) + ", "
+                       + String( cacheSizes.L3 );
+   logger.writeParameter< String >( "Cache (L1d, L1i, L2, L3):", cacheInfo, 1 );
+}
+
 void
 Host::parseCPUInfo( void )
 {
diff --git a/src/TNL/Devices/Host.h b/src/TNL/Devices/Host.h
index 4bc622efb2836a320e7a0c9f105987824c1579bc..6c5c8a869321e24c4c4d19fc66ef4d7aea72b345 100644
--- a/src/TNL/Devices/Host.h
+++ b/src/TNL/Devices/Host.h
@@ -21,6 +21,8 @@ namespace Config {
    class ParameterContainer;
 }
 
+class Logger;
+
 namespace Devices {
 
 struct CacheSizes {
@@ -50,6 +52,8 @@ class Host
       static int    getCPUMaxFrequency( int cpu_id );
       static CacheSizes getCPUCacheSizes( int cpu_id );
 
+      static void writeDeviceInfo( Logger& logger );
+
       static size_t getFreeMemory();
  
       static void disableOMP();
diff --git a/src/TNL/Logger.cpp b/src/TNL/Logger.cpp
index 5a10205db06478e913f7308a03cb58b87bd25cfb..6287cc3b3337c8ec78ca4039e404e8a316f192f2 100644
--- a/src/TNL/Logger.cpp
+++ b/src/TNL/Logger.cpp
@@ -10,7 +10,6 @@
 
 #include <iomanip>
 #include <TNL/Logger.h>
-#include <TNL/tnlConfig.h>
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/CudaDeviceInfo.h>
 
@@ -45,53 +44,9 @@ void Logger :: writeSeparator()
 
 bool Logger :: writeSystemInformation( const Config::ParameterContainer& parameters )
 {
-   writeParameter< String >( "Host name:", Devices::Host::getHostname() );
-   writeParameter< String >( "Architecture:", Devices::Host::getArchitecture() );
-   // FIXME: generalize for multi-socket systems, here we consider only the first found CPU
-   const int cpu_id = 0;
-   const int threads = Devices::Host::getNumberOfThreads( cpu_id );
-   const int cores = Devices::Host::getNumberOfCores( cpu_id );
-   int threadsPerCore = threads / cores;
-   writeParameter< String >( "CPU info", String("") );
-   writeParameter< String >( "Model name:", Devices::Host::getCPUModelName( cpu_id ), 1 );
-   writeParameter< int >( "Cores:", cores, 1 );
-   writeParameter< int >( "Threads per core:", threadsPerCore, 1 );
-   writeParameter< String >( "Max clock rate (in MHz):", Devices::Host::getCPUMaxFrequency( cpu_id ) / 1000, 1 );
-   Devices::CacheSizes cacheSizes = Devices::Host::getCPUCacheSizes( cpu_id );
-   String cacheInfo = String( cacheSizes.L1data ) + ", "
-                       + String( cacheSizes.L1instruction ) + ", "
-                       + String( cacheSizes.L2 ) + ", "
-                       + String( cacheSizes.L3 );
-   writeParameter< String >( "Cache (L1d, L1i, L2, L3):", cacheInfo, 1 );
+   Devices::Host::writeDeviceInfo( *this );
    if( parameters.getParameter< String >( "device" ) == "cuda" )
-   {
-      writeParameter< String >( "CUDA GPU info", String("") );
-      // TODO: Printing all devices does not make sense, but in the future TNL
-      //       might use more than one device for computations. Printing only
-      //       the active device for now...
-//      int devices = Devices::CudaDeviceInfo::getNumberOfDevices();
-//      writeParameter< int >( "Number of devices", devices, 1 );
-//      for( int i = 0; i < devices; i++ )
-//      {
-//        writeParameter< int >( "Device no.", i, 1 );
-        int i = Devices::CudaDeviceInfo::getActiveDevice();
-        writeParameter< String >( "Name", Devices::CudaDeviceInfo::getDeviceName( i ), 2 );
-        String deviceArch = String( Devices::CudaDeviceInfo::getArchitectureMajor( i ) ) + "." +
-                                String( Devices::CudaDeviceInfo::getArchitectureMinor( i ) );
-        writeParameter< String >( "Architecture", deviceArch, 2 );
-        writeParameter< int >( "CUDA cores", Devices::CudaDeviceInfo::getCudaCores( i ), 2 );
-        double clockRate = ( double ) Devices::CudaDeviceInfo::getClockRate( i ) / 1.0e3;
-        writeParameter< double >( "Clock rate (in MHz)", clockRate, 2 );
-        double globalMemory = ( double ) Devices::CudaDeviceInfo::getGlobalMemory( i ) / 1.0e9;
-        writeParameter< double >( "Global memory (in GB)", globalMemory, 2 );
-        double memoryClockRate = ( double ) Devices::CudaDeviceInfo::getMemoryClockRate( i ) / 1.0e3;
-        writeParameter< double >( "Memory clock rate (in Mhz)", memoryClockRate, 2 );
-        writeParameter< bool >( "ECC enabled", Devices::CudaDeviceInfo::getECCEnabled( i ), 2 );
-//      }
-   }
-   writeParameter< String >( "System:", Devices::Host::getSystemName() );
-   writeParameter< String >( "Release:", Devices::Host::getSystemRelease() );
-   writeParameter< char* >( "TNL Compiler:", ( char* ) TNL_CPP_COMPILER_NAME );
+      Devices::CudaDeviceInfo::writeDeviceInfo( *this );
    return true;
 }
 
@@ -102,29 +57,28 @@ void Logger :: writeCurrentTime( const char* label )
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 template void Logger::writeParameter< char* >( const String&,
-                                                  const String&,
-                                                  const Config::ParameterContainer&,
-                                                  int );
+                                               const String&,
+                                               const Config::ParameterContainer&,
+                                               int );
 template void Logger::writeParameter< double >( const String&,
-                                                   const String&,
-                                                   const Config::ParameterContainer&,
-                                                   int );
-template void Logger::writeParameter< int >( const String&,
                                                 const String&,
                                                 const Config::ParameterContainer&,
                                                 int );
+template void Logger::writeParameter< int >( const String&,
+                                             const String&,
+                                             const Config::ParameterContainer&,
+                                             int );
 
 // TODO: fix this
 //template void Logger :: WriteParameter< char* >( const char*,
-//                                                    const char*&,
-//                                                    int );
+//                                                 const char*&,
+//                                                 int );
 template void Logger::writeParameter< double >( const String&,
-                                                   const double&,
-                                                   int );
-template void Logger::writeParameter< int >( const String&,
-                                                const int&,
+                                                const double&,
                                                 int );
-
+template void Logger::writeParameter< int >( const String&,
+                                             const int&,
+                                             int );
 #endif
 
 } // namespace TNL
diff --git a/src/TNL/Logger.h b/src/TNL/Logger.h
index 90dd927da5547af88ef5b885a2192c449fd3cd74..791398649d8d61f89a984cbb8255bb0be22a69d9 100644
--- a/src/TNL/Logger.h
+++ b/src/TNL/Logger.h
@@ -26,7 +26,6 @@ class Logger
 
    void writeSeparator();
 
-   // TODO: move this to Devices::Host
    bool writeSystemInformation( const Config::ParameterContainer& parameters );
  
 
@@ -59,28 +58,28 @@ namespace TNL {
 
 #ifdef TEMPLATE_EXPLICIT_INSTANTIATION
 extern template void Logger::writeParameter< char* >( const String&,
-                                                         const String&,
-                                                         const Config::ParameterContainer&,
-                                                         int );
+                                                      const String&,
+                                                      const Config::ParameterContainer&,
+                                                      int );
 extern template void Logger::writeParameter< double >( const String&,
-                                                          const String&,
-                                                          const Config::ParameterContainer&,
-                                                          int );
-extern template void Logger::writeParameter< int >( const String&,
                                                        const String&,
                                                        const Config::ParameterContainer&,
                                                        int );
+extern template void Logger::writeParameter< int >( const String&,
+                                                    const String&,
+                                                    const Config::ParameterContainer&,
+                                                    int );
 
 // TODO: fix this
 //extern template void Logger :: WriteParameter< char* >( const char*,
-//                                                           const char*&,
-//                                                           int );
+//                                                        const char*&,
+//                                                        int );
 extern template void Logger::writeParameter< double >( const String&,
-                                                          const double&,
-                                                          int );
-extern template void Logger::writeParameter< int >( const String&,
-                                                       const int&,
+                                                       const double&,
                                                        int );
+extern template void Logger::writeParameter< int >( const String&,
+                                                    const int&,
+                                                    int );
 #endif
 
 } // namespace TNL