Loading src/TNL/File.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -44,13 +44,13 @@ bool File :: open( const String& fileName, std::cout << " for writing ... " << std::endl; } if( mode == IOMode::read ) file = fopen( fileName. getString(), "r" ); file = std::fopen( fileName.getString(), "r" ); if( mode == IOMode::write ) file = fopen( fileName. getString(), "w" ); file = std::fopen( fileName.getString(), "w" ); if( file == NULL ) { std::cerr << "I am not able to open the file " << fileName << ". "; perror( "" ); std::perror( "" ); return false; } this->fileOK = true; Loading @@ -63,7 +63,7 @@ bool File :: close() if( verbose ) std::cout << "Closing the file " << getFileName() << " ... " << std::endl; if( fclose( file ) != 0 ) if( std::fclose( file ) != 0 ) { std::cerr << "I was not able to close the file " << fileName << " properly!" << std::endl; return false; Loading src/TNL/File.h +4 −6 Original line number Diff line number Diff line Loading @@ -12,8 +12,7 @@ #include <iostream> #include <fstream> #include <stdio.h> #include <stdlib.h> #include <cstdio> #ifdef HAVE_CUDA #include <cuda_runtime.h> #endif Loading Loading @@ -46,15 +45,15 @@ class File { IOMode mode; FILE* file; std::FILE* file; bool fileOK; String fileName; size_t writtenElements; std::size_t writtenElements; size_t readElements; std::size_t readElements; public: Loading Loading @@ -99,7 +98,6 @@ class File bool close(); static int verbose; }; bool fileExists( const String& fileName ); Loading src/TNL/File_impl.h +44 −70 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ #pragma once #include <type_traits> #include <TNL/File.h> #include <TNL/Exceptions/CudaSupportMissing.h> Loading @@ -34,9 +36,9 @@ bool File :: read( Type* buffer, { TNL_ASSERT_GE( _elements, 0, "Number of elements to read must be non-negative." ); // convert _elements from Index to size_t, which is *unsigned* type // convert _elements from Index to std::size_t, which is *unsigned* type // (expected by fread etc) size_t elements = (size_t) _elements; std::size_t elements = (std::size_t) _elements; if( ! elements ) return true; Loading @@ -50,19 +52,17 @@ bool File :: read( Type* buffer, std::cerr << "File " << fileName << " was not opened for reading. " << std::endl; return false; } this->readElements = 0; const size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); void* host_buffer( 0 ); if( std::is_same< Device, Devices::Host >::value ) { if( fread( buffer, if( std::fread( buffer, sizeof( Type ), elements, file ) != elements ) { std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl; perror( "Fread ended with the error code" ); std::perror( "Fread ended with the error code" ); return false; } this->readElements = elements; Loading @@ -71,33 +71,21 @@ bool File :: read( Type* buffer, if( std::is_same< Device, Devices::Cuda >::value ) { #ifdef HAVE_CUDA /*!*** * Here we cannot use * * host_buffer = new Type[ host_buffer_size ]; * * because it does not work for constant types like * T = const bool. */ host_buffer = malloc( sizeof( Type ) * host_buffer_size ); readElements = 0; if( ! host_buffer ) { std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file " << this->getFileName() << "." << std::endl; return false; } const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); using BaseType = typename std::remove_cv< Type >::type; BaseType* host_buffer = new BaseType[ host_buffer_size ]; while( readElements < elements ) { size_t transfer = std::min( elements - readElements, host_buffer_size ); size_t transfered = fread( host_buffer, sizeof( Type ), transfer, file ); std::size_t transfer = std::min( elements - readElements, host_buffer_size ); std::size_t transfered = std::fread( host_buffer, sizeof( Type ), transfer, file ); if( transfered != transfer ) { std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl; std::cerr << transfered << " bytes were transfered. " << std::endl; perror( "Fread ended with the error code" ); std::perror( "Fread ended with the error code" ); delete[] host_buffer; return false; } Loading @@ -109,12 +97,12 @@ bool File :: read( Type* buffer, { std::cerr << "Transfer of data from the CUDA device to the file " << this->fileName << " failed." << std::endl; free( host_buffer ); delete[] host_buffer; return false; } readElements += transfer; this->readElements += transfer; } free( host_buffer ); delete[] host_buffer; return true; #else throw Exceptions::CudaSupportMissing(); Loading @@ -129,9 +117,9 @@ bool File :: write( const Type* buffer, { TNL_ASSERT_GE( _elements, 0, "Number of elements to write must be non-negative." ); // convert _elements from Index to size_t, which is *unsigned* type // convert _elements from Index to std::size_t, which is *unsigned* type // (expected by fread etc) size_t elements = (size_t) _elements; std::size_t elements = (std::size_t) _elements; if( ! elements ) return true; Loading @@ -146,20 +134,16 @@ bool File :: write( const Type* buffer, return false; } Type* buf = const_cast< Type* >( buffer ); void* host_buffer( 0 ); this->writtenElements = 0; const size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); if( std::is_same< Device, Devices::Host >::value ) { if( fwrite( buf, if( std::fwrite( buffer, sizeof( Type ), elements, this->file ) != elements ) { std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl; perror( "Fwrite ended with the error code" ); std::perror( "Fwrite ended with the error code" ); return false; } this->writtenElements = elements; Loading @@ -168,25 +152,14 @@ bool File :: write( const Type* buffer, if( std::is_same< Device, Devices::Cuda >::value ) { #ifdef HAVE_CUDA /*!*** * Here we cannot use * * host_buffer = new Type[ host_buffer_size ]; * * because it does not work for constant types like * T = const bool. */ host_buffer = malloc( sizeof( Type ) * host_buffer_size ); if( ! host_buffer ) { std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file " << this->getFileName() << "." << std::endl; return false; } const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); using BaseType = typename std::remove_cv< Type >::type; BaseType* host_buffer = new BaseType[ host_buffer_size ]; while( this->writtenElements < elements ) { size_t transfer = std::min( elements - this->writtenElements, host_buffer_size ); std::size_t transfer = std::min( elements - this->writtenElements, host_buffer_size ); cudaMemcpy( host_buffer, ( void* ) & ( buffer[ this->writtenElements ] ), transfer * sizeof( Type ), Loading @@ -195,21 +168,22 @@ bool File :: write( const Type* buffer, { std::cerr << "Transfer of data from the file " << this->fileName << " to the CUDA device failed." << std::endl; free( host_buffer ); delete[] host_buffer; return false; } if( fwrite( host_buffer, if( std::fwrite( host_buffer, sizeof( Type ), transfer, this->file ) != transfer ) { std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl; perror( "Fwrite ended with the error code" ); std::perror( "Fwrite ended with the error code" ); delete[] host_buffer; return false; } this->writtenElements += transfer; } free( host_buffer ); delete[] host_buffer; return true; #else throw Exceptions::CudaSupportMissing(); Loading src/UnitTests/FileTest.h +24 −0 Original line number Diff line number Diff line Loading @@ -28,19 +28,24 @@ TEST( FileTest, WriteAndRead ) 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() ); ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); 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 ) ); EXPECT_EQ( newIntData, intData ); for( int i = 0; i < 3; i ++ ) EXPECT_EQ( newDoubleData[ i ], doubleData[ i ] ); EXPECT_EQ( newConstDoubleData, constDoubleData ); }; #ifdef HAVE_CUDA Loading @@ -48,11 +53,14 @@ TEST( FileTest, WriteAndReadCUDA ) { int intData( 5 ); float floatData[ 3 ] = { 1.0, 2.0, 3.0 }; const double constDoubleData = 3.14; int* cudaIntData; float* cudaFloatData; const double* cudaConstDoubleData; cudaMalloc( ( void** ) &cudaIntData, sizeof( int ) ); cudaMalloc( ( void** ) &cudaFloatData, 3 * sizeof( float ) ); cudaMalloc( ( void** ) &cudaConstDoubleData, sizeof( double ) ); cudaMemcpy( cudaIntData, &intData, sizeof( int ), Loading @@ -61,6 +69,10 @@ TEST( FileTest, WriteAndReadCUDA ) floatData, 3 * sizeof( float ), cudaMemcpyHostToDevice ); cudaMemcpy( (void*) cudaConstDoubleData, &constDoubleData, sizeof( double ), cudaMemcpyHostToDevice ); File file; ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) ); Loading @@ -69,19 +81,26 @@ TEST( FileTest, WriteAndReadCUDA ) ASSERT_TRUE( status ); status = file.write< float, Devices::Cuda, int >( cudaFloatData, 3 ); ASSERT_TRUE( status ); status = file.write< const double, Devices::Cuda >( cudaConstDoubleData ); ASSERT_TRUE( status ); ASSERT_TRUE( file.close() ); ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); int newIntData; float newFloatData[ 3 ]; double newDoubleData; int* newCudaIntData; float* newCudaFloatData; double* newCudaDoubleData; 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, int >( newCudaFloatData, 3 ); ASSERT_TRUE( status ); status = file.read< double, Devices::Cuda >( newCudaDoubleData, 1 ); ASSERT_TRUE( status ); cudaMemcpy( &newIntData, newCudaIntData, sizeof( int ), Loading @@ -90,10 +109,15 @@ TEST( FileTest, WriteAndReadCUDA ) newCudaFloatData, 3 * sizeof( float ), cudaMemcpyDeviceToHost ); cudaMemcpy( &newDoubleData, newCudaDoubleData, sizeof( double ), cudaMemcpyDeviceToHost ); EXPECT_EQ( newIntData, intData ); for( int i = 0; i < 3; i ++ ) EXPECT_EQ( newFloatData[ i ], floatData[ i ] ); EXPECT_EQ( newDoubleData, constDoubleData ); }; #endif #endif Loading Loading
src/TNL/File.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -44,13 +44,13 @@ bool File :: open( const String& fileName, std::cout << " for writing ... " << std::endl; } if( mode == IOMode::read ) file = fopen( fileName. getString(), "r" ); file = std::fopen( fileName.getString(), "r" ); if( mode == IOMode::write ) file = fopen( fileName. getString(), "w" ); file = std::fopen( fileName.getString(), "w" ); if( file == NULL ) { std::cerr << "I am not able to open the file " << fileName << ". "; perror( "" ); std::perror( "" ); return false; } this->fileOK = true; Loading @@ -63,7 +63,7 @@ bool File :: close() if( verbose ) std::cout << "Closing the file " << getFileName() << " ... " << std::endl; if( fclose( file ) != 0 ) if( std::fclose( file ) != 0 ) { std::cerr << "I was not able to close the file " << fileName << " properly!" << std::endl; return false; Loading
src/TNL/File.h +4 −6 Original line number Diff line number Diff line Loading @@ -12,8 +12,7 @@ #include <iostream> #include <fstream> #include <stdio.h> #include <stdlib.h> #include <cstdio> #ifdef HAVE_CUDA #include <cuda_runtime.h> #endif Loading Loading @@ -46,15 +45,15 @@ class File { IOMode mode; FILE* file; std::FILE* file; bool fileOK; String fileName; size_t writtenElements; std::size_t writtenElements; size_t readElements; std::size_t readElements; public: Loading Loading @@ -99,7 +98,6 @@ class File bool close(); static int verbose; }; bool fileExists( const String& fileName ); Loading
src/TNL/File_impl.h +44 −70 Original line number Diff line number Diff line Loading @@ -10,6 +10,8 @@ #pragma once #include <type_traits> #include <TNL/File.h> #include <TNL/Exceptions/CudaSupportMissing.h> Loading @@ -34,9 +36,9 @@ bool File :: read( Type* buffer, { TNL_ASSERT_GE( _elements, 0, "Number of elements to read must be non-negative." ); // convert _elements from Index to size_t, which is *unsigned* type // convert _elements from Index to std::size_t, which is *unsigned* type // (expected by fread etc) size_t elements = (size_t) _elements; std::size_t elements = (std::size_t) _elements; if( ! elements ) return true; Loading @@ -50,19 +52,17 @@ bool File :: read( Type* buffer, std::cerr << "File " << fileName << " was not opened for reading. " << std::endl; return false; } this->readElements = 0; const size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); void* host_buffer( 0 ); if( std::is_same< Device, Devices::Host >::value ) { if( fread( buffer, if( std::fread( buffer, sizeof( Type ), elements, file ) != elements ) { std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl; perror( "Fread ended with the error code" ); std::perror( "Fread ended with the error code" ); return false; } this->readElements = elements; Loading @@ -71,33 +71,21 @@ bool File :: read( Type* buffer, if( std::is_same< Device, Devices::Cuda >::value ) { #ifdef HAVE_CUDA /*!*** * Here we cannot use * * host_buffer = new Type[ host_buffer_size ]; * * because it does not work for constant types like * T = const bool. */ host_buffer = malloc( sizeof( Type ) * host_buffer_size ); readElements = 0; if( ! host_buffer ) { std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file " << this->getFileName() << "." << std::endl; return false; } const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); using BaseType = typename std::remove_cv< Type >::type; BaseType* host_buffer = new BaseType[ host_buffer_size ]; while( readElements < elements ) { size_t transfer = std::min( elements - readElements, host_buffer_size ); size_t transfered = fread( host_buffer, sizeof( Type ), transfer, file ); std::size_t transfer = std::min( elements - readElements, host_buffer_size ); std::size_t transfered = std::fread( host_buffer, sizeof( Type ), transfer, file ); if( transfered != transfer ) { std::cerr << "I am not able to read the data from the file " << fileName << "." << std::endl; std::cerr << transfered << " bytes were transfered. " << std::endl; perror( "Fread ended with the error code" ); std::perror( "Fread ended with the error code" ); delete[] host_buffer; return false; } Loading @@ -109,12 +97,12 @@ bool File :: read( Type* buffer, { std::cerr << "Transfer of data from the CUDA device to the file " << this->fileName << " failed." << std::endl; free( host_buffer ); delete[] host_buffer; return false; } readElements += transfer; this->readElements += transfer; } free( host_buffer ); delete[] host_buffer; return true; #else throw Exceptions::CudaSupportMissing(); Loading @@ -129,9 +117,9 @@ bool File :: write( const Type* buffer, { TNL_ASSERT_GE( _elements, 0, "Number of elements to write must be non-negative." ); // convert _elements from Index to size_t, which is *unsigned* type // convert _elements from Index to std::size_t, which is *unsigned* type // (expected by fread etc) size_t elements = (size_t) _elements; std::size_t elements = (std::size_t) _elements; if( ! elements ) return true; Loading @@ -146,20 +134,16 @@ bool File :: write( const Type* buffer, return false; } Type* buf = const_cast< Type* >( buffer ); void* host_buffer( 0 ); this->writtenElements = 0; const size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); if( std::is_same< Device, Devices::Host >::value ) { if( fwrite( buf, if( std::fwrite( buffer, sizeof( Type ), elements, this->file ) != elements ) { std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl; perror( "Fwrite ended with the error code" ); std::perror( "Fwrite ended with the error code" ); return false; } this->writtenElements = elements; Loading @@ -168,25 +152,14 @@ bool File :: write( const Type* buffer, if( std::is_same< Device, Devices::Cuda >::value ) { #ifdef HAVE_CUDA /*!*** * Here we cannot use * * host_buffer = new Type[ host_buffer_size ]; * * because it does not work for constant types like * T = const bool. */ host_buffer = malloc( sizeof( Type ) * host_buffer_size ); if( ! host_buffer ) { std::cerr << "I am sorry but I cannot allocate supporting buffer on the host for writing data from the GPU to the file " << this->getFileName() << "." << std::endl; return false; } const std::size_t host_buffer_size = std::min( tnlFileGPUvsCPUTransferBufferSize / sizeof( Type ), elements ); using BaseType = typename std::remove_cv< Type >::type; BaseType* host_buffer = new BaseType[ host_buffer_size ]; while( this->writtenElements < elements ) { size_t transfer = std::min( elements - this->writtenElements, host_buffer_size ); std::size_t transfer = std::min( elements - this->writtenElements, host_buffer_size ); cudaMemcpy( host_buffer, ( void* ) & ( buffer[ this->writtenElements ] ), transfer * sizeof( Type ), Loading @@ -195,21 +168,22 @@ bool File :: write( const Type* buffer, { std::cerr << "Transfer of data from the file " << this->fileName << " to the CUDA device failed." << std::endl; free( host_buffer ); delete[] host_buffer; return false; } if( fwrite( host_buffer, if( std::fwrite( host_buffer, sizeof( Type ), transfer, this->file ) != transfer ) { std::cerr << "I am not able to write the data to the file " << fileName << "." << std::endl; perror( "Fwrite ended with the error code" ); std::perror( "Fwrite ended with the error code" ); delete[] host_buffer; return false; } this->writtenElements += transfer; } free( host_buffer ); delete[] host_buffer; return true; #else throw Exceptions::CudaSupportMissing(); Loading
src/UnitTests/FileTest.h +24 −0 Original line number Diff line number Diff line Loading @@ -28,19 +28,24 @@ TEST( FileTest, WriteAndRead ) 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() ); ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); 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 ) ); EXPECT_EQ( newIntData, intData ); for( int i = 0; i < 3; i ++ ) EXPECT_EQ( newDoubleData[ i ], doubleData[ i ] ); EXPECT_EQ( newConstDoubleData, constDoubleData ); }; #ifdef HAVE_CUDA Loading @@ -48,11 +53,14 @@ TEST( FileTest, WriteAndReadCUDA ) { int intData( 5 ); float floatData[ 3 ] = { 1.0, 2.0, 3.0 }; const double constDoubleData = 3.14; int* cudaIntData; float* cudaFloatData; const double* cudaConstDoubleData; cudaMalloc( ( void** ) &cudaIntData, sizeof( int ) ); cudaMalloc( ( void** ) &cudaFloatData, 3 * sizeof( float ) ); cudaMalloc( ( void** ) &cudaConstDoubleData, sizeof( double ) ); cudaMemcpy( cudaIntData, &intData, sizeof( int ), Loading @@ -61,6 +69,10 @@ TEST( FileTest, WriteAndReadCUDA ) floatData, 3 * sizeof( float ), cudaMemcpyHostToDevice ); cudaMemcpy( (void*) cudaConstDoubleData, &constDoubleData, sizeof( double ), cudaMemcpyHostToDevice ); File file; ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) ); Loading @@ -69,19 +81,26 @@ TEST( FileTest, WriteAndReadCUDA ) ASSERT_TRUE( status ); status = file.write< float, Devices::Cuda, int >( cudaFloatData, 3 ); ASSERT_TRUE( status ); status = file.write< const double, Devices::Cuda >( cudaConstDoubleData ); ASSERT_TRUE( status ); ASSERT_TRUE( file.close() ); ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); int newIntData; float newFloatData[ 3 ]; double newDoubleData; int* newCudaIntData; float* newCudaFloatData; double* newCudaDoubleData; 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, int >( newCudaFloatData, 3 ); ASSERT_TRUE( status ); status = file.read< double, Devices::Cuda >( newCudaDoubleData, 1 ); ASSERT_TRUE( status ); cudaMemcpy( &newIntData, newCudaIntData, sizeof( int ), Loading @@ -90,10 +109,15 @@ TEST( FileTest, WriteAndReadCUDA ) newCudaFloatData, 3 * sizeof( float ), cudaMemcpyDeviceToHost ); cudaMemcpy( &newDoubleData, newCudaDoubleData, sizeof( double ), cudaMemcpyDeviceToHost ); EXPECT_EQ( newIntData, intData ); for( int i = 0; i < 3; i ++ ) EXPECT_EQ( newFloatData[ i ], floatData[ i ] ); EXPECT_EQ( newDoubleData, constDoubleData ); }; #endif #endif Loading