diff --git a/Documentation/Doxyfile b/Documentation/Doxyfile index 11a3160f8637b739c7152c154064a7489f6e1e86..39df663bfd374585f602d37e6b674a3396eff402 100644 --- a/Documentation/Doxyfile +++ b/Documentation/Doxyfile @@ -2107,7 +2107,8 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = HAVE_MPI=1 + HAVE_CUDA=1 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/src/Benchmarks/BLAS/array-operations.h b/src/Benchmarks/BLAS/array-operations.h index b5cf9ff58da754aaa4c8ce645989afbb25e61f7c..926c729ce1af887c030d2a129bde735374377af1 100644 --- a/src/Benchmarks/BLAS/array-operations.h +++ b/src/Benchmarks/BLAS/array-operations.h @@ -66,10 +66,10 @@ benchmarkArrayOperations( Benchmark & benchmark, auto compareHost = [&]() { - resultHost = (int) hostArray == hostArray2; + resultHost = (int) ( hostArray == hostArray2 ); }; auto compareCuda = [&]() { - resultDevice = (int) deviceArray == deviceArray2; + resultDevice = (int) ( deviceArray == deviceArray2 ); }; benchmark.setOperation( "comparison (operator==)", 2 * datasetSize ); benchmark.time< Devices::Host >( reset1, "CPU", compareHost ); diff --git a/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h b/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h index 23f08152724222009ff8e818bfee9d6e78f81611..62e37117247bbe1d24398ed8b40159010213b182 100644 --- a/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h +++ b/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h @@ -163,9 +163,8 @@ struct SpmvBenchmark { MatrixType matrix; VectorType vector; - if( ! matrix.load( parameters.getParameter< String >( "input-matrix" ) ) || - ! vector.load( parameters.getParameter< String >( "input-vector" ) ) ) - return false; + matrix.load( parameters.getParameter< String >( "input-matrix" ) ); + vector.load( parameters.getParameter< String >( "input-vector" ) ); typename MatrixType::CompressedRowLengthsVector rowLengths; matrix.getCompressedRowLengths( rowLengths ); diff --git a/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h b/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h index e63e431c67a39eed8a06993f71605db48d8e39c5..2bfd1e71cf58bea53963d33c24c5baf601939cc9 100644 --- a/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h +++ b/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h @@ -144,7 +144,11 @@ setInitialCondition( const Config::ParameterContainer& parameters, { const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" ); Functions::MeshFunction< Mesh > u( this->getMesh(), dofsPointer ); - if( ! u.boundLoad( initialConditionFile ) ) + try + { + u.boundLoad( initialConditionFile ); + } + catch(...) { std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl; return false; @@ -200,8 +204,7 @@ makeSnapshot( const RealType& time, fileName.setIndex( step ); //FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName ); - if( ! u.save( fileName.getFileName() ) ) - return false; + u.save( fileName.getFileName() ); return true; } diff --git a/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h b/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h index 55211c4edb9043e1ae0258e041fcfd2846976e51..2926e6bb149131cb01592532027c1d2b66fc8968 100644 --- a/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h +++ b/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h @@ -332,10 +332,9 @@ struct LinearSolversBenchmark { SharedPointer< MatrixType > matrixPointer; VectorType x0, b; - if( ! matrixPointer->load( parameters.getParameter< String >( "input-matrix" ) ) || - ! x0.load( parameters.getParameter< String >( "input-dof" ) ) || - ! b.load( parameters.getParameter< String >( "input-rhs" ) ) ) - return false; + matrixPointer->load( parameters.getParameter< String >( "input-matrix" ) ); + x0.load( parameters.getParameter< String >( "input-dof" ) ); + b.load( parameters.getParameter< String >( "input-rhs" ) ); typename MatrixType::CompressedRowLengthsVector rowLengths; matrixPointer->getCompressedRowLengths( rowLengths ); diff --git a/src/Examples/ArrayExample.cpp b/src/Examples/ArrayExample.cpp deleted file mode 100644 index 2cc9c54e5167b6ed9faf6a67bf6de76305ed9b15..0000000000000000000000000000000000000000 --- a/src/Examples/ArrayExample.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include <iostream> -#include <TNL/Containers/Array.h> - -using namespace TNL; -using namespace std; - -int main() -{ - Containers::Array<int> array1; - array1.setSize(5); - array1.setValue(0); - cout << "Does array contain 1?" << array1.containsValue(1) << endl; - cout << "Does array contain only zeros?" << array1.containsOnlyValue(0) << endl; - - Containers::Array<int> array2(3); - array2.setValue(1); - array2.swap(array1); - array2.setElement(2,4); - - cout << "First array:" << array1.getData() << endl; - cout << "Second array:" << array2.getData() << endl; - - array2.reset(); - cout << "Second array after reset:" << array2.getData() << endl; - - // bind -} diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 1c52839e9116646d982eafaea5ba30bf04a9b995..2d46b24465629193ff505257561e974f8fa55a4a 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -1,3 +1,5 @@ +ADD_SUBDIRECTORY( Containers ) + add_subdirectory( simple-examples ) add_subdirectory( heat-equation ) add_subdirectory( transport-equation ) @@ -10,28 +12,85 @@ add_subdirectory( flow ) add_subdirectory( flow-sw ) add_subdirectory( flow-vl ) -#add_subdirectory( mean-curvature-flow ) -#add_subdirectory( hamilton-jacobi ) -#add_subdirectory( hamilton-jacobi-parallel ) -#add_subdirectory( fast-sweeping ) -#add_subdirectory( hamilton-jacobi-parallel-map ) -#add_subdirectory( fast-sweeping-map ) -#add_subdirectory( narrow-band ) - -ADD_EXECUTABLE( ArrayExample ArrayExample.cpp ) ADD_EXECUTABLE( ConfigDescriptionExample ConfigDescriptionExample.cpp ) + ADD_EXECUTABLE( FileExample FileExample.cpp ) +ADD_CUSTOM_COMMAND( COMMAND FileExample > FileExample.out OUTPUT FileExample.out ) + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(FileExampleCuda FileExampleCuda.cu) + ADD_CUSTOM_COMMAND( COMMAND FileExampleCuda > FileExampleCuda.out OUTPUT FileExampleCuda.out ) +ENDIF() + +ADD_EXECUTABLE( FileExampleSaveAndLoad FileExampleSaveAndLoad.cpp ) +ADD_CUSTOM_COMMAND( COMMAND FileExampleSaveAndLoad > FileExampleSaveAndLoad.out OUTPUT FileExampleSaveAndLoad.out ) + +ADD_EXECUTABLE( FileNameExample FileNameExample.cpp ) +ADD_CUSTOM_COMMAND( COMMAND FileNameExample > FileNameExample.out OUTPUT FileNameExample.out ) + +ADD_EXECUTABLE( FileNameExampleDistributedSystemNodeCoordinates FileNameExampleDistributedSystemNodeCoordinates.cpp ) +ADD_CUSTOM_COMMAND( COMMAND FileNameExampleDistributedSystemNodeCoordinates > FileNameExampleDistributedSystemNodeCoordinates.out OUTPUT FileNameExampleDistributedSystemNodeCoordinates.out ) + + +ADD_EXECUTABLE( FileNameExampleDistributedSystemNodeId FileNameExampleDistributedSystemNodeId.cpp ) +ADD_CUSTOM_COMMAND( COMMAND FileNameExampleDistributedSystemNodeId > FileNameExampleDistributedSystemNodeId.out OUTPUT FileNameExampleDistributedSystemNodeId.out ) + ADD_EXECUTABLE( ListExample ListExample.cpp ) ADD_EXECUTABLE( LoggerExample LoggerExample.cpp ) ADD_EXECUTABLE( MathExample MathExample.cpp ) +ADD_EXECUTABLE( ObjectExample_getType ObjectExample_getType.cpp ) +ADD_CUSTOM_COMMAND( COMMAND ObjectExample_getType > ObjectExample_getType.out OUTPUT ObjectExample_getType.out ) + ADD_EXECUTABLE( ParameterContainerExample ParameterContainerExample.cpp ) +ADD_EXECUTABLE( ParseObjectTypeExample ParseObjectTypeExample.cpp ) +ADD_CUSTOM_COMMAND( COMMAND ParseObjectTypeExample > ParseObjectTypeExample.out OUTPUT ParseObjectTypeExample.out ) + ADD_EXECUTABLE( StringExample StringExample.cpp ) +ADD_CUSTOM_COMMAND( COMMAND StringExample > StringExample.out OUTPUT StringExample.out ) + ADD_EXECUTABLE( StringExampleGetAllocatedSize StringExampleGetAllocatedSize.cpp ) -ADD_EXECUTABLE( StringExampleGetSize StringExampleGetSize.cpp ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleGetAllocatedSize > StringExampleGetAllocatedSize.out OUTPUT StringExampleGetAllocatedSize.out ) + +ADD_EXECUTABLE( StringExampleReplace StringExampleReplace.cpp ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleReplace > StringExampleReplace.out OUTPUT StringExampleReplace.out ) + ADD_EXECUTABLE( StringExampleSetSize StringExampleSetSize.cpp ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleSetSize > StringExampleSetSize.out OUTPUT StringExampleSetSize.out ) + +ADD_EXECUTABLE( StringExampleSplit StringExampleSplit.cpp ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleSplit > StringExampleSplit.out OUTPUT StringExampleSplit.out ) + +ADD_EXECUTABLE( StringExampleStrip StringExampleStrip.cpp ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleStrip > StringExampleStrip.out OUTPUT StringExampleStrip.out ) + ADD_EXECUTABLE( TimerExample TimerExample.cpp ) +ADD_CUSTOM_COMMAND( COMMAND TimerExample > TimerExample.out OUTPUT TimerExample.out ) + +ADD_EXECUTABLE( TimerExampleLogger TimerExampleLogger.cpp ) +ADD_CUSTOM_COMMAND( COMMAND TimerExampleLogger > TimerExampleLogger.out OUTPUT TimerExampleLogger.out ) ADD_EXECUTABLE( VectorExample VectorExample.cpp ) + +ADD_CUSTOM_TARGET( RunExamples ALL DEPENDS + FileExample.out + FileExampleSaveAndLoad.out + FileNameExample.out + FileNameExampleDistributedSystemNodeCoordinates.out + FileNameExampleDistributedSystemNodeId.out + ObjectExample_getType.out + ParseObjectTypeExample.out + StringExample.out + StringExampleGetAllocatedSize.out + StringExampleReplace.out + StringExampleSplit.out + StringExampleStrip.out + TimerExample.out + TimerExampleLogger.out ) + +if( BUILD_CUDA ) + ADD_CUSTOM_TARGET( RunExamples-cuda ALL DEPENDS + FileExampleCuda.out ) +ENDIF() \ No newline at end of file diff --git a/src/Examples/Containers/ArrayExample.cpp b/src/Examples/Containers/ArrayExample.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9dcfd7cbddc9ad4920ce024b3e2044b3a248efcf --- /dev/null +++ b/src/Examples/Containers/ArrayExample.cpp @@ -0,0 +1,78 @@ +#include <iostream> +#include <list> +#include <vector> +#include <TNL/Containers/Array.h> + +using namespace TNL; +using namespace std; + +/*** + * The following works for any device (CPU, GPU ...). + */ +template< typename Device > +void arrayExample() +{ + const int size = 10; + using ArrayType = Containers::Array< int, Device >; + using IndexType = typename ArrayType::IndexType; + ArrayType a1( size ), a2( size ); + + /*** + * You may initiate the array using setElement + */ + for( int i = 0; i< size; i++ ) + a1.setElement( i, i ); + std::cout << "a1 = " << a1 << std::endl; + + /*** + * You may also assign value to all array elements ... + */ + a2 = 0.0; + std::cout << "a2 = " << a2 << std::endl; + + /*** + * ... or assign STL list and vector. + */ + std::list< float > l = { 1.0, 2.0, 3.0 }; + std::vector< float > v = { 5.0, 6.0, 7.0 }; + a1 = l; + std::cout << "a1 = " << a1 << std::endl; + a1 = v; + std::cout << "a1 = " << a1 << std::endl; + + /*** + * Simple array values checks can be done as follows ... + */ + if( a1.containsValue( 1 ) ) + std::cout << "a1 contains value 1." << std::endl; + if( a1.containsValue( size ) ) + std::cout << "a1 contains value " << size << "." << std::endl; + if( a1.containsOnlyValue( 0 ) ) + std::cout << "a2 contains only value 0." << std::endl; + + /*** + * You may swap array data with the swap method. + */ + a1.swap( a2 ); + + /*** + * Of course, you may save it to file and load again + */ + a1.save( "a1.tnl" ); + a2.load( "a1.tnl" ); + + if( a2 != a1 ) + std::cerr << "Something is wrong!!!" << std::endl; + + std::cout << "a2 = " << a2 << std::endl; +} + +int main() +{ + std::cout << "The first test runs on CPU ..." << std::endl; + arrayExample< Devices::Host >(); +#ifdef HAVE_CUDA + std::cout << "The second test runs on GPU ..." << std::endl; + arrayExample< Devices::Cuda >(); +#endif +} diff --git a/src/Examples/Containers/ArrayExample.cu b/src/Examples/Containers/ArrayExample.cu new file mode 120000 index 0000000000000000000000000000000000000000..6cee614fe57fdd448dbc4b7dd6bacd2949d574d3 --- /dev/null +++ b/src/Examples/Containers/ArrayExample.cu @@ -0,0 +1 @@ +ArrayExample.cpp \ No newline at end of file diff --git a/src/Examples/Containers/ArrayViewExample.cpp b/src/Examples/Containers/ArrayViewExample.cpp new file mode 100644 index 0000000000000000000000000000000000000000..087dc19c6abf28d117eb0e05c048aab012e54bc3 --- /dev/null +++ b/src/Examples/Containers/ArrayViewExample.cpp @@ -0,0 +1,81 @@ +#include <iostream> +#include <list> +#include <vector> +#include <TNL/Containers/Array.h> +#include <TNL/Containers/ArrayView.h> + +using namespace TNL; +using namespace std; + +/*** + * The following works for any device (CPU, GPU ...). + */ +template< typename Device > +void arrayViewExample() +{ + const int size = 10; + using ArrayType = Containers::Array< int, Device >; + using IndexType = typename ArrayType::IndexType; + using ViewType = Containers::ArrayView< int, Device >; + ArrayType _a1( size ), _a2( size ); + ViewType a1( _a1 ), a2( _a2 ); + + /*** + * You may initiate the array view using setElement + */ + for( int i = 0; i< size; i++ ) + a1.setElement( i, i ); + + /*** + * You may also assign value to all array view elements ... + */ + a2 = 0.0; + + /*** + * Simple array view values checks can be done as follows ... + */ + if( a1.containsValue( 1 ) ) + std::cout << "a1 contains value 1." << std::endl; + if( a1.containsValue( size ) ) + std::cout << "a1 contains value " << size << "." << std::endl; + if( a1.containsOnlyValue( 0 ) ) + std::cout << "a2 contains only value 0." << std::endl; + + /*** + * More efficient way of array view elements manipulation is with the lambda functions + */ + ArrayType _a3( size ); + ViewType a3( _a3 ); + auto f1 = [] __cuda_callable__ ( IndexType i ) -> int { return 2 * i;}; + a3.evaluate( f1 ); + + for( int i = 0; i < size; i++ ) + if( a3.getElement( i ) != 2 * i ) + std::cerr << "Something is wrong!!!" << std::endl; + + /*** + * You may swap array view data with the swap method. + */ + a1.swap( a3 ); + + /*** + * Of course, you may save it to file and load again + */ + a1.save( "a1.tnl" ); + a2.load( "a1.tnl" ); + + if( a2 != a1 ) + std::cerr << "Something is wrong!!!" << std::endl; + + std::cout << "a2 = " << a2 << std::endl; +} + +int main() +{ + std::cout << "The first test runs on CPU ..." << std::endl; + arrayViewExample< Devices::Host >(); +#ifdef HAVE_CUDA + std::cout << "The second test runs on GPU ..." << std::endl; + arrayViewExample< Devices::Cuda >(); +#endif +} diff --git a/src/Examples/Containers/ArrayViewExample.cu b/src/Examples/Containers/ArrayViewExample.cu new file mode 120000 index 0000000000000000000000000000000000000000..10c7b94b2128415b1c93b849d3ff49a1b7176709 --- /dev/null +++ b/src/Examples/Containers/ArrayViewExample.cu @@ -0,0 +1 @@ +ArrayViewExample.cpp \ No newline at end of file diff --git a/src/Examples/Containers/CMakeLists.txt b/src/Examples/Containers/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b70b12670f085c70e9c00821b2f67fc0fe5458be --- /dev/null +++ b/src/Examples/Containers/CMakeLists.txt @@ -0,0 +1,26 @@ +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE( ArrayExampleCuda ArrayExample.cu ) + ADD_CUSTOM_COMMAND( COMMAND ArrayExampleCuda > ArrayExampleCuda.out OUTPUT ArrayExampleCuda.out ) +ELSE() + ADD_EXECUTABLE( ArrayExample ArrayExample.cpp ) + ADD_CUSTOM_COMMAND( COMMAND ArrayExample > ArrayExample.out OUTPUT ArrayExample.out ) +ENDIF() + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE( ArrayViewExampleCuda ArrayViewExample.cu ) + ADD_CUSTOM_COMMAND( COMMAND ArrayViewExampleCuda > ArrayViewExampleCuda.out OUTPUT ArrayViewExampleCuda.out ) +ELSE() + ADD_EXECUTABLE( ArrayViewExample ArrayViewExample.cpp ) + ADD_CUSTOM_COMMAND( COMMAND ArrayViewExample > ArrayViewExample.out OUTPUT ArrayViewExample.out ) +ENDIF() + + +IF( BUILD_CUDA ) +ADD_CUSTOM_TARGET( RunContainersExamples-cuda ALL DEPENDS + ArrayExampleCuda.out + ArrayViewExampleCuda.out ) +ELSE() +ADD_CUSTOM_TARGET( RunContainersExamples ALL DEPENDS + ArrayExample.out + ArrayViewExample.out ) +ENDIF() diff --git a/src/Examples/FileExample.cpp b/src/Examples/FileExample.cpp index 4d379f4b18f5ffd107cb5840ee745841486fa547..5239fc2144d6795a5dd1df79af47129bf314a8a6 100644 --- a/src/Examples/FileExample.cpp +++ b/src/Examples/FileExample.cpp @@ -4,21 +4,21 @@ using namespace TNL; using namespace std; - + int main() { File file; - file.open( String("new-file.tnl"), IOMode::write ); - String title("Header"); - file.write( &title ); + file.open( String("new-file.tnl"), File::Mode::Out ); + String title("'string to file'"); + file << title; file.close(); - file.open( String("new-file.tnl"), IOMode::read ); - String title2; - file.read( &title2, 4); + file.open( String("new-file.tnl"), File::Mode::In ); + String restoredString; + file >> restoredString; file.close(); - cout << "title2:" << title2 <<endl; + cout << "restored string = " << restoredString <<endl; } diff --git a/src/Examples/FileExampleCuda.cpp b/src/Examples/FileExampleCuda.cpp new file mode 120000 index 0000000000000000000000000000000000000000..53d150113492bacd7c39a515657054c818a3c95b --- /dev/null +++ b/src/Examples/FileExampleCuda.cpp @@ -0,0 +1 @@ +FileExampleCuda.cu \ No newline at end of file diff --git a/src/Examples/FileExampleCuda.cu b/src/Examples/FileExampleCuda.cu new file mode 100644 index 0000000000000000000000000000000000000000..cd7c2839923776d453b8df4b3df7e1b8c75a86b0 --- /dev/null +++ b/src/Examples/FileExampleCuda.cu @@ -0,0 +1,57 @@ +#include <iostream> +#include <TNL/File.h> +#include <cuda.h> + +using namespace TNL; +using namespace std; + +int main() +{ + const int size = 3; + double doubleArray[] = { 3.1415926535897932384626433, + 2.7182818284590452353602874, + 1.6180339887498948482045868 }; + + /*** + * Save array to file. + */ + File file; + file.open( "test-file.tnl", File::Mode::Out | File::Mode::Truncate ); + file.save< double, double, Devices::Host >( doubleArray, size ); + file.close(); + + /*** + * Allocate arrays on host and device + */ + double *deviceArray, *hostArray; + cudaMalloc( ( void** ) &deviceArray, size * sizeof( double ) ); + hostArray = new double[ 3 ]; + + /*** + * Read array from the file to device + */ + file.open( "test-file.tnl", File::Mode::In ); + file.load< double, double, Devices::Cuda >( deviceArray, size ); + file.close(); + + /*** + * Copy array from device to host + */ + cudaMemcpy( ( void* ) hostArray, ( const void* ) deviceArray, size * sizeof( double), cudaMemcpyDeviceToHost ); + + /*** + * Print the array on host + */ + std::cout.precision( 15 ); + for( int i = 0; i < size; i++ ) + std::cout << hostArray[ i ] << std::endl; + + /*** + * Free allocated memory + */ + cudaFree( deviceArray ); + delete[] hostArray; +} + + + diff --git a/src/Examples/FileExampleSaveAndLoad.cpp b/src/Examples/FileExampleSaveAndLoad.cpp new file mode 100644 index 0000000000000000000000000000000000000000..59718ed3ff1bbb845d1a333a078f0139d8a23ff5 --- /dev/null +++ b/src/Examples/FileExampleSaveAndLoad.cpp @@ -0,0 +1,48 @@ +#include <iostream> +#include <TNL/File.h> + +using namespace TNL; +using namespace std; + +int main() +{ + const int size = 3; + double doubleArray[] = { 3.1415926535897932384626433, + 2.7182818284590452353602874, + 1.6180339887498948482045868 }; + float floatArray[ 3 ]; + int intArray[ 3 ]; + + /*** + * Save the array of doubles as floats. + */ + File file; + file.open( "test-file.tnl", File::Mode::Out | File::Mode::Truncate ); + file.save< double, float, Devices::Host >( doubleArray, size ); + file.close(); + + /*** + * Load the array of floats from the file. + */ + file.open( "test-file.tnl", File::Mode::In ); + file.load< float, float, Devices::Host >( floatArray, size ); + file.close(); + + /*** + * Load the array of floats from the file and convert them to integers. + */ + file.open( "test-file.tnl", File::Mode::In ); + file.load< int, float, Devices::Host >( intArray, size ); + file.close(); + + /*** + * Print all arrays. + */ + std::cout.precision( 15 ); + for( int i = 0; i < size; i++ ) + std::cout << doubleArray[ i ] << " -- " + << floatArray[ i ] << " -- " + << intArray[ i ] << std::endl; +} + + diff --git a/src/Examples/FileNameExample.cpp b/src/Examples/FileNameExample.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32425377a76c711178c2cc427997857e814c359e --- /dev/null +++ b/src/Examples/FileNameExample.cpp @@ -0,0 +1,37 @@ +#include <iostream> +#include <TNL/FileName.h> + + +using namespace TNL; +using namespace std; + +int main() +{ + /*** + * Create file name with filename base 'velocity' and extension 'vtk'. + */ + FileName fileName( "velocity-", "vtk" ); + + /** + * Set the number of digits for the index to 2 and print file names for + * indexes 0 to 10. + */ + fileName.setDigitsCount( 2 ); + for( int i = 0; i <= 10; i ++ ) + { + fileName.setIndex( i ); + std::cout << fileName.getFileName() << std::endl; + } + + /*** + * Now set the number if index digits to 3 and do the same. + */ + fileName.setDigitsCount( 3 ); + for( int i = 0; i <= 10; i ++ ) + { + fileName.setIndex( i ); + std::cout << fileName.getFileName() << std::endl; + } +} + + diff --git a/src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp b/src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc9a3626e551424a169a59c20625a064c5745a67 --- /dev/null +++ b/src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp @@ -0,0 +1,34 @@ +#include <iostream> +#include <TNL/FileName.h> +#include <TNL/Containers/StaticVector.h> + +using namespace TNL; +using namespace std; + +int main() +{ + /** + * Create file name with filename base 'velocity' and extension 'vtk'. + */ + FileName fileName( "velocity-", "vtk" ); + + /*** + * Set the distributed system node ID to 0-0-0. + */ + using CoordinatesType = Containers::StaticVector< 3, int >; + CoordinatesType coordinates( 0, 0, 0 ); + fileName.setDistributedSystemNodeCoordinates( coordinates ); + + /** + * Now set the file name index digits count to 2 and print file names + * for indexes 0 to 10. + */ + fileName.setDigitsCount( 2 ); + for( int i = 0; i <= 10; i ++ ) + { + fileName.setIndex( i ); + std::cout << fileName.getFileName() << std::endl; + } +} + + diff --git a/src/Examples/FileNameExampleDistributedSystemNodeId.cpp b/src/Examples/FileNameExampleDistributedSystemNodeId.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d704c96b304413eea52275fde57f4073cd458899 --- /dev/null +++ b/src/Examples/FileNameExampleDistributedSystemNodeId.cpp @@ -0,0 +1,31 @@ +#include <iostream> +#include <TNL/FileName.h> + +using namespace TNL; +using namespace std; + +int main() +{ + /** + * Create file name with filename base 'velocity' and extension 'vtk'. + */ + FileName fileName( "velocity-", "vtk" ); + + /** + * Set the distributed system node ID to 0; + */ + fileName.setDistributedSystemNodeId( 0 ); + + /** + * Set the number of digits for the index to 2 and print file names for + * indexes 0 to 10. + */ + fileName.setDigitsCount( 2 ); + for( int i = 0; i <= 10; i ++ ) + { + fileName.setIndex( i ); + std::cout << fileName.getFileName() << std::endl; + } +} + + diff --git a/src/Examples/ObjectExample_getType.cpp b/src/Examples/ObjectExample_getType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7cc7476d6cc90debc1e495eab8b84959619881f7 --- /dev/null +++ b/src/Examples/ObjectExample_getType.cpp @@ -0,0 +1,63 @@ +#include <iostream> +#include <TNL/param-types.h> +#include <TNL/Object.h> +#include <TNL/Devices/Host.h> +#include <TNL/Devices/Cuda.h> + +using namespace TNL; +using namespace std; + +template< typename Value, + typename Device > +class MyArray : public Object +{ + public: + + using HostType = MyArray< Value, Devices::Host >; + + static String getType() + { + return "MyArray< " + TNL::getType< Value >() + ", " + TNL::getType< Device >() + " >"; + } + + String getTypeVirtual() const + { + return getType(); + } + + static String getSerializationType() + { + return HostType::getType(); + } + + String getSerializationTypeVirtual() const + { + return getSerializationType(); + } +}; + +int main() +{ + using HostArray = MyArray< int, Devices::Host >; + using CudaArray = MyArray< int, Devices::Cuda >; + + HostArray hostArray; + CudaArray cudaArray; + Object* hostArrayPtr = &hostArray; + Object* cudaArrayPtr = &cudaArray; + + // Object types + cout << "HostArray type is " << HostArray::getType() << endl; + cout << "hostArrayPtr type is " << hostArrayPtr->getTypeVirtual() << endl; + + cout << "CudaArray type is " << CudaArray::getType() << endl; + cout << "cudaArrayPtr type is " << cudaArrayPtr->getTypeVirtual() << endl; + + // Object serialization types + cout << "HostArray serialization type is " << HostArray::getSerializationType() << endl; + cout << "hostArrayPtr serialization type is " << hostArrayPtr->getSerializationTypeVirtual() << endl; + + cout << "CudaArray serialization type is " << CudaArray::getSerializationType() << endl; + cout << "cudaArrayPtr serialization type is " << cudaArrayPtr->getSerializationTypeVirtual() << endl; +} + diff --git a/src/Examples/ParseObjectTypeExample.cpp b/src/Examples/ParseObjectTypeExample.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ded8575534cf7c210c308f8a4699519cdce1e70 --- /dev/null +++ b/src/Examples/ParseObjectTypeExample.cpp @@ -0,0 +1,16 @@ +#include <iostream> +#include <TNL/Object.h> +#include <unistd.h> + +using namespace TNL; +using namespace std; + +int main() +{ + auto parsedObjectType = parseObjectType( String( "MyObject< Value, Device, Index >" ) ); + for( auto &token : parsedObjectType ) + { + cout << token << endl; + } +} + diff --git a/src/Examples/StringExample.cpp b/src/Examples/StringExample.cpp index a23904a4f96118ff3139f0403462e934fc8a7641..19ed24bd11d67e7b4b7d98de9c9f93c758bcbaa2 100644 --- a/src/Examples/StringExample.cpp +++ b/src/Examples/StringExample.cpp @@ -8,132 +8,50 @@ using namespace std; int main( int argc, char* argv[] ) { - // constructors - String str1; - String str2( "string" ); - String str3( str2 ); // copy constructor - String str4 = convertToString( 28.4 ); // converts to string - - cout << "str1:" << str1 << endl; - cout << "str2:" << str2 << endl; - cout << "str3:" << str3 << endl; - cout << "str4:" << str4 << endl; - - // functions - /*int size = str3.getSize(); - cout << "size of string:" << size << "bytes" << endl; - - int alloc_size = str3.getAllocatedSize(); - cout << "alloc_size:" << alloc_size << endl; - - str1.setSize( 256 ); - size = str3.getSize(); - cout << "size of string:" << size << "bytes" << endl;*/ - - String setter = "Something new"; - cout << "setter:" << setter << endl; - - const char* getter = str4.getString(); - cout << "getter:" << getter << endl; - - String word( "computer" ) ; - char third_letter = word[2]; - cout << "third_letter:" << third_letter << endl; - - // Operators for C Strings - String a( "hello" ); - a = "bye"; - cout << "a:" << a << endl; - - String b( "see" ); - b += " you"; - cout << "b:" << b << endl; - - String c; - c = b + " soon"; - cout << "c:" << c << endl; - - String name( "Jack" ); - if ( name == "Jack" ) cout << "Names are the same." << endl; - - String surname( "Sparrow" ); - if ( surname != "Jones" ) cout << "Surnames are different." << endl; - - // Operators for Strings - String d1( "Cheese" ); - String d = d1; - cout << "d:" << d << endl; - - String e( "Mac&" ); - e += d; - cout << "e:" << e << endl; - - String f; - String f1("Tim likes "); - f = f1 + e; - cout << "f:" << f << endl; - - String num1( "one" ); - String num2( "Anyone", 3); - if ( num1 == num2 ) cout << "Numbers are the same." << endl; - - String eq1( "a + b" ); - String eq2( "a" ); - if ( eq1 != eq2 ) cout << "Equations are different." << endl; - - // Operators for single characters - String g; - g = 'y'; - cout << "g:" << g << endl; - - String h( "x" ); - h += g; - cout << "h:" << h << endl; - - String i; - i = convertToString( 'a' ) + 'b'; - cout << "i:" << i << endl; - - String letter1( "u" ); - if ( letter1 == "u" ) cout << "Letters are the same." << endl; - - String letter2( "v" ); - if ( letter2 != "w" ) cout << "Letters are different." << endl; - - // Cast to bool operators - String full( "string" ); - if ( full ) cout << "String is not empty." << endl; - - String empty; - if ( !empty ) cout << "String is empty." << endl; - - // replace - String phrase( "Hakuna matata" ); - String new_phrase = phrase.replace( "a", "u", 2 ); - cout << "new_phrase:" << new_phrase << endl; - - // strip - String names(" Josh Martin John Marley Charles "); - String better_names = names.strip(); - cout << "better_names:" << better_names << endl; - - // split - String dates("3/4/2005;8/7/2011;11/12/2019"); - std::vector<String> list = dates.split(';'); - cout << "list_dates: " << list[0] << ", " << list[1] << ", " << list[2] << endl; - - String cars("opel,mazda,,skoda,"); - std::vector<String> list3 = cars.split(',', true); - cout << "split with true:" << list3[0] << ", " << list3[1] << ", " << list3[2] << endl; - std::vector<String> list5 = cars.split(','); - cout << "split with false:" << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl; - - // save - File myFile; - myFile << String("Header"); // saves "Header" into myFile - - // load - String strg; - myFile >> strg; - cout << "strg:" << strg << endl; + String emptyString; + String string1( "string 1" ); + String string2( "string 2" ); + String string3( string2 ); + String string4 = convertToString( 28.4 ); + + cout << "empytString = " << emptyString << endl; + cout << "string1 = " << string1 << endl; + cout << "string2 = " << string2 << endl; + cout << "string3 = " << string3 << endl; + cout << "string4 = " << string4 << endl; + + cout << "emptyString size = " << emptyString.getSize() << endl; + cout << "string1 size = " << string1.getSize() << endl; + cout << "string1 length = " << string1.getLength() << endl; + + const char* c_string = string1.getString(); + cout << "c_string = " << c_string << endl; + + cout << " 3rd letter of string1 =" << string1[ 2 ] << endl; + + cout << " string1 + string2 = " << string1 + string2 << endl; + cout << " string1 + \" another string\" = " << string1 + " another string" << endl; + + string2 += "another string"; + cout << " string2 = " << string2; + string2 = "string 2"; + + if( string3 == string2 ) + cout << "string3 == string2" << endl; + if( string1 != string2 ) + cout << "string1 != string2" << endl; + + if( ! emptyString ) + cout << "emptyString is empty" << endl; + if( string1 ) + cout << "string1 is not empty" << endl; + + File myFile; + myFile.open( "string_save.out", File::Mode::Out ); + myFile << string1; + myFile.close(); + + myFile.open( "string_save.out", File::Mode::In ); + myFile >> string3; + cout << "string 3 after loading = " << string3 << endl; } diff --git a/src/Examples/StringExampleGetAllocatedSize.cpp b/src/Examples/StringExampleGetAllocatedSize.cpp index ad616de67304d41769fbd4389a0d2d3e03e90546..2065c6d1ff98d9e8905446702a206f0f3b9c5a6e 100644 --- a/src/Examples/StringExampleGetAllocatedSize.cpp +++ b/src/Examples/StringExampleGetAllocatedSize.cpp @@ -3,10 +3,9 @@ using namespace TNL; using namespace std; - + int main() { String str("my world"); - int alloc_size = str.getAllocatedSize(); - cout << "alloc_size:" << alloc_size << endl; + cout << "Allocated_size = " << str.getAllocatedSize() << endl; } \ No newline at end of file diff --git a/src/Examples/StringExampleGetSize.cpp b/src/Examples/StringExampleGetSize.cpp deleted file mode 100644 index 77fb499a478f45b9da7355355e01c747bdd1e639..0000000000000000000000000000000000000000 --- a/src/Examples/StringExampleGetSize.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include <iostream> -#include <TNL/String.h> - -using namespace TNL; -using namespace std; - -int main() -{ - String str("my world"); - int size = str.getSize(); - cout << "size of string:" << size << "bytes" << endl; -} - diff --git a/src/Examples/StringExampleReplace.cpp b/src/Examples/StringExampleReplace.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f24c82b1e9064563be7f72af6bbdf1e89017fe42 --- /dev/null +++ b/src/Examples/StringExampleReplace.cpp @@ -0,0 +1,13 @@ +#include <iostream> +#include <TNL/String.h> + +using namespace TNL; +using namespace std; + +int main() +{ + String phrase( "Say yes yes yes!" ); + cout << "phrase.replace( \"yes\", \"no\", 1 ) = " << phrase.replace( "yes", "no", 1 ) << endl; + cout << "phrase.replace( \"yes\", \"no\", 2 ) = " << phrase.replace( "yes", "no", 2 ) << endl; + cout << "phrase.replace( \"yes\", \"no\", 3 ) = " << phrase.replace( "yes", "no", 3 ) << endl; +} \ No newline at end of file diff --git a/src/Examples/StringExampleSetSize.cpp b/src/Examples/StringExampleSetSize.cpp index 8451295a75a87f49e46c286cb5ef6ea94c06dcc8..2b9de7844469e500271e0a10b347dd36a52dacd4 100644 --- a/src/Examples/StringExampleSetSize.cpp +++ b/src/Examples/StringExampleSetSize.cpp @@ -3,11 +3,11 @@ using namespace TNL; using namespace std; - + int main() { - String memory; - memory.setSize( 256 ); - int memorysize = memory.getSize(); - cout << "memory:" << memorysize << endl; + String string; + string.setSize( 1024 ); + cout << "String size = " << string.getSize() << endl; + cout << "Allocated size = " << string.getAllocatedSize() << endl; } diff --git a/src/Examples/StringExampleSplit.cpp b/src/Examples/StringExampleSplit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d0b45e52586d8eced440fdf422c1a20f01d3e1ba --- /dev/null +++ b/src/Examples/StringExampleSplit.cpp @@ -0,0 +1,18 @@ +#include <iostream> +#include <TNL/String.h> + +using namespace TNL; +using namespace std; + +int main() +{ + String dates("3/4/2005;8/7/2011;11/12/2019"); + vector< String > list = dates.split(';'); + cout << "list_dates = " << list[0] << ", " << list[1] << ", " << list[2] << endl; + + String cars("Subaru,Mazda,,Skoda," ); + vector< String > list3 = cars.split(',', String::SplitSkip::SkipEmpty ); + cout << "split with String::SkipEmpty = " << list3[0] << ", " << list3[1] << ", " << list3[2] << endl; + std::vector<String> list5 = cars.split(','); + cout << "split without String::SkipEmpty = " << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl; +} diff --git a/src/Examples/StringExampleStrip.cpp b/src/Examples/StringExampleStrip.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed3fd656ce5d0244a4caed6034efdad5cf7796c8 --- /dev/null +++ b/src/Examples/StringExampleStrip.cpp @@ -0,0 +1,13 @@ +#include <iostream> +#include <TNL/String.h> + +using namespace TNL; +using namespace std; + +int main() +{ + String names( " Josh Martin John Marley Charles " ); + String names2( ".......Josh Martin...John..Marley.Charles..." ); + cout << "names strip is: " << names.strip() << endl; + cout << "names2 strip is: " << names.strip( '.' ) << endl; +} \ No newline at end of file diff --git a/src/Examples/TimerExample.cpp b/src/Examples/TimerExample.cpp index 5d5a814540aa7265e023efb571627dffc3c47334..ab8cdb8635cffce0e89379e41ee1f601d4885c6f 100644 --- a/src/Examples/TimerExample.cpp +++ b/src/Examples/TimerExample.cpp @@ -1,11 +1,10 @@ #include <iostream> #include <TNL/Timer.h> -#include <TNL/Logger.h> #include <unistd.h> using namespace TNL; using namespace std; - + int main() { unsigned int microseconds = 0.5; @@ -13,11 +12,12 @@ int main() time.start(); usleep(microseconds); time.stop(); - cout << "before reset:" << time.getRealTime() << endl; + cout << "Elapsed real time: " << time.getRealTime() << endl; + cout << "Elapsed CPU time: " << time.getCPUTime() << endl; + cout << "Elapsed CPU cycles: " << time.getCPUCycles() << endl; time.reset(); - cout << "after reset:" << time.getRealTime() << endl; - // writeLog example - Logger log1(50,cout); - time.writeLog( log1, 0 ); + cout << "Real time after reset:" << time.getRealTime() << endl; + cout << "CPU time after reset: " << time.getCPUTime() << endl; + cout << "CPU cycles after reset: " << time.getCPUCycles() << endl; } diff --git a/src/Examples/TimerExampleLogger.cpp b/src/Examples/TimerExampleLogger.cpp new file mode 100644 index 0000000000000000000000000000000000000000..96dde57022418be1174c2e7278e11d10d58c845b --- /dev/null +++ b/src/Examples/TimerExampleLogger.cpp @@ -0,0 +1,19 @@ +#include <iostream> +#include <TNL/Timer.h> +#include <TNL/Logger.h> +#include <unistd.h> + +using namespace TNL; +using namespace std; + +int main() +{ + unsigned int microseconds = 0.5; + Timer time; + time.start(); + usleep(microseconds); + time.stop(); + + Logger logger( 50,cout ); + time.writeLog( logger, 0 ); +} diff --git a/src/Examples/flow-sw/navierStokesProblem_impl.h b/src/Examples/flow-sw/navierStokesProblem_impl.h index fbe14668a3af75727800a9038d6f77962b47848a..886c9f03f4e981cd9533d72ba5f71809388c6438 100644 --- a/src/Examples/flow-sw/navierStokesProblem_impl.h +++ b/src/Examples/flow-sw/navierStokesProblem_impl.h @@ -193,16 +193,13 @@ makeSnapshot( const RealType& time, fileName.setExtension( "tnl" ); fileName.setIndex( step ); fileName.setFileNameBase( "density-" ); - if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getDensity()->save( fileName.getFileName() ); fileName.setFileNameBase( "velocity-" ); - if( ! this->velocity->save( fileName.getFileName() ) ) - return false; + this->velocity->save( fileName.getFileName() ); fileName.setFileNameBase( "pressure-" ); - if( ! this->pressure->save( fileName.getFileName() ) ) - return false; + this->pressure->save( fileName.getFileName() ); /*fileName.setFileNameBase( "energy-" ); if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) ) diff --git a/src/Examples/flow-vl/navierStokesProblem_impl.h b/src/Examples/flow-vl/navierStokesProblem_impl.h index fbe14668a3af75727800a9038d6f77962b47848a..886c9f03f4e981cd9533d72ba5f71809388c6438 100644 --- a/src/Examples/flow-vl/navierStokesProblem_impl.h +++ b/src/Examples/flow-vl/navierStokesProblem_impl.h @@ -193,16 +193,13 @@ makeSnapshot( const RealType& time, fileName.setExtension( "tnl" ); fileName.setIndex( step ); fileName.setFileNameBase( "density-" ); - if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getDensity()->save( fileName.getFileName() ); fileName.setFileNameBase( "velocity-" ); - if( ! this->velocity->save( fileName.getFileName() ) ) - return false; + this->velocity->save( fileName.getFileName() ); fileName.setFileNameBase( "pressure-" ); - if( ! this->pressure->save( fileName.getFileName() ) ) - return false; + this->pressure->save( fileName.getFileName() ); /*fileName.setFileNameBase( "energy-" ); if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) ) diff --git a/src/Examples/flow/navierStokesProblem_impl.h b/src/Examples/flow/navierStokesProblem_impl.h index 96603490cf90a3834e6c9107242641614e04d5fb..4b0c7977441e87cab05fccab2c3984705670cfd4 100644 --- a/src/Examples/flow/navierStokesProblem_impl.h +++ b/src/Examples/flow/navierStokesProblem_impl.h @@ -209,8 +209,7 @@ makeSnapshot( const RealType& time, // return false; fileName.setFileNameBase( "velocity-" ); - if( ! this->velocity->save( fileName.getFileName() ) ) - return false; + this->velocity->save( fileName.getFileName() ); // fileName.setFileNameBase( "pressure-" ); // if( ! this->pressure->save( fileName.getFileName() ) ) diff --git a/src/Examples/inviscid-flow-sw/eulerProblem_impl.h b/src/Examples/inviscid-flow-sw/eulerProblem_impl.h index e043589cc7eb0330ab3f3caedfc6fa14ee1aa374..e0382e9c2485bbec5740df99af47b87a28122139 100644 --- a/src/Examples/inviscid-flow-sw/eulerProblem_impl.h +++ b/src/Examples/inviscid-flow-sw/eulerProblem_impl.h @@ -190,24 +190,19 @@ makeSnapshot( const RealType& time, fileName.setExtension( "tnl" ); fileName.setIndex( step ); fileName.setFileNameBase( "density-" ); - if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getDensity()->save( fileName.getFileName() ); fileName.setFileNameBase( "velocity-" ); - if( ! this->velocity->save( fileName.getFileName() ) ) - return false; + this->velocity->save( fileName.getFileName() ); fileName.setFileNameBase( "pressure-" ); - if( ! this->pressure->save( fileName.getFileName() ) ) - return false; + this->pressure->save( fileName.getFileName() ); fileName.setFileNameBase( "energy-" ); - if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getEnergy()->save( fileName.getFileName() ); fileName.setFileNameBase( "momentum-" ); - if( ! this->conservativeVariables->getMomentum()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getMomentum()->save( fileName.getFileName() ); return true; } diff --git a/src/Examples/inviscid-flow-vl/eulerProblem_impl.h b/src/Examples/inviscid-flow-vl/eulerProblem_impl.h index e043589cc7eb0330ab3f3caedfc6fa14ee1aa374..e0382e9c2485bbec5740df99af47b87a28122139 100644 --- a/src/Examples/inviscid-flow-vl/eulerProblem_impl.h +++ b/src/Examples/inviscid-flow-vl/eulerProblem_impl.h @@ -190,24 +190,19 @@ makeSnapshot( const RealType& time, fileName.setExtension( "tnl" ); fileName.setIndex( step ); fileName.setFileNameBase( "density-" ); - if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getDensity()->save( fileName.getFileName() ); fileName.setFileNameBase( "velocity-" ); - if( ! this->velocity->save( fileName.getFileName() ) ) - return false; + this->velocity->save( fileName.getFileName() ); fileName.setFileNameBase( "pressure-" ); - if( ! this->pressure->save( fileName.getFileName() ) ) - return false; + this->pressure->save( fileName.getFileName() ); fileName.setFileNameBase( "energy-" ); - if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getEnergy()->save( fileName.getFileName() ); fileName.setFileNameBase( "momentum-" ); - if( ! this->conservativeVariables->getMomentum()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getMomentum()->save( fileName.getFileName() ); return true; } diff --git a/src/Examples/inviscid-flow/eulerProblem_impl.h b/src/Examples/inviscid-flow/eulerProblem_impl.h index 7347755cb118832f86b1015dac5d16428294ad3f..f992a30671844f1e94d0e3007b86a6f807e33e14 100644 --- a/src/Examples/inviscid-flow/eulerProblem_impl.h +++ b/src/Examples/inviscid-flow/eulerProblem_impl.h @@ -190,20 +190,16 @@ makeSnapshot( const RealType& time, fileName.setExtension( "tnl" ); fileName.setIndex( step ); fileName.setFileNameBase( "density-" ); - if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getDensity()->save( fileName.getFileName() ); fileName.setFileNameBase( "velocity-" ); - if( ! this->velocity->save( fileName.getFileName() ) ) - return false; + this->velocity->save( fileName.getFileName() ); fileName.setFileNameBase( "pressure-" ); - if( ! this->pressure->save( fileName.getFileName() ) ) - return false; + this->pressure->save( fileName.getFileName() ); fileName.setFileNameBase( "energy-" ); - if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) ) - return false; + this->conservativeVariables->getEnergy()->save( fileName.getFileName() ); return true; } diff --git a/src/Examples/quad-test/main.cpp b/src/Examples/quad-test/main.cpp index 583d3c4ca8470297d320ec305a99e96f6ef547d7..7f4626d74a1b553c7ff624419b454b85fb69a78a 100644 --- a/src/Examples/quad-test/main.cpp +++ b/src/Examples/quad-test/main.cpp @@ -34,7 +34,7 @@ int main(int argc, char* argv[]) { String inputFile = parameters.getParameter <String> ("input-file"); File binaryFile; - if(! binaryFile.open(inputFile, IOMode::read)) { + if(! binaryFile.open(inputFile, File::Mode::In)) { cerr << "I am not able to open the file " << inputFile << "." << std::endl; return 1; } diff --git a/src/Examples/transport-equation/transportEquationProblemEoc_impl.h b/src/Examples/transport-equation/transportEquationProblemEoc_impl.h index 512e310d2f62ac5e118a729db9a1c5ae775bef89..0ac3af2d8d963ea89cbb9a40837cc298c243fa40 100644 --- a/src/Examples/transport-equation/transportEquationProblemEoc_impl.h +++ b/src/Examples/transport-equation/transportEquationProblemEoc_impl.h @@ -100,8 +100,7 @@ setup( const Config::ParameterContainer& parameters, fileName.setFileNameBase( "exact-u-" ); fileName.setExtension( "tnl" ); fileName.setIndex( step ); - if( ! u->save( fileName.getFileName() ) ) - return false; + u->save( fileName.getFileName() ); while( time < finalTime ) { time += snapshotPeriod; @@ -112,8 +111,7 @@ setup( const Config::ParameterContainer& parameters, std::cerr << exactSolution->getOperator().getShift() << std::endl; evaluator.evaluate( u, exactSolution, time ); fileName.setIndex( ++step ); - if( ! u->save( fileName.getFileName() ) ) - return false; + u->save( fileName.getFileName() ); } } if( velocityFieldType == "rotation" ) @@ -141,7 +139,11 @@ setInitialCondition( const Config::ParameterContainer& parameters, fileName.setFileNameBase( "exact-u-" ); fileName.setExtension( "tnl" ); fileName.setIndex( 0 ); - if( ! this->uPointer->boundLoad( fileName.getFileName() ) ) + try + { + this->uPointer->boundLoad( fileName.getFileName() ); + } + catch(...) { std::cerr << "I am not able to load the initial condition from the file " << fileName.getFileName() << "." << std::endl; return false; diff --git a/src/Examples/transport-equation/transportEquationProblem_impl.h b/src/Examples/transport-equation/transportEquationProblem_impl.h index 2d019602cc69f4703ac8caa5d81d8ad9d26e7275..80c018e853f859adf5e9138fa6dfb2d65fc550b4 100644 --- a/src/Examples/transport-equation/transportEquationProblem_impl.h +++ b/src/Examples/transport-equation/transportEquationProblem_impl.h @@ -117,7 +117,11 @@ setInitialCondition( const Config::ParameterContainer& parameters, { this->bindDofs( dofs ); const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" ); - if( ! this->uPointer->boundLoad( initialConditionFile ) ) + try + { + this->uPointer->boundLoad( initialConditionFile ); + } + catch(...) { std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl; return false; @@ -169,8 +173,7 @@ makeSnapshot( const RealType& time, fileName.setFileNameBase( "u-" ); fileName.setExtension( "tnl" ); fileName.setIndex( step ); - if( ! printDofs.save( fileName.getFileName() ) ) - return false; + printDofs.save( fileName.getFileName() ); return true; } diff --git a/src/Python/pytnl/tnl/Object.cpp b/src/Python/pytnl/tnl/Object.cpp index cd592a2c6ac8eb0e3cd24ce09c5e27110e92f8a2..56b0f54e523df5201a3a14261d3ab712f1ea11da 100644 --- a/src/Python/pytnl/tnl/Object.cpp +++ b/src/Python/pytnl/tnl/Object.cpp @@ -10,13 +10,13 @@ void export_Object( py::module & m ) { py::class_< TNL::Object >( m, "Object" ) // TODO: make it abstract class in Python - .def("save", (bool (TNL::Object::*)(const TNL::String &) const) &TNL::Object::save) - .def("load", (bool (TNL::Object::*)(const TNL::String &)) &TNL::Object::load) - .def("boundLoad", (bool (TNL::Object::*)(const TNL::String &)) &TNL::Object::boundLoad) + .def("save", (void (TNL::Object::*)(const TNL::String &) const) &TNL::Object::save) + .def("load", (void (TNL::Object::*)(const TNL::String &)) &TNL::Object::load) + .def("boundLoad", (void (TNL::Object::*)(const TNL::String &)) &TNL::Object::boundLoad) // FIXME: why does it not work? // .def("save", py::overload_cast<TNL::File>(&TNL::Object::save, py::const_)) // .def("load", py::overload_cast<TNL::File>(&TNL::Object::load)) - .def("save", (bool (TNL::Object::*)(TNL::File &) const) &TNL::Object::save) - .def("load", (bool (TNL::Object::*)(TNL::File &)) &TNL::Object::load) + .def("save", (void (TNL::Object::*)(TNL::File &) const) &TNL::Object::save) + .def("load", (void (TNL::Object::*)(TNL::File &)) &TNL::Object::load) ; } diff --git a/src/TNL/Communicators/MPIPrint.h b/src/TNL/Communicators/MPIPrint.h index 52684e5740c8a503fbb7e3de8c6723c587a0014c..825ae239f92487358a3eeae71479a8624025fc5e 100644 --- a/src/TNL/Communicators/MPIPrint.h +++ b/src/TNL/Communicators/MPIPrint.h @@ -25,7 +25,7 @@ else __tnl_mpi_print_stream_ << "Node " << TNL::Communicators::MpiCommunicator::GetRank() << " of " \ << TNL::Communicators::MpiCommunicator::GetSize() << " : " << message << std::endl; \ TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str().c_str() ); \ - __tnl_mpi_print_string_.send( 0, std::numeric_limits< int >::max() ); \ + mpiSend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() ); \ } \ else \ { \ @@ -35,7 +35,7 @@ else __tnl_mpi_print_j++ ) \ { \ TNL::String __tnl_mpi_print_string_; \ - __tnl_mpi_print_string_.receive( __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ + mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ std::cerr << __tnl_mpi_print_string_; \ } \ } \ @@ -78,7 +78,7 @@ else __tnl_mpi_print_stream_ << "Node " << TNL::Communicators::MpiCommunicator::GetRank() << " of " \ << TNL::Communicators::MpiCommunicator::GetSize() << " : " << message << std::endl; \ TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str().c_str() ); \ - __tnl_mpi_print_string_.send( 0, std::numeric_limits< int >::max() ); \ + mpiSsend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() ); \ } \ } \ else \ @@ -94,7 +94,7 @@ else if( __tnl_mpi_print_cond ) \ { \ TNL::String __tnl_mpi_print_string_; \ - __tnl_mpi_print_string_.receive( __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ + mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ std::cerr << __tnl_mpi_print_string_; \ } \ } \ diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h new file mode 100644 index 0000000000000000000000000000000000000000..62ab43a84aa4046ee195439bd3102d1be579f4f7 --- /dev/null +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -0,0 +1,93 @@ +/*************************************************************************** + ArrayOperations.h - description + ------------------- + begin : Jul 15, 2013 + copyright : (C) 2013 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include<type_traits> +#include<utility> +#include <TNL/Containers/Algorithms/ArrayOperations.h> + +namespace TNL { +namespace Containers { +namespace Algorithms { + +namespace Details { +/** + * SFINAE for checking if T has getArrayData method + */ +template< typename T > +class HasGetArrayData +{ +private: + typedef char YesType[1]; + typedef char NoType[2]; + + template< typename C > static YesType& test( decltype(std::declval< C >().getArrayData()) ); + template< typename C > static NoType& test(...); + +public: + static constexpr bool value = ( sizeof( test< T >(0) ) == sizeof( YesType ) ); +}; +} // namespace Details + +template< typename Array, + typename T, + bool hasGetArrayData = Details::HasGetArrayData< T >::value > +struct ArrayAssignment{}; + +/** + * \brief Specialization for array-array assignment with containers implementing + * getArrayData method. + */ +template< typename Array, + typename T > +struct ArrayAssignment< Array, T, true > +{ + static void resize( Array& a, const T& t ) + { + a.setSize( t.getSize() ); + } + + static void assign( Array& a, const T& t ) + { + TNL_ASSERT_EQ( a.getSize(), t.getSize(), "The sizes of the arrays must be equal." ); + if( t.getSize() > 0 ) // we allow even assignment of empty arrays + ArrayOperations< typename Array::DeviceType, typename T::DeviceType >::template + copyMemory< typename Array::ValueType, typename T::ValueType, typename Array::IndexType > + ( a.getArrayData(), t.getArrayData(), t.getSize() ); + }; +}; + +/** + * \brief Specialization for array-value assignment for other types. We assume + * that T is convertible to Array::ValueType. + */ +template< typename Array, + typename T > +struct ArrayAssignment< Array, T, false > +{ + static void resize( Array& a, const T& t ) + { + }; + static void assign( Array& a, const T& t ) + { + TNL_ASSERT_FALSE( a.empty(), "Cannot assign value to empty array." ); + ArrayOperations< typename Array::DeviceType >::template + setMemory< typename Array::ValueType, typename Array::IndexType > + ( a.getArrayData(), ( typename Array::ValueType ) t, a.getSize() ); + }; + +}; + + + +} // namespace Algorithms +} // namespace Containers +} // namespace TNL diff --git a/src/TNL/Containers/Algorithms/ArrayIO.h b/src/TNL/Containers/Algorithms/ArrayIO.h index 9b14f7cca0e68a928ac166ed4ae7f2ba147784f7..77e82355f82d414dc77224633ed5bc79a6f4fb08 100644 --- a/src/TNL/Containers/Algorithms/ArrayIO.h +++ b/src/TNL/Containers/Algorithms/ArrayIO.h @@ -71,14 +71,16 @@ class ArrayIO< Value, Device, Index, false > const Value* data, const Index elements ) { - return file.write< Value, Device >( data, elements ); + file.save< Value, Value, Device >( data, elements ); + return true; } static bool load( File& file, Value* data, const Index elements ) { - return file.read< Value, Device >( data, elements ); + file.load< Value, Value, Device >( data, elements ); + return true; } }; diff --git a/src/TNL/Containers/Algorithms/ArrayOperations.h b/src/TNL/Containers/Algorithms/ArrayOperations.h index 47050d32fd8f037251e3fe5258c98fe4d5f90b2c..a6acc816edc4e20a73949c49df42164e365475b9 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperations.h +++ b/src/TNL/Containers/Algorithms/ArrayOperations.h @@ -10,6 +10,7 @@ #pragma once +#include <list> #include <TNL/Devices/Host.h> #include <TNL/Devices/Cuda.h> #include <TNL/Devices/MIC.h> @@ -53,6 +54,11 @@ class ArrayOperations< Devices::Host > const SourceElement* source, const Index size ); + template< typename DestinationElement, + typename SourceElement > + static void copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ); + template< typename Element1, typename Element2, typename Index > @@ -104,6 +110,11 @@ class ArrayOperations< Devices::Cuda > const SourceElement* source, const Index size ); + template< typename DestinationElement, + typename SourceElement > + static void copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ); + template< typename Element1, typename Element2, typename Index > @@ -196,6 +207,11 @@ class ArrayOperations< Devices::MIC > const SourceElement* source, const Index size ); + template< typename DestinationElement, + typename SourceElement > + static void copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ); + template< typename Element1, typename Element2, typename Index > @@ -260,6 +276,6 @@ class ArrayOperations< Devices::Host, Devices::MIC > } // namespace Containers } // namespace TNL -#include <TNL/Containers/Algorithms/ArrayOperationsHost_impl.h> -#include <TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h> -#include <TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h> +#include <TNL/Containers/Algorithms/ArrayOperationsHost.hpp> +#include <TNL/Containers/Algorithms/ArrayOperationsCuda.hpp> +#include <TNL/Containers/Algorithms/ArrayOperationsMIC.hpp> diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp similarity index 90% rename from src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h rename to src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp index 34946628a0ed9bb60b70b8802e30cc4c1385e8c6..3efe7e4d472bb5d9766faee73946941a480374e4 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h +++ b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp @@ -171,6 +171,29 @@ copyMemory( DestinationElement* destination, #endif } +template< typename DestinationElement, + typename SourceElement > +void +ArrayOperations< Devices::Cuda >:: +copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ) +{ + const auto size = source.size(); + const std::size_t copy_buffer_size = std::min( Devices::Cuda::TransferBufferSize / (std::size_t) sizeof( DestinationElement ), ( std::size_t ) size ); + using BaseType = typename std::remove_cv< DestinationElement >::type; + std::unique_ptr< BaseType[] > copy_buffer{ new BaseType[ copy_buffer_size ] }; + size_t copiedElements = 0; + auto it = source.begin(); + while( copiedElements < size ) + { + const auto copySize = std::min( size - copiedElements, copy_buffer_size ); + for( size_t i = 0; i < copySize; i++ ) + copy_buffer[ i ] = static_cast< DestinationElement >( * it ++ ); + ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory( &destination[ copiedElements ], ©_buffer[ 0 ], copySize ); + copiedElements += copySize; + } +} + template< typename Element1, typename Element2, typename Index > @@ -245,7 +268,8 @@ copyMemory( DestinationElement* destination, } else { - std::unique_ptr< SourceElement[] > buffer{ new SourceElement[ Devices::Cuda::getGPUTransferBufferSize() ] }; + using BaseType = typename std::remove_cv< SourceElement >::type; + std::unique_ptr< BaseType[] > buffer{ new BaseType[ Devices::Cuda::getGPUTransferBufferSize() ] }; Index i( 0 ); while( i < size ) { diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp similarity index 93% rename from src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h rename to src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp index 18fe544ea120c8ebd7596e325a8bf01a9a9274c3..ff24b237deaa074b7e3a46602606957fbb0fc629 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h +++ b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp @@ -100,6 +100,19 @@ copyMemory( DestinationElement* destination, destination[ i ] = ( DestinationElement ) source[ i ]; } +template< typename DestinationElement, + typename SourceElement > +void +ArrayOperations< Devices::Host >:: +copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ) +{ + size_t i = 0; + for( const SourceElement& e : source ) + destination[ i ++ ] = static_cast< DestinationElement >( e ); +} + + template< typename DestinationElement, typename SourceElement, typename Index > diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp similarity index 97% rename from src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h rename to src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp index 1823d8077eb8a69364c457708e2287b19179cc31..b41e09f0bee1bfee02d2587b0cb865a8d4f78e91 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h +++ b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp @@ -139,6 +139,16 @@ copyMemory( DestinationElement* destination, #endif } +template< typename DestinationElement, + typename SourceElement > +void +ArrayOperations< Devices::MIC >:: +copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ) +{ + TNL_ASSERT( false, std::cerr << "TODO" ); +} + template< typename Element1, typename Element2, typename Index > diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 867bca6a2b6c66d9bd50eb823dd9280a8c362cca..fd6a1ac4e53ce92fda6552332539601245a2c093 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -10,9 +10,11 @@ #pragma once +#include <list> +#include <vector> + #include <TNL/Object.h> -#include <TNL/File.h> -#include <TNL/Devices/Host.h> +#include <TNL/Containers/ArrayView.h> namespace TNL { /** @@ -23,14 +25,37 @@ namespace Containers { template< int, typename > class StaticArray; /** - * \brief Array handles memory allocation and sharing of the same data between more Arrays. + * \brief Array is responsible for memory management, basic elements + * manipulation and I/O operations. + * + * \tparam Value is type of array elements. + * \tparam Device is device where the array is going to be allocated - some of \ref Devices::Host and \ref Devices::Cuda. + * \tparam Index is indexing type. * - * \tparam Value Type of array values. - * \tparam Device Device type. - * \tparam Index Type of index. + * In the \e Device type, the Array remembers where the memory is allocated. + * This ensures the compile-time checks of correct pointers manipulation. + * Methods defined as \ref __cuda_callable__ can be called even from kernels + * running on device. Array elements can be changed either using the \ref operator[] + * which is more efficient but it can be called from CPU only for arrays + * allocated on host (CPU) and when the array is allocated on GPU, the operator[] + * can be called only from kernels running on the device (GPU). On the other + * hand, methods \ref setElement and \ref getElement, can be called only from the + * host (CPU) does not matter if the array is allocated on the host or the device. + * In the latter case, explicit data transfer between host and device (via PCI + * express or NVlink in more lucky systems) is invoked and so it can be very + * slow. In not time critical parts of code, this is not an issue, however. + * Another way to change data stored in the array is \ref evaluate which evaluates + * given lambda function. This is performed at the same place where the array is + * allocated i.e. it is efficient even on GPU. For simple checking of the array + * contents, one may use methods \ref containValue and \ref containsValue and + * \ref containsOnlyValue. + * Array also offers data sharing using methods \ref bind. This is, however, obsolete + * and will be soon replaced with proxy object \ref ArrayView. * * \par Example * \include ArrayExample.cpp + * + * See also \ref Containers::ArravView, \ref Containers::Vector, \ref Containers::VectorView. */ template< typename Value, typename Device = Devices::Host, @@ -39,27 +64,36 @@ class Array : public Object { public: - typedef Value ValueType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Containers::Array< Value, Devices::Host, Index > HostType; - typedef Containers::Array< Value, Devices::Cuda, Index > CudaType; + using ValueType = Value; + using DeviceType = Device; + using IndexType = Index; + using HostType = Containers::Array< Value, Devices::Host, Index >; + using CudaType = Containers::Array< Value, Devices::Cuda, Index >; + using ViewType = ArrayView< Value, Device, Index >; + using ConstViewType = ArrayView< typename std::add_const< Value >::type, Device, Index >; - /** \brief Basic constructor. + /** + * \brief Basic constructor. * - * Constructs an empty array with the size of zero. + * Constructs an empty array with zero size. */ Array(); /** - * \brief Constructor with size. + * \brief Constructor with array size. * - * \param size Number of array elements. / Size of allocated memory. + * \param size is number of array elements. */ Array( const IndexType& size ); /** - * \brief Constructor with data and size. + * \brief Constructor with data pointer and size. + * + * In this case, the Array just encapsulates the pointer \e data. No + * deallocation is done in destructor. + * + * This behavior of the Array is obsolete and \ref ArrayView should be used + * instead. * * \param data Pointer to data. * \param size Number of array elements. @@ -70,47 +104,110 @@ class Array : public Object /** * \brief Copy constructor. * + * \param array is an array to be copied. + */ + explicit Array( const Array& array ); + + /** + * \brief Bind constructor . + * * The constructor does not make a deep copy, but binds to the supplied array. - * \param array Existing array that is to be bound. - * \param begin The first index which should be bound. - * \param size Number of array elements that should be bound. + * This is also obsolete, \ref ArraView should be used instead. + * + * \param array is an array that is to be bound. + * \param begin is the first index which should be bound. + * \param size is number of array elements that should be bound. */ Array( Array& array, const IndexType& begin = 0, const IndexType& size = 0 ); - /** \brief Returns type of array Value, Device type and the type of Index. */ + /** + * \brief Move constructor. + * + * @param array is an array to be moved + */ + Array( Array&& array ); + + /** + * \brief Initialize the array from initializer list, i.e. { ... } + * + * @param list Initializer list. + */ + template< typename InValue > + Array( const std::initializer_list< InValue >& list ); + + /** + * \brief Initialize the array from std::list. + * + * @param list Input STL list. + */ + template< typename InValue > + Array( const std::list< InValue >& list ); + + /** + * \brief Initialize the array from std::vector. + * + * @param vector Input STL vector. + */ + template< typename InValue > + Array( const std::vector< InValue >& vector ); + + /** + * \brief Returns array type in C++ style. + * + * \return String with array type. + */ static String getType(); - /** \brief Returns type of array Value, Device type and the type of Index. */ + /** + * \brief Returns array type in C++ style. + * + * \return String with array type. + */ virtual String getTypeVirtual() const; - /** \brief Returns (host) type of array Value, Device type and the type of Index. */ + /** + * \brief Returns array type in C++ style where device is always \ref Devices::Host. + * + * \return String with serialization array type. + */ static String getSerializationType(); - /** \brief Returns (host) type of array Value, Device type and the type of Index. */ + /** + * \brief Returns array type in C++ style where device is always \ref Devices::Host. + * + * \return String with serialization array type. + */ virtual String getSerializationTypeVirtual() const; /** - * \brief Method for setting the size of an array. + * \brief Method for setting the array size. * * If the array shares data with other arrays these data are released. * If the current data are not shared and the current size is the same * as the new one, nothing happens. * - * \param size Number of array elements. + * \param size is number of array elements. */ void setSize( Index size ); - /** \brief Method for getting the size of an array. */ + /** + * \brief Method for getting the size of an array. + * + * This method can be called from device kernels. + * + * \return Array size. + */ __cuda_callable__ Index getSize() const; /** * \brief Assigns features of the existing \e array to the given array. * * Sets the same size as the size of existing \e array. - * \tparam ArrayT Type of array. - * \param array Reference to an existing array. + * + * \tparam ArrayT is any array type having method \ref getSize(). + * \param array is reference to the source array. */ template< typename ArrayT > void setLike( const ArrayT& array ); @@ -120,8 +217,11 @@ class Array : public Object * * Releases old data and binds this array with new \e _data. Also sets new * \e _size of this array. - * @param _data Pointer to new data. - * @param _size Size of new _data. Number of elements. + * + * This method is obsolete, use \ref ArrayView instead. + * + * \param _data Pointer to new data. + * \param _size Size of new _data. Number of elements. */ void bind( Value* _data, const Index _size ); @@ -131,6 +231,9 @@ class Array : public Object * * Releases old data and binds this array with new \e array starting at * position \e begin. Also sets new \e size of this array. + * + * This method is obsolete, use \ref ArrayView instead. + * * \tparam ArrayT Type of array. * \param array Reference to a new array. * \param begin Starting index position. @@ -146,6 +249,9 @@ class Array : public Object * * Releases old data and binds this array with a static array of size \e * Size. + * + * This method is obsolete, use \ref ArrayView instead. + * * \tparam Size Size of array. * \param array Reference to a static array. */ @@ -153,135 +259,278 @@ class Array : public Object void bind( StaticArray< Size, Value >& array ); /** - * \brief Swaps all features of given array with existing \e array. + * \brief Returns a modifiable view of the array. + */ + ViewType getView(); + + /** + * \brief Returns a non-modifiable view of the array. + */ + ConstViewType getConstView() const; + + /** + * \brief Conversion operator to a modifiable view of the array. + */ + operator ViewType(); + + /** + * \brief Conversion operator to a non-modifiable view of the array. + */ + operator ConstViewType() const; + + /** + * \brief Swaps this array with another. * - * Swaps sizes, all values (data), allocated memory and references of given - * array with existing array. - * \param array Existing array, which features are swaped with given array. + * The swap is done in a shallow way, i.e. swapping only pointers and sizes. + * + * \param array is the array to be swapped with this array. */ void swap( Array& array ); /** - * \brief Resets the given array. + * \brief Resets the array. * - * Releases all data from array. + * Releases the array to empty state. */ void reset(); /** - * \brief Method for getting the data from given array with constant poiner. + * \brief Data pointer getter for constant instances. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. */ __cuda_callable__ const Value* getData() const; /** - * \brief Method for getting the data from given array. + * \brief Data pointer getter. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. */ __cuda_callable__ Value* getData(); /** - * \brief Assignes the value \e x to the array element at position \e i. + * \brief Data pointer getter for constant instances. + * + * Use this method in algorithms where you want to emphasize that + * C-style array pointer is required. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. + */ + __cuda_callable__ const Value* getArrayData() const; + + /** + * \brief Data pointer getter. + * + * Use this method in algorithms where you want to emphasize that + * C-style array pointer is required. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. + */ + __cuda_callable__ Value* getArrayData(); + + + /** + * \brief Array elements setter - change value of an element at position \e i. * - * \param i Index position. - * \param x New value of an element. + * This method can be called only from the host system (CPU) but even for + * arrays allocated on device (GPU). + * + * \param i is element index. + * \param v is the new value of the element. */ - void setElement( const Index& i, const Value& x ); + void setElement( const Index& i, const Value& v ); /** - * \brief Accesses specified element at the position \e i and returns its value. + * \brief Array elements getter - returns value of an element at position \e i. + * + * This method can be called only from the host system (CPU) but even for + * arrays allocated on device (GPU). * * \param i Index position of an element. + * + * \return Copy of i-th element. */ Value getElement( const Index& i ) const; /** - * \brief Accesses specified element at the position \e i and returns a reference to its value. + * \brief Accesses specified element at the position \e i. * - * \param i Index position of an element. + * This method can be called from device (GPU) kernels if the array is allocated + * on the device. In this case, it cannot be called from host (CPU.) + * + * \param i is position of the element. + * + * \return Reference to i-th element. */ - __cuda_callable__ inline Value& operator[] ( const Index& i ); + __cuda_callable__ inline Value& operator[]( const Index& i ); /** - * \brief Accesses specified element at the position \e i and returns a (constant?) reference to its value. + * \brief Accesses specified element at the position \e i. * - * \param i Index position of an element. + * This method can be called from device (GPU) kernels if the array is allocated + * on the device. In this case, it cannot be called from host (CPU.) + * + * \param i is position of the element. + * + * \return Constant reference to i-th pointer. */ - __cuda_callable__ inline const Value& operator[] ( const Index& i ) const; + __cuda_callable__ inline const Value& operator[]( const Index& i ) const; /** * \brief Assigns \e array to this array, replacing its current contents. * - * \param array Reference to an array. + * \param array is reference to the array. + * + * \return Reference to this array. */ - Array& operator = ( const Array& array ); + Array& operator=( const Array& array ); /** - * \brief Assigns \e array to this array, replacing its current contents. + * \brief Move contents of \e array to this array. * - * \tparam ArrayT Type of array. - * \param array Reference to an array. + * \param array is reference to the array. + * + * \return Reference to this array. */ - template< typename ArrayT > - Array& operator = ( const ArrayT& array ); + Array& operator=( Array&& array ); /** - * \brief This function checks whether this array is equal to \e array. + * \brief Assigns either array-like container or single value. * - * \tparam ArrayT Type of array. - * \param array Reference to an array. + * If \e T is array type i.e. \ref Array, \ref ArrayView, \ref StaticArray, + * \ref Vector, \ref VectorView, \ref StaticVector, \ref DistributedArray, + * \ref DistributedArrayView, \ref DistributedVector or + * \ref DistributedVectorView, its elements are copied into this array. If + * it is other type convertibly to Array::ValueType, all array elements are + * set to the value \e data. + * + * \tparam T is type of array or value type. + * + * \param data is a reference to array or value. + * + * \return Reference to this array. + */ + template< typename T > + Array& operator=( const T& data ); + + /** + * \brief Assigns STL list to this array. + * + * \param list is STL list + * + * \return Reference to this array. + */ + template< typename InValue > + Array& operator=( const std::list< InValue >& list ); + + /** + * \brief Assigns STL vector to this array. + * + * \param vector is STL vector + * + * \return Reference to this array. + */ + template< typename InValue > + Array& operator=( const std::vector< InValue >& vector ); + + /** + * \brief Comparison operator with another array-like container. + * + * \tparam ArrayT is type of an array-like container, i.e Array, ArrayView, Vector, VectorView, DistributedArray, DistributedVector etc. + * \param array is reference to an array. + * + * \return True if both arrays are equal element-wise and false otherwise. */ template< typename ArrayT > - bool operator == ( const ArrayT& array ) const; + bool operator==( const ArrayT& array ) const; /** * \brief This function checks whether this array is not equal to \e array. * * \tparam ArrayT Type of array. * \param array Reference to an array. + * + * \return True if both arrays are not equal element-wise and false otherwise. */ template< typename ArrayT > - bool operator != ( const ArrayT& array ) const; + bool operator!=( const ArrayT& array ) const; /** - * \brief Sets the array values. + * \brief Sets the array elements to given value. * * Sets all the array values to \e v. * * \param v Reference to a value. */ - void setValue( const Value& v ); + void setValue( const Value& v, + const Index begin = 0, + Index end = -1 ); /** - * \brief Checks if there is an element with value \e v in this array. + * \brief Checks if there is an element with value \e v. * - * \param v Reference to a value. + * By default, the method checks all array elements. By setting indexes + * \e begin and \e end, only elements in given interval are checked. + * + * \param v is reference to the value. + * \param begin is the first element to be checked + * \param end is the last element to be checked. If \e end equals -1, its + * value is replaces by the array size. + * + * \return True if there is **at least one** array element in interval [\e begin, \e end ) having value \e v. */ - bool containsValue( const Value& v ) const; + bool containsValue( const Value& v, + const Index begin = 0, + Index end = -1 ) const; /** - * \brief Checks if all elements in this array have the same value \e v. + * \brief Checks if all elements have the same value \e v. + * + * By default, the method checks all array elements. By setting indexes + * \e begin and \e end, only elements in given interval are checked. * * \param v Reference to a value. + * \param begin is the first element to be checked + * \param end is the last element to be checked. If \e end equals -1, its + * value is replaces by the array size. + * + * \return True if there **all** array elements in interval [\e begin, \e end ) have value \e v. */ - bool containsOnlyValue( const Value& v ) const; + bool containsOnlyValue( const Value& v, + const Index begin = 0, + Index end = -1 ) const; /** * \brief Returns true if non-zero size is set. + * + * This method can be called from device kernels. + * + * \return Returns \e true if array view size is zero, \e false otherwise. */ - operator bool() const; + __cuda_callable__ + bool empty() const; /** * \brief Method for saving the object to a \e file as a binary data. * * \param file Reference to a file. */ - bool save( File& file ) const; + void save( File& file ) const; /** * Method for loading the object from a file as a binary data. * * \param file Reference to a file. */ - bool load( File& file ); + void load( File& file ); /** * \brief This method loads data without reallocation. @@ -290,8 +539,10 @@ class Array : public Object * If the array was not initialize yet, common load is * performed. Otherwise, the array size must fit with * the size of array being loaded. + * + * This method is deprecated - use ArrayView instead. */ - bool boundLoad( File& file ); + void boundLoad( File& file ); using Object::save; @@ -308,10 +559,10 @@ class Array : public Object void releaseData() const; /** \brief Number of elements in array. */ - mutable Index size; + mutable Index size = 0; /** \brief Pointer to data. */ - mutable Value* data; + mutable Value* data = nullptr; /** * \brief Pointer to the originally allocated data. @@ -322,7 +573,7 @@ class Array : public Object * by TNL) are bind then this pointer is zero since no deallocation is * necessary. */ - mutable Value* allocationPointer; + mutable Value* allocationPointer = nullptr; /** * \brief Counter of objects sharing this array or some parts of it. @@ -330,13 +581,13 @@ class Array : public Object * The reference counter is allocated after first sharing of the data between * more arrays. This is to avoid unnecessary dynamic memory allocation. */ - mutable int* referenceCounter; + mutable int* referenceCounter = nullptr; }; template< typename Value, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index >& v ); +std::ostream& operator<<( std::ostream& str, const Array< Value, Device, Index >& v ); } // namespace Containers } // namespace TNL -#include <TNL/Containers/Array_impl.h> +#include <TNL/Containers/Array.hpp> diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array.hpp similarity index 63% rename from src/TNL/Containers/Array_impl.h rename to src/TNL/Containers/Array.hpp index b44bdf0a147fd46af42d3f70e7669cb78d8dec60..61c4db1da44d67ae6380eadcd9dedf8e11e6eee5 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array.hpp @@ -11,13 +11,16 @@ #pragma once #include <iostream> + #include <TNL/Assert.h> -#include <TNL/File.h> #include <TNL/Math.h> #include <TNL/param-types.h> #include <TNL/Containers/Algorithms/ArrayOperations.h> #include <TNL/Containers/Algorithms/ArrayIO.h> -#include <TNL/Containers/Array.h> +#include <TNL/Containers/Algorithms/ArrayAssignment.h> +#include <TNL/Exceptions/ArrayWrongSize.h> + +#include "Array.h" namespace TNL { namespace Containers { @@ -60,6 +63,20 @@ Array( Value* data, { } +template< typename Value, + typename Device, + typename Index > +Array< Value, Device, Index >:: +Array( const Array< Value, Device, Index >& array ) +: size( 0 ), + data( nullptr ), + allocationPointer( nullptr ), + referenceCounter( 0 ) +{ + this->setSize( array.getSize() ); + Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), array.getData(), array.getSize() ); +} + template< typename Value, typename Device, typename Index > @@ -92,6 +109,72 @@ Array( Array< Value, Device, Index >& array, } } +template< typename Value, + typename Device, + typename Index > +Array< Value, Device, Index >:: +Array( Array< Value, Device, Index >&& array ) +{ + this->size = array.size; + this->data = array.data; + this->allocationPointer = array.allocationPointer; + this->referenceCounter = array.referenceCounter; + + array.size = 0; + array.data = nullptr; + array.allocationPointer = nullptr; + array.referenceCounter = nullptr; +} + +template< typename Value, + typename Device, + typename Index > + template< typename InValue > +Array< Value, Device, Index >:: +Array( const std::initializer_list< InValue >& list ) +: size( 0 ), + data( 0 ), + allocationPointer( 0 ), + referenceCounter( 0 ) +{ + this->setSize( list.size() ); + //// + // Here we assume that the underlying array for initializer_list is const T[N] + // as noted here: + // https://en.cppreference.com/w/cpp/utility/initializer_list + Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), &( *list.begin() ), list.size() ); +} + +template< typename Value, + typename Device, + typename Index > + template< typename InValue > +Array< Value, Device, Index >:: +Array( const std::list< InValue >& list ) +: size( 0 ), + data( 0 ), + allocationPointer( 0 ), + referenceCounter( 0 ) +{ + this->setSize( list.size() ); + Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list ); +} + +template< typename Value, + typename Device, + typename Index > + template< typename InValue > +Array< Value, Device, Index >:: +Array( const std::vector< InValue >& vector ) +: size( 0 ), + data( 0 ), + allocationPointer( 0 ), + referenceCounter( 0 ) +{ + this->setSize( vector.size() ); + Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), vector.data(), vector.size() ); +} + template< typename Value, typename Device, typename Index > @@ -192,7 +275,7 @@ Index Array< Value, Device, Index >:: getSize() const { - return this -> size; + return this->size; } template< typename Value, @@ -273,6 +356,43 @@ bind( StaticArray< Size, Value >& array ) this->data = array.getData(); } +template< typename Value, + typename Device, + typename Index > +typename Array< Value, Device, Index >::ViewType +Array< Value, Device, Index >:: +getView() +{ + return ViewType( getData(), getSize() ); +} + +template< typename Value, + typename Device, + typename Index > +typename Array< Value, Device, Index >::ConstViewType +Array< Value, Device, Index >:: +getConstView() const +{ + return ConstViewType( getData(), getSize() ); +} + +template< typename Value, + typename Device, + typename Index > +Array< Value, Device, Index >:: +operator ViewType() +{ + return getView(); +} + +template< typename Value, + typename Device, + typename Index > +Array< Value, Device, Index >:: +operator ConstViewType() const +{ + return getConstView(); +} template< typename Value, typename Device, @@ -315,6 +435,24 @@ Value* Array< Value, Device, Index >::getData() return this->data; } +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +const Value* Array< Value, Device, Index >::getArrayData() const +{ + return this->data; +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +Value* Array< Value, Device, Index >::getArrayData() +{ + return this->data; +} + template< typename Value, typename Device, typename Index > @@ -345,7 +483,7 @@ template< typename Value, __cuda_callable__ inline Value& Array< Value, Device, Index >:: -operator[] ( const Index& i ) +operator[]( const Index& i ) { TNL_ASSERT_GE( i, (Index) 0, "Element index must be non-negative." ); TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); @@ -358,7 +496,7 @@ template< typename Value, __cuda_callable__ inline const Value& Array< Value, Device, Index >:: -operator[] ( const Index& i ) const +operator[]( const Index& i ) const { TNL_ASSERT_GE( i, (Index) 0, "Element index must be non-negative." ); TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); @@ -370,7 +508,7 @@ template< typename Value, typename Index > Array< Value, Device, Index >& Array< Value, Device, Index >:: -operator = ( const Array< Value, Device, Index >& array ) +operator=( const Array< Value, Device, Index >& array ) { //TNL_ASSERT_EQ( array.getSize(), this->getSize(), "Array sizes must be the same." ); if( this->getSize() != array.getSize() ) @@ -380,26 +518,66 @@ operator = ( const Array< Value, Device, Index >& array ) copyMemory( this->getData(), array.getData(), array.getSize() ); - return ( *this ); + return *this; } template< typename Value, typename Device, typename Index > - template< typename ArrayT > Array< Value, Device, Index >& Array< Value, Device, Index >:: -operator = ( const ArrayT& array ) +operator=( Array< Value, Device, Index >&& array ) { - //TNL_ASSERT_EQ( array.getSize(), this->getSize(), "Array sizes must be the same." ); - if( this->getSize() != array.getSize() ) - this->setLike( array ); - if( this->getSize() > 0 ) - Algorithms::ArrayOperations< Device, typename ArrayT::DeviceType >:: - copyMemory( this->getData(), - array.getData(), - array.getSize() ); - return ( *this ); + this->size = array.size; + this->data = array.data; + this->allocationPointer = array.allocationPointer; + this->referenceCounter = array.referenceCounter; + + array.size = 0; + array.data = nullptr; + array.allocationPointer = nullptr; + array.referenceCounter = nullptr; + return *this; +} + + +template< typename Value, + typename Device, + typename Index > + template< typename T > +Array< Value, Device, Index >& +Array< Value, Device, Index >:: +operator=( const T& data ) +{ + Algorithms::ArrayAssignment< Array, T >::assign( *this, data ); + return *this; +} + +template< typename Value, + typename Device, + typename Index > + template< typename InValue > +Array< Value, Device, Index >& +Array< Value, Device, Index >:: +operator=( const std::list< InValue >& list ) +{ + this->setSize( list.size() ); + Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list ); + return *this; +} + +template< typename Value, + typename Device, + typename Index > + template< typename InValue > +Array< Value, Device, Index >& +Array< Value, Device, Index >:: +operator=( const std::vector< InValue >& vector ) +{ + if( this->getSize() != vector.size() ) + this->setSize( vector.size() ); + Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), vector.data(), vector.size() ); + return *this; } template< typename Value, @@ -408,7 +586,7 @@ template< typename Value, template< typename ArrayT > bool Array< Value, Device, Index >:: -operator == ( const ArrayT& array ) const +operator==( const ArrayT& array ) const { if( array.getSize() != this->getSize() ) return false; @@ -424,18 +602,24 @@ template< typename Value, typename Device, typename Index > template< typename ArrayT > -bool Array< Value, Device, Index >::operator != ( const ArrayT& array ) const +bool +Array< Value, Device, Index >:: +operator!=( const ArrayT& array ) const { - return ! ( ( *this ) == array ); + return ! ( *this == array ); } template< typename Value, typename Device, typename Index > -void Array< Value, Device, Index >::setValue( const Value& e ) +void Array< Value, Device, Index >::setValue( const ValueType& e, + const Index begin, + Index end ) { TNL_ASSERT_TRUE( this->getData(), "Attempted to set a value of an empty array." ); - Algorithms::ArrayOperations< Device >::setMemory( this->getData(), e, this->getSize() ); + if( end == -1 ) + end = this->getSize(); + Algorithms::ArrayOperations< Device >::setMemory( &this->getData()[ begin ], e, end - begin ); } template< typename Value, @@ -443,9 +627,15 @@ template< typename Value, typename Index > bool Array< Value, Device, Index >:: -containsValue( const Value& v ) const +containsValue( const Value& v, + const Index begin, + Index end ) const { - return Algorithms::ArrayOperations< Device >::containsValue( this->data, this->size, v ); + TNL_ASSERT_TRUE( this->getData(), "Attempted to check a value of an empty array." ); + if( end == -1 ) + end = this->getSize(); + + return Algorithms::ArrayOperations< Device >::containsValue( &this->getData()[ begin ], end - begin, v ); } template< typename Value, @@ -453,111 +643,78 @@ template< typename Value, typename Index > bool Array< Value, Device, Index >:: -containsOnlyValue( const Value& v ) const +containsOnlyValue( const Value& v, + const Index begin, + Index end ) const { - return Algorithms::ArrayOperations< Device >::containsOnlyValue( this->data, this->size, v ); + TNL_ASSERT_TRUE( this->getData(), "Attempted to check a value of an empty array." ); + if( end == -1 ) + end = this->getSize(); + + return Algorithms::ArrayOperations< Device >::containsOnlyValue( &this->getData()[ begin ], end - begin, v ); } template< typename Value, typename Device, typename Index > -Array< Value, Device, Index >::operator bool() const +bool +__cuda_callable__ +Array< Value, Device, Index >:: +empty() const { - return data != 0; + return ( data == nullptr ); } - template< typename Value, typename Device, typename Index > -bool Array< Value, Device, Index >::save( File& file ) const +void Array< Value, Device, Index >::save( File& file ) const { - if( ! Object::save( file ) ) - return false; - if( ! file.write( &this->size ) ) - return false; - if( this->size != 0 && ! Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size ) ) - { - std::cerr << "I was not able to save " << this->getType() - << " with size " << this -> getSize() << std::endl; - return false; - } - return true; + Object::save( file ); + file.save( &this->size ); + if( this->size != 0 ) + Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size ); } template< typename Value, typename Device, typename Index > -bool +void Array< Value, Device, Index >:: load( File& file ) { - if( ! Object::load( file ) ) - return false; + Object::load( file ); Index _size; - if( ! file.read( &_size ) ) - { - std::cerr << "Unable to read the array size." << std::endl; - return false; - } + file.load( &_size ); if( _size < 0 ) - { - std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl; - return false; - } + throw Exceptions::ArrayWrongSize( _size, "positive" ); setSize( _size ); if( _size ) - { - if( ! Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ) ) - { - std::cerr << "I was not able to load " << this->getType() - << " with size " << this -> getSize() << std::endl; - return false; - } - } - return true; + Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ); } template< typename Value, typename Device, typename Index > -bool +void Array< Value, Device, Index >:: boundLoad( File& file ) { - if( ! Object::load( file ) ) - return false; + Object::load( file ); Index _size; - if( ! file.read( &_size ) ) - return false; + file.load( &_size ); if( _size < 0 ) - { - std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl; - return false; - } + throw Exceptions::ArrayWrongSize( _size, "Positive is expected," ); if( this->getSize() != 0 ) { if( this->getSize() != _size ) - { - std::cerr << "Error: The current array size is not zero (" << this->getSize() << ") and it is different from the size of " - << "the array being loaded (" << _size << "). This is not possible. Call method reset() before." << std::endl; - return false; - } + throw Exceptions::ArrayWrongSize( _size, convertToString( this->getSize() ) + " is expected." ); } else setSize( _size ); if( _size ) - { - if( ! Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ) ) - { - std::cerr << "I was not able to load " << this->getType() - << " with size " << this -> getSize() << std::endl; - return false; - } - } - return true; + Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ); } - template< typename Value, typename Device, typename Index > @@ -568,7 +725,7 @@ Array< Value, Device, Index >:: } template< typename Value, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index >& v ) +std::ostream& operator<<( std::ostream& str, const Array< Value, Device, Index >& v ) { str << "[ "; if( v.getSize() > 0 ) diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 7e98a0d3db82209e70e810f6773f56e12094f18a..91de01dac18b7dd1a0178c0ae19b4cb449ec822a 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -12,6 +12,9 @@ #pragma once +#include <type_traits> // std::add_const + +#include <TNL/File.h> #include <TNL/Devices/Host.h> #include <TNL/Devices/Cuda.h> @@ -21,126 +24,424 @@ namespace Containers { template< typename Value, typename Device, typename Index > class Array; -template< int Size, typename Value > -class StaticArray; - +/** + * \brief ArrayView serves for managing array of data allocated by TNL::Array or + * another way. It makes no data deallocation at the end of its life cycle. Compared + * to TNL Array, it is lighter data structure and therefore it is more efficient + * especially when it is being passed on GPU. The ArrayView can also be created + * in CUDA kernels which is not the case of Array. + * + * \tparam Value is type of array elements. + * \tparam Device is device where the array is going to be allocated - some of \ref Devices::Host and \ref Devices::Cuda. + * \tparam Index is indexing type. + * + * In the \e Device type, the Array remembers where the memory is allocated. + * This ensures the compile-time checks of correct pointers manipulation. + * Methods defined as \ref __cuda_callable__ can be called even from kernels + * running on device. Array elements can be changed either using the \ref operator[]. + * This can be called from CPU only for arrays allocated on host (CPU). If the + * array is allocated on GPU, the operator[] can be called only from kernels + * running on the device (GPU). On the other hand, methods \ref setElement and + * \ref getElement, can be called only from the host (CPU) does not matter if + * the array resides on the host or the device. In the latter case, explicit data + * transfer between host and device (via PCI express or NVlink in more lucky + * systems) is invoked and so it can be very slow. In not time critical parts + * of code, this is not an issue, however. Another way to change data being + * accessed by the ArrayView is \ref evaluate which evaluates given lambda + * function. This is performed at the same place where the array is + * allocated i.e. it is efficient even on GPU. For simple checking of the array + * contents, one may use methods \ref containValue and \ref containsValue and + * \ref containsOnlyValue. + * + * \par Example + * \include ArrayViewExample.cpp + * + * See also \ref Containers::Arrav, \ref Containers::Vector, \ref Containers::VectorView, + * Containers::StaticArray, Containers::StaticVector. + */ template< typename Value, typename Device = Devices::Host, typename Index = int > class ArrayView { + using SerializationType = Array< Value, Devices::Host, Index >; public: using ValueType = Value; using DeviceType = Device; using IndexType = Index; using HostType = ArrayView< Value, Devices::Host, Index >; using CudaType = ArrayView< Value, Devices::Cuda, Index >; + using ViewType = ArrayView< Value, Device, Index >; + using ConstViewType = ArrayView< typename std::add_const< Value >::type, Device, Index >; + + /** + * \brief Returns type of array view in C++ style. + * + * \return String with array view type. + */ + static String getType(); + /** + * \brief Basic constructor for empty ArrayView. + * + * This method can be called from device kernels. + */ __cuda_callable__ ArrayView() = default; - // explicit initialization by raw data pointer and size + /** + * \brief Constructor with explicit initialization by raw data pointer and size. + * + * This method can be called from device kernels. + * + * \param data is data pointer + * \param size is number of elements to be managed by the array view + */ __cuda_callable__ ArrayView( Value* data, Index size ); - // Copy-constructor does shallow copy, so views can be passed-by-value into - // CUDA kernels and they can be captured-by-value in __cuda_callable__ - // lambda functions. + /** + * \brief Copy constructor. + * Copy-constructor does shallow copy, so views can be passed-by-value into + * CUDA kernels and they can be captured-by-value in __cuda_callable__ + * lambda functions. + * + * This method can be called from device kernels. + * + * \param view is ArrayView to be copied. + */ __cuda_callable__ - ArrayView( const ArrayView& ) = default; - - // "Templated copy-constructor" accepting any cv-qualification of Value + ArrayView( const ArrayView& view ) = default; + + /** + * \brief "Templated copy-constructor". + * + * It makes shallow copy only. + * + * This method can be called from device kernels. + * + * \tparam Value is any cv-qualified ValueType. + */ template< typename Value_ > __cuda_callable__ ArrayView( const ArrayView< Value_, Device, Index >& array ) : data(array.getData()), size(array.getSize()) {} - // default move-constructor - __cuda_callable__ - ArrayView( ArrayView&& ) = default; - - // initialization from other array containers (using shallow copy) - template< typename Value_ > // template catches both const and non-const qualified Value - __cuda_callable__ - ArrayView( Array< Value_, Device, Index >& array ); - - template< int Size, typename Value_ > // template catches both const and non-const qualified Value - __cuda_callable__ - ArrayView( StaticArray< Size, Value_ >& array ); - - // these constructors will be used only when Value is const-qualified - // (const views are initializable by const references) - template< typename Value_ > // template catches both const and non-const qualified Value + /** + * \brief Default move-constructor. + * + * This method can be called from device kernels. + * + * \param view is ArrayView to be moved to this ArrayView. + */ __cuda_callable__ - ArrayView( const Array< Value_, Device, Index >& array ); - - template< int Size, typename Value_ > // template catches both const and non-const qualified Value - __cuda_callable__ - ArrayView( const StaticArray< Size, Value_ >& array ); - - - // methods for rebinding (reinitialization) + ArrayView( ArrayView&& view ) = default; + + /** + * \brief Method for rebinding (reinitialization). + * + * This method can be called from device kernels. + * + * \param data is pointer to data to be bound to the array view. + * \param size is the number of elements to be managed by the array view. + */ __cuda_callable__ void bind( Value* data, const Index size ); - // Note that you can also bind directly to Array and other types implicitly - // convertible to ArrayView. + /** + * \brief Method for rebinding (reinitialization) with another ArrayView. + * + * Note that you can also bind directly to Array and other types implicitly + * convertible to ArrayView. + * + * This method can be called from device kernels. + * + * \param view is array view to be bound. + */ __cuda_callable__ void bind( ArrayView view ); + /** + * \brief Returns a modifiable view of the array view. + */ + __cuda_callable__ + ViewType getView(); - // Copy-assignment does deep copy, just like regular array, but the sizes - // must match (i.e. copy-assignment cannot resize). + /** + * \brief Returns a non-modifiable view of the array view. + */ + __cuda_callable__ + ConstViewType getConstView() const; + + /** + * \brief Assignment operator. + * + * Copy-assignment does deep copy, just like regular array, but the sizes + * must match (i.e. copy-assignment cannot resize). + * + * \param view is array view to be copied + */ ArrayView& operator=( const ArrayView& view ); - template< typename Array > - ArrayView& operator=( const Array& array ); - - - static String getType(); - - + /** + * \brief Assignment operator for array-like containers or single value. + * + * If \e T is array type i.e. \ref Array, \ref ArrayView, \ref StaticArray, + * \ref Vector, \ref VectorView, \ref StaticVector, \ref DistributedArray, + * \ref DistributedArrayView, \ref DistributedVector or + * \ref DistributedVectorView, its elements are copied into this array. If + * it is other type convertibly to ArrayView::ValueType, all array elements are + * set to the value \e data. + * + * \tparam T is type of array or value type. + * + * \param data is a reference to array or value. + * + * \return Reference to this array. + */ + template< typename T > + ArrayView& operator=( const T& array ); + + /** + * \brief Swaps this array view content with another. + * + * The swap is done in a shallow way, i.e. swapping only pointers and sizes. + * + * This method can be called from device kernels. + * + * \param view is the array view to be swapped with this array view. + */ __cuda_callable__ void swap( ArrayView& view ); + /*** + * \brief Resets the array view. + * + * The array view behaves like being empty after calling this method. + * + * This method can be called from device kernels. + */ __cuda_callable__ void reset(); + /** + * \brief Returns constant pointer to data managed by the array view. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. + */ __cuda_callable__ const Value* getData() const; + /** + * \brief Returns pointer to data managed by the array view. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. + */ __cuda_callable__ Value* getData(); + /** + * \brief Returns constant pointer to data managed by the array view. + * + * Use this method in algorithms where you want to emphasize that + * C-style array pointer is required. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. + */ + __cuda_callable__ + const Value* getArrayData() const; + + /** + * \brief Returns pointer to data managed by the array view. + * + * Use this method in algorithms where you want to emphasize that + * C-style array pointer is required. + * + * This method can be called from device kernels. + * + * \return Pointer to array data. + */ + __cuda_callable__ + Value* getArrayData(); + + /** + * \brief Returns the array view size, i.e. number of elements being managed by the array view. + * + * This method can be called from device kernels. + * + * \return The array view size. + */ __cuda_callable__ Index getSize() const; + /** + * \brief Array view elements setter - change value of an element at position \e i. + * + * This method can be called only from the host system (CPU) but even for + * array views managing data allocated on device (GPU). + * + * \param i is element index. + * \param v is the new value of the element. + */ void setElement( Index i, Value value ); + /** + * \brief Array view elements getter - returns value of an element at position \e i. + * + * This method can be called only from the host system (CPU) but even for + * array views managing data allocated on device (GPU). + * + * \param i Index position of an element. + * + * \return Copy of i-th element. + */ Value getElement( Index i ) const; + /** + * \brief Accesses specified element at the position \e i. + * + * This method can be called from device (GPU) kernels if the array view + * manages data allocated on the device. In this case, it cannot be called + * from the host (CPU.) + * + * \param i is position of the element. + * + * \return Reference to i-th element. + */ __cuda_callable__ Value& operator[]( Index i ); + /** + * \brief Returns constant reference to an element at a position \e i. + * + * This method can be called from device (GPU) kernels if the array view + * manages data allocated on the device. In this case, it cannot be called + * from the host (CPU.) + * + * \param i is position of the element. + * + * \return Reference to i-th element. + */ __cuda_callable__ const Value& operator[]( Index i ) const; - template< typename Value_, typename Device_, typename Index_ > - bool operator==( const ArrayView< Value_, Device_, Index_ >& view ) const; - - template< typename Value_, typename Device_, typename Index_ > - bool operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const; - + /** + * \brief Comparison operator with another array-like container \e array. + * + * \tparam ArrayT is type of an array-like container, i.e Array, ArrayView, Vector, VectorView, DistributedArray, DistributedVector etc. + * \param array is reference to an array. + * + * \return True if both array views are equal element-wise and false otherwise. + */ + template< typename ArrayT > + bool operator==( const ArrayT& array ) const; + + /** + * \brief Comparison negation operator with another array-like container \e array. + * + * \tparam ArrayT is type of an array-like container, i.e Array, ArrayView, Vector, VectorView, DistributedArray, DistributedVector etc. + * \param array is reference to an array. + * + * \return True if both array views are not equal element-wise and false otherwise. + */ + template< typename ArrayT > + bool operator!=( const ArrayT& array ) const; + + /** + * \brief Sets the array view elements to given value. + * + * Sets all the array values to \e v. + * + * \param v Reference to a value. + */ void setValue( Value value ); - // Checks if there is an element with given value in this array + /** + * \brief Sets the array elements using given lambda function. + * + * Sets all the array values to \e v. + * + * \param v Reference to a value. + */ + template< typename Function > + void evaluate( Function& f, + const Index begin = 0, + Index end = -1 ); + + /** + * \brief Checks if there is an element with value \e v. + * + * By default, the method checks all array view elements. By setting indexes + * \e begin and \e end, only elements in given interval are checked. + * + * \param v is reference to the value. + * \param begin is the first element to be checked + * \param end is the last element to be checked. If \e end equals -1, its + * value is replaces by the array size. + * + * \return True if there is **at least one** array element in interval [\e begin, \e end ) having value \e v. + */ bool containsValue( Value value ) const; - // Checks if all elements in this array have the same given value + /** + * \brief Checks if all elements have the same value \e v. + * + * By default, the method checks all array view elements. By setting indexes + * \e begin and \e end, only elements in given interval are checked. + * + * \param v Reference to a value. + * \param begin is the first element to be checked + * \param end is the last element to be checked. If \e end equals -1, its + * value is replaces by the array size. + * + * \return True if there **all** array elements in interval [\e begin, \e end ) have value \e v. + */ bool containsOnlyValue( Value value ) const; - //! Returns true if non-zero size is set. - operator bool() const; + /** + * \brief Returns true if non-zero size is set. + * + * This method can be called from device kernels. + * + * \return Returns \e true if array view size is zero, \e false otherwise. + */ + __cuda_callable__ + bool empty() const; + + /** + * \brief Method for saving the object to a \e file as a binary data. + * + * \param file Reference to a file. + */ + void save( File& file ) const; + + /** + * Method for loading the object from a file as a binary data. + * + * \param file Reference to a file. + */ + void load( File& file ); + + /** + * \brief Method for saving the array view to a file as a binary data. + * + * \param fileName String defining the name of a file. + */ + void save( const String& fileName ) const; + + /** + * \brief Method for restoring the array view from a file. + * + * \param fileName String defining the name of a file. + */ + void load( const String& fileName ); + protected: //! Pointer to allocated data @@ -156,4 +457,4 @@ std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Ind } // namespace Containers } // namespace TNL -#include <TNL/Containers/ArrayView_impl.h> +#include <TNL/Containers/ArrayView.hpp> diff --git a/src/TNL/Containers/ArrayView_impl.h b/src/TNL/Containers/ArrayView.hpp similarity index 71% rename from src/TNL/Containers/ArrayView_impl.h rename to src/TNL/Containers/ArrayView.hpp index 96d00e7dea42ae244f928f5679a1045ba78af856..a32c2c5f07659e368ced1832bf68835126aed868 100644 --- a/src/TNL/Containers/ArrayView_impl.h +++ b/src/TNL/Containers/ArrayView.hpp @@ -13,98 +13,89 @@ #include <iostream> #include <TNL/param-types.h> +#include <TNL/ParallelFor.h> #include <TNL/Containers/Algorithms/ArrayOperations.h> +#include <TNL/Containers/Algorithms/ArrayIO.h> +#include <TNL/Containers/Algorithms/ArrayAssignment.h> +#include <TNL/Exceptions/ArrayWrongSize.h> #include "ArrayView.h" namespace TNL { namespace Containers { -// explicit initialization by raw data pointer and size template< typename Value, typename Device, typename Index > -__cuda_callable__ +String ArrayView< Value, Device, Index >:: -ArrayView( Value* data, Index size ) : data(data), size(size) +getType() { - TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." ); - TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0), - "ArrayView was initialized with a positive address and zero size or zero address and positive size." ); + return String( "Containers::ArrayView< " ) + ", " + + TNL::getType< Value >() + ", " + + Device::getDeviceType() + ", " + + TNL::getType< Index >() + " >"; } -// initialization from other array containers (using shallow copy) +// explicit initialization by raw data pointer and size template< typename Value, typename Device, typename Index > - template< typename Value_ > __cuda_callable__ ArrayView< Value, Device, Index >:: -ArrayView( Array< Value_, Device, Index >& array ) +ArrayView( Value* data, Index size ) : data(data), size(size) { - this->bind( array.getData(), array.getSize() ); + TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." ); + TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0), + "ArrayView was initialized with a positive address and zero size or zero address and positive size." ); } +// methods for rebinding (reinitialization) template< typename Value, typename Device, typename Index > - template< int Size, typename Value_ > __cuda_callable__ +void ArrayView< Value, Device, Index >:: -ArrayView( StaticArray< Size, Value_ >& array ) +bind( Value* data, Index size ) { - this->bind( array.getData(), Size ); -} + TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." ); + TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0), + "ArrayView was initialized with a positive address and zero size or zero address and positive size." ); -template< typename Value, - typename Device, - typename Index > - template< typename Value_ > -__cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( const Array< Value_, Device, Index >& array ) -{ - this->bind( array.getData(), array.getSize() ); + this->data = data; + this->size = size; } template< typename Value, typename Device, typename Index > - template< int Size, typename Value_ > __cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( const StaticArray< Size, Value_ >& array ) +void ArrayView< Value, Device, Index >::bind( ArrayView view ) { - this->bind( array.getData(), Size ); + bind( view.getData(), view.getSize() ); } -// methods for rebinding (reinitialization) template< typename Value, typename Device, typename Index > -__cuda_callable__ -void +typename ArrayView< Value, Device, Index >::ViewType ArrayView< Value, Device, Index >:: -bind( Value* data, Index size ) +getView() { - TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." ); - TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0), - "ArrayView was initialized with a positive address and zero size or zero address and positive size." ); - - this->data = data; - this->size = size; + return *this; } template< typename Value, typename Device, typename Index > -__cuda_callable__ -void ArrayView< Value, Device, Index >::bind( ArrayView view ) +typename ArrayView< Value, Device, Index >::ConstViewType +ArrayView< Value, Device, Index >:: +getConstView() const { - bind( view.getData(), view.getSize() ); + return *this; } - // Copy-assignment does deep copy, just like regular array, but the sizes // must match (i.e. copy-assignment cannot resize). template< typename Value, @@ -120,35 +111,18 @@ operator=( const ArrayView& view ) return *this; } -template< typename Value, - typename Device, - typename Index > - template< typename Array > -ArrayView< Value, Device, Index >& -ArrayView< Value, Device, Index >:: -operator=( const Array& array ) -{ - TNL_ASSERT_EQ( getSize(), array.getSize(), "The sizes of the array views must be equal, views are not resizable." ); - if( getSize() > 0 ) - Algorithms::ArrayOperations< Device, typename Array::DeviceType >::copyMemory( getData(), array.getData(), getSize() ); - return *this; -} - - template< typename Value, typename Device, typename Index > -String + template< typename T > +ArrayView< Value, Device, Index >& ArrayView< Value, Device, Index >:: -getType() +operator = ( const T& data ) { - return String( "Containers::ArrayView< " ) + ", " + - TNL::getType< Value >() + ", " + - Device::getDeviceType() + ", " + - TNL::getType< Index >() + " >"; + Algorithms::ArrayAssignment< ArrayView, T >::assign( *this, data ); + return *this; } - template< typename Value, typename Device, typename Index > @@ -173,7 +147,6 @@ reset() size = 0; } - template< typename Value, typename Device, typename Index > @@ -196,6 +169,28 @@ getData() return data; } +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +const +Value* ArrayView< Value, Device, Index >:: +getArrayData() const +{ + return data; +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +Value* +ArrayView< Value, Device, Index >:: +getArrayData() +{ + return data; +} + template< typename Value, typename Device, typename Index > @@ -259,27 +254,30 @@ operator[]( Index i ) const template< typename Value, typename Device, typename Index > - template< typename Value_, typename Device_, typename Index_ > + template< typename ArrayT > bool ArrayView< Value, Device, Index >:: -operator==( const ArrayView< Value_, Device_, Index_ >& view ) const +operator==( const ArrayT& array ) const { - if( view.getSize() != getSize() ) + if( array.getSize() != this->getSize() ) return false; - if( getSize() == 0 ) + if( this->getSize() == 0 ) return true; - return Algorithms::ArrayOperations< Device, Device_ >::compareMemory( getData(), view.getData(), getSize() ); + return Algorithms::ArrayOperations< DeviceType, typename ArrayT::DeviceType >:: + compareMemory( this->getData(), + array.getData(), + array.getSize() ); } template< typename Value, typename Device, typename Index > - template< typename Value_, typename Device_, typename Index_ > + template< typename ArrayT > bool ArrayView< Value, Device, Index >:: -operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const +operator!=( const ArrayT& array ) const { - return ! ( *this == view ); + return ! ( *this == array ); } template< typename Value, @@ -293,6 +291,27 @@ setValue( Value value ) Algorithms::ArrayOperations< Device >::setMemory( getData(), value, getSize() ); } +template< typename Value, + typename Device, + typename Index > + template< typename Function > +void ArrayView< Value, Device, Index >:: +evaluate( Function& f, const Index begin, Index end ) +{ + TNL_ASSERT_TRUE( this->getData(), "Attempted to set a value of an empty array view." ); + + ValueType* d = this->data; + auto eval = [=] __cuda_callable__ ( Index i ) + { + d[ i ] = f( i ); + }; + + if( end == -1 ) + end = this->getSize(); + + ParallelFor< DeviceType >::exec( begin, end, eval ); +} + template< typename Value, typename Device, typename Index > @@ -316,12 +335,65 @@ containsOnlyValue( Value value ) const template< typename Value, typename Device, typename Index > +bool ArrayView< Value, Device, Index >:: -operator bool() const +empty() const { - return data; + return ( data == nullptr ); } +template< typename Value, + typename Device, + typename Index > +void ArrayView< Value, Device, Index >::save( File& file ) const +{ + saveHeader( file, SerializationType::getType() ); + file.save( &this->size ); + if( this->size != 0 ) + Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size ); +} + +template< typename Value, + typename Device, + typename Index > +void +ArrayView< Value, Device, Index >:: +load( File& file ) +{ + String type; + loadHeader( file, type ); + if( type != SerializationType::getType() ) + throw Exceptions::ObjectTypeMismatch( SerializationType::getType(), type ); + Index _size; + file.load( &_size ); + if( _size != this->getSize() ) + throw Exceptions::ArrayWrongSize( _size, convertToString( this->getSize() ) ); + Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ); +} + +template< typename Value, + typename Device, + typename Index > +void +ArrayView< Value, Device, Index >:: +save( const String& fileName ) const +{ + File file; + file.open( fileName, File::Mode::Out ); + this->save( file ); +} + +template< typename Value, + typename Device, + typename Index > +void +ArrayView< Value, Device, Index >:: +load( const String& fileName ) +{ + File file; + file.open( fileName, File::Mode::In ); + this->load( file ); +} template< typename Value, typename Device, typename Index > std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Index >& v ) diff --git a/src/TNL/Containers/DistributedArray.h b/src/TNL/Containers/DistributedArray.h index d653fc57170f519887bec2f7a3a12067e690e460..f624100cb6e8b6ad2a3c09d34f871e9994df440c 100644 --- a/src/TNL/Containers/DistributedArray.h +++ b/src/TNL/Containers/DistributedArray.h @@ -15,9 +15,7 @@ #include <type_traits> // std::add_const #include <TNL/Containers/Array.h> -#include <TNL/Containers/ArrayView.h> -#include <TNL/Communicators/MpiCommunicator.h> -#include <TNL/Containers/Subrange.h> +#include <TNL/Containers/DistributedArrayView.h> namespace TNL { namespace Containers { @@ -41,6 +39,8 @@ public: using ConstLocalArrayViewType = Containers::ArrayView< typename std::add_const< Value >::type, Device, Index >; using HostType = DistributedArray< Value, Devices::Host, Index, Communicator >; using CudaType = DistributedArray< Value, Devices::Cuda, Index, Communicator >; + using ViewType = DistributedArrayView< Value, Device, Index, Communicator >; + using ConstViewType = DistributedArrayView< typename std::add_const< Value >::type, Device, Index, Communicator >; DistributedArray() = default; @@ -69,9 +69,28 @@ public: // TODO: no getSerializationType method until there is support for serialization - /* - * Usual Array methods follow below. + // Usual Array methods follow below. + + /** + * \brief Returns a modifiable view of the array. + */ + ViewType getView(); + + /** + * \brief Returns a non-modifiable view of the array. + */ + ConstViewType getConstView() const; + + /** + * \brief Conversion operator to a modifiable view of the array. + */ + operator ViewType(); + + /** + * \brief Conversion operator to a non-modifiable view of the array. */ + operator ConstViewType() const; + template< typename Array > void setLike( const Array& array ); diff --git a/src/TNL/Containers/DistributedArrayView.h b/src/TNL/Containers/DistributedArrayView.h index e9e9e0a487e38cd084d3f6ec80c4ee5c372f095e..6995cf03e494fda563f0e0a386a494a8afc892c3 100644 --- a/src/TNL/Containers/DistributedArrayView.h +++ b/src/TNL/Containers/DistributedArrayView.h @@ -12,7 +12,9 @@ #pragma once -#include <TNL/Containers/DistributedArray.h> +#include <TNL/Containers/ArrayView.h> +#include <TNL/Communicators/MpiCommunicator.h> +#include <TNL/Containers/Subrange.h> namespace TNL { namespace Containers { @@ -34,6 +36,14 @@ public: using ConstLocalArrayViewType = Containers::ArrayView< typename std::add_const< Value >::type, Device, Index >; using HostType = DistributedArrayView< Value, Devices::Host, Index, Communicator >; using CudaType = DistributedArrayView< Value, Devices::Cuda, Index, Communicator >; + using ViewType = DistributedArrayView< Value, Device, Index, Communicator >; + using ConstViewType = DistributedArrayView< typename std::add_const< Value >::type, Device, Index, Communicator >; + + // Initialization by raw data + __cuda_callable__ + DistributedArrayView( const LocalRangeType& localRange, IndexType globalSize, CommunicationGroup group, LocalArrayViewType localData ) + : localRange(localRange), globalSize(globalSize), group(group), localData(localData) + {} __cuda_callable__ DistributedArrayView() = default; @@ -53,15 +63,6 @@ public: __cuda_callable__ DistributedArrayView( DistributedArrayView&& ) = default; - // initialization from distributed array - template< typename Value_ > - DistributedArrayView( DistributedArray< Value_, Device, Index, Communicator >& array ); - - // this constructor will be used only when Value is const-qualified - // (const views are initializable by const references) - template< typename Value_ > - DistributedArrayView( const DistributedArray< Value_, Device, Index, Communicator >& array ); - // method for rebinding (reinitialization) // Note that you can also bind directly to Array and other types implicitly // convertible to ArrayView. @@ -73,6 +74,18 @@ public: template< typename Value_ > void bind( Value_* data, IndexType localSize ); + /** + * \brief Returns a modifiable view of the array view. + */ + __cuda_callable__ + ViewType getView(); + + /** + * \brief Returns a non-modifiable view of the array view. + */ + __cuda_callable__ + ConstViewType getConstView() const; + // Copy-assignment does deep copy, just like regular array, but the sizes // must match (i.e. copy-assignment cannot resize). diff --git a/src/TNL/Containers/DistributedArrayView_impl.h b/src/TNL/Containers/DistributedArrayView_impl.h index 8fa18cbff956866cece9efb2cc78ea36f2b2d6c6..ad4a38b110bf392b788fa19821d8f378843b4148 100644 --- a/src/TNL/Containers/DistributedArrayView_impl.h +++ b/src/TNL/Containers/DistributedArrayView_impl.h @@ -35,55 +35,53 @@ template< typename Value, typename Device, typename Index, typename Communicator > - template< typename Value_ > +__cuda_callable__ +void DistributedArrayView< Value, Device, Index, Communicator >:: -DistributedArrayView( DistributedArray< Value_, Device, Index, Communicator >& array ) -: localRange( array.getLocalRange() ), - globalSize( array.getSize() ), - group( array.getCommunicationGroup() ), - localData( array.getLocalArrayView() ) -{} +bind( DistributedArrayView view ) +{ + localRange = view.getLocalRange(); + globalSize = view.getSize(); + group = view.getCommunicationGroup(); + localData.bind( view.getLocalArrayView() ); +} template< typename Value, typename Device, typename Index, typename Communicator > template< typename Value_ > +void DistributedArrayView< Value, Device, Index, Communicator >:: -DistributedArrayView( const DistributedArray< Value_, Device, Index, Communicator >& array ) -: localRange( array.getLocalRange() ), - globalSize( array.getSize() ), - group( array.getCommunicationGroup() ), - localData( array.getLocalArrayView() ) -{} +bind( Value_* data, IndexType localSize ) +{ + TNL_ASSERT_EQ( localSize, localRange.getSize(), + "The local array size does not match the local range of the distributed array." ); + localData.bind( data, localSize ); +} template< typename Value, typename Device, typename Index, typename Communicator > __cuda_callable__ -void +typename DistributedArrayView< Value, Device, Index, Communicator >::ViewType DistributedArrayView< Value, Device, Index, Communicator >:: -bind( DistributedArrayView view ) +getView() { - localRange = view.getLocalRange(); - globalSize = view.getSize(); - group = view.getCommunicationGroup(); - localData.bind( view.getLocalArrayView() ); + return *this; } template< typename Value, typename Device, typename Index, typename Communicator > - template< typename Value_ > -void +__cuda_callable__ +typename DistributedArrayView< Value, Device, Index, Communicator >::ConstViewType DistributedArrayView< Value, Device, Index, Communicator >:: -bind( Value_* data, IndexType localSize ) +getConstView() const { - TNL_ASSERT_EQ( localSize, localRange.getSize(), - "The local array size does not match the local range of the distributed array." ); - localData.bind( data, localSize ); + return *this; } diff --git a/src/TNL/Containers/DistributedArray_impl.h b/src/TNL/Containers/DistributedArray_impl.h index aab55bd718f480e839c83183fd0fe810c1cfc575..34e8e041b4b0945f708f40e26da8c3f8ea226c20 100644 --- a/src/TNL/Containers/DistributedArray_impl.h +++ b/src/TNL/Containers/DistributedArray_impl.h @@ -76,7 +76,7 @@ typename DistributedArray< Value, Device, Index, Communicator >::LocalArrayViewT DistributedArray< Value, Device, Index, Communicator >:: getLocalArrayView() { - return localData; + return localData.getView(); } template< typename Value, @@ -87,7 +87,7 @@ typename DistributedArray< Value, Device, Index, Communicator >::ConstLocalArray DistributedArray< Value, Device, Index, Communicator >:: getLocalArrayView() const { - return localData; + return localData.getConstView(); } template< typename Value, @@ -117,6 +117,48 @@ copyFromGlobal( ConstLocalArrayViewType globalArray ) * Usual Array methods follow below. */ +template< typename Value, + typename Device, + typename Index, + typename Communicator > +typename DistributedArray< Value, Device, Index, Communicator >::ViewType +DistributedArray< Value, Device, Index, Communicator >:: +getView() +{ + return ViewType( getLocalRange(), getSize(), getCommunicationGroup(), getLocalArrayView() ); +} + +template< typename Value, + typename Device, + typename Index, + typename Communicator > +typename DistributedArray< Value, Device, Index, Communicator >::ConstViewType +DistributedArray< Value, Device, Index, Communicator >:: +getConstView() const +{ + return ConstViewType( getLocalRange(), getSize(), getCommunicationGroup(), getLocalArrayView() ); +} + +template< typename Value, + typename Device, + typename Index, + typename Communicator > +DistributedArray< Value, Device, Index, Communicator >:: +operator ViewType() +{ + return getView(); +} + +template< typename Value, + typename Device, + typename Index, + typename Communicator > +DistributedArray< Value, Device, Index, Communicator >:: +operator ConstViewType() const +{ + return getConstView(); +} + template< typename Value, typename Device, typename Index, diff --git a/src/TNL/Containers/DistributedVector.h b/src/TNL/Containers/DistributedVector.h index 794b99f48d2996af94c52c24d29e20deae1a0e4c..3e110b1270e0609d6b5a140e83cb61dd58ea9829 100644 --- a/src/TNL/Containers/DistributedVector.h +++ b/src/TNL/Containers/DistributedVector.h @@ -12,8 +12,8 @@ #pragma once -#include "DistributedArray.h" -#include <TNL/Containers/VectorView.h> +#include <TNL/Containers/DistributedArray.h> +#include <TNL/Containers/DistributedVectorView.h> namespace TNL { namespace Containers { @@ -36,6 +36,8 @@ public: using ConstLocalVectorViewType = Containers::VectorView< typename std::add_const< Real >::type, Device, Index >; using HostType = DistributedVector< Real, Devices::Host, Index, Communicator >; using CudaType = DistributedVector< Real, Devices::Cuda, Index, Communicator >; + using ViewType = DistributedVectorView< Real, Device, Index, Communicator >; + using ConstViewType = DistributedVectorView< typename std::add_const< Real >::type, Device, Index, Communicator >; // inherit all constructors and assignment operators from Array using BaseType::DistributedArray; @@ -46,6 +48,26 @@ public: ConstLocalVectorViewType getLocalVectorView() const; + /** + * \brief Returns a modifiable view of the vector. + */ + ViewType getView(); + + /** + * \brief Returns a non-modifiable view of the vector. + */ + ConstViewType getConstView() const; + + /** + * \brief Conversion operator to a modifiable view of the vector. + */ + operator ViewType(); + + /** + * \brief Conversion operator to a non-modifiable view of the vector. + */ + operator ConstViewType() const; + static String getType(); diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h index e36e60e00e4990efc986e3ef89c87bfe75720813..7fc3778b4dd162ce789f140315c433523bfcf695 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -37,15 +37,41 @@ public: using ConstLocalVectorViewType = Containers::VectorView< typename std::add_const< Real >::type, Device, Index >; using HostType = DistributedVectorView< Real, Devices::Host, Index, Communicator >; using CudaType = DistributedVectorView< Real, Devices::Cuda, Index, Communicator >; + using ViewType = DistributedVectorView< Real, Device, Index, Communicator >; + using ConstViewType = DistributedVectorView< typename std::add_const< Real >::type, Device, Index, Communicator >; // inherit all constructors and assignment operators from ArrayView using BaseType::DistributedArrayView; using BaseType::operator=; + // In C++14, default constructors cannot be inherited, although Clang + // and GCC since version 7.0 inherit them. + // https://stackoverflow.com/a/51854172 + __cuda_callable__ + DistributedVectorView() = default; + + // initialization by base class is not a copy constructor so it has to be explicit + template< typename Real_ > // template catches both const and non-const qualified Element + __cuda_callable__ + DistributedVectorView( const DistributedArrayView< Real_, Device, Index, Communicator >& view ) + : BaseType::DistributedArrayView( view ) {} + LocalVectorViewType getLocalVectorView(); ConstLocalVectorViewType getLocalVectorView() const; + /** + * \brief Returns a modifiable view of the array view. + */ + __cuda_callable__ + ViewType getView(); + + /** + * \brief Returns a non-modifiable view of the array view. + */ + __cuda_callable__ + ConstViewType getConstView() const; + static String getType(); diff --git a/src/TNL/Containers/DistributedVectorView_impl.h b/src/TNL/Containers/DistributedVectorView_impl.h index cd1fd1619bd1c167a32fb722f5eee37286ed5bd4..0639b2f8e1a68105b48bbca43def645d622f1580 100644 --- a/src/TNL/Containers/DistributedVectorView_impl.h +++ b/src/TNL/Containers/DistributedVectorView_impl.h @@ -42,6 +42,30 @@ getLocalVectorView() const return this->getLocalArrayView(); } +template< typename Value, + typename Device, + typename Index, + typename Communicator > +__cuda_callable__ +typename DistributedVectorView< Value, Device, Index, Communicator >::ViewType +DistributedVectorView< Value, Device, Index, Communicator >:: +getView() +{ + return *this; +} + +template< typename Value, + typename Device, + typename Index, + typename Communicator > +__cuda_callable__ +typename DistributedVectorView< Value, Device, Index, Communicator >::ConstViewType +DistributedVectorView< Value, Device, Index, Communicator >:: +getConstView() const +{ + return *this; +} + template< typename Real, typename Device, diff --git a/src/TNL/Containers/DistributedVector_impl.h b/src/TNL/Containers/DistributedVector_impl.h index a44baa9363c21508534941d5e7b90fc00fc7f853..239239ead7f2b5b5f4b066a11d81648f389a77ae 100644 --- a/src/TNL/Containers/DistributedVector_impl.h +++ b/src/TNL/Containers/DistributedVector_impl.h @@ -42,6 +42,48 @@ getLocalVectorView() const return this->getLocalArrayView(); } +template< typename Value, + typename Device, + typename Index, + typename Communicator > +typename DistributedVector< Value, Device, Index, Communicator >::ViewType +DistributedVector< Value, Device, Index, Communicator >:: +getView() +{ + return ViewType( this->getLocalRange(), this->getSize(), this->getCommunicationGroup(), this->getLocalVectorView() ); +} + +template< typename Value, + typename Device, + typename Index, + typename Communicator > +typename DistributedVector< Value, Device, Index, Communicator >::ConstViewType +DistributedVector< Value, Device, Index, Communicator >:: +getConstView() const +{ + return ConstViewType( this->getLocalRange(), this->getSize(), this->getCommunicationGroup(), this->getLocalVectorView() ); +} + +template< typename Value, + typename Device, + typename Index, + typename Communicator > +DistributedVector< Value, Device, Index, Communicator >:: +operator ViewType() +{ + return getView(); +} + +template< typename Value, + typename Device, + typename Index, + typename Communicator > +DistributedVector< Value, Device, Index, Communicator >:: +operator ConstViewType() const +{ + return getConstView(); +} + template< typename Real, typename Device, diff --git a/src/TNL/Containers/List_impl.h b/src/TNL/Containers/List_impl.h index 36fd5dbdc2c928d2feb07bf505eb5c441ab85101..a8bcb81158ad187b3a3573e2a4c34c758f64640f 100644 --- a/src/TNL/Containers/List_impl.h +++ b/src/TNL/Containers/List_impl.h @@ -282,9 +282,9 @@ void List< T >::DeepEraseAll() template< typename T > bool List< T >::Save( File& file ) const { - file.write( &size ); + file.save( &size ); for( int i = 0; i < size; i ++ ) - if( ! file. write( &operator[]( i ), 1 ) ) + if( ! file. save( &operator[]( i ), 1 ) ) return false; return true; } @@ -292,7 +292,7 @@ bool List< T >::Save( File& file ) const template< typename T > bool List< T >::DeepSave( File& file ) const { - file. write( &size ); + file.save( &size ); for( int i = 0; i < size; i ++ ) if( ! operator[]( i ). save( file ) ) return false; return true; @@ -303,7 +303,7 @@ bool List< T >::Load( File& file ) { reset(); int _size; - file. read( &_size, 1 ); + file.load( &_size, 1 ); if( _size < 0 ) { std::cerr << "The curve size is negative." << std::endl; @@ -312,7 +312,7 @@ bool List< T >::Load( File& file ) T t; for( int i = 0; i < _size; i ++ ) { - if( ! file. read( &t, 1 ) ) + if( ! file.load( &t, 1 ) ) return false; Append( t ); } @@ -324,7 +324,7 @@ bool List< T >::DeepLoad( File& file ) { reset(); int _size; - file. read( &_size ); + file.load( &_size ); if( _size < 0 ) { std::cerr << "The list size is negative." << std::endl; diff --git a/src/TNL/Containers/MultiArray.h b/src/TNL/Containers/MultiArray.h deleted file mode 100644 index cdcda634bcf768759c44f486790a3511445392d4..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiArray.h +++ /dev/null @@ -1,371 +0,0 @@ -/*************************************************************************** - MultiArray.h - description - ------------------- - begin : Nov 25, 2010 - copyright : (C) 2010 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -#include <iostream> -#include <TNL/Containers/Array.h> -#include <TNL/Containers/StaticVector.h> -#include <TNL/Assert.h> - -namespace TNL { -namespace Containers { - -template< int Dimension, typename Value = double, typename Device = Devices::Host, typename Index = int > -class MultiArray : public Array< Value, Device, Index > -{ -}; - -template< typename Value, typename Device, typename Index > -class MultiArray< 1, Value, Device, Index > : public Array< Value, Device, Index > -{ - public: - enum { Dimension = 1}; - typedef Value ValueType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiArray< 1, Value, Devices::Host, Index > HostType; - typedef MultiArray< 1, Value, Devices::Cuda, Index > CudaType; - - - MultiArray(); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index iSize ); - - void setDimensions( const Containers::StaticVector< 1, Index >& dimensions ); - - __cuda_callable__ void getDimensions( Index& iSize ) const; - - __cuda_callable__ const Containers::StaticVector< 1, Index >& getDimensions() const; - - //! Set dimensions of the array using another array as a template - template< typename MultiArray > - void setLike( const MultiArray& v ); - - void reset(); - - __cuda_callable__ Index getElementIndex( const Index i ) const; - - void setElement( const Index i, Value value ); - - //! This method can be used for general access to the elements of the arrays. - /*! It does not return reference but value. So it can be used to access - * arrays in different address space (usually GPU device). - * See also operator(). - */ - Value getElement( const Index i ) const; - - //! Operator for accessing elements of the array. - __cuda_callable__ Value& operator()( const Index i ); - - __cuda_callable__ const Value& operator()( const Index i ) const; - - - template< typename MultiArrayT > - bool operator == ( const MultiArrayT& array ) const; - - template< typename MultiArrayT > - bool operator != ( const MultiArrayT& array ) const; - - MultiArray< 1, Value, Device, Index >& operator = ( const MultiArray< 1, Value, Device, Index >& array ); - - template< typename MultiArrayT > - MultiArray< 1, Value, Device, Index >& operator = ( const MultiArrayT& array ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - Containers::StaticVector< 1, Index > dimensions; -}; - -template< typename Value, typename Device, typename Index > -class MultiArray< 2, Value, Device, Index > : public Array< Value, Device, Index > -{ - public: - enum { Dimension = 2 }; - typedef Value ValueType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiArray< 2, Value, Devices::Host, Index > HostType; - typedef MultiArray< 2, Value, Devices::Cuda, Index > CudaType; - - - MultiArray(); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index jSize, const Index iSize ); - - void setDimensions( const Containers::StaticVector< 2, Index >& dimensions ); - - __cuda_callable__ void getDimensions( Index& jSize, Index& iSize ) const; - - __cuda_callable__ const Containers::StaticVector< 2, Index >& getDimensions() const; - - //! Set dimensions of the array using another array as a template - template< typename MultiArray > - void setLike( const MultiArray& v ); - - void reset(); - - __cuda_callable__ Index getElementIndex( const Index j, const Index i ) const; - - void setElement( const Index j, const Index i, Value value ); - - //! This method can be used for general access to the elements of the arrays. - /*! It does not return reference but value. So it can be used to access - * arrays in different adress space (usualy GPU device). - * See also operator(). - */ - Value getElement( const Index j, const Index i ) const; - - //! Operator for accessing elements of the array. - /*! It returns reference to given elements so it cannot be - * used to access elements of arrays in different address space - * (GPU device usually). - */ - __cuda_callable__ Value& operator()( const Index j, const Index i ); - - __cuda_callable__ const Value& operator()( const Index j, const Index i ) const; - - template< typename MultiArrayT > - bool operator == ( const MultiArrayT& array ) const; - - template< typename MultiArrayT > - bool operator != ( const MultiArrayT& array ) const; - - MultiArray< 2, Value, Device, Index >& operator = ( const MultiArray< 2, Value, Device, Index >& array ); - - template< typename MultiArrayT > - MultiArray< 2, Value, Device, Index >& operator = ( const MultiArrayT& array ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - Containers::StaticVector< 2, Index > dimensions; -}; - -template< typename Value, typename Device, typename Index > -class MultiArray< 3, Value, Device, Index > : public Array< Value, Device, Index > -{ - public: - - enum { Dimension = 3 }; - typedef Value ValueType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiArray< 3, Value, Devices::Host, Index > HostType; - typedef MultiArray< 3, Value, Devices::Cuda, Index > CudaType; - - - MultiArray(); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index k, const Index j, const Index iSize ); - - void setDimensions( const Containers::StaticVector< 3, Index >& dimensions ); - - __cuda_callable__ void getDimensions( Index& k, Index& j, Index& iSize ) const; - - __cuda_callable__ const Containers::StaticVector< 3, Index >& getDimensions() const; - - //! Set dimensions of the array using another array as a template - template< typename MultiArrayT > - void setLike( const MultiArrayT& v ); - - void reset(); - - __cuda_callable__ Index getElementIndex( const Index k, const Index j, const Index i ) const; - - void setElement( const Index k, const Index j, const Index i, Value value ); - - //! This method can be used for general access to the elements of the arrays. - /*! It does not return reference but value. So it can be used to access - * arrays in different adress space (usualy GPU device). - * See also operator(). - */ - Value getElement( const Index k, const Index j, const Index i ) const; - - //! Operator for accessing elements of the array. - /*! It returns reference to given elements so it cannot be - * used to access elements of arrays in different adress space - * (GPU device usualy). - */ - __cuda_callable__ Value& operator()( const Index k, const Index j, const Index i ); - - __cuda_callable__ const Value& operator()( const Index k, const Index j, const Index i ) const; - - template< typename MultiArrayT > - bool operator == ( const MultiArrayT& array ) const; - - template< typename MultiArrayT > - bool operator != ( const MultiArrayT& array ) const; - - MultiArray< 3, Value, Device, Index >& operator = ( const MultiArray< 3, Value, Device, Index >& array ); - - template< typename MultiArrayT > - MultiArray< 3, Value, Device, Index >& operator = ( const MultiArrayT& array ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - Containers::StaticVector< 3, Index > dimensions; -}; - -template< typename Value, typename Device, typename Index > -class MultiArray< 4, Value, Device, Index > : public Array< Value, Device, Index > -{ - public: - - enum { Dimension = 4 }; - typedef Value ValueType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiArray< 4, Value, Devices::Host, Index > HostType; - typedef MultiArray< 4, Value, Devices::Cuda, Index > CudaType; - - - MultiArray(); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index l, const Index k, const Index j, const Index iSize ); - - void setDimensions( const Containers::StaticVector< 4, Index >& dimensions ); - - __cuda_callable__ void getDimensions( Index& l, Index& k, Index& j, Index& iSize ) const; - - __cuda_callable__ const Containers::StaticVector< 4, Index >& getDimensions() const; - - //! Set dimensions of the array using another array as a template - template< typename MultiArrayT > - void setLike( const MultiArrayT& v ); - - void reset(); - - __cuda_callable__ Index getElementIndex( const Index l, const Index k, const Index j, const Index i ) const; - - void setElement( const Index l, const Index k, const Index j, const Index i, Value value ); - - //! This method can be used for general access to the elements of the arrays. - /*! It does not return reference but value. So it can be used to access - * arrays in different adress space (usualy GPU device). - * See also operator(). - */ - Value getElement( const Index l, const Index k, const Index j, const Index i ) const; - - //! Operator for accessing elements of the array. - /*! It returns reference to given elements so it cannot be - * used to access elements of arrays in different adress space - * (GPU device usualy). - */ - __cuda_callable__ Value& operator()( const Index l, const Index k, const Index j, const Index i ); - - __cuda_callable__ const Value& operator()( const Index l, const Index k, const Index j, const Index i ) const; - - template< typename MultiArrayT > - bool operator == ( const MultiArrayT& array ) const; - - template< typename MultiArrayT > - bool operator != ( const MultiArrayT& array ) const; - - MultiArray< 4, Value, Device, Index >& operator = ( const MultiArray< 4, Value, Device, Index >& array ); - - template< typename MultiArrayT > - MultiArray< 4, Value, Device, Index >& operator = ( const MultiArrayT& array ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - Containers::StaticVector< 4, Index > dimensions; -}; - -template< typename Value, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 1, Value, device, Index >& array ); - -template< typename Value, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 2, Value, device, Index >& array ); - -template< typename Value, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 3, Value, device, Index >& array ); - -template< typename Value, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 4, Value, device, Index >& array ); - -} // namespace Containers -} // namespace TNL - -#include <TNL/Containers/MultiArray1D_impl.h> -#include <TNL/Containers/MultiArray2D_impl.h> -#include <TNL/Containers/MultiArray3D_impl.h> -#include <TNL/Containers/MultiArray4D_impl.h> diff --git a/src/TNL/Containers/MultiArray1D_impl.h b/src/TNL/Containers/MultiArray1D_impl.h deleted file mode 100644 index 6c8f0b29ceefb37ea4bb237d0a920295603125c0..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiArray1D_impl.h +++ /dev/null @@ -1,241 +0,0 @@ -/*************************************************************************** - MultiArray1D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - -template< typename Value, typename Device, typename Index > -MultiArray< 1, Value, Device, Index > :: MultiArray() -{ -} - -template< typename Value, typename Device, typename Index > -String MultiArray< 1, Value, Device, Index > :: getType() -{ - return String( "Containers::MultiArray< ") + - String( Dimension ) + - String( ", " ) + - String( TNL::getType< Value >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 1, Value, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 1, Value, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 1, Value, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Value, typename Device, typename Index > -void MultiArray< 1, Value, Device, Index > :: setDimensions( const Index iSize ) -{ - TNL_ASSERT( iSize > 0, - std::cerr << "iSize = " << iSize ); - dimensions[ 0 ] = iSize; - Array< Value, Device, Index >::setSize( iSize ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 1, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 1, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0, - std::cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] ); - this->dimensions = dimensions; - Array< Value, Device, Index >::setSize( this->dimensions[ 0 ] ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -void MultiArray< 1, Value, Device, Index > :: setLike( const MultiArrayT& multiArray ) -{ - setDimensions( multiArray. getDimensions() ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 1, Value, Device, Index >::reset() -{ - this->dimensions = Containers::StaticVector< 1, Index >( ( Index ) 0 ); - Array< Value, Device, Index >::reset(); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -void MultiArray< 1, Value, Device, Index > :: getDimensions( Index& xSize ) const -{ - xSize = this->dimensions[ 0 ]; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Containers::StaticVector< 1, Index >& MultiArray< 1, Value, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Index MultiArray< 1, Value, Device, Index > :: getElementIndex( const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ], - std::cerr << "i = " << i << " this->dimensions[ 0 ] = " << this->dimensions[ 0 ] ); - return i; -} - -template< typename Value, typename Device, typename Index > -Value MultiArray< 1, Value, Device, Index > :: getElement( const Index i ) const -{ - return Array< Value, Device, Index > :: getElement( getElementIndex( i ) ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 1, Value, Device, Index > :: setElement( const Index i, Value value ) -{ - Array< Value, Device, Index > :: setElement( getElementIndex( i ), value ); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Value& MultiArray< 1, Value, Device, Index > :: operator()( const Index element ) -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( element ) ); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Value& MultiArray< 1, Value, Device, Index > :: operator()( const Index element ) const -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( element ) ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 1, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - return Array< Value, Device, Index > :: operator == ( array ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 1, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const -{ - return ! ( (* this ) == array ); -} - -template< typename Value, typename Device, typename Index > -MultiArray< 1, Value, Device, Index >& - MultiArray< 1, Value, Device, Index > :: operator = ( const MultiArray< 1, Value, Device, Index >& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -MultiArray< 1, Value, Device, Index >& - MultiArray< 1, Value, Device, Index > :: operator = ( const MultiArrayT& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 1, Value, Device, Index > :: save( File& file ) const -{ - if( ! Array< Value, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 1, Value, Device, Index > :: load( File& file ) -{ - if( ! Array< Value, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 1, Value, Device, Index > :: save( const String& fileName ) const -{ - return Object :: save( fileName ); -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 1, Value, Device, Index > :: load( const String& fileName ) -{ - return Object :: load( fileName ); -} - -template< typename Value, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 1, Value, Device, Index >& array ) -{ - for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ ) - { - str << array. getElement( i ) << " "; - } - return str; -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/MultiArray2D_impl.h b/src/TNL/Containers/MultiArray2D_impl.h deleted file mode 100644 index 44d860167968df549a63ed089cad38f9c0919881..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiArray2D_impl.h +++ /dev/null @@ -1,255 +0,0 @@ -/*************************************************************************** - MultiArray2D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - -template< typename Value, typename Device, typename Index > -MultiArray< 2, Value, Device, Index > :: MultiArray() -{ -} - -template< typename Value, typename Device, typename Index > -String MultiArray< 2, Value, Device, Index > :: getType() -{ - return String( "Containers::MultiArray< ") + - String( Dimension ) + - String( ", " ) + - String( TNL::getType< Value >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 2, Value, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 2, Value, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 2, Value, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Value, typename Device, typename Index > -void MultiArray< 2, Value, Device, Index > :: setDimensions( const Index jSize, - const Index iSize ) -{ - TNL_ASSERT( iSize > 0 && jSize > 0, - std::cerr << "iSize = " << iSize - << "jSize = " << jSize ); - - dimensions[ 0 ] = iSize; - dimensions[ 1 ] = jSize; - Array< Value, Device, Index > :: setSize( iSize * jSize ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 2, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 2, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0, - std::cerr << "dimensions = " << dimensions ); - /**** - * Swap the dimensions in the tuple to be compatible with the previous method. - */ - this->dimensions. x() = dimensions. y(); - this->dimensions. y() = dimensions. x(); - Array< Value, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -void MultiArray< 2, Value, Device, Index > :: setLike( const MultiArrayT& multiArray ) -{ - setDimensions( multiArray. getDimensions() ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 2, Value, Device, Index >::reset() -{ - this->dimensions = Containers::StaticVector< 2, Index >( ( Index ) 0 ); - Array< Value, Device, Index >::reset(); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -void MultiArray< 2, Value, Device, Index > :: getDimensions( Index& jSize, Index& iSize ) const -{ - iSize = this->dimensions[ 0 ]; - jSize = this->dimensions[ 1 ]; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Containers::StaticVector< 2, Index >& MultiArray< 2, Value, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Index MultiArray< 2, Value, Device, Index > :: getElementIndex( const Index j, const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ], - std::cerr << "i = " << i << " j = " << j << " this->dimensions[ 0 ] = " << this->dimensions[ 0 ] - << " this->dimensions[ 1 ] = " << this->dimensions[ 1 ] ); - return j * this->dimensions[ 0 ] + i; -} - -template< typename Value, typename Device, typename Index > -Value MultiArray< 2, Value, Device, Index > :: getElement( const Index j, const Index i ) const -{ - return Array< Value, Device, Index > :: getElement( getElementIndex( j, i ) ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 2, Value, Device, Index > :: setElement( const Index j, const Index i, Value value ) -{ - Array< Value, Device, Index > :: setElement( getElementIndex( j, i ), value ); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Value& MultiArray< 2, Value, Device, Index > :: operator()( const Index j, const Index i ) -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( j, i ) ); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Value& MultiArray< 2, Value, Device, Index > :: operator()( const Index j, const Index i ) const -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( j, i ) ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 2, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - return Array< Value, Device, Index > :: operator == ( array ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 2, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const -{ - return ! ( (* this ) == array ); -} - -template< typename Value, typename Device, typename Index > -MultiArray< 2, Value, Device, Index >& - MultiArray< 2, Value, Device, Index > :: operator = ( const MultiArray< 2, Value, Device, Index >& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -MultiArray< 2, Value, Device, Index >& - MultiArray< 2, Value, Device, Index > :: operator = ( const MultiArrayT& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 2, Value, Device, Index > :: save( File& file ) const -{ - if( ! Array< Value, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 2, Value, Device, Index > :: load( File& file ) -{ - if( ! Array< Value, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 2, Value, Device, Index > :: save( const String& fileName ) const -{ - return Object :: save( fileName ); -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 2, Value, Device, Index > :: load( const String& fileName ) -{ - return Object :: load( fileName ); -} - -template< typename Value, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 2, Value, Device, Index >& array ) -{ - for( Index j = 0; j < array. getDimensions()[ 1 ]; j ++ ) - { - for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ ) - { - str << array. getElement( j, i ) << " "; - } - str << std::endl; - } - return str; -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/MultiArray3D_impl.h b/src/TNL/Containers/MultiArray3D_impl.h deleted file mode 100644 index 9dc3c031795b2e4c5b68fa093512f81911d1abc2..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiArray3D_impl.h +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************** - MultiArray3D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - -template< typename Value, typename Device, typename Index > -MultiArray< 3, Value, Device, Index > :: MultiArray() -{ -} - -template< typename Value, typename Device, typename Index > -String MultiArray< 3, Value, Device, Index > :: getType() -{ - return String( "Containers::MultiArray< ") + - String( Dimension ) + - String( ", " ) + - String( TNL::getType< Value >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 3, Value, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 3, Value, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 3, Value, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Value, typename Device, typename Index > -void MultiArray< 3, Value, Device, Index > :: setDimensions( const Index kSize, - const Index jSize, - const Index iSize ) -{ - TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0, - std::cerr << "iSize = " << iSize - << "jSize = " << jSize - << "kSize = " << kSize ); - - dimensions[ 0 ] = iSize; - dimensions[ 1 ] = jSize; - dimensions[ 2 ] = kSize; - Array< Value, Device, Index > :: setSize( iSize * jSize * kSize ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 3, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 3, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ], - std::cerr << "dimensions = " << dimensions ); - /**** - * Swap the dimensions in the tuple to be compatible with the previous method. - */ - this->dimensions. x() = dimensions. z(); - this->dimensions. y() = dimensions. y(); - this->dimensions. z() = dimensions. x(); - Array< Value, Device, Index > :: setSize( this->dimensions[ 2 ] * - this->dimensions[ 1 ] * - this->dimensions[ 0 ] ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -void MultiArray< 3, Value, Device, Index > :: setLike( const MultiArrayT& multiArray ) -{ - setDimensions( multiArray. getDimensions() ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 3, Value, Device, Index >::reset() -{ - this->dimensions = Containers::StaticVector< 3, Index >( ( Index ) 0 ); - Array< Value, Device, Index >::reset(); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -void MultiArray< 3, Value, Device, Index > :: getDimensions( Index& kSize, - Index& jSize, - Index& iSize ) const -{ - iSize = this->dimensions[ 0 ]; - jSize = this->dimensions[ 1 ]; - kSize = this->dimensions[ 2 ]; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Containers::StaticVector< 3, Index >& MultiArray< 3, Value, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Index MultiArray< 3, Value, Device, Index > :: getElementIndex( const Index k, - const Index j, - const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && - j >= 0 && j < this->dimensions[ 1 ] && - k >= 0 && k < this->dimensions[ 2 ], - std::cerr << " i = " << i - << " j = " << j - << " k = " << k - << " this->dimensions = " << this->dimensions ); - return ( k * this->dimensions[ 1 ] + j ) * this->dimensions[ 0 ] + i; -} - -template< typename Value, typename Device, typename Index > -Value MultiArray< 3, Value, Device, Index > :: getElement( const Index k, - const Index j, - const Index i ) const -{ - return Array< Value, Device, Index > :: getElement( getElementIndex( k, j, i ) ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 3, Value, Device, Index > :: setElement( const Index k, - const Index j, - const Index i, Value value ) -{ - Array< Value, Device, Index > :: setElement( getElementIndex( k, j, i ), value ); -} - - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Value& MultiArray< 3, Value, Device, Index > :: operator()( const Index k, - const Index j, - const Index i ) -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( k, j, i ) ); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Value& MultiArray< 3, Value, Device, Index > :: operator()( const Index k, - const Index j, - const Index i ) const -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( k, j, i ) ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 3, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - return Array< Value, Device, Index > :: operator == ( array ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 3, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const -{ - return ! ( (* this ) == array ); -} - -template< typename Value, typename Device, typename Index > -MultiArray< 3, Value, Device, Index >& - MultiArray< 3, Value, Device, Index > :: operator = ( const MultiArray< 3, Value, Device, Index >& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -MultiArray< 3, Value, Device, Index >& - MultiArray< 3, Value, Device, Index > :: operator = ( const MultiArrayT& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 3, Value, Device, Index > :: save( File& file ) const -{ - if( ! Array< Value, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 3, Value, Device, Index > :: load( File& file ) -{ - if( ! Array< Value, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 3, Value, Device, Index >& array ) -{ - for( Index k = 0; k < array. getDimensions()[ 2 ]; k ++ ) - { - for( Index j = 0; j < array. getDimensions()[ 1 ]; j ++ ) - { - for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ ) - { - str << array. getElement( k, j, i ) << " "; - } - str << std::endl; - } - str << std::endl; - } - return str; -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/MultiArray4D_impl.h b/src/TNL/Containers/MultiArray4D_impl.h deleted file mode 100644 index 2b35c1caaf5180645ca1999f69b08a6458cfe4c3..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiArray4D_impl.h +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************** - MultiArray4D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - - -template< typename Value, typename Device, typename Index > -MultiArray< 4, Value, Device, Index > :: MultiArray() -{ -} - -template< typename Value, typename Device, typename Index > -String MultiArray< 4, Value, Device, Index > :: getType() -{ - return String( "Containers::MultiArray< ") + - String( Dimension ) + - String( ", " ) + - String( TNL::getType< Value >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 4, Value, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 4, Value, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Value, - typename Device, - typename Index > -String MultiArray< 4, Value, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Value, typename Device, typename Index > -void MultiArray< 4, Value, Device, Index > :: setDimensions( const Index lSize, - const Index kSize, - const Index jSize, - const Index iSize ) -{ - TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0, - std::cerr << "iSize = " << iSize - << "jSize = " << jSize - << "kSize = " << kSize - << "lSize = " << lSize ); - - dimensions[ 0 ] = iSize; - dimensions[ 1 ] = jSize; - dimensions[ 2 ] = kSize; - dimensions[ 3 ] = lSize; - Array< Value, Device, Index > :: setSize( iSize * jSize * kSize * lSize ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 4, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 4, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0, - std::cerr << "dimensions = " << dimensions ); - /**** - * Swap the dimensions in the tuple to be compatible with the previous method. - */ - this->dimensions[ 0 ] = dimensions[ 3 ]; - this->dimensions[ 1 ] = dimensions[ 2 ]; - this->dimensions[ 2 ] = dimensions[ 1 ]; - this->dimensions[ 3 ] = dimensions[ 0 ]; - Array< Value, Device, Index > :: setSize( this->dimensions[ 3 ] * - this->dimensions[ 2 ] * - this->dimensions[ 1 ] * - this->dimensions[ 0 ] ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -void MultiArray< 4, Value, Device, Index > :: setLike( const MultiArrayT& multiArray ) -{ - setDimensions( multiArray. getDimensions() ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 4, Value, Device, Index >::reset() -{ - this->dimensions = Containers::StaticVector< 4, Index >( ( Index ) 0 ); - Array< Value, Device, Index >::reset(); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -void MultiArray< 4, Value, Device, Index > :: getDimensions( Index& lSize, - Index& kSize, - Index& jSize, - Index& iSize ) const -{ - iSize = this->dimensions[ 0 ]; - jSize = this->dimensions[ 1 ]; - kSize = this->dimensions[ 2 ]; - lSize = this->dimensions[ 3 ]; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Containers::StaticVector< 4, Index >& MultiArray< 4, Value, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Index MultiArray< 4, Value, Device, Index > :: getElementIndex( const Index l, - const Index k, - const Index j, - const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && - j >= 0 && j < this->dimensions[ 1 ] && - k >= 0 && k < this->dimensions[ 2 ] && - l >= 0 && l < this->dimensions[ 3 ], - std::cerr << " i = " << i - << " j = " << j - << " k = " << k - << " l = " << l - << " this->dimensions = " << this->dimensions ); - return ( ( l * this->dimensions[ 2 ] + k ) * this->dimensions[ 1 ] + j ) * this->dimensions[ 0 ] + i; -} - -template< typename Value, typename Device, typename Index > -Value MultiArray< 4, Value, Device, Index > :: getElement( const Index l, - const Index k, - const Index j, - const Index i ) const -{ - return Array< Value, Device, Index > :: getElement( getElementIndex( l, k, j, i ) ); -} - -template< typename Value, typename Device, typename Index > -void MultiArray< 4, Value, Device, Index > :: setElement( const Index l, - const Index k, - const Index j, - const Index i, Value value ) -{ - Array< Value, Device, Index > :: setElement( getElementIndex( l, k, j, i ), value ); -} - - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -Value& MultiArray< 4, Value, Device, Index > :: operator()( const Index l, - const Index k, - const Index j, - const Index i ) -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) ); -} - -template< typename Value, typename Device, typename Index > -__cuda_callable__ -const Value& MultiArray< 4, Value, Device, Index > :: operator()( const Index l, - const Index k, - const Index j, - const Index i ) const -{ - return Array< Value, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 4, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - return Array< Value, Device, Index > :: operator == ( array ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -bool MultiArray< 4, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const -{ - return ! ( (* this ) == array ); -} - -template< typename Value, typename Device, typename Index > -MultiArray< 4, Value, Device, Index >& - MultiArray< 4, Value, Device, Index > :: operator = ( const MultiArray< 4, Value, Device, Index >& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > - template< typename MultiArrayT > -MultiArray< 4, Value, Device, Index >& - MultiArray< 4, Value, Device, Index > :: operator = ( const MultiArrayT& array ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == array. getDimensions(), - std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl - << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; ); - Array< Value, Device, Index > :: operator = ( array ); - return ( *this ); -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 4, Value, Device, Index > :: save( File& file ) const -{ - if( ! Array< Value, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -bool MultiArray< 4, Value, Device, Index > :: load( File& file ) -{ - if( ! Array< Value, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Array of MultiArray." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl; - return false; - } - return true; -} - -template< typename Value, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiArray< 4, Value, Device, Index >& array ) -{ - for( Index l = 0; l < array. getDimensions()[ 3 ]; l ++ ) - { - for( Index k = 0; k < array. getDimensions()[ 2 ]; k ++ ) - { - for( Index j = 0; j < array. getDimensions()[ 1 ]; j ++ ) - { - for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ ) - { - str << array. getElement( l, k, j, i ) << " "; - } - str << std::endl; - } - str << std::endl; - } - str << std::endl; - } - return str; -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/MultiVector.h b/src/TNL/Containers/MultiVector.h deleted file mode 100644 index aa30db976ac35087ae1648c898695fb208e5abbc..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiVector.h +++ /dev/null @@ -1,369 +0,0 @@ -/*************************************************************************** - MultiVector.h - description - ------------------- - begin : Nov 25, 2010 - copyright : (C) 2010 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/StaticVector.h> -#include <TNL/Assert.h> - -namespace TNL { -namespace Containers { - -template< int Dimension, typename Real = double, typename Device = Devices::Host, typename Index = int > -class MultiVector : public Vector< Real, Device, Index > -{ -}; - -template< typename Real, typename Device, typename Index > -class MultiVector< 1, Real, Device, Index > : public Vector< Real, Device, Index > -{ - public: - enum { Dimension = 1}; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType; - typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType; - - MultiVector(); - - MultiVector( const String& name ); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index iSize ); - - void setDimensions( const StaticVector< Dimension, Index >& dimensions ); - - void getDimensions( Index& iSize ) const; - - const StaticVector< 1, Index >& getDimensions() const; - - //! Set dimensions of the Vector using another Vector as a template - template< typename MultiVector > - void setLike( const MultiVector& v ); - - Index getElementIndex( const Index i ) const; - - void setElement( const Index i, Real value ); - - //! This method can be used for general access to the elements of the Vectors. - /*! It does not return reference but value. So it can be used to access - * Vectors in different adress space (usualy GPU device). - * See also operator(). - */ - Real getElement( const Index i ) const; - - //! Operator for accessing elements of the Vector. - /*! It returns reference to given elements so it cannot be - * used to access elements of Vectors in different adress space - * (GPU device usualy). - */ - Real& operator()( const Index i ); - - const Real& operator()( const Index i ) const; - - template< typename MultiVector > - bool operator == ( const MultiVector& Vector ) const; - - template< typename MultiVector > - bool operator != ( const MultiVector& Vector ) const; - - MultiVector< 1, Real, Device, Index >& operator = ( const MultiVector< 1, Real, Device, Index >& Vector ); - - template< typename MultiVectorT > - MultiVector< 1, Real, Device, Index >& operator = ( const MultiVectorT& Vector ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - StaticVector< Dimension, Index > dimensions; -}; - -template< typename Real, typename Device, typename Index > -class MultiVector< 2, Real, Device, Index > : public Vector< Real, Device, Index > -{ - public: - enum { Dimension = 2 }; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType; - typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType; - - MultiVector(); - - MultiVector( const String& name ); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index jSize, const Index iSize ); - - void setDimensions( const StaticVector< 2, Index >& dimensions ); - - void getDimensions( Index& jSize, Index& iSize ) const; - - const StaticVector< 2, Index >& getDimensions() const; - - //! Set dimensions of the Vector using another Vector as a template - template< typename MultiVector > - void setLike( const MultiVector& v ); - - Index getElementIndex( const Index j, const Index i ) const; - - void setElement( const Index j, const Index i, Real value ); - - //! This method can be used for general access to the elements of the Vectors. - /*! It does not return reference but value. So it can be used to access - * Vectors in different adress space (usualy GPU device). - * See also operator(). - */ - Real getElement( const Index j, const Index i ) const; - - //! Operator for accessing elements of the Vector. - /*! It returns reference to given elements so it cannot be - * used to access elements of Vectors in different adress space - * (GPU device usualy). - */ - Real& operator()( const Index j, const Index i ); - - const Real& operator()( const Index j, const Index i ) const; - - template< typename MultiVector > - bool operator == ( const MultiVector& Vector ) const; - - template< typename MultiVector > - bool operator != ( const MultiVector& Vector ) const; - - MultiVector< 2, Real, Device, Index >& operator = ( const MultiVector< 2, Real, Device, Index >& Vector ); - - template< typename MultiVectorT > - MultiVector< 2, Real, Device, Index >& operator = ( const MultiVectorT& Vector ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - StaticVector< 2, Index > dimensions; -}; - -template< typename Real, typename Device, typename Index > -class MultiVector< 3, Real, Device, Index > : public Vector< Real, Device, Index > -{ - public: - - enum { Dimension = 3 }; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType; - typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType; - - MultiVector(); - - MultiVector( const String& name ); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index k, const Index j, const Index iSize ); - - void setDimensions( const StaticVector< 3, Index >& dimensions ); - - void getDimensions( Index& k, Index& j, Index& iSize ) const; - - const StaticVector< 3, Index >& getDimensions() const; - - //! Set dimensions of the Vector using another Vector as a template - template< typename MultiVector > - void setLike( const MultiVector& v ); - - Index getElementIndex( const Index k, const Index j, const Index i ) const; - - void setElement( const Index k, const Index j, const Index i, Real value ); - - //! This method can be used for general access to the elements of the Vectors. - /*! It does not return reference but value. So it can be used to access - * Vectors in different adress space (usualy GPU device). - * See also operator(). - */ - Real getElement( const Index k, const Index j, const Index i ) const; - - //! Operator for accessing elements of the Vector. - /*! It returns reference to given elements so it cannot be - * used to access elements of Vectors in different adress space - * (GPU device usualy). - */ - Real& operator()( const Index k, const Index j, const Index i ); - - const Real& operator()( const Index k, const Index j, const Index i ) const; - - template< typename MultiVector > - bool operator == ( const MultiVector& Vector ) const; - - template< typename MultiVector > - bool operator != ( const MultiVector& Vector ) const; - - MultiVector< 3, Real, Device, Index >& operator = ( const MultiVector< 3, Real, Device, Index >& Vector ); - - template< typename MultiVectorT > - MultiVector< 3, Real, Device, Index >& operator = ( const MultiVectorT& Vector ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - StaticVector< 3, Index > dimensions; -}; - -template< typename Real, typename Device, typename Index > -class MultiVector< 4, Real, Device, Index > : public Vector< Real, Device, Index > -{ - public: - - enum { Dimension = 4 }; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType; - typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType; - - MultiVector(); - - MultiVector( const String& name ); - - static String getType(); - - virtual String getTypeVirtual() const; - - static String getSerializationType(); - - virtual String getSerializationTypeVirtual() const; - - void setDimensions( const Index l, const Index k, const Index j, const Index iSize ); - - void setDimensions( const StaticVector< 4, Index >& dimensions ); - - void getDimensions( Index& l, Index& k, Index& j, Index& iSize ) const; - - const StaticVector< 4, Index >& getDimensions() const; - - //! Set dimensions of the Vector using another Vector as a template - template< typename MultiVector > - void setLike( const MultiVector& v ); - - Index getElementIndex( const Index l, const Index k, const Index j, const Index i ) const; - - void setElement( const Index l, const Index k, const Index j, const Index i, Real value ); - - //! This method can be used for general access to the elements of the Vectors. - /*! It does not return reference but value. So it can be used to access - * Vectors in different adress space (usualy GPU device). - * See also operator(). - */ - Real getElement( const Index l, const Index k, const Index j, const Index i ) const; - - //! Operator for accessing elements of the Vector. - /*! It returns reference to given elements so it cannot be - * used to access elements of Vectors in different adress space - * (GPU device usualy). - */ - Real& operator()( const Index l, const Index k, const Index j, const Index i ); - - const Real& operator()( const Index l, const Index k, const Index j, const Index i ) const; - - template< typename MultiVector > - bool operator == ( const MultiVector& Vector ) const; - - template< typename MultiVector > - bool operator != ( const MultiVector& Vector ) const; - - MultiVector< 4, Real, Device, Index >& operator = ( const MultiVector< 4, Real, Device, Index >& Vector ); - - template< typename MultiVectorT > - MultiVector< 4, Real, Device, Index >& operator = ( const MultiVectorT& Vector ); - - //! Method for saving the object to a file as a binary data - bool save( File& file ) const; - - //! Method for restoring the object from a file - bool load( File& file ); - - bool save( const String& fileName ) const; - - bool load( const String& fileName ); - - protected: - - StaticVector< 4, Index > dimensions; -}; - -template< typename Real, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 1, Real, device, Index >& Vector ); - -template< typename Real, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 2, Real, device, Index >& Vector ); - -template< typename Real, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 3, Real, device, Index >& Vector ); - -template< typename Real, typename device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 4, Real, device, Index >& Vector ); - -} // namespace Containers -} // namespace TNL - -#include <TNL/Containers/MultiVector1D_impl.h> -#include <TNL/Containers/MultiVector2D_impl.h> -#include <TNL/Containers/MultiVector3D_impl.h> -#include <TNL/Containers/MultiVector4D_impl.h> diff --git a/src/TNL/Containers/MultiVector1D_impl.h b/src/TNL/Containers/MultiVector1D_impl.h deleted file mode 100644 index 5ac452c2929a5717d37d726aa1778bf13db77921..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiVector1D_impl.h +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************** - MultiVector1D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - -template< typename Real, typename Device, typename Index > -MultiVector< 1, Real, Device, Index > :: MultiVector() -{ -} - -template< typename Real, typename Device, typename Index > -String MultiVector< 1, Real, Device, Index > :: getType() -{ - return String( "Containers::MultiVector< ") + - convertToString( Dimension ) + - String( ", " ) + - String( TNL::getType< Real >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 1, Real, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 1, Real, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 1, Real, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Real, typename Device, typename Index > -void MultiVector< 1, Real, Device, Index > :: setDimensions( const Index iSize ) -{ - TNL_ASSERT( iSize > 0, - std::cerr << "iSize = " << iSize ); - dimensions[ 0 ] = iSize; - Vector< Real, Device, Index > :: setSize( iSize ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 1, Real, Device, Index > :: setDimensions( const StaticVector< Dimension, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0, - std::cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] ); - this->dimensions = dimensions; - Vector< Real, Device, Index > :: setSize( this->dimensions[ 0 ] ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -void MultiVector< 1, Real, Device, Index > :: setLike( const MultiVectorT& multiVector ) -{ - setDimensions( multiVector. getDimensions() ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 1, Real, Device, Index > :: getDimensions( Index& xSize ) const -{ - xSize = this->dimensions[ 0 ]; -} - -template< typename Real, typename Device, typename Index > -const StaticVector< 1, Index >& MultiVector< 1, Real, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Real, typename Device, typename Index > -Index MultiVector< 1, Real, Device, Index > :: getElementIndex( const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ], - std::cerr << "i = " << i - << "this->dimensions[ 0 ] " << this->dimensions[ 0 ] ); - return i; -} - -template< typename Real, typename Device, typename Index > -Real MultiVector< 1, Real, Device, Index > :: getElement( const Index i ) const -{ - return Vector< Real, Device, Index > :: getElement( getElementIndex( i ) ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 1, Real, Device, Index > :: setElement( const Index i, Real value ) -{ - Vector< Real, Device, Index > :: setElement( getElementIndex( i ), value ); -} - - -template< typename Real, typename Device, typename Index > -Real& MultiVector< 1, Real, Device, Index > :: operator()( const Index element ) -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( element ) ); -} - -template< typename Real, typename Device, typename Index > -const Real& MultiVector< 1, Real, Device, Index > :: operator()( const Index element ) const -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( element ) ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 1, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl - << "First Vector name dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second Vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - return Vector< Real, Device, Index > :: operator == ( vector ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 1, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const -{ - return ! ( (* this ) == vector ); -} - -template< typename Real, typename Device, typename Index > -MultiVector< 1, Real, Device, Index >& - MultiVector< 1, Real, Device, Index > :: operator = ( const MultiVector< 1, Real, Device, Index >& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -MultiVector< 1, Real, Device, Index >& - MultiVector< 1, Real, Device, Index > :: operator = ( const MultiVectorT& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: save( File& file ) const -{ - if( ! Vector< Real, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: load( File& file ) -{ - if( ! Vector< Real, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 1, Real, Device, Index >& Vector ) -{ - for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ ) - { - str << Vector. getElement( i ) << " "; - } - return str; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: save( const String& fileName ) const -{ - return Object :: save( fileName ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: load( const String& fileName ) -{ - return Object :: load( fileName ); -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/MultiVector2D_impl.h b/src/TNL/Containers/MultiVector2D_impl.h deleted file mode 100644 index 7f061ad06cf9e0288d465ab3aa775855374ddd98..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiVector2D_impl.h +++ /dev/null @@ -1,242 +0,0 @@ -/*************************************************************************** - MultiVector2D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - -template< typename Real, typename Device, typename Index > -MultiVector< 2, Real, Device, Index > :: MultiVector() -{ -} - -template< typename Real, typename Device, typename Index > -String MultiVector< 2, Real, Device, Index > :: getType() -{ - return String( "Containers::MultiVector< ") + - convertToString( Dimension ) + - String( ", " ) + - String( TNL::getType< Real >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 2, Real, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 2, Real, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 2, Real, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Real, typename Device, typename Index > -void MultiVector< 2, Real, Device, Index > :: setDimensions( const Index jSize, - const Index iSize ) -{ - TNL_ASSERT( iSize > 0 && jSize > 0, - std::cerr << "iSize = " << iSize - << "jSize = " << jSize ); - - dimensions[ 0 ] = iSize; - dimensions[ 1 ] = jSize; - Vector< Real, Device, Index > :: setSize( iSize * jSize ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 2, Real, Device, Index > :: setDimensions( const StaticVector< 2, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0, - std::cerr << "dimensions = " << dimensions ); - this->dimensions = dimensions; - Vector< Real, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -void MultiVector< 2, Real, Device, Index > :: setLike( const MultiVectorT& multiVector ) -{ - setDimensions( multiVector. getDimensions() ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 2, Real, Device, Index > :: getDimensions( Index& jSize, Index& iSize ) const -{ - iSize = this->dimensions[ 0 ]; - jSize = this->dimensions[ 1 ]; -} - -template< typename Real, typename Device, typename Index > -const StaticVector< 2, Index >& MultiVector< 2, Real, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Real, typename Device, typename Index > -Index MultiVector< 2, Real, Device, Index > :: getElementIndex( const Index j, const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ], - std::cerr << "i = " << i - << "j = " << j - << "this->dimensions[ 0 ] = " << this->dimensions[ 0 ] - << "this->dimensions[ 1 ] = " << this->dimensions[ 1 ] ); - return j * this->dimensions[ 0 ] + i; -} - -template< typename Real, typename Device, typename Index > -Real MultiVector< 2, Real, Device, Index > :: getElement( const Index j, const Index i ) const -{ - return Vector< Real, Device, Index > :: getElement( getElementIndex( j, i ) ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 2, Real, Device, Index > :: setElement( const Index j, const Index i, Real value ) -{ - Vector< Real, Device, Index > :: setElement( getElementIndex( j, i ), value ); -} - - -template< typename Real, typename Device, typename Index > -Real& MultiVector< 2, Real, Device, Index > :: operator()( const Index j, const Index i ) -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( j, i ) ); -} - -template< typename Real, typename Device, typename Index > -const Real& MultiVector< 2, Real, Device, Index > :: operator()( const Index j, const Index i ) const -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( j, i ) ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 2, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - return Vector< Real, Device, Index > :: operator == ( vector ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 2, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const -{ - return ! ( (* this ) == vector ); -} - -template< typename Real, typename Device, typename Index > -MultiVector< 2, Real, Device, Index >& - MultiVector< 2, Real, Device, Index > :: operator = ( const MultiVector< 2, Real, Device, Index >& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -MultiVector< 2, Real, Device, Index >& - MultiVector< 2, Real, Device, Index > :: operator = ( const MultiVectorT& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: save( File& file ) const -{ - if( ! Vector< Real, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: load( File& file ) -{ - if( ! Vector< Real, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: save( const String& fileName ) const -{ - return Object :: save( fileName ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: load( const String& fileName ) -{ - return Object :: load( fileName ); -} - -template< typename Real, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 2, Real, Device, Index >& Vector ) -{ - for( Index j = 0; j < Vector. getDimensions()[ 1 ]; j ++ ) - { - for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ ) - { - str << Vector. getElement( j, i ) << " "; - } - str << std::endl; - } - return str; -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/MultiVector3D_impl.h b/src/TNL/Containers/MultiVector3D_impl.h deleted file mode 100644 index c7949014d7233bc14d744457201d14e7923a70fe..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiVector3D_impl.h +++ /dev/null @@ -1,266 +0,0 @@ -/*************************************************************************** - MultiVector3D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - -template< typename Real, typename Device, typename Index > -MultiVector< 3, Real, Device, Index > :: MultiVector() -{ -} - -template< typename Real, typename Device, typename Index > -String MultiVector< 3, Real, Device, Index > :: getType() -{ - return String( "Containers::MultiVector< ") + - convertToString( Dimension ) + - String( ", " ) + - String( TNL::getType< Real >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 3, Real, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 3, Real, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 3, Real, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Real, typename Device, typename Index > -void MultiVector< 3, Real, Device, Index > :: setDimensions( const Index kSize, - const Index jSize, - const Index iSize ) -{ - TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0, - std::cerr << "iSize = " << iSize - << "jSize = " << jSize - << "kSize = " << kSize ); - - dimensions[ 0 ] = iSize; - dimensions[ 1 ] = jSize; - dimensions[ 2 ] = kSize; - return Vector< Real, Device, Index > :: setSize( iSize * jSize * kSize ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 3, Real, Device, Index > :: setDimensions( const StaticVector< 3, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ], - std::cerr << "dimensions = " << dimensions ); - this->dimensions = dimensions; - Vector< Real, Device, Index > :: setSize( this->dimensions[ 2 ] * - this->dimensions[ 1 ] * - this->dimensions[ 0 ] ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -void MultiVector< 3, Real, Device, Index > :: setLike( const MultiVectorT& multiVector ) -{ - setDimensions( multiVector. getDimensions() ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 3, Real, Device, Index > :: getDimensions( Index& kSize, - Index& jSize, - Index& iSize ) const -{ - iSize = this->dimensions[ 0 ]; - jSize = this->dimensions[ 1 ]; - kSize = this->dimensions[ 2 ]; -} - -template< typename Real, typename Device, typename Index > -const StaticVector< 3, Index >& MultiVector< 3, Real, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Real, typename Device, typename Index > -Index MultiVector< 3, Real, Device, Index > :: getElementIndex( const Index k, - const Index j, - const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && - j >= 0 && j < this->dimensions[ 1 ] && - k >= 0 && k < this->dimensions[ 2 ], - std::cerr << " i = " << i - << " j = " << j - << " k = " << k - << " this->dimensions = " << this->dimensions ); - return ( k * this->dimensions[ 1 ] + j ) * this->dimensions[ 0 ] + i; -} - -template< typename Real, typename Device, typename Index > -Real MultiVector< 3, Real, Device, Index > :: getElement( const Index k, - const Index j, - const Index i ) const -{ - return Vector< Real, Device, Index > :: getElement( getElementIndex( k, j, i ) ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 3, Real, Device, Index > :: setElement( const Index k, - const Index j, - const Index i, Real value ) -{ - Vector< Real, Device, Index > :: setElement( getElementIndex( k, j, i ), value ); -} - - -template< typename Real, typename Device, typename Index > -Real& MultiVector< 3, Real, Device, Index > :: operator()( const Index k, - const Index j, - const Index i ) -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( k, j, i ) ); -} - -template< typename Real, typename Device, typename Index > -const Real& MultiVector< 3, Real, Device, Index > :: operator()( const Index k, - const Index j, - const Index i ) const -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( k, j, i ) ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 3, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - return Vector< Real, Device, Index > :: operator == ( vector ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 3, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const -{ - return ! ( (* this ) == vector ); -} - -template< typename Real, typename Device, typename Index > -MultiVector< 3, Real, Device, Index >& - MultiVector< 3, Real, Device, Index > :: operator = ( const MultiVector< 3, Real, Device, Index >& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -MultiVector< 3, Real, Device, Index >& - MultiVector< 3, Real, Device, Index > :: operator = ( const MultiVectorT& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: save( File& file ) const -{ - if( ! Vector< Real, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: load( File& file ) -{ - if( ! Vector< Real, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 3, Real, Device, Index >& Vector ) -{ - for( Index k = 0; k < Vector. getDimensions()[ 2 ]; k ++ ) - { - for( Index j = 0; j < Vector. getDimensions()[ 1 ]; j ++ ) - { - for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ ) - { - str << Vector. getElement( k, j, i ) << " "; - } - str << std::endl; - } - str << std::endl; - } - return str; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: save( const String& fileName ) const -{ - return Object :: save( fileName ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: load( const String& fileName ) -{ - return Object :: load( fileName ); -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/MultiVector4D_impl.h b/src/TNL/Containers/MultiVector4D_impl.h deleted file mode 100644 index 14708ec20c6d7c4daa5cb1424843bb34fcd78aa9..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/MultiVector4D_impl.h +++ /dev/null @@ -1,287 +0,0 @@ -/*************************************************************************** - MultiVector4D_impl.h - description - ------------------- - begin : Nov 13, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { -namespace Containers { - -template< typename Real, typename Device, typename Index > -MultiVector< 4, Real, Device, Index > :: MultiVector() -{ -} - -template< typename Real, typename Device, typename Index > -String MultiVector< 4, Real, Device, Index > :: getType() -{ - return String( "Containers::MultiVector< ") + - convertToString( Dimension ) + - String( ", " ) + - String( TNL::getType< Real >() ) + - String( ", " ) + - String( Device :: getDeviceType() ) + - String( ", " ) + - String( TNL::getType< Index >() ) + - String( " >" ); -} - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 4, Real, Device, Index > :: getTypeVirtual() const -{ - return this->getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 4, Real, Device, Index > :: getSerializationType() -{ - return HostType::getType(); -}; - -template< typename Real, - typename Device, - typename Index > -String MultiVector< 4, Real, Device, Index > :: getSerializationTypeVirtual() const -{ - return this->getSerializationType(); -}; - -template< typename Real, typename Device, typename Index > -void MultiVector< 4, Real, Device, Index > :: setDimensions( const Index lSize, - const Index kSize, - const Index jSize, - const Index iSize ) -{ - TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0, - std::cerr << "iSize = " << iSize - << "jSize = " << jSize - << "kSize = " << kSize - << "lSize = " << lSize ); - - dimensions[ 0 ] = iSize; - dimensions[ 1 ] = jSize; - dimensions[ 2 ] = kSize; - dimensions[ 3 ] = lSize; - Vector< Real, Device, Index > :: setSize( iSize * jSize * kSize * lSize ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 4, Real, Device, Index > :: setDimensions( const StaticVector< 4, Index >& dimensions ) -{ - TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0, - std::cerr << "dimensions = " << dimensions ); - this->dimensions = dimensions; - Vector< Real, Device, Index > :: setSize( this->dimensions[ 3 ] * - this->dimensions[ 2 ] * - this->dimensions[ 1 ] * - this->dimensions[ 0 ] ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -void MultiVector< 4, Real, Device, Index > :: setLike( const MultiVectorT& multiVector ) -{ - setDimensions( multiVector. getDimensions() ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 4, Real, Device, Index > :: getDimensions( Index& lSize, - Index& kSize, - Index& jSize, - Index& iSize ) const -{ - iSize = this->dimensions[ 0 ]; - jSize = this->dimensions[ 1 ]; - kSize = this->dimensions[ 2 ]; - lSize = this->dimensions[ 3 ]; -} - -template< typename Real, typename Device, typename Index > -const StaticVector< 4, Index >& MultiVector< 4, Real, Device, Index > :: getDimensions() const -{ - return this->dimensions; -} - -template< typename Real, typename Device, typename Index > -Index MultiVector< 4, Real, Device, Index > :: getElementIndex( const Index l, - const Index k, - const Index j, - const Index i ) const -{ - TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && - j >= 0 && j < this->dimensions[ 1 ] && - k >= 0 && k < this->dimensions[ 2 ] && - l >= 0 && l < this->dimensions[ 3 ], - std::cerr << " i = " << i - << " j = " << j - << " k = " << k - << " l = " << l - << " this->dimensions = " << this->dimensions ); - return ( ( l * this->dimensions[ 2 ] + k ) * this->dimensions[ 1 ] + j ) * this->dimensions[ 0 ] + i; -} - -template< typename Real, typename Device, typename Index > -Real -MultiVector< 4, Real, Device, Index >:: -getElement( const Index l, - const Index k, - const Index j, - const Index i ) const -{ - return Vector< Real, Device, Index > :: getElement( getElementIndex( l, k, j, i ) ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 4, Real, Device, Index > :: setElement( const Index l, - const Index k, - const Index j, - const Index i, Real value ) -{ - Vector< Real, Device, Index > :: setElement( getElementIndex( l, k, j, i ), value ); -} - - -template< typename Real, typename Device, typename Index > -Real& -MultiVector< 4, Real, Device, Index >:: -operator()( const Index l, - const Index k, - const Index j, - const Index i ) -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) ); -} - -template< typename Real, typename Device, typename Index > -const Real& MultiVector< 4, Real, Device, Index > :: operator()( const Index l, - const Index k, - const Index j, - const Index i ) const -{ - return Vector< Real, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 4, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - return Vector< Real, Device, Index > :: operator == ( vector ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -bool MultiVector< 4, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const -{ - return ! ( (* this ) == vector ); -} - -template< typename Real, typename Device, typename Index > -MultiVector< 4, Real, Device, Index >& - MultiVector< 4, Real, Device, Index > :: operator = ( const MultiVector< 4, Real, Device, Index >& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > - template< typename MultiVectorT > -MultiVector< 4, Real, Device, Index >& - MultiVector< 4, Real, Device, Index > :: operator = ( const MultiVectorT& vector ) -{ - // TODO: Static assert on dimensions - TNL_ASSERT( this->getDimensions() == vector. getDimensions(), - std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl - << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl - << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; ); - Vector< Real, Device, Index > :: operator = ( vector ); - return ( *this ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: save( File& file ) const -{ - if( ! Vector< Real, Device, Index > :: save( file ) ) - { - std::cerr << "I was not able to write the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. save( file ) ) - { - std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: load( File& file ) -{ - if( ! Vector< Real, Device, Index > :: load( file ) ) - { - std::cerr << "I was not able to read the Vector of MultiVector." << std::endl; - return false; - } - if( ! dimensions. load( file ) ) - { - std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl; - return false; - } - return true; -} - -template< typename Real, typename Device, typename Index > -std::ostream& operator << ( std::ostream& str, const MultiVector< 4, Real, Device, Index >& Vector ) -{ - for( Index l = 0; l < Vector. getDimensions()[ 3 ]; l ++ ) - { - for( Index k = 0; k < Vector. getDimensions()[ 2 ]; k ++ ) - { - for( Index j = 0; j < Vector. getDimensions()[ 1 ]; j ++ ) - { - for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ ) - { - str << Vector. getElement( l, k, j, i ) << " "; - } - str << std::endl; - } - str << std::endl; - } - str << std::endl; - } - return str; -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: save( const String& fileName ) const -{ - return Object :: save( fileName ); -} - -template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: load( const String& fileName ) -{ - return Object :: load( fileName ); -} - -} // namespace Containers -} // namespace TNL diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h index feac869e51ea0800cd96f1b1c6f6d5d7ccadea81..822b7abb4d533ba10de88d3bb24111e3b8888086 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h @@ -76,9 +76,9 @@ class EllpackIndexMultimap bool operator==( const EllpackIndexMultimap& other ) const; - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); using Object::load; diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h index 52182ad06f02f8e1add8318da3cf980ffc772447..2d145d377245ae8e0c92560aeaf9d8389bda2bd4 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h @@ -238,42 +238,30 @@ template< typename Index, typename Device, typename LocalIndex, int SliceSize > -bool +void EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >:: save( File& file ) const { - if( ! Object::save( file ) ) - return false; - if( ! file.write( &this->keysRange ) ) - return false; - if( ! file.write( &this->maxValuesCount ) ) - return false; - if( ! this->values.save( file ) ) - return false; - if( ! this->valuesCounts.save( file ) ) - return false; - return true; + Object::save( file ); + file.save( &this->keysRange ); + file.save( &this->maxValuesCount ); + this->values.save( file ); + this->valuesCounts.save( file ); } template< typename Index, typename Device, typename LocalIndex, int SliceSize > -bool +void EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >:: load( File& file ) { - if( ! Object::load( file ) ) - return false; - if( ! file.read( &this->keysRange ) ) - return false; - if( ! file.read( &this->maxValuesCount ) ) - return false; - if( ! this->values.load( file ) ) - return false; - if( ! this->valuesCounts.load( file ) ) - return false; - return true; + Object::load( file ); + file.load( &this->keysRange ); + file.load( &this->maxValuesCount ); + this->values.load( file ); + this->valuesCounts.load( file ); } template< typename Index, diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h index 4811a763d145f1a922e64dfc27968b8dd9f10521..1af67bd3b165b419065f06eb1673f0f9e69bf2a0 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h @@ -74,9 +74,9 @@ class StaticEllpackIndexMultimap bool operator==( const StaticEllpackIndexMultimap& other ) const; - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); using Object::load; diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h index 9a9309635c27d79c823516d3a621f4426cc2cbbd..95cb75d5db4069319c9bbd7bcbc138e102285ec5 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h @@ -197,17 +197,13 @@ template< int ValuesCount, typename Device, typename LocalIndex, int SliceSize > -bool +void StaticEllpackIndexMultimap< ValuesCount, Index, Device, LocalIndex, SliceSize >:: save( File& file ) const { - if( ! Object::save( file ) ) - return false; - if( ! file.write( &this->keysRange ) ) - return false; - if( ! this->values.save( file ) ) - return false; - return true; + Object::save( file ); + file.save( &this->keysRange ); + this->values.save( file ); } template< int ValuesCount, @@ -215,17 +211,13 @@ template< int ValuesCount, typename Device, typename LocalIndex, int SliceSize > -bool +void StaticEllpackIndexMultimap< ValuesCount, Index, Device, LocalIndex, SliceSize >:: load( File& file ) { - if( ! Object::load( file ) ) - return false; - if( ! file.read( &this->keysRange ) ) - return false; - if( ! this->values.load( file ) ) - return false; - return true; + Object::load( file ); + file.load( &this->keysRange ); + this->values.load( file ); } template< int ValuesCount, diff --git a/src/TNL/Containers/StaticArray1D_impl.h b/src/TNL/Containers/StaticArray1D_impl.h index e9b1fbc1d0726dcdb03414b8e0ad0ff0fa8c29bc..98963dcf350b5ebb7dd7323a73122a30b60dcb6d 100644 --- a/src/TNL/Containers/StaticArray1D_impl.h +++ b/src/TNL/Containers/StaticArray1D_impl.h @@ -162,22 +162,14 @@ inline void StaticArray< 1, Value >::setValue( const ValueType& val ) template< typename Value > bool StaticArray< 1, Value >::save( File& file ) const { - if( ! file. write< Value, Devices::Host >( data, size ) ) - { - std::cerr << "Unable to write " << getType() << "." << std::endl; - return false; - } + file.save< Value, Value, Devices::Host >( data, size ); return true; } template< typename Value > bool StaticArray< 1, Value >::load( File& file) { - if( ! file.read( data, size ) ) - { - std::cerr << "Unable to read " << getType() << "." << std::endl; - return false; - } + file.load< Value, Value, Devices::Host >( data, size ); return true; } diff --git a/src/TNL/Containers/StaticArray2D_impl.h b/src/TNL/Containers/StaticArray2D_impl.h index 664a938d79f4df5259609f74d5a379e26927b770..29dcbee5993e7f4a1b00b687e817f4323e0b936f 100644 --- a/src/TNL/Containers/StaticArray2D_impl.h +++ b/src/TNL/Containers/StaticArray2D_impl.h @@ -192,22 +192,14 @@ inline void StaticArray< 2, Value >::setValue( const ValueType& val ) template< typename Value > bool StaticArray< 2, Value >::save( File& file ) const { - if( ! file. write< Value, Devices::Host >( data, size ) ) - { - std::cerr << "Unable to write " << getType() << "." << std::endl; - return false; - } + file.save< Value, Value, Devices::Host >( data, size ); return true; } template< typename Value > bool StaticArray< 2, Value >::load( File& file) { - if( ! file.read< Value, Devices::Host >( data, size ) ) - { - std::cerr << "Unable to read " << getType() << "." << std::endl; - return false; - } + file.load< Value, Value, Devices::Host >( data, size ); return true; } diff --git a/src/TNL/Containers/StaticArray3D_impl.h b/src/TNL/Containers/StaticArray3D_impl.h index 2489196c05f91c294507fc9dd105b4da36f7a2bb..69c1998a471ae993d452ba684ac056aee6dfaf5e 100644 --- a/src/TNL/Containers/StaticArray3D_impl.h +++ b/src/TNL/Containers/StaticArray3D_impl.h @@ -213,22 +213,14 @@ void StaticArray< 3, Value >::setValue( const ValueType& val ) template< typename Value > bool StaticArray< 3, Value >::save( File& file ) const { - if( ! file. write< Value, Devices::Host >( data, size ) ) - { - std::cerr << "Unable to write " << getType() << "." << std::endl; - return false; - } + file.save< Value, Value, Devices::Host >( data, size ); return true; } template< typename Value > bool StaticArray< 3, Value >::load( File& file) { - if( ! file.read< Value, Devices::Host >( data, size ) ) - { - std::cerr << "Unable to read " << getType() << "." << std::endl; - return false; - } + file.load< Value, Value, Devices::Host >( data, size ); return true; } diff --git a/src/TNL/Containers/StaticArray_impl.h b/src/TNL/Containers/StaticArray_impl.h index a154ebc480ea8ba0529f3f452652fe5cc426f134..9c7835ce82c47b62057c0ba1ee519102112f4db9 100644 --- a/src/TNL/Containers/StaticArray_impl.h +++ b/src/TNL/Containers/StaticArray_impl.h @@ -160,22 +160,14 @@ inline void StaticArray< Size, Value >::setValue( const ValueType& val ) template< int Size, typename Value > bool StaticArray< Size, Value >::save( File& file ) const { - if( ! file. write< Value, Devices::Host >( data, size ) ) - { - std::cerr << "Unable to write " << getType() << "." << std::endl; - return false; - } + file.save< Value, Value, Devices::Host >( data, size ); return true; } template< int Size, typename Value > bool StaticArray< Size, Value >::load( File& file) { - if( ! file.read< Value, Devices::Host >( data, size ) ) - { - std::cerr << "Unable to read " << getType() << "." << std::endl; - return false; - } + file.load< Value, Value, Devices::Host >( data, size ); return true; } diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h index e116508ba3a54571e718938e4961233a73d98499..30e399312afc584d5f053de6d8792e4bd0064d13 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -11,12 +11,17 @@ #pragma once #include <TNL/Containers/Array.h> +#include <TNL/Containers/VectorView.h> namespace TNL { namespace Containers { /** - * \brief Class for storing vector elements and handling vector operations. + * \brief This class extends TNL::Array with algebraic operations. + * + * \tparam Real is numeric type usually float or double. + * \tparam Device is device where the array is going to be allocated - some of \ref Devices::Host and \ref Devices::Cuda. + * \tparam Index is indexing type. * * \par Example * \include VectorExample.cpp @@ -27,13 +32,14 @@ template< typename Real = double, class Vector : public Array< Real, Device, Index > { - public: - - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Vector< Real, TNL::Devices::Host, Index > HostType; - typedef Vector< Real, TNL::Devices::Cuda, Index > CudaType; +public: + using RealType = Real; + using DeviceType = Device; + using IndexType = Index; + using HostType = Vector< Real, TNL::Devices::Host, Index >; + using CudaType = Vector< Real, TNL::Devices::Cuda, Index >; + using ViewType = VectorView< Real, Device, Index >; + using ConstViewType = VectorView< typename std::add_const< Real >::type, Device, Index >; /** Constructors and assignment operators are inherited from the class \ref Array. */ using Array< Real, Device, Index >::Array; @@ -51,6 +57,26 @@ class Vector /** \brief Returns (host) type of vector Real value, Device type and the type of Index. */ virtual String getSerializationTypeVirtual() const; + /** + * \brief Returns a modifiable view of the vector. + */ + ViewType getView(); + + /** + * \brief Returns a non-modifiable view of the vector. + */ + ConstViewType getConstView() const; + + /** + * \brief Conversion operator to a modifiable view of the vector. + */ + operator ViewType(); + + /** + * \brief Conversion operator to a non-modifiable view of the vector. + */ + operator ConstViewType() const; + /** * \brief Adds another element to this vector. * @@ -282,4 +308,4 @@ class Vector } // namespace Containers } // namespace TNL -#include <TNL/Containers/Vector_impl.h> +#include <TNL/Containers/Vector.hpp> diff --git a/src/TNL/Containers/Vector_impl.h b/src/TNL/Containers/Vector.hpp similarity index 91% rename from src/TNL/Containers/Vector_impl.h rename to src/TNL/Containers/Vector.hpp index 6838215144393e8a69f5771d8109c4a36b8d6e2c..5f15d9bae5fc6d0527943f8b4245b6f94379fec3 100644 --- a/src/TNL/Containers/Vector_impl.h +++ b/src/TNL/Containers/Vector.hpp @@ -59,6 +59,44 @@ getSerializationTypeVirtual() const return this->getSerializationType(); } +template< typename Real, + typename Device, + typename Index > +typename Vector< Real, Device, Index >::ViewType +Vector< Real, Device, Index >:: +getView() +{ + return ViewType( this->getData(), this->getSize() ); +} + +template< typename Real, + typename Device, + typename Index > +typename Vector< Real, Device, Index >::ConstViewType +Vector< Real, Device, Index >:: +getConstView() const +{ + return ConstViewType( this->getData(), this->getSize() ); +} + +template< typename Value, + typename Device, + typename Index > +Vector< Value, Device, Index >:: +operator ViewType() +{ + return getView(); +} + +template< typename Value, + typename Device, + typename Index > +Vector< Value, Device, Index >:: +operator ConstViewType() const +{ + return getConstView(); +} + template< typename Real, typename Device, typename Index > @@ -174,7 +212,6 @@ ResultType Vector< Real, Device, Index >::lpNorm( const Scalar p ) const return Algorithms::VectorOperations< Device >::template getVectorLpNorm< Vector, ResultType >( *this, p ); } - template< typename Real, typename Device, typename Index > @@ -184,7 +221,6 @@ ResultType Vector< Real, Device, Index >::sum() const return Algorithms::VectorOperations< Device >::template getVectorSum< Vector, ResultType >( *this ); } - template< typename Real, typename Device, typename Index > @@ -194,7 +230,6 @@ Real Vector< Real, Device, Index >::differenceMax( const VectorT& v ) const return Algorithms::VectorOperations< Device >::getVectorDifferenceMax( *this, v ); } - template< typename Real, typename Device, typename Index > diff --git a/src/TNL/Containers/VectorView.h b/src/TNL/Containers/VectorView.h index 6ae0bcb816aff7feec18ef84b0e15c6c3e98cb13..1e5f070486052b6e52bc01da6d5ce5ff88d3edab 100644 --- a/src/TNL/Containers/VectorView.h +++ b/src/TNL/Containers/VectorView.h @@ -37,6 +37,8 @@ public: using IndexType = Index; using HostType = VectorView< Real, Devices::Host, Index >; using CudaType = VectorView< Real, Devices::Cuda, Index >; + using ViewType = VectorView< Real, Device, Index >; + using ConstViewType = VectorView< typename std::add_const< Real >::type, Device, Index >; // inherit all ArrayView's constructors #ifndef __NVCC__ @@ -62,6 +64,18 @@ public: VectorView( const ArrayView< Real_, Device, Index >& view ) : BaseType::ArrayView( view ) {} + /** + * \brief Returns a modifiable view of the array view. + */ + __cuda_callable__ + ViewType getView(); + + /** + * \brief Returns a non-modifiable view of the array view. + */ + __cuda_callable__ + ConstViewType getConstView() const; + static String getType(); diff --git a/src/TNL/Containers/VectorView_impl.h b/src/TNL/Containers/VectorView_impl.h index 39b6f703e9035d0ad5ab029be7b3e2b71aafba54..af4df853738c7520510bd4fa5a47c8ec5e56acda 100644 --- a/src/TNL/Containers/VectorView_impl.h +++ b/src/TNL/Containers/VectorView_impl.h @@ -16,6 +16,26 @@ namespace TNL { namespace Containers { +template< typename Value, + typename Device, + typename Index > +typename VectorView< Value, Device, Index >::ViewType +VectorView< Value, Device, Index >:: +getView() +{ + return *this; +} + +template< typename Value, + typename Device, + typename Index > +typename VectorView< Value, Device, Index >::ConstViewType +VectorView< Value, Device, Index >:: +getConstView() const +{ + return *this; +} + template< typename Real, typename Device, typename Index > diff --git a/src/TNL/Devices/Cuda.h b/src/TNL/Devices/Cuda.h index 0ba22cb00a433d3346d4429823c75cb6dfe002d6..7831014155e9a730c1be101c47cb2602cd8d3179 100644 --- a/src/TNL/Devices/Cuda.h +++ b/src/TNL/Devices/Cuda.h @@ -29,6 +29,9 @@ class Cuda static inline String getDeviceType(); + // TODO: Remove getDeviceType(); + static inline String getType() { return getDeviceType();}; + static inline void configSetup( Config::ConfigDescription& config, const String& prefix = "" ); static inline bool setup( const Config::ParameterContainer& parameters, @@ -169,6 +172,15 @@ class Cuda static inline Timer& getSmartPointersSynchronizationTimer(); + //// + // When we transfer data between the GPU and the CPU we use 5 MB buffer. This + // size should ensure good performance -- see. + // http://wiki.accelereyes.com/wiki/index.php/GPU_Memory_Transfer . + // We use the same buffer size even for retyping data during IO operations. + // + static constexpr std::size_t TransferBufferSize = 5 * 2<<20; + + protected: static inline Pointers::SmartPointersRegister& getSmartPointersRegister(); diff --git a/src/TNL/Devices/CudaCallable.h b/src/TNL/Devices/CudaCallable.h index e0a86a3e4f01a8ae112a45c7528f77e152289b04..f9311443f12a0c85fb6fba9ebaf07ca47736b030 100644 --- a/src/TNL/Devices/CudaCallable.h +++ b/src/TNL/Devices/CudaCallable.h @@ -16,6 +16,12 @@ // For example, the implementation of Devices::Cuda needs TNL_ASSERT_* // macros, which need __cuda_callable__ functions. +/*** + * This macro serves for definition of function which are supposed to be called + * even from device. If HAVE_CUDA is defined, the __cuda_callable__ function + * is compiled for both CPU and GPU. If HAVE_CUDA is not defined, this macro has + * no effect. Support for Intel Xeon Phi is now in "hibernated" state. + */ #ifdef HAVE_MIC #define __cuda_callable__ __attribute__((target(mic))) #elif HAVE_CUDA diff --git a/src/TNL/Devices/Cuda_impl.h b/src/TNL/Devices/Cuda_impl.h index c9828c66deab37b889b8e738ec5eabfe1ab26352..234f45b720fcfa9502b6f4c5c14debfb48ecca64 100644 --- a/src/TNL/Devices/Cuda_impl.h +++ b/src/TNL/Devices/Cuda_impl.h @@ -23,7 +23,7 @@ namespace Devices { inline String Cuda::getDeviceType() { - return String( "Cuda" ); + return String( "Devices::Cuda" ); } inline void diff --git a/src/TNL/Devices/Host.h b/src/TNL/Devices/Host.h index 6b56302a248d98182c030ed3eb1c846a051ccd7f..98b95f2f659d364897910c96461f52a42a45ca91 100644 --- a/src/TNL/Devices/Host.h +++ b/src/TNL/Devices/Host.h @@ -30,6 +30,9 @@ public: return String( "Devices::Host" ); } + // TODO: Remove getDeviceType(); + static inline String getType() { return getDeviceType();}; + static void disableOMP() { ompEnabled = false; diff --git a/src/TNL/Devices/MIC.h b/src/TNL/Devices/MIC.h index 373e838f72634a8f34440556ff66b7ac51ddeb0a..db1a238097f12cdaf3a2076b030baebe50d94eaf 100644 --- a/src/TNL/Devices/MIC.h +++ b/src/TNL/Devices/MIC.h @@ -69,11 +69,14 @@ class MIC { public: - static String getDeviceType() - { - return String( "Devices::MIC" ); - }; - + static String getDeviceType() + { + return String( "Devices::MIC" ); + }; + + // TODO: Remove getDeviceType(); + static inline String getType() { return getDeviceType(); }; + #ifdef HAVE_MIC //useful debuging -- but produce warning diff --git a/src/TNL/Exceptions/ArrayWrongSize.h b/src/TNL/Exceptions/ArrayWrongSize.h new file mode 100644 index 0000000000000000000000000000000000000000..8181b3c557e176ab530d8b5f33a8c53896e09a73 --- /dev/null +++ b/src/TNL/Exceptions/ArrayWrongSize.h @@ -0,0 +1,32 @@ +/*************************************************************************** + ArrayWrongSize.h - description + ------------------- + begin : Mar 8, 2019 + copyright : (C) 2019 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +// Implemented by: Tomas Oberhuber + +#pragma once + +#include <string> +#include <stdexcept> +#include <TNL/String.h> + +namespace TNL { +namespace Exceptions { + +class ArrayWrongSize + : public std::runtime_error +{ +public: + ArrayWrongSize( std::size_t size, const String& mesg = "" ) + : std::runtime_error( "Wrong array size " + convertToString( size ) + ". " + mesg ) + {} +}; + +} // namespace Exceptions +} // namespace TNL diff --git a/src/TNL/Exceptions/MeshFunctionDataMismatch.h b/src/TNL/Exceptions/MeshFunctionDataMismatch.h new file mode 100644 index 0000000000000000000000000000000000000000..6106db872a3eacb5edbc73290f192a2e1e40d392 --- /dev/null +++ b/src/TNL/Exceptions/MeshFunctionDataMismatch.h @@ -0,0 +1,32 @@ +/*************************************************************************** + MeshFunctionDataMismatch.h - description + ------------------- + begin : Mar 8, 2019 + copyright : (C) 2019 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +// Implemented by: Tomas Oberhuber + +#pragma once + +#include <string> +#include <stdexcept> +#include <TNL/String.h> + +namespace TNL { +namespace Exceptions { + +class MeshFunctionDataMismatch + : public std::runtime_error +{ +public: + MeshFunctionDataMismatch( std::size_t size, const String& mesg = "" ) + : std::runtime_error( "Mesh function data size " + convertToString( size ) + " mismatch." + mesg ) + {} +}; + +} // namespace Exceptions +} // namespace TNL diff --git a/src/TNL/Exceptions/NotTNLFile.h b/src/TNL/Exceptions/NotTNLFile.h new file mode 100644 index 0000000000000000000000000000000000000000..ce2d756a533133a068254ad2428fc49c243dd4b5 --- /dev/null +++ b/src/TNL/Exceptions/NotTNLFile.h @@ -0,0 +1,31 @@ +/*************************************************************************** + NotTNLFile.h - description + ------------------- + begin : Mar 4, 2019 + copyright : (C) 2019 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +// Implemented by: Tomas Oberhuber + +#pragma once + +#include <string> +#include <stdexcept> + +namespace TNL { +namespace Exceptions { + +class NotTNLFile + : public std::runtime_error +{ +public: + NotTNLFile() + : std::runtime_error( "Wrong magic number found in a binary file. It is not TNL compatible file." ) + {} +}; + +} // namespace Exceptions +} // namespace TNL diff --git a/src/TNL/Exceptions/ObjectTypeDetectionFailure.h b/src/TNL/Exceptions/ObjectTypeDetectionFailure.h new file mode 100644 index 0000000000000000000000000000000000000000..6381c2fd73f36287b7585f1f067aad5af0deeb41 --- /dev/null +++ b/src/TNL/Exceptions/ObjectTypeDetectionFailure.h @@ -0,0 +1,31 @@ +/*************************************************************************** + ObjectTypeDetectionFailure.h - description + ------------------- + begin : Mar 4, 2019 + copyright : (C) 2019 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +// Implemented by: Tomas Oberhuber + +#pragma once + +#include <string> +#include <stdexcept> + +namespace TNL { +namespace Exceptions { + +class ObjectTypeDetectionFailure + : public std::runtime_error +{ +public: + ObjectTypeDetectionFailure( const String& fileName, const String& objectType ) + : std::runtime_error( "Failed to detect " + objectType + " in file " + fileName + "." ) + {} +}; + +} // namespace Exceptions +} // namespace TNL diff --git a/src/TNL/Exceptions/ObjectTypeMismatch.h b/src/TNL/Exceptions/ObjectTypeMismatch.h new file mode 100644 index 0000000000000000000000000000000000000000..9b48fd0ea3a0fcfcb12d804bc41485a9f342e261 --- /dev/null +++ b/src/TNL/Exceptions/ObjectTypeMismatch.h @@ -0,0 +1,32 @@ +/*************************************************************************** + ObjectTypeMismatch.h - description + ------------------- + begin : Mar 8, 2019 + copyright : (C) 2019 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +// Implemented by: Tomas Oberhuber + +#pragma once + +#include <string> +#include <stdexcept> +#include <TNL/String.h> + +namespace TNL { +namespace Exceptions { + +class ObjectTypeMismatch + : public std::runtime_error +{ +public: + ObjectTypeMismatch( const String& expected, const String& detected ) + : std::runtime_error( "Object type mismatch. Expected object type is " + expected + " but " + detected + " was detcted." ) + {} +}; + +} // namespace Exceptions +} // namespace TNL diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h index 7c65ef94d4818c2fe6b5b703dfe390f23ea37d21..7437803e262b517632d43c590f485b5e923b2698 100644 --- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h @@ -128,9 +128,15 @@ setInitialCondition( const Config::ParameterContainer& parameters, } else { - if( !this->initialData->boundLoad( inputFile ) ) - std::cerr << "I am not able to load the initial condition from the file " << inputFile << "." << std::endl; - return false; + try + { + this->initialData->boundLoad( inputFile ); + } + catch(...) + { + std::cerr << "I am not able to load the initial condition from the file " << inputFile << "." << std::endl; + return false; + } } return true; } diff --git a/src/TNL/File.h b/src/TNL/File.h index 178ce95858a50954ea05c34649084dd368fc9243..120d7342dd2d3151c864e3c68daf864a81679e37 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -20,143 +20,193 @@ namespace TNL { -/// \brief Supported modes for opening \ref TNL::File "files". -enum class IOMode -{ -// undefined = 0, - read = 1, - write = 2 -}; - -/* When we need to transfer data between the GPU and the CPU we use - * 5 MB buffer. This size should ensure good performance -- see. - * http://wiki.accelereyes.com/wiki/index.php/GPU_Memory_Transfer - * Similar constant is defined in tnlLonegVectorCUDA +/** + * \brief This class serves for binary IO. It allows to do IO even for data allocated on GPU together with on-the-fly data type conversion. + * + * \par Example + * \include FileExample.cpp + * \par Output + * \include FileExample.out */ -static constexpr std::streamsize FileGPUvsCPUTransferBufferSize = 5 * 2<<20; - - -///\brief Class file is aimed mainly for saving and loading binary data. -/// -/// \par Example -/// \include FileExample.cpp -// \par Output -// \include FileExample.out class File { - std::fstream file; - String fileName; - -public: - /// \brief Basic constructor. - File() = default; - - ///// - /// \brief Attempts to open given file and returns \e true after the file is - /// successfully opened. Otherwise returns \e false. - /// - /// Opens file with given \e fileName and returns true/false based on the success in opening the file. - /// \param fileName String which indicates name of the file user wants to open. - /// \param mode Indicates what user needs to do with opened file. - bool open( const String& fileName, - const IOMode mode ); - - /// \brief Attempts to close given file and returns \e true when the file is - /// successfully closed. Otherwise returns \e false. - bool close(); - - /// \brief Returns name of given file. - const String& getFileName() const - { - return this->fileName; - } - - /// \brief Method that can write particular data type from given file into GPU. (Function that gets particular elements from given file.) - /// - /// Returns \e true when the elements are successfully read from given file. Otherwise returns \e false. - /// - /// Throws \ref std::ios_base::failure on failure. - /// - /// \tparam Type Type of data. - /// \tparam Device Place where data are stored after reading from file. For example \ref Devices::Host or \ref Devices::Cuda. - /// \tparam Index Type of index by which the elements are indexed. - /// \param buffer Pointer in memory where the elements are loaded and stored after reading. - /// \param elements Number of elements the user wants to get (read) from given file. - template< typename Type, typename Device = Devices::Host > - bool read( Type* buffer, std::streamsize elements ); - - // Toto je treba?? - template< typename Type, typename Device = Devices::Host > - bool read( Type* buffer ); - - /// \brief Method that can write particular data type from CPU into given file. (Function that writes particular elements into given file.) - /// - /// Returns \e true when the elements are successfully written into given file. Otherwise returns \e false. - /// - /// Throws \ref std::ios_base::failure on failure. - /// - /// \tparam Type Type of data. - /// \tparam Device Place from where the data are loaded before writing into file. For example \ref Devices::Host or \ref Devices::Cuda. - /// \tparam Index Type of index by which the elements are indexed. - /// \param buffer Pointer in memory where the elements are loaded from before writing into file. - /// \param elements Number of elements the user wants to write into the given file. - template< typename Type, typename Device = Devices::Host > - bool write( const Type* buffer, std::streamsize elements ); - - // Toto je treba? - template< typename Type, typename Device = Devices::Host > - bool write( const Type* buffer ); - -protected: - template< typename Type, - typename Device, - typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type > - bool read_impl( Type* buffer, std::streamsize elements ); - - template< typename Type, - typename Device, - typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type, - typename = void > - bool read_impl( Type* buffer, std::streamsize elements ); - - template< typename Type, - typename Device, - typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type, - typename = void, - typename = void > - bool read_impl( Type* buffer, std::streamsize elements ); - - template< typename Type, - typename Device, - typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type > - bool write_impl( const Type* buffer, std::streamsize elements ); - - template< typename Type, - typename Device, - typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type, - typename = void > - bool write_impl( const Type* buffer, std::streamsize elements ); - - template< typename Type, - typename Device, - typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type, - typename = void, - typename = void > - bool write_impl( const Type* buffer, std::streamsize elements ); + public: + + /** + * This enum defines mode for opening files. + */ + enum class Mode + { + In = 1, ///< Open for input. + Out = 2, ///< Open for output. + Append = 4, ///< Output operations are appended at the end of file. + AtEnd = 8, ///< Set the initial position at the end. + Truncate = 16 ///< If the file is opened for ouptput, its previous content is deleted. + }; + + /** + * \brief Basic constructor. + */ + File() = default; + + /** + * \brief Open given file. + * + * Opens file with given \e fileName in some \e mode from \ref File::Mode. + * + * Throws \ref std::ios_base::failure on failure. + * + * \param fileName String which indicates file name. + * \param mode Indicates in what mode the file will be opened - see. \ref File::Mode. + */ + void open( const String& fileName, + Mode mode = static_cast< Mode >( static_cast< int >( Mode::In ) | static_cast< int >( Mode::Out ) ) ); + + /** + * \brief Closes the file. + * + * Throws \ref std::ios_base::failure on failure. + */ + void close(); + + /** + * \brief Returns name of the file. + */ + const String& getFileName() const + { + return this->fileName; + } + + /** + * \brief Method for loading data from the file. + * + * The data will be stored in \e buffer allocated on device given by the + * \e Device parameter. The data type of the buffer is given by the + * template parameter \e Type. The second template parameter + * \e SourceType defines the type of data in the source file. If both + * types are different, on-the-fly conversion takes place during the + * data loading. + * + * Throws \ref std::ios_base::failure on failure. + * + * \tparam Type type of data to be loaded to the \e buffer. + * \tparam SourceType type of data stored on the file, + * \tparam Device device where the data are stored after reading. For example \ref Devices::Host or \ref Devices::Cuda. + * \param buffer Pointer in memory where the elements are loaded and stored after reading. + * \param elements number of elements to be loaded from the file. + * + * The following example shows how to load data directly to GPU. + * + * \par Example + * \include FileExampleCuda.cpp + * \par Output + * \include FileExampleCuda.out + * The following example shows how to do on-the-fly data conversion. + * + * \par Example + * \include FileExampleSaveAndLoad.cpp + * \par Output + * \include FileExampleSaveAndLoad.out + */ + template< typename Type, typename SourceType = Type, typename Device = Devices::Host > + void load( Type* buffer, std::streamsize elements = 1 ); + + /** + * \brief Method for saving data to the file. + * + * The data from the \e buffer (with type \e Type) allocated on the device + * \e Device will be saved into the file. \e TargetType defines as what + * data type the buffer shall be saved. If the type is different from the + * data type, on-the-fly data type conversion takes place during the data + * saving. + * + * Throws \ref std::ios_base::failure on failure. + * + * \tparam Type type of data in the \e buffer. + * \tparam TargetType tells as what type data the buffer shall be saved. + * \tparam Device device from where the data are loaded before writing into file. For example \ref Devices::Host or \ref Devices::Cuda. + * \tparam Index type of index by which the elements are indexed. + * \param buffer buffer that is going to be saved to the file. + * \param elements number of elements saved to the file. + * + * See \ref File::load for examples. + */ + template< typename Type, typename TargetType = Type, typename Device = Devices::Host > + void save( const Type* buffer, std::streamsize elements = 1 ); + + protected: + template< typename Type, + typename SourceType, + typename Device, + typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type > + void load_impl( Type* buffer, std::streamsize elements ); + + template< typename Type, + typename SourceType, + typename Device, + typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type, + typename = void > + void load_impl( Type* buffer, std::streamsize elements ); + + template< typename Type, + typename SourceType, + typename Device, + typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type, + typename = void, + typename = void > + void load_impl( Type* buffer, std::streamsize elements ); + + template< typename Type, + typename TargetType, + typename Device, + typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type > + void save_impl( const Type* buffer, std::streamsize elements ); + + template< typename Type, + typename TargetType, + typename Device, + typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type, + typename = void > + void save_impl( const Type* buffer, std::streamsize elements ); + + template< typename Type, + typename TargetType, + typename Device, + typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type, + typename = void, + typename = void > + void save_impl( const Type* buffer, std::streamsize elements ); + + std::fstream file; + String fileName; + + //// + // When we transfer data between the GPU and the CPU we use 5 MB buffer. This + // size should ensure good performance -- see. + // http://wiki.accelereyes.com/wiki/index.php/GPU_Memory_Transfer . + // We use the same buffer size even for retyping data during IO operations. + // + static constexpr std::streamsize TransferBufferSize = 5 * 2<<20; }; -/// Returns true if the file exists and false otherwise. -/// -/// Finds out if the file \e fileName exists. -/// \param fileName Name of the file that user wants to find in the PC. +/** + * \brief Returns true if the file exists and false otherwise. + * + * Finds out if the file \e fileName exists. + * \param fileName Name of the file to check. + * \return returns true if the file exists and false othervise + */ bool fileExists( const String& fileName ); -// serialization of strings +/** + * \brief Serialization of strings + */ File& operator<<( File& file, const std::string& str ); -// deserialization of strings +/** + * \brief Deserialization of strings. + */ File& operator>>( File& file, std::string& str ); - } // namespace TNL -#include <TNL/File_impl.h> +#include <TNL/File.hpp> diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp new file mode 100644 index 0000000000000000000000000000000000000000..df1181af7e1a13238418d23562c7377982f347d1 --- /dev/null +++ b/src/TNL/File.hpp @@ -0,0 +1,426 @@ +/*************************************************************************** + File_impl.h - description + ------------------- + begin : Mar 5, Oct 2016 + copyright : (C) 2016 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <memory> +#include <iostream> +#include <ios> +#include <sstream> + +#include <TNL/File.h> +#include <TNL/Assert.h> +#include <TNL/Exceptions/CudaSupportMissing.h> +#include <TNL/Exceptions/MICSupportMissing.h> +#include <TNL/Exceptions/FileSerializationError.h> +#include <TNL/Exceptions/FileDeserializationError.h> + +namespace TNL { + +inline File::Mode operator|( File::Mode m1, File::Mode m2 ); + +inline bool operator&( File::Mode m1, File::Mode m2 ); + +inline void File::open( const String& fileName, Mode mode ) +{ + // enable exceptions + file.exceptions( std::fstream::failbit | std::fstream::badbit | std::fstream::eofbit ); + + close(); + + auto ios_mode = std::ios::binary; + if( mode & Mode::In ) ios_mode |= std::ios::in; + if( mode & Mode::Out ) ios_mode |= std::ios::out; + if( mode & Mode::Append ) ios_mode |= std::ios::app; + if( mode & Mode::AtEnd ) ios_mode |= std::ios::ate; + if( mode & Mode::Truncate ) ios_mode |= std::ios::trunc; + try + { + file.open( fileName.getString(), ios_mode ); + } + catch( std::ios_base::failure& ) + { + std::stringstream msg; + msg << "Unable to open file " << fileName << " "; + if( mode & Mode::In ) + msg << " for reading."; + if( mode & Mode::Out ) + msg << " for writing."; + + throw std::ios_base::failure( msg.str() ); + } + + this->fileName = fileName; +} + +inline void File::close() +{ + if( file.is_open() ) + { + try + { + file.close(); + } + catch( std::ios_base::failure& ) + { + std::stringstream msg; + msg << "Unable to close file " << fileName << "."; + + throw std::ios_base::failure( msg.str() ); + } + } + // reset file name + fileName = ""; +} + +template< typename Type, + typename SourceType, + typename Device > +void File::load( Type* buffer, std::streamsize elements ) +{ + TNL_ASSERT_GE( elements, 0, "Number of elements to load must be non-negative." ); + + if( ! elements ) + return; + + load_impl< Type, SourceType, Device >( buffer, elements ); +} + +// Host +template< typename Type, + typename SourceType, + typename Device, + typename > +void File::load_impl( Type* buffer, std::streamsize elements ) +{ + if( std::is_same< Type, SourceType >::value ) + file.read( reinterpret_cast<char*>(buffer), sizeof(Type) * elements ); + else + { + const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(SourceType), elements ); + using BaseType = typename std::remove_cv< SourceType >::type; + std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] }; + std::streamsize readElements = 0; + while( readElements < elements ) + { + const std::streamsize transfer = std::min( elements - readElements, cast_buffer_size ); + file.read( reinterpret_cast<char*>(cast_buffer.get()), sizeof(SourceType) * transfer ); + for( std::streamsize i = 0; i < transfer; i++ ) + buffer[ readElements ++ ] = static_cast< Type >( cast_buffer[ i ] ); + readElements += transfer; + } + } +} + +// Cuda +template< typename Type, + typename SourceType, + typename Device, + typename, typename > +void File::load_impl( Type* buffer, std::streamsize elements ) +{ +#ifdef HAVE_CUDA + const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements ); + using BaseType = typename std::remove_cv< Type >::type; + std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; + + std::streamsize readElements = 0; + if( std::is_same< Type, SourceType >::value ) + { + while( readElements < elements ) + { + const std::streamsize transfer = std::min( elements - readElements, host_buffer_size ); + file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer ); + cudaMemcpy( (void*) &buffer[ readElements ], + (void*) host_buffer.get(), + transfer * sizeof( Type ), + cudaMemcpyHostToDevice ); + TNL_CHECK_CUDA_DEVICE; + readElements += transfer; + } + } + else + { + const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(SourceType), elements ); + using BaseType = typename std::remove_cv< SourceType >::type; + std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] }; + + while( readElements < elements ) + { + const std::streamsize transfer = std::min( elements - readElements, cast_buffer_size ); + file.read( reinterpret_cast<char*>(cast_buffer.get()), sizeof(SourceType) * transfer ); + for( std::streamsize i = 0; i < transfer; i++ ) + host_buffer[ i ] = static_cast< Type >( cast_buffer[ i ] ); + cudaMemcpy( (void*) &buffer[ readElements ], + (void*) host_buffer.get(), + transfer * sizeof( Type ), + cudaMemcpyHostToDevice ); + TNL_CHECK_CUDA_DEVICE; + readElements += transfer; + } + } +#else + throw Exceptions::CudaSupportMissing(); +#endif +} + +// MIC +template< typename Type, + typename SourceType, + typename Device, + typename, typename, typename > +void File::load_impl( Type* buffer, std::streamsize elements ) +{ +#ifdef HAVE_MIC + const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements ); + using BaseType = typename std::remove_cv< Type >::type; + std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; + + std::streamsize readElements = 0; + if( std::is_same< Type, SourceType >::value ) + { + while( readElements < elements ) + { + const std::streamsize transfer = std::min( elements - readElements, host_buffer_size ); + file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer ); + + Devices::MICHider<Type> device_buff; + device_buff.pointer=buffer; + #pragma offload target(mic) in(device_buff,readElements) in(host_buffer:length(transfer)) + { + /* + for(int i=0;i<transfer;i++) + device_buff.pointer[readElements+i]=host_buffer[i]; + */ + memcpy(&(device_buff.pointer[readElements]), host_buffer.get(), transfer*sizeof(Type) ); + } + + readElements += transfer; + } + free( host_buffer ); + } + else + { + std::cerr << "Type conversion during loading is not implemented for MIC." << std::endl; + abort(); + } +#else + throw Exceptions::MICSupportMissing(); +#endif +} + +template< typename Type, + typename TargetType, + typename Device > +void File::save( const Type* buffer, std::streamsize elements ) +{ + TNL_ASSERT_GE( elements, 0, "Number of elements to save must be non-negative." ); + + if( ! elements ) + return; + + save_impl< Type, TargetType, Device >( buffer, elements ); +} + +// Host +template< typename Type, + typename TargetType, + typename Device, + typename > +void File::save_impl( const Type* buffer, std::streamsize elements ) +{ + if( std::is_same< Type, TargetType >::value ) + file.write( reinterpret_cast<const char*>(buffer), sizeof(Type) * elements ); + else + { + const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(TargetType), elements ); + using BaseType = typename std::remove_cv< TargetType >::type; + std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] }; + std::streamsize writtenElements = 0; + while( writtenElements < elements ) + { + const std::streamsize transfer = std::min( elements - writtenElements, cast_buffer_size ); + for( std::streamsize i = 0; i < transfer; i++ ) + cast_buffer[ i ] = static_cast< TargetType >( buffer[ writtenElements ++ ] ); + file.write( reinterpret_cast<char*>(cast_buffer.get()), sizeof(TargetType) * transfer ); + writtenElements += transfer; + } + + } +} + +// Cuda +template< typename Type, + typename TargetType, + typename Device, + typename, typename > +void File::save_impl( const Type* buffer, std::streamsize elements ) +{ +#ifdef HAVE_CUDA + const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements ); + using BaseType = typename std::remove_cv< Type >::type; + std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; + + std::streamsize writtenElements = 0; + if( std::is_same< Type, TargetType >::value ) + { + while( writtenElements < elements ) + { + const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size ); + cudaMemcpy( (void*) host_buffer.get(), + (void*) &buffer[ writtenElements ], + transfer * sizeof(Type), + cudaMemcpyDeviceToHost ); + TNL_CHECK_CUDA_DEVICE; + file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer ); + writtenElements += transfer; + } + } + else + { + const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(TargetType), elements ); + using BaseType = typename std::remove_cv< TargetType >::type; + std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] }; + + while( writtenElements < elements ) + { + const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size ); + cudaMemcpy( (void*) host_buffer.get(), + (void*) &buffer[ writtenElements ], + transfer * sizeof(Type), + cudaMemcpyDeviceToHost ); + TNL_CHECK_CUDA_DEVICE; + for( std::streamsize i = 0; i < transfer; i++ ) + cast_buffer[ i ] = static_cast< TargetType >( host_buffer[ i ] ); + + file.write( reinterpret_cast<const char*>(cast_buffer.get()), sizeof(TargetType) * transfer ); + writtenElements += transfer; + } + } +#else + throw Exceptions::CudaSupportMissing(); +#endif +} + +// MIC +template< typename Type, + typename TargetType, + typename Device, + typename, typename, typename > +void File::save_impl( const Type* buffer, std::streamsize elements ) +{ +#ifdef HAVE_MIC + const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements ); + using BaseType = typename std::remove_cv< Type >::type; + std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; + + std::streamsize writtenElements = 0; + if( std::is_same< Type, TargetType >::value ) + { + while( this->writtenElements < elements ) + { + const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size ); + + Devices::MICHider<const Type> device_buff; + device_buff.pointer=buffer; + #pragma offload target(mic) in(device_buff,writtenElements) out(host_buffer:length(transfer)) + { + //THIS SHOULD WORK... BUT NOT WHY? + /*for(int i=0;i<transfer;i++) + host_buffer[i]=device_buff.pointer[writtenElements+i]; + */ + + memcpy(host_buffer.get(), &(device_buff.pointer[writtenElements]), transfer*sizeof(Type) ); + } + + file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer ); + writtenElements += transfer; + } + } + else + { + std::cerr << "Type conversion during saving is not implemented for MIC." << std::endl; + abort(); + } +#else + throw Exceptions::MICSupportMissing(); +#endif +} + +inline bool fileExists( const String& fileName ) +{ + std::fstream file; + file.open( fileName.getString(), std::ios::in ); + return ! file.fail(); +} + + +// serialization of strings +inline File& operator<<( File& file, const std::string& str ) +{ + const int len = str.size(); + try + { + file.save( &len ); + } + catch(...) + { + throw Exceptions::FileSerializationError( getType< int >(), file.getFileName() ); + } + try + { + file.save( str.c_str(), len ); + } + catch(...) + { + throw Exceptions::FileSerializationError( "String", file.getFileName() ); + } + return file; +} + +// deserialization of strings +inline File& operator>>( File& file, std::string& str ) +{ + int length; + try + { + file.load( &length ); + } + catch(...) + { + throw Exceptions::FileDeserializationError( getType< int >(), file.getFileName() ); + } + char buffer[ length ]; + if( length ) + { + try + { + file.load( buffer, length ); + } + catch(...) + { + throw Exceptions::FileDeserializationError( "String", file.getFileName() ); + } + } + str.assign( buffer, length ); + return file; +} + +inline File::Mode operator|( File::Mode m1, File::Mode m2 ) +{ + return static_cast< File::Mode >( static_cast< int >( m1 ) | static_cast< int >( m2 ) ); +} + +inline bool operator&( File::Mode m1, File::Mode m2 ) +{ + return static_cast< bool >( static_cast< int >( m1 ) & static_cast< int >( m2 ) ); +} + +} // namespace TNL diff --git a/src/TNL/FileName.h b/src/TNL/FileName.h index 2c860770d47b4a2f55a7c23d1ad4d5b5d3627cbc..0f4950ae82ffec79f2c7f314d71c1921706913dc 100644 --- a/src/TNL/FileName.h +++ b/src/TNL/FileName.h @@ -14,70 +14,144 @@ namespace TNL { -String getFileExtension( const String fileName ); - -void removeFileExtension( String& file_name ); - -/// \brief Class for the construction of file names from multiple parts. -/// -/// Merges base name, index number and extention to create the full name of a file. +/** + * \brief Helper class for the construction of file names based on name, index and extension. + * + * Optionally, the file name can also handle node ID for distributed systems. + * + * The following example demonstrates the use of FileName. + * + * \par Example + * \include FileNameExample.cpp + * \par Output + * \include FileNameExample.out + */ class FileName { public: - /// \brief Basic constructor. - /// - /// Constructs an empty filename object. + /** + * \brief Basic constructor. + * + * Sets no file name base, index to zero and index digits count to five; + */ FileName(); - + + /** + * \brief Constructor with file name base parameter. + * + * The index is set to zero and index digits count to five. + * + * @param fileNameBase File name base. + */ FileName( const String& fileNameBase ); - - FileName( const String& fileNameBase, + + /** + * \brief Constructor with file name base and file name extension. + * + * The index is set to zero and index digits count to five. + * + * @param fileNameBase File name base. + * @param extension File name extension. + */ + FileName( const String& fileNameBase, const String& extension ); - - /// \brief Sets the base name of given file. - /// - /// Sets \e fileNameBase as the base name of given file. - /// @param fileNameBase String that specifies new name of file. + + /** + * \brief Sets the file name base. + * + * @param fileNameBase String that specifies the new file name base. + */ void setFileNameBase( const String& fileNameBase ); - /// \brief Sets the extension of given file. - /// - /// Sets \e extension as suffix of a file name. - /// @param extension A String that specifies extension of file (without dot). - /// Suffix of a file name. E.g. doc, xls, tnl. + /** + * \brief Sets the file name extension. + * + * @param extension A String that specifies the new extension of file without dot. + */ void setExtension( const String& extension ); - /// \brief Sets index for given file. - /// - /// Sets \e index after the base name of given file. - /// @param index Integer - number of maximum 5(default) digits. - /// (Number of digits can be changed with \ref setDigitsCount). - void setIndex( const int index ); - - /// \brief Sets number of digits for index of given file. - /// - /// @param digitsCount Integer - number of digits. - void setDigitsCount( const int digitsCount ); - - void setDistributedSystemNodeId( int nodeId ); - + /** + * \brief Sets index of the file name. + * + * @param index Index of the file name. + */ + void setIndex( const size_t index ); + + /** + * \brief Sets number of digits for index of the file name. + * + * @param digitsCount Number of digits. It is 5 by default. + */ + void setDigitsCount( const size_t digitsCount ); + + /** + * \brief Sets the distributed system node ID as integer, for example MPI process ID. + * + * @param nodeId Node ID. + * + * See the following example: + * + * \par Example + * \include FileNameExampleDistributedSystemNodeId.cpp + * \par Output + * \include FileNameExampleDistributedSystemNodeId.out + */ + void setDistributedSystemNodeId( size_t nodeId ); + + /** + * \brief Sets the distributed system node ID in a form of Cartesian coordinates. + * + * @tparam Coordinates Type of Cartesian coordinates. It is Containers::StaticVector usually. + * @param nodeId Node ID in a form of Cartesian coordinates. + * + * See the following example: + * + * \par Example + * \include FileNameExampleDistributedSystemNodeCoordinates.cpp + * \par Output + * \include FileNameExampleDistributedSystemNodeCoordinates.out + * + */ template< typename Coordinates > - void setDistributedSystemNodeId( const Coordinates& nodeId ); - - /// \brief Creates appropriate name for given file. - /// - /// Creates particular file name using \e fileNameBase, \e digitsCount, - /// \e index and \e extension. + void setDistributedSystemNodeCoordinates( const Coordinates& nodeId ); + + /** + * \brief Resets the distributed system node ID. + */ + void resetDistributedSystemNodeId(); + + /** + * \brief Returns complete file name. + * + * @return String with the complete file name. + */ String getFileName(); protected: - + String fileNameBase, extension, distributedSystemNodeId; - - int index, digitsCount; + + size_t index, digitsCount; }; +/** + * \brief Returns extension of given file name, i.e. part after the last dot. + * + * @param fileName Input file name. + * + * @return Extension of the given file name. + */ +String getFileExtension( const String fileName ); + +/** + * \brief Cuts off the file extension. + * + * @param file_name Input file name. + * @return String with the file name without extension. + */ +String removeFileNameExtension( String fileName ); + } // namespace TNL #include <TNL/FileName.hpp> diff --git a/src/TNL/FileName.hpp b/src/TNL/FileName.hpp index 4cda1fda29d5b4f74c7368ec55efc60321fdac43..5fdbf1b3f21debfd672d0e63f7ebf5c27c0b6e57 100644 --- a/src/TNL/FileName.hpp +++ b/src/TNL/FileName.hpp @@ -17,6 +17,8 @@ #include <TNL/String.h> #include <TNL/Math.h> +#include "FileName.h" + namespace TNL { inline FileName::FileName() @@ -50,28 +52,28 @@ inline void FileName::setExtension( const String& extension ) this->extension = extension; } -inline void FileName::setIndex( const int index ) +inline void FileName::setIndex( const size_t index ) { this->index = index; } -inline void FileName::setDigitsCount( const int digitsCount ) +inline void FileName::setDigitsCount( const size_t digitsCount ) { this->digitsCount = digitsCount; } -inline void FileName::setDistributedSystemNodeId( int nodeId ) +inline void FileName::setDistributedSystemNodeId( size_t nodeId ) { - this->distributedSystemNodeId = "-"; + this->distributedSystemNodeId = "-@"; this->distributedSystemNodeId += convertToString( nodeId ); } template< typename Coordinates > void FileName:: -setDistributedSystemNodeId( const Coordinates& nodeId ) +setDistributedSystemNodeCoordinates( const Coordinates& nodeId ) { - this->distributedSystemNodeId = "-"; + this->distributedSystemNodeId = "-@"; this->distributedSystemNodeId += convertToString( nodeId[ 0 ] ); for( int i = 1; i < nodeId.getSize(); i++ ) { @@ -80,6 +82,13 @@ setDistributedSystemNodeId( const Coordinates& nodeId ) } } +void +FileName:: +resetDistributedSystemNodeId() +{ + this->distributedSystemNodeId = ""; +} + inline String FileName::getFileName() { std::stringstream stream; @@ -96,16 +105,17 @@ inline String getFileExtension( const String fileName ) { const int size = fileName.getLength(); int i = 1; - while( fileName[ size - i ] != '.' && size > i ) i++; + while( fileName[ size - i ] != '.' && i < size ) i++; return fileName.substr( size - i + 1 ); } -inline void removeFileExtension( String& fileName ) +inline String removeFileNameExtension( String fileName ) { const int size = fileName.getLength(); int i = 1; while( fileName[ size - i ] != '.' && size > i ) i++; fileName = fileName.substr( 0, size - i + 1 ); + return fileName; } } // namespace TNL diff --git a/src/TNL/File_impl.h b/src/TNL/File_impl.h deleted file mode 100644 index 03c3f0d4a23cb8ba7a4972e09c0846f03bb39503..0000000000000000000000000000000000000000 --- a/src/TNL/File_impl.h +++ /dev/null @@ -1,277 +0,0 @@ -/*************************************************************************** - File_impl.h - description - ------------------- - begin : Mar 5, Oct 2016 - copyright : (C) 2016 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -#include <memory> -#include <iostream> - -#include <TNL/File.h> -#include <TNL/Assert.h> -#include <TNL/Exceptions/CudaSupportMissing.h> -#include <TNL/Exceptions/MICSupportMissing.h> -#include <TNL/Exceptions/FileSerializationError.h> -#include <TNL/Exceptions/FileDeserializationError.h> - -namespace TNL { - -inline bool File::open( const String& fileName, const IOMode mode ) -{ - // enable exceptions - file.exceptions( std::fstream::failbit | std::fstream::badbit | std::fstream::eofbit ); - - close(); - - if( mode == IOMode::read ) - file.open( fileName.getString(), std::ios::binary | std::ios::in ); - else - file.open( fileName.getString(), std::ios::binary | std::ios::out ); - - this->fileName = fileName; - if( ! file.good() ) { - std::cerr << "I am not able to open the file " << fileName << ". "; - return false; - } - return true; -} - -inline bool File::close() -{ - if( file.is_open() ) { - file.close(); - if( ! file.good() ) { - std::cerr << "I was not able to close the file " << fileName << " properly!" << std::endl; - return false; - } - } - // reset all attributes - fileName = ""; - return true; -} - -template< typename Type, typename Device > -bool File::read( Type* buffer ) -{ - return read< Type, Device >( buffer, 1 ); -} - -template< typename Type, typename Device > -bool File::write( const Type* buffer ) -{ - return write< Type, Device >( buffer, 1 ); -} - -template< typename Type, typename Device > -bool File::read( Type* buffer, std::streamsize elements ) -{ - TNL_ASSERT_GE( elements, 0, "Number of elements to read must be non-negative." ); - - if( ! elements ) - return true; - - return read_impl< Type, Device >( buffer, elements ); -} - -// Host -template< typename Type, - typename Device, - typename > -bool File::read_impl( Type* buffer, std::streamsize elements ) -{ - file.read( reinterpret_cast<char*>(buffer), sizeof(Type) * elements ); - return true; -} - -// Cuda -template< typename Type, - typename Device, - typename, typename > -bool File::read_impl( Type* buffer, std::streamsize elements ) -{ -#ifdef HAVE_CUDA - const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements ); - using BaseType = typename std::remove_cv< Type >::type; - std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; - - std::streamsize readElements = 0; - while( readElements < elements ) - { - const std::streamsize transfer = std::min( elements - readElements, host_buffer_size ); - file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer ); - cudaMemcpy( (void*) &buffer[ readElements ], - (void*) host_buffer.get(), - transfer * sizeof( Type ), - cudaMemcpyHostToDevice ); - TNL_CHECK_CUDA_DEVICE; - readElements += transfer; - } - return true; -#else - throw Exceptions::CudaSupportMissing(); -#endif -} - -// MIC -template< typename Type, - typename Device, - typename, typename, typename > -bool File::read_impl( Type* buffer, std::streamsize elements ) -{ -#ifdef HAVE_MIC - const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements ); - using BaseType = typename std::remove_cv< Type >::type; - std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; - - std::streamsize readElements = 0; - while( readElements < elements ) - { - const std::streamsize transfer = std::min( elements - readElements, host_buffer_size ); - file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer ); - - Devices::MICHider<Type> device_buff; - device_buff.pointer=buffer; - #pragma offload target(mic) in(device_buff,readElements) in(host_buffer:length(transfer)) - { - /* - for(int i=0;i<transfer;i++) - device_buff.pointer[readElements+i]=host_buffer[i]; - */ - memcpy(&(device_buff.pointer[readElements]), host_buffer.get(), transfer*sizeof(Type) ); - } - - readElements += transfer; - } - free( host_buffer ); - return true; -#else - throw Exceptions::MICSupportMissing(); -#endif -} - -template< class Type, typename Device > -bool File::write( const Type* buffer, std::streamsize elements ) -{ - TNL_ASSERT_GE( elements, 0, "Number of elements to write must be non-negative." ); - - if( ! elements ) - return true; - - return write_impl< Type, Device >( buffer, elements ); -} - -// Host -template< typename Type, - typename Device, - typename > -bool File::write_impl( const Type* buffer, std::streamsize elements ) -{ - file.write( reinterpret_cast<const char*>(buffer), sizeof(Type) * elements ); - return true; -} - -// Cuda -template< typename Type, - typename Device, - typename, typename > -bool File::write_impl( const Type* buffer, std::streamsize elements ) -{ -#ifdef HAVE_CUDA - const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements ); - using BaseType = typename std::remove_cv< Type >::type; - std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; - - std::streamsize writtenElements = 0; - while( writtenElements < elements ) - { - const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size ); - cudaMemcpy( (void*) host_buffer.get(), - (void*) &buffer[ writtenElements ], - transfer * sizeof(Type), - cudaMemcpyDeviceToHost ); - TNL_CHECK_CUDA_DEVICE; - file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer ); - writtenElements += transfer; - } - return true; -#else - throw Exceptions::CudaSupportMissing(); -#endif -} - -// MIC -template< typename Type, - typename Device, - typename, typename, typename > -bool File::write_impl( const Type* buffer, std::streamsize elements ) -{ -#ifdef HAVE_MIC - const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements ); - using BaseType = typename std::remove_cv< Type >::type; - std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; - - std::streamsize writtenElements = 0; - while( this->writtenElements < elements ) - { - const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size ); - - Devices::MICHider<const Type> device_buff; - device_buff.pointer=buffer; - #pragma offload target(mic) in(device_buff,writtenElements) out(host_buffer:length(transfer)) - { - //THIS SHOULD WORK... BUT NOT WHY? - /*for(int i=0;i<transfer;i++) - host_buffer[i]=device_buff.pointer[writtenElements+i]; - */ - - memcpy(host_buffer.get(), &(device_buff.pointer[writtenElements]), transfer*sizeof(Type) ); - } - - file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer ); - writtenElements += transfer; - } - return true; -#else - throw Exceptions::MICSupportMissing(); -#endif -} - -inline bool fileExists( const String& fileName ) -{ - std::fstream file; - file.open( fileName.getString(), std::ios::in ); - return ! file.fail(); -} - - -// serialization of strings -inline File& operator<<( File& file, const std::string& str ) -{ - const int len = str.size(); - if( ! file.write( &len ) ) - throw Exceptions::FileSerializationError( getType< int >(), file.getFileName() ); - if( ! file.write( str.c_str(), len ) ) - throw Exceptions::FileSerializationError( "String", file.getFileName() ); - return file; -} - -// deserialization of strings -inline File& operator>>( File& file, std::string& str ) -{ - int length; - if( ! file.read( &length ) ) - throw Exceptions::FileDeserializationError( getType< int >(), file.getFileName() ); - char buffer[ length ]; - if( length && ! file.read( buffer, length ) ) - throw Exceptions::FileDeserializationError( "String", file.getFileName() ); - str.assign( buffer, length ); - return file; -} - -} // namespace TNL diff --git a/src/TNL/Functions/MeshFunction.h b/src/TNL/Functions/MeshFunction.h index 9d67808e1ec2f5b827bc346fe531841195ffee57..1850f4fb200ab43c3360385fe7ac9d321ed6d88f 100644 --- a/src/TNL/Functions/MeshFunction.h +++ b/src/TNL/Functions/MeshFunction.h @@ -147,11 +147,11 @@ class MeshFunction : RealType getMaxNorm() const; - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool boundLoad( File& file ); + void boundLoad( File& file ); bool write( const String& fileName, const String& format = "vtk", diff --git a/src/TNL/Functions/MeshFunction_impl.h b/src/TNL/Functions/MeshFunction_impl.h index e9426084e0de39ff4a5cecb69f478310583477db..107503ca4c97e5c59db73bfdae7f6f95f2922a63 100644 --- a/src/TNL/Functions/MeshFunction_impl.h +++ b/src/TNL/Functions/MeshFunction_impl.h @@ -15,6 +15,7 @@ #include <TNL/Functions/MeshFunctionNormGetter.h> #include <TNL/Functions/MeshFunctionGnuplotWriter.h> #include <TNL/Functions/MeshFunctionVTKWriter.h> +#include <TNL/Exceptions/MeshFunctionDataMismatch.h> #pragma once @@ -164,8 +165,7 @@ setup( const MeshPointer& meshPointer, if( parameters.checkParameter( prefix + "file" ) ) { String fileName = parameters.getParameter< String >( prefix + "file" ); - if( ! this->load( fileName ) ) - return false; + this->load( fileName ); } else { @@ -468,47 +468,39 @@ getMaxNorm() const template< typename Mesh, int MeshEntityDimension, typename Real > -bool +void MeshFunction< Mesh, MeshEntityDimension, Real >:: save( File& file ) const { TNL_ASSERT_EQ( this->data.getSize(), this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(), "Size of the mesh function data does not match the mesh." ); - if( ! Object::save( file ) ) - return false; - return this->data.save( file ); + Object::save( file ); + this->data.save( file ); } template< typename Mesh, int MeshEntityDimension, typename Real > -bool +void MeshFunction< Mesh, MeshEntityDimension, Real >:: load( File& file ) { - if( ! Object::load( file ) ) - return false; - if( ! this->data.load( file ) ) - return false; + Object::load( file ); + this->data.load( file ); const IndexType meshSize = this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(); if( this->data.getSize() != meshSize ) - { - std::cerr << "Size of the data loaded to the mesh function (" << this->data.getSize() << ") does not fit with the mesh size (" << meshSize << ")." << std::endl; - return false; - } - return true; + throw Exceptions::MeshFunctionDataMismatch( this->data.getSize(), " Does not fit with mesh size " + convertToString( meshSize ) + "." ); } template< typename Mesh, int MeshEntityDimension, typename Real > -bool +void MeshFunction< Mesh, MeshEntityDimension, Real >:: boundLoad( File& file ) { - if( ! Object::load( file ) ) - return false; - return this->data.boundLoad( file ); + Object::load( file ); + this->data.boundLoad( file ); } template< typename Mesh, diff --git a/src/TNL/Functions/VectorField.h b/src/TNL/Functions/VectorField.h index 46fdffcba1ffe34d1a57f75ad8b6b1474fbefb5e..c7d5bf553ac01cf55a63c0cff75d5d0a323d5d3b 100644 --- a/src/TNL/Functions/VectorField.h +++ b/src/TNL/Functions/VectorField.h @@ -270,34 +270,25 @@ class VectorField< Size, MeshFunction< Mesh, MeshEntityDimension, Real > > return v; } - bool save( File& file ) const + void save( File& file ) const { - if( ! Object::save( file ) ) - return false; + Object::save( file ); for( int i = 0; i < Size; i++ ) - if( ! vectorField[ i ]->save( file ) ) - return false; - return true; + vectorField[ i ]->save( file ); } - bool load( File& file ) + void load( File& file ) { - if( ! Object::load( file ) ) - return false; + Object::load( file ); for( int i = 0; i < Size; i++ ) - if( ! vectorField[ i ]->load( file ) ) - return false; - return true; + vectorField[ i ]->load( file ); } - bool boundLoad( File& file ) + void boundLoad( File& file ) { - if( ! Object::load( file ) ) - return false; + Object::load( file ); for( int i = 0; i < Size; i++ ) - if( ! vectorField[ i ]->boundLoad( file ) ) - return false; - return true; + vectorField[ i ]->boundLoad( file ); } bool write( const String& fileName, diff --git a/src/TNL/Matrices/AdEllpack.h b/src/TNL/Matrices/AdEllpack.h index f5fdc767346f9fbc90236f04ab000f3fdc20327b..bfe70b6cbba6f1c98558f7b59a21e98713d9fc6f 100644 --- a/src/TNL/Matrices/AdEllpack.h +++ b/src/TNL/Matrices/AdEllpack.h @@ -145,13 +145,13 @@ public: void vectorProduct( const InVector& inVector, OutVector& outVector ) const; - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/AdEllpack_impl.h b/src/TNL/Matrices/AdEllpack_impl.h index daab3b8cdc351459120436186cb3060aeee54d8f..0838bf09b7861f60a99415c20cbb5503cc028ae7 100644 --- a/src/TNL/Matrices/AdEllpack_impl.h +++ b/src/TNL/Matrices/AdEllpack_impl.h @@ -609,45 +609,41 @@ void AdEllpack< Real, Device, Index >::vectorProduct( const InVector& inVector, template< typename Real, typename Device, typename Index > -bool AdEllpack< Real, Device, Index >::save( File& file ) const +void AdEllpack< Real, Device, Index >::save( File& file ) const { - if( Sparse< Real, Device, Index >::save( file ) || - this->offset.save( file ) || - this->rowOffset.save( file ) || - this->localLoad.save( file ) || - this->reduceMap.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->offset.save( file ); + this->rowOffset.save( file ); + this->localLoad.save( file ); + this->reduceMap.save( file ); } template< typename Real, typename Device, typename Index > -bool AdEllpack< Real, Device, Index >::load( File& file ) +void AdEllpack< Real, Device, Index >::load( File& file ) { - if( Sparse< Real, Device, Index >::load( file ) || - this->offset.load( file ) || - this->rowOffset.load( file ) || - this->localLoad.load( file ) || - this->reduceMap.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->offset.load( file ); + this->rowOffset.load( file ); + this->localLoad.load( file ); + this->reduceMap.load( file ); } template< typename Real, typename Device, typename Index > -bool AdEllpack< Real, Device, Index >::save( const String& fileName ) const +void AdEllpack< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool AdEllpack< Real, Device, Index >::load( const String& fileName ) +void AdEllpack< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, @@ -872,8 +868,9 @@ bool AdEllpack< Real, Device, Index >::createArrays( warpList* list ) row++; this->reduceMap.setElement( i, row ); } - if( localLoad > this->totalLoad ) - std::cout << "Error localLoad!!" << std::endl; + // TODO: Fix, operator > is not defined for vectors + //if( localLoad > this->totalLoad ) + // std::cout << "Error localLoad!!" << std::endl; iteration++; warp = warp->next; } diff --git a/src/TNL/Matrices/BiEllpack.h b/src/TNL/Matrices/BiEllpack.h index b724a0ada17dc4efb2c1d0907054715107da01a4..93bfeabaa5814269c4329c70b7555cfc963b2c12 100644 --- a/src/TNL/Matrices/BiEllpack.h +++ b/src/TNL/Matrices/BiEllpack.h @@ -129,13 +129,13 @@ public: void reset(); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/BiEllpackSymmetric.h b/src/TNL/Matrices/BiEllpackSymmetric.h index e44921fe837e7d0f0060df78af167c12ea1c102e..5e72d9b641480d70426d2fd75e186ff9a1aca851 100644 --- a/src/TNL/Matrices/BiEllpackSymmetric.h +++ b/src/TNL/Matrices/BiEllpackSymmetric.h @@ -118,13 +118,13 @@ public: void reset(); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/BiEllpackSymmetric_impl.h b/src/TNL/Matrices/BiEllpackSymmetric_impl.h index 5b6f94b57b571963f5ba18c3c4c7e8fb7700fa99..69d32a4722dfeadfcb9182262508b28014ce4a1b 100644 --- a/src/TNL/Matrices/BiEllpackSymmetric_impl.h +++ b/src/TNL/Matrices/BiEllpackSymmetric_impl.h @@ -677,44 +677,40 @@ template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpackSymmetric< Real, Device, Index, StripSize >::save( File& file ) const +void BiEllpackSymmetric< Real, Device, Index, StripSize >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file ) || - ! this->groupPointers.save( file ) || - ! this->rowPermArray.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->groupPointers.save( file ); + this->rowPermArray.save( file ); } template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpackSymmetric< Real, Device, Index, StripSize >::load( File& file ) +void BiEllpackSymmetric< Real, Device, Index, StripSize >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file ) || - ! this->groupPointers.load( file ) || - ! this->rowPermArray.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->groupPointers.load( file ); + this->rowPermArray.load( file ); } template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpackSymmetric< Real, Device, Index, StripSize >::save( const String& fileName ) const +void BiEllpackSymmetric< Real, Device, Index, StripSize >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpackSymmetric< Real, Device, Index, StripSize >::load( const String& fileName ) +void BiEllpackSymmetric< Real, Device, Index, StripSize >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/BiEllpack_impl.h b/src/TNL/Matrices/BiEllpack_impl.h index ea5e1efb9463915ec724b28b38abbfe64ac596b0..31dbd2bb3f8f5fb178ade2eff590873fe27d6a18 100644 --- a/src/TNL/Matrices/BiEllpack_impl.h +++ b/src/TNL/Matrices/BiEllpack_impl.h @@ -681,44 +681,40 @@ template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpack< Real, Device, Index, StripSize >::save( File& file ) const +void BiEllpack< Real, Device, Index, StripSize >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file ) || - ! this->groupPointers.save( file ) || - ! this->rowPermArray.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->groupPointers.save( file ); + this->rowPermArray.save( file ); } template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpack< Real, Device, Index, StripSize >::load( File& file ) +void BiEllpack< Real, Device, Index, StripSize >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file ) || - ! this->groupPointers.load( file ) || - ! this->rowPermArray.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->groupPointers.load( file ); + this->rowPermArray.load( file ); } template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpack< Real, Device, Index, StripSize >::save( const String& fileName ) const +void BiEllpack< Real, Device, Index, StripSize >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index, int StripSize > -bool BiEllpack< Real, Device, Index, StripSize >::load( const String& fileName ) +void BiEllpack< Real, Device, Index, StripSize >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/CSR.h b/src/TNL/Matrices/CSR.h index 10b7184569e80ceaea1b560dd39142e9098c672b..4f42c1bacdc64da76e189a344e655bd8b44d63e6 100644 --- a/src/TNL/Matrices/CSR.h +++ b/src/TNL/Matrices/CSR.h @@ -84,7 +84,7 @@ public: IndexType getRowLengthFast( const IndexType row ) const; IndexType getNonZeroRowLength( const IndexType row ) const; - + __cuda_callable__ IndexType getNonZeroRowLengthFast( const IndexType row ) const; @@ -191,13 +191,13 @@ public: typename = typename Enabler< Device2 >::type > CSR& operator=( const CSR< Real2, Device2, Index2 >& matrix ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/CSR_impl.h b/src/TNL/Matrices/CSR_impl.h index 0a682a9dc25cbea51617bb8c5ab89b0a76b0d846..5fe617b5430ca870a3857f5a1545e1a038163c7c 100644 --- a/src/TNL/Matrices/CSR_impl.h +++ b/src/TNL/Matrices/CSR_impl.h @@ -615,39 +615,35 @@ CSR< Real, Device, Index >::operator=( const CSR< Real2, Device2, Index2 >& matr template< typename Real, typename Device, typename Index > -bool CSR< Real, Device, Index >::save( File& file ) const +void CSR< Real, Device, Index >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file ) || - ! this->rowPointers.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->rowPointers.save( file ); } template< typename Real, typename Device, typename Index > -bool CSR< Real, Device, Index >::load( File& file ) +void CSR< Real, Device, Index >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file ) || - ! this->rowPointers.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->rowPointers.load( file ); } template< typename Real, typename Device, typename Index > -bool CSR< Real, Device, Index >::save( const String& fileName ) const +void CSR< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool CSR< Real, Device, Index >::load( const String& fileName ) +void CSR< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/ChunkedEllpack.h b/src/TNL/Matrices/ChunkedEllpack.h index ff889a49fe0d7b71c4e1fb1e6e1165e7d8970b86..928dcd8d1f6ad7303d913400f269a0b85aa22e61 100644 --- a/src/TNL/Matrices/ChunkedEllpack.h +++ b/src/TNL/Matrices/ChunkedEllpack.h @@ -241,13 +241,13 @@ public: typename = typename Enabler< Device2 >::type > ChunkedEllpack& operator=( const ChunkedEllpack< Real2, Device2, Index2 >& matrix ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/ChunkedEllpack_impl.h b/src/TNL/Matrices/ChunkedEllpack_impl.h index ff1dd0742f1f2010b441206395e5cf278deaf37e..e3a686264dd3defe5921708fbc5373bc19b0b5ef 100644 --- a/src/TNL/Matrices/ChunkedEllpack_impl.h +++ b/src/TNL/Matrices/ChunkedEllpack_impl.h @@ -1284,45 +1284,41 @@ ChunkedEllpack< Real, Device, Index >::operator=( const ChunkedEllpack< Real2, D template< typename Real, typename Device, typename Index > -bool ChunkedEllpack< Real, Device, Index >::save( File& file ) const +void ChunkedEllpack< Real, Device, Index >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file ) || - ! this->rowToChunkMapping.save( file ) || - ! this->rowToSliceMapping.save( file ) || - ! this->rowPointers.save( file ) || - ! this->slices.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->rowToChunkMapping.save( file ); + this->rowToSliceMapping.save( file ); + this->rowPointers.save( file ); + this->slices.save( file ); } template< typename Real, typename Device, typename Index > -bool ChunkedEllpack< Real, Device, Index >::load( File& file ) +void ChunkedEllpack< Real, Device, Index >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file ) || - ! this->rowToChunkMapping.load( file ) || - ! this->rowToSliceMapping.load( file ) || - ! this->rowPointers.load( file ) || - ! this->slices.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->rowToChunkMapping.load( file ); + this->rowToSliceMapping.load( file ); + this->rowPointers.load( file ); + this->slices.load( file ); } template< typename Real, typename Device, typename Index > -bool ChunkedEllpack< Real, Device, Index >::save( const String& fileName ) const +void ChunkedEllpack< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool ChunkedEllpack< Real, Device, Index >::load( const String& fileName ) +void ChunkedEllpack< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/Dense.h b/src/TNL/Matrices/Dense.h index 351e8a8c7631feb1cf952cb8dd57762723a29bfc..e9601a9face2e7a754c25a1b8a397aae79da1a27 100644 --- a/src/TNL/Matrices/Dense.h +++ b/src/TNL/Matrices/Dense.h @@ -200,13 +200,13 @@ public: typename = typename Enabler< Device2 >::type > Dense& operator=( const Dense< Real2, Device2, Index2 >& matrix ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/Dense_impl.h b/src/TNL/Matrices/Dense_impl.h index d204c3a0a6b48bb2c62d6802c48d636034ed320e..3844751d4638561b883d666d507fbf4ed444de71 100644 --- a/src/TNL/Matrices/Dense_impl.h +++ b/src/TNL/Matrices/Dense_impl.h @@ -936,37 +936,33 @@ Dense< Real, Device, Index >::operator=( const Dense< Real2, Device2, Index2 >& template< typename Real, typename Device, typename Index > -bool Dense< Real, Device, Index >::save( const String& fileName ) const +void Dense< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool Dense< Real, Device, Index >::load( const String& fileName ) +void Dense< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, typename Device, typename Index > -bool Dense< Real, Device, Index >::save( File& file ) const +void Dense< Real, Device, Index >::save( File& file ) const { - if( ! Matrix< Real, Device, Index >::save( file ) ) - return false; - return true; + Matrix< Real, Device, Index >::save( file ); } template< typename Real, typename Device, typename Index > -bool Dense< Real, Device, Index >::load( File& file ) +void Dense< Real, Device, Index >::load( File& file ) { - if( ! Matrix< Real, Device, Index >::load( file ) ) - return false; - return true; + Matrix< Real, Device, Index >::load( file ); } template< typename Real, diff --git a/src/TNL/Matrices/DistributedSpMV.h b/src/TNL/Matrices/DistributedSpMV.h index a96f028bcbb1bb6420419debf6ff019d6615cef7..f70773c1fc6afd998e833223a97cbef3c87c1476 100644 --- a/src/TNL/Matrices/DistributedSpMV.h +++ b/src/TNL/Matrices/DistributedSpMV.h @@ -199,8 +199,7 @@ public: else { auto outVectorView = outVector.getLocalVectorView(); const Pointers::DevicePointer< const MatrixType > localMatrixPointer( localMatrix ); - using InView = Containers::DistributedVectorView< const typename InVector::RealType, typename InVector::DeviceType, typename InVector::IndexType, typename InVector::CommunicatorType >; - const InView inView( inVector ); + const auto inView = inVector.getConstView(); // matrix-vector multiplication using local-only rows auto kernel1 = [=] __cuda_callable__ ( IndexType i, const MatrixType* localMatrix ) mutable diff --git a/src/TNL/Matrices/Ellpack.h b/src/TNL/Matrices/Ellpack.h index e19010dafa9f47a36f669f9b5832d31c7b289d10..100685e7b3fc43cc566d589cc64ed8e82c7df940 100644 --- a/src/TNL/Matrices/Ellpack.h +++ b/src/TNL/Matrices/Ellpack.h @@ -186,13 +186,13 @@ public: typename = typename Enabler< Device2 >::type > Ellpack& operator=( const Ellpack< Real2, Device2, Index2 >& matrix ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/EllpackSymmetric.h b/src/TNL/Matrices/EllpackSymmetric.h index 0720d9d5293f5190edfb3411807ae29b380d91d3..b150bc4d9b9a6f0b764192ea0c2b6df2d458558a 100644 --- a/src/TNL/Matrices/EllpackSymmetric.h +++ b/src/TNL/Matrices/EllpackSymmetric.h @@ -158,13 +158,13 @@ class EllpackSymmetric : public Sparse< Real, Device, Index > Vector& x, const RealType& omega = 1.0 ) const; - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/EllpackSymmetricGraph.h b/src/TNL/Matrices/EllpackSymmetricGraph.h index 3a282c796be439209184023fb76aa692ff1e4294..85c7e49b0c46b5dde10b31f6c52d18a28360d7ed 100644 --- a/src/TNL/Matrices/EllpackSymmetricGraph.h +++ b/src/TNL/Matrices/EllpackSymmetricGraph.h @@ -157,13 +157,13 @@ class EllpackSymmetricGraph : public Sparse< Real, Device, Index > bool rearrangeMatrix( bool verbose ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h index 799d07281e62ae441c39162ee2fc5271997effac..8f038742bc4a261662a5b272ece80c857b16ed05 100644 --- a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h +++ b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h @@ -743,37 +743,35 @@ void EllpackSymmetricGraph< Real, Device, Index >::vectorProduct( const InVector template< typename Real, typename Device, typename Index > -bool EllpackSymmetricGraph< Real, Device, Index >::save( File& file ) const +void EllpackSymmetricGraph< Real, Device, Index >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.write( &this->rowLengths ) ) return false; - return true; + Sparse< Real, Device, Index >::save( file); + file.save( &this->rowLengths ); } template< typename Real, typename Device, typename Index > -bool EllpackSymmetricGraph< Real, Device, Index >::load( File& file ) +void EllpackSymmetricGraph< Real, Device, Index >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.read( &this->rowLengths ) ) return false; - return true; + Sparse< Real, Device, Index >::load( file); + file.load( &this->rowLengths ); } template< typename Real, typename Device, typename Index > -bool EllpackSymmetricGraph< Real, Device, Index >::save( const String& fileName ) const +void EllpackSymmetricGraph< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool EllpackSymmetricGraph< Real, Device, Index >::load( const String& fileName ) +void EllpackSymmetricGraph< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/EllpackSymmetric_impl.h b/src/TNL/Matrices/EllpackSymmetric_impl.h index 42202a883c0c887317aaf68904dfa0bddf27a646..fed7f7669c4f33abdadf4b91f30f8ec5e14b1e23 100644 --- a/src/TNL/Matrices/EllpackSymmetric_impl.h +++ b/src/TNL/Matrices/EllpackSymmetric_impl.h @@ -537,37 +537,35 @@ bool EllpackSymmetric< Real, Device, Index > :: performSORIteration( const Vecto template< typename Real, typename Device, typename Index > -bool EllpackSymmetric< Real, Device, Index >::save( File& file ) const +void EllpackSymmetric< Real, Device, Index >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.write( &this->rowLengths ) ) return false; - return true; + Sparse< Real, Device, Index >::save( file); + file.save( &this->rowLengths ); } template< typename Real, typename Device, typename Index > -bool EllpackSymmetric< Real, Device, Index >::load( File& file ) +void EllpackSymmetric< Real, Device, Index >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.read( &this->rowLengths ) ) return false; - return true; + Sparse< Real, Device, Index >::load( file); + file.load( &this->rowLengths ); } template< typename Real, typename Device, typename Index > -bool EllpackSymmetric< Real, Device, Index >::save( const String& fileName ) const +void EllpackSymmetric< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool EllpackSymmetric< Real, Device, Index >::load( const String& fileName ) +void EllpackSymmetric< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/Ellpack_impl.h b/src/TNL/Matrices/Ellpack_impl.h index 7c2a3b6f00fcc428d2fd422a069c5357497a4c9e..6c06fdd98beb4bba90bc0a16ddffacc998458ee2 100644 --- a/src/TNL/Matrices/Ellpack_impl.h +++ b/src/TNL/Matrices/Ellpack_impl.h @@ -713,37 +713,35 @@ Ellpack< Real, Device, Index >::operator=( const Ellpack< Real2, Device2, Index2 template< typename Real, typename Device, typename Index > -bool Ellpack< Real, Device, Index >::save( File& file ) const +void Ellpack< Real, Device, Index >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.write( &this->rowLengths ) ) return false; - return true; + Sparse< Real, Device, Index >::save( file); + file.save( &this->rowLengths ); } template< typename Real, typename Device, typename Index > -bool Ellpack< Real, Device, Index >::load( File& file ) +void Ellpack< Real, Device, Index >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.read( &this->rowLengths ) ) return false; - return true; + Sparse< Real, Device, Index >::load( file); + file.load( &this->rowLengths ); } template< typename Real, typename Device, typename Index > -bool Ellpack< Real, Device, Index >::save( const String& fileName ) const +void Ellpack< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool Ellpack< Real, Device, Index >::load( const String& fileName ) +void Ellpack< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/Matrix.h b/src/TNL/Matrices/Matrix.h index 99f4bf1d63f7a78eb659794fde844196fdfbac1d..e8677b8532518dda1744070b7f7bf29c0c01f1cb 100644 --- a/src/TNL/Matrices/Matrix.h +++ b/src/TNL/Matrices/Matrix.h @@ -105,9 +105,9 @@ public: template< typename Matrix > bool operator != ( const Matrix& matrix ) const; - virtual bool save( File& file ) const; + virtual void save( File& file ) const; - virtual bool load( File& file ); + virtual void load( File& file ); virtual void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/Matrix_impl.h b/src/TNL/Matrices/Matrix_impl.h index cb685917fd676e0d062f400ab0fd42836dbe1e05..815e0e7d82c8406369665e947d4fa9de414fba89 100644 --- a/src/TNL/Matrices/Matrix_impl.h +++ b/src/TNL/Matrices/Matrix_impl.h @@ -43,7 +43,7 @@ template< typename Real, void Matrix< Real, Device, Index >::getCompressedRowLengths( CompressedRowLengthsVector& rowLengths ) const { rowLengths.setSize( this->getRows() ); - getCompressedRowLengths( CompressedRowLengthsVectorView( rowLengths ) ); + getCompressedRowLengths( rowLengths.getView() ); } template< typename Real, @@ -142,27 +142,23 @@ bool Matrix< Real, Device, Index >::operator != ( const MatrixT& matrix ) const template< typename Real, typename Device, typename Index > -bool Matrix< Real, Device, Index >::save( File& file ) const +void Matrix< Real, Device, Index >::save( File& file ) const { - if( ! Object::save( file ) || - ! file.write( &this->rows ) || - ! file.write( &this->columns ) || - ! this->values.save( file ) ) - return false; - return true; + Object::save( file ); + file.save( &this->rows ); + file.save( &this->columns ); + this->values.save( file ); } template< typename Real, typename Device, typename Index > -bool Matrix< Real, Device, Index >::load( File& file ) +void Matrix< Real, Device, Index >::load( File& file ) { - if( ! Object::load( file ) || - ! file.read( &this->rows ) || - ! file.read( &this->columns ) || - ! this->values.load( file ) ) - return false; - return true; + Object::load( file ); + file.load( &this->rows ); + file.load( &this->columns ); + this->values.load( file ); } template< typename Real, diff --git a/src/TNL/Matrices/Multidiagonal.h b/src/TNL/Matrices/Multidiagonal.h index cfa798e7a254916455db5c896640495bdbc504c1..969a1e0aaaeac9412979a9626d08ed173b0b82fa 100644 --- a/src/TNL/Matrices/Multidiagonal.h +++ b/src/TNL/Matrices/Multidiagonal.h @@ -192,13 +192,13 @@ public: typename = typename Enabler< Device2 >::type > Multidiagonal& operator=( const Multidiagonal< Real2, Device2, Index2 >& matrix ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/Multidiagonal_impl.h b/src/TNL/Matrices/Multidiagonal_impl.h index bd4c24691252ac425466906c549168248aca8244..860b3717ca94a1a38d7b48f2dcb4d9060ccfd11c 100644 --- a/src/TNL/Matrices/Multidiagonal_impl.h +++ b/src/TNL/Matrices/Multidiagonal_impl.h @@ -650,39 +650,37 @@ Multidiagonal< Real, Device, Index >::operator=( const Multidiagonal< Real2, Dev template< typename Real, typename Device, typename Index > -bool Multidiagonal< Real, Device, Index >::save( File& file ) const +void Multidiagonal< Real, Device, Index >::save( File& file ) const { - if( ! Matrix< Real, Device, Index >::save( file ) ) return false; - if( ! this->values.save( file ) ) return false; - if( ! this->diagonalsShift.save( file ) ) return false; - return true; + Matrix< Real, Device, Index >::save( file ); + this->values.save( file ); + this->diagonalsShift.save( file ); } template< typename Real, typename Device, typename Index > -bool Multidiagonal< Real, Device, Index >::load( File& file ) +void Multidiagonal< Real, Device, Index >::load( File& file ) { - if( ! Matrix< Real, Device, Index >::load( file ) ) return false; - if( ! this->values.load( file ) ) return false; - if( ! this->diagonalsShift.load( file ) ) return false; - return true; + Matrix< Real, Device, Index >::load( file ); + this->values.load( file ); + this->diagonalsShift.load( file ); } template< typename Real, typename Device, typename Index > -bool Multidiagonal< Real, Device, Index >::save( const String& fileName ) const +void Multidiagonal< Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool Multidiagonal< Real, Device, Index >::load( const String& fileName ) +void Multidiagonal< Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/SlicedEllpack.h b/src/TNL/Matrices/SlicedEllpack.h index 0fc9ccb0b2ca42bd2ec6441f9fe76cd661679f8e..b7302e55973eb699c80a2ed07cbdaae6cfa8d099 100644 --- a/src/TNL/Matrices/SlicedEllpack.h +++ b/src/TNL/Matrices/SlicedEllpack.h @@ -204,13 +204,13 @@ public: typename = typename Enabler< Device2 >::type > SlicedEllpack& operator=( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/SlicedEllpackSymmetric.h b/src/TNL/Matrices/SlicedEllpackSymmetric.h index d9abb0de2ef664fd4032e8e5b0e00203093eb250..550df75c43529ce909902389302221a8a0e8869c 100644 --- a/src/TNL/Matrices/SlicedEllpackSymmetric.h +++ b/src/TNL/Matrices/SlicedEllpackSymmetric.h @@ -173,13 +173,13 @@ class SlicedEllpackSymmetric : public Sparse< Real, Device, Index > Vector& x, const RealType& omega = 1.0 ) const; - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h b/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h index a2ab000957227a88a9655888cb417cea6498f56f..762b0a21e3383ed3c551ee8409e23e8da18d56f4 100644 --- a/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h +++ b/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h @@ -171,13 +171,13 @@ class SlicedEllpackSymmetricGraph : public Sparse< Real, Device, Index > Containers::Vector< Index, Device, Index > getRealRowLengths(); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); - bool save( const String& fileName ) const; + void save( const String& fileName ) const; - bool load( const String& fileName ); + void load( const String& fileName ); void print( std::ostream& str ) const; diff --git a/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h b/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h index 9f09a21c506bd08110bc8360e17d3bf1f3a4097c..dcd7ca3dc079c249ef45f2b0874faa622b1f329b 100644 --- a/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h +++ b/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h @@ -573,44 +573,40 @@ template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( File& file ) const +void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file ) || - ! this->slicePointers.save( file ) || - ! this->sliceRowLengths.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->slicePointers.save( file ); + this->sliceRowLengths.save( file ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( File& file ) +void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file ) || - ! this->slicePointers.load( file ) || - ! this->sliceRowLengths.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->slicePointers.load( file ); + this->sliceRowLengths.load( file ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( const String& fileName ) const +void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( const String& fileName ) +void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h b/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h index 402ac5a6c8128ab67bbf2393528fb3a2b58b9077..3a8e3cab4b8e874462c7f7695bab1b3693d4f8d4 100644 --- a/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h +++ b/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h @@ -622,44 +622,40 @@ template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( File& file ) const +void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file ) || - ! this->slicePointers.save( file ) || - ! this->sliceRowLengths.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->slicePointers.save( file ); + this->sliceRowLengths.save( file ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( File& file ) +void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file ) || - ! this->slicePointers.load( file ) || - ! this->sliceRowLengths.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->slicePointers.load( file ); + this->sliceRowLengths.load( file ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( const String& fileName ) const +void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( const String& fileName ) +void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/SlicedEllpack_impl.h b/src/TNL/Matrices/SlicedEllpack_impl.h index 4d7593d3f33a1e1140f87fd8eb876172e70e42a5..8e20c970e95611849d528d2f7d910c2a254a0f9e 100644 --- a/src/TNL/Matrices/SlicedEllpack_impl.h +++ b/src/TNL/Matrices/SlicedEllpack_impl.h @@ -704,44 +704,40 @@ template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpack< Real, Device, Index, SliceSize >::save( File& file ) const +void SlicedEllpack< Real, Device, Index, SliceSize >::save( File& file ) const { - if( ! Sparse< Real, Device, Index >::save( file ) || - ! this->slicePointers.save( file ) || - ! this->sliceCompressedRowLengths.save( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::save( file ); + this->slicePointers.save( file ); + this->sliceCompressedRowLengths.save( file ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpack< Real, Device, Index, SliceSize >::load( File& file ) +void SlicedEllpack< Real, Device, Index, SliceSize >::load( File& file ) { - if( ! Sparse< Real, Device, Index >::load( file ) || - ! this->slicePointers.load( file ) || - ! this->sliceCompressedRowLengths.load( file ) ) - return false; - return true; + Sparse< Real, Device, Index >::load( file ); + this->slicePointers.load( file ); + this->sliceCompressedRowLengths.load( file ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpack< Real, Device, Index, SliceSize >::save( const String& fileName ) const +void SlicedEllpack< Real, Device, Index, SliceSize >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index, int SliceSize > -bool SlicedEllpack< Real, Device, Index, SliceSize >::load( const String& fileName ) +void SlicedEllpack< Real, Device, Index, SliceSize >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Matrices/Sparse.h b/src/TNL/Matrices/Sparse.h index 069ade36cb989e18e1b6e1cc9821af5df50de8c1..7dc3798d22fa421655944f6ad6669725fece5e4c 100644 --- a/src/TNL/Matrices/Sparse.h +++ b/src/TNL/Matrices/Sparse.h @@ -48,9 +48,9 @@ class Sparse : public Matrix< Real, Device, Index > void reset(); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); void printStructure( std::ostream& str ) const; diff --git a/src/TNL/Matrices/Sparse_impl.h b/src/TNL/Matrices/Sparse_impl.h index cd57637cbd773dc2ce25a13ad9b39191a7d2507b..13b7ee7a933c936f75d41b58f9e83a5467dce1e6 100644 --- a/src/TNL/Matrices/Sparse_impl.h +++ b/src/TNL/Matrices/Sparse_impl.h @@ -88,25 +88,21 @@ void Sparse< Real, Device, Index >::reset() template< typename Real, typename Device, typename Index > -bool Sparse< Real, Device, Index >::save( File& file ) const +void Sparse< Real, Device, Index >::save( File& file ) const { - if( ! Matrix< Real, Device, Index >::save( file ) || - ! this->values.save( file ) || - ! this->columnIndexes.save( file ) ) - return false; - return true; + Matrix< Real, Device, Index >::save( file ); + this->values.save( file ); + this->columnIndexes.save( file ); } template< typename Real, typename Device, typename Index > -bool Sparse< Real, Device, Index >::load( File& file ) +void Sparse< Real, Device, Index >::load( File& file ) { - if( ! Matrix< Real, Device, Index >::load( file ) || - ! this->values.load( file ) || - ! this->columnIndexes.load( file ) ) - return false; - return true; + Matrix< Real, Device, Index >::load( file ); + this->values.load( file ); + this->columnIndexes.load( file ); } template< typename Real, diff --git a/src/TNL/Matrices/ThreePartVector.h b/src/TNL/Matrices/ThreePartVector.h index b492879bdec0fd9c92788c585dad6814e2693a02..6afc2dd114150da67084ffd9b4394c3c81574ab0 100644 --- a/src/TNL/Matrices/ThreePartVector.h +++ b/src/TNL/Matrices/ThreePartVector.h @@ -118,7 +118,7 @@ public: ThreePartVectorView< ConstReal, Device, Index > getConstView() { - return {left, middle, right}; + return {left.getConstView(), middle, right.getConstView()}; } // __cuda_callable__ diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h index 00342c7a948977c2c8c1acbdd313671050ca51a1..b9d3c5e24e7ad2c99a888c30e361711029bcb601 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h @@ -47,7 +47,7 @@ class DistributedGridIO< if(distrGrid==NULL) //not distributed { - return meshFunction.save(fileName); + meshFunction.save(fileName); } MeshType mesh=meshFunction.getMesh(); @@ -65,11 +65,7 @@ class DistributedGridIO< newMesh->setOrigin(origin+TNL::Containers::Scale(spaceSteps,localBegin)); File meshFile; - if( ! meshFile.open( fileName+String("-mesh-")+distrGrid->printProcessCoords()+String(".tnl"),IOMode::write) ) - { - std::cerr << "Failed to open mesh file for writing." << std::endl; - return false; - } + meshFile.open( fileName+String("-mesh-")+distrGrid->printProcessCoords()+String(".tnl"),File::Mode::Out ); newMesh->save( meshFile ); meshFile.close(); @@ -84,15 +80,11 @@ class DistributedGridIO< CopyEntitiesHelper<MeshFunctionType>::Copy(meshFunction,newMeshFunction,localBegin,zeroCoord,localSize); File file; - if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), IOMode::write ) ) - { - std::cerr << "Failed to open file for writing." << std::endl; - return false; - } - bool ret=newMeshFunction.save(file); + file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::Out ); + newMeshFunction.save(file); file.close(); - return ret; + return true; }; @@ -101,7 +93,8 @@ class DistributedGridIO< auto *distrGrid=meshFunction.getMesh().getDistributedMesh(); if(distrGrid==NULL) //not distributed { - return meshFunction.boundLoad(fileName); + meshFunction.boundLoad(fileName); + return true; } MeshType mesh=meshFunction.getMesh(); @@ -126,16 +119,12 @@ class DistributedGridIO< zeroCoord.setValue(0); File file; - if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), IOMode::read ) ) - { - std::cerr << "Failed to open file for reading." << std::endl; - return false; - } - bool result=newMeshFunction.boundLoad(file); + file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::In ); + newMeshFunction.boundLoad(file); file.close(); CopyEntitiesHelper<MeshFunctionType>::Copy(newMeshFunction,meshFunction,zeroCoord,localBegin,localSize); - return result; + return true; }; }; @@ -165,7 +154,7 @@ class DistributedGridIO_MPIIOBase if(distrGrid==NULL) //not distributed { - return meshFunction.save(fileName); + meshFunction.save(fileName); } MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup())); @@ -307,7 +296,7 @@ class DistributedGridIO_MPIIOBase MPI_File_write(file,&meshFunctionSerializationTypeLength,1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); - MPI_File_write(file,meshFunctionSerializationType.getString(),meshFunctionSerializationType.getLength(),MPI_CHAR,&wstatus); + MPI_File_write(file,const_cast< void* >( ( const void* ) meshFunctionSerializationType.getString() ),meshFunctionSerializationType.getLength(),MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); @@ -321,7 +310,7 @@ class DistributedGridIO_MPIIOBase MPI_File_write(file,&dataSerializationTypeLength,1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); - MPI_File_write(file,dataSerializationType.getString(),dataSerializationType.getLength(),MPI_CHAR,&wstatus); + MPI_File_write( file, const_cast< void* >( ( const void* ) dataSerializationType.getString() ), dataSerializationType.getLength(), MPI_CHAR, &wstatus ); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Data count @@ -332,12 +321,13 @@ class DistributedGridIO_MPIIOBase return size; }; - static bool load(const String& fileName,MeshFunctionType &meshFunction, RealType* data ) - { - auto *distrGrid=meshFunction.getMesh().getDistributedMesh(); + static bool load(const String& fileName,MeshFunctionType &meshFunction, RealType* data ) + { + auto *distrGrid=meshFunction.getMesh().getDistributedMesh(); if(distrGrid==NULL) //not distributed { - return meshFunction.boundLoad(fileName); + meshFunction.boundLoad(fileName); + return true; } MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup())); @@ -352,11 +342,11 @@ class DistributedGridIO_MPIIOBase std::cerr << "Unable to open file " << fileName.getString() << std::endl; return false; } - bool ret= load(file, meshFunction, data,0)>0; + bool ret= load(file, meshFunction, data,0)>0; MPI_File_close(&file); - return ret; - } + return ret; + } /* Funky bomb - no checks - only dirty load */ static int load(MPI_File &file,MeshFunctionType &meshFunction, RealType* data, int offset ) diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h index c3489994f69458bec85813f1915ce8aa245e681d..1ba844071df9c51843c6de26a5c459d17de19e50 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h @@ -49,7 +49,8 @@ class DistributedGridIO< auto *distrGrid=vectorField.getMesh().getDistributedMesh(); if(distrGrid==NULL) { - return vectorField.save(fileName); + vectorField.save(fileName); + return true; } MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup())); @@ -105,7 +106,7 @@ class DistributedGridIO< MPI_File_write(file,&vectorFieldSerializationTypeLength,1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); - MPI_File_write(file,vectorFieldSerializationType.getString(),vectorFieldSerializationType.getLength(),MPI_CHAR,&wstatus); + MPI_File_write(file,const_cast< void* >( ( const void* ) vectorFieldSerializationType.getString() ),vectorFieldSerializationType.getLength(),MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); @@ -139,7 +140,8 @@ class DistributedGridIO< auto *distrGrid=vectorField.getMesh().getDistributedMesh(); if(distrGrid==NULL) { - return vectorField.save(fileName); + vectorField.save(fileName); + return true; } MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup())); diff --git a/src/TNL/Meshes/GridDetails/Grid1D.h b/src/TNL/Meshes/GridDetails/Grid1D.h index 9a8f1460076d578837b48b7f0dbcee258e70d9f2..e4986c9fa140cf2f185204c2bdde16b41a01a999 100644 --- a/src/TNL/Meshes/GridDetails/Grid1D.h +++ b/src/TNL/Meshes/GridDetails/Grid1D.h @@ -208,22 +208,22 @@ class Grid< 1, Real, Device, Index > : public Object /** * \brief Method for saving the object to a file as a binary data */ - bool save( File& file ) const; + void save( File& file ) const; /** * \brief Method for restoring the object from a file. */ - bool load( File& file ); + void load( File& file ); /** * \brief Method for saving the object to a file. */ - bool save( const String& fileName ) const; + void save( const String& fileName ) const; /** * \brief Method for restoring the object from a file. */ - bool load( const String& fileName ); + void load( const String& fileName ); void writeProlog( Logger& logger ) const; diff --git a/src/TNL/Meshes/GridDetails/Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Grid1D_impl.h index 995fa6dab31446cdd5e2a293e3377f04e97cb7ab..5f3e919c662ee40d0c9f6ca0c830b1824c7f305e 100644 --- a/src/TNL/Meshes/GridDetails/Grid1D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid1D_impl.h @@ -371,53 +371,41 @@ Grid< 1, Real, Device, Index >:: getDistributedMesh(void) const template< typename Real, typename Device, typename Index > -bool Grid< 1, Real, Device, Index >::save( File& file ) const +void Grid< 1, Real, Device, Index >::save( File& file ) const { - if( ! Object::save( file ) ) - return false; - if( ! this->origin.save( file ) || - ! this->proportions.save( file ) || - ! this->dimensions.save( file ) ) - { - std::cerr << "I was not able to save the domain description of a Grid." << std::endl; - return false; - } - return true; + Object::save( file ); + this->origin.save( file ); + this->proportions.save( file ); + this->dimensions.save( file ); }; template< typename Real, typename Device, typename Index > -bool Grid< 1, Real, Device, Index >::load( File& file ) +void Grid< 1, Real, Device, Index >::load( File& file ) { - if( ! Object::load( file ) ) - return false; + Object::load( file ); CoordinatesType dimensions; - if( ! this->origin.load( file ) || - ! this->proportions.load( file ) || - ! dimensions.load( file ) ) - { - std::cerr << "I was not able to load the domain description of a Grid." << std::endl; - return false; - } + this->origin.load( file ); + this->proportions.load( file ); + dimensions.load( file ); this->setDimensions( dimensions ); - return true; }; template< typename Real, typename Device, typename Index > -bool Grid< 1, Real, Device, Index >::save( const String& fileName ) const +void Grid< 1, Real, Device, Index >::save( const String& fileName ) const { - return Object::save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool Grid< 1, Real, Device, Index >::load( const String& fileName ) +void Grid< 1, Real, Device, Index >::load( const String& fileName ) { - return Object::load( fileName ); + Object::load( fileName ); } template< typename Real, diff --git a/src/TNL/Meshes/GridDetails/Grid2D.h b/src/TNL/Meshes/GridDetails/Grid2D.h index f2dbebc5c78c36959a68a574886496c75857ca81..59ad153e229973033bd8c7b8c4501fa6992167f8 100644 --- a/src/TNL/Meshes/GridDetails/Grid2D.h +++ b/src/TNL/Meshes/GridDetails/Grid2D.h @@ -207,22 +207,22 @@ class Grid< 2, Real, Device, Index > : public Object /** * \brief See Grid1D::save( File& file ) const. */ - bool save( File& file ) const; + void save( File& file ) const; /** * \brief See Grid1D::load( File& file ). */ - bool load( File& file ); + void load( File& file ); /** * \brief See Grid1D::save( const String& fileName ) const. */ - bool save( const String& fileName ) const; + void save( const String& fileName ) const; /** * \brief See Grid1D::load( const String& fileName ). */ - bool load( const String& fileName ); + void load( const String& fileName ); void writeProlog( Logger& logger ) const; diff --git a/src/TNL/Meshes/GridDetails/Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Grid2D_impl.h index 41e05d8b5a5853f8f5cc9d08ef8a0360b7202636..42f2601b67facfde7bd52a7bf62c5fea5ea4c618 100644 --- a/src/TNL/Meshes/GridDetails/Grid2D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid2D_impl.h @@ -453,53 +453,41 @@ Grid< 2, Real, Device, Index >:: getDistributedMesh(void) const template< typename Real, typename Device, typename Index > -bool Grid< 2, Real, Device, Index > :: save( File& file ) const +void Grid< 2, Real, Device, Index > :: save( File& file ) const { - if( ! Object::save( file ) ) - return false; - if( ! this->origin.save( file ) || - ! this->proportions.save( file ) || - ! this->dimensions.save( file ) ) - { - std::cerr << "I was not able to save the domain description of a Grid." << std::endl; - return false; - } - return true; + Object::save( file ); + this->origin.save( file ); + this->proportions.save( file ); + this->dimensions.save( file ); }; template< typename Real, typename Device, typename Index > -bool Grid< 2, Real, Device, Index > :: load( File& file ) +void Grid< 2, Real, Device, Index > :: load( File& file ) { - if( ! Object::load( file ) ) - return false; + Object::load( file ); CoordinatesType dimensions; - if( ! this->origin.load( file ) || - ! this->proportions.load( file ) || - ! dimensions.load( file ) ) - { - std::cerr << "I was not able to load the domain description of a Grid." << std::endl; - return false; - } + this->origin.load( file ); + this->proportions.load( file ); + dimensions.load( file ); this->setDimensions( dimensions ); - return true; }; template< typename Real, typename Device, typename Index > -bool Grid< 2, Real, Device, Index > :: save( const String& fileName ) const +void Grid< 2, Real, Device, Index > :: save( const String& fileName ) const { - return Object :: save( fileName ); + Object::save( fileName ); }; template< typename Real, typename Device, typename Index > -bool Grid< 2, Real, Device, Index > :: load( const String& fileName ) +void Grid< 2, Real, Device, Index > :: load( const String& fileName ) { - return Object :: load( fileName ); + Object::load( fileName ); }; template< typename Real, diff --git a/src/TNL/Meshes/GridDetails/Grid3D.h b/src/TNL/Meshes/GridDetails/Grid3D.h index 617efe7f31bc9e8b5ef3898e0f75eb9cf1ada11a..232c3680549a7956e9275e5a477fa43fc63370a6 100644 --- a/src/TNL/Meshes/GridDetails/Grid3D.h +++ b/src/TNL/Meshes/GridDetails/Grid3D.h @@ -208,22 +208,22 @@ class Grid< 3, Real, Device, Index > : public Object /** * \brief See Grid1D::save( File& file ) const. */ - bool save( File& file ) const; + void save( File& file ) const; /** * \brief See Grid1D::load( File& file ). */ - bool load( File& file ); + void load( File& file ); /** * \brief See Grid1D::save( const String& fileName ) const. */ - bool save( const String& fileName ) const; + void save( const String& fileName ) const; /** * \brief See Grid1D::load( const String& fileName ). */ - bool load( const String& fileName ); + void load( const String& fileName ); void writeProlog( Logger& logger ) const; diff --git a/src/TNL/Meshes/GridDetails/Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Grid3D_impl.h index edbee0c006bc50e2575262efc64f5b2978d13034..4908ad7074df5d828049ff41339147a00b2a8551 100644 --- a/src/TNL/Meshes/GridDetails/Grid3D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid3D_impl.h @@ -535,53 +535,41 @@ Grid< 3, Real, Device, Index >:: getDistributedMesh(void) const template< typename Real, typename Device, typename Index > -bool Grid< 3, Real, Device, Index > :: save( File& file ) const +void Grid< 3, Real, Device, Index > :: save( File& file ) const { - if( ! Object::save( file ) ) - return false; - if( ! this->origin.save( file ) || - ! this->proportions.save( file ) || - ! this->dimensions.save( file ) ) - { - std::cerr << "I was not able to save the domain description of a Grid." << std::endl; - return false; - } - return true; + Object::save( file ); + this->origin.save( file ); + this->proportions.save( file ); + this->dimensions.save( file ); }; template< typename Real, typename Device, typename Index > -bool Grid< 3, Real, Device, Index > :: load( File& file ) +void Grid< 3, Real, Device, Index >::load( File& file ) { - if( ! Object :: load( file ) ) - return false; + Object :: load( file ); CoordinatesType dimensions; - if( ! this->origin.load( file ) || - ! this->proportions.load( file ) || - ! dimensions.load( file ) ) - { - std::cerr << "I was not able to load the domain description of a Grid." << std::endl; - return false; - } + this->origin.load( file ); + this->proportions.load( file ); + dimensions.load( file ); this->setDimensions( dimensions ); - return true; }; template< typename Real, typename Device, typename Index > -bool Grid< 3, Real, Device, Index > :: save( const String& fileName ) const +void Grid< 3, Real, Device, Index >::save( const String& fileName ) const { - return Object :: save( fileName ); + Object::save( fileName ); }; template< typename Real, typename Device, typename Index > -bool Grid< 3, Real, Device, Index > :: load( const String& fileName ) +void Grid< 3, Real, Device, Index >::load( const String& fileName ) { - return Object :: load( fileName ); + Object::load( fileName ); }; template< typename Real, diff --git a/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp b/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp index 5b35d5be972516d945da497837fc5711d62bb693..42ba1b636a0a7626097f32d8283c88798de4d65e 100644 --- a/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp +++ b/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp @@ -185,7 +185,7 @@ processEntities( auto& pool = CudaStreamPool::getInstance(); const cudaStream_t& s = pool.getStream( stream ); - //Devices::Cuda::synchronizeDevice(); + Devices::Cuda::synchronizeDevice(); if( processOnlyBoundaryEntities ) { dim3 cudaBlockSize( 2 ); diff --git a/src/TNL/Meshes/Mesh.h b/src/TNL/Meshes/Mesh.h index 793f1b0bbf925fa720e2cf4c583054b6c6466f43..589a862b9228bfbc7b1108c3caa51af6303532c0 100644 --- a/src/TNL/Meshes/Mesh.h +++ b/src/TNL/Meshes/Mesh.h @@ -160,9 +160,9 @@ class Mesh const GlobalIndexVector& iperm ); - bool save( File& file ) const; + void save( File& file ) const; - bool load( File& file ); + void load( File& file ); using Object::load; using Object::save; diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h index f743fd25e435ef32b8aa50a550a229772d08d89e..99a0e612667ed157f153d5a120ecd497cdc70110 100644 --- a/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h +++ b/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h @@ -170,7 +170,11 @@ public: bool save( File& file ) const { - if( ! boundaryTags.save( file ) ) + try + { + boundaryTags.save( file ); + } + catch(...) { std::cerr << "Failed to save the boundary tags of the entities with dimension " << DimensionTag::value << "." << std::endl; return false; @@ -180,7 +184,11 @@ public: bool load( File& file ) { - if( ! boundaryTags.load( file ) ) + try + { + boundaryTags.load( file ); + } + catch(...) { std::cerr << "Failed to load the boundary tags of the entities with dimension " << DimensionTag::value << "." << std::endl; return false; diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h index 80bb94da67d4f89b62f2d99794686f4a031a0bb5..a9d25d8438316f34782cb8d4cf14c97573dd0b96 100644 --- a/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h +++ b/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h @@ -141,10 +141,14 @@ public: bool save( File& file ) const { - if( ! SubentityStorageBaseType::save( file ) || - ! SuperentityStorageBaseType::save( file ) || - ! this->entities.save( file ) || - ! BaseType::save( file ) ) + try + { + SubentityStorageBaseType::save( file ); + SuperentityStorageBaseType::save( file ); + this->entities.save( file ); + BaseType::save( file ); + } + catch(...) { std::cerr << "Saving of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl; return false; @@ -154,10 +158,14 @@ public: bool load( File& file ) { - if( ! SubentityStorageBaseType::load( file ) || - ! SuperentityStorageBaseType::load( file ) || - ! this->entities.load( file ) || - ! BaseType::load( file ) ) + try + { + SubentityStorageBaseType::load( file ); + SuperentityStorageBaseType::load( file ); + this->entities.load( file ); + BaseType::load( file ); + } + catch(...) { std::cerr << "Loading of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl; return false; diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h index c26e525a9c5e532708a3bb430bdeb140b56f0dc4..cd4d9edf00c6da911b5bf172094dcc04df6d9aaf 100644 --- a/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h +++ b/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h @@ -107,8 +107,12 @@ protected: bool save( File& file ) const { - if( ! BaseType::save( file ) || - ! this->storageNetwork.save( file ) ) + try + { + BaseType::save( file ); + this->storageNetwork.save( file ); + } + catch(...) { std::cerr << "Saving of the entity subentities layer with " << SubdimensionTag::value << " dimension failed." << std::endl; return false; @@ -118,8 +122,12 @@ protected: bool load( File& file ) { - if( ! BaseType::load( file ) || - ! this->storageNetwork.load( file ) ) + try + { + BaseType::load( file ); + this->storageNetwork.load( file ); + } + catch(...) { std::cerr << "Loading of the entity subentities layer with " << SubdimensionTag::value << " dimension failed." << std::endl; return false; diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h index 62d86fe7bff83042f19ab41f68023c91c4cf83ee..7e49a3155cc389d08655387874977e038db2cfa6 100644 --- a/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h +++ b/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h @@ -109,8 +109,12 @@ protected: bool save( File& file ) const { - if( ! BaseType::save( file ) || - ! this->storageNetwork.save( file ) ) + try + { + BaseType::save( file ); + this->storageNetwork.save( file ); + } + catch(...) { std::cerr << "Saving of the entity superentities layer with " << SuperdimensionTag::value << " dimension failed." << std::endl; return false; @@ -120,8 +124,12 @@ protected: bool load( File& file ) { - if( ! BaseType::load( file ) || - ! this->storageNetwork.load( file ) ) + try + { + BaseType::load( file ); + this->storageNetwork.load( file ); + } + catch(...) { std::cerr << "Loading of the entity superentities layer with " << SuperdimensionTag::value << " dimension failed." << std::endl; return false; diff --git a/src/TNL/Meshes/MeshDetails/Mesh_impl.h b/src/TNL/Meshes/MeshDetails/Mesh_impl.h index cd704edafc8dd0488ef971586235ed8534ccb0b3..3f00336a8df0f225dc6614ad23a061e8d99207dc 100644 --- a/src/TNL/Meshes/MeshDetails/Mesh_impl.h +++ b/src/TNL/Meshes/MeshDetails/Mesh_impl.h @@ -212,8 +212,8 @@ reorderEntities( const GlobalIndexVector& perm, // basic sanity check if( perm.getSize() != entitiesCount || iperm.getSize() != entitiesCount ) { throw std::logic_error( "Wrong size of permutation vectors: " - "perm = " + std::to_string( perm ) + ", " - "iperm = " + std::to_string( iperm ) ); + "perm size = " + std::to_string( perm.getSize() ) + ", " + "iperm size = " + std::to_string( iperm.getSize() ) ); } TNL_ASSERT( perm.min() == 0 && perm.max() == entitiesCount - 1, std::cerr << "Given array is not a permutation: min = " << perm.min() @@ -236,35 +236,25 @@ reorderEntities( const GlobalIndexVector& perm, template< typename MeshConfig, typename Device > -bool +void Mesh< MeshConfig, Device >:: save( File& file ) const { - if( ! Object::save( file ) || - ! StorageBaseType::save( file ) || - ! BoundaryTagsLayerFamily::save( file ) ) - { - std::cerr << "Mesh saving failed." << std::endl; - return false; - } - return true; + Object::save( file ); + StorageBaseType::save( file ); + BoundaryTagsLayerFamily::save( file ); } template< typename MeshConfig, typename Device > -bool +void Mesh< MeshConfig, Device >:: load( File& file ) { - if( ! Object::load( file ) || - ! StorageBaseType::load( file ) || - ! BoundaryTagsLayerFamily::load( file ) ) - { - std::cerr << "Mesh loading failed." << std::endl; - return false; - } + Object::load( file ); + StorageBaseType::load( file ); + BoundaryTagsLayerFamily::load( file ); // update pointers from entities into the subentity and superentity storage networks EntityStorageRebinder< Mesh< MeshConfig, Device > >::exec( *this ); - return true; } template< typename MeshConfig, typename Device > diff --git a/src/TNL/Meshes/Readers/TNLReader.h b/src/TNL/Meshes/Readers/TNLReader.h index 68f4d13a21c99bb2ce93bd6e0bdf2f0e32f1bcf4..6100a5119474fde61ad49c450def2a77ff84f53e 100644 --- a/src/TNL/Meshes/Readers/TNLReader.h +++ b/src/TNL/Meshes/Readers/TNLReader.h @@ -12,6 +12,7 @@ #include <TNL/String.h> #include <TNL/Object.h> +#include <TNL/Exceptions/ObjectTypeDetectionFailure.h> #include <TNL/Meshes/Readers/EntityShape.h> namespace TNL { @@ -28,9 +29,13 @@ public: this->fileName = fileName; String objectType; - if( ! getObjectType( fileName, objectType ) ) { - std::cerr << "Failed to detect the mesh type from the file " << fileName << "." << std::endl; - return EXIT_FAILURE; + try + { + objectType = getObjectType( fileName ); + } + catch( ... ) + { + throw Exceptions::ObjectTypeDetectionFailure( fileName, "mesh" ); } const std::vector< String > parsedMeshType = parseObjectType( objectType ); @@ -103,7 +108,8 @@ public: static bool readMesh( const String& fileName, MeshType& mesh ) { - return mesh.load( fileName ); + mesh.load( fileName ); + return true; } String diff --git a/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h b/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h index b3fe7f1ba5f9ae9d85af8d508e7a5ab1b4a0795d..6c60126457d1d4aa33426631b836407be6a412d7 100644 --- a/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h +++ b/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h @@ -130,7 +130,7 @@ loadMesh( const String& fileName, bool status = true; if( ends_with( fileName_, ".tnl" ) ) - status = mesh.load( fileName ); + mesh.load( fileName ); else if( ends_with( fileName_, ".ng" ) ) { Readers::NetgenReader reader; status = reader.readMesh( fileName, mesh ); @@ -210,7 +210,11 @@ loadMesh( const String& fileName, { std::cout << "Loading a global mesh from the file " << fileName << "..."; Grid< Dimension, Real, Device, Index > globalGrid; - if( ! globalGrid.load( fileName ) ) + try + { + globalGrid.load( fileName ); + } + catch(...) { std::cerr << std::endl; std::cerr << "I am not able to load the global mesh from the file " << fileName << "." << std::endl; @@ -226,7 +230,11 @@ loadMesh( const String& fileName, else { std::cout << "Loading a mesh from the file " << fileName << "..."; - if( ! mesh.load( fileName ) ) + try + { + mesh.load( fileName ); + } + catch(...) { std::cerr << std::endl; std::cerr << "I am not able to load the mesh from the file " << fileName << "." << std::endl; diff --git a/src/TNL/Object.h b/src/TNL/Object.h index d909a21edda099e8b4c8fd70a8a1f9499918ad42..92ed9fef7821cd3bb295d7b5eeace72e3f1a50bf 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -22,40 +22,68 @@ namespace TNL { /** - * \brief Basic class for all 'large' objects like matrices, meshes, grids, solvers, etc.. + * \brief Basic class for majority of TNL objects like matrices, meshes, grids, solvers, etc.. * - * Objects like numerical grids, meshes, matrices large vectors etc. - * are inherited by this class. This class provides name for such objects. Giving - * a name to each bigger object is compulsory. The name can help to locate - * possible errors in the code. This can help to identify an object where, for - * example, one tries to touch non-existing element. All objects of the TNL should - * have only constructor with name and then only setter methods and method init. - * Each object derived from the Object must be able to tell its type via the method - * \ref getType and it must support methods \ref save and \ref load for saving and - * loading the object from a \ref File "file". + * Objects like numerical meshes, matrices large vectors etc. are inherited by + * this class. This class introduces virtual method \ref getType which is + * supposed to tell the object type in a C++ style. + * + * Since the virtual destructor is not defined as \ref __cuda_callable__, + * objects inherited from Object should not be created in CUDA kernels. + * + * In addition to methods of this class, see the following related functions: + * + * \ref getObjectType + * + * \ref parseObjectType + * */ class Object { public: /** - * \brief Type getter. + * \brief Static type getter. * * Returns the type in C++ style - for example the returned value - * may look as \c "Vector< double, Devices::Cuda >". + * may look as \c "Array< double, Devices::Cuda, int >". + * + * \par Example + * \include ObjectExample_getType.cpp + * \par Output + * \include ObjectExample_getType.out */ - static String getType(); + static String getType(); - virtual String getTypeVirtual() const; + /*** + * \brief Virtual type getter. + * + * Returns the type in C++ style - for example the returned value + * may look as \c "Array< double, Devices::Cuda, int >". + * See example at \ref Object::getType. + */ + virtual String getTypeVirtual() const; /** - * \brief This is used for load and save methods. + * \brief Static serialization type getter. * - * Each object is saved as if it was stored on \ref Devices::Host. So even - * \c Vector< double, Devices::Cuda > is saved as \c Vector< double, Devices::Host >. + * Objects in TNL are saved as in a device independent manner. This method + * is supposed to return the object type but with the device type replaced + * by Devices::Host. For example \c Array< double, Devices::Cuda > is + * saved as \c Array< double, Devices::Host >. + * See example at \ref Object::getType. */ static String getSerializationType(); + /*** + * \brief Virtual serialization type getter. + * + * Objects in TNL are saved as in a device independent manner. This method + * is supposed to return the object type but with the device type replaced + * by Devices::Host. For example \c Array< double, Devices::Cuda > is + * saved as \c Array< double, Devices::Host >. + * See example at \ref Object::getType. + */ virtual String getSerializationTypeVirtual() const; /** @@ -63,59 +91,89 @@ class Object * * \param file Name of file object. */ - virtual bool save( File& file ) const; + virtual void save( File& file ) const; /** * \brief Method for restoring the object from a file. * * \param file Name of file object. */ - virtual bool load( File& file ); + virtual void load( File& file ); /** * \brief Method for restoring the object from a file. * * \param file Name of file object. */ - virtual bool boundLoad( File& file ); + virtual void boundLoad( File& file ); /** * \brief Method for saving the object to a file as a binary data. * * \param fileName String defining the name of a file. */ - bool save( const String& fileName ) const; + void save( const String& fileName ) const; /** * \brief Method for restoring the object from a file. * * \param fileName String defining the name of a file. */ - bool load( const String& fileName ); + void load( const String& fileName ); /** * \brief Method for restoring the object from a file. * * \param fileName String defining the name of a file. */ - bool boundLoad( const String& fileName ); + void boundLoad( const String& fileName ); - /// Destructor. - // FIXME: __cuda_callable__ would have to be added to every overriding destructor, - // even if the object's constructor is not __cuda_callable__ - // __cuda_callable__ + /** + * \brief Destructor. + * + * Since it is not defined as \ref __cuda_callable__, objects inherited + * from Object should not be created in CUDA kernels. + */ #ifndef HAVE_MIC virtual ~Object(){}; #endif }; -bool getObjectType( File& file, String& type ); +/** + * \brief Extracts object type from a binary file. + * + * @param file is file where the object is stored + * @return string with the object type + */ +String getObjectType( File& file ); -bool getObjectType( const String& file_name, String& type ); +/** + * \brief Does the same as \ref getObjectType but with a \e fileName parameter instead of file. + * + * @param fileName name of a file where the object is stored + * @return string with the object type + */ +String getObjectType( const String& fileName ); +/** + * \brief Parses the object type + * + * @param objectType is a string with the object type to be parsed. + * @return vector of strings where the first one is the object type and the next + * strings are the template parameters. + * + * \par Example + * \include ParseObjectTypeExample.cpp + * \par Output + * \include ParseObjectTypeExample.out + */ std::vector< String > parseObjectType( const String& objectType ); +inline void saveHeader( File& file, const String& type ); + +inline void loadHeader( File& file, String& type ); + } // namespace TNL -#include <TNL/Object_impl.h> +#include <TNL/Object.hpp> diff --git a/src/TNL/Object_impl.h b/src/TNL/Object.hpp similarity index 54% rename from src/TNL/Object_impl.h rename to src/TNL/Object.hpp index f0b1a8545ac0769e270b6804463f7d2af1aa64ac..1e83f036f123cff75fafe63bbcb6b9cc3fba50db 100644 --- a/src/TNL/Object_impl.h +++ b/src/TNL/Object.hpp @@ -15,113 +15,88 @@ #include <cstring> #include <TNL/Object.h> +#include <TNL/Exceptions/NotTNLFile.h> +#include <TNL/Exceptions/ObjectTypeMismatch.h> namespace TNL { static constexpr char magic_number[] = "TNLMN"; -inline String Object :: getType() +inline String Object::getType() { return String( "Object" ); } -inline String Object :: getTypeVirtual() const +inline String Object::getTypeVirtual() const { return this->getType(); } -inline String Object :: getSerializationType() +inline String Object::getSerializationType() { return String( "Object" ); } -inline String Object :: getSerializationTypeVirtual() const +inline String Object::getSerializationTypeVirtual() const { return this->getSerializationType(); } -inline bool Object :: save( File& file ) const +inline void Object::save( File& file ) const { - if( ! file.write( magic_number, strlen( magic_number ) ) ) - return false; + file.save( magic_number, strlen( magic_number ) ); file << this->getSerializationTypeVirtual(); - return true; } -inline bool Object :: load( File& file ) +inline void Object::load( File& file ) { - String objectType; - if( ! getObjectType( file, objectType ) ) - return false; + String objectType = getObjectType( file ); if( objectType != this->getSerializationTypeVirtual() ) - { - std::cerr << "Given file contains instance of " << objectType << " but " << getSerializationTypeVirtual() << " is expected." << std::endl; - return false; - } - return true; + throw Exceptions::ObjectTypeMismatch( this->getSerializationTypeVirtual(), objectType ); } -inline bool Object :: boundLoad( File& file ) +inline void Object::boundLoad( File& file ) { - return load( file ); + this->load( file ); } -inline bool Object :: save( const String& fileName ) const +inline void Object::save( const String& fileName ) const { File file; - if( ! file.open( fileName, IOMode::write ) ) - { - std::cerr << "I am not able to open the file " << fileName << " for writing." << std::endl; - return false; - } - return this->save( file ); + file.open( fileName, File::Mode::Out ); + this->save( file ); } -inline bool Object :: load( const String& fileName ) +inline void Object::load( const String& fileName ) { File file; - if( ! file.open( fileName, IOMode::read ) ) - { - std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl; - return false; - } - return this->load( file ); + file.open( fileName, File::Mode::In ); + this->load( file ); } -inline bool Object :: boundLoad( const String& fileName ) +inline void Object::boundLoad( const String& fileName ) { File file; - if( ! file.open( fileName, IOMode::read ) ) - { - std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl; - return false; - } - return this->boundLoad( file ); + file.open( fileName, File::Mode::In ); + this->boundLoad( file ); } - -inline bool getObjectType( File& file, String& type ) +inline String getObjectType( File& file ) { char mn[ 10 ]; - file.read( mn, strlen( magic_number ) ); + String type; + file.load( mn, strlen( magic_number ) ); if( strncmp( mn, magic_number, 5 ) != 0 ) - { - std::cout << "Not a TNL file (wrong magic number)." << std::endl; - return false; - } + throw Exceptions::NotTNLFile(); file >> type; - return true; + return type; } -inline bool getObjectType( const String& fileName, String& type ) +inline String getObjectType( const String& fileName ) { File binaryFile; - if( ! binaryFile.open( fileName, IOMode::read ) ) - { - std::cerr << "I am not able to open the file " << fileName << " for detecting the object inside!" << std::endl; - return false; - } - return getObjectType( binaryFile, type ); + binaryFile.open( fileName, File::Mode::In ); + return getObjectType( binaryFile ); } inline std::vector< String > @@ -176,4 +151,21 @@ parseObjectType( const String& objectType ) return parsedObjectType; } +inline void saveHeader( File& file, const String& type ) +{ + file.save( magic_number, strlen( magic_number ) ); + file << type; +} + +inline void loadHeader( File& file, String& type ) +{ + char mn[ 10 ]; + file.load( mn, strlen( magic_number ) ); + if( strncmp( mn, magic_number, 5 ) != 0 ) + throw Exceptions::NotTNLFile(); + file >> type; +} + + + } // namespace TNL diff --git a/src/TNL/Problems/HeatEquationProblem_impl.h b/src/TNL/Problems/HeatEquationProblem_impl.h index 03be60b3b1a39922ba7bd24b8e92264b3fb2dd5a..0c0cd7418e5f88235f7acb751f3404e404ab636e 100644 --- a/src/TNL/Problems/HeatEquationProblem_impl.h +++ b/src/TNL/Problems/HeatEquationProblem_impl.h @@ -162,12 +162,16 @@ setInitialCondition( const Config::ParameterContainer& parameters, } else { - if( ! this->uPointer->boundLoad( initialConditionFile ) ) - { - std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl; - return false; - } - } + try + { + this->uPointer->boundLoad( initialConditionFile ); + } + catch(...) + { + std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl; + return false; + } + } return true; } @@ -226,8 +230,7 @@ makeSnapshot( const RealType& time, } else { - if( ! this->uPointer->save( fileName.getFileName() ) ) - return false; + this->uPointer->save( fileName.getFileName() ); } return true; } diff --git a/src/TNL/Solvers/Linear/GMRES_impl.h b/src/TNL/Solvers/Linear/GMRES_impl.h index 17f8dd1f38fe64ae96fafe8735a23ea331dfb2a1..4731ccaf7d36ce6e0c7db2857b55f10eb60cf369 100644 --- a/src/TNL/Solvers/Linear/GMRES_impl.h +++ b/src/TNL/Solvers/Linear/GMRES_impl.h @@ -185,7 +185,8 @@ orthogonalize_MGS( const int m, const RealType normb, const RealType beta ) { // initial binding to _M_tmp sets the correct local range, global size and // communication group for distributed views - VectorViewType v_i( _M_tmp ), v_k( _M_tmp ); + VectorViewType v_i( _M_tmp.getView() ); + VectorViewType v_k( _M_tmp.getView() ); /*** * v_0 = r / | r | = 1.0 / beta * r @@ -258,7 +259,8 @@ orthogonalize_CWY( const int m, const RealType normb, const RealType beta ) { // initial binding to _M_tmp sets the correct local range, global size and // communication group for distributed views - VectorViewType v_i( _M_tmp ), y_i( _M_tmp ); + VectorViewType v_i( _M_tmp.getView() ); + VectorViewType y_i( _M_tmp.getView() ); /*** * z = r / | r | = 1.0 / beta * r diff --git a/src/TNL/String.h b/src/TNL/String.h index 3da2ffbf4b74d63665140ad980d00640d921855d..a04802216c2dd14a6495b30146a49066f708820e 100644 --- a/src/TNL/String.h +++ b/src/TNL/String.h @@ -1,4 +1,4 @@ -/*************************************************************************** +/************************************************************************* String.h - description ------------------- begin : 2004/04/10 16:35 @@ -23,226 +23,361 @@ namespace TNL { class String; -///// -/// \brief Class for managing strings. -/// -/// \par Example -/// \include StringExample.cpp -/// \par Output -/// \include StringExample.out +/** + * \brief Class for managing strings. + * + * The following example shows common use of String. + * + * \par Example + * \include StringExample.cpp + * \par Output + * \include StringExample.out + * + * In addition to methods of this class, check the following related functions: + * + * \ref convertToString + * + * \ref operator+ + * + * \ref operator<< + * + * \ref mpiSend + * + * \ref mpiReceive + */ class String : public std::string { -public: - ///// - /// \brief Default constructor. - /// - /// Constructs an empty string object. - String() = default; - - /// \brief Default copy constructor. - String( const String& ) = default; - - /// \brief Default move constructor. - String( String&& ) = default; - - /// \brief Initialization by \e std::string. - String( const std::string& str ) : std::string( str ) {} - - /// \brief Default copy assignment operator. - String& operator=( const String& ) = default; - - /// \brief Default move assignment operator. - String& operator=( String&& ) = default; - - /// \brief Inherited constructors and assignment operators. - using std::string::string; - using std::string::operator=; - - - /// \brief Returns type of string: \c "String". - static String getType(); - - /// \brief Returns the number of characters in given string. Equivalent to \ref getSize. - int getLength() const; - - /// \brief Returns the number of characters in given string. - /// - /// \par Example - /// \include StringExampleGetSize.cpp - /// \par Output - /// \include StringExampleGetSize.out - int getSize() const; - - /// \brief Returns size of allocated storage for given string. - /// - /// \par Example - /// \include StringExampleGetAllocatedSize.cpp - /// \par Output - /// \include StringExampleGetAllocatedSize.out - int getAllocatedSize() const; - - ///// - /// \brief Reserves space for given \e size. - /// - /// Requests to allocate storage space of given \e size to avoid memory reallocation. - /// It allocates one more byte for the terminating 0. - /// @param size Number of characters. - /// - /// \par Example - /// \include StringExampleSetSize.cpp - /// \par Output - /// \include StringExampleSetSize.out - void setSize( int size ); - - ///// - /// \brief Returns pointer to data. - /// - /// It returns the content of the given string as a constant pointer to char. - const char* getString() const; - - ///// - /// \brief Operator for accessing particular chars of the string. - /// - /// This function overloads \ref operator[]. It returns a reference to - /// the character at position \e i in given string. - /// The character can not be changed be user. - const char& operator[]( int i ) const; - - /// \brief Operator for accessing particular chars of the string. - /// - /// It returns the character at the position \e i in given string as - /// a modifiable reference. - char& operator[]( int i ); - - ///// - // Operators for single characters. - - /// \brief This function overloads \ref operator+=. - /// - /// Appends character \e str to this string. - String& operator+=( char str ); - /// \brief This function concatenates strings and returns a newly constructed string object. - String operator+( char str ) const; - /// \brief This function checks whether the given string is equal to \e str. - /// - /// It returns \e true when the given string is equal to \e str. Otherwise returns \e false. - bool operator==( char str ) const; - /// \brief This function overloads \ref operator!=. - bool operator!=( char str ) const; - - ///// - // Operators for C strings. - - /// \brief This function overloads \ref operator+=. - /// - /// It appends the C string \e str to this string. - String& operator+=( const char* str ); - /// \brief This function concatenates C strings \e str and returns a newly - /// constructed string object. - String operator+( const char* str ) const; - /// \brief This function overloads \ref operator==. - bool operator==( const char* str ) const; - /// \brief This function overloads \ref operator!=. - bool operator!=( const char* str ) const; - - ///// - // Operators for std::string. - - /// \brief This function overloads \ref operator+=. - /// - /// It appends the C string \e str to this string. - String& operator+=( const std::string& str ); - /// \brief This function concatenates C strings \e str and returns a newly - /// constructed string object. - String operator+( const std::string& str ) const; - /// \brief This function overloads \ref operator==. - bool operator==( const std::string& str ) const; - /// \brief This function overloads \ref operator!=. - bool operator!=( const std::string& str ) const; - - ///// - // Operators for String. - - /// \brief This function overloads \ref operator+=. - /// - /// It appends the C string \e str to this string. - String& operator+=( const String& str ); - /// \brief This function concatenates C strings \e str and returns a newly - /// constructed string object. - String operator+( const String& str ) const; - /// \brief This function overloads \ref operator==. - bool operator==( const String& str ) const; - /// \brief This function overloads \ref operator!=. - bool operator!=( const String& str ) const; - - /// \brief Cast to bool operator. - /// - /// This operator converts string to boolean expression (true or false). - operator bool() const; - - /// \brief Cast to bool with negation operator. - /// - /// This operator converts string to boolean expression (false or true). - bool operator!() const; - - ///// - /// \brief Replaces portion of string. - /// - /// Replaces section \e pattern from this string with new piece of string \e replaceWith. - /// If parameter \e count is defined, the function makes replacement several times, - /// every time when it finds the same pattern in this string. - /// @param pattern Section of given string that will be replaced. - /// @param replaceWith New piece of string that will be used to replace \e pattern. - /// @param count A whole number that specifies how many replacements should be done. - String replace( const String& pattern, - const String& replaceWith, - int count = 0 ) const; - - ///// - /// \brief Trims/strips given string. - /// - /// Removes all spaces from given string except for single spaces between words. - String strip( char strip = ' ' ) const; - - /// \brief Splits string into list of strings with respect to given \e separator. - /// - /// Splits the string into list of substrings wherever \e separator occurs, - /// and returs list of those strings. When \e separator does not appear - /// anywhere in the given string, this function returns a single-element list - /// containing given sting. - /// @param separator Character, which separates substrings in given string. - std::vector< String > split( const char separator = ' ', bool skipEmpty = false ) const; - -#ifdef HAVE_MPI - - /**** - * \brief Sends the string to the target MPI process. - */ - void send( int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); - - /**** - * \brief Receives a string from the source MPI process. - */ - void receive( int source, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); - - //! Broadcast to other nodes in MPI cluster - // void MPIBcast( int root, MPI_Comm mpi_comm = MPI_COMM_WORLD ); -#endif + public: + + /** + * \brief This enum defines how the operation split of string is to be performed. + */ + enum class SplitSkip + { + NoSkip, ///< Do not skip empty characters + SkipEmpty ///< Skip empty characters. + }; + + /** + * \brief Default constructor. + * + * Constructs an empty string object. + */ + String() = default; + + /** + * \brief Default copy constructor. + */ + String( const String& ) = default; + + /** + * \brief Default move constructor. + */ + String( String&& ) = default; + + /** + * \brief Initialization by \e std::string. + */ + String( const std::string& str ) : std::string( str ) {} + + /** + * \brief Default copy assignment operator. + */ + String& operator=( const String& ) = default; + + /** + * \brief Default move assignment operator. + */ + String& operator=( String&& ) = default; + + /** + * \brief Inherited constructors. + */ + using std::string::string; + + /** + * \brief Inherited assignment operators. + */ + using std::string::operator=; + + /** + * \brief Returns type of string: \c "String". + */ + static String getType(); + + /** + * \brief Returns the number of characters in given string. Equivalent to \ref getSize. + */ + int getLength() const; + + /** + * \brief Returns the number of characters in given string. + */ + int getSize() const; + + /** + * \brief Returns size of allocated storage for given string. + * + * \par Example + * \include StringExampleGetAllocatedSize.cpp + * \par Output + * \include StringExampleGetAllocatedSize.out + */ + int getAllocatedSize() const; + + /** + * \brief Reserves space for given \e size. + * + * Requests to allocate storage space of given \e size to avoid memory reallocation. + * It allocates one more byte for the terminating 0. + * @param size Number of characters. + * + * \par Example + * \include StringExampleSetSize.cpp + * \par Output + * \include StringExampleSetSize.out + */ + void setSize( int size ); + + /** + * \brief Returns pointer to data. + * + * It returns the content of the given string as a constant pointer to char. + */ + const char* getString() const; + + /** + * \brief Operator for accessing particular chars of the string. + * + * This function overloads \ref operator[]. It returns a reference to + * the character at position \e i in given string. + * The character can not be changed be user. + */ + const char& operator[]( int i ) const; + + /** + * \brief Operator for accessing particular chars of the string. + * + * It returns the character at the position \e i in given string as + * a modifiable reference. + */ + char& operator[]( int i ); + + /** + * Operators for single characters. + */ + + /** + * \brief This function overloads \ref operator+=. + * + * Appends character \e str to this string. + */ + String& operator+=( char str ); + + /** + * \brief This function concatenates strings and returns a newly constructed string object. + */ + String operator+( char str ) const; + + /** + * \brief This function checks whether the given string is equal to \e str. + * + * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false. + */ + bool operator==( char str ) const; + + /** + * \brief This function overloads \ref operator!=. + * + * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true. + */ + bool operator!=( char str ) const; + + /** + * Operators for C strings. + */ + + /** + * \brief This function overloads \ref operator+=. + * + * It appends the C string \e str to this string. + */ + String& operator+=( const char* str ); + + /** + * \brief This function concatenates C strings \e str and returns a newly constructed string object. + */ + String operator+( const char* str ) const; + + /** + * \brief This function overloads \ref operator==. + * + * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false. + */ + bool operator==( const char* str ) const; + + /** + * \brief This function overloads \ref operator!=. + * + * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true. + */ + bool operator!=( const char* str ) const; + + /** + * Operators for std::string. + */ + + /** + * \brief This function overloads \ref operator+=. + * + * It appends the C string \e str to this string. + */ + String& operator+=( const std::string& str ); + + /** + * \brief This function concatenates C strings \e str and returns a newly constructed string object. + */ + String operator+( const std::string& str ) const; + + /** + * \brief This function overloads \ref operator==. + * + * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false. + */ + bool operator==( const std::string& str ) const; + + /** + * \brief This function overloads \ref operator!=. + * + * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true. + */ + bool operator!=( const std::string& str ) const; + + /** + * Operators for String. + */ + + /** + * \brief This function overloads \ref operator+=. + * + * It appends the C string \e str to this string. + */ + String& operator+=( const String& str ); + + /** + * \brief This function concatenates C strings \e str and returns a newly constructed string object. + */ + String operator+( const String& str ) const; + + /** + * \brief This function overloads \ref operator==. + * + * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false. + */ + bool operator==( const String& str ) const; + + /** + * \brief This function overloads \ref operator!=. + * + * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true. + */ + bool operator!=( const String& str ) const; + + /** + * \brief Cast to bool operator. + * + * This operator converts string to boolean expression (true or false). + * It returns \e true if the string is NOT empty. Otherwise it returns \e false. + */ + operator bool() const; + + /** \brief Cast to bool with negation operator. + * + * This operator converts string to boolean expression (false or true). + * It returns \e true if the string is empty. Otherwise it returns \e false. + */ + bool operator!() const; + + /** + * \brief This method replaces part of the string. + * + * It replaces \e pattern in this string with a string \e replaceWith. + * If parameter \e count is defined, the function makes replacement only count occurrences, + * of the given pattern. If \e count is zero, all pattern occurrences are replaced. + * + * @param pattern to be replaced. + * @param replaceWith string the \e pattern will be replaced with. + * @param count number of occurrences to be replaced. All occurrences are replaced if \e count is zero.. + * + * \par Example + * \include StringExampleReplace.cpp + * \par Output + * \include StringExampleReplace.out + */ + String replace( const String& pattern, + const String& replaceWith, + int count = 0 ) const; + + /** + * \brief Trims/strips this string. + * + * Removes all 'spaces' from given string except for single 'spaces' between words. + * + * @param strip can be used to change the character to be removed. + * + * \par Example + * \include StringExampleStrip.cpp + * \par Output + * \include StringExampleStrip.out + */ + String strip( char strip = ' ' ) const; + + /** + * \brief Splits string into list of strings with respect to given \e separator. + * + * This method splits the string into sequence of substrings divided by occurrences of \e separator. + * It returns the list of those strings via std::vector. When \e separator does not appear + * anywhere in the given string, this function returns a single-element list + * containing given sting. If \e skipEmpty equals \e SkipEmpty no empty substrings are + * inserted into the resulting container. + * + * @param separator is a character separating substrings in given string. + * @param skipEmpty + * + * \par Example + * \include StringExampleSplit.cpp + * \par Output + * \include StringExampleSplit.out + */ + std::vector< String > split( const char separator = ' ', SplitSkip skipEmpty = SplitSkip::NoSkip ) const; }; -/// \brief Returns concatenation of \e string1 and \e string2. +/** + * \brief Returns concatenation of \e string1 and \e string2. + */ String operator+( char string1, const String& string2 ); -/// \brief Returns concatenation of \e string1 and \e string2. +/** + * \brief Returns concatenation of \e string1 and \e string2. + */ String operator+( const char* string1, const String& string2 ); -/// \brief Returns concatenation of \e string1 and \e string2. +/** + * \brief Returns concatenation of \e string1 and \e string2. + */ String operator+( const std::string& string1, const String& string2 ); -/// \brief Performs the string output to a stream +/** + * \brief Writes the string \e str to given \e stream + */ std::ostream& operator<<( std::ostream& stream, const String& str ); +/** + * \brief Converts \e value of type \e T to a String. + * + * \tparam T can be any type fir which operator << is defined. + */ template< typename T > String convertToString( const T& value ) { @@ -251,12 +386,44 @@ String convertToString( const T& value ) return String( str.str().data() ); } +/** + * \brief Specialization of function \ref convertToString for boolean. + * + * The boolean type is converted to 'true' ot 'false'. + */ template<> inline String convertToString( const bool& b ) { if( b ) return "true"; return "false"; } +#ifdef HAVE_MPI + +/** + * \brief Sends the string to the target MPI process. + * + * @param str string to be sent + * @param target target MPI process ID + * @param tag MPI tag + * @param mpi_comm MPI communication group + */ +void mpiSend( const String& str, int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); + +/** + * \brief Receives a string from the target MPI process. + * + * @param str says where the received string is to be saved to + * @param source source MPI process ID + * @param tag MPI tag + * @param mpi_comm MPI communication group + */ +void mpiReceive( String& str, int source, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); + +//! Broadcast to other nodes in MPI cluster +// void MPIBcast( String& str, int root, MPI_Comm mpi_comm = MPI_COMM_WORLD ); + +#endif + } // namespace TNL -#include <TNL/String_impl.h> +#include <TNL/String.hpp> diff --git a/src/TNL/String_impl.h b/src/TNL/String.hpp similarity index 90% rename from src/TNL/String_impl.h rename to src/TNL/String.hpp index 3c5aa253a083a43c6d7a2936dea09c3474406797..4cdeee7aceb62e93b27a91655938df494c9e3666 100644 --- a/src/TNL/String_impl.h +++ b/src/TNL/String.hpp @@ -50,7 +50,6 @@ inline const char* String::getString() const return this->c_str(); } - inline const char& String::operator[]( int i ) const { TNL_ASSERT( i >= 0 && i < getLength(), @@ -65,7 +64,6 @@ inline char& String::operator[]( int i ) return std::string::operator[]( i ); } - /**** * Operators for single characters */ @@ -90,7 +88,6 @@ inline bool String::operator!=( char str ) const return ! operator==( str ); } - /**** * Operators for C strings */ @@ -115,7 +112,6 @@ inline bool String::operator!=( const char* str ) const return ! operator==( str ); } - /**** * Operators for std::string */ @@ -140,7 +136,6 @@ inline bool String::operator!=( const std::string& str ) const return ! operator==( str ); } - /**** * Operators for String */ @@ -216,44 +211,64 @@ String::strip( char strip ) const } inline std::vector< String > -String::split( const char separator, bool skipEmpty ) const +String::split( const char separator, SplitSkip skip ) const { std::vector< String > parts; String s; for( int i = 0; i < this->getLength(); i++ ) { if( ( *this )[ i ] == separator ) { - if( ! skipEmpty || s != "" ) + if( skip != SplitSkip::SkipEmpty || s != "" ) parts.push_back( s ); s = ""; } else s += ( *this )[ i ]; } - if( ! skipEmpty || s != "" ) + if( skip != SplitSkip::SkipEmpty || s != "" ) parts.push_back( s ); return parts; } +inline String operator+( char string1, const String& string2 ) +{ + return convertToString( string1 ) + string2; +} + +inline String operator+( const char* string1, const String& string2 ) +{ + return String( string1 ) + string2; +} + +inline String operator+( const std::string& string1, const String& string2 ) +{ + return String( string1 ) + string2; +} + +inline std::ostream& operator<<( std::ostream& stream, const String& str ) +{ + stream << str.getString(); + return stream; +} + #ifdef HAVE_MPI -inline void String::send( int target, int tag, MPI_Comm mpi_comm ) +inline void mpiSend( const String& str, int target, int tag, MPI_Comm mpi_comm ) { - int size = this->getSize(); + int size = str.getSize(); MPI_Send( &size, 1, MPI_INT, target, tag, mpi_comm ); - MPI_Send( this->getString(), this->length(), MPI_CHAR, target, tag, mpi_comm ); + MPI_Send( const_cast< void* >( ( const void* ) str.getString() ), str.length(), MPI_CHAR, target, tag, mpi_comm ); } -inline void String::receive( int source, int tag, MPI_Comm mpi_comm ) +inline void mpiReceive( String& str, int source, int tag, MPI_Comm mpi_comm ) { int size; MPI_Status status; MPI_Recv( &size, 1, MPI_INT, source, tag, mpi_comm, &status ); - this->setSize( size ); - MPI_Recv( const_cast< void* >( ( const void* ) this->data() ), size, MPI_CHAR, source, tag, mpi_comm, &status ); + str.setSize( size ); + MPI_Recv( const_cast< void* >( ( const void* ) str.data() ), size, MPI_CHAR, source, tag, mpi_comm, &status ); } /* inline void String :: MPIBcast( int root, MPI_Comm comm ) { -#ifdef USE_MPI int iproc; MPI_Comm_rank( MPI_COMM_WORLD, &iproc ); TNL_ASSERT( string, ); @@ -270,30 +285,9 @@ inline void String :: MPIBcast( int root, MPI_Comm comm ) } MPI_Bcast( string, len + 1, MPI_CHAR, root, comm ); -#endif } */ #endif -inline String operator+( char string1, const String& string2 ) -{ - return convertToString( string1 ) + string2; -} - -inline String operator+( const char* string1, const String& string2 ) -{ - return String( string1 ) + string2; -} - -inline String operator+( const std::string& string1, const String& string2 ) -{ - return String( string1 ) + string2; -} - -inline std::ostream& operator<<( std::ostream& stream, const String& str ) -{ - stream << str.getString(); - return stream; -} } // namespace TNL diff --git a/src/TNL/Timer.h b/src/TNL/Timer.h index 486f09f38e84ecfc3829c2dfd6b5428af5995460..2c697a04e95b81d07f4a12871f19344e16688617 100644 --- a/src/TNL/Timer.h +++ b/src/TNL/Timer.h @@ -16,78 +16,92 @@ namespace TNL { class Logger; -/// \brief Class for time measuring. -/// -/// Counts the elapsed time in seconds between the \ref start and \ref stop methods. -/// \par Example -/// \include TimerExample.cpp -// \par Output -// \include TimerExample.out +/** + * \brief Class for real time, CPU time and CPU cycles measuring. + * + * It measures the elapsed real time, CPU time (in seconds) and CPU cycles + * elapsed on the timer. The timer can be paused by calling \ref stop and \ref + * start methods and reseted by calling \ref reset. + * + * \par Example + * \include TimerExample.cpp + * \par Output + * \include TimerExample.out + */ class Timer { public: - ///// - /// \brief Basic constructor. - /// - /// This function creates a new timer and resets it. + /** + * \brief Basic constructor. + * + * This function creates a new timer and resets it. + */ Timer(); - ///// - /// \brief Resets timer. - /// - /// Resets all time and cycle measurements such as real time, CPU time and CPU cycles. - /// Sets all of them to zero. + /** + * \brief Resets timer. + * + * Resets all time and cycle measurements such as real time, CPU time and + * CPU cycles. Sets all of them to zero. + */ void reset(); - //// - /// \brief Stops (pauses) the timer. - /// - /// Pauses all time and cycle measurements such as real time, CPU time and - /// CPU cycles, but does not set them to zero. + /** + * \brief Stops (pauses) the timer. + * + * Pauses all time and cycle measurements such as real time, CPU time and + * CPU cycles, but does not set them to zero. + */ void stop(); - ///// - /// \brief Starts timer. - /// - /// Starts all time and cycle measurements such as real time, CPU time and - /// CPU cycles. This method can be used also after using the \ref stop method. - /// The timer then continues measuring the time without reseting. + /** + * \brief Starts timer. + * + * Starts all time and cycle measurements such as real time, CPU time and + * CPU cycles. This method can be used also after using the \ref stop + * method. The timer then continues measuring the time without reseting. + */ void start(); - ///// - /// \brief Returns the elapsed time on given timer. - /// - /// It returns the elapsed time (in seconds) between calling the \ref start and \ref stop methods. - /// Starts counting the real time after the method \ref start is called and - /// pauses when the method \ref stop is called. - /// If the timer has been started more then once without resetting, - /// the real time is counted by adding all intervals (between \ref start and \ref stop - /// methods) together. - /// This function can be called while the timer is running, there is no - /// need to use \ref stop method first. + /** + * \brief Returns the elapsed real time on this timer. + * + * This method returns the real time elapsed so far (in seconds). + * This method can be called while the timer is running, there is no + * need to use \ref stop method first. + */ double getRealTime() const; - ///// - /// \brief Returns the elapsed CPU time on given timer. - /// - /// The CPU time is measured in seconds. - /// CPU time is the amount of time for which a central processing unit (CPU) - /// was used for processing instructions of a computer program or operating system. - /// The CPU time is measured by adding the amount of CPU time between \ref start and \ref stop - /// methods together. + /** + * \brief Returns the elapsed CPU time on this timer. + * + * This method returns the CPU time (i.e. time the CPU spent by processing + * this process) elapsed so far (in seconds). This method can be called + * while the timer is running, there is no need to use \ref stop method + * first. + */ double getCPUTime() const; - /// \brief Returns the number of CPU cycles (machine cycles). - /// - /// CPU cycles are counted by adding the number of CPU cycles between \ref start and \ref stop - /// methods together. + /** + * \brief Returns the number of CPU cycles (machine cycles) elapsed on this timer. + * + * CPU cycles are counted by adding the number of CPU cycles between + * \ref start and \ref stop methods together. + */ unsigned long long int getCPUCycles() const; - /// \brief Writes a record into the \e logger. - /// - /// \param logger Name of Logger object. - /// \param logLevel A non-negative integer recording the log record indent. + /** + * \brief Writes a record into the \e logger. + * + * \param logger Name of Logger object. + * \param logLevel A non-negative integer recording the log record indent. + * + * \par Example + * \include TimerExampleLogger.cpp + * \par Output + * \include TimerExampleLogger.out + */ bool writeLog( Logger& logger, int logLevel = 0 ) const; protected: @@ -95,43 +109,44 @@ class Timer using TimePoint = typename std::chrono::high_resolution_clock::time_point; using Duration = typename std::chrono::high_resolution_clock::duration; - /// \brief Function for measuring the real time. + /** + * \brief Function for measuring the real time. + */ TimePoint readRealTime() const; - /// \brief Function for measuring the CPU time. - /// - /// CPU time is the amount of time for which a central processing unit (CPU) - /// was used for processing instructions of a computer program or operating system. + /** + * \brief Function for measuring the CPU time. + */ double readCPUTime() const; - /// \brief Function for counting the number of CPU cycles (machine cycles). + /** + * \brief Function for counting the number of CPU cycles (machine cycles). + */ unsigned long long int readCPUCycles() const; + /** + * \brief Converts the real time into seconds as a floating point number. + */ double durationToDouble( const Duration& duration ) const; - TimePoint initialRealTime; - Duration totalRealTime; + /** + * \brief Time Stamp Counter returning number of CPU cycles since reset. + * + * Only for x86 compatible CPUs. + */ + inline unsigned long long rdtsc() const; - double initialCPUTime, totalCPUTime; + TimePoint initialRealTime; - unsigned long long int initialCPUCycles, totalCPUCycles; + Duration totalRealTime; - /// \brief Saves information about the state of given timer. - /// - /// Knows whether the timer is currently stopped or it is running. - bool stopState; + double initialCPUTime, totalCPUTime; - /// \brief Time Stamp Counter returning number of CPU cycles since reset. - /// - /// Only for x86 compatibile CPUs. - inline unsigned long long rdtsc() const - { - unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); - return ( ( unsigned long long ) lo ) | ( ( ( unsigned long long ) hi ) << 32 ); - } + unsigned long long int initialCPUCycles, totalCPUCycles; + + bool stopState; }; } // namespace TNL -#include <TNL/Timer_impl.h> +#include <TNL/Timer.hpp> diff --git a/src/TNL/Timer_impl.h b/src/TNL/Timer.hpp similarity index 93% rename from src/TNL/Timer_impl.h rename to src/TNL/Timer.hpp index 5a1cec336efcb1b226949064a62a9f573eb1ee61..b4a4fa63996a5a9a867fb773d67183659e9efe6c 100644 --- a/src/TNL/Timer_impl.h +++ b/src/TNL/Timer.hpp @@ -78,6 +78,14 @@ inline unsigned long long int Timer::getCPUCycles() const return this->totalCPUCycles; } +inline bool Timer::writeLog( Logger& logger, int logLevel ) const +{ + logger.writeParameter< double >( "Real time:", this->getRealTime(), logLevel ); + logger.writeParameter< double >( "CPU time:", this->getCPUTime(), logLevel ); + logger.writeParameter< unsigned long long int >( "CPU Cycles:", this->getCPUCycles(), logLevel ); + return true; +} + inline typename Timer::TimePoint Timer::readRealTime() const { return std::chrono::high_resolution_clock::now(); @@ -105,13 +113,11 @@ inline double Timer::durationToDouble( const Duration& duration ) const return dur.count(); } - -inline bool Timer::writeLog( Logger& logger, int logLevel ) const +inline unsigned long long Timer::rdtsc() const { - logger.writeParameter< double >( "Real time:", this->getRealTime(), logLevel ); - logger.writeParameter< double >( "CPU time:", this->getCPUTime(), logLevel ); - logger.writeParameter< unsigned long long int >( "CPU Cycles:", this->getCPUCycles(), logLevel ); - return true; + unsigned hi, lo; + __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); + return ( ( unsigned long long ) lo ) | ( ( ( unsigned long long ) hi ) << 32 ); } } // namespace TNL diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp index b35dba1726d34d729906b6c0cc4d3a5f753da06f..1d681a6df133001011cf01c7bc0ba8a4ea671859 100644 --- a/src/Tools/tnl-diff.cpp +++ b/src/Tools/tnl-diff.cpp @@ -9,6 +9,7 @@ /* See Copyright Notice in tnl/Copyright */ #include "tnl-diff.h" +#include <TNL/Exceptions/ObjectTypeDetectionFailure.h> #include <TNL/Meshes/DummyMesh.h> #include <TNL/Meshes/Grid.h> @@ -50,10 +51,13 @@ int main( int argc, char* argv[] ) return EXIT_SUCCESS; }*/ String meshType; - if( ! getObjectType( meshFile, meshType ) ) + try { - std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl; - return EXIT_FAILURE; + meshType = getObjectType( meshFile ); + } + catch(...) + { + throw Exceptions::ObjectTypeDetectionFailure( meshFile, "mesh" ); } std::cout << meshType << " detected in " << meshFile << " file." << std::endl; const std::vector< String > parsedMeshType = parseObjectType( meshType ); diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index 0f90bc28aa400c22aeda2ec8eabbb3e99e07fbab..5443f953ac1163b649d5b4afa4cf12121183e709 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -227,8 +227,12 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con } if( verbose ) std::cout << "Processing files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "... \r" << std::flush; - if( ! v1.load( inputFiles[ i ] ) || - ! v2.load( inputFiles[ i + 1 ] ) ) + try + { + v1.load( inputFiles[ i ] ); + v2.load( inputFiles[ i + 1 ] ); + } + catch(...) { std::cerr << "Unable to read the files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "." << std::endl; outputFile.close(); @@ -246,22 +250,12 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con { if( verbose ) std::cout << "Reading the file " << inputFiles[ 0 ] << "... \r" << std::flush; - if( ! v1.load( inputFiles[ 0 ] ) ) - { - std::cerr << "Unable to read the file " << inputFiles[ 0 ] << std::endl; - outputFile.close(); - return false; - } + v1.load( inputFiles[ 0 ] ); file1 = inputFiles[ 0 ]; } if( verbose ) std::cout << "Processing the files " << inputFiles[ 0 ] << " and " << inputFiles[ i ] << "... \r" << std::flush; - if( ! v2.load( inputFiles[ i ] ) ) - { - std::cerr << "Unable to read the file " << inputFiles[ 1 ] << std::endl; - outputFile.close(); - return false; - } + v2.load( inputFiles[ i ] ); if( ! exactMatch ) outputFile << std::setw( 6 ) << ( i - 1 ) * snapshotPeriod << " "; file2 = inputFiles[ i ]; @@ -273,13 +267,8 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con i = half; if( verbose ) std::cout << "Processing files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "... \r" << std::flush; - if( ! v1.load( inputFiles[ i - half ] ) || - ! v2.load( inputFiles[ i ] ) ) - { - std::cerr << "Unable to read the files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "." << std::endl; - outputFile.close(); - return false; - } + v1.load( inputFiles[ i - half ] ); + v2.load( inputFiles[ i ] ); //if( snapshotPeriod != 0.0 ) if( ! exactMatch ) outputFile << std::setw( 6 ) << ( i - half ) * snapshotPeriod << " "; @@ -315,10 +304,7 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con if( writeDifference ) { - String differenceFileName; - differenceFileName = inputFiles[ i ]; - removeFileExtension( differenceFileName ); - differenceFileName += ".diff.tnl"; + String differenceFileName = removeFileNameExtension( inputFiles[ i ] ) + ".diff.tnl"; //diff.setLike( v1 ); diff = v1; diff -= v2; @@ -377,13 +363,8 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P } if( verbose ) std::cout << "Processing files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "... \r" << std::flush; - if( ! v1.load( inputFiles[ i ] ) || - ! v2.load( inputFiles[ i + 1 ] ) ) - { - std::cerr << "Unable to read the files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "." << std::endl; - outputFile.close(); - return false; - } + v1.load( inputFiles[ i ] ); + v2.load( inputFiles[ i + 1 ] ); outputFile << std::setw( 6 ) << i/2 * snapshotPeriod << " "; i++; } @@ -393,21 +374,11 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P { if( verbose ) std::cout << "Reading the file " << inputFiles[ 0 ] << "... \r" << std::flush; - if( ! v1.load( inputFiles[ 0 ] ) ) - { - std::cerr << "Unable to read the file " << inputFiles[ 0 ] << std::endl; - outputFile.close(); - return false; - } + v1.load( inputFiles[ 0 ] ); } if( verbose ) std::cout << "Processing the files " << inputFiles[ 0 ] << " and " << inputFiles[ i ] << "... \r" << std::flush; - if( ! v2.load( inputFiles[ i ] ) ) - { - std::cerr << "Unable to read the file " << inputFiles[ 1 ] << std::endl; - outputFile.close(); - return false; - } + v2.load( inputFiles[ i ] ); outputFile << std::setw( 6 ) << ( i - 1 ) * snapshotPeriod << " "; } if( mode == "halves" ) @@ -417,13 +388,8 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P i = half; if( verbose ) std::cout << "Processing files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "... \r" << std::flush; - if( ! v1.load( inputFiles[ i - half ] ) || - ! v2.load( inputFiles[ i ] ) ) - { - std::cerr << "Unable to read the files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "." << std::endl; - outputFile.close(); - return false; - } + v1.load( inputFiles[ i - half ] ); + v2.load( inputFiles[ i ] ); //if( snapshotPeriod != 0.0 ) outputFile << std::setw( 6 ) << ( i - half ) * snapshotPeriod << " "; } @@ -450,10 +416,7 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P if( writeDifference ) { - String differenceFileName; - differenceFileName = inputFiles[ i ]; - removeFileExtension( differenceFileName ); - differenceFileName += ".diff.tnl"; + String differenceFileName = removeFileNameExtension( inputFiles[ i ] ) + ".diff.tnl"; Containers::Vector< Real, Devices::Host, Index > diff; diff.setLike( v1 ); diff = v1; @@ -471,11 +434,9 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P template< typename MeshPointer, typename Value, typename Real, typename Index > bool computeDifference( const MeshPointer& meshPointer, const String& objectType, const Config::ParameterContainer& parameters ) { - if( objectType == "Functions::MeshFunction" || - objectType == "tnlMeshFunction" ) // TODO: remove deprecated type name + if( objectType == "Functions::MeshFunction" ) return computeDifferenceOfMeshFunctions< MeshPointer, Value, Real, Index >( meshPointer, parameters ); - if( objectType == "Containers::Vector" || - objectType == "tnlVector" || objectType == "tnlSharedVector" ) // TODO: remove deprecated type name + if( objectType == "Containers::Vector" ) return computeDifferenceOfVectors< MeshPointer, Value, Real, Index >( meshPointer, parameters ); std::cerr << "Unknown object type " << objectType << "." << std::endl; return false; @@ -489,19 +450,12 @@ bool setIndexType( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters ) { String indexType; - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // - indexType = parsedObjectType[ 4 ]; - if( parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlSharedVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlVector" ) // + if( parsedObjectType[ 0 ] == "Containers::Vector" ) indexType = parsedObjectType[ 3 ]; - if( parsedObjectType[ 0 ] == "Functions::MeshFunction" || - parsedObjectType[ 0 ] == "tnlMeshFunction" ) // TODO: remove deprecated type names + if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ) return computeDifference< MeshPointer, Value, Real, typename MeshPointer::ObjectType::IndexType >( meshPointer, parsedObjectType[ 0 ], parameters ); - + if( indexType == "int" ) return computeDifference< MeshPointer, Value, Real, int >( meshPointer, parsedObjectType[ 0 ], parameters ); if( indexType == "long-int" ) @@ -569,16 +523,9 @@ bool setValueType( const MeshPointer& meshPointer, { String elementType; - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // - elementType = parsedObjectType[ 2 ]; - if( parsedObjectType[ 0 ] == "Functions::MeshFunction" || - parsedObjectType[ 0 ] == "tnlMeshFunction" ) // TODO: remove deprecated type names + if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ) elementType = parsedObjectType[ 3 ]; - if( parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlSharedVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlVector" ) // + if( parsedObjectType[ 0 ] == "Containers::Vector" ) elementType = parsedObjectType[ 1 ]; @@ -616,16 +563,22 @@ bool processFiles( const Config::ParameterContainer& parameters ) MeshPointer meshPointer; if( meshFile != "" ) - if( ! meshPointer->load( meshFile ) ) + { + try + { + meshPointer->load( meshFile ); + } + catch(...) { std::cerr << "I am not able to load mesh from the file " << meshFile << "." << std::endl; return false; } + } String objectType; try { - getObjectType( inputFiles[ 0 ], objectType ); + objectType = getObjectType( inputFiles[ 0 ] ); } catch( std::ios_base::failure exception ) { diff --git a/src/Tools/tnl-grid-setup.h b/src/Tools/tnl-grid-setup.h index 48da6a16dc16695c7eef8aa2d212a0a30ac17ba5..896d3abb971571abcededb8bed75dcd9cb0f1fff 100644 --- a/src/Tools/tnl-grid-setup.h +++ b/src/Tools/tnl-grid-setup.h @@ -36,7 +36,11 @@ bool setupGrid( const Config::ParameterContainer& parameters ) grid.setDimensions( CoordinatesType( sizeX ) ); std::cout << "Setting dimensions to ... " << sizeX << std::endl; std::cout << "Writing the grid to the file " << outputFile << " .... "; - if( ! grid.save( outputFile ) ) + try + { + grid.save( outputFile ); + } + catch(...) { std::cerr << "[ FAILED ] " << std::endl; return false; @@ -70,7 +74,11 @@ bool setupGrid( const Config::ParameterContainer& parameters ) std::cout << "Setting dimensions to ... " << grid.getDimensions() << std::endl; std::cout << "Writing the grid to the file " << outputFile << " .... "; - if( ! grid.save( outputFile ) ) + try + { + grid.save( outputFile ); + } + catch(...) { std::cerr << "[ FAILED ] " << std::endl; return false; @@ -108,7 +116,11 @@ bool setupGrid( const Config::ParameterContainer& parameters ) std::cout << "Setting dimensions to ... " << grid.getDimensions() << std::endl; std::cout << "Writing the grid to the file " << outputFile << " .... "; - if( ! grid.save( outputFile ) ) + try + { + grid.save( outputFile ); + } + catch(...) { std::cerr << "[ FAILED ] " << std::endl; return false; diff --git a/src/Tools/tnl-grid-to-mesh.cpp b/src/Tools/tnl-grid-to-mesh.cpp index 2cd56244676ce70f700775943cfe970105ed95cd..d2d03a29a850c38b8bb940102ae1a1f235d193ab 100644 --- a/src/Tools/tnl-grid-to-mesh.cpp +++ b/src/Tools/tnl-grid-to-mesh.cpp @@ -186,7 +186,12 @@ struct GridConverter return false; } - if( ! mesh.save( outputFileName ) ) { + try + { + mesh.save( outputFileName ); + } + catch(...) + { std::cerr << "Failed to save the mesh to file '" << outputFileName << "'." << std::endl; return false; } diff --git a/src/Tools/tnl-image-converter.cpp b/src/Tools/tnl-image-converter.cpp index f06ba841df524c4bd7522b81dc947f8080c0debe..8a7fccf5009f9c101b3f2ad85c983635aa96101d 100644 --- a/src/Tools/tnl-image-converter.cpp +++ b/src/Tools/tnl-image-converter.cpp @@ -77,9 +77,7 @@ bool processImages( const Config::ParameterContainer& parameters ) meshFunction.setMesh( grid ); if( ! pgmImage.read( roi, meshFunction ) ) return false; - String outputFileName( fileName ); - removeFileExtension( outputFileName ); - outputFileName += ".tnl"; + String outputFileName = removeFileNameExtension( fileName ) + ".tnl"; std::cout << "Writing image data to " << outputFileName << std::endl; meshFunction.save( outputFileName ); pgmImage.close(); @@ -104,9 +102,7 @@ bool processImages( const Config::ParameterContainer& parameters ) meshFunction.setMesh( grid ); if( ! pngImage.read( roi, meshFunction ) ) return false; - String outputFileName( fileName ); - removeFileExtension( outputFileName ); - outputFileName += ".tnl"; + String outputFileName = removeFileNameExtension( fileName ) + ".tnl"; std::cout << "Writing image data to " << outputFileName << std::endl; meshFunction.save( outputFileName ); pgmImage.close(); @@ -131,9 +127,7 @@ bool processImages( const Config::ParameterContainer& parameters ) meshFunction.setMesh( grid ); if( ! jpegImage.read( roi, meshFunction ) ) return false; - String outputFileName( fileName ); - removeFileExtension( outputFileName ); - outputFileName += ".tnl"; + String outputFileName = removeFileNameExtension( fileName ) + ".tnl"; std::cout << "Writing image data to " << outputFileName << std::endl; meshFunction.save( outputFileName ); pgmImage.close(); @@ -150,7 +144,11 @@ bool processFiles( const Config::ParameterContainer& parameters ) String meshFile = parameters.getParameter< String >( "mesh-file" ); Meshes::Grid< 2, double, Devices::Host, int > grid; - if( ! grid.load( meshFile ) ) + try + { + grid.load( meshFile ); + } + catch(...) { std::cerr << "I am not able to load the mesh file " << meshFile << "." << std::endl; return false; @@ -160,7 +158,11 @@ bool processFiles( const Config::ParameterContainer& parameters ) { const String& fileName = inputFiles[ i ]; std::cout << "Processing file " << fileName << "... "; - if( ! vector.load( fileName ) ) + try + { + vector.load( fileName ); + } + catch(...) { std::cerr << "I am not able to load data from a file " << fileName << "." << std::endl; return false; @@ -168,9 +170,7 @@ bool processFiles( const Config::ParameterContainer& parameters ) if( imageFormat == "pgm" || imageFormat == "pgm-binary" || imageFormat == "pgm-ascii" ) { Images::PGMImage< int > image; - String outputFileName( fileName ); - removeFileExtension( outputFileName ); - outputFileName += ".pgm"; + String outputFileName = removeFileNameExtension( fileName ) + ".pgm"; if ( imageFormat == "pgm" || imageFormat == "pgm-binary") image.openForWrite( outputFileName, grid, true ); if ( imageFormat == "pgm-ascii" ) @@ -182,9 +182,7 @@ bool processFiles( const Config::ParameterContainer& parameters ) if( imageFormat == "png" ) { Images::PNGImage< int > image; - String outputFileName( fileName ); - removeFileExtension( outputFileName ); - outputFileName += ".png"; + String outputFileName = removeFileNameExtension( fileName ) + ".png"; image.openForWrite( outputFileName, grid ); image.write( grid, vector ); image.close(); @@ -192,9 +190,7 @@ bool processFiles( const Config::ParameterContainer& parameters ) if( imageFormat == "jpg" ) { Images::JPEGImage< int > image; - String outputFileName( fileName ); - removeFileExtension( outputFileName ); - outputFileName += ".jpg"; + String outputFileName = removeFileNameExtension( fileName ) + ".jpg"; image.openForWrite( outputFileName, grid ); image.write( grid, vector ); image.close(); diff --git a/src/Tools/tnl-init.cpp b/src/Tools/tnl-init.cpp index 0695d62e106b6959c852f96c27f7a398025e4202..1bdadb07aef7896e4ff9943f69bcf5ed71d33478 100644 --- a/src/Tools/tnl-init.cpp +++ b/src/Tools/tnl-init.cpp @@ -64,7 +64,11 @@ int main( int argc, char* argv[] ) String meshFile = parameters. getParameter< String >( "mesh" ); String meshType; - if( ! getObjectType( meshFile, meshType ) ) + try + { + meshType = getObjectType( meshFile ); + } + catch(...) { std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl; return EXIT_FAILURE; diff --git a/src/Tools/tnl-init.h b/src/Tools/tnl-init.h index 5530ee5ad5a68107242c01092409d77bee2ac196..a393a7a7cf25523dfbf40034cd5833da5ebb4716 100644 --- a/src/Tools/tnl-init.h +++ b/src/Tools/tnl-init.h @@ -47,8 +47,7 @@ bool renderFunction( const Config::ParameterContainer& parameters ) //suppose global mesh loaded from single file String meshFile = parameters.getParameter< String >( "mesh" ); std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl; - if( ! globalMesh.load( meshFile ) ) - return false; + globalMesh.load( meshFile ); // TODO: This should work with no overlaps distributedMesh.template setGlobalGrid<CommunicatorType>(globalMesh); @@ -61,8 +60,7 @@ bool renderFunction( const Config::ParameterContainer& parameters ) { String meshFile = parameters.getParameter< String >( "mesh" ); std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl; - if( ! meshPointer->load( meshFile ) ) - return false; + meshPointer->load( meshFile ); } typedef Functions::TestFunction< MeshType::getMeshDimension(), RealType > FunctionType; @@ -107,7 +105,7 @@ bool renderFunction( const Config::ParameterContainer& parameters ) if( finalTime > 0.0 ) { String extension = getFileExtension( outputFile ); - removeFileExtension( outputFile ); + outputFile = removeFileNameExtension( outputFile ); outputFile += "-"; FileName outputFileName; outputFileName.setFileNameBase( outputFile.getString() ); @@ -125,10 +123,7 @@ bool renderFunction( const Config::ParameterContainer& parameters ) return false; } else - { - if( ! meshFunction->save( outputFile) ) - return false; - } + meshFunction->save( outputFile); time += tau; step ++; diff --git a/src/Tools/tnl-lattice-init.h b/src/Tools/tnl-lattice-init.h index 0b42a72ead2ea71758697dbf70190fb15639094c..557bf53594f158016373d1e915bc484a5c16546c 100644 --- a/src/Tools/tnl-lattice-init.h +++ b/src/Tools/tnl-lattice-init.h @@ -12,6 +12,7 @@ #include <TNL/Object.h> #include <TNL/Config/ParameterContainer.h> +#include <TNL/Exceptions/ObjectTypeDetectionFailure.h> #include <TNL/Meshes/Grid.h> #include <TNL/Meshes/GridEntity.h> #include <TNL/Functions/MeshFunction.h> @@ -163,11 +164,7 @@ bool performExtrude( const Config::ParameterContainer& parameters, } } String outputFile = parameters.getParameter< String >( "output-file" ); - if( ! f.save( outputFile ) ) - { - std::cerr << "Unable to save output file " << outputFile << "." << std::endl; - return false; - } + f.save( outputFile ); return true; } @@ -179,14 +176,22 @@ readProfileMeshFunction( const Config::ParameterContainer& parameters ) String profileMeshFile = parameters.getParameter< String >( "profile-mesh" ); using ProfileMeshPointer = Pointers::SharedPointer< typename ProfileMeshFunction::MeshType >; ProfileMeshPointer profileMesh; - if( ! profileMesh->load( profileMeshFile ) ) + try + { + profileMesh->load( profileMeshFile ); + } + catch(...) { std::cerr << "Unable to load the profile mesh file." << profileMeshFile << "." << std::endl; return false; } String profileFile = parameters.getParameter< String >( "profile-file" ); ProfileMeshFunction profileMeshFunction( profileMesh ); - if( ! profileMeshFunction.load( profileFile ) ) + try + { + profileMeshFunction.load( profileFile ); + } + catch(...) { std::cerr << "Unable to load profile mesh function from the file " << profileFile << "." << std::endl; return false; @@ -194,7 +199,11 @@ readProfileMeshFunction( const Config::ParameterContainer& parameters ) String meshFile = parameters.getParameter< String >( "mesh" ); using MeshPointer = Pointers::SharedPointer< Mesh >; MeshPointer mesh; - if( ! mesh->load( meshFile ) ) + try + { + mesh->load( meshFile ); + } + catch(...) { std::cerr << "Unable to load 3D mesh from the file " << meshFile << "." << std::endl; return false; @@ -204,7 +213,11 @@ readProfileMeshFunction( const Config::ParameterContainer& parameters ) if( parameters.checkParameter( "input-file" ) ) { const String& inputFile = parameters.getParameter< String >( "input-file" ); - if( ! meshFunction.load( inputFile ) ) + try + { + meshFunction.load( inputFile ); + } + catch(...) { std::cerr << "Unable to load " << inputFile << "." << std::endl; return false; @@ -221,10 +234,13 @@ bool resolveProfileReal( const Config::ParameterContainer& parameters ) { String profileFile = parameters. getParameter< String >( "profile-file" ); String meshFunctionType; - if( ! getObjectType( profileFile, meshFunctionType ) ) + try { - std::cerr << "I am not able to detect the mesh function type from the profile file " << profileFile << "." << std::endl; - return EXIT_FAILURE; + meshFunctionType = getObjectType( profileFile ); + } + catch(...) + { + throw Exceptions::ObjectTypeDetectionFailure( profileFile, "mesh" ); } //std::cout << meshFunctionType << " detected in " << profileFile << " file." << std::endl; const std::vector< String > parsedMeshFunctionType = parseObjectType( meshFunctionType ); @@ -277,10 +293,13 @@ bool resolveMesh( const Config::ParameterContainer& parameters ) { String meshFile = parameters.getParameter< String >( "mesh" ); String meshType; - if( ! getObjectType( meshFile, meshType ) ) + try { - std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl; - return EXIT_FAILURE; + meshType = getObjectType( meshFile ); + } + catch(...) + { + throw Exceptions::ObjectTypeDetectionFailure( meshFile, "mesh" ); } std::cout << meshType << " detected in " << meshFile << " file." << std::endl; const std::vector< String > parsedMeshType = parseObjectType( meshType ); @@ -372,10 +391,13 @@ bool resolveProfileMeshType( const Config::ParameterContainer& parameters ) { String meshFile = parameters. getParameter< String >( "profile-mesh" ); String meshType; - if( ! getObjectType( meshFile, meshType ) ) + try { - std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl; - return EXIT_FAILURE; + meshType = getObjectType( meshFile ); + } + catch(...) + { + throw Exceptions::ObjectTypeDetectionFailure( meshFile, "mesh" ); } std::cout << meshType << " detected in " << meshFile << " file." << std::endl; const std::vector< String > parsedMeshType = parseObjectType( meshType ); diff --git a/src/Tools/tnl-mesh-converter.cpp b/src/Tools/tnl-mesh-converter.cpp index dd7ec0b2049ed7421ff6ec72ad4aeece22ff0e34..cd9de1a597c266722092d1851ac41e2c8dfa7217 100644 --- a/src/Tools/tnl-mesh-converter.cpp +++ b/src/Tools/tnl-mesh-converter.cpp @@ -78,8 +78,14 @@ struct MeshConverter return false; } - if( outputFormat == "tnl" ) { - if( ! mesh.save( outputFileName ) ) { + if( outputFormat == "tnl" ) + { + try + { + mesh.save( outputFileName ); + } + catch(...) + { std::cerr << "Failed to save the mesh to file '" << outputFileName << "'." << std::endl; return false; } diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h index e4ae274ae63be5e1dc2cd476917b3d4abd6f55a8..64c09e32bb8263de055f443c60ab1627d4424839 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -16,7 +16,6 @@ #include <TNL/Config/ParameterContainer.h> #include <TNL/String.h> #include <TNL/Containers/Vector.h> -#include <TNL/Containers/MultiVector.h> #include <TNL/Meshes/Grid.h> #include <TNL/Functions/MeshFunction.h> #include <TNL/Functions/VectorField.h> @@ -30,8 +29,7 @@ bool getOutputFileName( const String& inputFileName, const String& outputFormat, String& outputFileName ) { - outputFileName = inputFileName; - removeFileExtension( outputFileName ); + outputFileName = removeFileNameExtension( inputFileName ); if( outputFormat == "gnuplot" ) { outputFileName += ".gplt"; @@ -55,7 +53,11 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer, MeshFunction function( meshPointer ); std::cout << "Mesh function: " << function.getType() << std::endl; - if( ! function.load( inputFileName ) ) + try + { + function.load( inputFileName ); + } + catch(...) { std::cerr << "Unable to load mesh function from a file " << inputFileName << "." << std::endl; return false; @@ -83,7 +85,11 @@ bool writeVectorField( const typename VectorField::FunctionType::MeshPointer& me VectorField field( meshPointer ); std::cout << "VectorField: " << field.getType() << std::endl; - if( ! field.load( inputFileName ) ) + try + { + field.load( inputFileName ); + } + catch(...) { std::cerr << "Unable to load vector field from a file " << inputFileName << "." << std::endl; return false; @@ -244,37 +250,16 @@ bool convertObject( const MeshPointer& meshPointer, std::cout << " writing to " << outputFileName << " ... " << std::flush; - if( parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlSharedVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlVector" ) // + if( parsedObjectType[ 0 ] == "Containers::Vector" ) { using MeshType = typename MeshPointer::ObjectType; // FIXME: why is MeshType::GlobalIndexType not the same as Index? // Containers::Vector< Value, Devices::Host, Index > vector; Containers::Vector< Value, Devices::Host, typename MeshType::GlobalIndexType > vector; - if( ! vector.load( inputFileName ) ) - return false; + vector.load( inputFileName ); Functions::MeshFunction< MeshType, MeshType::getMeshDimension(), Value > mf; mf.bind( meshPointer, vector ); - if( ! mf.write( outputFileName, outputFormat ) ) - return false; - } - - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // - { - Containers::MultiVector< Dimension, Value, Devices::Host, Index > multiVector; - if( ! multiVector. load( inputFileName ) ) - return false; - typedef Meshes::Grid< Dimension, Real, Devices::Host, Index > GridType; - typedef typename GridType::PointType PointType; - typedef typename GridType::CoordinatesType CoordinatesType; -// GridType grid; -// grid. setDomain( PointType( 0.0 ), PointType( 1.0 ) ); -// grid. setDimensions( CoordinatesType( multiVector. getDimensions() ) ); -// if( ! grid. write( multiVector, outputFileName, outputFormat ) ) - return false; + mf.write( outputFileName, outputFormat ); } return true; } @@ -286,13 +271,7 @@ bool setDimension( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters ) { int dimensions( 0 ); - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // - dimensions = atoi( parsedObjectType[ 1 ]. getString() ); - if( parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedVector" ) // + if( parsedObjectType[ 0 ] == "Containers::Vector" ) dimensions = 1; switch( dimensions ) { @@ -314,13 +293,7 @@ bool setIndexType( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters ) { String indexType; - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // - indexType = parsedObjectType[ 4 ]; - if( parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlSharedVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlVector" ) // + if( parsedObjectType[ 0 ] == "Containers::Vector" ) indexType = parsedObjectType[ 3 ]; if( indexType == "int" ) @@ -391,13 +364,7 @@ bool setValueType( const MeshPointer& meshPointer, String elementType; // TODO: Fix this even for arrays - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // - elementType = parsedObjectType[ 2 ]; - if( parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlSharedVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlVector" ) // + if( parsedObjectType[ 0 ] == "Containers::Vector" ) elementType = parsedObjectType[ 1 ]; if( elementType == "float" ) @@ -419,8 +386,7 @@ bool setValueType( const MeshPointer& meshPointer, std::cerr << "Unable to parse object type " << elementType << "." << std::endl; return false; } - if( parsedValueType[ 0 ] == "Containers::StaticVector" || - parsedValueType[ 0 ] == "Containers::StaticVector" ) // TODO: remove deprecated type names + if( parsedValueType[ 0 ] == "Containers::StaticVector" ) return setTupleType< MeshPointer >( meshPointer, inputFileName, parsedObjectType, parsedValueType, parameters ); std::cerr << "Unknown element type " << elementType << "." << std::endl; @@ -473,35 +439,34 @@ struct FilesProcessor } String objectType; - if( ! getObjectType( inputFiles[ i ], objectType ) ) - std::cerr << "unknown object ... SKIPPING!" << std::endl; - else + try { - if( verbose ) - std::cout << objectType << " detected ... "; - - const std::vector< String > parsedObjectType = parseObjectType( objectType ); - if( ! parsedObjectType.size() ) - { - std::cerr << "Unable to parse object type " << objectType << "." << std::endl; - error = true; - continue; - } - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" || // - parsedObjectType[ 0 ] == "tnlSharedVector" || // - parsedObjectType[ 0 ] == "tnlVector" ) // - setValueType< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); - if( parsedObjectType[ 0 ] == "Functions::MeshFunction" || - parsedObjectType[ 0 ] == "tnlMeshFunction" ) // TODO: remove deprecated type names - setMeshFunction< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); - if( parsedObjectType[ 0 ] == "Functions::VectorField" ) - setVectorFieldSize< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); - if( verbose ) - std::cout << "[ OK ]. " << std::endl; + objectType = getObjectType( inputFiles[ i ] ); + } + catch(...) + { + std::cerr << "unknown object ... SKIPPING!" << std::endl; + continue; } + + if( verbose ) + std::cout << objectType << " detected ... "; + + const std::vector< String > parsedObjectType = parseObjectType( objectType ); + if( ! parsedObjectType.size() ) + { + std::cerr << "Unable to parse object type " << objectType << "." << std::endl; + error = true; + continue; + } + if( parsedObjectType[ 0 ] == "Containers::Vector" ) + setValueType< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); + if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ) + setMeshFunction< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); + if( parsedObjectType[ 0 ] == "Functions::VectorField" ) + setVectorFieldSize< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); + if( verbose ) + std::cout << "[ OK ]. " << std::endl; } if( verbose ) std::cout << std::endl; diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index d2bddbd29640e87f3c8bd3029a5c5e05a5e42cc4..3790b35dc9935e1dba49676b0b0ff1ba0245e82c 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.h @@ -10,7 +10,7 @@ #pragma once -#ifdef HAVE_GTEST +#ifdef HAVE_GTEST #include <type_traits> #include <TNL/Containers/Array.h> @@ -158,7 +158,7 @@ TYPED_TEST( ArrayTest, constructors ) EXPECT_EQ( w.getData(), data ); ArrayType z1( w ); - EXPECT_EQ( z1.getData(), data ); + //EXPECT_EQ( z1.getData(), data ); EXPECT_EQ( z1.getSize(), 10 ); ArrayType z2( w, 1 ); @@ -169,6 +169,31 @@ TYPED_TEST( ArrayTest, constructors ) EXPECT_EQ( z3.getData(), data + 2 ); EXPECT_EQ( z3.getSize(), 3 ); } + + ArrayType w( v ); + EXPECT_EQ( w.getSize(), v.getSize() ); + for( int i = 0; i < 10; i++ ) + EXPECT_EQ( v.getElement( i ), w.getElement( i ) ); + v.reset(); + EXPECT_EQ( w.getSize(), 10 ); + + ArrayType a1 { 1, 2, 3 }; + EXPECT_EQ( a1.getElement( 0 ), 1 ); + EXPECT_EQ( a1.getElement( 1 ), 2 ); + EXPECT_EQ( a1.getElement( 2 ), 3 ); + + std::list< int > l = { 4, 5, 6 }; + ArrayType a2( l ); + EXPECT_EQ( a2.getElement( 0 ), 4 ); + EXPECT_EQ( a2.getElement( 1 ), 5 ); + EXPECT_EQ( a2.getElement( 2 ), 6 ); + + std::vector< int > q = { 7, 8, 9 }; + + ArrayType a3( q ); + EXPECT_EQ( a3.getElement( 0 ), 7 ); + EXPECT_EQ( a3.getElement( 1 ), 8 ); + EXPECT_EQ( a3.getElement( 2 ), 9 ); } TYPED_TEST( ArrayTest, setSize ) @@ -184,18 +209,22 @@ TYPED_TEST( ArrayTest, setSize ) ArrayType v( u ); EXPECT_EQ( v.getSize(), 10 ); - EXPECT_EQ( v.getData(), u.getData() ); + //EXPECT_EQ( v.getData(), u.getData() ); v.setSize( 11 ); EXPECT_EQ( u.getSize(), 10 ); EXPECT_EQ( v.getSize(), 11 ); EXPECT_NE( v.getData(), u.getData() ); - // cast to bool returns true iff size > 0 - EXPECT_TRUE( (bool) u ); - EXPECT_FALSE( ! u ); - u.setSize( 0 ); - EXPECT_FALSE( (bool) u ); - EXPECT_TRUE( ! u ); +} + +TYPED_TEST( ArrayTest, empty ) +{ + using ArrayType = typename TestFixture::ArrayType; + ArrayType u( 10 ); + + EXPECT_FALSE( u.empty() ); + u.reset(); + EXPECT_TRUE( u.empty() ); } TYPED_TEST( ArrayTest, setLike ) @@ -273,15 +302,19 @@ TYPED_TEST( ArrayTest, reset ) ArrayType u; u.setSize( 100 ); EXPECT_EQ( u.getSize(), 100 ); + EXPECT_FALSE( u.empty() ); EXPECT_NE( u.getData(), nullptr ); u.reset(); EXPECT_EQ( u.getSize(), 0 ); + EXPECT_TRUE( u.empty() ); EXPECT_EQ( u.getData(), nullptr ); u.setSize( 100 ); EXPECT_EQ( u.getSize(), 100 ); + EXPECT_FALSE( u.empty() ); EXPECT_NE( u.getData(), nullptr ); u.reset(); EXPECT_EQ( u.getSize(), 0 ); + EXPECT_TRUE( u.empty() ); EXPECT_EQ( u.getData(), nullptr ); } @@ -437,7 +470,9 @@ TYPED_TEST( ArrayTest, assignmentOperator ) u_host.setElement( i, i ); } - v.setValue( 0 ); + v = 72; //.setValue( 0 ); + for( int i = 0; i < 10; i++ ) + EXPECT_EQ( v.getElement( i ), 72 ); v = u; EXPECT_EQ( u, v ); @@ -450,6 +485,10 @@ TYPED_TEST( ArrayTest, assignmentOperator ) u_host.setValue( 0 ); u_host = u; EXPECT_EQ( u_host, u ); + + u = 5; + for( int i = 0; i < 10; i++ ) + EXPECT_EQ( u.getElement( i ), 5 ); } // test works only for arithmetic types @@ -504,11 +543,11 @@ TYPED_TEST( ArrayTest, SaveAndLoad ) for( int i = 0; i < 100; i ++ ) v.setElement( i, 3.14147 ); File file; - file.open( "test-file.tnl", IOMode::write ); - EXPECT_TRUE( v.save( file ) ); + file.open( "test-file.tnl", File::Mode::Out ); + v.save( file ); file.close(); - file.open( "test-file.tnl", IOMode::read ); - EXPECT_TRUE( u.load( file ) ); + file.open( "test-file.tnl", File::Mode::In ); + u.load( file ); EXPECT_EQ( u, v ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); @@ -523,24 +562,33 @@ TYPED_TEST( ArrayTest, boundLoad ) for( int i = 0; i < 100; i ++ ) v.setElement( i, 3.14147 ); File file; - file.open( "test-file.tnl", IOMode::write ); - EXPECT_TRUE( v.save( file ) ); + file.open( "test-file.tnl", File::Mode::Out ); + v.save( file ); file.close(); w.setSize( 100 ); u.bind( w ); - file.open( "test-file.tnl", IOMode::read ); - EXPECT_TRUE( u.boundLoad( file ) ); + file.open( "test-file.tnl", File::Mode::In ); + u.boundLoad( file ); EXPECT_EQ( u, v ); EXPECT_EQ( u.getData(), w.getData() ); u.setSize( 50 ); - file.open( "test-file.tnl", IOMode::read ); - EXPECT_FALSE( u.boundLoad( file ) ); + file.open( "test-file.tnl", File::Mode::In ); + bool catched( false ); + try + { + u.boundLoad( file ); + } + catch(...) + { + catched = true; + } + EXPECT_TRUE( catched ); u.reset(); - file.open( "test-file.tnl", IOMode::read ); - EXPECT_TRUE( u.boundLoad( file ) ); + file.open( "test-file.tnl", File::Mode::In ); + u.boundLoad( file ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); } @@ -553,8 +601,8 @@ TYPED_TEST( ArrayTest, referenceCountingConstructors ) ArrayType u( 10 ); ArrayType v( u ); ArrayType w( v ); - EXPECT_EQ( v.getData(), u.getData() ); - EXPECT_EQ( w.getData(), u.getData() ); + //EXPECT_EQ( v.getData(), u.getData() ); + //EXPECT_EQ( w.getData(), u.getData() ); // copies of a static array if( std::is_same< typename ArrayType::DeviceType, Devices::Host >::value ) { @@ -563,8 +611,8 @@ TYPED_TEST( ArrayTest, referenceCountingConstructors ) ArrayType v( u ); ArrayType w( v ); EXPECT_EQ( u.getData(), data ); - EXPECT_EQ( v.getData(), data ); - EXPECT_EQ( w.getData(), data ); + //EXPECT_EQ( v.getData(), data ); + //EXPECT_EQ( w.getData(), data ); } } diff --git a/src/UnitTests/Containers/ArrayViewTest.h b/src/UnitTests/Containers/ArrayViewTest.h index 7f3cc7bb338f8178b44fea3275feceabb709dd2f..061a2f5effcf45680c43d6645bdbbc383775bb76 100644 --- a/src/UnitTests/Containers/ArrayViewTest.h +++ b/src/UnitTests/Containers/ArrayViewTest.h @@ -149,12 +149,12 @@ TYPED_TEST( ArrayViewTest, constructors ) { using ArrayType = typename TestFixture::ArrayType; using ViewType = typename TestFixture::ViewType; - using ConstViewType = VectorView< const typename ArrayType::ValueType, typename ArrayType::DeviceType, typename ArrayType::IndexType >; + using ConstViewType = typename ViewType::ConstViewType; ArrayType a( 10 ); EXPECT_EQ( a.getSize(), 10 ); - ViewType v( a ); + ViewType v = a.getView(); EXPECT_EQ( v.getSize(), 10 ); EXPECT_EQ( v.getData(), a.getData() ); @@ -170,10 +170,10 @@ TYPED_TEST( ArrayViewTest, constructors ) // test initialization by const reference const ArrayType& b = a; - ConstViewType b_view( b ); - ConstViewType const_a_view( a ); + ConstViewType b_view = b.getConstView(); + ConstViewType const_a_view = a.getConstView(); - // test initialization of cons view by non-const view + // test initialization of const view by non-const view ConstViewType const_b_view( b_view ); } @@ -221,7 +221,8 @@ TYPED_TEST( ArrayViewTest, swap ) a.setValue( 0 ); b.setValue( 1 ); - ViewType u( a ), v( b ); + ViewType u = a.getView(); + ViewType v = b.getView(); u.swap( v ); EXPECT_EQ( u.getSize(), 20 ); EXPECT_EQ( v.getSize(), 10 ); @@ -238,7 +239,7 @@ TYPED_TEST( ArrayViewTest, reset ) ArrayType a; a.setSize( 100 ); - ViewType u( a ); + ViewType u = a.getView(); EXPECT_EQ( u.getSize(), 100 ); EXPECT_NE( u.getData(), nullptr ); u.reset(); @@ -306,6 +307,35 @@ TYPED_TEST( ArrayViewTest, elementwiseAccess ) testArrayViewElementwiseAccess( ArrayType() ); } +template< typename ArrayType > +void ArrayViewEvaluateTest( ArrayType& u ) +{ + using ValueType = typename ArrayType::ValueType; + using DeviceType = typename ArrayType::DeviceType; + using IndexType = typename ArrayType::IndexType; + using ViewType = ArrayView< ValueType, DeviceType, IndexType >; + ViewType v( u ); + + auto f = [] __cuda_callable__ ( IndexType i ) + { + return 3 * i % 4; + }; + + v.evaluate( f ); + for( int i = 0; i < 10; i++ ) + { + EXPECT_EQ( u.getElement( i ), 3 * i % 4 ); + EXPECT_EQ( v.getElement( i ), 3 * i % 4 ); + } +} + +TYPED_TEST( ArrayViewTest, evaluate ) +{ + using ArrayType = typename TestFixture::ArrayType; + ArrayType u( 10 ); + ArrayViewEvaluateTest( u ); +} + TYPED_TEST( ArrayViewTest, containsValue ) { using ArrayType = typename TestFixture::ArrayType; @@ -313,7 +343,7 @@ TYPED_TEST( ArrayViewTest, containsValue ) ArrayType a; a.setSize( 1024 ); - ViewType v( a ); + ViewType v = a.getView(); for( int i = 0; i < v.getSize(); i++ ) v.setElement( i, i % 10 ); @@ -332,7 +362,7 @@ TYPED_TEST( ArrayViewTest, containsOnlyValue ) ArrayType a; a.setSize( 1024 ); - ViewType v( a ); + ViewType v = a.getView(); for( int i = 0; i < v.getSize(); i++ ) v.setElement( i, i % 10 ); @@ -357,7 +387,9 @@ TYPED_TEST( ArrayViewTest, comparisonOperator ) b.setElement( i, 2 * i ); } - ViewType u( a ), v( a ), w( b ); + ViewType u = a.getView(); + ViewType v = a.getView(); + ViewType w = b.getView(); EXPECT_TRUE( u == u ); EXPECT_TRUE( u == v ); @@ -406,8 +438,8 @@ TYPED_TEST( ArrayViewTest, comparisonOperatorWithDifferentType ) b.setElement( i, i ); } - ViewType1 u( a ); - ViewType2 v( b ); + ViewType1 u = a.getView(); + ViewType2 v = b.getView(); EXPECT_TRUE( u == v ); EXPECT_FALSE( u != v ); @@ -431,8 +463,9 @@ TYPED_TEST( ArrayViewTest, assignmentOperator ) a_host.setElement( i, i ); } - ViewType u( a ), v( b ); - typename ViewType::HostType u_host( a_host ); + ViewType u = a.getView(); + ViewType v = b.getView(); + typename ViewType::HostType u_host = a_host.getView(); v.setValue( 0 ); v = u; @@ -472,7 +505,7 @@ void testArrayAssignmentWithDifferentType() } using ViewType = ArrayView< typename ArrayType::ValueType, typename ArrayType::DeviceType, typename ArrayType::IndexType >; - ViewType u( a ); + ViewType u = a.getView(); typename ViewType::HostType u_host( a_host ); using ShortViewType = ArrayView< short, typename ArrayType::DeviceType, short >; ShortViewType v( b ); diff --git a/src/UnitTests/Containers/CMakeLists.txt b/src/UnitTests/Containers/CMakeLists.txt index fe75ed458bad9e8e8314a4e351e86dcfc6870bea..99e4d677bc3df482484bb56b87cea9c71c3a6f15 100644 --- a/src/UnitTests/Containers/CMakeLists.txt +++ b/src/UnitTests/Containers/CMakeLists.txt @@ -58,16 +58,6 @@ ADD_EXECUTABLE( StaticVectorTest StaticVectorTest.cpp ) TARGET_COMPILE_OPTIONS( StaticVectorTest PRIVATE ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( StaticVectorTest ${GTEST_BOTH_LIBRARIES} ) -#IF( BUILD_CUDA ) -# CUDA_ADD_EXECUTABLE( MultiArrayTest MultiArrayTest.cu -# OPTIONS ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( MultiArrayTest ${GTEST_BOTH_LIBRARIES} ) -#ELSE( BUILD_CUDA ) -# ADD_EXECUTABLE( MultiArrayTest MultiArrayTest.cpp ) -# TARGET_COMPILE_OPTIONS( MultiArrayTest PRIVATE ${CXX_TESTS_FLAGS} ) -# TARGET_LINK_LIBRARIES( MultiArrayTest ${GTEST_BOTH_LIBRARIES} ) -#ENDIF( BUILD_CUDA ) - ADD_TEST( ListTest ${EXECUTABLE_OUTPUT_PATH}/ListTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( ArrayOperationsTest ${EXECUTABLE_OUTPUT_PATH}/ArrayOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) @@ -82,7 +72,6 @@ ENDIF() ADD_TEST( MultireductionTest ${EXECUTABLE_OUTPUT_PATH}/MultireductionTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( StaticArrayTest ${EXECUTABLE_OUTPUT_PATH}/StaticArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( StaticVectorTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorTest${CMAKE_EXECUTABLE_SUFFIX} ) -#ADD_TEST( MultiArrayTest ${EXECUTABLE_OUTPUT_PATH}/MultiArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_SUBDIRECTORY( Multimaps ) diff --git a/src/UnitTests/Containers/DistributedArrayTest.h b/src/UnitTests/Containers/DistributedArrayTest.h index 15ed6214a1d0ef4f74a8fec6dfdf1a24ff31851d..381539af6b72ec44ce6f62497e2b1530d8edc9f9 100644 --- a/src/UnitTests/Containers/DistributedArrayTest.h +++ b/src/UnitTests/Containers/DistributedArrayTest.h @@ -88,11 +88,15 @@ TYPED_TEST( DistributedArrayTest, copyFromGlobal ) using ArrayType = typename TestFixture::ArrayType; this->distributedArray.setValue( 0.0 ); - ArrayViewType localArrayView = this->distributedArray.getLocalArrayView(); ArrayType globalArray( this->globalSize ); globalArray.setValue( 1.0 ); this->distributedArray.copyFromGlobal( globalArray ); - EXPECT_EQ( localArrayView, globalArray ); + + ArrayViewType localArrayView = this->distributedArray.getLocalArrayView(); + auto globalView = globalArray.getConstView(); + const auto localRange = this->distributedArray.getLocalRange(); + globalView.bind( &globalArray[ localRange.getBegin() ], localRange.getEnd() - localRange.getBegin() ); + EXPECT_EQ( localArrayView, globalView ); } TYPED_TEST( DistributedArrayTest, setLike ) @@ -188,7 +192,7 @@ TYPED_TEST( DistributedArrayTest, copyConstructor ) this->distributedArray.setValue( 1 ); DistributedArrayType copy( this->distributedArray ); // Array has "binding" copy-constructor - EXPECT_EQ( copy.getLocalArrayView().getData(), this->distributedArray.getLocalArrayView().getData() ); + //EXPECT_EQ( copy.getLocalArrayView().getData(), this->distributedArray.getLocalArrayView().getData() ); } TYPED_TEST( DistributedArrayTest, copyAssignment ) diff --git a/src/UnitTests/Containers/MultiArrayTest.cpp b/src/UnitTests/Containers/MultiArrayTest.cpp deleted file mode 100644 index 18e7453ccf928f288127d2de469f60d63005ca7b..0000000000000000000000000000000000000000 --- a/src/UnitTests/Containers/MultiArrayTest.cpp +++ /dev/null @@ -1,11 +0,0 @@ -/*************************************************************************** - MultiArrayTest.cpp - description - ------------------- - begin : Feb 3, 2014 - copyright : (C) 2014 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#include "MultiArrayTest.h" \ No newline at end of file diff --git a/src/UnitTests/Containers/MultiArrayTest.cu b/src/UnitTests/Containers/MultiArrayTest.cu deleted file mode 100644 index 97d7ff312b645d87bbaa230cb355a883678508d1..0000000000000000000000000000000000000000 --- a/src/UnitTests/Containers/MultiArrayTest.cu +++ /dev/null @@ -1,11 +0,0 @@ -/*************************************************************************** - MultiArrayTest.cu - description - ------------------- - begin : Feb 3, 2014 - copyright : (C) 2014 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#include "MultiArrayTest.h" diff --git a/src/UnitTests/Containers/MultiArrayTest.h b/src/UnitTests/Containers/MultiArrayTest.h deleted file mode 100644 index 66fc9dc08574d717409718c1ab7a97d94828941f..0000000000000000000000000000000000000000 --- a/src/UnitTests/Containers/MultiArrayTest.h +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************** - MultiArrayTester.h - description - ------------------- - begin : Jul 4, 2012 - copyright : (C) 2012 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -#include <TNL/Containers/MultiArray.h> - -#ifdef HAVE_GTEST -#include "gtest/gtest.h" -#endif - -using namespace TNL; -using namespace TNL::Containers; - -#ifdef HAVE_CUDA -template< typename ValueType, typename IndexType > -__global__ void testSetGetElementKernel( MultiArray< 1, ValueType, Devices::Cuda, IndexType >* u ) -{ - if( threadIdx.x < ( *u ).getDimensions().x() ) - ( *u )( threadIdx.x ) = threadIdx.x; -} - -template< typename ValueType, typename IndexType > -__global__ void testSetGetElementKernel( MultiArray< 2, ValueType, Devices::Cuda, IndexType >* u ) -{ - if( threadIdx.x < ( *u ).getDimensions().x() && - threadIdx.x < ( *u ).getDimensions().y() ) - ( *u )( threadIdx.x, threadIdx.x ) = threadIdx.x; -} - -template< typename ValueType, typename IndexType > -__global__ void testSetGetElementKernel( MultiArray< 3, ValueType, Devices::Cuda, IndexType >* u ) -{ - if( threadIdx.x < ( *u ).getDimensions().x() && - threadIdx.x < ( *u ).getDimensions().y() && - threadIdx.x < ( *u ).getDimensions().z() ) - ( *u )( threadIdx.x, threadIdx.x, threadIdx.x ) = threadIdx.x; -} - -#endif /* HAVE_CUDA */ - -#ifdef HAVE_GTEST - -TEST( MultiArrayTest, testConstructorDestructor ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > u; -} - -TEST( MultiArrayTest, testSetSize ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > u, v; - u. setDimensions( 10 ); - v. setDimensions( 10 ); -} - -void setDiagonalElement( Containers::MultiArray< 1, ValueType, Device, IndexType >& u, - const IndexType& i, - const ValueType& v ) -{ - u.setElement( i, v ); -} - -void setDiagonalElement( Containers::MultiArray< 2, ValueType, Device, IndexType >& u, - const IndexType& i, - const ValueType& v ) -{ - u.setElement( i, i, v ); -} - -void setDiagonalElement( Containers::MultiArray< 3, ValueType, Device, IndexType >& u, - const IndexType& i, - const ValueType& v ) -{ - u.setElement( i, i, i, v ); -} - -IndexType getDiagonalElement( Containers::MultiArray< 1, ValueType, Device, IndexType >& u, - const IndexType& i ) -{ - return u.getElement( i ); -} - -IndexType getDiagonalElement( Containers::MultiArray< 2, ValueType, Device, IndexType >& u, - const IndexType& i ) -{ - return u.getElement( i, i ); -} - -IndexType getDiagonalElement( Containers::MultiArray< 3, ValueType, Device, IndexType >& u, - const IndexType& i ) -{ - return u.getElement( i, i, i ); -} - - -TEST( MultiArrayTest, testSetGetElement ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > u; - u. setDimensions( 10 ); - if( std::is_same< Device, Devices::Host >::value ) - { - for( int i = 0; i < 10; i ++ ) - this->setDiagonalElement( u, i, i ); - } - if( std::is_same< Device, Devices::Cuda >::value ) - { -#ifdef HAVE_CUDA - MultiArray< Dimension, ValueType, Device, IndexType >* kernel_u = - Devices::Cuda::passToDevice( u ); - testSetGetElementKernel<<< 1, 16 >>>( kernel_u ); - Devices::Cuda::freeFromDevice( kernel_u ); - ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE ); -#endif - } - for( int i = 0; i < 10; i ++ ) - ASSERT_EQ( getDiagonalElement( u, i ), i ); -}; - -TEST( MultiArrayTest, testComparisonOperator ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > u, v, w; - u.setDimensions( 10 ); - v.setDimensions( 10 ); - w.setDimensions( 10 ); - u.setValue( 0 ); - v.setValue( 0 ); - w.setValue( 0 ); - for( int i = 0; i < 10; i ++ ) - { - setDiagonalElement( u, i, i ); - setDiagonalElement( v, i, i ); - setDiagonalElement( w, i, 2*1 ); - } - ASSERT_TRUE( u == v ); - ASSERT_FALSE( u != v ); - ASSERT_TRUE( u != w ); - ASSERT_FALSE( u == w ); -}; - -TEST( MultiArrayTest, testEquivalenceOperator ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > u; - MultiArray< Dimension, ValueType, Device, IndexType > v; - u. setDimensions( 10 ); - v. setDimensions( 10 ); - for( int i = 0; i < 10; i ++ ) - setDiagonalElement( u, i, i ); - v = u; - ASSERT_TRUE( u == v ); - ASSERT_FALSE( u != v ); -}; - -TEST( MultiArrayTest, testGetSize ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > u; - const int maxSize = 10; - for( int i = 1; i < maxSize; i ++ ) - u. setDimensions( i ); - - ASSERT_EQ( u. getDimensions().x(), maxSize - 1 ); -}; - -TEST( MultiArrayTest, testReset ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > u; - u.setDimensions( 100 ); - ASSERT_EQ( u. getDimensions().x(), 100 ); - u.reset(); - ASSERT_EQ( u. getDimensions().x(), 0 ); - u.setDimensions( 100 ); - ASSERT_EQ( u. getDimensions().x(), 100 ); - u.reset(); - ASSERT_EQ( u. getDimensions().x(), 0 ); - -}; - -TEST( MultiArrayTest, testSetSizeAndDestructor ) -{ - using namespace TNL::Containers; - for( int i = 1; i < 100; i ++ ) - { - MultiArray< Dimension, ValueType, Device, IndexType > u; - u. setDimensions( i ); - } -} - -TEST( MultiArrayTest, testSaveAndLoad ) -{ - using namespace TNL::Containers; - MultiArray< Dimension, ValueType, Device, IndexType > v; - const int size( 10 ); - ASSERT_TRUE( v. setDimensions( size ) ); - for( int i = 0; i < size; i ++ ) - setDiagonalElement( v, i, 3.14147 ); - File file; - file. open( "test-file.tnl", IOMode::write ); - ASSERT_TRUE( v. save( file ) ); - file. close(); - MultiArray< Dimension, ValueType, Device, IndexType > u; - file. open( "test-file.tnl", IOMode::read ); - ASSERT_TRUE( u. load( file ) ); - file. close(); - ASSERT_TRUE( u == v ); - - EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); -} -#endif /* HAVE_GTEST */ - -int main( int argc, char* argv[] ) -{ -#ifdef HAVE_GTEST - ::testing::InitGoogleTest( &argc, argv ); - return RUN_ALL_TESTS(); -#else - return EXIT_FAILURE; -#endif -} - - - - - - diff --git a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp index 120a2451fb7a2989aad9bb23a31ce0689bc7bf30..4612c1dd3709efcc470fee9b70e0d3a359b6a693 100644 --- a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp +++ b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp @@ -42,20 +42,23 @@ TEST( MultimapTest, TestSettingSizes ) for( IndexType i = 0; i < inputs; i++ ) { auto values = map.getValues( i ); - const auto constValues = ( (const MultimapType) map ).getValues( i ); + const auto constValues = ( (const MultimapType&) map ).getValues( i ); // uninitialized should be equal to the value from the allocation vector ASSERT_EQ( values.getSize(), allocationRanges[ i ] ); + // This does not work with Array deep copy constructor ASSERT_EQ( constValues.getSize(), allocationRanges[ i ] ); // setting lower sizes values.setSize( valuesLocalMax ); ASSERT_EQ( values.getSize(), valuesLocalMax ); + // This does not work with Array deep copy constructor ASSERT_EQ( constValues.getSize(), valuesLocalMax ); // setting global max values.setSize( valuesGlobalMax ); ASSERT_EQ( values.getSize(), valuesGlobalMax ); + // This does not work with Array deep copy constructor ASSERT_EQ( constValues.getSize(), valuesGlobalMax ); } } @@ -78,7 +81,7 @@ TEST( MultimapTest, TestSettingValues ) for( IndexType i = 0; i < inputs; i++ ) { auto values = map.getValues( i ); - const auto constValues = ( (const MultimapType) map ).getValues( i ); + const auto constValues = ( (const MultimapType&) map ).getValues( i ); values.setSize( allocatedValues ); @@ -126,8 +129,8 @@ TEST( MultimapTest, TestSaveAndLoad ) values.setValue( o, i + o ); } - ASSERT_TRUE( map.save( "multimap-test.tnl" ) ); - ASSERT_TRUE( map2.load( "multimap-test.tnl" ) ); + map.save( "multimap-test.tnl" ); + map2.load( "multimap-test.tnl" ); EXPECT_EQ( map, map2 ); EXPECT_EQ( map.getKeysRange(), map2.getKeysRange() ); diff --git a/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp b/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp index 3e29dadf00a1c9310b1de232c670e3b38da33f66..3602f53ca83708f874bd5a4492ec751800b4876f 100644 --- a/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp +++ b/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp @@ -77,8 +77,8 @@ TEST( MultimapTest, TestSaveAndLoad ) values.setValue( o, i + o ); } - ASSERT_TRUE( map.save( "multimap-test.tnl" ) ); - ASSERT_TRUE( map2.load( "multimap-test.tnl" ) ); + map.save( "multimap-test.tnl" ); + map2.load( "multimap-test.tnl" ); EXPECT_EQ( map, map2 ); EXPECT_EQ( map.getKeysRange(), map2.getKeysRange() ); diff --git a/src/UnitTests/Containers/StaticArrayTest.cpp b/src/UnitTests/Containers/StaticArrayTest.cpp index e3d0b1f63e28864b0980d71af6623b51224c1218..a418b9d06ce026fcb0584e3a71150fe332d1729b 100644 --- a/src/UnitTests/Containers/StaticArrayTest.cpp +++ b/src/UnitTests/Containers/StaticArrayTest.cpp @@ -246,10 +246,10 @@ TYPED_TEST( StaticArrayTest, SaveAndLoad ) ArrayType u1( 7 ), u2; File file; - file.open( "tnl-static-array-test.tnl", IOMode::write ); + file.open( "tnl-static-array-test.tnl", File::Mode::Out ); u1.save( file ); file.close(); - file.open( "tnl-static-array-test.tnl", IOMode::read ); + file.open( "tnl-static-array-test.tnl", File::Mode::In ); u2.load( file ); file.close(); diff --git a/src/UnitTests/FileTest.h b/src/UnitTests/FileTest.h index 4da7418924b5b8e0089bac8f53b8daeb627f91bc..39671ba661ca77add041345206c9fd2926ce2879 100644 --- a/src/UnitTests/FileTest.h +++ b/src/UnitTests/FileTest.h @@ -15,38 +15,32 @@ using namespace TNL; -TEST( FileTest, CloseEmpty ) -{ - File file; - ASSERT_TRUE( file.close() ); -} - TEST( FileTest, OpenInvalid ) { File file; - EXPECT_THROW( file.open( "invalid-file.tnl", IOMode::read ), std::ios_base::failure ); + EXPECT_THROW( file.open( "invalid-file.tnl", File::Mode::In ), std::ios_base::failure ); } TEST( FileTest, WriteAndRead ) { File file; - ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) ); + file.open( String( "test-file.tnl" ), File::Mode::Out ); int intData( 5 ); double doubleData[ 3 ] = { 1.0, 2.0, 3.0 }; const double constDoubleData = 3.14; - ASSERT_TRUE( file.write( &intData ) ); - ASSERT_TRUE( file.write( doubleData, 3 ) ); - ASSERT_TRUE( file.write( &constDoubleData ) ); - ASSERT_TRUE( file.close() ); + file.save( &intData ); + file.save( doubleData, 3 ); + file.save( &constDoubleData ); + file.close(); - ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); + file.open( String( "test-file.tnl" ), File::Mode::In ); int newIntData; double newDoubleData[ 3 ]; double newConstDoubleData; - ASSERT_TRUE( file.read( &newIntData, 1 ) ); - ASSERT_TRUE( file.read( newDoubleData, 3 ) ); - ASSERT_TRUE( file.read( &newConstDoubleData, 1 ) ); + file.load( &newIntData, 1 ); + file.load( newDoubleData, 3 ); + file.load( &newConstDoubleData, 1 ); EXPECT_EQ( newIntData, intData ); for( int i = 0; i < 3; i ++ ) @@ -56,6 +50,37 @@ TEST( FileTest, WriteAndRead ) EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); }; +TEST( FileTest, WriteAndReadWithConversion ) +{ + double doubleData[ 3 ] = { 3.1415926535897932384626433, + 2.7182818284590452353602874, + 1.6180339887498948482045868 }; + float floatData[ 3 ]; + int intData[ 3 ]; + File file; + file.open( "test-file.tnl", File::Mode::Out | File::Mode::Truncate ); + file.save< double, float, Devices::Host >( doubleData, 3 ); + file.close(); + + file.open( "test-file.tnl", File::Mode::In ); + file.load< float, float, Devices::Host >( floatData, 3 ); + file.close(); + + file.open( "test-file.tnl", File::Mode::In ); + file.load< int, float, Devices::Host >( intData, 3 ); + file.close(); + + EXPECT_NEAR( floatData[ 0 ], 3.14159, 0.0001 ); + EXPECT_NEAR( floatData[ 1 ], 2.71828, 0.0001 ); + EXPECT_NEAR( floatData[ 2 ], 1.61803, 0.0001 ); + + EXPECT_EQ( intData[ 0 ], 3 ); + EXPECT_EQ( intData[ 1 ], 2 ); + EXPECT_EQ( intData[ 2 ], 1 ); + + EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); +} + #ifdef HAVE_CUDA TEST( FileTest, WriteAndReadCUDA ) { @@ -83,17 +108,14 @@ TEST( FileTest, WriteAndReadCUDA ) cudaMemcpyHostToDevice ); File file; - ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) ); + file.open( String( "test-file.tnl" ), File::Mode::Out ); - bool status = file.write< int, Devices::Cuda >( cudaIntData ); - ASSERT_TRUE( status ); - status = file.write< float, Devices::Cuda >( cudaFloatData, 3 ); - ASSERT_TRUE( status ); - status = file.write< const double, Devices::Cuda >( cudaConstDoubleData ); - ASSERT_TRUE( status ); - ASSERT_TRUE( file.close() ); + file.save< int, int, Devices::Cuda >( cudaIntData ); + file.save< float, float, Devices::Cuda >( cudaFloatData, 3 ); + file.save< const double, double, Devices::Cuda >( cudaConstDoubleData ); + file.close(); - ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); + file.open( String( "test-file.tnl" ), File::Mode::In ); int newIntData; float newFloatData[ 3 ]; double newDoubleData; @@ -103,12 +125,9 @@ TEST( FileTest, WriteAndReadCUDA ) cudaMalloc( ( void** ) &newCudaIntData, sizeof( int ) ); cudaMalloc( ( void** ) &newCudaFloatData, 3 * sizeof( float ) ); cudaMalloc( ( void** ) &newCudaDoubleData, sizeof( double ) ); - status = file.read< int, Devices::Cuda >( newCudaIntData, 1 ); - ASSERT_TRUE( status ); - status = file.read< float, Devices::Cuda >( newCudaFloatData, 3 ); - ASSERT_TRUE( status ); - status = file.read< double, Devices::Cuda >( newCudaDoubleData, 1 ); - ASSERT_TRUE( status ); + file.load< int, int, Devices::Cuda >( newCudaIntData, 1 ); + file.load< float, float, Devices::Cuda >( newCudaFloatData, 3 ); + file.load< double, double, Devices::Cuda >( newCudaDoubleData, 1 ); cudaMemcpy( &newIntData, newCudaIntData, sizeof( int ), @@ -129,6 +148,60 @@ TEST( FileTest, WriteAndReadCUDA ) EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); }; + +TEST( FileTest, WriteAndReadCUDAWithConversion ) +{ + const double constDoubleData[ 3 ] = { 3.1415926535897932384626433, + 2.7182818284590452353602874, + 1.6180339887498948482045868 }; + float floatData[ 3 ]; + int intData[ 3 ]; + + int* cudaIntData; + float* cudaFloatData; + const double* cudaConstDoubleData; + cudaMalloc( ( void** ) &cudaIntData, 3 * sizeof( int ) ); + cudaMalloc( ( void** ) &cudaFloatData, 3 * sizeof( float ) ); + cudaMalloc( ( void** ) &cudaConstDoubleData, 3 * sizeof( double ) ); + cudaMemcpy( (void*) cudaConstDoubleData, + &constDoubleData, + 3 * sizeof( double ), + cudaMemcpyHostToDevice ); + + File file; + file.open( String( "cuda-test-file.tnl" ), File::Mode::Out | File::Mode::Truncate ); + file.save< double, float, Devices::Cuda >( cudaConstDoubleData, 3 ); + file.close(); + + file.open( String( "cuda-test-file.tnl" ), File::Mode::In ); + file.load< float, float, Devices::Cuda >( cudaFloatData, 3 ); + file.close(); + + file.open( String( "cuda-test-file.tnl" ), File::Mode::In ); + file.load< int, float, Devices::Cuda >( cudaIntData, 3 ); + file.close(); + + cudaMemcpy( floatData, + cudaFloatData, + 3 * sizeof( float ), + cudaMemcpyDeviceToHost ); + cudaMemcpy( &intData, + cudaIntData, + 3* sizeof( int ), + cudaMemcpyDeviceToHost ); + + + EXPECT_NEAR( floatData[ 0 ], 3.14159, 0.0001 ); + EXPECT_NEAR( floatData[ 1 ], 2.71828, 0.0001 ); + EXPECT_NEAR( floatData[ 2 ], 1.61803, 0.0001 ); + + EXPECT_EQ( intData[ 0 ], 3 ); + EXPECT_EQ( intData[ 1 ], 2 ); + EXPECT_EQ( intData[ 2 ], 1 ); + + EXPECT_EQ( std::remove( "cuda-test-file.tnl" ), 0 ); +}; + #endif #endif diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp index 000a832b6011cd7b444ed27d141a8debbfec7c38..caaf3f613e39a616da425b330799c6d12e817ae9 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp +++ b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp @@ -592,7 +592,7 @@ TEST(CutDistributedMeshFunction, 3D_2_Save) if(CommunicatorType::GetRank(*group)==0) { File meshFile; - meshFile.open( FileName+String("-mesh.tnl"),IOMode::write); + meshFile.open( FileName+String("-mesh.tnl"),File::Mode::Out); cutDistributedGrid.getGlobalGrid().save( meshFile ); meshFile.close(); } @@ -612,8 +612,7 @@ TEST(CutDistributedMeshFunction, 3D_2_Save) loadMeshFunctionptr.bind(globalCutGrid,loaddof); File file; - bool ok=file.open( FileName, IOMode::read ); - TNL_ASSERT_TRUE(ok,"Cannot open file"); + file.open( FileName, File::Mode::In ); loadMeshFunctionptr.boundLoad(file); file.close(); diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h index d8b19c229c53ce0d3a558b62399163a653b47cd0..09be099c5507654e5075cfd36e5764017524efd0 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h +++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h @@ -276,7 +276,7 @@ class TestDistributedGridIO String localFileName= fileName+String("-")+distributedGrid.printProcessCoords()+String(".tnl"); File file; - ASSERT_TRUE( file.open(localFileName, IOMode::read ) ); + file.open(localFileName, File::Mode::In ); loadMeshFunctionptr->boundLoad(file); file.close(); @@ -336,7 +336,7 @@ class TestDistributedGridIO String fileName=String("test-file-distributedgrid-io-load.tnl"); String localFileName=fileName+String("-")+distributedGrid.printProcessCoords()+String(".tnl"); File file; - ASSERT_TRUE( file.open( localFileName, IOMode::write ) ); + file.open( localFileName, File::Mode::Out ); localMeshFunctionptr->save(file); file.close(); diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h index ef0160741641be58b36291cb0cf42b9594c9cc2d..b19c8641f2adfd3d30f8e3001b432d7231e9eab5 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h +++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h @@ -100,7 +100,7 @@ class TestDistributedGridMPIIO{ loadDof.setValue(-1); File file; - file.open( FileName, IOMode::read ); + file.open( FileName, File::Mode::In ); loadMeshFunctionptr->boundLoad(file); file.close(); @@ -148,7 +148,7 @@ class TestDistributedGridMPIIO{ linearFunctionEvaluator.evaluateAllEntities(saveMeshFunctionptr , linearFunctionPtr); File file; - file.open( FileName, IOMode::write ); + file.open( FileName, File::Mode::Out ); saveMeshFunctionptr->save(file); file.close(); } diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h index e668847832825318d7da057e2909ba350fbcd347..055faa81226f3716d49594fe255b475a366f2797 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h +++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h @@ -80,7 +80,7 @@ class TestDistributedVectorFieldMPIIO{ String FileName=String("/tmp/test-file.tnl"); DistributedGridIO<VectorFieldType,MpiIO> ::save(FileName, vectorField ); /*File file; - file.open( FileName, IOMode::write ); + file.open( FileName, File::Mode::Out ); vectorField.save(file); file.close(); */ @@ -102,17 +102,13 @@ class TestDistributedVectorFieldMPIIO{ loadDof.setValue(-1); File file; - file.open( FileName, IOMode::read ); - bool loaded=loadvct.boundLoad(file); - file.close(); - if(!loaded) - EXPECT_TRUE(loaded)<< "Chyba naÄtenà souboru" <<std::endl; - else - for(int i=0;i<loadDof.getSize();i++) - { - EXPECT_EQ( globalEvaluatedDof.getElement(i), loadDof.getElement(i)) << "Compare Loaded and evaluated Dof Failed for: "<< i; - } - } + file.open( FileName, File::Mode::In ); + loadvct.boundLoad(file); + for(int i=0;i<loadDof.getSize();i++) + { + EXPECT_EQ( globalEvaluatedDof.getElement(i), loadDof.getElement(i)) << "Compare Loaded and evaluated Dof Failed for: "<< i; + } + } }; static void TestLoad() @@ -153,7 +149,7 @@ class TestDistributedVectorFieldMPIIO{ linearFunctionEvaluator.evaluateAllEntities(saveVectorField[i] , linearFunctionPtr); File file; - file.open( FileName, IOMode::write ); + file.open( FileName, File::Mode::Out ); saveVectorField.save(file); file.close(); } diff --git a/src/UnitTests/Meshes/MeshTest.h b/src/UnitTests/Meshes/MeshTest.h index 3835df28d5cae1ac07d952ed861474561f03c4f9..65ec8c353b3f4b2addbe4d5cea188adc18185c82 100644 --- a/src/UnitTests/Meshes/MeshTest.h +++ b/src/UnitTests/Meshes/MeshTest.h @@ -107,13 +107,13 @@ void testMeshOnCuda( const Mesh& mesh ) EXPECT_EQ( mesh2, mesh ); // test load from file to CUDA - ASSERT_TRUE( mesh.save( "mesh.tnl" ) ); - ASSERT_TRUE( dmesh1.load( "mesh.tnl" ) ); + mesh.save( "mesh.tnl" ); + dmesh1.load( "mesh.tnl" ); EXPECT_EQ( dmesh1, mesh ); // test save into file from CUDA - ASSERT_TRUE( dmesh1.save( "mesh.tnl" ) ); - ASSERT_TRUE( mesh2.load( "mesh.tnl" ) ); + dmesh1.save( "mesh.tnl" ); + mesh2.load( "mesh.tnl" ); EXPECT_EQ( mesh2, mesh ); EXPECT_EQ( std::remove( "mesh.tnl" ), 0 ); @@ -154,8 +154,8 @@ template< typename Mesh > void testFinishedMesh( const Mesh& mesh ) { Mesh mesh2; - ASSERT_TRUE( mesh.save( "mesh.tnl" ) ); - ASSERT_TRUE( mesh2.load( "mesh.tnl" ) ); + mesh.save( "mesh.tnl" ); + mesh2.load( "mesh.tnl" ); EXPECT_EQ( std::remove( "mesh.tnl" ), 0 ); ASSERT_EQ( mesh, mesh2 ); compareStringRepresentation( mesh, mesh2 ); diff --git a/src/UnitTests/ObjectTest.cpp b/src/UnitTests/ObjectTest.cpp index 488f7a49756727fd9314a50413d3f40f85a70172..ac0281afa2fd66614da1393a8f12b027beaba8f8 100644 --- a/src/UnitTests/ObjectTest.cpp +++ b/src/UnitTests/ObjectTest.cpp @@ -24,11 +24,11 @@ TEST( ObjectTest, SaveAndLoadTest ) { Object testObject; File file; - file.open( "test-file.tnl", IOMode::write ); - ASSERT_TRUE( testObject.save( file ) ); + file.open( "test-file.tnl", File::Mode::Out ); + testObject.save( file ); file.close(); - file.open( "test-file.tnl", IOMode::read ); - ASSERT_TRUE( testObject.load( file ) ); + file.open( "test-file.tnl", File::Mode::In ); + testObject.load( file ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); } @@ -75,6 +75,24 @@ TEST( ObjectTest, parseObjectTypeTest ) expected = { "A", "b", "c <E>", "d" }; EXPECT_EQ( parsed, expected ); } + +TEST( HeaderTest, SaveAndLoadTest ) +{ + Object testObject; + File file; + file.open( "test-file.tnl", File::Mode::Out ); + saveHeader( file, "TYPE" ); + file.close(); + file.open( "test-file.tnl", File::Mode::In ); + String type; + loadHeader( file, type ); + + EXPECT_EQ( type, "TYPE" ); + + EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); +} + + #endif diff --git a/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp b/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp index f4b0cc7e6467ded039417d15b60b2f99fdb55335..e7079e894b1353c969231c1efcd607e1e8d8e8c3 100644 --- a/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp +++ b/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp @@ -62,9 +62,9 @@ class TestSaveAndLoadMeshfunction linearFunctionEvaluator.evaluateAllEntities(localMeshFunctionptr , linearFunctionPtr); File file; - ASSERT_TRUE( file.open( String( FILENAME), IOMode::write )); - ASSERT_TRUE( localMeshFunctionptr->save(file)); - ASSERT_TRUE( file.close() ); + file.open( String( FILENAME), File::Mode::Out ); + localMeshFunctionptr->save(file); + file.close(); //load other meshfunction on same localgrid from created file Pointers::SharedPointer<MeshType> loadGridptr; @@ -80,9 +80,9 @@ class TestSaveAndLoadMeshfunction loadDof[i]=-1; } - ASSERT_TRUE( file.open( String( FILENAME ), IOMode::read )); - ASSERT_TRUE( loadMeshFunctionptr->boundLoad(file)); - ASSERT_TRUE( file.close()); + file.open( String( FILENAME ), File::Mode::In ); + loadMeshFunctionptr->boundLoad(file); + file.close(); for(int i=0;i<localDof.getSize();i++) { diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp index 10c85497b0044d03653b91cdc8b8729862158074..f44eac1c68ee30bfc053325b4f9a9803b6b013e2 100644 --- a/src/UnitTests/StringTest.cpp +++ b/src/UnitTests/StringTest.cpp @@ -83,7 +83,7 @@ TEST( StringTest, SetSize ) { String str; str.setSize( 42 ); - EXPECT_GT( str.getAllocatedSize(), 0 ); + EXPECT_EQ( str.getAllocatedSize(), 42 ); } TEST( StringTest, GetString ) @@ -277,7 +277,7 @@ TEST( StringTest, split ) EXPECT_EQ( parts[ 4 ], "br" ); EXPECT_EQ( parts[ 5 ], "" ); - parts = String( "abracadabra" ).split( 'a', true ); + parts = String( "abracadabra" ).split( 'a', String::SplitSkip::SkipEmpty ); ASSERT_EQ( (int) parts.size(), 4 ); EXPECT_EQ( parts[ 0 ], "br" ); EXPECT_EQ( parts[ 1 ], "c" ); @@ -306,10 +306,10 @@ TEST( StringTest, SaveLoad ) { String str1( "testing-string" ); File file; - file.open( "test-file.tnl", IOMode::write ); + file.open( "test-file.tnl", File::Mode::Out ); ASSERT_NO_THROW( file << str1 ); file.close(); - file.open( "test-file.tnl", IOMode::read ); + file.open( "test-file.tnl", File::Mode::In ); String str2; ASSERT_NO_THROW( file >> str2 ); EXPECT_EQ( str1, str2 );