diff --git a/src/Python/CMakeLists.txt b/src/Python/CMakeLists.txt
index 82186a4ef123f7d3943a08f97fe7a8f565e312bf..43f58d0805d302d6af5f6c7c5ed0525d612ac529 100644
--- a/src/Python/CMakeLists.txt
+++ b/src/Python/CMakeLists.txt
@@ -1,3 +1,2 @@
 INSTALL( FILES __init__.py
-         DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/TNL
-         PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
+         DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/TNL )
diff --git a/src/TNL/Containers/StaticVector.h b/src/TNL/Containers/StaticVector.h
index 095c9c1ffefd2c9364562f6e9a0d65ee15c33387..ca410edfefaf94e4d74b3c84b91b72fad0c4d07d 100644
--- a/src/TNL/Containers/StaticVector.h
+++ b/src/TNL/Containers/StaticVector.h
@@ -24,8 +24,6 @@ class StaticVector : public StaticArray< Size, Real >
    typedef StaticVector< Size, Real > ThisType;
    enum { size = Size };
 
-   using StaticArray< Size, Real >::operator=;
-
    __cuda_callable__
    StaticVector();
 
@@ -97,6 +95,23 @@ class StaticVector : public StaticArray< Size, Real >
 
    __cuda_callable__
    Real lpNorm( const Real& p ) const;
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< Size, Real >& operator=( const StaticVector< Size, Real >& vector )
+   {
+      StaticArray< Size, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< Size, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< Size, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
 template< typename Real >
@@ -107,8 +122,6 @@ class StaticVector< 1, Real > : public StaticArray< 1, Real >
    typedef StaticVector< 1, Real > ThisType;
    enum { size = 1 };
 
-   using StaticArray< 1, Real >::operator=;
-
    __cuda_callable__
    StaticVector();
 
@@ -180,6 +193,23 @@ class StaticVector< 1, Real > : public StaticArray< 1, Real >
 
    __cuda_callable__
    Real lpNorm( const Real& p ) const;   
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< 1, Real >& operator=( const StaticVector< 1, Real >& vector )
+   {
+      StaticArray< 1, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< 1, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< 1, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
 template< typename Real >
@@ -190,8 +220,6 @@ class StaticVector< 2, Real > : public StaticArray< 2, Real >
    typedef StaticVector< 2, Real > ThisType;
    enum { size = 2 };
 
-   using StaticArray< 2, Real >::operator=;
-
    __cuda_callable__
    StaticVector();
 
@@ -266,6 +294,23 @@ class StaticVector< 2, Real > : public StaticArray< 2, Real >
 
    __cuda_callable__
    Real lpNorm( const Real& p ) const;   
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< 2, Real >& operator=( const StaticVector< 2, Real >& vector )
+   {
+      StaticArray< 2, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< 2, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< 2, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
 template< typename Real >
@@ -276,8 +321,6 @@ class StaticVector< 3, Real > : public StaticArray< 3, Real >
    typedef StaticVector< 3, Real > ThisType;
    enum { size = 3 };
 
-   using StaticArray< 3, Real >::operator=;
-
    __cuda_callable__
    StaticVector();
 
@@ -352,6 +395,23 @@ class StaticVector< 3, Real > : public StaticArray< 3, Real >
 
    __cuda_callable__
    Real lpNorm( const Real& p ) const;   
+
+#ifdef HAVE_MIC
+   __cuda_callable__
+   inline StaticVector< 3, Real >& operator=( const StaticVector< 3, Real >& vector )
+   {
+      StaticArray< 3, Real >::operator=( vector );
+      return *this;
+   }
+
+   template< typename Vector >
+   __cuda_callable__
+   inline StaticVector< 3, Real >& operator=( const Vector& vector )
+   {
+      StaticArray< 3, Real >::operator=( vector );
+      return *this;
+   }
+#endif
 };
 
 template< int Size, typename Real, typename Scalar >
diff --git a/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h b/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h
index e72d92365c4c554a0803e79517da0b034428122b..4852a50358a615e02cd518a6ac0e71c4cc909657 100644
--- a/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h
+++ b/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h
@@ -86,7 +86,7 @@ getPartialDerivative( const PointType& v,
                       const Real& time ) const
 {
    const RealType& x = v.x();
-   RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / ( 2.0*M_PI );
+   RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / ( 2.0*M_PI );
    if( this->wavesNumber.x() != 0.0 && xp > this->wavesNumber.x() * this->waveLength.x() )
       return 0.0;
    if( YDiffOrder != 0 || ZDiffOrder != 0 )
@@ -239,4 +239,4 @@ getPartialDerivative( const PointType& v,
 
       } // namespace Analytic
    } // namespace Fucntions
-} // namespace TNL
\ No newline at end of file
+} // namespace TNL
diff --git a/src/TNL/Functions/Analytic/SinBumps_impl.h b/src/TNL/Functions/Analytic/SinBumps_impl.h
index befe83856099c89a3cd87e972a375fbf3df4d124..44ea88c3c57d9512d8854f58520e892037eea127 100644
--- a/src/TNL/Functions/Analytic/SinBumps_impl.h
+++ b/src/TNL/Functions/Analytic/SinBumps_impl.h
@@ -101,7 +101,7 @@ getPartialDerivative( const PointType& v,
       return 0.0;
    
    const RealType& x = v.x();
-   const RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   const RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
    if( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() )
       return 0.0;
   
@@ -162,8 +162,8 @@ getPartialDerivative( const PointType& v,
 
    const RealType& x = v.x();
    const RealType& y = v.y();
-   const RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
-   const RealType yp = ::fabs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
+   const RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   const RealType yp = abs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
    //std::cerr << "this->wavesNumber.x() = " << this->wavesNumber.x() << "fabs( x ) = " << fabs( x ) << " 2.0*M_PI * this->waveLength.x() * this->wavesNumber.x() = " << 2.0*M_PI * this->waveLength.x() * this->wavesNumber.x() << std::endl;
    if( ( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() ) ||
        ( this->wavesNumber.y() != 0.0 && yp > this->waveLength.y() * this->wavesNumber.y() ) )
@@ -235,9 +235,9 @@ getPartialDerivative( const PointType& v,
    const RealType& y = v.y();
    const RealType& z = v.z();
    
-   const RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
-   const RealType yp = ::fabs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
-   const RealType zp = ::fabs( z ) + sign( z ) * this->phase.z() * this->waveLength.z() / (2.0*M_PI);
+   const RealType xp = abs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI);
+   const RealType yp = abs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI);
+   const RealType zp = abs( z ) + sign( z ) * this->phase.z() * this->waveLength.z() / (2.0*M_PI);
 
    if( ( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() ) ||
        ( this->wavesNumber.y() != 0.0 && yp > this->waveLength.y() * this->wavesNumber.y() ) ||
diff --git a/src/TNL/Math.h b/src/TNL/Math.h
index ca15bb876d6da3accedb65f7b9c729a0b6d7cda9..e6993069e55cf9a999df56a06588ca13ac5231e3 100644
--- a/src/TNL/Math.h
+++ b/src/TNL/Math.h
@@ -30,9 +30,8 @@ using both_integral_or_floating = typename std::conditional<
 
 // 1. If both types are integral or floating-point, the larger type is selected.
 // 2. If one type is integral and the other floating-point, the floating-point type is selected.
-// This is necessary only due to the limitations of nvcc. Note that clang and gcc
-// can handle automatic promotion using a single-type template, exactly like
-// std::min and std::max are implemented in STL.
+// Casting both arguments to the same type is necessary because std::min and std::max
+// are implemented as a single-type template.
 template< typename T1, typename T2 >
 using larger_type = typename std::conditional<
          ( both_integral_or_floating< T1, T2 >::value && sizeof(T1) >= sizeof(T2) ) ||
diff --git a/src/TNL/Solvers/IterativeSolverMonitor.h b/src/TNL/Solvers/IterativeSolverMonitor.h
index 9dec90384a116cf1a9ae79d2cbbd1d6a3a28c47c..3180abb3c34641f7359710dd4e4d8fde44578e77 100644
--- a/src/TNL/Solvers/IterativeSolverMonitor.h
+++ b/src/TNL/Solvers/IterativeSolverMonitor.h
@@ -18,40 +18,36 @@ namespace Solvers {
 template< typename Real, typename Index>
 class IterativeSolverMonitor : public SolverMonitor
 {
-   public:
-
+public:
    typedef Index IndexType;
    typedef Real RealType;
 
    IterativeSolverMonitor();
 
+   void setStage( const std::string& stage );
+
    void setTime( const RealType& time );
 
    void setTimeStep( const RealType& timeStep );
 
-   void setStage( const std::string& stage );
-
    void setIterations( const IndexType& iterations );
 
    void setResidue( const RealType& residue );
 
    void setVerbose( const Index& verbose );
  
-   virtual void refresh( bool force = false );
-
-   protected:
+   virtual void refresh();
 
+protected:
    int getLineWidth();
 
-   RealType time;
-
-   RealType timeStep;
+   std::string stage, saved_stage;
 
-   std::string stage;
+   std::atomic_bool saved;
 
-   IndexType iterations;
+   RealType time, saved_time, timeStep, saved_timeStep, residue, saved_residue;
 
-   RealType residue;
+   IndexType iterations, saved_iterations;
 
    IndexType verbose;
 };
diff --git a/src/TNL/Solvers/IterativeSolverMonitor_impl.h b/src/TNL/Solvers/IterativeSolverMonitor_impl.h
index 6d9f6bfc7a0846ebacd18ff74bfe3abf0ddf799e..ef18320193dc83007fc87bd4e04e960f95c0ff0e 100644
--- a/src/TNL/Solvers/IterativeSolverMonitor_impl.h
+++ b/src/TNL/Solvers/IterativeSolverMonitor_impl.h
@@ -13,45 +13,66 @@
 #include <iomanip>
 #include <limits>
 
+// make sure to include the config before the check
+#include <TNL/tnlConfig.h>
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #include <unistd.h>
 #endif
 
+#include <TNL/Solvers/IterativeSolver.h>
+
 namespace TNL {
 namespace Solvers {   
 
 template< typename Real, typename Index>
 IterativeSolverMonitor< Real, Index > :: IterativeSolverMonitor()
 : SolverMonitor(),
+  stage( "" ),
+  saved_stage( "" ),
+  saved( false ),
   time( 0.0 ),
+  saved_time( 0.0 ),
   timeStep( 0.0 ),
-  stage( "" ),
+  saved_timeStep( 0.0 ),
+  residue( 0.0 ),
+  saved_residue( 0.0 ),
   iterations( 0 ),
-  residue( 0 ),
+  saved_iterations( 0 ),
   verbose( 1 )
 {
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: setTime( const RealType& time )
+void IterativeSolverMonitor< Real, Index > :: setStage( const std::string& stage )
 {
-   this->time = time;
+   // save the items after a complete stage
+   if( iterations > 0 ) {
+      saved_stage = this->stage;
+      saved_time = time;
+      saved_timeStep = timeStep;
+      saved_iterations = iterations;
+      saved_residue = residue;
+   }
+
+   // reset the current items
+   iterations = 0;
+   residue = 0.0;
+
+   this->stage = stage;
+   saved = true;
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: setTimeStep( const RealType& timeStep )
+void IterativeSolverMonitor< Real, Index > :: setTime( const RealType& time )
 {
-   this->timeStep = timeStep;
+   this->time = time;
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: setStage( const std::string& stage )
+void IterativeSolverMonitor< Real, Index > :: setTimeStep( const RealType& timeStep )
 {
-   this->stage = stage;
-   // reset numerical items displayed after stage
-   this->iterations = 0;
-   this->residue = 0.0;
+   this->timeStep = timeStep;
 }
 
 template< typename Real, typename Index>
@@ -73,47 +94,72 @@ void IterativeSolverMonitor< Real, Index > :: setVerbose( const Index& verbose )
 }
 
 template< typename Real, typename Index>
-void IterativeSolverMonitor< Real, Index > :: refresh( bool force )
+void IterativeSolverMonitor< Real, Index > :: refresh()
 {
-//   if( this->verbose > 0 && ( force || this->getIterations() % this->refreshRate == 0 ) )
-   if( this->verbose > 0 || force )
+   if( this->verbose > 0 )
    {
-      const int line_width = this->getLineWidth();
+      // Check if we should display the current values or the values saved after
+      // the previous stage. If the iterations cycle much faster than the solver
+      // monitor refreshes, we display only the values saved after the whole
+      // cycle to hide the irrelevant partial progress.
+      const bool saved = this->saved;
+      this->saved = false;
+
+      const int line_width = getLineWidth();
       int free = line_width ? line_width : std::numeric_limits<int>::max();
 
-      // FIXME: std::setw sets only minimum width, so free should be adjusted dynamically if more chars are actually written
-      std::cout << std::setprecision( 5 );
-      std::cout << "\33[2K\r ELA:" << std::setw( 8 ) << this->getElapsedTime()
-                << " T:"   << std::setw( 8 ) << this->time;
-      free -= 24;
-      if( this->timeStep > 0 ) {
-         std::cout << " TAU:" << std::setw( 8 ) << this->timeStep;
-         free -= 13;
+      auto real_to_string = []( Real value, int precision = 6 ) {
+         std::stringstream stream;
+         stream << std::setprecision( precision ) << value;
+         return stream.str();
+      };
+
+      auto print_item = [&free]( const std::string& item, int width = 0 ) {
+         width = min( free, (width) ? width : item.length() );
+         std::cout << std::setw( width ) << item.substr( 0, width );
+         free -= width;
+      };
+
+      // \33[2K erases the current line, see https://stackoverflow.com/a/35190285
+      std::cout << "\33[2K\r";
+
+      // FIXME: nvcc 8.0 ignores default parameter values for lambda functions in template functions, so we have to pass the defaults
+//      print_item( " ELA:" );
+      print_item( " ELA:", 0 );
+      print_item( real_to_string( getElapsedTime(), 5 ), 8 );
+//      print_item( " T:" );
+      print_item( " T:", 0 );
+      print_item( real_to_string( (saved) ? saved_time : time, 5 ), 8 );
+      if( (saved) ? saved_timeStep : timeStep > 0 ) {
+//         print_item( " TAU:" );
+         print_item( " TAU:", 0 );
+         print_item( real_to_string( (saved) ? saved_timeStep : timeStep, 5 ), 8 );
       }
 
-      if( this->stage.length() && free > 5 ) {
-         if( (int) this->stage.length() <= free - 2 ) {
-            std::cout << "  " << this->stage;
-            free -= ( 2 + this->stage.length() );
+      const std::string displayed_stage = (saved) ? saved_stage : stage;
+      if( displayed_stage.length() && free > 5 ) {
+         if( (int) displayed_stage.length() <= free - 2 ) {
+            std::cout << "  " << displayed_stage;
+            free -= ( 2 + displayed_stage.length() );
          }
          else {
-            std::cout << "  " << this->stage.substr( 0, free - 5 ) << "...";
+            std::cout << "  " << displayed_stage.substr( 0, free - 5 ) << "...";
             free = 0;
          }
       }
 
-      if( this->iterations > 0 && free >= 14 ) {
-         std::cout << " ITER:" << std::setw( 8 ) << this->iterations;
-         free -= 14;
+      if( (saved) ? saved_iterations : iterations > 0 && free >= 14 ) {
+//         print_item( " ITER:" );
+         print_item( " ITER:", 0 );
+         print_item( std::to_string( (saved) ? saved_iterations : iterations ), 8 );
       }
-      if( this->residue && free >= 17 ) {
-         std::cout << " RES:" << std::setprecision( 5 ) << std::setw( 12 ) << this->residue;
-         free -= 17;
+      if( (saved) ? saved_residue : residue && free >= 17 ) {
+//         print_item( " RES:" );
+         print_item( " RES:", 0 );
+         print_item( real_to_string( (saved) ? saved_residue : residue, 5 ), 12 );
       }
 
-      // fill the rest of the line with spaces to clear previous content
-      //while( line_width && free-- > 8 )
-      //   std::cout << " ";
+      // return to the beginning of the line
       std::cout << "\r" << std::flush;
    }
 }
diff --git a/src/TNL/Solvers/IterativeSolver_impl.h b/src/TNL/Solvers/IterativeSolver_impl.h
index da811762ae2b5d1f11f5748e37d52b4026a7f78e..9b98dbea3d308f685d6e9d2acfe701b10f1e270c 100644
--- a/src/TNL/Solvers/IterativeSolver_impl.h
+++ b/src/TNL/Solvers/IterativeSolver_impl.h
@@ -212,7 +212,6 @@ void IterativeSolver< Real, Index> :: refreshSolverMonitor( bool force )
       this->solverMonitor->setIterations( this->getIterations() );
       this->solverMonitor->setResidue( this->getResidue() );
       this->solverMonitor->setRefreshRate( this-> refreshRate );
-//      this->solverMonitor -> refresh( force );
    }
 }
 
diff --git a/src/TNL/Solvers/ODE/ExplicitSolver_impl.h b/src/TNL/Solvers/ODE/ExplicitSolver_impl.h
index 11cd7f19285e21d92ddeeb4bcff98897ab59f0d9..352c5ca2b2fee5a6a93ce641114553e0feb662fa 100644
--- a/src/TNL/Solvers/ODE/ExplicitSolver_impl.h
+++ b/src/TNL/Solvers/ODE/ExplicitSolver_impl.h
@@ -159,7 +159,6 @@ refreshSolverMonitor( bool force )
       this->solverMonitor->setTimeStep( this->getTau() );
       this->solverMonitor->setTime( this->getTime() );
       this->solverMonitor->setRefreshRate( this->refreshRate );
-      this->solverMonitor->refresh( force );
    }
 }
 
diff --git a/src/TNL/Solvers/SolverMonitor.h b/src/TNL/Solvers/SolverMonitor.h
index 73d78ea4cd458f4e6981d56bf5357d5df6eac3da..124bf1a839f01b720bf35a0a9d2c39d25d3fde22 100644
--- a/src/TNL/Solvers/SolverMonitor.h
+++ b/src/TNL/Solvers/SolverMonitor.h
@@ -28,7 +28,7 @@ public:
         timer( nullptr )
    {}
 
-   virtual void refresh( bool force = false ) = 0;
+   virtual void refresh() = 0;
 
    void setRefreshRate( const int& refreshRate )
    {
@@ -52,7 +52,7 @@ public:
       const std::chrono::milliseconds timeout( timeout_base );
 
       while( ! stopped ) {
-         refresh( true );
+         refresh();
 
          // make sure to detect changes to refresh rate
          int steps = timeout_milliseconds / timeout_base;
@@ -90,8 +90,7 @@ protected:
 
    std::atomic_int timeout_milliseconds;
 
-   std::atomic_bool started;
-   std::atomic_bool stopped;
+   std::atomic_bool started, stopped;
 
    Timer* timer;
 };
@@ -121,4 +120,4 @@ class SolverMonitorThread
 };
 
 } // namespace Solvers
-} // namespace TNL
\ No newline at end of file
+} // namespace TNL
diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h
index 7b9bc2f5659644199c91c3a291857cc5e18e2564..cd7959b5ff477bb70c1c7be8206e3fc46c38c1f3 100644
--- a/src/UnitTests/Containers/ArrayTest.h
+++ b/src/UnitTests/Containers/ArrayTest.h
@@ -325,14 +325,15 @@ TYPED_TEST( ArrayTest, elementwiseAccess )
    testArrayElementwiseAccess( ArrayType() );
 }
 
-// TODO: comparison with different device
 TYPED_TEST( ArrayTest, comparisonOperator )
 {
    using ArrayType = typename TestFixture::ArrayType;
 
    ArrayType u( 10 ), v( 10 ), w( 10 );
+   typename ArrayType::HostType u_host( 10 );
    for( int i = 0; i < 10; i ++ ) {
       u.setElement( i, i );
+      u_host.setElement( i, i );
       v.setElement( i, i );
       w.setElement( i, 2 * i );
    }
@@ -346,6 +347,12 @@ TYPED_TEST( ArrayTest, comparisonOperator )
    EXPECT_FALSE( u == w );
    EXPECT_FALSE( w == u );
 
+   // comparison with different device
+   EXPECT_TRUE( u == u_host );
+   EXPECT_TRUE( u_host == u );
+   EXPECT_TRUE( w != u_host );
+   EXPECT_TRUE( u_host != w );
+
    v.setSize( 0 );
    EXPECT_FALSE( u == v );
    u.setSize( 0 );
@@ -369,17 +376,30 @@ TYPED_TEST( ArrayTest, comparisonOperatorWithDifferentType )
 }
 */
 
-// TODO: assignment from different device
 TYPED_TEST( ArrayTest, assignmentOperator )
 {
    using ArrayType = typename TestFixture::ArrayType;
 
    ArrayType u( 10 ), v( 10 );
-   for( int i = 0; i < 10; i++ )
+   typename ArrayType::HostType u_host( 10 );
+   for( int i = 0; i < 10; i++ ) {
       u.setElement( i, i );
+      u_host.setElement( i, i );
+   }
+
    v.setValue( 0 );
    v = u;
    EXPECT_EQ( u, v );
+
+   // assignment from host to device
+   v.setValue( 0 );
+   v = u_host;
+   EXPECT_EQ( u, v );
+
+   // assignment from device to host
+   u_host.setValue( 0 );
+   u_host = u;
+   EXPECT_EQ( u_host, u );
 }
 
 // test works only for arithmetic types
@@ -388,15 +408,36 @@ template< typename ArrayType,
 void testArrayAssignmentWithDifferentType()
 {
    ArrayType u( 10 );
-   for( int i = 0; i < 10; i++ )
-      u.setElement( i, i );
    Array< short, typename ArrayType::DeviceType, short > v( 10 );
+   Array< short, Devices::Host, short > v_host( 10 );
+   typename ArrayType::HostType u_host( 10 );
+   for( int i = 0; i < 10; i++ ) {
+      u.setElement( i, i );
+      u_host.setElement( i, i );
+   }
+
    v.setValue( 0 );
    v = u;
 // TODO: missing implementation of relevant reduction operation on CUDA with different types
-//   EXPECT_EQ( u, v );
+//   EXPECT_EQ( v, u );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v.getElement( i ), i );
+
+   // assignment from host to device
+   v.setValue( 0 );
+   v = u_host;
+// TODO: missing implementation of relevant reduction operation on CUDA with different types
+//   EXPECT_EQ( v, u_host );
    for( int i = 0; i < 10; i++ )
       EXPECT_EQ( v.getElement( i ), i );
+
+   // assignment from host to device
+   v_host.setValue( 0 );
+   v_host = u;
+// TODO: missing implementation of relevant reduction operation on CUDA with different types
+//   EXPECT_EQ( v_host, u );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v_host.getElement( i ), i );
 }
 
 template< typename ArrayType,
@@ -406,7 +447,6 @@ void testArrayAssignmentWithDifferentType()
 {
 }
 
-// TODO: assignment from different device
 TYPED_TEST( ArrayTest, assignmentOperatorWithDifferentType )
 {
    using ArrayType = typename TestFixture::ArrayType;
diff --git a/src/UnitTests/Containers/StaticArrayTest.cpp b/src/UnitTests/Containers/StaticArrayTest.cpp
index d6dedf6236caf347dba2c458e9ef992cfdec5565..dfe99c5876ccc855d8ab62464f59456490e403e2 100644
--- a/src/UnitTests/Containers/StaticArrayTest.cpp
+++ b/src/UnitTests/Containers/StaticArrayTest.cpp
@@ -212,7 +212,7 @@ TYPED_TEST( StaticArrayTest, AssignmentOperator )
    EXPECT_TRUE( u3 != u1 );
 
    // assignment from different type
-   StaticArray< Size, char > u4( 128 );
+   StaticArray< Size, char > u4( 127 );
    u3 = u4;
    EXPECT_TRUE( u3 == u4 );
 }