From 0c1362a9573b85eab655bd304322bf8d4ae1c20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 3 Mar 2019 13:38:18 +0100 Subject: [PATCH 01/72] Modifications in String documentantion. Splitting the String examples. Adding String enum 'SplitSkipEmpty' for the method split. --- src/Examples/CMakeLists.txt | 8 +- src/Examples/StringExample.cpp | 155 ++--- .../StringExampleGetAllocatedSize.cpp | 5 +- src/Examples/StringExampleGetSize.cpp | 13 - src/Examples/StringExampleReplace.cpp | 13 + src/Examples/StringExampleSetSize.cpp | 10 +- src/Examples/StringExampleSplit.cpp | 18 + src/Examples/StringExampleStrip.cpp | 13 + src/TNL/String.h | 534 +++++++++++------- src/TNL/{String_impl.h => String.hpp} | 7 +- src/UnitTests/StringTest.cpp | 2 +- 11 files changed, 426 insertions(+), 352 deletions(-) delete mode 100644 src/Examples/StringExampleGetSize.cpp create mode 100644 src/Examples/StringExampleReplace.cpp create mode 100644 src/Examples/StringExampleSplit.cpp create mode 100644 src/Examples/StringExampleStrip.cpp rename src/TNL/{String_impl.h => String.hpp} (98%) diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 1c52839e9..736fb9c57 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -29,9 +29,15 @@ ADD_EXECUTABLE( MathExample MathExample.cpp ) ADD_EXECUTABLE( ParameterContainerExample ParameterContainerExample.cpp ) ADD_EXECUTABLE( StringExample StringExample.cpp ) +ADD_CUSTOM_COMMAND( OUTPUT StringExample.out + COMMAND StringExample + DEPENDS StringExample + COMMENT Executing StringExample ) ADD_EXECUTABLE( StringExampleGetAllocatedSize StringExampleGetAllocatedSize.cpp ) -ADD_EXECUTABLE( StringExampleGetSize StringExampleGetSize.cpp ) +ADD_EXECUTABLE( StringExampleReplace StringExampleReplace.cpp ) ADD_EXECUTABLE( StringExampleSetSize StringExampleSetSize.cpp ) +ADD_EXECUTABLE( StringExampleSplit StringExampleSplit.cpp ) +ADD_EXECUTABLE( StringExampleStrip StringExampleStrip.cpp ) ADD_EXECUTABLE( TimerExample TimerExample.cpp ) ADD_EXECUTABLE( VectorExample VectorExample.cpp ) diff --git a/src/Examples/StringExample.cpp b/src/Examples/StringExample.cpp index a23904a4f..ff5efd2ab 100644 --- a/src/Examples/StringExample.cpp +++ b/src/Examples/StringExample.cpp @@ -8,125 +8,44 @@ 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 + 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; - 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 list = dates.split(';'); - cout << "list_dates: " << list[0] << ", " << list[1] << ", " << list[2] << endl; - - String cars("opel,mazda,,skoda,"); - std::vector list3 = cars.split(',', true); - cout << "split with true:" << list3[0] << ", " << list3[1] << ", " << list3[2] << endl; - std::vector list5 = cars.split(','); - cout << "split with false:" << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl; // save File myFile; diff --git a/src/Examples/StringExampleGetAllocatedSize.cpp b/src/Examples/StringExampleGetAllocatedSize.cpp index ad616de67..2065c6d1f 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 77fb499a4..000000000 --- a/src/Examples/StringExampleGetSize.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include - -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 000000000..f24c82b1e --- /dev/null +++ b/src/Examples/StringExampleReplace.cpp @@ -0,0 +1,13 @@ +#include +#include + +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 8451295a7..2b9de7844 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 000000000..f81f256fb --- /dev/null +++ b/src/Examples/StringExampleSplit.cpp @@ -0,0 +1,18 @@ +#include +#include + +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::SkipEmpty ); + cout << "split with true:" << list3[0] << ", " << list3[1] << ", " << list3[2] << endl; + std::vector list5 = cars.split(','); + cout << "split with false:" << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl; +} \ No newline at end of file diff --git a/src/Examples/StringExampleStrip.cpp b/src/Examples/StringExampleStrip.cpp new file mode 100644 index 000000000..87b9230c8 --- /dev/null +++ b/src/Examples/StringExampleStrip.cpp @@ -0,0 +1,13 @@ +#include +#include + +using namespace TNL; +using namespace std; + +int main() +{ + String names( " Josh Martin John Marley Charles " ); + String names2( ".......Josh Martin...John..Marley.Charles..." ); + cout << "better_names:" << names.strip() << endl; + cout << "better_names:" << names.strip( '.' ) << endl; +} \ No newline at end of file diff --git a/src/TNL/String.h b/src/TNL/String.h index 3da2ffbf4..559358a8c 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,212 +23,336 @@ namespace TNL { class String; -///// -/// \brief Class for managing strings. -/// -/// \par Example -/// \include StringExample.cpp -/// \par Output -/// \include StringExample.out +/** + * \brief Class for managing strings. + * + * \par Example + * \include StringExample.cpp + * \par Output + * \include StringExample.out + */ 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 SplitSkipEmpty + { + DoNotSkipEmpty, ///< 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 = ' ', SplitSkipEmpty skipEmpty = DoNotSkipEmpty ) 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 }; /// \brief Returns concatenation of \e string1 and \e string2. @@ -259,4 +383,4 @@ template<> inline String convertToString( const bool& b ) } // namespace TNL -#include +#include diff --git a/src/TNL/String_impl.h b/src/TNL/String.hpp similarity index 98% rename from src/TNL/String_impl.h rename to src/TNL/String.hpp index 3c5aa253a..f380e3cd7 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,7 +211,7 @@ String::strip( char strip ) const } inline std::vector< String > -String::split( const char separator, bool skipEmpty ) const +String::split( const char separator, SplitSkipEmpty skipEmpty ) const { std::vector< String > parts; String s; diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp index 10c85497b..2f0c29220 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(), 43 ); } TEST( StringTest, GetString ) -- GitLab From db2c359941f92897dc5e8928fc70f64f4f9b0359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 3 Mar 2019 14:13:36 +0100 Subject: [PATCH 02/72] String send and receive was changed from methods to functions. --- src/Examples/CMakeLists.txt | 16 +++++-- src/TNL/Communicators/MPIPrint.h | 8 ++-- src/TNL/String.h | 73 +++++++++++++++++++++++--------- src/TNL/String.hpp | 55 ++++++++++++------------ 4 files changed, 96 insertions(+), 56 deletions(-) diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 736fb9c57..51f45611c 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -29,15 +29,23 @@ ADD_EXECUTABLE( MathExample MathExample.cpp ) ADD_EXECUTABLE( ParameterContainerExample ParameterContainerExample.cpp ) ADD_EXECUTABLE( StringExample StringExample.cpp ) -ADD_CUSTOM_COMMAND( OUTPUT StringExample.out - COMMAND StringExample - DEPENDS StringExample - COMMENT Executing StringExample ) +EXECUTE_PROCESS( COMMAND StringExample OUTPUT_FILE StringExample.out ) + ADD_EXECUTABLE( StringExampleGetAllocatedSize StringExampleGetAllocatedSize.cpp ) +EXECUTE_PROCESS( COMMAND StringExampleGetAllocatedSize OUTPUT_FILE StringExampleGetAllocatedSize.out ) + ADD_EXECUTABLE( StringExampleReplace StringExampleReplace.cpp ) +EXECUTE_PROCESS( COMMAND StringExampleReplace OUTPUT_FILE StringExampleReplace.out ) + ADD_EXECUTABLE( StringExampleSetSize StringExampleSetSize.cpp ) +EXECUTE_PROCESS( COMMAND StringExampleSetSize OUTPUT_FILE StringExampleSetSize.out ) + ADD_EXECUTABLE( StringExampleSplit StringExampleSplit.cpp ) +EXECUTE_PROCESS( COMMAND StringExampleSpli OUTPUT_FILE StringExampleSplit.out ) + ADD_EXECUTABLE( StringExampleStrip StringExampleStrip.cpp ) +EXECUTE_PROCESS( COMMAND StringExampleStrip OUTPUT_FILE StringExampleStrip.out ) + ADD_EXECUTABLE( TimerExample TimerExample.cpp ) ADD_EXECUTABLE( VectorExample VectorExample.cpp ) diff --git a/src/TNL/Communicators/MPIPrint.h b/src/TNL/Communicators/MPIPrint.h index 52684e574..8b58d17a1 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() ); \ + send( __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() ); \ + receive( __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() ); \ + send( __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() ); \ + receive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() ); \ std::cerr << __tnl_mpi_print_string_; \ } \ } \ diff --git a/src/TNL/String.h b/src/TNL/String.h index 559358a8c..7fc13524c 100644 --- a/src/TNL/String.h +++ b/src/TNL/String.h @@ -337,36 +337,33 @@ class String * \include StringExampleSplit.out */ std::vector< String > split( const char separator = ' ', SplitSkipEmpty skipEmpty = DoNotSkipEmpty ) 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 }; -/// \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 ) { @@ -375,12 +372,48 @@ String convertToString( const T& value ) return String( str.str().data() ); } +/** + * \brief Specialization of function \ref conertToString 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 send( const String& str, int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); + +/** + * \brief Receives a string from the source MPI process. + */ + +/** + * \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 receive( 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 diff --git a/src/TNL/String.hpp b/src/TNL/String.hpp index f380e3cd7..b54333394 100644 --- a/src/TNL/String.hpp +++ b/src/TNL/String.hpp @@ -228,27 +228,47 @@ String::split( const char separator, SplitSkipEmpty skipEmpty ) const 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 send( 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( str.getString(), str.length(), MPI_CHAR, target, tag, mpi_comm ); } -inline void String::receive( int source, int tag, MPI_Comm mpi_comm ) +inline void receive( 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, ); @@ -265,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 -- GitLab From a89c663dbf2183d60950b9474c4b661cc97b3822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 3 Mar 2019 17:14:04 +0100 Subject: [PATCH 03/72] Fixed execution of String examples. --- src/Examples/CMakeLists.txt | 19 +++++++++++++------ src/Examples/StringExample.cpp | 12 +----------- src/Examples/StringExampleSplit.cpp | 4 ++-- src/Examples/StringExampleStrip.cpp | 4 ++-- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 51f45611c..334df3db6 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -29,23 +29,30 @@ ADD_EXECUTABLE( MathExample MathExample.cpp ) ADD_EXECUTABLE( ParameterContainerExample ParameterContainerExample.cpp ) ADD_EXECUTABLE( StringExample StringExample.cpp ) -EXECUTE_PROCESS( COMMAND StringExample OUTPUT_FILE StringExample.out ) +ADD_CUSTOM_COMMAND( COMMAND StringExample > StringExample.out OUTPUT StringExample.out ) ADD_EXECUTABLE( StringExampleGetAllocatedSize StringExampleGetAllocatedSize.cpp ) -EXECUTE_PROCESS( COMMAND StringExampleGetAllocatedSize OUTPUT_FILE StringExampleGetAllocatedSize.out ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleGetAllocatedSize > StringExampleGetAllocatedSize.out OUTPUT StringExampleGetAllocatedSize.out ) ADD_EXECUTABLE( StringExampleReplace StringExampleReplace.cpp ) -EXECUTE_PROCESS( COMMAND StringExampleReplace OUTPUT_FILE StringExampleReplace.out ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleReplace > StringExampleReplace.out OUTPUT StringExampleReplace.out ) ADD_EXECUTABLE( StringExampleSetSize StringExampleSetSize.cpp ) -EXECUTE_PROCESS( COMMAND StringExampleSetSize OUTPUT_FILE StringExampleSetSize.out ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleSetSize > StringExampleSetSize.out OUTPUT StringExampleSetSize.out ) ADD_EXECUTABLE( StringExampleSplit StringExampleSplit.cpp ) -EXECUTE_PROCESS( COMMAND StringExampleSpli OUTPUT_FILE StringExampleSplit.out ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleSplit > StringExampleSplit.out OUTPUT StringExampleSplit.out ) ADD_EXECUTABLE( StringExampleStrip StringExampleStrip.cpp ) -EXECUTE_PROCESS( COMMAND StringExampleStrip OUTPUT_FILE StringExampleStrip.out ) +ADD_CUSTOM_COMMAND( COMMAND StringExampleStrip > StringExampleStrip.out OUTPUT StringExampleStrip.out ) ADD_EXECUTABLE( TimerExample TimerExample.cpp ) ADD_EXECUTABLE( VectorExample VectorExample.cpp ) + +ADD_CUSTOM_TARGET( run ALL DEPENDS + StringExample.out + StringExampleGetAllocatedSize.out + StringExampleReplace.out + StringExampleSplit.out + StringExampleStrip.out ) diff --git a/src/Examples/StringExample.cpp b/src/Examples/StringExample.cpp index ff5efd2ab..d9fc61420 100644 --- a/src/Examples/StringExample.cpp +++ b/src/Examples/StringExample.cpp @@ -30,7 +30,7 @@ int main( int argc, char* argv[] ) cout << " 3rd letter of string1 =" << string1[ 2 ] << endl; cout << " string1 + string2 = " << string1 + string2 << endl; - cout << " string1 + \"another string\" = " << string1 + "another string" << endl; + cout << " string1 + \" another string\" = " << string1 + " another string" << endl; string2 += "another string"; cout << " string2 = " << string2; @@ -45,14 +45,4 @@ int main( int argc, char* argv[] ) cout << "emptyString is empty" << endl; if( string1 ) cout << "string1 is not empty" << endl; - - - // save - File myFile; - myFile << String("Header"); // saves "Header" into myFile - - // load - String strg; - myFile >> strg; - cout << "strg:" << strg << endl; } diff --git a/src/Examples/StringExampleSplit.cpp b/src/Examples/StringExampleSplit.cpp index f81f256fb..52aa0ee3e 100644 --- a/src/Examples/StringExampleSplit.cpp +++ b/src/Examples/StringExampleSplit.cpp @@ -12,7 +12,7 @@ int main() String cars("Subaru,Mazda,,Skoda," ); vector< String > list3 = cars.split(',', String::SkipEmpty ); - cout << "split with true:" << list3[0] << ", " << list3[1] << ", " << list3[2] << endl; + cout << "split with String::SkipEmpty = " << list3[0] << ", " << list3[1] << ", " << list3[2] << endl; std::vector list5 = cars.split(','); - cout << "split with false:" << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl; + cout << "split without String::SkipEmpty = " << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl; } \ No newline at end of file diff --git a/src/Examples/StringExampleStrip.cpp b/src/Examples/StringExampleStrip.cpp index 87b9230c8..ed3fd656c 100644 --- a/src/Examples/StringExampleStrip.cpp +++ b/src/Examples/StringExampleStrip.cpp @@ -8,6 +8,6 @@ int main() { String names( " Josh Martin John Marley Charles " ); String names2( ".......Josh Martin...John..Marley.Charles..." ); - cout << "better_names:" << names.strip() << endl; - cout << "better_names:" << names.strip( '.' ) << endl; + cout << "names strip is: " << names.strip() << endl; + cout << "names2 strip is: " << names.strip( '.' ) << endl; } \ No newline at end of file -- GitLab From 4729e7f8bdb211243d2e11878f2a46d66d37908e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 3 Mar 2019 17:54:40 +0100 Subject: [PATCH 04/72] Reformatting documentation of Timer and adding logger example. --- src/Examples/CMakeLists.txt | 8 +- src/Examples/TimerExample.cpp | 14 +-- src/Examples/TimerExampleLogger.cpp | 19 ++++ src/TNL/Timer.h | 171 +++++++++++++++------------- src/TNL/{Timer_impl.h => Timer.hpp} | 18 ++- 5 files changed, 138 insertions(+), 92 deletions(-) create mode 100644 src/Examples/TimerExampleLogger.cpp rename src/TNL/{Timer_impl.h => Timer.hpp} (93%) diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 334df3db6..c03149ef5 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -47,6 +47,10 @@ 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 ) @@ -55,4 +59,6 @@ ADD_CUSTOM_TARGET( run ALL DEPENDS StringExampleGetAllocatedSize.out StringExampleReplace.out StringExampleSplit.out - StringExampleStrip.out ) + StringExampleStrip.out + TimerExample.out + TimerExampleLogger.out ) diff --git a/src/Examples/TimerExample.cpp b/src/Examples/TimerExample.cpp index 5d5a81454..ab8cdb863 100644 --- a/src/Examples/TimerExample.cpp +++ b/src/Examples/TimerExample.cpp @@ -1,11 +1,10 @@ #include #include -#include #include 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 000000000..96dde5702 --- /dev/null +++ b/src/Examples/TimerExampleLogger.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +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/TNL/Timer.h b/src/TNL/Timer.h index 486f09f38..9f68182c4 100644 --- a/src/TNL/Timer.h +++ b/src/TNL/Timer.h @@ -16,78 +16,91 @@ 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 time measuring. + * + * Counts the elapsed real time and CPU time in seconds together with CPU cycles + * between the \ref start and \ref stop methods. + * + * \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 +108,45 @@ 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; + + unsigned long long int initialCPUCycles, totalCPUCycles; + + bool stopState; - /// \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 ); - } }; } // namespace TNL -#include +#include 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 5a1cec336..b4a4fa639 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 -- GitLab From af8de0da00c35c8951e82952489852e549cc4fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 3 Mar 2019 20:19:39 +0100 Subject: [PATCH 05/72] Revision of Timer - documentation reformatting and code refactoring. --- src/TNL/Timer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TNL/Timer.h b/src/TNL/Timer.h index 9f68182c4..2c697a04e 100644 --- a/src/TNL/Timer.h +++ b/src/TNL/Timer.h @@ -17,10 +17,11 @@ namespace TNL { class Logger; /** - * \brief Class for time measuring. + * \brief Class for real time, CPU time and CPU cycles measuring. * - * Counts the elapsed real time and CPU time in seconds together with CPU cycles - * between the \ref start and \ref stop methods. + * 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 @@ -144,7 +145,6 @@ class Timer unsigned long long int initialCPUCycles, totalCPUCycles; bool stopState; - }; } // namespace TNL -- GitLab From 87b665783d6a527e8de50ce33c4ef4aa935eced6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 3 Mar 2019 20:21:02 +0100 Subject: [PATCH 06/72] Renaming Object_impl.h to Object.hpp. --- src/TNL/Object.h | 2 +- src/TNL/{Object_impl.h => Object.hpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/TNL/{Object_impl.h => Object.hpp} (100%) diff --git a/src/TNL/Object.h b/src/TNL/Object.h index d909a21ed..fc45779bb 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -118,4 +118,4 @@ parseObjectType( const String& objectType ); } // namespace TNL -#include +#include diff --git a/src/TNL/Object_impl.h b/src/TNL/Object.hpp similarity index 100% rename from src/TNL/Object_impl.h rename to src/TNL/Object.hpp -- GitLab From 9d5dc745ee9bcf542f9383b8f8ce49f262ce4ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 3 Mar 2019 21:40:07 +0100 Subject: [PATCH 07/72] Revision of Object - writing example for getType method. --- src/Examples/CMakeLists.txt | 4 ++ src/Examples/ObjectExample_getType.cpp | 63 ++++++++++++++++++++++++++ src/TNL/Devices/Cuda.h | 3 ++ src/TNL/Devices/Cuda_impl.h | 2 +- src/TNL/Devices/Host.h | 3 ++ src/TNL/Devices/MIC.h | 13 ++++-- src/TNL/Object.h | 52 ++++++++++++++------- 7 files changed, 117 insertions(+), 23 deletions(-) create mode 100644 src/Examples/ObjectExample_getType.cpp diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index c03149ef5..1798d98f5 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -26,6 +26,9 @@ 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( StringExample StringExample.cpp ) @@ -55,6 +58,7 @@ ADD_CUSTOM_COMMAND( COMMAND TimerExampleLogger > TimerExampleLogger.out OUTPUT T ADD_EXECUTABLE( VectorExample VectorExample.cpp ) ADD_CUSTOM_TARGET( run ALL DEPENDS + ObjectExample_getType.out StringExample.out StringExampleGetAllocatedSize.out StringExampleReplace.out diff --git a/src/Examples/ObjectExample_getType.cpp b/src/Examples/ObjectExample_getType.cpp new file mode 100644 index 000000000..7cc7476d6 --- /dev/null +++ b/src/Examples/ObjectExample_getType.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +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/TNL/Devices/Cuda.h b/src/TNL/Devices/Cuda.h index 0ba22cb00..4a802a021 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, diff --git a/src/TNL/Devices/Cuda_impl.h b/src/TNL/Devices/Cuda_impl.h index c9828c66d..234f45b72 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 6b56302a2..98b95f2f6 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 373e838f7..db1a23809 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/Object.h b/src/TNL/Object.h index fc45779bb..8c601380b 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -22,40 +22,58 @@ 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. */ 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; /** -- GitLab From 656cfd84e506afbc9a9739587a9340ff14d7283f Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 4 Mar 2019 15:39:59 +0100 Subject: [PATCH 08/72] Fixed String tests. --- src/UnitTests/StringTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp index 2f0c29220..ebf0c41d6 100644 --- a/src/UnitTests/StringTest.cpp +++ b/src/UnitTests/StringTest.cpp @@ -83,7 +83,7 @@ TEST( StringTest, SetSize ) { String str; str.setSize( 42 ); - EXPECT_EQ( str.getAllocatedSize(), 43 ); + 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::SkipEmpty ); ASSERT_EQ( (int) parts.size(), 4 ); EXPECT_EQ( parts[ 0 ], "br" ); EXPECT_EQ( parts[ 1 ], "c" ); -- GitLab From cc2c47963c854148d8b11a6f76d9c23c54b54ec7 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 4 Mar 2019 16:30:49 +0100 Subject: [PATCH 09/72] Adding save/load to String example. --- src/Examples/StringExample.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Examples/StringExample.cpp b/src/Examples/StringExample.cpp index d9fc61420..5789020c1 100644 --- a/src/Examples/StringExample.cpp +++ b/src/Examples/StringExample.cpp @@ -45,4 +45,13 @@ int main( int argc, char* argv[] ) cout << "emptyString is empty" << endl; if( string1 ) cout << "string1 is not empty" << endl; + + File myFile; + myFile.open( "string_save.out", File::out ); + myFile << string1; + myFile.close(); + + myFile.open( "string_save.out", File::in ); + myFile >> string3; + cout << "string 3 after loading = " << strg << endl; } -- GitLab From 01b45f6ca4829f7517aefb2c26b0c7bc019e76d8 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 4 Mar 2019 16:31:25 +0100 Subject: [PATCH 10/72] Making CSR::getNonZeroRowLengthFast __cuda_callable__. --- src/TNL/Matrices/CSR.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TNL/Matrices/CSR.h b/src/TNL/Matrices/CSR.h index 10b718456..fab302bed 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; -- GitLab From d7f5c73b5409655997c1cb5ccc80076b2f8ccf7c Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 4 Mar 2019 16:32:02 +0100 Subject: [PATCH 11/72] Fixing commented smart pointers synchronization in CUDA 1D grid traverser. --- src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp b/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp index 5b35d5be9..42ba1b636 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 ); -- GitLab From b9b0973c4c611cf7edba5831fc97d117f5332002 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 4 Mar 2019 16:32:50 +0100 Subject: [PATCH 12/72] Deleting FIXME for Object destructor. --- src/TNL/Object.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/TNL/Object.h b/src/TNL/Object.h index 8c601380b..bd30e15b1 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -119,9 +119,6 @@ class Object bool 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__ #ifndef HAVE_MIC virtual ~Object(){}; #endif -- GitLab From c510629f69510c5e7cad16e5e2325901e2857e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Mon, 4 Mar 2019 18:58:15 +0100 Subject: [PATCH 13/72] Renaming String send and receive to mpiSend and mpiReceive. --- src/Examples/StringExample.cpp | 4 ++-- src/TNL/Communicators/MPIPrint.h | 8 ++++---- src/TNL/String.h | 4 ++-- src/TNL/String.hpp | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Examples/StringExample.cpp b/src/Examples/StringExample.cpp index 5789020c1..a8272ac06 100644 --- a/src/Examples/StringExample.cpp +++ b/src/Examples/StringExample.cpp @@ -46,12 +46,12 @@ int main( int argc, char* argv[] ) if( string1 ) cout << "string1 is not empty" << endl; - File myFile; + /*File myFile; myFile.open( "string_save.out", File::out ); myFile << string1; myFile.close(); myFile.open( "string_save.out", File::in ); myFile >> string3; - cout << "string 3 after loading = " << strg << endl; + cout << "string 3 after loading = " << string3 << endl;*/ } diff --git a/src/TNL/Communicators/MPIPrint.h b/src/TNL/Communicators/MPIPrint.h index 8b58d17a1..825ae239f 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() ); \ - send( __tnl_mpi_print_string_, 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_; \ - receive( __tnl_mpi_print_string_, __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() ); \ - send( __tnl_mpi_print_string_, 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_; \ - receive( __tnl_mpi_print_string_, __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/String.h b/src/TNL/String.h index 7fc13524c..e275e64de 100644 --- a/src/TNL/String.h +++ b/src/TNL/String.h @@ -393,7 +393,7 @@ template<> inline String convertToString( const bool& b ) * @param tag MPI tag * @param mpi_comm MPI communication group */ -void send( const String& str, int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); +void mpiSend( const String& str, int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); /** * \brief Receives a string from the source MPI process. @@ -407,7 +407,7 @@ void send( const String& str, int target, int tag = 0, MPI_Comm mpi_comm = MPI_C * @param tag MPI tag * @param mpi_comm MPI communication group */ -void receive( String& str, int source, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); +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 ); diff --git a/src/TNL/String.hpp b/src/TNL/String.hpp index b54333394..91228a37e 100644 --- a/src/TNL/String.hpp +++ b/src/TNL/String.hpp @@ -250,14 +250,14 @@ inline std::ostream& operator<<( std::ostream& stream, const String& str ) } #ifdef HAVE_MPI -inline void send( const String& str, int target, int tag, MPI_Comm mpi_comm ) +inline void mpiSend( const String& str, int target, int tag, MPI_Comm mpi_comm ) { int size = str.getSize(); MPI_Send( &size, 1, MPI_INT, target, tag, mpi_comm ); MPI_Send( str.getString(), str.length(), MPI_CHAR, target, tag, mpi_comm ); } -inline void receive( String& str, 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; -- GitLab From adbe8e814ac6ce65e237461f4d7fdcc103aa1c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Mon, 4 Mar 2019 19:43:25 +0100 Subject: [PATCH 14/72] Fixing String documentation. --- Documentation/Doxyfile | 3 ++- src/Examples/StringExampleSplit.cpp | 4 ++-- src/TNL/String.h | 36 ++++++++++++++++++----------- src/TNL/String.hpp | 6 ++--- src/UnitTests/StringTest.cpp | 2 +- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/Documentation/Doxyfile b/Documentation/Doxyfile index 11a3160f8..39df663bf 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/Examples/StringExampleSplit.cpp b/src/Examples/StringExampleSplit.cpp index 52aa0ee3e..d0b45e525 100644 --- a/src/Examples/StringExampleSplit.cpp +++ b/src/Examples/StringExampleSplit.cpp @@ -11,8 +11,8 @@ int main() cout << "list_dates = " << list[0] << ", " << list[1] << ", " << list[2] << endl; String cars("Subaru,Mazda,,Skoda," ); - vector< String > list3 = cars.split(',', String::SkipEmpty ); + vector< String > list3 = cars.split(',', String::SplitSkip::SkipEmpty ); cout << "split with String::SkipEmpty = " << list3[0] << ", " << list3[1] << ", " << list3[2] << endl; std::vector list5 = cars.split(','); cout << "split without String::SkipEmpty = " << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl; -} \ No newline at end of file +} diff --git a/src/TNL/String.h b/src/TNL/String.h index e275e64de..a04802216 100644 --- a/src/TNL/String.h +++ b/src/TNL/String.h @@ -26,10 +26,24 @@ class String; /** * \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 @@ -39,10 +53,10 @@ class String /** * \brief This enum defines how the operation split of string is to be performed. */ - enum SplitSkipEmpty + enum class SplitSkip { - DoNotSkipEmpty, ///< Do not skip empty characters - SkipEmpty ///< Skip empty characters. + NoSkip, ///< Do not skip empty characters + SkipEmpty ///< Skip empty characters. }; /** @@ -336,26 +350,26 @@ class String * \par Output * \include StringExampleSplit.out */ - std::vector< String > split( const char separator = ' ', SplitSkipEmpty skipEmpty = DoNotSkipEmpty ) const; + 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 Writes the string \e str to given \e stream + * \brief Writes the string \e str to given \e stream */ std::ostream& operator<<( std::ostream& stream, const String& str ); @@ -373,7 +387,7 @@ String convertToString( const T& value ) } /** - * \brief Specialization of function \ref conertToString for boolean. + * \brief Specialization of function \ref convertToString for boolean. * * The boolean type is converted to 'true' ot 'false'. */ @@ -395,10 +409,6 @@ template<> inline String convertToString( const bool& b ) */ void mpiSend( const String& str, int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD ); -/** - * \brief Receives a string from the source MPI process. - */ - /** * \brief Receives a string from the target MPI process. * diff --git a/src/TNL/String.hpp b/src/TNL/String.hpp index 91228a37e..ed0a54fb9 100644 --- a/src/TNL/String.hpp +++ b/src/TNL/String.hpp @@ -211,19 +211,19 @@ String::strip( char strip ) const } inline std::vector< String > -String::split( const char separator, SplitSkipEmpty 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; } diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp index ebf0c41d6..9582c8221 100644 --- a/src/UnitTests/StringTest.cpp +++ b/src/UnitTests/StringTest.cpp @@ -277,7 +277,7 @@ TEST( StringTest, split ) EXPECT_EQ( parts[ 4 ], "br" ); EXPECT_EQ( parts[ 5 ], "" ); - parts = String( "abracadabra" ).split( 'a', String::SkipEmpty ); + parts = String( "abracadabra" ).split( 'a', String::SplitSkip::SkipEmpty ); ASSERT_EQ( (int) parts.size(), 4 ); EXPECT_EQ( parts[ 0 ], "br" ); EXPECT_EQ( parts[ 1 ], "c" ); -- GitLab From 35b5321867e3dd1698ac507473f1ec01255f45e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Mon, 4 Mar 2019 20:43:06 +0100 Subject: [PATCH 15/72] getObjectType is void and it throws exceptions. --- src/TNL/Exceptions/NotTNLFile.h | 31 ++++++++++ .../Exceptions/ObjectTypeDetectionFailure.h | 31 ++++++++++ src/TNL/Meshes/Readers/TNLReader.h | 11 +++- src/TNL/Object.h | 21 ++++++- src/TNL/Object.hpp | 43 ++++++-------- src/Tools/tnl-diff.cpp | 10 +++- src/Tools/tnl-init.cpp | 6 +- src/Tools/tnl-lattice-init.h | 28 ++++++--- src/Tools/tnl-view.h | 59 ++++++++++--------- 9 files changed, 168 insertions(+), 72 deletions(-) create mode 100644 src/TNL/Exceptions/NotTNLFile.h create mode 100644 src/TNL/Exceptions/ObjectTypeDetectionFailure.h diff --git a/src/TNL/Exceptions/NotTNLFile.h b/src/TNL/Exceptions/NotTNLFile.h new file mode 100644 index 000000000..e65fd490b --- /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 +#include + +namespace TNL { +namespace Exceptions { + +class NotTNLFile + : public std::runtime_error +{ +public: + NotTNLFile() + : std::runtime_error( "Wring 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 000000000..6381c2fd7 --- /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 +#include + +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/Meshes/Readers/TNLReader.h b/src/TNL/Meshes/Readers/TNLReader.h index 68f4d13a2..18fe2e690 100644 --- a/src/TNL/Meshes/Readers/TNLReader.h +++ b/src/TNL/Meshes/Readers/TNLReader.h @@ -12,6 +12,7 @@ #include #include +#include #include 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 + { + getObjectType( fileName, objectType ); + } + catch( ... ) + { + throw Exceptions::ObjectTypeDetectionFailure( fileName, "mesh" ); } const std::vector< String > parsedMeshType = parseObjectType( objectType ); diff --git a/src/TNL/Object.h b/src/TNL/Object.h index bd30e15b1..1c957853f 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -27,6 +27,9 @@ namespace TNL { * 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. */ class Object { @@ -118,15 +121,27 @@ class Object */ bool boundLoad( const String& fileName ); - /// Destructor. + /** + * \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 + * @param type + * @return + */ +void getObjectType( File& file, String& type ); -bool getObjectType( const String& file_name, String& type ); +void getObjectType( const String& file_name, String& type ); std::vector< String > parseObjectType( const String& objectType ); diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index f0b1a8545..49e8c70ca 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -15,32 +15,33 @@ #include #include +#include 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 bool Object::save( File& file ) const { if( ! file.write( magic_number, strlen( magic_number ) ) ) return false; @@ -48,11 +49,10 @@ inline bool Object :: save( File& file ) const return true; } -inline bool Object :: load( File& file ) +inline bool Object::load( File& file ) { String objectType; - if( ! getObjectType( file, objectType ) ) - return false; + getObjectType( file, objectType ); if( objectType != this->getSerializationTypeVirtual() ) { std::cerr << "Given file contains instance of " << objectType << " but " << getSerializationTypeVirtual() << " is expected." << std::endl; @@ -61,12 +61,12 @@ inline bool Object :: load( File& file ) return true; } -inline bool Object :: boundLoad( File& file ) +inline bool Object::boundLoad( File& file ) { return load( file ); } -inline bool Object :: save( const String& fileName ) const +inline bool Object::save( const String& fileName ) const { File file; if( ! file.open( fileName, IOMode::write ) ) @@ -77,7 +77,7 @@ inline bool Object :: save( const String& fileName ) const return this->save( file ); } -inline bool Object :: load( const String& fileName ) +inline bool Object::load( const String& fileName ) { File file; if( ! file.open( fileName, IOMode::read ) ) @@ -88,7 +88,7 @@ inline bool Object :: load( const String& fileName ) return this->load( file ); } -inline bool Object :: boundLoad( const String& fileName ) +inline bool Object::boundLoad( const String& fileName ) { File file; if( ! file.open( fileName, IOMode::read ) ) @@ -99,29 +99,20 @@ inline bool Object :: boundLoad( const String& fileName ) return this->boundLoad( file ); } - -inline bool getObjectType( File& file, String& type ) +inline void getObjectType( File& file, String& type ) { char mn[ 10 ]; file.read( 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; } -inline bool getObjectType( const String& fileName, String& type ) +inline void getObjectType( const String& fileName, String& type ) { 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, IOMode::read ); + getObjectType( binaryFile, type ); } inline std::vector< String > diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp index b35dba172..6e8674eae 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 #include #include @@ -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; + getObjectType( meshFile, meshType ); + } + 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-init.cpp b/src/Tools/tnl-init.cpp index 0695d62e1..40ada4a8e 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 + { + getObjectType( meshFile, meshType ); + } + 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-lattice-init.h b/src/Tools/tnl-lattice-init.h index 0b42a72ea..d993e1ff7 100644 --- a/src/Tools/tnl-lattice-init.h +++ b/src/Tools/tnl-lattice-init.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -221,10 +222,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; + getObjectType( profileFile, meshFunctionType ); + } + catch(...) + { + throw Exceptions::ObjectTypeDetectionFailure( profileFile, "mesh" ); } //std::cout << meshFunctionType << " detected in " << profileFile << " file." << std::endl; const std::vector< String > parsedMeshFunctionType = parseObjectType( meshFunctionType ); @@ -277,10 +281,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; + getObjectType( meshFile, meshType ); + } + catch(...) + { + throw Exceptions::ObjectTypeDetectionFailure( meshFile, "mesh" ); } std::cout << meshType << " detected in " << meshFile << " file." << std::endl; const std::vector< String > parsedMeshType = parseObjectType( meshType ); @@ -372,10 +379,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; + getObjectType( meshFile, meshType ); + } + 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-view.h b/src/Tools/tnl-view.h index e4ae274ae..6ce8967e4 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -473,35 +473,40 @@ 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; + getObjectType( inputFiles[ i ], objectType ); + } + 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::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; } if( verbose ) std::cout << std::endl; -- GitLab From e55f31a958b3438bd1fb4edce17f666c8ee3f10d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Mon, 4 Mar 2019 21:15:29 +0100 Subject: [PATCH 16/72] getObjectType returns String with the object type. --- src/TNL/Meshes/Readers/TNLReader.h | 2 +- src/TNL/Object.h | 22 +++++++++++++++++----- src/TNL/Object.hpp | 11 ++++++----- src/Tools/tnl-diff.cpp | 2 +- src/Tools/tnl-diff.h | 2 +- src/Tools/tnl-init.cpp | 2 +- src/Tools/tnl-lattice-init.h | 6 +++--- src/Tools/tnl-view.h | 2 +- 8 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/TNL/Meshes/Readers/TNLReader.h b/src/TNL/Meshes/Readers/TNLReader.h index 18fe2e690..881a50265 100644 --- a/src/TNL/Meshes/Readers/TNLReader.h +++ b/src/TNL/Meshes/Readers/TNLReader.h @@ -31,7 +31,7 @@ public: String objectType; try { - getObjectType( fileName, objectType ); + objectType = getObjectType( fileName ); } catch( ... ) { diff --git a/src/TNL/Object.h b/src/TNL/Object.h index 1c957853f..6267da9d3 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -135,14 +135,26 @@ class Object /** * \brief Extracts object type from a binary file. * - * @param file - * @param type - * @return + * @param file is file where the object is stored + * @return string with the object type */ -void getObjectType( File& file, String& type ); +String getObjectType( File& file ); -void getObjectType( const String& file_name, String& type ); +/** + * \brief Does the same as \ref getObjectType but with \e fileName parameter instead of file. + * + * @param fileName name of file where the object is stored + * @param type string with the object type + */ +String getObjectType( const String& fileName ); +/** + * \brief Parses the object type + * + * @param objectType is a string with the object type + * @return list of strings where the first one is the object type and the next + * strings are the template parameters + */ std::vector< String > parseObjectType( const String& objectType ); diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index 49e8c70ca..b6de3817f 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -51,8 +51,7 @@ inline bool Object::save( File& file ) const inline bool Object::load( File& file ) { - String objectType; - getObjectType( file, objectType ); + String objectType = getObjectType( file ); if( objectType != this->getSerializationTypeVirtual() ) { std::cerr << "Given file contains instance of " << objectType << " but " << getSerializationTypeVirtual() << " is expected." << std::endl; @@ -99,20 +98,22 @@ inline bool Object::boundLoad( const String& fileName ) return this->boundLoad( file ); } -inline void getObjectType( File& file, String& type ) +inline String getObjectType( File& file ) { char mn[ 10 ]; + String type; file.read( mn, strlen( magic_number ) ); if( strncmp( mn, magic_number, 5 ) != 0 ) throw Exceptions::NotTNLFile(); file >> type; + return type; } -inline void getObjectType( const String& fileName, String& type ) +inline String getObjectType( const String& fileName ) { File binaryFile; binaryFile.open( fileName, IOMode::read ); - getObjectType( binaryFile, type ); + return getObjectType( binaryFile ); } inline std::vector< String > diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp index 6e8674eae..1d681a6df 100644 --- a/src/Tools/tnl-diff.cpp +++ b/src/Tools/tnl-diff.cpp @@ -53,7 +53,7 @@ int main( int argc, char* argv[] ) String meshType; try { - getObjectType( meshFile, meshType ); + meshType = getObjectType( meshFile ); } catch(...) { diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index 0f90bc28a..d4f7514e2 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -625,7 +625,7 @@ bool processFiles( const Config::ParameterContainer& parameters ) String objectType; try { - getObjectType( inputFiles[ 0 ], objectType ); + objectType = getObjectType( inputFiles[ 0 ] ); } catch( std::ios_base::failure exception ) { diff --git a/src/Tools/tnl-init.cpp b/src/Tools/tnl-init.cpp index 40ada4a8e..1bdadb07a 100644 --- a/src/Tools/tnl-init.cpp +++ b/src/Tools/tnl-init.cpp @@ -66,7 +66,7 @@ int main( int argc, char* argv[] ) String meshType; try { - getObjectType( meshFile, meshType ); + meshType = getObjectType( meshFile ); } catch(...) { diff --git a/src/Tools/tnl-lattice-init.h b/src/Tools/tnl-lattice-init.h index d993e1ff7..6b8b019e3 100644 --- a/src/Tools/tnl-lattice-init.h +++ b/src/Tools/tnl-lattice-init.h @@ -224,7 +224,7 @@ bool resolveProfileReal( const Config::ParameterContainer& parameters ) String meshFunctionType; try { - getObjectType( profileFile, meshFunctionType ); + meshFunctionType = getObjectType( profileFile ); } catch(...) { @@ -283,7 +283,7 @@ bool resolveMesh( const Config::ParameterContainer& parameters ) String meshType; try { - getObjectType( meshFile, meshType ); + meshType = getObjectType( meshFile ); } catch(...) { @@ -381,7 +381,7 @@ bool resolveProfileMeshType( const Config::ParameterContainer& parameters ) String meshType; try { - getObjectType( meshFile, meshType ); + meshType = getObjectType( meshFile ); } catch(...) { diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h index 6ce8967e4..273bac769 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -475,7 +475,7 @@ struct FilesProcessor String objectType; try { - getObjectType( inputFiles[ i ], objectType ); + objectType = getObjectType( inputFiles[ i ] ); } catch(...) { -- GitLab From 04d0568added80fe6b08f759bd2c808d39957c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Mon, 4 Mar 2019 21:35:26 +0100 Subject: [PATCH 17/72] Added parseObjectType function example. --- src/Examples/CMakeLists.txt | 4 ++++ src/Examples/ParseObjectTypeExample.cpp | 16 ++++++++++++++++ src/TNL/Object.h | 24 ++++++++++++++++++------ 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 src/Examples/ParseObjectTypeExample.cpp diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 1798d98f5..9030d26ef 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -31,6 +31,9 @@ ADD_CUSTOM_COMMAND( COMMAND ObjectExample_getType > ObjectExample_getType.out OU 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 ) @@ -59,6 +62,7 @@ ADD_EXECUTABLE( VectorExample VectorExample.cpp ) ADD_CUSTOM_TARGET( run ALL DEPENDS ObjectExample_getType.out + ParseObjectTypeExample.out StringExample.out StringExampleGetAllocatedSize.out StringExampleReplace.out diff --git a/src/Examples/ParseObjectTypeExample.cpp b/src/Examples/ParseObjectTypeExample.cpp new file mode 100644 index 000000000..1ded85755 --- /dev/null +++ b/src/Examples/ParseObjectTypeExample.cpp @@ -0,0 +1,16 @@ +#include +#include +#include + +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/TNL/Object.h b/src/TNL/Object.h index 6267da9d3..24aef554a 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -30,6 +30,13 @@ namespace TNL { * * 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 { @@ -141,19 +148,24 @@ class Object String getObjectType( File& file ); /** - * \brief Does the same as \ref getObjectType but with \e fileName parameter instead of file. + * \brief Does the same as \ref getObjectType but with a \e fileName parameter instead of file. * - * @param fileName name of file where the object is stored - * @param type string with the object type + * @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 - * @return list of strings where the first one is the object type and the next - * strings are the template parameters + * @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 ); -- GitLab From 26562c2c3a9667451471aadba44da63b165b96aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Mon, 4 Mar 2019 21:53:54 +0100 Subject: [PATCH 18/72] Renaming File_impl.h to File.hpp. Reformatting the File documentation. --- src/TNL/File.h | 254 +++++++++++++++++------------- src/TNL/{File_impl.h => File.hpp} | 8 +- 2 files changed, 145 insertions(+), 117 deletions(-) rename src/TNL/{File_impl.h => File.hpp} (98%) diff --git a/src/TNL/File.h b/src/TNL/File.h index 178ce9585..9412c23cc 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -28,7 +28,8 @@ enum class IOMode write = 2 }; -/* When we need to transfer data between the GPU and the CPU we use +/** + * 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 @@ -36,127 +37,154 @@ enum class IOMode 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 +/** + * \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: + + enum class Mode + { + In = 1, + Out = 2, + Append = 4 + }; + + /** + * \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 = 1 ); + + // 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 = 1 ); + + // 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 ); + + std::fstream file; + String fileName; }; -/// 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. + */ 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 +#include diff --git a/src/TNL/File_impl.h b/src/TNL/File.hpp similarity index 98% rename from src/TNL/File_impl.h rename to src/TNL/File.hpp index 03c3f0d4a..9c4defdbc 100644 --- a/src/TNL/File_impl.h +++ b/src/TNL/File.hpp @@ -56,17 +56,17 @@ inline bool File::close() return true; } -template< typename Type, typename Device > +/*template< typename Type, typename Device > bool File::read( Type* buffer ) { return read< Type, Device >( buffer, 1 ); -} +}*/ -template< typename Type, typename Device > +/*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 ) -- GitLab From 2c8f1be74ea0ba4b025d83205f3451a9a86cf647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Tue, 5 Mar 2019 21:08:10 +0100 Subject: [PATCH 19/72] IOMode replaced with File::Mode. --- src/Examples/FileExample.cpp | 16 +++---- src/Examples/quad-test/main.cpp | 2 +- src/TNL/File.h | 42 +++++++------------ src/TNL/File.hpp | 40 +++++++++++------- .../DistributedGridIO_MeshFunction.h | 6 +-- src/TNL/Object.hpp | 8 ++-- src/UnitTests/Containers/ArrayTest.h | 12 +++--- src/UnitTests/Containers/MultiArrayTest.h | 4 +- src/UnitTests/Containers/StaticArrayTest.cpp | 4 +- src/UnitTests/FileTest.h | 10 ++--- .../CutDistributedMeshFunctionTest.cpp | 4 +- .../DistributedMeshes/DistributedGridIOTest.h | 4 +- .../DistributedGridIO_MPIIOTest.h | 4 +- .../DistributedVectorFieldIO_MPIIOTestBase.h | 6 +-- src/UnitTests/ObjectTest.cpp | 4 +- src/UnitTests/SaveAndLoadMeshfunctionTest.cpp | 4 +- src/UnitTests/StringTest.cpp | 4 +- 17 files changed, 85 insertions(+), 89 deletions(-) diff --git a/src/Examples/FileExample.cpp b/src/Examples/FileExample.cpp index 4d379f4b1..5239fc214 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 <( static_cast< int >( Mode::In ) | static_cast< int >( Mode::Out ) ) ); /** * \brief Attempts to close given file and returns \e true when the file is @@ -102,10 +97,6 @@ class File template< typename Type, typename Device = Devices::Host > bool read( Type* buffer, std::streamsize elements = 1 ); - // 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.) * @@ -122,10 +113,6 @@ class File template< typename Type, typename Device = Devices::Host > bool write( const Type* buffer, std::streamsize elements = 1 ); - // Toto je treba? - //template< typename Type, typename Device = Devices::Host > - //bool write( const Type* buffer ); - protected: template< typename Type, typename Device, @@ -184,7 +171,6 @@ File& operator<<( File& file, const std::string& str ); * \brief Deserialization of strings. */ File& operator>>( File& file, std::string& str ); - } // namespace TNL #include diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index 9c4defdbc..257dd8da8 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -22,17 +22,29 @@ namespace TNL { -inline bool File::open( const String& fileName, const IOMode mode ) +inline File::Mode operator|( File::Mode m1, File::Mode m2 ); + +inline bool operator&( File::Mode m1, File::Mode m2 ); + +inline bool File::open( const String& fileName, Mode mode ) { // enable exceptions file.exceptions( std::fstream::failbit | std::fstream::badbit | std::fstream::eofbit ); close(); - if( mode == IOMode::read ) + 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; + file.open( fileName.getString(), ios_mode ); + + /*if( mode == Mode::In ) file.open( fileName.getString(), std::ios::binary | std::ios::in ); else - file.open( fileName.getString(), std::ios::binary | std::ios::out ); + file.open( fileName.getString(), std::ios::binary | std::ios::out );*/ this->fileName = fileName; if( ! file.good() ) { @@ -56,18 +68,6 @@ inline bool File::close() 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 ) { @@ -274,4 +274,14 @@ inline File& operator>>( File& file, std::string& str ) 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/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h index 00342c7a9..faac6d142 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h @@ -65,7 +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) ) + if( ! meshFile.open( fileName+String("-mesh-")+distrGrid->printProcessCoords()+String(".tnl"),File::Mode::Out ) ) { std::cerr << "Failed to open mesh file for writing." << std::endl; return false; @@ -84,7 +84,7 @@ class DistributedGridIO< CopyEntitiesHelper::Copy(meshFunction,newMeshFunction,localBegin,zeroCoord,localSize); File file; - if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), IOMode::write ) ) + if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::Out ) ) { std::cerr << "Failed to open file for writing." << std::endl; return false; @@ -126,7 +126,7 @@ class DistributedGridIO< zeroCoord.setValue(0); File file; - if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), IOMode::read ) ) + if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::In ) ) { std::cerr << "Failed to open file for reading." << std::endl; return false; diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index b6de3817f..120dd7296 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -68,7 +68,7 @@ inline bool Object::boundLoad( File& file ) inline bool Object::save( const String& fileName ) const { File file; - if( ! file.open( fileName, IOMode::write ) ) + if( ! file.open( fileName, File::Mode::Out ) ) { std::cerr << "I am not able to open the file " << fileName << " for writing." << std::endl; return false; @@ -79,7 +79,7 @@ inline bool Object::save( const String& fileName ) const inline bool Object::load( const String& fileName ) { File file; - if( ! file.open( fileName, IOMode::read ) ) + if( ! file.open( fileName, File::Mode::In ) ) { std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl; return false; @@ -90,7 +90,7 @@ inline bool Object::load( const String& fileName ) inline bool Object::boundLoad( const String& fileName ) { File file; - if( ! file.open( fileName, IOMode::read ) ) + if( ! file.open( fileName, File::Mode::In ) ) { std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl; return false; @@ -112,7 +112,7 @@ inline String getObjectType( File& file ) inline String getObjectType( const String& fileName ) { File binaryFile; - binaryFile.open( fileName, IOMode::read ); + binaryFile.open( fileName, File::Mode::In ); return getObjectType( binaryFile ); } diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index d2bddbd29..601d30921 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.h @@ -504,10 +504,10 @@ 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 ); + file.open( "test-file.tnl", File::Mode::Out ); EXPECT_TRUE( v.save( file ) ); file.close(); - file.open( "test-file.tnl", IOMode::read ); + file.open( "test-file.tnl", File::Mode::In ); EXPECT_TRUE( u.load( file ) ); EXPECT_EQ( u, v ); @@ -523,23 +523,23 @@ 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 ); + file.open( "test-file.tnl", File::Mode::Out ); EXPECT_TRUE( v.save( file ) ); file.close(); w.setSize( 100 ); u.bind( w ); - file.open( "test-file.tnl", IOMode::read ); + file.open( "test-file.tnl", File::Mode::In ); EXPECT_TRUE( u.boundLoad( file ) ); EXPECT_EQ( u, v ); EXPECT_EQ( u.getData(), w.getData() ); u.setSize( 50 ); - file.open( "test-file.tnl", IOMode::read ); + file.open( "test-file.tnl", File::Mode::In ); EXPECT_FALSE( u.boundLoad( file ) ); u.reset(); - file.open( "test-file.tnl", IOMode::read ); + file.open( "test-file.tnl", File::Mode::In ); EXPECT_TRUE( u.boundLoad( file ) ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); diff --git a/src/UnitTests/Containers/MultiArrayTest.h b/src/UnitTests/Containers/MultiArrayTest.h index 66fc9dc08..3e8d330a1 100644 --- a/src/UnitTests/Containers/MultiArrayTest.h +++ b/src/UnitTests/Containers/MultiArrayTest.h @@ -207,11 +207,11 @@ TEST( MultiArrayTest, testSaveAndLoad ) for( int i = 0; i < size; i ++ ) setDiagonalElement( v, i, 3.14147 ); File file; - file. open( "test-file.tnl", IOMode::write ); + file. open( "test-file.tnl", File::Mode::Out ); ASSERT_TRUE( v. save( file ) ); file. close(); MultiArray< Dimension, ValueType, Device, IndexType > u; - file. open( "test-file.tnl", IOMode::read ); + file. open( "test-file.tnl", File::Mode::In ); ASSERT_TRUE( u. load( file ) ); file. close(); ASSERT_TRUE( u == v ); diff --git a/src/UnitTests/Containers/StaticArrayTest.cpp b/src/UnitTests/Containers/StaticArrayTest.cpp index e3d0b1f63..a418b9d06 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 4da741892..08cd5e151 100644 --- a/src/UnitTests/FileTest.h +++ b/src/UnitTests/FileTest.h @@ -24,13 +24,13 @@ TEST( FileTest, CloseEmpty ) 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 ) ); + ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::Out ) ); int intData( 5 ); double doubleData[ 3 ] = { 1.0, 2.0, 3.0 }; @@ -40,7 +40,7 @@ TEST( FileTest, WriteAndRead ) ASSERT_TRUE( file.write( &constDoubleData ) ); ASSERT_TRUE( file.close() ); - ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); + ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::In ) ); int newIntData; double newDoubleData[ 3 ]; double newConstDoubleData; @@ -83,7 +83,7 @@ TEST( FileTest, WriteAndReadCUDA ) cudaMemcpyHostToDevice ); File file; - ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) ); + ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::Out ) ); bool status = file.write< int, Devices::Cuda >( cudaIntData ); ASSERT_TRUE( status ); @@ -93,7 +93,7 @@ TEST( FileTest, WriteAndReadCUDA ) ASSERT_TRUE( status ); ASSERT_TRUE( file.close() ); - ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) ); + ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::In ) ); int newIntData; float newFloatData[ 3 ]; double newDoubleData; diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp index 000a832b6..108784e5d 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,7 +612,7 @@ TEST(CutDistributedMeshFunction, 3D_2_Save) loadMeshFunctionptr.bind(globalCutGrid,loaddof); File file; - bool ok=file.open( FileName, IOMode::read ); + bool ok=file.open( FileName, File::Mode::In ); TNL_ASSERT_TRUE(ok,"Cannot open file"); loadMeshFunctionptr.boundLoad(file); file.close(); diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h index d8b19c229..fd25c83da 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 ) ); + ASSERT_TRUE( 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 ) ); + ASSERT_TRUE( 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 ef0160741..b19c8641f 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 e66884783..c70d165e5 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 ::save(FileName, vectorField ); /*File file; - file.open( FileName, IOMode::write ); + file.open( FileName, File::Mode::Out ); vectorField.save(file); file.close(); */ @@ -102,7 +102,7 @@ class TestDistributedVectorFieldMPIIO{ loadDof.setValue(-1); File file; - file.open( FileName, IOMode::read ); + file.open( FileName, File::Mode::In ); bool loaded=loadvct.boundLoad(file); file.close(); if(!loaded) @@ -153,7 +153,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/ObjectTest.cpp b/src/UnitTests/ObjectTest.cpp index 488f7a497..436a13e0e 100644 --- a/src/UnitTests/ObjectTest.cpp +++ b/src/UnitTests/ObjectTest.cpp @@ -24,10 +24,10 @@ TEST( ObjectTest, SaveAndLoadTest ) { Object testObject; File file; - file.open( "test-file.tnl", IOMode::write ); + file.open( "test-file.tnl", File::Mode::Out ); ASSERT_TRUE( testObject.save( file ) ); file.close(); - file.open( "test-file.tnl", IOMode::read ); + file.open( "test-file.tnl", File::Mode::In ); ASSERT_TRUE( testObject.load( file ) ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); diff --git a/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp b/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp index f4b0cc7e6..0bc1bb516 100644 --- a/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp +++ b/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp @@ -62,7 +62,7 @@ class TestSaveAndLoadMeshfunction linearFunctionEvaluator.evaluateAllEntities(localMeshFunctionptr , linearFunctionPtr); File file; - ASSERT_TRUE( file.open( String( FILENAME), IOMode::write )); + ASSERT_TRUE( file.open( String( FILENAME), File::Mode::Out )); ASSERT_TRUE( localMeshFunctionptr->save(file)); ASSERT_TRUE( file.close() ); @@ -80,7 +80,7 @@ class TestSaveAndLoadMeshfunction loadDof[i]=-1; } - ASSERT_TRUE( file.open( String( FILENAME ), IOMode::read )); + ASSERT_TRUE( file.open( String( FILENAME ), File::Mode::In )); ASSERT_TRUE( loadMeshFunctionptr->boundLoad(file)); ASSERT_TRUE( file.close()); diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp index 9582c8221..f44eac1c6 100644 --- a/src/UnitTests/StringTest.cpp +++ b/src/UnitTests/StringTest.cpp @@ -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 ); -- GitLab From 0b81f7e7e78aa60c93464b3033291f6fd24f782e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Tue, 5 Mar 2019 21:33:03 +0100 Subject: [PATCH 20/72] Added FileOpenError exception. --- src/TNL/Exceptions/FileOpenError.h | 32 ++++++++++++++++++++++++++++++ src/TNL/Exceptions/NotTNLFile.h | 2 +- src/TNL/File.hpp | 19 +++++++++--------- 3 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 src/TNL/Exceptions/FileOpenError.h diff --git a/src/TNL/Exceptions/FileOpenError.h b/src/TNL/Exceptions/FileOpenError.h new file mode 100644 index 000000000..3975c267e --- /dev/null +++ b/src/TNL/Exceptions/FileOpenError.h @@ -0,0 +1,32 @@ +/*************************************************************************** + FileOpenError.h - description + ------------------- + begin : Mar 5, 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 +#include +#include + +namespace TNL { +namespace Exceptions { + +class FileOpenError + : public std::runtime_error +{ +public: + FileOpenError( const String& fileName ) + : std::runtime_error( "Unable to open file " + fileName + "." ) + {} +}; + +} // namespace Exceptions +} // namespace TNL diff --git a/src/TNL/Exceptions/NotTNLFile.h b/src/TNL/Exceptions/NotTNLFile.h index e65fd490b..ce2d756a5 100644 --- a/src/TNL/Exceptions/NotTNLFile.h +++ b/src/TNL/Exceptions/NotTNLFile.h @@ -23,7 +23,7 @@ class NotTNLFile { public: NotTNLFile() - : std::runtime_error( "Wring magic number found in a binary file. It is not TNL compatible file." ) + : std::runtime_error( "Wrong magic number found in a binary file. It is not TNL compatible file." ) {} }; diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index 257dd8da8..c89afa567 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace TNL { @@ -39,18 +40,16 @@ inline bool File::open( const String& fileName, Mode mode ) 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; - file.open( fileName.getString(), ios_mode ); - - /*if( mode == Mode::In ) - file.open( fileName.getString(), std::ios::binary | std::ios::in ); - else - file.open( fileName.getString(), std::ios::binary | std::ios::out );*/ + try + { + file.open( fileName.getString(), ios_mode ); + } + catch(...) + { + throw Exceptions::FileOpenError( fileName ); + } this->fileName = fileName; - if( ! file.good() ) { - std::cerr << "I am not able to open the file " << fileName << ". "; - return false; - } return true; } -- GitLab From 62636134f76cc5dbd340e7e071c70ce0efcccd52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Tue, 5 Mar 2019 21:49:41 +0100 Subject: [PATCH 21/72] Added FileCloseError exception. --- src/TNL/Exceptions/FileCloseError.h | 32 +++++++++++++++++++++++++++++ src/TNL/File.hpp | 17 +++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 src/TNL/Exceptions/FileCloseError.h diff --git a/src/TNL/Exceptions/FileCloseError.h b/src/TNL/Exceptions/FileCloseError.h new file mode 100644 index 000000000..3b4a7f973 --- /dev/null +++ b/src/TNL/Exceptions/FileCloseError.h @@ -0,0 +1,32 @@ +/*************************************************************************** + FileCloseError.h - description + ------------------- + begin : Mar 5, 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 +#include +#include + +namespace TNL { +namespace Exceptions { + +class FileCloseError + : public std::runtime_error +{ +public: + FileCloseError( const String& fileName ) + : std::runtime_error( "An error occurred when closing file " + fileName + "." ) + {} +}; + +} // namespace Exceptions +} // namespace TNL diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index c89afa567..623465bb8 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace TNL { @@ -55,14 +56,18 @@ inline bool File::open( const String& fileName, Mode mode ) 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; + if( file.is_open() ) + { + try + { + file.close(); + } + catch(...) + { + throw Exceptions::FileCloseError( fileName ); } } - // reset all attributes + // reset file name fileName = ""; return true; } -- GitLab From 78adf69558c0a2c84d416af4674bb19d0d6c58c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Tue, 5 Mar 2019 22:29:21 +0100 Subject: [PATCH 22/72] [WIP] Changing File load and save from bool to void. --- src/TNL/File.h | 4 ++-- src/TNL/File.hpp | 6 ++---- .../DistributedGridIO_MeshFunction.h | 18 +++--------------- src/TNL/Object.hpp | 18 +++--------------- src/UnitTests/FileTest.h | 18 ++++++------------ src/UnitTests/SaveAndLoadMeshfunctionTest.cpp | 12 ++++++------ 6 files changed, 22 insertions(+), 54 deletions(-) diff --git a/src/TNL/File.h b/src/TNL/File.h index ce4a2ba4c..4a8863b9b 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -64,14 +64,14 @@ class 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, + void open( const String& fileName, Mode mode = static_cast< Mode >( static_cast< int >( Mode::In ) | static_cast< int >( Mode::Out ) ) ); /** * \brief Attempts to close given file and returns \e true when the file is * successfully closed. Otherwise returns \e false. */ - bool close(); + void close(); /** * \brief Returns name of given file. diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index 623465bb8..5cc7f01aa 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -28,7 +28,7 @@ inline File::Mode operator|( File::Mode m1, File::Mode m2 ); inline bool operator&( File::Mode m1, File::Mode m2 ); -inline bool File::open( const String& fileName, Mode mode ) +inline void File::open( const String& fileName, Mode mode ) { // enable exceptions file.exceptions( std::fstream::failbit | std::fstream::badbit | std::fstream::eofbit ); @@ -51,10 +51,9 @@ inline bool File::open( const String& fileName, Mode mode ) } this->fileName = fileName; - return true; } -inline bool File::close() +inline void File::close() { if( file.is_open() ) { @@ -69,7 +68,6 @@ inline bool File::close() } // reset file name fileName = ""; - return true; } template< typename Type, typename Device > diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h index faac6d142..c6c7842ad 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h @@ -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"),File::Mode::Out ) ) - { - 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,11 +80,7 @@ class DistributedGridIO< CopyEntitiesHelper::Copy(meshFunction,newMeshFunction,localBegin,zeroCoord,localSize); File file; - if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::Out ) ) - { - std::cerr << "Failed to open file for writing." << std::endl; - return false; - } + file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::Out ); bool ret=newMeshFunction.save(file); file.close(); @@ -126,11 +118,7 @@ class DistributedGridIO< zeroCoord.setValue(0); File file; - if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::In ) ) - { - std::cerr << "Failed to open file for reading." << std::endl; - return false; - } + file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::In ); bool result=newMeshFunction.boundLoad(file); file.close(); CopyEntitiesHelper::Copy(newMeshFunction,meshFunction,zeroCoord,localBegin,localSize); diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index 120dd7296..1d3dd31a5 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -68,33 +68,21 @@ inline bool Object::boundLoad( File& file ) inline bool Object::save( const String& fileName ) const { File file; - if( ! file.open( fileName, File::Mode::Out ) ) - { - std::cerr << "I am not able to open the file " << fileName << " for writing." << std::endl; - return false; - } + file.open( fileName, File::Mode::Out ); return this->save( file ); } inline bool Object::load( const String& fileName ) { File file; - if( ! file.open( fileName, File::Mode::In ) ) - { - std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl; - return false; - } + file.open( fileName, File::Mode::In ); return this->load( file ); } inline bool Object::boundLoad( const String& fileName ) { File file; - if( ! file.open( fileName, File::Mode::In ) ) - { - std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl; - return false; - } + file.open( fileName, File::Mode::In ); return this->boundLoad( file ); } diff --git a/src/UnitTests/FileTest.h b/src/UnitTests/FileTest.h index 08cd5e151..4f15d6ac7 100644 --- a/src/UnitTests/FileTest.h +++ b/src/UnitTests/FileTest.h @@ -15,12 +15,6 @@ using namespace TNL; -TEST( FileTest, CloseEmpty ) -{ - File file; - ASSERT_TRUE( file.close() ); -} - TEST( FileTest, OpenInvalid ) { File file; @@ -30,7 +24,7 @@ TEST( FileTest, OpenInvalid ) TEST( FileTest, WriteAndRead ) { File file; - ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::Out ) ); + file.open( String( "test-file.tnl" ), File::Mode::Out ); int intData( 5 ); double doubleData[ 3 ] = { 1.0, 2.0, 3.0 }; @@ -38,9 +32,9 @@ TEST( FileTest, WriteAndRead ) ASSERT_TRUE( file.write( &intData ) ); ASSERT_TRUE( file.write( doubleData, 3 ) ); ASSERT_TRUE( file.write( &constDoubleData ) ); - ASSERT_TRUE( file.close() ); + file.close(); - ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::In ) ); + file.open( String( "test-file.tnl" ), File::Mode::In ); int newIntData; double newDoubleData[ 3 ]; double newConstDoubleData; @@ -83,7 +77,7 @@ TEST( FileTest, WriteAndReadCUDA ) cudaMemcpyHostToDevice ); File file; - ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::Out ) ); + file.open( String( "test-file.tnl" ), File::Mode::Out ); bool status = file.write< int, Devices::Cuda >( cudaIntData ); ASSERT_TRUE( status ); @@ -91,9 +85,9 @@ TEST( FileTest, WriteAndReadCUDA ) ASSERT_TRUE( status ); status = file.write< const double, Devices::Cuda >( cudaConstDoubleData ); ASSERT_TRUE( status ); - ASSERT_TRUE( file.close() ); + file.close(); - ASSERT_TRUE( file.open( String( "test-file.tnl" ), File::Mode::In ) ); + file.open( String( "test-file.tnl" ), File::Mode::In ); int newIntData; float newFloatData[ 3 ]; double newDoubleData; diff --git a/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp b/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp index 0bc1bb516..e7079e894 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), File::Mode::Out )); - 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 loadGridptr; @@ -80,9 +80,9 @@ class TestSaveAndLoadMeshfunction loadDof[i]=-1; } - ASSERT_TRUE( file.open( String( FILENAME ), File::Mode::In )); - 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 Date: Wed, 6 Mar 2019 07:35:34 +0100 Subject: [PATCH 23/72] Changed File load and save from bool to void. --- .../DistributedMeshes/CutDistributedMeshFunctionTest.cpp | 3 +-- .../Meshes/DistributedMeshes/DistributedGridIOTest.h | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp index 108784e5d..caaf3f613 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp +++ b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp @@ -612,8 +612,7 @@ TEST(CutDistributedMeshFunction, 3D_2_Save) loadMeshFunctionptr.bind(globalCutGrid,loaddof); File file; - bool ok=file.open( FileName, File::Mode::In ); - 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 fd25c83da..09be099c5 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, File::Mode::In ) ); + 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, File::Mode::Out ) ); + file.open( localFileName, File::Mode::Out ); localMeshFunctionptr->save(file); file.close(); -- GitLab From 4809ff772a8d1cbc1eb6b0f68b1b532e6b5c804c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 6 Mar 2019 20:42:48 +0100 Subject: [PATCH 24/72] File exceptions replaced with ios exception. --- src/TNL/Exceptions/FileCloseError.h | 32 ----------------------------- src/TNL/Exceptions/FileOpenError.h | 32 ----------------------------- src/TNL/File.hpp | 22 ++++++++++++++------ 3 files changed, 16 insertions(+), 70 deletions(-) delete mode 100644 src/TNL/Exceptions/FileCloseError.h delete mode 100644 src/TNL/Exceptions/FileOpenError.h diff --git a/src/TNL/Exceptions/FileCloseError.h b/src/TNL/Exceptions/FileCloseError.h deleted file mode 100644 index 3b4a7f973..000000000 --- a/src/TNL/Exceptions/FileCloseError.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - FileCloseError.h - description - ------------------- - begin : Mar 5, 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 -#include -#include - -namespace TNL { -namespace Exceptions { - -class FileCloseError - : public std::runtime_error -{ -public: - FileCloseError( const String& fileName ) - : std::runtime_error( "An error occurred when closing file " + fileName + "." ) - {} -}; - -} // namespace Exceptions -} // namespace TNL diff --git a/src/TNL/Exceptions/FileOpenError.h b/src/TNL/Exceptions/FileOpenError.h deleted file mode 100644 index 3975c267e..000000000 --- a/src/TNL/Exceptions/FileOpenError.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - FileOpenError.h - description - ------------------- - begin : Mar 5, 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 -#include -#include - -namespace TNL { -namespace Exceptions { - -class FileOpenError - : public std::runtime_error -{ -public: - FileOpenError( const String& fileName ) - : std::runtime_error( "Unable to open file " + fileName + "." ) - {} -}; - -} // namespace Exceptions -} // namespace TNL diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index 5cc7f01aa..1db792bd5 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include @@ -19,8 +21,6 @@ #include #include #include -#include -#include namespace TNL { @@ -45,9 +45,16 @@ inline void File::open( const String& fileName, Mode mode ) { file.open( fileName.getString(), ios_mode ); } - catch(...) + catch( std::ios_base::failure ) { - throw Exceptions::FileOpenError( fileName ); + std::stringstream msg; + msg << "Unable to open file " << fileName << " "; + if( mode & Mode::In ) + msg << " for reading."; + if( mode & Mode::Out ) + msg << " for writting."; + + throw std::ios_base::failure( msg.str() ); } this->fileName = fileName; @@ -61,9 +68,12 @@ inline void File::close() { file.close(); } - catch(...) + catch( std::ios_base::failure ) { - throw Exceptions::FileCloseError( fileName ); + std::stringstream msg; + msg << "Unable to close file " << fileName << "."; + + throw std::ios_base::failure( msg.str() ); } } // reset file name -- GitLab From 4b22c5e5722cd2071ec5f0d9cba03af4fdac00d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 6 Mar 2019 21:40:23 +0100 Subject: [PATCH 25/72] [WIP] Adding data conversion to File:read and File::write. --- src/TNL/File.h | 53 ++++++++++++++++++------------- src/TNL/File.hpp | 81 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 96 insertions(+), 38 deletions(-) diff --git a/src/TNL/File.h b/src/TNL/File.h index 4a8863b9b..9295c2368 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -20,13 +20,6 @@ namespace TNL { -/** - * 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 - */ -static constexpr std::streamsize FileGPUvsCPUTransferBufferSize = 5 * 2<<20; - /** * \brief This class serves for binary IO. It allows to do IO even for data allocated on GPU * @@ -57,24 +50,27 @@ class File File() = default; /** - * \brief Open given file and returns \e true after the file is - * successfully opened. Otherwise returns \e false. + * \brief Open given file. * - * 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. + * 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 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 Attempts to close given file and returns \e true when the file is - * successfully closed. Otherwise returns \e false. + * \brief Closes the file. + * + * Throws \ref std::ios_base::failure on failure. */ void close(); /** - * \brief Returns name of given file. + * \brief Returns name of the file. */ const String& getFileName() const { @@ -82,19 +78,20 @@ class File } /** - * \brief Method that can write particular data type from given file into GPU. (Function that gets particular elements from given file.) + * \brief Method for reading data with given \e Type from the file. * - * Returns \e true when the elements are successfully read from given file. Otherwise returns \e false. + * The data will be stored in \e buffer allocated on device given by the + * \e Device parameter. * * 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. + * \tparam Device Device where the data are stored after reading. For example \ref Devices::Host or \ref Devices::Cuda. + * \tparam SourceType 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 > + template< typename Type, typename Device = Devices::Host, typename SourceType = Type > bool read( Type* buffer, std::streamsize elements = 1 ); /** @@ -110,23 +107,26 @@ class File * \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 > + template< typename Type, typename Device = Devices::Host, typename TargetType = Type > bool write( const Type* buffer, std::streamsize elements = 1 ); protected: template< typename Type, typename Device, + typename SourceType, 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 SourceType, 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 SourceType, typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type, typename = void, typename = void > @@ -134,17 +134,20 @@ class File template< typename Type, typename Device, + typename TargetType, 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 TargetType, 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 TargetType, typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type, typename = void, typename = void > @@ -152,6 +155,14 @@ class File 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; }; /** diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index 1db792bd5..bbff0ab96 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -80,7 +80,7 @@ inline void File::close() fileName = ""; } -template< typename Type, typename Device > +template< typename Type, typename Device, typename SourceType > bool File::read( Type* buffer, std::streamsize elements ) { TNL_ASSERT_GE( elements, 0, "Number of elements to read must be non-negative." ); @@ -94,35 +94,78 @@ bool File::read( Type* buffer, std::streamsize elements ) // Host template< typename Type, typename Device, + typename SourceType, typename > bool File::read_impl( Type* buffer, std::streamsize elements ) { - file.read( reinterpret_cast(buffer), sizeof(Type) * elements ); - return true; + if( std::is_same< Type, SourceType >::value ) + { + file.read( reinterpret_cast(buffer), sizeof(Type) * elements ); + return true; + } + 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(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 Device, + typename SourceType, 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 ); + 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; - while( readElements < elements ) + if( std::is_same< Type, SourceType >::value ) { - const std::streamsize transfer = std::min( elements - readElements, host_buffer_size ); - file.read( reinterpret_cast(host_buffer.get()), sizeof(Type) * transfer ); - cudaMemcpy( (void*) &buffer[ readElements ], - (void*) host_buffer.get(), - transfer * sizeof( Type ), - cudaMemcpyHostToDevice ); - TNL_CHECK_CUDA_DEVICE; - readElements += transfer; + while( readElements < elements ) + { + const std::streamsize transfer = std::min( elements - readElements, host_buffer_size ); + file.read( reinterpret_cast(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< SorceType >::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(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; + } } return true; #else @@ -133,11 +176,12 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) // MIC template< typename Type, typename Device, + typename SourceType, 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 ); + 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 ] }; @@ -167,7 +211,7 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) #endif } -template< class Type, typename Device > +template< class Type, typename Device, typename TargeType > bool File::write( const Type* buffer, std::streamsize elements ) { TNL_ASSERT_GE( elements, 0, "Number of elements to write must be non-negative." ); @@ -181,6 +225,7 @@ bool File::write( const Type* buffer, std::streamsize elements ) // Host template< typename Type, typename Device, + typename TargetType, typename > bool File::write_impl( const Type* buffer, std::streamsize elements ) { @@ -191,11 +236,12 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) // Cuda template< typename Type, typename Device, + typename TargetType, 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 ); + 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 ] }; @@ -220,11 +266,12 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) // MIC template< typename Type, typename Device, + typename TargetType, 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 ); + 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 ] }; -- GitLab From ad01b6e3144843ccb16ac99bd12fd1ab1fc7a7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Thu, 7 Mar 2019 21:41:06 +0100 Subject: [PATCH 26/72] Added type conversion to File read and write. --- src/TNL/File.hpp | 145 +++++++++++++++++++++++++++------------ src/UnitTests/FileTest.h | 85 +++++++++++++++++++++++ 2 files changed, 186 insertions(+), 44 deletions(-) diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index bbff0ab96..37ca5ef2d 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -88,7 +88,7 @@ bool File::read( Type* buffer, std::streamsize elements ) if( ! elements ) return true; - return read_impl< Type, Device >( buffer, elements ); + return read_impl< Type, Device, SourceType >( buffer, elements ); } // Host @@ -150,7 +150,7 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) else { const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(SourceType), elements ); - using BaseType = typename std::remove_cv< SorceType >::type; + using BaseType = typename std::remove_cv< SourceType >::type; std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] }; while( readElements < elements ) @@ -186,32 +186,40 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; std::streamsize readElements = 0; - while( readElements < elements ) + if( std::is_same< Type, SourceType >::value ) { - const std::streamsize transfer = std::min( elements - readElements, host_buffer_size ); - file.read( reinterpret_cast(host_buffer.get()), sizeof(Type) * transfer ); - - Devices::MICHider device_buff; - device_buff.pointer=buffer; - #pragma offload target(mic) in(device_buff,readElements) in(host_buffer:length(transfer)) + while( readElements < elements ) { - /* - for(int i=0;i(host_buffer.get()), sizeof(Type) * transfer ); + + Devices::MICHider device_buff; + device_buff.pointer=buffer; + #pragma offload target(mic) in(device_buff,readElements) in(host_buffer:length(transfer)) + { + /* + for(int i=0;i +template< class Type, typename Device, typename TargetType > bool File::write( const Type* buffer, std::streamsize elements ) { TNL_ASSERT_GE( elements, 0, "Number of elements to write must be non-negative." ); @@ -219,7 +227,7 @@ bool File::write( const Type* buffer, std::streamsize elements ) if( ! elements ) return true; - return write_impl< Type, Device >( buffer, elements ); + return write_impl< Type, Device, TargetType >( buffer, elements ); } // Host @@ -229,7 +237,24 @@ template< typename Type, typename > bool File::write_impl( const Type* buffer, std::streamsize elements ) { - file.write( reinterpret_cast(buffer), sizeof(Type) * elements ); + if( std::is_same< Type, TargetType >::value ) + file.write( reinterpret_cast(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(cast_buffer.get()), sizeof(TargetType) * transfer ); + writtenElements += transfer; + } + + } return true; } @@ -246,16 +271,40 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; std::streamsize writtenElements = 0; - while( writtenElements < elements ) + 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(host_buffer.get()), sizeof(Type) * transfer ); + writtenElements += transfer; + } + } + else { - 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(host_buffer.get()), sizeof(Type) * transfer ); - writtenElements += transfer; + 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(cast_buffer.get()), sizeof(TargetType) * transfer ); + writtenElements += transfer; + } } return true; #else @@ -276,24 +325,32 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] }; std::streamsize writtenElements = 0; - while( this->writtenElements < elements ) + if( std::is_same< Type, TargetType >::value ) { - const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size ); - - Devices::MICHider device_buff; - device_buff.pointer=buffer; - #pragma offload target(mic) in(device_buff,writtenElements) out(host_buffer:length(transfer)) + while( this->writtenElements < elements ) { - //THIS SHOULD WORK... BUT NOT WHY? - /*for(int i=0;i 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(host_buffer.get()), sizeof(Type) * transfer ); + writtenElements += transfer; } - - file.write( reinterpret_cast(host_buffer.get()), sizeof(Type) * transfer ); - writtenElements += transfer; + } + else + { + std::cerr << "Type conversion during saving is not implemented for MIC." << std::endl; + abort(); } return true; #else diff --git a/src/UnitTests/FileTest.h b/src/UnitTests/FileTest.h index 4f15d6ac7..93616bb17 100644 --- a/src/UnitTests/FileTest.h +++ b/src/UnitTests/FileTest.h @@ -50,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.write< double, Devices::Host, float >( doubleData, 3 ); + file.close(); + + file.open( "test-file.tnl", File::Mode::In ); + file.read< float, Devices::Host, float >( floatData, 3 ); + file.close(); + + file.open( "test-file.tnl", File::Mode::In ); + file.read< int, Devices::Host, float >( 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 ) { @@ -123,6 +154,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.write< double, Devices::Cuda, float >( cudaConstDoubleData, 3 ); + file.close(); + + file.open( String( "cuda-test-file.tnl" ), File::Mode::In ); + file.read< float, Devices::Cuda, float >( cudaFloatData, 3 ); + file.close(); + + file.open( String( "cuda-test-file.tnl" ), File::Mode::In ); + file.read< int, Devices::Cuda, float >( 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 -- GitLab From 2172dfdebf0b332cbeedd9b971a413bb9ed06ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Thu, 7 Mar 2019 22:27:04 +0100 Subject: [PATCH 27/72] Renamed File read and write to load and save. --- src/TNL/Containers/Algorithms/ArrayIO.h | 4 +-- src/TNL/Containers/Array_impl.h | 6 ++-- src/TNL/Containers/List_impl.h | 12 +++---- .../Multimaps/EllpackIndexMultimap_impl.h | 8 ++--- .../StaticEllpackIndexMultimap_impl.h | 4 +-- src/TNL/Containers/StaticArray1D_impl.h | 4 +-- src/TNL/Containers/StaticArray2D_impl.h | 4 +-- src/TNL/Containers/StaticArray3D_impl.h | 4 +-- src/TNL/Containers/StaticArray_impl.h | 4 +-- src/TNL/File.h | 20 +++++------ src/TNL/File.hpp | 36 ++++++++++--------- src/TNL/Matrices/EllpackSymmetricGraph_impl.h | 4 +-- src/TNL/Matrices/EllpackSymmetric_impl.h | 4 +-- src/TNL/Matrices/Ellpack_impl.h | 4 +-- src/TNL/Matrices/Matrix_impl.h | 8 ++--- src/TNL/Object.hpp | 4 +-- src/UnitTests/FileTest.h | 36 +++++++++---------- 17 files changed, 85 insertions(+), 81 deletions(-) diff --git a/src/TNL/Containers/Algorithms/ArrayIO.h b/src/TNL/Containers/Algorithms/ArrayIO.h index 9b14f7cca..79da384b9 100644 --- a/src/TNL/Containers/Algorithms/ArrayIO.h +++ b/src/TNL/Containers/Algorithms/ArrayIO.h @@ -71,14 +71,14 @@ class ArrayIO< Value, Device, Index, false > const Value* data, const Index elements ) { - return file.write< Value, Device >( data, elements ); + return file.save< Value, Value, Device >( data, elements ); } static bool load( File& file, Value* data, const Index elements ) { - return file.read< Value, Device >( data, elements ); + return file.load< Value, Value, Device >( data, elements ); } }; diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h index b44bdf0a1..60dba8f9b 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array_impl.h @@ -474,7 +474,7 @@ bool Array< Value, Device, Index >::save( File& file ) const { if( ! Object::save( file ) ) return false; - if( ! file.write( &this->size ) ) + if( ! file.save( &this->size ) ) return false; if( this->size != 0 && ! Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size ) ) { @@ -495,7 +495,7 @@ load( File& file ) if( ! Object::load( file ) ) return false; Index _size; - if( ! file.read( &_size ) ) + if( ! file.load( &_size ) ) { std::cerr << "Unable to read the array size." << std::endl; return false; @@ -528,7 +528,7 @@ boundLoad( File& file ) if( ! Object::load( file ) ) return false; Index _size; - if( ! file.read( &_size ) ) + if( ! file.load( &_size ) ) return false; if( _size < 0 ) { diff --git a/src/TNL/Containers/List_impl.h b/src/TNL/Containers/List_impl.h index 36fd5dbdc..a8bcb8115 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/Multimaps/EllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h index 52182ad06..e9654e739 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h @@ -244,9 +244,9 @@ save( File& file ) const { if( ! Object::save( file ) ) return false; - if( ! file.write( &this->keysRange ) ) + if( ! file.save( &this->keysRange ) ) return false; - if( ! file.write( &this->maxValuesCount ) ) + if( ! file.save( &this->maxValuesCount ) ) return false; if( ! this->values.save( file ) ) return false; @@ -265,9 +265,9 @@ load( File& file ) { if( ! Object::load( file ) ) return false; - if( ! file.read( &this->keysRange ) ) + if( ! file.load( &this->keysRange ) ) return false; - if( ! file.read( &this->maxValuesCount ) ) + if( ! file.load( &this->maxValuesCount ) ) return false; if( ! this->values.load( file ) ) return false; diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h index 9a9309635..269b620c2 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h @@ -203,7 +203,7 @@ save( File& file ) const { if( ! Object::save( file ) ) return false; - if( ! file.write( &this->keysRange ) ) + if( ! file.save( &this->keysRange ) ) return false; if( ! this->values.save( file ) ) return false; @@ -221,7 +221,7 @@ load( File& file ) { if( ! Object::load( file ) ) return false; - if( ! file.read( &this->keysRange ) ) + if( ! file.load( &this->keysRange ) ) return false; if( ! this->values.load( file ) ) return false; diff --git a/src/TNL/Containers/StaticArray1D_impl.h b/src/TNL/Containers/StaticArray1D_impl.h index e9b1fbc1d..1da2b0c79 100644 --- a/src/TNL/Containers/StaticArray1D_impl.h +++ b/src/TNL/Containers/StaticArray1D_impl.h @@ -162,7 +162,7 @@ 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 ) ) + if( ! file.save< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to write " << getType() << "." << std::endl; return false; @@ -173,7 +173,7 @@ bool StaticArray< 1, Value >::save( File& file ) const template< typename Value > bool StaticArray< 1, Value >::load( File& file) { - if( ! file.read( data, size ) ) + if( ! file.load< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to read " << getType() << "." << std::endl; return false; diff --git a/src/TNL/Containers/StaticArray2D_impl.h b/src/TNL/Containers/StaticArray2D_impl.h index 664a938d7..1ce77b2eb 100644 --- a/src/TNL/Containers/StaticArray2D_impl.h +++ b/src/TNL/Containers/StaticArray2D_impl.h @@ -192,7 +192,7 @@ 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 ) ) + if( ! file.save< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to write " << getType() << "." << std::endl; return false; @@ -203,7 +203,7 @@ bool StaticArray< 2, Value >::save( File& file ) const template< typename Value > bool StaticArray< 2, Value >::load( File& file) { - if( ! file.read< Value, Devices::Host >( data, size ) ) + if( ! file.load< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to read " << getType() << "." << std::endl; return false; diff --git a/src/TNL/Containers/StaticArray3D_impl.h b/src/TNL/Containers/StaticArray3D_impl.h index 2489196c0..448f8df94 100644 --- a/src/TNL/Containers/StaticArray3D_impl.h +++ b/src/TNL/Containers/StaticArray3D_impl.h @@ -213,7 +213,7 @@ 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 ) ) + if( ! file.save< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to write " << getType() << "." << std::endl; return false; @@ -224,7 +224,7 @@ bool StaticArray< 3, Value >::save( File& file ) const template< typename Value > bool StaticArray< 3, Value >::load( File& file) { - if( ! file.read< Value, Devices::Host >( data, size ) ) + if( ! file.load< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to read " << getType() << "." << std::endl; return false; diff --git a/src/TNL/Containers/StaticArray_impl.h b/src/TNL/Containers/StaticArray_impl.h index a154ebc48..2a9f46347 100644 --- a/src/TNL/Containers/StaticArray_impl.h +++ b/src/TNL/Containers/StaticArray_impl.h @@ -160,7 +160,7 @@ 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 ) ) + if( ! file.save< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to write " << getType() << "." << std::endl; return false; @@ -171,7 +171,7 @@ bool StaticArray< Size, Value >::save( File& file ) const template< int Size, typename Value > bool StaticArray< Size, Value >::load( File& file) { - if( ! file.read< Value, Devices::Host >( data, size ) ) + if( ! file.load< Value, Value, Devices::Host >( data, size ) ) { std::cerr << "Unable to read " << getType() << "." << std::endl; return false; diff --git a/src/TNL/File.h b/src/TNL/File.h index 9295c2368..0e6066452 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -91,8 +91,8 @@ class File * \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, typename SourceType = Type > - bool read( Type* buffer, std::streamsize elements = 1 ); + template< typename Type, typename SourceType = Type, typename Device = Devices::Host > + bool load( Type* buffer, std::streamsize elements = 1 ); /** * \brief Method that can write particular data type from CPU into given file. (Function that writes particular elements into given file.) @@ -107,47 +107,47 @@ class File * \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, typename TargetType = Type > - bool write( const Type* buffer, std::streamsize elements = 1 ); + template< typename Type, typename TargetType = Type, typename Device = Devices::Host > + bool save( const Type* buffer, std::streamsize elements = 1 ); protected: template< typename Type, - typename Device, typename SourceType, + 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 SourceType, + 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 SourceType, + 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 TargetType, + 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 TargetType, + 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 TargetType, + typename Device, typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type, typename = void, typename = void > diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index 37ca5ef2d..cf9c68441 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -80,21 +80,23 @@ inline void File::close() fileName = ""; } -template< typename Type, typename Device, typename SourceType > -bool File::read( Type* buffer, std::streamsize elements ) +template< typename Type, + typename SourceType, + typename Device > +bool File::load( 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, SourceType >( buffer, elements ); + return read_impl< Type, SourceType, Device >( buffer, elements ); } // Host template< typename Type, - typename Device, typename SourceType, + typename Device, typename > bool File::read_impl( Type* buffer, std::streamsize elements ) { @@ -122,8 +124,8 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) // Cuda template< typename Type, - typename Device, typename SourceType, + typename Device, typename, typename > bool File::read_impl( Type* buffer, std::streamsize elements ) { @@ -175,8 +177,8 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) // MIC template< typename Type, - typename Device, typename SourceType, + typename Device, typename, typename, typename > bool File::read_impl( Type* buffer, std::streamsize elements ) { @@ -219,21 +221,23 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) #endif } -template< class Type, typename Device, typename TargetType > -bool File::write( const Type* buffer, std::streamsize elements ) +template< typename Type, + typename TargetType, + typename Device > +bool File::save( 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, TargetType >( buffer, elements ); + return write_impl< Type, TargetType, Device >( buffer, elements ); } // Host template< typename Type, - typename Device, typename TargetType, + typename Device, typename > bool File::write_impl( const Type* buffer, std::streamsize elements ) { @@ -260,8 +264,8 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) // Cuda template< typename Type, - typename Device, typename TargetType, + typename Device, typename, typename > bool File::write_impl( const Type* buffer, std::streamsize elements ) { @@ -314,8 +318,8 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) // MIC template< typename Type, - typename Device, typename TargetType, + typename Device, typename, typename, typename > bool File::write_impl( const Type* buffer, std::streamsize elements ) { @@ -370,9 +374,9 @@ inline bool fileExists( const String& fileName ) inline File& operator<<( File& file, const std::string& str ) { const int len = str.size(); - if( ! file.write( &len ) ) + if( ! file.save( &len ) ) throw Exceptions::FileSerializationError( getType< int >(), file.getFileName() ); - if( ! file.write( str.c_str(), len ) ) + if( ! file.save( str.c_str(), len ) ) throw Exceptions::FileSerializationError( "String", file.getFileName() ); return file; } @@ -381,10 +385,10 @@ inline File& operator<<( File& file, const std::string& str ) inline File& operator>>( File& file, std::string& str ) { int length; - if( ! file.read( &length ) ) + if( ! file.load( &length ) ) throw Exceptions::FileDeserializationError( getType< int >(), file.getFileName() ); char buffer[ length ]; - if( length && ! file.read( buffer, length ) ) + if( length && ! file.load( buffer, length ) ) throw Exceptions::FileDeserializationError( "String", file.getFileName() ); str.assign( buffer, length ); return file; diff --git a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h index 799d07281..e318b70b4 100644 --- a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h +++ b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h @@ -746,7 +746,7 @@ template< typename Real, bool EllpackSymmetricGraph< Real, Device, Index >::save( File& file ) const { if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.write( &this->rowLengths ) ) return false; + if( ! file.save( &this->rowLengths ) ) return false; return true; } @@ -756,7 +756,7 @@ template< typename Real, bool EllpackSymmetricGraph< Real, Device, Index >::load( File& file ) { if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.read( &this->rowLengths ) ) return false; + if( ! file.load( &this->rowLengths ) ) return false; return true; } diff --git a/src/TNL/Matrices/EllpackSymmetric_impl.h b/src/TNL/Matrices/EllpackSymmetric_impl.h index 42202a883..fe41a1c9e 100644 --- a/src/TNL/Matrices/EllpackSymmetric_impl.h +++ b/src/TNL/Matrices/EllpackSymmetric_impl.h @@ -540,7 +540,7 @@ template< typename Real, bool EllpackSymmetric< Real, Device, Index >::save( File& file ) const { if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.write( &this->rowLengths ) ) return false; + if( ! file.save( &this->rowLengths ) ) return false; return true; } @@ -550,7 +550,7 @@ template< typename Real, bool EllpackSymmetric< Real, Device, Index >::load( File& file ) { if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.read( &this->rowLengths ) ) return false; + if( ! file.load( &this->rowLengths ) ) return false; return true; } diff --git a/src/TNL/Matrices/Ellpack_impl.h b/src/TNL/Matrices/Ellpack_impl.h index 7c2a3b6f0..f42173530 100644 --- a/src/TNL/Matrices/Ellpack_impl.h +++ b/src/TNL/Matrices/Ellpack_impl.h @@ -716,7 +716,7 @@ template< typename Real, bool Ellpack< Real, Device, Index >::save( File& file ) const { if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.write( &this->rowLengths ) ) return false; + if( ! file.save( &this->rowLengths ) ) return false; return true; } @@ -726,7 +726,7 @@ template< typename Real, bool Ellpack< Real, Device, Index >::load( File& file ) { if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.read( &this->rowLengths ) ) return false; + if( ! file.load( &this->rowLengths ) ) return false; return true; } diff --git a/src/TNL/Matrices/Matrix_impl.h b/src/TNL/Matrices/Matrix_impl.h index cb685917f..4e1db06ad 100644 --- a/src/TNL/Matrices/Matrix_impl.h +++ b/src/TNL/Matrices/Matrix_impl.h @@ -145,8 +145,8 @@ template< typename Real, bool Matrix< Real, Device, Index >::save( File& file ) const { if( ! Object::save( file ) || - ! file.write( &this->rows ) || - ! file.write( &this->columns ) || + ! file.save( &this->rows ) || + ! file.save( &this->columns ) || ! this->values.save( file ) ) return false; return true; @@ -158,8 +158,8 @@ template< typename Real, bool Matrix< Real, Device, Index >::load( File& file ) { if( ! Object::load( file ) || - ! file.read( &this->rows ) || - ! file.read( &this->columns ) || + ! file.load( &this->rows ) || + ! file.load( &this->columns ) || ! this->values.load( file ) ) return false; return true; diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index 1d3dd31a5..7d135b060 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -43,7 +43,7 @@ inline String Object::getSerializationTypeVirtual() const inline bool Object::save( File& file ) const { - if( ! file.write( magic_number, strlen( magic_number ) ) ) + if( ! file.save( magic_number, strlen( magic_number ) ) ) return false; file << this->getSerializationTypeVirtual(); return true; @@ -90,7 +90,7 @@ inline String getObjectType( File& file ) { char mn[ 10 ]; String type; - file.read( mn, strlen( magic_number ) ); + file.load( mn, strlen( magic_number ) ); if( strncmp( mn, magic_number, 5 ) != 0 ) throw Exceptions::NotTNLFile(); file >> type; diff --git a/src/UnitTests/FileTest.h b/src/UnitTests/FileTest.h index 93616bb17..17d2df6ed 100644 --- a/src/UnitTests/FileTest.h +++ b/src/UnitTests/FileTest.h @@ -29,18 +29,18 @@ 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.save( &intData ) ); + ASSERT_TRUE( file.save( doubleData, 3 ) ); + ASSERT_TRUE( file.save( &constDoubleData ) ); file.close(); 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 ) ); + ASSERT_TRUE( file.load( &newIntData, 1 ) ); + ASSERT_TRUE( file.load( newDoubleData, 3 ) ); + ASSERT_TRUE( file.load( &newConstDoubleData, 1 ) ); EXPECT_EQ( newIntData, intData ); for( int i = 0; i < 3; i ++ ) @@ -59,15 +59,15 @@ TEST( FileTest, WriteAndReadWithConversion ) int intData[ 3 ]; File file; file.open( "test-file.tnl", File::Mode::Out | File::Mode::Truncate ); - file.write< double, Devices::Host, float >( doubleData, 3 ); + file.save< double, float, Devices::Host >( doubleData, 3 ); file.close(); file.open( "test-file.tnl", File::Mode::In ); - file.read< float, Devices::Host, float >( floatData, 3 ); + file.load< float, float, Devices::Host >( floatData, 3 ); file.close(); file.open( "test-file.tnl", File::Mode::In ); - file.read< int, Devices::Host, float >( intData, 3 ); + file.load< int, float, Devices::Host >( intData, 3 ); file.close(); EXPECT_NEAR( floatData[ 0 ], 3.14159, 0.0001 ); @@ -110,11 +110,11 @@ TEST( FileTest, WriteAndReadCUDA ) File file; file.open( String( "test-file.tnl" ), File::Mode::Out ); - bool status = file.write< int, Devices::Cuda >( cudaIntData ); + bool status = file.save< int, int, Devices::Cuda >( cudaIntData ); ASSERT_TRUE( status ); - status = file.write< float, Devices::Cuda >( cudaFloatData, 3 ); + status = file.save< float, float, Devices::Cuda >( cudaFloatData, 3 ); ASSERT_TRUE( status ); - status = file.write< const double, Devices::Cuda >( cudaConstDoubleData ); + status = file.save< const double, double, Devices::Cuda >( cudaConstDoubleData ); ASSERT_TRUE( status ); file.close(); @@ -128,11 +128,11 @@ 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 ); + status = file.load< int, int, Devices::Cuda >( newCudaIntData, 1 ); ASSERT_TRUE( status ); - status = file.read< float, Devices::Cuda >( newCudaFloatData, 3 ); + status = file.load< float, float, Devices::Cuda >( newCudaFloatData, 3 ); ASSERT_TRUE( status ); - status = file.read< double, Devices::Cuda >( newCudaDoubleData, 1 ); + status = file.load< double, double, Devices::Cuda >( newCudaDoubleData, 1 ); ASSERT_TRUE( status ); cudaMemcpy( &newIntData, newCudaIntData, @@ -176,15 +176,15 @@ TEST( FileTest, WriteAndReadCUDAWithConversion ) File file; file.open( String( "cuda-test-file.tnl" ), File::Mode::Out | File::Mode::Truncate ); - file.write< double, Devices::Cuda, float >( cudaConstDoubleData, 3 ); + file.save< double, float, Devices::Cuda >( cudaConstDoubleData, 3 ); file.close(); file.open( String( "cuda-test-file.tnl" ), File::Mode::In ); - file.read< float, Devices::Cuda, float >( cudaFloatData, 3 ); + file.load< float, float, Devices::Cuda >( cudaFloatData, 3 ); file.close(); file.open( String( "cuda-test-file.tnl" ), File::Mode::In ); - file.read< int, Devices::Cuda, float >( cudaIntData, 3 ); + file.load< int, float, Devices::Cuda >( cudaIntData, 3 ); file.close(); cudaMemcpy( floatData, -- GitLab From 1cd1f99784a759e55d03b8f15f6b20bb6364ef23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Thu, 7 Mar 2019 23:09:57 +0100 Subject: [PATCH 28/72] [WIP] Changing File load and save from bool to void. --- src/TNL/Containers/Algorithms/ArrayIO.h | 6 +- src/TNL/Containers/Array_impl.h | 12 ++- .../Multimaps/EllpackIndexMultimap_impl.h | 12 +-- .../StaticEllpackIndexMultimap_impl.h | 6 +- src/TNL/Containers/StaticArray1D_impl.h | 12 +-- src/TNL/Containers/StaticArray2D_impl.h | 12 +-- src/TNL/Containers/StaticArray3D_impl.h | 12 +-- src/TNL/File.h | 16 ++-- src/TNL/File.hpp | 73 ++++++++++++------- src/TNL/Matrices/EllpackSymmetricGraph_impl.h | 4 +- src/TNL/Matrices/EllpackSymmetric_impl.h | 4 +- src/TNL/Matrices/Ellpack_impl.h | 4 +- src/TNL/Matrices/Matrix_impl.h | 16 ++-- src/TNL/Object.hpp | 3 +- 14 files changed, 90 insertions(+), 102 deletions(-) diff --git a/src/TNL/Containers/Algorithms/ArrayIO.h b/src/TNL/Containers/Algorithms/ArrayIO.h index 79da384b9..77e82355f 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.save< Value, 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.load< Value, Value, Device >( data, elements ); + file.load< Value, Value, Device >( data, elements ); + return true; } }; diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h index 60dba8f9b..a40c7fa8a 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array_impl.h @@ -474,8 +474,7 @@ bool Array< Value, Device, Index >::save( File& file ) const { if( ! Object::save( file ) ) return false; - if( ! file.save( &this->size ) ) - return false; + file.save( &this->size ); 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() @@ -495,11 +494,11 @@ load( File& file ) if( ! Object::load( file ) ) return false; Index _size; - if( ! file.load( &_size ) ) - { + file.load( &_size ); + /*{ std::cerr << "Unable to read the array size." << std::endl; return false; - } + }*/ if( _size < 0 ) { std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl; @@ -528,8 +527,7 @@ boundLoad( File& file ) if( ! Object::load( file ) ) return false; Index _size; - if( ! file.load( &_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; diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h index e9654e739..25a3448dd 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h @@ -244,10 +244,8 @@ save( File& file ) const { if( ! Object::save( file ) ) return false; - if( ! file.save( &this->keysRange ) ) - return false; - if( ! file.save( &this->maxValuesCount ) ) - return false; + file.save( &this->keysRange ); + file.save( &this->maxValuesCount ); if( ! this->values.save( file ) ) return false; if( ! this->valuesCounts.save( file ) ) @@ -265,10 +263,8 @@ load( File& file ) { if( ! Object::load( file ) ) return false; - if( ! file.load( &this->keysRange ) ) - return false; - if( ! file.load( &this->maxValuesCount ) ) - return false; + file.load( &this->keysRange ); + file.load( &this->maxValuesCount ); if( ! this->values.load( file ) ) return false; if( ! this->valuesCounts.load( file ) ) diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h index 269b620c2..58ba348eb 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h @@ -203,8 +203,7 @@ save( File& file ) const { if( ! Object::save( file ) ) return false; - if( ! file.save( &this->keysRange ) ) - return false; + file.save( &this->keysRange ); if( ! this->values.save( file ) ) return false; return true; @@ -221,8 +220,7 @@ load( File& file ) { if( ! Object::load( file ) ) return false; - if( ! file.load( &this->keysRange ) ) - return false; + file.load( &this->keysRange ); if( ! this->values.load( file ) ) return false; return true; diff --git a/src/TNL/Containers/StaticArray1D_impl.h b/src/TNL/Containers/StaticArray1D_impl.h index 1da2b0c79..98963dcf3 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.save< Value, 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.load< Value, 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/StaticArray2D_impl.h b/src/TNL/Containers/StaticArray2D_impl.h index 1ce77b2eb..29dcbee59 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.save< Value, 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.load< Value, 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 448f8df94..69c1998a4 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.save< Value, 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.load< Value, 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/File.h b/src/TNL/File.h index 0e6066452..f79b24401 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -92,7 +92,7 @@ class File * \param elements Number of elements the user wants to get (read) from given file. */ template< typename Type, typename SourceType = Type, typename Device = Devices::Host > - bool load( Type* buffer, std::streamsize elements = 1 ); + void load( Type* buffer, std::streamsize elements = 1 ); /** * \brief Method that can write particular data type from CPU into given file. (Function that writes particular elements into given file.) @@ -108,21 +108,21 @@ class File * \param elements Number of elements the user wants to write into the given file. */ template< typename Type, typename TargetType = Type, typename Device = Devices::Host > - bool save( const Type* buffer, std::streamsize elements = 1 ); + 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 > - bool read_impl( Type* buffer, std::streamsize elements ); + 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 > - bool read_impl( Type* buffer, std::streamsize elements ); + void load_impl( Type* buffer, std::streamsize elements ); template< typename Type, typename SourceType, @@ -130,20 +130,20 @@ class File 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 ); + 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 > - bool write_impl( const Type* buffer, std::streamsize elements ); + 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 > - bool write_impl( const Type* buffer, std::streamsize elements ); + void save_impl( const Type* buffer, std::streamsize elements ); template< typename Type, typename TargetType, @@ -151,7 +151,7 @@ class File 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 ); + void save_impl( const Type* buffer, std::streamsize elements ); std::fstream file; String fileName; diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index cf9c68441..ec06e51e8 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -83,14 +83,14 @@ inline void File::close() template< typename Type, typename SourceType, typename Device > -bool File::load( Type* buffer, std::streamsize elements ) +void File::load( Type* buffer, std::streamsize elements ) { - TNL_ASSERT_GE( elements, 0, "Number of elements to read must be non-negative." ); + TNL_ASSERT_GE( elements, 0, "Number of elements to load must be non-negative." ); if( ! elements ) - return true; + return; - return read_impl< Type, SourceType, Device >( buffer, elements ); + load_impl< Type, SourceType, Device >( buffer, elements ); } // Host @@ -98,13 +98,10 @@ template< typename Type, typename SourceType, typename Device, typename > -bool File::read_impl( Type* buffer, std::streamsize elements ) +void File::load_impl( Type* buffer, std::streamsize elements ) { if( std::is_same< Type, SourceType >::value ) - { file.read( reinterpret_cast(buffer), sizeof(Type) * elements ); - return true; - } else { const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(SourceType), elements ); @@ -127,7 +124,7 @@ template< typename Type, typename SourceType, typename Device, typename, typename > -bool File::read_impl( Type* buffer, std::streamsize elements ) +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 ); @@ -169,7 +166,6 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) readElements += transfer; } } - return true; #else throw Exceptions::CudaSupportMissing(); #endif @@ -180,7 +176,7 @@ template< typename Type, typename SourceType, typename Device, typename, typename, typename > -bool File::read_impl( Type* buffer, std::streamsize elements ) +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 ); @@ -215,7 +211,6 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) std::cerr << "Type conversion during loading is not implemented for MIC." << std::endl; abort(); } - return true; #else throw Exceptions::MICSupportMissing(); #endif @@ -224,14 +219,14 @@ bool File::read_impl( Type* buffer, std::streamsize elements ) template< typename Type, typename TargetType, typename Device > -bool File::save( const Type* buffer, std::streamsize elements ) +void File::save( const Type* buffer, std::streamsize elements ) { - TNL_ASSERT_GE( elements, 0, "Number of elements to write must be non-negative." ); + TNL_ASSERT_GE( elements, 0, "Number of elements to save must be non-negative." ); if( ! elements ) - return true; + return; - return write_impl< Type, TargetType, Device >( buffer, elements ); + save_impl< Type, TargetType, Device >( buffer, elements ); } // Host @@ -239,7 +234,7 @@ template< typename Type, typename TargetType, typename Device, typename > -bool File::write_impl( const Type* buffer, std::streamsize elements ) +void File::save_impl( const Type* buffer, std::streamsize elements ) { if( std::is_same< Type, TargetType >::value ) file.write( reinterpret_cast(buffer), sizeof(Type) * elements ); @@ -259,7 +254,6 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) } } - return true; } // Cuda @@ -267,7 +261,7 @@ template< typename Type, typename TargetType, typename Device, typename, typename > -bool File::write_impl( const Type* buffer, std::streamsize elements ) +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 ); @@ -310,7 +304,6 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) writtenElements += transfer; } } - return true; #else throw Exceptions::CudaSupportMissing(); #endif @@ -321,7 +314,7 @@ template< typename Type, typename TargetType, typename Device, typename, typename, typename > -bool File::write_impl( const Type* buffer, std::streamsize elements ) +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 ); @@ -356,7 +349,6 @@ bool File::write_impl( const Type* buffer, std::streamsize elements ) std::cerr << "Type conversion during saving is not implemented for MIC." << std::endl; abort(); } - return true; #else throw Exceptions::MICSupportMissing(); #endif @@ -374,10 +366,22 @@ inline bool fileExists( const String& fileName ) inline File& operator<<( File& file, const std::string& str ) { const int len = str.size(); - if( ! file.save( &len ) ) + try + { + file.save( &len ); + } + catch(...) + { throw Exceptions::FileSerializationError( getType< int >(), file.getFileName() ); - if( ! file.save( str.c_str(), len ) ) + } + try + { + file.save( str.c_str(), len ); + } + catch(...) + { throw Exceptions::FileSerializationError( "String", file.getFileName() ); + } return file; } @@ -385,11 +389,26 @@ inline File& operator<<( File& file, const std::string& str ) inline File& operator>>( File& file, std::string& str ) { int length; - if( ! file.load( &length ) ) + try + { + file.load( &length ); + } + catch(...) + { throw Exceptions::FileDeserializationError( getType< int >(), file.getFileName() ); + } char buffer[ length ]; - if( length && ! file.load( buffer, length ) ) - throw Exceptions::FileDeserializationError( "String", file.getFileName() ); + if( length ) + { + try + { + file.load( buffer, length ); + } + catch(...) + { + throw Exceptions::FileDeserializationError( "String", file.getFileName() ); + } + } str.assign( buffer, length ); return file; } diff --git a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h index e318b70b4..6c811315c 100644 --- a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h +++ b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h @@ -746,7 +746,7 @@ template< typename Real, bool EllpackSymmetricGraph< Real, Device, Index >::save( File& file ) const { if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.save( &this->rowLengths ) ) return false; + file.save( &this->rowLengths ); return true; } @@ -756,7 +756,7 @@ template< typename Real, bool EllpackSymmetricGraph< Real, Device, Index >::load( File& file ) { if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.load( &this->rowLengths ) ) return false; + file.load( &this->rowLengths ); return true; } diff --git a/src/TNL/Matrices/EllpackSymmetric_impl.h b/src/TNL/Matrices/EllpackSymmetric_impl.h index fe41a1c9e..74a588371 100644 --- a/src/TNL/Matrices/EllpackSymmetric_impl.h +++ b/src/TNL/Matrices/EllpackSymmetric_impl.h @@ -540,7 +540,7 @@ template< typename Real, bool EllpackSymmetric< Real, Device, Index >::save( File& file ) const { if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.save( &this->rowLengths ) ) return false; + file.save( &this->rowLengths ); return true; } @@ -550,7 +550,7 @@ template< typename Real, bool EllpackSymmetric< Real, Device, Index >::load( File& file ) { if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.load( &this->rowLengths ) ) return false; + file.load( &this->rowLengths ); return true; } diff --git a/src/TNL/Matrices/Ellpack_impl.h b/src/TNL/Matrices/Ellpack_impl.h index f42173530..4c4690159 100644 --- a/src/TNL/Matrices/Ellpack_impl.h +++ b/src/TNL/Matrices/Ellpack_impl.h @@ -716,7 +716,7 @@ template< typename Real, bool Ellpack< Real, Device, Index >::save( File& file ) const { if( ! Sparse< Real, Device, Index >::save( file) ) return false; - if( ! file.save( &this->rowLengths ) ) return false; + file.save( &this->rowLengths ); return true; } @@ -726,7 +726,7 @@ template< typename Real, bool Ellpack< Real, Device, Index >::load( File& file ) { if( ! Sparse< Real, Device, Index >::load( file) ) return false; - if( ! file.load( &this->rowLengths ) ) return false; + file.load( &this->rowLengths ); return true; } diff --git a/src/TNL/Matrices/Matrix_impl.h b/src/TNL/Matrices/Matrix_impl.h index 4e1db06ad..b6bddf6e7 100644 --- a/src/TNL/Matrices/Matrix_impl.h +++ b/src/TNL/Matrices/Matrix_impl.h @@ -144,10 +144,10 @@ template< typename Real, typename Index > bool Matrix< Real, Device, Index >::save( File& file ) const { - if( ! Object::save( file ) || - ! file.save( &this->rows ) || - ! file.save( &this->columns ) || - ! this->values.save( file ) ) + Object::save( file ); + file.save( &this->rows ); + file.save( &this->columns ); + if( ! this->values.save( file ) ) return false; return true; } @@ -157,10 +157,10 @@ template< typename Real, typename Index > bool Matrix< Real, Device, Index >::load( File& file ) { - if( ! Object::load( file ) || - ! file.load( &this->rows ) || - ! file.load( &this->columns ) || - ! this->values.load( file ) ) + Object::load( file ); + file.load( &this->rows ); + file.load( &this->columns ); + if( ! this->values.load( file ) ) return false; return true; } diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index 7d135b060..39c071b4f 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -43,8 +43,7 @@ inline String Object::getSerializationTypeVirtual() const inline bool Object::save( File& file ) const { - if( ! file.save( magic_number, strlen( magic_number ) ) ) - return false; + file.save( magic_number, strlen( magic_number ) ); file << this->getSerializationTypeVirtual(); return true; } -- GitLab From 453f554cdd82390aeae7adbda7a47afc9ac38b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Fri, 8 Mar 2019 20:42:21 +0100 Subject: [PATCH 29/72] Changed File load and save from bool to void. --- src/TNL/Containers/StaticArray_impl.h | 12 ++--------- src/UnitTests/FileTest.h | 30 +++++++++++---------------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/TNL/Containers/StaticArray_impl.h b/src/TNL/Containers/StaticArray_impl.h index 2a9f46347..9c7835ce8 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.save< Value, 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.load< Value, 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/UnitTests/FileTest.h b/src/UnitTests/FileTest.h index 17d2df6ed..39671ba66 100644 --- a/src/UnitTests/FileTest.h +++ b/src/UnitTests/FileTest.h @@ -29,18 +29,18 @@ TEST( FileTest, WriteAndRead ) int intData( 5 ); double doubleData[ 3 ] = { 1.0, 2.0, 3.0 }; const double constDoubleData = 3.14; - ASSERT_TRUE( file.save( &intData ) ); - ASSERT_TRUE( file.save( doubleData, 3 ) ); - ASSERT_TRUE( file.save( &constDoubleData ) ); + file.save( &intData ); + file.save( doubleData, 3 ); + file.save( &constDoubleData ); file.close(); file.open( String( "test-file.tnl" ), File::Mode::In ); int newIntData; double newDoubleData[ 3 ]; double newConstDoubleData; - ASSERT_TRUE( file.load( &newIntData, 1 ) ); - ASSERT_TRUE( file.load( newDoubleData, 3 ) ); - ASSERT_TRUE( file.load( &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 ++ ) @@ -110,12 +110,9 @@ TEST( FileTest, WriteAndReadCUDA ) File file; file.open( String( "test-file.tnl" ), File::Mode::Out ); - bool status = file.save< int, int, Devices::Cuda >( cudaIntData ); - ASSERT_TRUE( status ); - status = file.save< float, float, Devices::Cuda >( cudaFloatData, 3 ); - ASSERT_TRUE( status ); - status = file.save< const double, double, Devices::Cuda >( cudaConstDoubleData ); - ASSERT_TRUE( status ); + 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(); file.open( String( "test-file.tnl" ), File::Mode::In ); @@ -128,12 +125,9 @@ TEST( FileTest, WriteAndReadCUDA ) cudaMalloc( ( void** ) &newCudaIntData, sizeof( int ) ); cudaMalloc( ( void** ) &newCudaFloatData, 3 * sizeof( float ) ); cudaMalloc( ( void** ) &newCudaDoubleData, sizeof( double ) ); - status = file.load< int, int, Devices::Cuda >( newCudaIntData, 1 ); - ASSERT_TRUE( status ); - status = file.load< float, float, Devices::Cuda >( newCudaFloatData, 3 ); - ASSERT_TRUE( status ); - status = file.load< double, 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 ), -- GitLab From 5461f6c0a94d634021b58bb9e409aba258e9c9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sat, 9 Mar 2019 10:31:26 +0100 Subject: [PATCH 30/72] Changed Object load and save from bool to void. --- .../DistSpMV/tnl-benchmark-distributed-spmv.h | 5 +- .../HeatEquationBenchmarkProblem_impl.h | 9 ++- .../tnl-benchmark-linear-solvers.h | 6 +- .../flow-sw/navierStokesProblem_impl.h | 9 +-- .../flow-vl/navierStokesProblem_impl.h | 9 +-- src/Examples/flow/navierStokesProblem_impl.h | 3 +- .../inviscid-flow-sw/eulerProblem_impl.h | 15 ++-- .../inviscid-flow-vl/eulerProblem_impl.h | 15 ++-- .../inviscid-flow/eulerProblem_impl.h | 12 ++-- .../transportEquationProblemEoc_impl.h | 12 ++-- .../transportEquationProblem_impl.h | 9 ++- src/TNL/Containers/Array.h | 6 +- src/TNL/Containers/Array_impl.h | 68 ++++-------------- src/TNL/Containers/MultiVector.h | 32 ++++----- src/TNL/Containers/MultiVector1D_impl.h | 38 +++------- src/TNL/Containers/MultiVector2D_impl.h | 38 +++------- src/TNL/Containers/MultiVector3D_impl.h | 38 +++------- src/TNL/Containers/MultiVector4D_impl.h | 38 +++------- .../Multimaps/EllpackIndexMultimap.h | 4 +- .../Multimaps/EllpackIndexMultimap_impl.h | 24 +++---- .../Multimaps/StaticEllpackIndexMultimap.h | 4 +- .../StaticEllpackIndexMultimap_impl.h | 18 ++--- src/TNL/Exceptions/ArrayWrongSize.h | 32 +++++++++ src/TNL/Exceptions/MeshFunctionDataMismatch.h | 32 +++++++++ src/TNL/Exceptions/ObjectTypeMismatch.h | 32 +++++++++ .../tnlDirectEikonalProblem_impl.h | 12 +++- src/TNL/Functions/MeshFunction.h | 6 +- src/TNL/Functions/MeshFunction_impl.h | 32 ++++----- src/TNL/Functions/VectorField.h | 27 +++---- src/TNL/Matrices/AdEllpack.h | 8 +-- src/TNL/Matrices/AdEllpack_impl.h | 36 +++++----- src/TNL/Matrices/BiEllpack.h | 8 +-- src/TNL/Matrices/BiEllpackSymmetric.h | 8 +-- src/TNL/Matrices/BiEllpackSymmetric_impl.h | 28 ++++---- src/TNL/Matrices/BiEllpack_impl.h | 28 ++++---- src/TNL/Matrices/CSR.h | 8 +-- src/TNL/Matrices/CSR_impl.h | 24 +++---- src/TNL/Matrices/ChunkedEllpack.h | 8 +-- src/TNL/Matrices/ChunkedEllpack_impl.h | 36 +++++----- src/TNL/Matrices/Dense.h | 8 +-- src/TNL/Matrices/Dense_impl.h | 20 +++--- src/TNL/Matrices/Ellpack.h | 8 +-- src/TNL/Matrices/EllpackSymmetric.h | 8 +-- src/TNL/Matrices/EllpackSymmetricGraph.h | 8 +-- src/TNL/Matrices/EllpackSymmetricGraph_impl.h | 18 +++-- src/TNL/Matrices/EllpackSymmetric_impl.h | 18 +++-- src/TNL/Matrices/Ellpack_impl.h | 18 +++-- src/TNL/Matrices/Matrix.h | 4 +- src/TNL/Matrices/Matrix_impl.h | 12 ++-- src/TNL/Matrices/Multidiagonal.h | 8 +-- src/TNL/Matrices/Multidiagonal_impl.h | 26 ++++--- src/TNL/Matrices/SlicedEllpack.h | 8 +-- src/TNL/Matrices/SlicedEllpackSymmetric.h | 8 +-- .../Matrices/SlicedEllpackSymmetricGraph.h | 8 +-- .../SlicedEllpackSymmetricGraph_impl.h | 28 ++++---- .../Matrices/SlicedEllpackSymmetric_impl.h | 28 ++++---- src/TNL/Matrices/SlicedEllpack_impl.h | 28 ++++---- src/TNL/Matrices/Sparse.h | 4 +- src/TNL/Matrices/Sparse_impl.h | 20 +++--- .../DistributedGridIO_MeshFunction.h | 30 ++++---- .../DistributedGridIO_VectorField.h | 6 +- src/TNL/Meshes/GridDetails/Grid1D.h | 8 +-- src/TNL/Meshes/GridDetails/Grid1D_impl.h | 40 ++++------- src/TNL/Meshes/GridDetails/Grid2D.h | 8 +-- src/TNL/Meshes/GridDetails/Grid2D_impl.h | 40 ++++------- src/TNL/Meshes/GridDetails/Grid3D.h | 8 +-- src/TNL/Meshes/GridDetails/Grid3D_impl.h | 40 ++++------- src/TNL/Meshes/Mesh.h | 4 +- .../MeshLayers/BoundaryTags/Layer.h | 12 +++- .../MeshDetails/MeshLayers/StorageLayer.h | 24 ++++--- .../MeshLayers/SubentityStorageLayer.h | 16 +++-- .../MeshLayers/SuperentityStorageLayer.h | 16 +++-- src/TNL/Meshes/MeshDetails/Mesh_impl.h | 26 +++---- src/TNL/Meshes/Readers/TNLReader.h | 3 +- .../Meshes/TypeResolver/TypeResolver_impl.h | 14 +++- src/TNL/Object.h | 12 ++-- src/TNL/Object.hpp | 28 ++++---- src/TNL/Problems/HeatEquationProblem_impl.h | 19 ++--- src/Tools/tnl-diff.h | 71 ++++++------------- src/Tools/tnl-grid-setup.h | 18 ++++- src/Tools/tnl-grid-to-mesh.cpp | 7 +- src/Tools/tnl-image-converter.cpp | 12 +++- src/Tools/tnl-init.h | 11 +-- src/Tools/tnl-lattice-init.h | 30 +++++--- src/Tools/tnl-mesh-converter.cpp | 10 ++- src/Tools/tnl-view.h | 23 +++--- src/UnitTests/Containers/ArrayTest.h | 21 ++++-- .../Containers/Multimaps/MultimapTest.cpp | 4 +- .../Multimaps/StaticMultimapTest.cpp | 4 +- .../DistributedVectorFieldIO_MPIIOTestBase.h | 16 ++--- src/UnitTests/Meshes/MeshTest.h | 12 ++-- src/UnitTests/ObjectTest.cpp | 4 +- 92 files changed, 788 insertions(+), 874 deletions(-) create mode 100644 src/TNL/Exceptions/ArrayWrongSize.h create mode 100644 src/TNL/Exceptions/MeshFunctionDataMismatch.h create mode 100644 src/TNL/Exceptions/ObjectTypeMismatch.h diff --git a/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h b/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h index 23f081527..62e371172 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 e63e431c6..2bfd1e71c 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 55211c4ed..c3d2cc9cd 100644 --- a/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h +++ b/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h @@ -332,9 +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" ) ) ) + matrixPointer->load( parameters.getParameter< String >( "input-matrix" ) ); + x0.load( parameters.getParameter< String >( "input-dof" ) ); + b.load( parameters.getParameter< String >( "input-rhs" ) ); return false; typename MatrixType::CompressedRowLengthsVector rowLengths; diff --git a/src/Examples/flow-sw/navierStokesProblem_impl.h b/src/Examples/flow-sw/navierStokesProblem_impl.h index fbe14668a..886c9f03f 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 fbe14668a..886c9f03f 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 96603490c..4b0c79774 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 e043589cc..e0382e9c2 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 e043589cc..e0382e9c2 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 7347755cb..f992a3067 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/transport-equation/transportEquationProblemEoc_impl.h b/src/Examples/transport-equation/transportEquationProblemEoc_impl.h index 512e310d2..0ac3af2d8 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 2d019602c..80c018e85 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/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 867bca6a2..2834ec52f 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -274,14 +274,14 @@ class Array : public Object * * \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. @@ -291,7 +291,7 @@ class Array : public Object * performed. Otherwise, the array size must fit with * the size of array being loaded. */ - bool boundLoad( File& file ); + void boundLoad( File& file ); using Object::save; diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h index a40c7fa8a..39a6fa08f 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array_impl.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace TNL { namespace Containers { @@ -470,89 +471,48 @@ Array< Value, Device, Index >::operator bool() const 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; + Object::save( file ); file.save( &this->size ); - 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; + 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; file.load( &_size ); - /*{ - std::cerr << "Unable to read the array size." << std::endl; - return false; - }*/ 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; 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 ); } diff --git a/src/TNL/Containers/MultiVector.h b/src/TNL/Containers/MultiVector.h index aa30db976..eaebf5cd5 100644 --- a/src/TNL/Containers/MultiVector.h +++ b/src/TNL/Containers/MultiVector.h @@ -89,14 +89,14 @@ class MultiVector< 1, Real, Device, Index > : public Vector< Real, Device, Index 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; + void save( File& file ) const; //! Method for restoring the object from a file - 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 ); protected: @@ -170,14 +170,14 @@ class MultiVector< 2, Real, Device, Index > : public Vector< Real, Device, Index 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; + void save( File& file ) const; //! Method for restoring the object from a file - 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 ); protected: @@ -252,14 +252,14 @@ class MultiVector< 3, Real, Device, Index > : public Vector< Real, Device, Index 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; + void save( File& file ) const; //! Method for restoring the object from a file - 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 ); protected: @@ -334,14 +334,14 @@ class MultiVector< 4, Real, Device, Index > : public Vector< Real, Device, Index 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; + void save( File& file ) const; //! Method for restoring the object from a file - 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 ); protected: diff --git a/src/TNL/Containers/MultiVector1D_impl.h b/src/TNL/Containers/MultiVector1D_impl.h index 5ac452c29..1d4f67890 100644 --- a/src/TNL/Containers/MultiVector1D_impl.h +++ b/src/TNL/Containers/MultiVector1D_impl.h @@ -174,35 +174,17 @@ MultiVector< 1, Real, Device, Index >& } template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: save( File& file ) const +void 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; + Vector< Real, Device, Index > :: save( file ); + dimensions. save( file ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: load( File& file ) +void 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; + Vector< Real, Device, Index > :: load( file ); + dimensions. load( file ); } template< typename Real, typename Device, typename Index > @@ -216,15 +198,15 @@ std::ostream& operator << ( std::ostream& str, const MultiVector< 1, Real, Devic } template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: save( const String& fileName ) const +void MultiVector< 1, Real, Device, Index > :: save( const String& fileName ) const { - return Object :: save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 1, Real, Device, Index > :: load( const String& fileName ) +void MultiVector< 1, Real, Device, Index > :: load( const String& fileName ) { - return Object :: load( fileName ); + Object::load( fileName ); } } // namespace Containers diff --git a/src/TNL/Containers/MultiVector2D_impl.h b/src/TNL/Containers/MultiVector2D_impl.h index 7f061ad06..a52caff8a 100644 --- a/src/TNL/Containers/MultiVector2D_impl.h +++ b/src/TNL/Containers/MultiVector2D_impl.h @@ -181,47 +181,29 @@ MultiVector< 2, Real, Device, Index >& } template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: save( File& file ) const +void 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; + Vector< Real, Device, Index > :: save( file ); + dimensions. save( file ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: load( File& file ) +void 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; + Vector< Real, Device, Index > :: load( file ); + dimensions. load( file ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: save( const String& fileName ) const +void MultiVector< 2, Real, Device, Index > :: save( const String& fileName ) const { - return Object :: save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 2, Real, Device, Index > :: load( const String& fileName ) +void MultiVector< 2, Real, Device, Index > :: load( const String& fileName ) { - return Object :: load( fileName ); + Object::load( fileName ); } template< typename Real, typename Device, typename Index > diff --git a/src/TNL/Containers/MultiVector3D_impl.h b/src/TNL/Containers/MultiVector3D_impl.h index c7949014d..2a280f513 100644 --- a/src/TNL/Containers/MultiVector3D_impl.h +++ b/src/TNL/Containers/MultiVector3D_impl.h @@ -201,35 +201,17 @@ MultiVector< 3, Real, Device, Index >& } template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: save( File& file ) const +void 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; + Vector< Real, Device, Index > :: save( file ); + dimensions. save( file ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: load( File& file ) +void 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; + Vector< Real, Device, Index > :: load( file ); + dimensions. load( file ); } template< typename Real, typename Device, typename Index > @@ -251,15 +233,15 @@ std::ostream& operator << ( std::ostream& str, const MultiVector< 3, Real, Devic } template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: save( const String& fileName ) const +void MultiVector< 3, Real, Device, Index > :: save( const String& fileName ) const { - return Object :: save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 3, Real, Device, Index > :: load( const String& fileName ) +void MultiVector< 3, Real, Device, Index > :: load( const String& fileName ) { - return Object :: load( fileName ); + Object::load( fileName ); } } // namespace Containers diff --git a/src/TNL/Containers/MultiVector4D_impl.h b/src/TNL/Containers/MultiVector4D_impl.h index 14708ec20..f3c838155 100644 --- a/src/TNL/Containers/MultiVector4D_impl.h +++ b/src/TNL/Containers/MultiVector4D_impl.h @@ -218,35 +218,17 @@ MultiVector< 4, Real, Device, Index >& } template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: save( File& file ) const +void 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; + Vector< Real, Device, Index > :: save( file ); + dimensions. save( file ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: load( File& file ) +void 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; + Vector< Real, Device, Index > :: load( file ); + dimensions. load( file ); } template< typename Real, typename Device, typename Index > @@ -272,15 +254,15 @@ std::ostream& operator << ( std::ostream& str, const MultiVector< 4, Real, Devic } template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: save( const String& fileName ) const +void MultiVector< 4, Real, Device, Index > :: save( const String& fileName ) const { - return Object :: save( fileName ); + Object::save( fileName ); } template< typename Real, typename Device, typename Index > -bool MultiVector< 4, Real, Device, Index > :: load( const String& fileName ) +void MultiVector< 4, Real, Device, Index > :: load( const String& fileName ) { - return Object :: load( fileName ); + Object::load( fileName ); } } // namespace Containers diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h index feac869e5..822b7abb4 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 25a3448dd..2d145d377 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h @@ -238,38 +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; + Object::save( file ); file.save( &this->keysRange ); file.save( &this->maxValuesCount ); - if( ! this->values.save( file ) ) - return false; - if( ! this->valuesCounts.save( file ) ) - return false; - return true; + 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; + Object::load( file ); file.load( &this->keysRange ); file.load( &this->maxValuesCount ); - if( ! this->values.load( file ) ) - return false; - if( ! this->valuesCounts.load( file ) ) - return false; - return true; + 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 4811a763d..1af67bd3b 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 58ba348eb..95cb75d5d 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h @@ -197,16 +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; + Object::save( file ); file.save( &this->keysRange ); - if( ! this->values.save( file ) ) - return false; - return true; + this->values.save( file ); } template< int ValuesCount, @@ -214,16 +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; + Object::load( file ); file.load( &this->keysRange ); - if( ! this->values.load( file ) ) - return false; - return true; + this->values.load( file ); } template< int ValuesCount, diff --git a/src/TNL/Exceptions/ArrayWrongSize.h b/src/TNL/Exceptions/ArrayWrongSize.h new file mode 100644 index 000000000..8181b3c55 --- /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 +#include +#include + +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 000000000..6106db872 --- /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 +#include +#include + +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/ObjectTypeMismatch.h b/src/TNL/Exceptions/ObjectTypeMismatch.h new file mode 100644 index 000000000..9b48fd0ea --- /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 +#include +#include + +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 7c65ef94d..7437803e2 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/Functions/MeshFunction.h b/src/TNL/Functions/MeshFunction.h index 9d67808e1..1850f4fb2 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 e9426084e..107503ca4 100644 --- a/src/TNL/Functions/MeshFunction_impl.h +++ b/src/TNL/Functions/MeshFunction_impl.h @@ -15,6 +15,7 @@ #include #include #include +#include #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 46fdffcba..c7d5bf553 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 f5fdc7673..bfe70b6cb 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 daab3b8cd..57658788c 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, diff --git a/src/TNL/Matrices/BiEllpack.h b/src/TNL/Matrices/BiEllpack.h index b724a0ada..93bfeabaa 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 e44921fe8..5e72d9b64 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 5b6f94b57..69d32a472 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 ea5e1efb9..31dbd2bb3 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 fab302bed..4f42c1bac 100644 --- a/src/TNL/Matrices/CSR.h +++ b/src/TNL/Matrices/CSR.h @@ -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 0a682a9dc..5fe617b54 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 ff889a49f..928dcd8d1 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 ff1dd0742..e3a686264 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 351e8a8c7..e9601a9fa 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 d204c3a0a..3844751d4 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/Ellpack.h b/src/TNL/Matrices/Ellpack.h index e19010daf..100685e7b 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 0720d9d52..b150bc4d9 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 3a282c796..85c7e49b0 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 6c811315c..8f038742b 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; + Sparse< Real, Device, Index >::save( file); file.save( &this->rowLengths ); - return true; } 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; + Sparse< Real, Device, Index >::load( file); file.load( &this->rowLengths ); - return true; } 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 74a588371..fed7f7669 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; + Sparse< Real, Device, Index >::save( file); file.save( &this->rowLengths ); - return true; } 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; + Sparse< Real, Device, Index >::load( file); file.load( &this->rowLengths ); - return true; } 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 4c4690159..6c06fdd98 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; + Sparse< Real, Device, Index >::save( file); file.save( &this->rowLengths ); - return true; } 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; + Sparse< Real, Device, Index >::load( file); file.load( &this->rowLengths ); - return true; } 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 99f4bf1d6..e8677b853 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 b6bddf6e7..9f0ed2e76 100644 --- a/src/TNL/Matrices/Matrix_impl.h +++ b/src/TNL/Matrices/Matrix_impl.h @@ -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 { Object::save( file ); file.save( &this->rows ); file.save( &this->columns ); - if( ! this->values.save( file ) ) - return false; - return true; + 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 ) { Object::load( file ); file.load( &this->rows ); file.load( &this->columns ); - if( ! this->values.load( file ) ) - return false; - return true; + this->values.load( file ); } template< typename Real, diff --git a/src/TNL/Matrices/Multidiagonal.h b/src/TNL/Matrices/Multidiagonal.h index cfa798e7a..969a1e0aa 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 bd4c24691..860b3717c 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 0fc9ccb0b..b7302e559 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 d9abb0de2..550df75c4 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 a2ab00095..762b0a21e 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 9f09a21c5..dcd7ca3dc 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 402ac5a6c..3a8e3cab4 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 4d7593d3f..8e20c970e 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 069ade36c..7dc3798d2 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 cd57637cb..13b7ee7a9 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/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h index c6c7842ad..d72610628 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(); @@ -81,10 +81,10 @@ class DistributedGridIO< File file; file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::Out ); - bool ret=newMeshFunction.save(file); + newMeshFunction.save(file); file.close(); - return ret; + return true; }; @@ -93,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(); @@ -119,11 +120,11 @@ class DistributedGridIO< File file; file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::In ); - bool result=newMeshFunction.boundLoad(file); + newMeshFunction.boundLoad(file); file.close(); CopyEntitiesHelper::Copy(newMeshFunction,meshFunction,zeroCoord,localBegin,localSize); - return result; + return true; }; }; @@ -153,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())); @@ -320,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())); @@ -340,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 c3489994f..3353e8b9e 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())); @@ -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 9a8f14600..e4986c9fa 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 995fa6dab..5f3e919c6 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 f2dbebc5c..59ad153e2 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 41e05d8b5..42f2601b6 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 617efe7f3..232c36805 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 edbee0c00..4908ad707 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/Mesh.h b/src/TNL/Meshes/Mesh.h index 793f1b0bb..589a862b9 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 f743fd25e..99a0e6126 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 80bb94da6..a9d25d843 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 c26e525a9..cd4d9edf0 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 62d86fe7b..7e49a3155 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 cd704edaf..f95fd0e3a 100644 --- a/src/TNL/Meshes/MeshDetails/Mesh_impl.h +++ b/src/TNL/Meshes/MeshDetails/Mesh_impl.h @@ -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 881a50265..6100a5119 100644 --- a/src/TNL/Meshes/Readers/TNLReader.h +++ b/src/TNL/Meshes/Readers/TNLReader.h @@ -108,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 b3fe7f1ba..6c6012645 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 24aef554a..c66e5ccfc 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -91,42 +91,42 @@ 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 ); /** * \brief Destructor. diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index 39c071b4f..d4057c96b 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -16,6 +16,7 @@ #include #include +#include namespace TNL { @@ -41,48 +42,43 @@ inline String Object::getSerializationTypeVirtual() const return this->getSerializationType(); } -inline bool Object::save( File& file ) const +inline void Object::save( File& file ) const { 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 = 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; file.open( fileName, File::Mode::Out ); - return this->save( file ); + this->save( file ); } -inline bool Object::load( const String& fileName ) +inline void Object::load( const String& fileName ) { File file; file.open( fileName, File::Mode::In ); - return this->load( file ); + this->load( file ); } -inline bool Object::boundLoad( const String& fileName ) +inline void Object::boundLoad( const String& fileName ) { File file; file.open( fileName, File::Mode::In ); - return this->boundLoad( file ); + this->boundLoad( file ); } inline String getObjectType( File& file ) diff --git a/src/TNL/Problems/HeatEquationProblem_impl.h b/src/TNL/Problems/HeatEquationProblem_impl.h index 03be60b3b..0c0cd7418 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/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index d4f7514e2..d1b8cac24 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 << " "; @@ -377,13 +366,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 +377,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 +391,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 << " "; } @@ -616,11 +585,17 @@ 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 diff --git a/src/Tools/tnl-grid-setup.h b/src/Tools/tnl-grid-setup.h index 48da6a16d..896d3abb9 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 2cd562446..d2d03a29a 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 f06ba841d..51efacf14 100644 --- a/src/Tools/tnl-image-converter.cpp +++ b/src/Tools/tnl-image-converter.cpp @@ -150,7 +150,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 +164,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; diff --git a/src/Tools/tnl-init.h b/src/Tools/tnl-init.h index 5530ee5ad..36abb47dd 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(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; @@ -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 6b8b019e3..557bf5359 100644 --- a/src/Tools/tnl-lattice-init.h +++ b/src/Tools/tnl-lattice-init.h @@ -164,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; } @@ -180,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; @@ -195,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; @@ -205,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; diff --git a/src/Tools/tnl-mesh-converter.cpp b/src/Tools/tnl-mesh-converter.cpp index dd7ec0b20..cd9de1a59 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 273bac769..55d0fa60c 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -55,7 +55,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 +87,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; @@ -252,12 +260,10 @@ bool convertObject( const MeshPointer& meshPointer, // 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; + mf.write( outputFileName, outputFormat ); } if( parsedObjectType[ 0 ] == "Containers::MultiVector" || @@ -265,8 +271,7 @@ bool convertObject( const MeshPointer& meshPointer, parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // { Containers::MultiVector< Dimension, Value, Devices::Host, Index > multiVector; - if( ! multiVector. load( inputFileName ) ) - return false; + multiVector. load( inputFileName ); typedef Meshes::Grid< Dimension, Real, Devices::Host, Index > GridType; typedef typename GridType::PointType PointType; typedef typename GridType::CoordinatesType CoordinatesType; @@ -274,7 +279,7 @@ bool convertObject( const MeshPointer& meshPointer, // grid. setDomain( PointType( 0.0 ), PointType( 1.0 ) ); // grid. setDimensions( CoordinatesType( multiVector. getDimensions() ) ); // if( ! grid. write( multiVector, outputFileName, outputFormat ) ) - return false; +// return false; } return true; } diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index 601d30921..7e1c833f2 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.h @@ -505,10 +505,10 @@ TYPED_TEST( ArrayTest, SaveAndLoad ) v.setElement( i, 3.14147 ); File file; file.open( "test-file.tnl", File::Mode::Out ); - EXPECT_TRUE( v.save( file ) ); + v.save( file ); file.close(); file.open( "test-file.tnl", File::Mode::In ); - EXPECT_TRUE( u.load( file ) ); + u.load( file ); EXPECT_EQ( u, v ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); @@ -524,23 +524,32 @@ TYPED_TEST( ArrayTest, boundLoad ) v.setElement( i, 3.14147 ); File file; file.open( "test-file.tnl", File::Mode::Out ); - EXPECT_TRUE( v.save( file ) ); + v.save( file ); file.close(); w.setSize( 100 ); u.bind( w ); file.open( "test-file.tnl", File::Mode::In ); - EXPECT_TRUE( u.boundLoad( file ) ); + u.boundLoad( file ); EXPECT_EQ( u, v ); EXPECT_EQ( u.getData(), w.getData() ); u.setSize( 50 ); file.open( "test-file.tnl", File::Mode::In ); - EXPECT_FALSE( u.boundLoad( file ) ); + bool catched( false ); + try + { + u.boundLoad( file ); + } + catch(...) + { + catched = true; + } + EXPECT_TRUE( catched ); u.reset(); file.open( "test-file.tnl", File::Mode::In ); - EXPECT_TRUE( u.boundLoad( file ) ); + u.boundLoad( file ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); } diff --git a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp index 120a2451f..c5490cdf4 100644 --- a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp +++ b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp @@ -126,8 +126,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 3e29dadf0..3602f53ca 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/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h index c70d165e5..055faa812 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h +++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h @@ -103,16 +103,12 @@ class TestDistributedVectorFieldMPIIO{ File file; file.open( FileName, File::Mode::In ); - bool loaded=loadvct.boundLoad(file); - file.close(); - if(!loaded) - EXPECT_TRUE(loaded)<< "Chyba načtení souboru" < 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 436a13e0e..21b12f958 100644 --- a/src/UnitTests/ObjectTest.cpp +++ b/src/UnitTests/ObjectTest.cpp @@ -25,10 +25,10 @@ TEST( ObjectTest, SaveAndLoadTest ) Object testObject; File file; file.open( "test-file.tnl", File::Mode::Out ); - ASSERT_TRUE( testObject.save( file ) ); + testObject.save( file ); file.close(); file.open( "test-file.tnl", File::Mode::In ); - ASSERT_TRUE( testObject.load( file ) ); + testObject.load( file ); EXPECT_EQ( std::remove( "test-file.tnl" ), 0 ); } -- GitLab From a36d42a24bbe61474848e408e8138d15b7d18dce Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Sat, 9 Mar 2019 22:06:42 +0100 Subject: [PATCH 31/72] Fixed Array::boundLoad. --- src/TNL/Containers/Array_impl.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h index 39a6fa08f..e93b6eac3 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array_impl.h @@ -509,7 +509,10 @@ boundLoad( File& file ) if( _size < 0 ) throw Exceptions::ArrayWrongSize( _size, "Positive is expected," ); if( this->getSize() != 0 ) - throw Exceptions::ArrayWrongSize( _size, convertToString( this->getSize() ) + "is expected." ); + { + if( this->getSize() != _size ) + throw Exceptions::ArrayWrongSize( _size, convertToString( this->getSize() ) + " is expected." ); + } else setSize( _size ); if( _size ) Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ); -- GitLab From 3ade215f5be77488bd934cd8b045ddcb773309fa Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Sat, 9 Mar 2019 22:07:07 +0100 Subject: [PATCH 32/72] Fixed const_cast in MPI calls. --- .../Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h | 4 ++-- .../Meshes/DistributedMeshes/DistributedGridIO_VectorField.h | 2 +- src/TNL/String.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h index d72610628..b9d3c5e24 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h @@ -296,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); @@ -310,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 diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h index 3353e8b9e..1ba844071 100644 --- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h +++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h @@ -106,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); diff --git a/src/TNL/String.hpp b/src/TNL/String.hpp index ed0a54fb9..4cdeee7ac 100644 --- a/src/TNL/String.hpp +++ b/src/TNL/String.hpp @@ -254,7 +254,7 @@ inline void mpiSend( const String& str, int target, int tag, MPI_Comm mpi_comm ) { int size = str.getSize(); MPI_Send( &size, 1, MPI_INT, target, tag, mpi_comm ); - MPI_Send( str.getString(), str.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 mpiReceive( String& str, int source, int tag, MPI_Comm mpi_comm ) -- GitLab From 649bf42b7918e84c8636449024d22a0b702ad4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 10 Mar 2019 21:00:54 +0100 Subject: [PATCH 33/72] Updating the File documentation. --- src/TNL/File.h | 51 +++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/TNL/File.h b/src/TNL/File.h index f79b24401..882d1c725 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -21,7 +21,7 @@ namespace TNL { /** - * \brief This class serves for binary IO. It allows to do IO even for data allocated on GPU + * \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 @@ -57,7 +57,7 @@ class File * Throws \ref std::ios_base::failure on failure. * * \param fileName String which indicates file name. - * \param mode Indicates in what mode the will be opened - see. \ref File::Mode. + * \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 ) ) ); @@ -78,34 +78,43 @@ class File } /** - * \brief Method for reading data with given \e Type from the file. + * \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. + * \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. - * \tparam Device Device where the data are stored after reading. For example \ref Devices::Host or \ref Devices::Cuda. - * \tparam SourceType Type of index by which the elements are indexed. + * \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 the user wants to get (read) from given file. + * \param elements number of elements to be loaded from the file. */ template< typename Type, typename SourceType = Type, typename Device = Devices::Host > void load( Type* buffer, std::streamsize elements = 1 ); /** - * \brief Method that can write particular data type from CPU into given file. (Function that writes particular elements into given file.) + * \brief Method for saving data to the file. * - * Returns \e true when the elements are successfully written into given file. Otherwise returns \e false. + * 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. - * \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. + * \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. */ template< typename Type, typename TargetType = Type, typename Device = Devices::Host > void save( const Type* buffer, std::streamsize elements = 1 ); @@ -156,12 +165,12 @@ class File 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. - */ + //// + // 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; }; -- GitLab From 6f411470cf3cf28ed8db730245ba30065f915619 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 11 Mar 2019 12:35:33 +0100 Subject: [PATCH 34/72] Fixed exception catching and a typo in File.hpp. --- src/TNL/File.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp index ec06e51e8..df1181af7 100644 --- a/src/TNL/File.hpp +++ b/src/TNL/File.hpp @@ -45,14 +45,14 @@ inline void File::open( const String& fileName, Mode mode ) { file.open( fileName.getString(), ios_mode ); } - catch( std::ios_base::failure ) + 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 writting."; + msg << " for writing."; throw std::ios_base::failure( msg.str() ); } @@ -68,7 +68,7 @@ inline void File::close() { file.close(); } - catch( std::ios_base::failure ) + catch( std::ios_base::failure& ) { std::stringstream msg; msg << "Unable to close file " << fileName << "."; -- GitLab From ab81368e865f1d2289d864cc1d562eccc90d2b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Fri, 15 Mar 2019 21:00:04 +0100 Subject: [PATCH 35/72] Added and updated File examples. --- src/Examples/CMakeLists.txt | 19 +++++++++ src/Examples/FileExampleCuda.cpp | 1 + src/Examples/FileExampleCuda.cu | 57 +++++++++++++++++++++++++ src/Examples/FileExampleSaveAndLoad.cpp | 48 +++++++++++++++++++++ src/Examples/StringExample.cpp | 8 ++-- src/TNL/File.h | 16 +++++++ 6 files changed, 145 insertions(+), 4 deletions(-) create mode 120000 src/Examples/FileExampleCuda.cpp create mode 100644 src/Examples/FileExampleCuda.cu create mode 100644 src/Examples/FileExampleSaveAndLoad.cpp diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 9030d26ef..00548de42 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -21,7 +21,19 @@ add_subdirectory( flow-vl ) 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( ListExample ListExample.cpp ) ADD_EXECUTABLE( LoggerExample LoggerExample.cpp ) ADD_EXECUTABLE( MathExample MathExample.cpp ) @@ -61,6 +73,8 @@ ADD_CUSTOM_COMMAND( COMMAND TimerExampleLogger > TimerExampleLogger.out OUTPUT T ADD_EXECUTABLE( VectorExample VectorExample.cpp ) ADD_CUSTOM_TARGET( run ALL DEPENDS + FileExample.out + FileExampleSaveAndLoad.out ObjectExample_getType.out ParseObjectTypeExample.out StringExample.out @@ -70,3 +84,8 @@ ADD_CUSTOM_TARGET( run ALL DEPENDS StringExampleStrip.out TimerExample.out TimerExampleLogger.out ) + +if( BUILD_CUDA ) + ADD_CUSTOM_TARGET( run-cuda ALL DEPENDS + FileExampleCuda.out ) +ENDIF() \ No newline at end of file diff --git a/src/Examples/FileExampleCuda.cpp b/src/Examples/FileExampleCuda.cpp new file mode 120000 index 000000000..53d150113 --- /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 000000000..cd7c28399 --- /dev/null +++ b/src/Examples/FileExampleCuda.cu @@ -0,0 +1,57 @@ +#include +#include +#include + +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 000000000..59718ed3f --- /dev/null +++ b/src/Examples/FileExampleSaveAndLoad.cpp @@ -0,0 +1,48 @@ +#include +#include + +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/StringExample.cpp b/src/Examples/StringExample.cpp index a8272ac06..19ed24bd1 100644 --- a/src/Examples/StringExample.cpp +++ b/src/Examples/StringExample.cpp @@ -46,12 +46,12 @@ int main( int argc, char* argv[] ) if( string1 ) cout << "string1 is not empty" << endl; - /*File myFile; - myFile.open( "string_save.out", File::out ); + File myFile; + myFile.open( "string_save.out", File::Mode::Out ); myFile << string1; myFile.close(); - myFile.open( "string_save.out", File::in ); + myFile.open( "string_save.out", File::Mode::In ); myFile >> string3; - cout << "string 3 after loading = " << string3 << endl;*/ + cout << "string 3 after loading = " << string3 << endl; } diff --git a/src/TNL/File.h b/src/TNL/File.h index 882d1c725..d1c6c62a7 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -94,6 +94,19 @@ class 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 ); @@ -115,6 +128,8 @@ class File * \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 ); @@ -179,6 +194,7 @@ class File * * 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 ); -- GitLab From a7b6d58874c42f62fcd97708005d0969f51b7829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Fri, 15 Mar 2019 21:08:20 +0100 Subject: [PATCH 36/72] Editing of documentation in FileName.h. --- src/TNL/FileName.h | 84 +++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/src/TNL/FileName.h b/src/TNL/FileName.h index 2c860770d..dabcd2d53 100644 --- a/src/TNL/FileName.h +++ b/src/TNL/FileName.h @@ -18,63 +18,77 @@ 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 Class for the construction of file names from multiple parts. + * + * Merges base name, index number and extension to create the full name of a file. + */ class FileName { public: - /// \brief Basic constructor. - /// - /// Constructs an empty filename object. + /*** + * \brief Basic constructor. + * + * Constructs an empty filename object. + */ FileName(); - + FileName( const String& fileNameBase ); - + 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 base name of given file. + * + * Sets \e fileNameBase as the base name of given file. + * @param fileNameBase String that specifies new name of file. + */ 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 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. + */ 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). + /*** + * \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. + /*** + * \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 ); - + 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. + + /*** + * \brief Creates appropriate name for given file. + * + * Creates particular file name using \e fileNameBase, \e digitsCount, + * \e index and \e extension. + */ String getFileName(); protected: - + String fileNameBase, extension, distributedSystemNodeId; - + int index, digitsCount; }; -- GitLab From 4d322fa4411ad4e9ffc52b47e53d31dda0f4ccb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sat, 16 Mar 2019 10:10:54 +0100 Subject: [PATCH 37/72] Revision of FileName. --- src/Examples/CMakeLists.txt | 12 ++ src/Examples/FileNameExample.cpp | 37 +++++ ...xampleDistributedSystemNodeCoordinates.cpp | 34 +++++ ...FileNameExampleDistributedSystemNodeId.cpp | 31 ++++ src/TNL/FileName.h | 136 +++++++++++++----- src/TNL/FileName.hpp | 26 ++-- src/Tools/tnl-diff.h | 10 +- src/Tools/tnl-image-converter.cpp | 24 +--- src/Tools/tnl-init.h | 2 +- src/Tools/tnl-view.h | 3 +- 10 files changed, 240 insertions(+), 75 deletions(-) create mode 100644 src/Examples/FileNameExample.cpp create mode 100644 src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp create mode 100644 src/Examples/FileNameExampleDistributedSystemNodeId.cpp diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt index 00548de42..3d2c81d72 100644 --- a/src/Examples/CMakeLists.txt +++ b/src/Examples/CMakeLists.txt @@ -33,6 +33,15 @@ 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 ) @@ -75,6 +84,9 @@ ADD_EXECUTABLE( VectorExample VectorExample.cpp ) ADD_CUSTOM_TARGET( run ALL DEPENDS FileExample.out FileExampleSaveAndLoad.out + FileNameExample.out + FileNameExampleDistributedSystemNodeCoordinates.out + FileNameExampleDistributedSystemNodeId.out ObjectExample_getType.out ParseObjectTypeExample.out StringExample.out diff --git a/src/Examples/FileNameExample.cpp b/src/Examples/FileNameExample.cpp new file mode 100644 index 000000000..32425377a --- /dev/null +++ b/src/Examples/FileNameExample.cpp @@ -0,0 +1,37 @@ +#include +#include + + +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 000000000..fc9a3626e --- /dev/null +++ b/src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp @@ -0,0 +1,34 @@ +#include +#include +#include + +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 000000000..d704c96b3 --- /dev/null +++ b/src/Examples/FileNameExampleDistributedSystemNodeId.cpp @@ -0,0 +1,31 @@ +#include +#include + +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/TNL/FileName.h b/src/TNL/FileName.h index dabcd2d53..0f4950ae8 100644 --- a/src/TNL/FileName.h +++ b/src/TNL/FileName.h @@ -14,74 +14,117 @@ namespace TNL { -String getFileExtension( const String fileName ); - -void removeFileExtension( String& file_name ); - -/*** - * \brief Class for the construction of file names from multiple parts. +/** + * \brief Helper class for the construction of file names based on name, index and extension. * - * Merges base name, index number and extension to create the full name of a file. + * 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. + * 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. + /** + * \brief Sets the file name base. * - * Sets \e fileNameBase as the base name of given file. - * @param fileNameBase String that specifies new name of file. + * @param fileNameBase String that specifies the new file name base. */ void setFileNameBase( const String& fileNameBase ); - /*** - * \brief Sets the extension of given file. + /** + * \brief Sets the file name extension. * - * 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. + * @param extension A String that specifies the new extension of file without dot. */ void setExtension( const String& extension ); - /*** - * \brief Sets index for given file. + /** + * \brief Sets index of the file name. * - * 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). + * @param index Index of the file name. */ - void setIndex( const int index ); + void setIndex( const size_t index ); - /*** - * \brief Sets number of digits for index of given file. + /** + * \brief Sets number of digits for index of the file name. * - * @param digitsCount Integer - number of digits. + * @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 + * */ - void setDigitsCount( const int digitsCount ); - - void setDistributedSystemNodeId( int nodeId ); - template< typename Coordinates > - void setDistributedSystemNodeId( const Coordinates& nodeId ); + void setDistributedSystemNodeCoordinates( const Coordinates& nodeId ); + + /** + * \brief Resets the distributed system node ID. + */ + void resetDistributedSystemNodeId(); - /*** - * \brief Creates appropriate name for given file. + /** + * \brief Returns complete file name. * - * Creates particular file name using \e fileNameBase, \e digitsCount, - * \e index and \e extension. + * @return String with the complete file name. */ String getFileName(); @@ -89,9 +132,26 @@ class FileName 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 diff --git a/src/TNL/FileName.hpp b/src/TNL/FileName.hpp index 4cda1fda2..5fdbf1b3f 100644 --- a/src/TNL/FileName.hpp +++ b/src/TNL/FileName.hpp @@ -17,6 +17,8 @@ #include #include +#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/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index d1b8cac24..364dbd294 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -304,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; @@ -419,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; diff --git a/src/Tools/tnl-image-converter.cpp b/src/Tools/tnl-image-converter.cpp index 51efacf14..8a7fccf50 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(); @@ -176,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" ) @@ -190,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(); @@ -200,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.h b/src/Tools/tnl-init.h index 36abb47dd..a393a7a7c 100644 --- a/src/Tools/tnl-init.h +++ b/src/Tools/tnl-init.h @@ -105,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() ); diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h index 55d0fa60c..cfd958aea 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -30,8 +30,7 @@ bool getOutputFileName( const String& inputFileName, const String& outputFormat, String& outputFileName ) { - outputFileName = inputFileName; - removeFileExtension( outputFileName ); + outputFileName = removeFileNameExtension( inputFileName ); if( outputFormat == "gnuplot" ) { outputFileName += ".gplt"; -- GitLab From c2f017049df128de9f03363c81beb6e6f51b5fba Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Sun, 17 Mar 2019 11:39:06 +0100 Subject: [PATCH 38/72] [WIP] Adding new constructors to Array. --- src/TNL/Containers/Array.h | 52 +++++++++++++++++++---- src/TNL/Containers/Array_impl.h | 75 ++++++++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 14 deletions(-) diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 2834ec52f..155364218 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -79,6 +79,24 @@ class Array : public Object const IndexType& begin = 0, const IndexType& size = 0 ); + /** + * + * @param list + */ + Array( const std::initializer_list< Value >& list ); + + /** + * + * @param list + */ + Array( const std::list< Value >& list ); + + /** + * + * @param vector + */ + Array( const std::vector< Value >& vector ); + /** \brief Returns type of array Value, Device type and the type of Index. */ static String getType(); @@ -242,27 +260,45 @@ class Array : public Object 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, + const Index begin = 0, + const Index end = this->getSize() ); + + /** + * \brief Sets the array elements using given lambda function. * * Sets all the array values to \e v. * * \param v Reference to a value. */ - void setValue( const Value& v ); + template< typename Fuction > + void setValues( Functions& f, + const Index begin = 0, + const Index end = this->getSize() ); /** * \brief Checks if there is an element with value \e v in this array. * * \param v Reference to a value. */ - bool containsValue( const Value& v ) const; + bool containsValue( const Value& v, + const Index begin = 0, + const Index end = this->getSize() ) const; /** * \brief Checks if all elements in this array have the same value \e v. * * \param v Reference to a value. */ - bool containsOnlyValue( const Value& v ) const; + bool containsOnlyValue( const Value& v, + const Index begin = 0, + const Index end = this->getSize() ) const; /** * \brief Returns true if non-zero size is set. @@ -308,10 +344,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 +358,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,7 +366,7 @@ 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 > diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h index e93b6eac3..1f0881be5 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array_impl.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +94,45 @@ Array( Array< Value, Device, Index >& array, } } +template< typename Value, + typename Device, + typename Index > +Array< Value, Device, Index >:: +Array( const std::initializer_list< Value >& list ) +: size( 0 ), + data( 0 ), + allocationPointer( 0 ), + referenceCounter( 0 ) +{ + this->setSize( list.size() ); +} + +template< typename Value, + typename Device, + typename Index > +Array< Value, Device, Index >:: +Array( const std::list< Value >& list ) +: size( 0 ), + data( 0 ), + allocationPointer( 0 ), + referenceCounter( 0 ) +{ + this->setSize( list.size() ); +} + +template< typename Value, + typename Device, + typename Index > +Array< Value, Device, Index >:: +Array( const std::vector< Value >& vector ) +: size( 0 ), + data( 0 ), + allocationPointer( 0 ), + referenceCounter( 0 ) +{ + this->setSize( vector.size() ); +} + template< typename Value, typename Device, typename Index > @@ -433,10 +473,29 @@ bool Array< Value, Device, Index >::operator != ( const ArrayT& array ) const template< typename Value, typename Device, typename Index > -void Array< Value, Device, Index >::setValue( const Value& e ) +void Array< Value, Device, Index >::setValue( const Value& e, + const Index begin, + const 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() ); + Algorithms::ArrayOperations< Device >::setMemory( &this->getData()[ begin ], e, end - begin ); +} + +template< typename Value, + typename Device, + typename Index > + template< typename Function > +void Array< Value, Device, Index >::setValues( Function& f, + const Index begin, + const Index end ) +{ + TNL_ASSERT_TRUE( this->getData(), "Attempted to set a value of an empty array." ); + auto evaluate = [=] __cuda_callable__ ( Index i ) + { + this->data[ i ] = f( i ); + } + + ParallelFor< DeviceType >( begin, end, evaluate ); } template< typename Value, @@ -444,9 +503,11 @@ template< typename Value, typename Index > bool Array< Value, Device, Index >:: -containsValue( const Value& v ) const +containsValue( const Value& v, + const Index begin, + const Index end ) const { - return Algorithms::ArrayOperations< Device >::containsValue( this->data, this->size, v ); + return Algorithms::ArrayOperations< Device >::containsValue( &this->getData()[ begin ], end - begin, v ); } template< typename Value, @@ -454,9 +515,11 @@ template< typename Value, typename Index > bool Array< Value, Device, Index >:: -containsOnlyValue( const Value& v ) const +containsOnlyValue( const Value& v, + const Index begin, + const Index end ) const { - return Algorithms::ArrayOperations< Device >::containsOnlyValue( this->data, this->size, v ); + return Algorithms::ArrayOperations< Device >::containsOnlyValue( &this->getData()[ begin ], end - begin, v ); } template< typename Value, -- GitLab From 402faa22fac405c4cd47e77001d6e9b3a350ed0d Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Sun, 17 Mar 2019 14:47:23 +0100 Subject: [PATCH 39/72] [WIP] Implementing new Array constructors. --- .../Containers/Algorithms/ArrayOperations.h | 11 ++++-- ...onsCuda_impl.h => ArrayOperationsCuda.hpp} | 21 +++++++++++ ...onsHost_impl.h => ArrayOperationsHost.hpp} | 12 +++++++ ...tionsMIC_impl.h => ArrayOperationsMIC.hpp} | 9 +++++ src/TNL/Containers/Array.h | 36 +++++++++++++------ .../Containers/{Array_impl.h => Array.hpp} | 16 +++++++-- src/TNL/Devices/Cuda.h | 9 +++++ src/TNL/File.h | 2 +- 8 files changed, 98 insertions(+), 18 deletions(-) rename src/TNL/Containers/Algorithms/{ArrayOperationsCuda_impl.h => ArrayOperationsCuda.hpp} (92%) rename src/TNL/Containers/Algorithms/{ArrayOperationsHost_impl.h => ArrayOperationsHost.hpp} (93%) rename src/TNL/Containers/Algorithms/{ArrayOperationsMIC_impl.h => ArrayOperationsMIC.hpp} (97%) rename src/TNL/Containers/{Array_impl.h => Array.hpp} (95%) diff --git a/src/TNL/Containers/Algorithms/ArrayOperations.h b/src/TNL/Containers/Algorithms/ArrayOperations.h index 47050d32f..364f1506d 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperations.h +++ b/src/TNL/Containers/Algorithms/ArrayOperations.h @@ -53,6 +53,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 > @@ -260,6 +265,6 @@ class ArrayOperations< Devices::Host, Devices::MIC > } // namespace Containers } // namespace TNL -#include -#include -#include +#include +#include +#include diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp similarity index 92% rename from src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h rename to src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp index 34946628a..d7d2b6f6f 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h +++ b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp @@ -171,6 +171,27 @@ copyMemory( DestinationElement* destination, #endif } +template< typename DestinationElement, + typename SourceElement > +ArrayOperations< Devices::Cuda >:: +void copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ) +{ + const auto size = source.size(); + const std::streamsize copy_buffer_size = std::min( Devices::Cuda::TransferBufferSize / (std::streamsize) sizeof(SourceType), size ); + using BaseType = typename std::remove_cv< SourceType >::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[ copiedElements ++ ] = static_cast< DestinationElement >( * it ++ ); + ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory( destination, copy_buffer, copySize ); + } +} + template< typename Element1, typename Element2, typename Index > 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 18fe544ea..35c13e492 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h +++ b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp @@ -100,6 +100,18 @@ copyMemory( DestinationElement* destination, destination[ i ] = ( DestinationElement ) source[ i ]; } +template< typename DestinationElement, + typename SourceElement > +ArrayOperations< Devices::Host >:: +void copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ) +{ + size_t i = 0; + for( SourceElement& e : source ) + destination[ i ++ ] = static_cast< DesitnationElement >( 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 1823d8077..21c3988fd 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h +++ b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp @@ -139,6 +139,15 @@ copyMemory( DestinationElement* destination, #endif } +template< typename DestinationElement, + typename SourceElement > +ArrayOperations< Devices::MIC >:: +void 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 155364218..bdfa5b173 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -80,33 +80,47 @@ class Array : public Object const IndexType& size = 0 ); /** + * \brief Initialize the array from initializer list, i.e. { ... } * - * @param list + * @param list Initializer list. */ - Array( const std::initializer_list< Value >& list ); + template< typename InValue > + Array( const std::initializer_list< InValue >& list ); /** + * \brief Initialize the array from std::list. * - * @param list + * @param list Input STL list. */ - Array( const std::list< Value >& list ); + template< typename InValue > + Array( const std::list< InValue >& list ); /** + * \brief Initialize the array from std::vector. * - * @param vector + * @param vector Input STL vector. */ - Array( const std::vector< Value >& vector ); + template< typename InValue > + Array( const std::vector< InValue >& vector ); - /** \brief Returns type of array Value, Device type and the type of Index. */ + /** + * \brief Returns type of array Value, Device type and the type of Index. + */ static String getType(); - /** \brief Returns type of array Value, Device type and the type of Index. */ + /** + * \brief Returns type of array Value, Device type and the type of Index. + */ virtual String getTypeVirtual() const; - /** \brief Returns (host) type of array Value, Device type and the type of Index. */ + /** + * \brief Returns (host) type of array Value, Device type and the type of Index. + */ static String getSerializationType(); - /** \brief Returns (host) type of array Value, Device type and the type of Index. */ + /** + * \brief Returns (host) type of array Value, Device type and the type of Index. + */ virtual String getSerializationTypeVirtual() const; /** @@ -375,4 +389,4 @@ std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index } // namespace Containers } // namespace TNL -#include +#include diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array.hpp similarity index 95% rename from src/TNL/Containers/Array_impl.h rename to src/TNL/Containers/Array.hpp index 1f0881be5..105f632bd 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array.hpp @@ -97,40 +97,50 @@ Array( Array< Value, Device, Index >& array, template< typename Value, typename Device, typename Index > + template< typename InValue > Array< Value, Device, Index >:: -Array( const std::initializer_list< Value >& list ) +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 >::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< Value >& list ) +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< Value >& vector ) +Array( const std::vector< InValue >& vector ) : size( 0 ), data( 0 ), allocationPointer( 0 ), referenceCounter( 0 ) { this->setSize( vector.size() ); + Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), vector.data(), vector.size() ); } template< typename Value, diff --git a/src/TNL/Devices/Cuda.h b/src/TNL/Devices/Cuda.h index 4a802a021..626d23bf1 100644 --- a/src/TNL/Devices/Cuda.h +++ b/src/TNL/Devices/Cuda.h @@ -172,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::streamsize TransferBufferSize = 5 * 2<<20; + + protected: static inline Pointers::SmartPointersRegister& getSmartPointersRegister(); diff --git a/src/TNL/File.h b/src/TNL/File.h index d1c6c62a7..120d7342d 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -179,7 +179,7 @@ class File 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. -- GitLab From cd3a19c859e6779f97e90655b7c56e420e60dcbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 24 Mar 2019 18:29:10 +0100 Subject: [PATCH 40/72] Array revision - assignement operator modified to accept arrays and non-array types. --- src/Examples/ArrayExample.cpp | 27 ---- src/Examples/CMakeLists.txt | 15 +- src/Examples/Containers/ArrayExample.cpp | 75 +++++++++ src/Examples/Containers/ArrayExample.cu | 1 + src/Examples/Containers/CMakeLists.txt | 15 ++ .../Containers/Algorithms/ArrayOperations.h | 11 ++ .../Algorithms/ArrayOperationsCuda.hpp | 9 +- .../Algorithms/ArrayOperationsHost.hpp | 9 +- .../Algorithms/ArrayOperationsMIC.hpp | 3 +- src/TNL/Containers/Array.h | 115 +++++++++++-- src/TNL/Containers/Array.hpp | 153 +++++++++++++++--- src/TNL/Containers/ArrayView.h | 11 ++ src/TNL/Containers/DistributedArray.h | 10 ++ src/TNL/Containers/DistributedArrayView.h | 10 ++ src/TNL/Containers/DistributedVector.h | 12 +- src/TNL/Containers/DistributedVectorView.h | 10 ++ .../Multimaps/EllpackIndexMultimapValues.h | 11 ++ .../StaticEllpackIndexMultimapValues.h | 12 ++ src/TNL/Containers/Vector.h | 10 ++ src/TNL/Containers/VectorView.h | 10 ++ src/TNL/Devices/Cuda.h | 2 +- src/TNL/Devices/CudaCallable.h | 6 + src/TNL/TypeTraits.h | 21 +++ src/UnitTests/Containers/ArrayTest.h | 56 ++++++- .../Containers/DistributedArrayTest.h | 2 +- .../Containers/Multimaps/MultimapTest.cpp | 3 + 26 files changed, 526 insertions(+), 93 deletions(-) delete mode 100644 src/Examples/ArrayExample.cpp create mode 100644 src/Examples/Containers/ArrayExample.cpp create mode 120000 src/Examples/Containers/ArrayExample.cu create mode 100644 src/Examples/Containers/CMakeLists.txt create mode 100644 src/TNL/TypeTraits.h diff --git a/src/Examples/ArrayExample.cpp b/src/Examples/ArrayExample.cpp deleted file mode 100644 index 2cc9c54e5..000000000 --- a/src/Examples/ArrayExample.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -using namespace TNL; -using namespace std; - -int main() -{ - Containers::Array 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 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 3d2c81d72..2d46b2446 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,15 +12,6 @@ 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 ) @@ -81,7 +74,7 @@ ADD_CUSTOM_COMMAND( COMMAND TimerExampleLogger > TimerExampleLogger.out OUTPUT T ADD_EXECUTABLE( VectorExample VectorExample.cpp ) -ADD_CUSTOM_TARGET( run ALL DEPENDS +ADD_CUSTOM_TARGET( RunExamples ALL DEPENDS FileExample.out FileExampleSaveAndLoad.out FileNameExample.out @@ -98,6 +91,6 @@ ADD_CUSTOM_TARGET( run ALL DEPENDS TimerExampleLogger.out ) if( BUILD_CUDA ) - ADD_CUSTOM_TARGET( run-cuda ALL DEPENDS + 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 000000000..f9a6dd58a --- /dev/null +++ b/src/Examples/Containers/ArrayExample.cpp @@ -0,0 +1,75 @@ +#include +#include + +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 ); + + /*** + * You may also assign value to all array elements + */ + a2 = 0; + + /*** + * 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; + + /*** + * More efficient way of array elements manipulation is with the lambda functions + */ + ArrayType a3( size ); + 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 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; + 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 000000000..6cee614fe --- /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/CMakeLists.txt b/src/Examples/Containers/CMakeLists.txt new file mode 100644 index 000000000..7c5b616a4 --- /dev/null +++ b/src/Examples/Containers/CMakeLists.txt @@ -0,0 +1,15 @@ +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 ) +ADD_CUSTOM_TARGET( RunContainersExamples-cuda ALL DEPENDS + ArrayExampleCuda.out ) +ELSE() +ADD_CUSTOM_TARGET( RunContainersExamples ALL DEPENDS + ArrayExample.out ) +ENDIF() diff --git a/src/TNL/Containers/Algorithms/ArrayOperations.h b/src/TNL/Containers/Algorithms/ArrayOperations.h index 364f1506d..a6acc816e 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperations.h +++ b/src/TNL/Containers/Algorithms/ArrayOperations.h @@ -10,6 +10,7 @@ #pragma once +#include #include #include #include @@ -109,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 > @@ -201,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 > diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp index d7d2b6f6f..d56764313 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp +++ b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp @@ -173,13 +173,14 @@ copyMemory( DestinationElement* destination, template< typename DestinationElement, typename SourceElement > +void ArrayOperations< Devices::Cuda >:: -void copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ) +copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ) { const auto size = source.size(); - const std::streamsize copy_buffer_size = std::min( Devices::Cuda::TransferBufferSize / (std::streamsize) sizeof(SourceType), size ); - using BaseType = typename std::remove_cv< SourceType >::type; + 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(); diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp index 35c13e492..ff24b237d 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp +++ b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp @@ -102,13 +102,14 @@ copyMemory( DestinationElement* destination, template< typename DestinationElement, typename SourceElement > +void ArrayOperations< Devices::Host >:: -void copySTLList( DestinationElement* destination, - const std::list< SourceElement >& source ) +copySTLList( DestinationElement* destination, + const std::list< SourceElement >& source ) { size_t i = 0; - for( SourceElement& e : source ) - destination[ i ++ ] = static_cast< DesitnationElement >( e ); + for( const SourceElement& e : source ) + destination[ i ++ ] = static_cast< DestinationElement >( e ); } diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp index 21c3988fd..b41e09f0b 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp +++ b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp @@ -141,8 +141,9 @@ copyMemory( DestinationElement* destination, template< typename DestinationElement, typename SourceElement > +void ArrayOperations< Devices::MIC >:: -void copySTLList( DestinationElement* destination, +copySTLList( DestinationElement* destination, const std::list< SourceElement >& source ) { TNL_ASSERT( false, std::cerr << "TODO" ); diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index bdfa5b173..bdeff1f84 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -10,8 +10,11 @@ #pragma once +#include +#include #include #include +#include #include namespace TNL { @@ -23,12 +26,33 @@ 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 Type of array values. - * \tparam Device Device type. - * \tparam Index Type of index. + * \tparam Device Device type - some of \ref Devices::Host and \ref Devices::Cuda. + * \tparam Index Type for indexing. * + * 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 */ @@ -39,11 +63,12 @@ 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 ThisType = Containers::Array< ValueType, DeviceType, IndexType >; + using HostType = Containers::Array< Value, Devices::Host, Index >; + using CudaType = Containers::Array< Value, Devices::Cuda, Index >; /** \brief Basic constructor. * @@ -67,6 +92,13 @@ class Array : public Object Array( Value* data, const IndexType& size ); + /** + * + * @param + */ + // Deep copy does not work because of EllpackIndexMultiMap - TODO: Fix it + //Array( const Array& ); + /** * \brief Copy constructor. * @@ -79,6 +111,8 @@ class Array : public Object const IndexType& begin = 0, const IndexType& size = 0 ); + Array( Array&& ); + /** * \brief Initialize the array from initializer list, i.e. { ... } * @@ -246,6 +280,13 @@ class Array : public Object */ Array& operator = ( const Array& array ); + /** + * \brief Assigns \e array to this array, replacing its current contents. + * + * \param array Reference to an array. + */ + Array& operator = ( Array&& array ); + /** * \brief Assigns \e array to this array, replacing its current contents. * @@ -255,6 +296,22 @@ class Array : public Object template< typename ArrayT > Array& operator = ( const ArrayT& array ); + /** + * + * @param list + * @return + */ + template< typename InValue > + Array& operator = ( const std::list< InValue >& list ); + + /** + * + * @param vector + * @return + */ + template< typename InValue > + Array& operator = ( const std::vector< InValue >& vector ); + /** * \brief This function checks whether this array is equal to \e array. * @@ -282,7 +339,7 @@ class Array : public Object */ void setValue( const Value& v, const Index begin = 0, - const Index end = this->getSize() ); + Index end = -1 ); /** * \brief Sets the array elements using given lambda function. @@ -291,10 +348,10 @@ class Array : public Object * * \param v Reference to a value. */ - template< typename Fuction > - void setValues( Functions& f, - const Index begin = 0, - const Index end = this->getSize() ); + 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 in this array. @@ -303,7 +360,7 @@ class Array : public Object */ bool containsValue( const Value& v, const Index begin = 0, - const Index end = this->getSize() ) const; + Index end = -1 ) const; /** * \brief Checks if all elements in this array have the same value \e v. @@ -312,7 +369,7 @@ class Array : public Object */ bool containsOnlyValue( const Value& v, const Index begin = 0, - const Index end = this->getSize() ) const; + Index end = -1 ) const; /** * \brief Returns true if non-zero size is set. @@ -383,10 +440,38 @@ class Array : public Object mutable int* referenceCounter = nullptr; }; +template< typename Array, + typename Data, + bool isArray = TNL::isArray< Data >::value > +struct ArrayAssignment {}; + +template< typename Array, + typename Data > +struct ArrayAssignment< Array, Data, true > +{ + static void assign( Array& a, const Data& d ); +}; + +template< typename Array, + typename Data > +struct ArrayAssignment< Array, Data, false > +{ + static void assign( Array& a, const Data& d ); +}; + template< typename Value, typename Device, typename Index > std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index >& v ); } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::Array< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 105f632bd..1273f5834 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -62,6 +62,21 @@ 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 ) +{ + // Deep copy does not work because of EllpackIndexMultiMap - TODO: Fix it + this->setSize( array.getSize() ); + Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), array.getData(), array.getSize() ); +}*/ + template< typename Value, typename Device, typename Index > @@ -94,6 +109,23 @@ 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 > @@ -437,22 +469,60 @@ operator = ( const Array< Value, Device, Index >& array ) 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() ); + 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 T > +Array< Value, Device, Index >& +Array< Value, Device, Index >:: +operator = ( const T& data ) +{ + ArrayAssignment< ThisType, 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 ) +{ + if( this->getSize() != list.size() ) + 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< Value, Device, Index >:: +operator = ( const std::vector< InValue >& vector ) +{ + if( this->getSize() != vector.size() ) + this->setSize( vector.size() ); + Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), vector.data(), vector.size() ); +} + template< typename Value, typename Device, typename Index > @@ -483,11 +553,13 @@ bool Array< Value, Device, Index >::operator != ( const ArrayT& array ) const 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, - const Index end ) + Index end ) { TNL_ASSERT_TRUE( this->getData(), "Attempted to set a value of an empty array." ); + if( end == -1 ) + end = this->getSize(); Algorithms::ArrayOperations< Device >::setMemory( &this->getData()[ begin ], e, end - begin ); } @@ -495,17 +567,22 @@ template< typename Value, typename Device, typename Index > template< typename Function > -void Array< Value, Device, Index >::setValues( Function& f, - const Index begin, - const Index end ) +void Array< 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." ); - auto evaluate = [=] __cuda_callable__ ( Index i ) + + ValueType* d = this->data; + auto eval = [=] __cuda_callable__ ( Index i ) { - this->data[ i ] = f( i ); - } + d[ i ] = f( i ); + }; + + if( end == -1 ) + end = this->getSize(); - ParallelFor< DeviceType >( begin, end, evaluate ); + ParallelFor< DeviceType >::exec( begin, end, eval ); } template< typename Value, @@ -515,8 +592,12 @@ bool Array< Value, Device, Index >:: containsValue( const Value& v, const Index begin, - const Index end ) const + Index end ) const { + 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 ); } @@ -527,8 +608,12 @@ bool Array< Value, Device, Index >:: containsOnlyValue( const Value& v, const Index begin, - const Index end ) const + Index end ) const { + 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 ); } @@ -591,7 +676,6 @@ boundLoad( File& file ) Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ); } - template< typename Value, typename Device, typename Index > @@ -615,5 +699,30 @@ std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index return str; } +template< typename Array, + typename Data > +void +ArrayAssignment< Array, Data, true >:: +assign( Array& array, const Data& data ) +{ + if( array.getSize() != data.getSize() ) + array.setLike( data ); + if( array.getSize() > 0 ) + Algorithms::ArrayOperations< typename Array::DeviceType, typename Data::DeviceType >:: + copyMemory( array.getData(), + data.getData(), + data.getSize() ); +}; + +template< typename Array, + typename Data > +void +ArrayAssignment< Array, Data, false >:: +assign( Array& array, const Data& data ) +{ + array.setValue( data ); +}; + + } // namespace Containers } // namespace TNL diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 7e98a0d3d..7ddab67a9 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -12,6 +12,7 @@ #pragma once +#include #include #include @@ -154,6 +155,16 @@ template< typename Value, typename Device, typename Index > std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Index >& v ); } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::ArrayView< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + + } // namespace TNL #include diff --git a/src/TNL/Containers/DistributedArray.h b/src/TNL/Containers/DistributedArray.h index d653fc571..036024027 100644 --- a/src/TNL/Containers/DistributedArray.h +++ b/src/TNL/Containers/DistributedArray.h @@ -14,6 +14,7 @@ #include // std::add_const +#include #include #include #include @@ -137,6 +138,15 @@ private: }; } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::DistributedArray< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include "DistributedArray_impl.h" diff --git a/src/TNL/Containers/DistributedArrayView.h b/src/TNL/Containers/DistributedArrayView.h index e9e9e0a48..7e829712b 100644 --- a/src/TNL/Containers/DistributedArrayView.h +++ b/src/TNL/Containers/DistributedArrayView.h @@ -12,6 +12,7 @@ #pragma once +#include #include namespace TNL { @@ -147,6 +148,15 @@ protected: }; } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::DistributedArrayView< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include "DistributedArrayView_impl.h" diff --git a/src/TNL/Containers/DistributedVector.h b/src/TNL/Containers/DistributedVector.h index 794b99f48..1e50f6dd4 100644 --- a/src/TNL/Containers/DistributedVector.h +++ b/src/TNL/Containers/DistributedVector.h @@ -12,7 +12,8 @@ #pragma once -#include "DistributedArray.h" +#include +#include #include namespace TNL { @@ -138,6 +139,15 @@ public: }; } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::DistributedVector< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include "DistributedVector_impl.h" diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h index e36e60e00..b4fbb81ba 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -12,6 +12,7 @@ #pragma once +#include #include #include @@ -136,6 +137,15 @@ public: }; } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::DistributedVectorView< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include "DistributedVectorView_impl.h" diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h index 42addccd1..9aabab480 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h @@ -13,6 +13,7 @@ #include #include +#include #include namespace TNL { @@ -116,6 +117,16 @@ std::ostream& operator << ( std::ostream& str, const EllpackIndexMultimapValues< } // namespace Multimaps } // namespace Containers + +template< typename Index, + typename Device, + typename LocalIndex, + int step > +struct isArray< Containers::Multimaps::EllpackIndexMultimapValues< Index, Device, LocalIndex, step > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h index 1b88f0816..ae937bfbe 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h @@ -13,6 +13,7 @@ #include #include +#include #include namespace TNL { @@ -103,6 +104,17 @@ std::ostream& operator << ( std::ostream& str, const StaticEllpackIndexMultimapV } // namespace Multimaps } // namespace Containers + +template< int ValuesCount, + typename Index, + typename Device, + typename LocalIndex, + int step > +struct isArray< Containers::Multimaps::StaticEllpackIndexMultimapValues< ValuesCount, Index, Device, LocalIndex, step > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h index e116508ba..831134aba 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -10,6 +10,7 @@ #pragma once +#include #include namespace TNL { @@ -280,6 +281,15 @@ class Vector }; } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::Vector< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include diff --git a/src/TNL/Containers/VectorView.h b/src/TNL/Containers/VectorView.h index 6ae0bcb81..2f837c91a 100644 --- a/src/TNL/Containers/VectorView.h +++ b/src/TNL/Containers/VectorView.h @@ -12,6 +12,7 @@ #pragma once +#include #include namespace TNL { @@ -149,6 +150,15 @@ public: }; } // namespace Containers + +template< typename Value, + typename Device, + typename Index > +struct isArray< Containers::VectorView< Value, Device, Index > > +{ + static constexpr bool value = true; +}; + } // namespace TNL #include diff --git a/src/TNL/Devices/Cuda.h b/src/TNL/Devices/Cuda.h index 626d23bf1..783101415 100644 --- a/src/TNL/Devices/Cuda.h +++ b/src/TNL/Devices/Cuda.h @@ -178,7 +178,7 @@ class Cuda // 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; + static constexpr std::size_t TransferBufferSize = 5 * 2<<20; protected: diff --git a/src/TNL/Devices/CudaCallable.h b/src/TNL/Devices/CudaCallable.h index e0a86a3e4..f9311443f 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/TypeTraits.h b/src/TNL/TypeTraits.h new file mode 100644 index 000000000..9b0b3815d --- /dev/null +++ b/src/TNL/TypeTraits.h @@ -0,0 +1,21 @@ +/*************************************************************************** + TypeTraits.h - description + ------------------- + begin : Mar 24, 2019 + copyright : (C) 2019 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +namespace TNL { + + template< typename T > + struct isArray + { + static constexpr bool value = false; + }; + +} // namespace TNL \ No newline at end of file diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index 7e1c833f2..517b990fb 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.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,7 +209,7 @@ 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 ); @@ -450,6 +475,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 @@ -495,6 +524,21 @@ TYPED_TEST( ArrayTest, assignmentOperatorWithDifferentType ) testArrayAssignmentWithDifferentType< ArrayType >(); } +TYPED_TEST( ArrayTest, evaluate ) +{ + using ArrayType = typename TestFixture::ArrayType; + using IndexType = typename ArrayType::IndexType; + ArrayType u( 10 ); + + auto f = [] __cuda_callable__ ( IndexType i ) + { + return 3 * i % 4; + }; + u.evaluate( f ); + for( int i = 0; i < 10; i++ ) + EXPECT_EQ( u.getElement( i ), 3 * i % 4 ); +} + TYPED_TEST( ArrayTest, SaveAndLoad ) { using ArrayType = typename TestFixture::ArrayType; @@ -562,8 +606,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 ) { @@ -572,8 +616,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/DistributedArrayTest.h b/src/UnitTests/Containers/DistributedArrayTest.h index 15ed6214a..169a98b7a 100644 --- a/src/UnitTests/Containers/DistributedArrayTest.h +++ b/src/UnitTests/Containers/DistributedArrayTest.h @@ -188,7 +188,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/Multimaps/MultimapTest.cpp b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp index c5490cdf4..b0ff7cf81 100644 --- a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp +++ b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp @@ -46,16 +46,19 @@ TEST( MultimapTest, TestSettingSizes ) // 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 ); } } -- GitLab From 58797a3a2907d4ba4d70fbc67eaa6aaf5f38790f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Sun, 24 Mar 2019 21:44:06 +0100 Subject: [PATCH 41/72] Writting Array documentation. --- src/TNL/Containers/Array.h | 110 +++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index bdeff1f84..abc06ea8e 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -29,9 +29,9 @@ template< int, typename > class StaticArray; * \brief Array is responsible for memory management, basic elements * manipulation and I/O operations. * - * \tparam Value Type of array values. - * \tparam Device Device type - some of \ref Devices::Host and \ref Devices::Cuda. - * \tparam Index Type for indexing. + * \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. @@ -55,6 +55,8 @@ template< int, typename > class StaticArray; * * \par Example * \include ArrayExample.cpp + * + * See also \ref Containers::ArravView, \ref Containers::Vector, \ref Containers::VectorView. */ template< typename Value, typename Device = Devices::Host, @@ -72,20 +74,26 @@ class Array : public Object /** \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. */ @@ -93,25 +101,33 @@ class Array : public Object const IndexType& size ); /** - * - * @param + * \brief Copy constructor. + * + * \param array is an array to be copied. */ // Deep copy does not work because of EllpackIndexMultiMap - TODO: Fix it - //Array( const Array& ); + //Array( const Array& array ); /** - * \brief Copy constructor. + * \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 ); - Array( Array&& ); + /** + * \brief Move constructor. + * + * @param array is an array to be moved + */ + Array( Array&& array ); /** * \brief Initialize the array from initializer list, i.e. { ... } @@ -138,45 +154,51 @@ class Array : public Object Array( const std::vector< InValue >& vector ); /** - * \brief Returns type of array Value, Device type and the type of Index. + * \brief Returns type of array in C++ style. */ static String getType(); /** - * \brief Returns type of array Value, Device type and the type of Index. + * \brief Returns type of array in C++ style. */ virtual String getTypeVirtual() const; /** - * \brief Returns (host) type of array Value, Device type and the type of Index. + * \brief Returns type of array in C++ style where device is always \ref Devices::Host. */ static String getSerializationType(); /** - * \brief Returns (host) type of array Value, Device type and the type of Index. + * \brief Returns type of array in C++ style where device is always \ref Devices::Host. */ 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. + * + */ __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 ); @@ -186,6 +208,9 @@ class Array : public Object * * Releases old data and binds this array with new \e _data. Also sets new * \e _size of this array. + * + * This method is obsolete, use \ref ArrayView instead. + * * @param _data Pointer to new data. * @param _size Size of new _data. Number of elements. */ @@ -197,6 +222,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. @@ -212,6 +240,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. */ @@ -219,38 +250,45 @@ class Array : public Object void bind( StaticArray< Size, Value >& array ); /** - * \brief Swaps all features of given array with existing \e array. + * \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 by swaping the meta-data, i.e. 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. */ __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. */ __cuda_callable__ Value* getData(); /** - * \brief Assignes the value \e x to the array element at position \e i. + * \brief Assignes the value \e v to the array 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 x 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. -- GitLab From 7135fefb2b7c6e777651344515dd11cd32f19999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Thu, 28 Mar 2019 22:04:52 +0100 Subject: [PATCH 42/72] Array documentation and array assignment operator. --- src/Examples/Containers/ArrayExample.cpp | 12 +- .../Containers/Algorithms/ArrayAssignment.h | 61 ++++++++++ src/TNL/Containers/Array.h | 109 +++++++++++++----- src/TNL/TypeTraits.h | 2 +- 4 files changed, 155 insertions(+), 29 deletions(-) create mode 100644 src/TNL/Containers/Algorithms/ArrayAssignment.h diff --git a/src/Examples/Containers/ArrayExample.cpp b/src/Examples/Containers/ArrayExample.cpp index f9a6dd58a..09deea7b2 100644 --- a/src/Examples/Containers/ArrayExample.cpp +++ b/src/Examples/Containers/ArrayExample.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include using namespace TNL; @@ -22,10 +24,18 @@ void arrayExample() a1.setElement( i, i ); /*** - * You may also assign value to all array elements + * You may also assign value to all array elements ... */ a2 = 0; + /*** + * ... 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 = v; + a1 = l; + /*** * Simple array values checks can be done as follows ... */ diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h new file mode 100644 index 000000000..3c7f20c21 --- /dev/null +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -0,0 +1,61 @@ +/*************************************************************************** + 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 + +namespace TNL { +namespace Containers { +namespace Algorithms { + + +template< typename Array, + typename T, + bool isArray = TNL::IsArray< T > > +struct ArraysAsignment +{}; + +/** + * \brief Specialization for array-array assignment + */ +template< typename Array, + typename T > +struct ArraysAsignment< Array, T, true > +{ + void assign( Array& a, T& t ) + { + a.setSize( t.getSize() ); + ArrayOperations< typename Array::DeviceType, typename T::DeviceType >:: + copyMemory< typename Array::ValueType, typename T::ValueType, typename T::IndexType > + ( a.getData(), t.getData(), t.getSize() ); + }; +}; + +/** + * \brief Specialization for array-value assignment + */ +template< typename Array, + typename T > +struct ArraysAsignment< Array, T, false > +{ + void assign( Array& a, T& t ) + { + ArrayOperations< typename Array::DeviceType >:: + setMemory< typename Array::ValueType, typename Array::IndexType > + ( a.getData(), ( typename Array::ValueType ) t, t.getSize() ); + }; + +}; + + +} // namespace Algorithms +} // namespace Containers +} // namespace TNL diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index abc06ea8e..417d22bd9 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -154,22 +154,30 @@ class Array : public Object Array( const std::vector< InValue >& vector ); /** - * \brief Returns type of array in C++ style. + * \brief Returns type of array in C++ style. + * + * \return String with array type. */ static String getType(); /** * \brief Returns type of array in C++ style. + * + * \return String with array type. */ virtual String getTypeVirtual() const; /** * \brief Returns type of array in C++ style where device is always \ref Devices::Host. + * + * \return String with serialization array type. */ static String getSerializationType(); /** * \brief Returns type of array in C++ style where device is always \ref Devices::Host. + * + * \return String with serialization array type. */ virtual String getSerializationTypeVirtual() const; @@ -188,7 +196,8 @@ class Array : public Object * \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; @@ -211,8 +220,8 @@ class Array : public Object * * This method is obsolete, use \ref ArrayView instead. * - * @param _data Pointer to new data. - * @param _size Size of new _data. Number of elements. + * \param _data Pointer to new data. + * \param _size Size of new _data. Number of elements. */ void bind( Value* _data, const Index _size ); @@ -269,6 +278,8 @@ class Array : public Object * \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; @@ -276,76 +287,108 @@ class Array : public Object * \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 v to the array element at position \e i. + * \brief Array 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 * arrays allocated on device (GPU). * * \param i is element index. - * \param x is the new value of the element. + * \param v is the new value of the element. */ 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. * * \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 ); /** - * \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; /** * \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 ); /** - * \brief Assigns \e array to this array, replacing its current contents. + * \brief Move contents of \e array to this array. * - * \param array Reference to an array. + * \param array is reference to the array. + * + * \return Reference to this array. */ Array& operator = ( Array&& array ); /** - * \brief Assigns \e array to this array, replacing its current contents. + * \brief Assigns either TNL array 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 ArrayT > - Array& operator = ( const ArrayT& array ); + template< typename T > + Array& operator = ( const T& data ); /** + * \brief Assigns STL list to this array. * - * @param list - * @return + * \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 * - * @param vector - * @return + * \return Reference to this array. */ template< typename InValue > Array& operator = ( const std::vector< InValue >& vector ); @@ -353,8 +396,10 @@ class Array : public Object /** * \brief This function checks whether this array is equal to \e array. * - * \tparam ArrayT Type of array. - * \param array Reference to an array. + * \tparam ArrayT is type of array. + * \param array is reference to an array. + * + * \return True if arrays are equal and false otherwise. */ template< typename ArrayT > bool operator == ( const ArrayT& array ) const; @@ -364,6 +409,8 @@ class Array : public Object * * \tparam ArrayT Type of array. * \param array Reference to an array. + * + * \return True if arrays are not equal and false otherwise. */ template< typename ArrayT > bool operator != ( const ArrayT& array ) const; @@ -394,7 +441,15 @@ class Array : public Object /** * \brief Checks if there is an element with value \e v in this array. * - * \param v Reference to a value. + * By default, the methods 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 array contains only given value in given interval. */ bool containsValue( const Value& v, const Index begin = 0, @@ -505,7 +560,7 @@ std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index template< typename Value, typename Device, typename Index > -struct isArray< Containers::Array< Value, Device, Index > > +struct IsArray< Containers::Array< Value, Device, Index > > { static constexpr bool value = true; }; diff --git a/src/TNL/TypeTraits.h b/src/TNL/TypeTraits.h index 9b0b3815d..05e3a6c29 100644 --- a/src/TNL/TypeTraits.h +++ b/src/TNL/TypeTraits.h @@ -13,7 +13,7 @@ namespace TNL { template< typename T > - struct isArray + struct IsArray { static constexpr bool value = false; }; -- GitLab From ed2c4b4e9b82ac463e1a1abf3304c90b42360e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Tue, 2 Apr 2019 21:29:25 +0200 Subject: [PATCH 43/72] Attempt for SFINAE in array assignment. --- src/Examples/Containers/ArrayExample.cpp | 2 +- .../Containers/Algorithms/ArrayAssignment.h | 38 +++++++++---------- src/TNL/Containers/Array.h | 29 +------------- src/TNL/Containers/Array.hpp | 27 +------------ src/TNL/Containers/ArrayView.h | 10 ----- src/TNL/Containers/DistributedArray.h | 9 ----- src/TNL/Containers/DistributedArrayView.h | 9 ----- src/TNL/Containers/DistributedVector.h | 9 ----- src/TNL/Containers/DistributedVectorView.h | 9 ----- .../Multimaps/EllpackIndexMultimapValues.h | 10 ----- .../StaticEllpackIndexMultimapValues.h | 11 ------ src/TNL/Containers/Vector.h | 9 ----- src/TNL/Containers/VectorView.h | 9 ----- 13 files changed, 22 insertions(+), 159 deletions(-) diff --git a/src/Examples/Containers/ArrayExample.cpp b/src/Examples/Containers/ArrayExample.cpp index 09deea7b2..7d26a8fcd 100644 --- a/src/Examples/Containers/ArrayExample.cpp +++ b/src/Examples/Containers/ArrayExample.cpp @@ -26,7 +26,7 @@ void arrayExample() /*** * You may also assign value to all array elements ... */ - a2 = 0; + a2 = 0.0; /*** * ... or assign STL list and vector. diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 3c7f20c21..496fcc0eb 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -10,50 +10,48 @@ #pragma once -#include +#include namespace TNL { namespace Containers { namespace Algorithms { - -template< typename Array, - typename T, - bool isArray = TNL::IsArray< T > > -struct ArraysAsignment -{}; - /** * \brief Specialization for array-array assignment */ template< typename Array, - typename T > -struct ArraysAsignment< Array, T, true > + typename T > +struct ArrayAssignment { - void assign( Array& a, T& t ) + static void assign( Array& a, const T& t, const typename T::ValueType* ) { - a.setSize( t.getSize() ); - ArrayOperations< typename Array::DeviceType, typename T::DeviceType >:: + /*a.setSize( t.getSize() ); + ArrayOperations< typename Array::DeviceType, typename T::DeviceType >::template copyMemory< typename Array::ValueType, typename T::ValueType, typename T::IndexType > - ( a.getData(), t.getData(), t.getSize() ); + ( a.getData(), t.getData(), t.getSize() );*/ + }; + + static void assign( Array& a, const T& t, const void* ) + { + }; }; /** * \brief Specialization for array-value assignment */ -template< typename Array, - typename T > -struct ArraysAsignment< Array, T, false > +/*template< typename Array, + typename T > +struct ArrayAssignment< Array, T, void > { - void assign( Array& a, T& t ) + static void assign( Array& a, const T& t ) { - ArrayOperations< typename Array::DeviceType >:: + ArrayOperations< typename Array::DeviceType >::template setMemory< typename Array::ValueType, typename Array::IndexType > ( a.getData(), ( typename Array::ValueType ) t, t.getSize() ); }; -}; +};*/ } // namespace Algorithms diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 417d22bd9..bf032a619 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -106,7 +106,7 @@ class Array : public Object * \param array is an array to be copied. */ // Deep copy does not work because of EllpackIndexMultiMap - TODO: Fix it - //Array( const Array& array ); + explicit Array( const Array& array ); /** * \brief Bind constructor . @@ -533,38 +533,11 @@ class Array : public Object mutable int* referenceCounter = nullptr; }; -template< typename Array, - typename Data, - bool isArray = TNL::isArray< Data >::value > -struct ArrayAssignment {}; - -template< typename Array, - typename Data > -struct ArrayAssignment< Array, Data, true > -{ - static void assign( Array& a, const Data& d ); -}; - -template< typename Array, - typename Data > -struct ArrayAssignment< Array, Data, false > -{ - static void assign( Array& a, const Data& d ); -}; - template< typename Value, typename Device, typename Index > std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index >& v ); } // namespace Containers -template< typename Value, - typename Device, - typename Index > -struct IsArray< Containers::Array< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 1273f5834..53aa4cbcc 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -493,7 +494,7 @@ Array< Value, Device, Index >& Array< Value, Device, Index >:: operator = ( const T& data ) { - ArrayAssignment< ThisType, T >::assign( *this, data ); + Algorithms::ArrayAssignment< ThisType, T >::assign( *this, data ); return ( *this ); } @@ -699,30 +700,6 @@ std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index return str; } -template< typename Array, - typename Data > -void -ArrayAssignment< Array, Data, true >:: -assign( Array& array, const Data& data ) -{ - if( array.getSize() != data.getSize() ) - array.setLike( data ); - if( array.getSize() > 0 ) - Algorithms::ArrayOperations< typename Array::DeviceType, typename Data::DeviceType >:: - copyMemory( array.getData(), - data.getData(), - data.getSize() ); -}; - -template< typename Array, - typename Data > -void -ArrayAssignment< Array, Data, false >:: -assign( Array& array, const Data& data ) -{ - array.setValue( data ); -}; - } // namespace Containers } // namespace TNL diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 7ddab67a9..2ad403922 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -155,16 +155,6 @@ template< typename Value, typename Device, typename Index > std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Index >& v ); } // namespace Containers - -template< typename Value, - typename Device, - typename Index > -struct isArray< Containers::ArrayView< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - - } // namespace TNL #include diff --git a/src/TNL/Containers/DistributedArray.h b/src/TNL/Containers/DistributedArray.h index 036024027..22e13fbac 100644 --- a/src/TNL/Containers/DistributedArray.h +++ b/src/TNL/Containers/DistributedArray.h @@ -138,15 +138,6 @@ private: }; } // namespace Containers - -template< typename Value, - typename Device, - typename Index > -struct isArray< Containers::DistributedArray< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include "DistributedArray_impl.h" diff --git a/src/TNL/Containers/DistributedArrayView.h b/src/TNL/Containers/DistributedArrayView.h index 7e829712b..c2ac79ec5 100644 --- a/src/TNL/Containers/DistributedArrayView.h +++ b/src/TNL/Containers/DistributedArrayView.h @@ -148,15 +148,6 @@ protected: }; } // namespace Containers - -template< typename Value, - typename Device, - typename Index > -struct isArray< Containers::DistributedArrayView< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include "DistributedArrayView_impl.h" diff --git a/src/TNL/Containers/DistributedVector.h b/src/TNL/Containers/DistributedVector.h index 1e50f6dd4..819e6962c 100644 --- a/src/TNL/Containers/DistributedVector.h +++ b/src/TNL/Containers/DistributedVector.h @@ -139,15 +139,6 @@ public: }; } // namespace Containers - -template< typename Value, - typename Device, - typename Index > -struct isArray< Containers::DistributedVector< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include "DistributedVector_impl.h" diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h index b4fbb81ba..4e18a86c8 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -137,15 +137,6 @@ public: }; } // namespace Containers - -template< typename Value, - typename Device, - typename Index > -struct isArray< Containers::DistributedVectorView< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include "DistributedVectorView_impl.h" diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h index 9aabab480..ae0df5ee5 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h @@ -117,16 +117,6 @@ std::ostream& operator << ( std::ostream& str, const EllpackIndexMultimapValues< } // namespace Multimaps } // namespace Containers - -template< typename Index, - typename Device, - typename LocalIndex, - int step > -struct isArray< Containers::Multimaps::EllpackIndexMultimapValues< Index, Device, LocalIndex, step > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h index ae937bfbe..ad6ba7f5e 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h @@ -104,17 +104,6 @@ std::ostream& operator << ( std::ostream& str, const StaticEllpackIndexMultimapV } // namespace Multimaps } // namespace Containers - -template< int ValuesCount, - typename Index, - typename Device, - typename LocalIndex, - int step > -struct isArray< Containers::Multimaps::StaticEllpackIndexMultimapValues< ValuesCount, Index, Device, LocalIndex, step > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h index 831134aba..b66adf9f1 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -281,15 +281,6 @@ class Vector }; } // namespace Containers - -template< typename Value, - typename Device, - typename Index > -struct isArray< Containers::Vector< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include diff --git a/src/TNL/Containers/VectorView.h b/src/TNL/Containers/VectorView.h index 2f837c91a..49c12ee68 100644 --- a/src/TNL/Containers/VectorView.h +++ b/src/TNL/Containers/VectorView.h @@ -150,15 +150,6 @@ public: }; } // namespace Containers - -template< typename Value, - typename Device, - typename Index > -struct isArray< Containers::VectorView< Value, Device, Index > > -{ - static constexpr bool value = true; -}; - } // namespace TNL #include -- GitLab From 4b84bb3a2520ab7860533a7295523656f922aa33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 3 Apr 2019 21:34:37 +0200 Subject: [PATCH 44/72] [WIP] SFINAE for array assignment is still not working for arrays of tnlChunkedEllpackSliceInfo. --- .../Containers/Algorithms/ArrayAssignment.h | 53 +++++++++++++------ src/TNL/Containers/Array.h | 25 +++++++++ src/TNL/Containers/Array.hpp | 18 +++++++ src/TNL/Containers/ArrayView.h | 8 ++- src/TNL/Containers/ArrayView_impl.h | 22 ++++++++ 5 files changed, 108 insertions(+), 18 deletions(-) diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 496fcc0eb..fc8b6f15c 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -16,42 +16,63 @@ namespace TNL { namespace Containers { namespace Algorithms { +namespace Details { /** - * \brief Specialization for array-array assignment + * 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(&C::getArrayData) ) ; + template< typename C > static NoType& test(...); + +public: + enum { 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 +struct ArrayAssignment< Array, T, true > { - static void assign( Array& a, const T& t, const typename T::ValueType* ) + static void assign( Array& a, const T& t ) { - /*a.setSize( t.getSize() ); ArrayOperations< typename Array::DeviceType, typename T::DeviceType >::template - copyMemory< typename Array::ValueType, typename T::ValueType, typename T::IndexType > - ( a.getData(), t.getData(), t.getSize() );*/ - }; - - static void assign( Array& a, const T& t, const void* ) - { - + copyMemory< typename Array::ValueType, typename T::ValueType, typename Array::IndexType > + ( a.getArrayData(), t.getArrayData(), t.getSize() ); }; }; /** - * \brief Specialization for array-value assignment + * \brief Specialization for array-value assignment for other types. We assume + * thet T is convertible to Array::ValueType. */ -/*template< typename Array, +template< typename Array, typename T > -struct ArrayAssignment< Array, T, void > +struct ArrayAssignment< Array, T, false > { static void assign( Array& a, const T& t ) { ArrayOperations< typename Array::DeviceType >::template setMemory< typename Array::ValueType, typename Array::IndexType > - ( a.getData(), ( typename Array::ValueType ) t, t.getSize() ); + ( a.getArrayData(), ( typename Array::ValueType ) t, a.getSize() ); }; -};*/ +}; + } // namespace Algorithms diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index bf032a619..683f22fd9 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -292,6 +292,31 @@ class Array : public Object */ __cuda_callable__ Value* getData(); + /** + * \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. * diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 53aa4cbcc..83f6ee4af 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -399,6 +399,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 > diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 2ad403922..7e4129a07 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -97,10 +97,8 @@ public: template< typename Array > ArrayView& operator=( const Array& array ); - static String getType(); - __cuda_callable__ void swap( ArrayView& view ); @@ -113,6 +111,12 @@ public: __cuda_callable__ Value* getData(); + __cuda_callable__ + const Value* getArrayData() const; + + __cuda_callable__ + Value* getArrayData(); + __cuda_callable__ Index getSize() const; diff --git a/src/TNL/Containers/ArrayView_impl.h b/src/TNL/Containers/ArrayView_impl.h index 96d00e7de..bebd83c6a 100644 --- a/src/TNL/Containers/ArrayView_impl.h +++ b/src/TNL/Containers/ArrayView_impl.h @@ -196,6 +196,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 > -- GitLab From a1a9e5fe721d18571fdc0f97a7c1dd406e6570dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Thu, 4 Apr 2019 22:40:49 +0200 Subject: [PATCH 45/72] [WIP] Debugging array assignment. --- src/TNL/Containers/Algorithms/ArrayAssignment.h | 8 ++++---- src/TNL/Containers/Array.h | 2 +- src/TNL/Containers/Array.hpp | 8 ++++---- src/UnitTests/Containers/ArrayTest.h | 8 +++++--- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index fc8b6f15c..713fcc6ba 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -27,11 +27,11 @@ private: typedef char YesType[1]; typedef char NoType[2]; - template< typename C > static YesType& test( decltype(&C::getArrayData) ) ; - template< typename C > static NoType& test(...); + template< typename C > static YesType& test( decltype(&C::getArrayData) ); + //template< typename C > static NoType& test(...); public: - enum { value = sizeof( test< T >(0) ) == sizeof( YesType ) }; + static constexpr bool value = ( sizeof( test< T >(0) ) == sizeof( YesType ) ); }; } // namespace Details @@ -58,7 +58,7 @@ struct ArrayAssignment< Array, T, true > /** * \brief Specialization for array-value assignment for other types. We assume - * thet T is convertible to Array::ValueType. + * that T is convertible to Array::ValueType. */ template< typename Array, typename T > diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 683f22fd9..a3292c6cf 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -492,7 +492,7 @@ class Array : public Object /** * \brief Returns true if non-zero size is set. */ - operator bool() const; + //operator bool() const; /** * \brief Method for saving the object to a \e file as a binary data. diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 83f6ee4af..42920af00 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -63,7 +63,7 @@ Array( Value* data, { } -/*template< typename Value, +template< typename Value, typename Device, typename Index > Array< Value, Device, Index >:: @@ -76,7 +76,7 @@ Array( const Array< Value, Device, Index >& array ) // Deep copy does not work because of EllpackIndexMultiMap - TODO: Fix it this->setSize( array.getSize() ); Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), array.getData(), array.getSize() ); -}*/ +} template< typename Value, typename Device, @@ -636,13 +636,13 @@ containsOnlyValue( const Value& v, return Algorithms::ArrayOperations< Device >::containsOnlyValue( &this->getData()[ begin ], end - begin, v ); } -template< typename Value, +/*template< typename Value, typename Device, typename Index > Array< Value, Device, Index >::operator bool() const { return data != 0; -} +}*/ template< typename Value, diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index 517b990fb..0d9b41aef 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.h @@ -216,11 +216,11 @@ TYPED_TEST( ArrayTest, setSize ) EXPECT_NE( v.getData(), u.getData() ); // cast to bool returns true iff size > 0 - EXPECT_TRUE( (bool) u ); + /*EXPECT_TRUE( (bool) u ); EXPECT_FALSE( ! u ); u.setSize( 0 ); EXPECT_FALSE( (bool) u ); - EXPECT_TRUE( ! u ); + EXPECT_TRUE( ! u );*/ } TYPED_TEST( ArrayTest, setLike ) @@ -462,7 +462,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[ i ], 72 ); v = u; EXPECT_EQ( u, v ); -- GitLab From 0a91a2656b7441a6fdd3c604068a4e1594ebf703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Thu, 4 Apr 2019 23:14:13 +0200 Subject: [PATCH 46/72] SFINAE for array asignment seems to be solved. --- src/TNL/Containers/Algorithms/ArrayAssignment.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 713fcc6ba..28f7557f3 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -10,6 +10,8 @@ #pragma once +#include +#include #include namespace TNL { @@ -27,8 +29,8 @@ private: typedef char YesType[1]; typedef char NoType[2]; - template< typename C > static YesType& test( decltype(&C::getArrayData) ); - //template< typename C > static NoType& test(...); + 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 ) ); -- GitLab From 8d569cb1312bd51fca085fbf92ef51be8ab2de9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 6 Apr 2019 16:01:06 +0200 Subject: [PATCH 47/72] Fixed typo from revision in tnl-benchmark-linear-solvers.h --- src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h b/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h index c3d2cc9cd..2926e6bb1 100644 --- a/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h +++ b/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h @@ -335,7 +335,6 @@ struct LinearSolversBenchmark matrixPointer->load( parameters.getParameter< String >( "input-matrix" ) ); x0.load( parameters.getParameter< String >( "input-dof" ) ); b.load( parameters.getParameter< String >( "input-rhs" ) ); - return false; typename MatrixType::CompressedRowLengthsVector rowLengths; matrixPointer->getCompressedRowLengths( rowLengths ); -- GitLab From c928885490ad1b8ac391e62e1ba0a7227d65eaf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 6 Apr 2019 20:46:46 +0200 Subject: [PATCH 48/72] Removed MultiArray and MultiVector classes They were not used anywhere and will be superseded by NDArray. --- src/TNL/Containers/MultiArray.h | 371 -------------------- src/TNL/Containers/MultiArray1D_impl.h | 241 ------------- src/TNL/Containers/MultiArray2D_impl.h | 255 -------------- src/TNL/Containers/MultiArray3D_impl.h | 271 -------------- src/TNL/Containers/MultiArray4D_impl.h | 290 --------------- src/TNL/Containers/MultiVector.h | 369 ------------------- src/TNL/Containers/MultiVector1D_impl.h | 213 ----------- src/TNL/Containers/MultiVector2D_impl.h | 224 ------------ src/TNL/Containers/MultiVector3D_impl.h | 248 ------------- src/TNL/Containers/MultiVector4D_impl.h | 269 -------------- src/Tools/tnl-diff.h | 8 - src/Tools/tnl-view.h | 36 +- src/UnitTests/Containers/CMakeLists.txt | 11 - src/UnitTests/Containers/MultiArrayTest.cpp | 11 - src/UnitTests/Containers/MultiArrayTest.cu | 11 - src/UnitTests/Containers/MultiArrayTest.h | 237 ------------- 16 files changed, 2 insertions(+), 3063 deletions(-) delete mode 100644 src/TNL/Containers/MultiArray.h delete mode 100644 src/TNL/Containers/MultiArray1D_impl.h delete mode 100644 src/TNL/Containers/MultiArray2D_impl.h delete mode 100644 src/TNL/Containers/MultiArray3D_impl.h delete mode 100644 src/TNL/Containers/MultiArray4D_impl.h delete mode 100644 src/TNL/Containers/MultiVector.h delete mode 100644 src/TNL/Containers/MultiVector1D_impl.h delete mode 100644 src/TNL/Containers/MultiVector2D_impl.h delete mode 100644 src/TNL/Containers/MultiVector3D_impl.h delete mode 100644 src/TNL/Containers/MultiVector4D_impl.h delete mode 100644 src/UnitTests/Containers/MultiArrayTest.cpp delete mode 100644 src/UnitTests/Containers/MultiArrayTest.cu delete mode 100644 src/UnitTests/Containers/MultiArrayTest.h diff --git a/src/TNL/Containers/MultiArray.h b/src/TNL/Containers/MultiArray.h deleted file mode 100644 index cdcda634b..000000000 --- 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 -#include -#include -#include - -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 -#include -#include -#include diff --git a/src/TNL/Containers/MultiArray1D_impl.h b/src/TNL/Containers/MultiArray1D_impl.h deleted file mode 100644 index 6c8f0b29c..000000000 --- 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 44d860167..000000000 --- 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 9dc3c0317..000000000 --- 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 2b35c1caa..000000000 --- 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 eaebf5cd5..000000000 --- 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 -#include -#include - -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 - void save( File& file ) const; - - //! Method for restoring the object from a file - void load( File& file ); - - void save( const String& fileName ) const; - - void 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 - void save( File& file ) const; - - //! Method for restoring the object from a file - void load( File& file ); - - void save( const String& fileName ) const; - - void 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 - void save( File& file ) const; - - //! Method for restoring the object from a file - void load( File& file ); - - void save( const String& fileName ) const; - - void 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 - void save( File& file ) const; - - //! Method for restoring the object from a file - void load( File& file ); - - void save( const String& fileName ) const; - - void 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 -#include -#include -#include diff --git a/src/TNL/Containers/MultiVector1D_impl.h b/src/TNL/Containers/MultiVector1D_impl.h deleted file mode 100644 index 1d4f67890..000000000 --- a/src/TNL/Containers/MultiVector1D_impl.h +++ /dev/null @@ -1,213 +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 > -void MultiVector< 1, Real, Device, Index > :: save( File& file ) const -{ - Vector< Real, Device, Index > :: save( file ); - dimensions. save( file ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 1, Real, Device, Index > :: load( File& file ) -{ - Vector< Real, Device, Index > :: load( file ); - dimensions. load( file ); -} - -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 > -void MultiVector< 1, Real, Device, Index > :: save( const String& fileName ) const -{ - Object::save( fileName ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 1, Real, Device, Index > :: load( const String& fileName ) -{ - 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 a52caff8a..000000000 --- a/src/TNL/Containers/MultiVector2D_impl.h +++ /dev/null @@ -1,224 +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 > -void MultiVector< 2, Real, Device, Index > :: save( File& file ) const -{ - Vector< Real, Device, Index > :: save( file ); - dimensions. save( file ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 2, Real, Device, Index > :: load( File& file ) -{ - Vector< Real, Device, Index > :: load( file ); - dimensions. load( file ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 2, Real, Device, Index > :: save( const String& fileName ) const -{ - Object::save( fileName ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 2, Real, Device, Index > :: load( const String& fileName ) -{ - 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 2a280f513..000000000 --- a/src/TNL/Containers/MultiVector3D_impl.h +++ /dev/null @@ -1,248 +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 > -void MultiVector< 3, Real, Device, Index > :: save( File& file ) const -{ - Vector< Real, Device, Index > :: save( file ); - dimensions. save( file ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 3, Real, Device, Index > :: load( File& file ) -{ - Vector< Real, Device, Index > :: load( file ); - dimensions. load( file ); -} - -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 > -void MultiVector< 3, Real, Device, Index > :: save( const String& fileName ) const -{ - Object::save( fileName ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 3, Real, Device, Index > :: load( const String& fileName ) -{ - 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 f3c838155..000000000 --- a/src/TNL/Containers/MultiVector4D_impl.h +++ /dev/null @@ -1,269 +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 > -void MultiVector< 4, Real, Device, Index > :: save( File& file ) const -{ - Vector< Real, Device, Index > :: save( file ); - dimensions. save( file ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 4, Real, Device, Index > :: load( File& file ) -{ - Vector< Real, Device, Index > :: load( file ); - dimensions. load( file ); -} - -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 > -void MultiVector< 4, Real, Device, Index > :: save( const String& fileName ) const -{ - Object::save( fileName ); -} - -template< typename Real, typename Device, typename Index > -void MultiVector< 4, Real, Device, Index > :: load( const String& fileName ) -{ - Object::load( fileName ); -} - -} // namespace Containers -} // namespace TNL diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index 364dbd294..01be8959f 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -452,10 +452,6 @@ 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" ) // @@ -532,10 +528,6 @@ 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 elementType = parsedObjectType[ 3 ]; diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h index cfd958aea..d7a25fd1e 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -264,22 +263,6 @@ bool convertObject( const MeshPointer& meshPointer, mf.bind( meshPointer, vector ); mf.write( outputFileName, outputFormat ); } - - if( parsedObjectType[ 0 ] == "Containers::MultiVector" || - parsedObjectType[ 0 ] == "tnlMultiVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) // - { - Containers::MultiVector< Dimension, Value, Devices::Host, Index > multiVector; - multiVector. load( inputFileName ); - 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; - } return true; } @@ -290,10 +273,6 @@ 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" ) // @@ -318,10 +297,6 @@ 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" ) // @@ -395,10 +370,6 @@ 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" ) // @@ -497,11 +468,8 @@ struct FilesProcessor 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" || // + if( parsedObjectType[ 0 ] == "Containers::Vector" || + parsedObjectType[ 0 ] == "tnlSharedVector" || // TODO: remove deprecated type names parsedObjectType[ 0 ] == "tnlVector" ) // setValueType< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); if( parsedObjectType[ 0 ] == "Functions::MeshFunction" || diff --git a/src/UnitTests/Containers/CMakeLists.txt b/src/UnitTests/Containers/CMakeLists.txt index fe75ed458..99e4d677b 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/MultiArrayTest.cpp b/src/UnitTests/Containers/MultiArrayTest.cpp deleted file mode 100644 index 18e7453cc..000000000 --- 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 97d7ff312..000000000 --- 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 3e8d330a1..000000000 --- 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 - -#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", File::Mode::Out ); - ASSERT_TRUE( v. save( file ) ); - file. close(); - MultiArray< Dimension, ValueType, Device, IndexType > u; - file. open( "test-file.tnl", File::Mode::In ); - 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 -} - - - - - - -- GitLab From 70372c2e14ffa6c41b1a7b127663bb8472473085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Sat, 6 Apr 2019 20:50:34 +0200 Subject: [PATCH 49/72] Removed deprecated type names from tnl-view and tnl-diff --- src/Tools/tnl-diff.h | 22 +++++++--------------- src/Tools/tnl-view.h | 26 +++++++------------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index 01be8959f..5443f953a 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -434,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; @@ -452,15 +450,12 @@ bool setIndexType( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters ) { String indexType; - 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" ) @@ -528,12 +523,9 @@ bool setValueType( const MeshPointer& meshPointer, { String elementType; - 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 ]; diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h index d7a25fd1e..64c09e32b 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -250,9 +250,7 @@ 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? @@ -273,9 +271,7 @@ bool setDimension( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters ) { int dimensions( 0 ); - 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 ) { @@ -297,9 +293,7 @@ bool setIndexType( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters ) { String indexType; - 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" ) @@ -370,9 +364,7 @@ bool setValueType( const MeshPointer& meshPointer, String elementType; // TODO: Fix this even for arrays - 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" ) @@ -394,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; @@ -468,12 +459,9 @@ struct FilesProcessor error = true; continue; } - if( parsedObjectType[ 0 ] == "Containers::Vector" || - parsedObjectType[ 0 ] == "tnlSharedVector" || // TODO: remove deprecated type names - parsedObjectType[ 0 ] == "tnlVector" ) // + if( parsedObjectType[ 0 ] == "Containers::Vector" ) setValueType< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); - if( parsedObjectType[ 0 ] == "Functions::MeshFunction" || - parsedObjectType[ 0 ] == "tnlMeshFunction" ) // TODO: remove deprecated type names + if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ) setMeshFunction< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); if( parsedObjectType[ 0 ] == "Functions::VectorField" ) setVectorFieldSize< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); -- GitLab From 28da807cb02bfbbf6f8c30215e1d85f89e09bc3c Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Mon, 8 Apr 2019 19:16:49 +0200 Subject: [PATCH 50/72] [WIP] Fixing changes in Array. --- src/Benchmarks/BLAS/array-operations.h | 4 +- src/Python/pytnl/tnl/Object.cpp | 10 +- .../Algorithms/ArrayOperationsCuda.hpp | 8 +- src/TNL/Containers/Array.h | 6 +- src/TNL/Containers/Array.hpp | 6 +- src/TNL/Containers/ArrayView.h | 110 +++++++++++++++--- src/TNL/Containers/ArrayView_impl.h | 29 +++++ src/TNL/Matrices/AdEllpack_impl.h | 5 +- src/TNL/Meshes/MeshDetails/Mesh_impl.h | 4 +- src/UnitTests/Containers/ArrayTest.h | 10 +- 10 files changed, 154 insertions(+), 38 deletions(-) diff --git a/src/Benchmarks/BLAS/array-operations.h b/src/Benchmarks/BLAS/array-operations.h index b5cf9ff58..926c729ce 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/Python/pytnl/tnl/Object.cpp b/src/Python/pytnl/tnl/Object.cpp index cd592a2c6..56b0f54e5 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::Object::save, py::const_)) // .def("load", py::overload_cast(&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/Containers/Algorithms/ArrayOperationsCuda.hpp b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp index d56764313..3efe7e4d4 100644 --- a/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp +++ b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp @@ -188,8 +188,9 @@ copySTLList( DestinationElement* destination, { const auto copySize = std::min( size - copiedElements, copy_buffer_size ); for( size_t i = 0; i < copySize; i++ ) - copy_buffer[ copiedElements ++ ] = static_cast< DestinationElement >( * it ++ ); - ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory( destination, copy_buffer, copySize ); + copy_buffer[ i ] = static_cast< DestinationElement >( * it ++ ); + ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory( &destination[ copiedElements ], ©_buffer[ 0 ], copySize ); + copiedElements += copySize; } } @@ -267,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/Array.h b/src/TNL/Containers/Array.h index a3292c6cf..bf40c5a7a 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -52,7 +52,7 @@ template< int, typename > class StaticArray; * \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 * @@ -72,7 +72,8 @@ class Array : public Object using HostType = Containers::Array< Value, Devices::Host, Index >; using CudaType = Containers::Array< Value, Devices::Cuda, Index >; - /** \brief Basic constructor. + /** + * \brief Basic constructor. * * Constructs an empty array with zero size. */ @@ -105,7 +106,6 @@ class Array : public Object * * \param array is an array to be copied. */ - // Deep copy does not work because of EllpackIndexMultiMap - TODO: Fix it explicit Array( const Array& array ); /** diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 42920af00..cd970adcd 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -73,7 +73,6 @@ Array( const Array< Value, Device, Index >& array ) allocationPointer( nullptr ), referenceCounter( 0 ) { - // Deep copy does not work because of EllpackIndexMultiMap - TODO: Fix it this->setSize( array.getSize() ); Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), array.getData(), array.getSize() ); } @@ -524,8 +523,7 @@ Array< Value, Device, Index >& Array< Value, Device, Index >:: operator = ( const std::list< InValue >& list ) { - if( this->getSize() != list.size() ) - this->setSize( list.size() ); + this->setSize( list.size() ); Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list ); } @@ -539,7 +537,7 @@ operator = ( const std::vector< InValue >& vector ) { if( this->getSize() != vector.size() ) this->setSize( vector.size() ); - Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), vector.data(), vector.size() ); + Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), vector.data(), vector.size() ); } template< typename Value, diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 7e4129a07..9aee7f35e 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -25,6 +25,41 @@ class Array; template< int Size, typename Value > class StaticArray; +/** + * \brief ArrayView serves for accessing 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[] + * which is more efficient but it 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 > @@ -37,31 +72,72 @@ public: using HostType = ArrayView< Value, Devices::Host, Index >; using CudaType = ArrayView< Value, Devices::Cuda, Index >; + /** + * \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. - __cuda_callable__ - ArrayView( const ArrayView& ) = default; - - // "Templated copy-constructor" accepting any cv-qualification of Value + /** + * \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& 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 + /** + * \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( ArrayView&& view ) = default; + + /** + * \brief Constructor for initialization from other array containers. + * + * It makes shallow copy only. + * + * This method can be called from device kernels. + * + * \tparam Value_ can be both const and non-const qualified Value. + */ + template< typename Value_ > __cuda_callable__ ArrayView( Array< Value_, Device, Index >& array ); @@ -133,8 +209,14 @@ public: template< typename Value_, typename Device_, typename Index_ > bool operator==( const ArrayView< Value_, Device_, Index_ >& view ) const; + template< typename ArrayT > + bool operator == ( const ArrayT& array ) const; + template< typename Value_, typename Device_, typename Index_ > bool operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const; + + template< typename ArrayT > + bool operator != ( const ArrayT& array ) const; void setValue( Value value ); diff --git a/src/TNL/Containers/ArrayView_impl.h b/src/TNL/Containers/ArrayView_impl.h index bebd83c6a..35230f2d2 100644 --- a/src/TNL/Containers/ArrayView_impl.h +++ b/src/TNL/Containers/ArrayView_impl.h @@ -293,6 +293,24 @@ operator==( const ArrayView< Value_, Device_, Index_ >& view ) const return Algorithms::ArrayOperations< Device, Device_ >::compareMemory( getData(), view.getData(), getSize() ); } +template< typename Value_, + typename Device_, + typename Index_ > + template< typename ArrayT > +bool +ArrayView< Value_, Device_, Index_ >:: +operator == ( const ArrayT& array ) const +{ + if( array.getSize() != this->getSize() ) + return false; + if( this->getSize() == 0 ) + return true; + return Algorithms::ArrayOperations< DeviceType, typename ArrayT::DeviceType >:: + compareMemory( this->getData(), + array.getData(), + array.getSize() ); +} + template< typename Value, typename Device, typename Index > @@ -304,6 +322,17 @@ operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const return ! ( *this == view ); } +template< typename Value_, + typename Device_, + typename Index_ > + template< typename ArrayT > +bool +ArrayView< Value_, Device_, Index_ >:: +operator != ( const ArrayT& array ) const +{ + return ! ( *this == array ); +} + template< typename Value, typename Device, typename Index > diff --git a/src/TNL/Matrices/AdEllpack_impl.h b/src/TNL/Matrices/AdEllpack_impl.h index 57658788c..0838bf09b 100644 --- a/src/TNL/Matrices/AdEllpack_impl.h +++ b/src/TNL/Matrices/AdEllpack_impl.h @@ -868,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/Meshes/MeshDetails/Mesh_impl.h b/src/TNL/Meshes/MeshDetails/Mesh_impl.h index f95fd0e3a..3f00336a8 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() diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index 0d9b41aef..efaeac38b 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.h @@ -146,7 +146,7 @@ TYPED_TEST( ArrayTest, constructors ) { using ArrayType = typename TestFixture::ArrayType; - ArrayType u; + /* ArrayType u; EXPECT_EQ( u.getSize(), 0 ); ArrayType v( 10 ); @@ -194,6 +194,8 @@ TYPED_TEST( ArrayTest, constructors ) EXPECT_EQ( a3.getElement( 0 ), 7 ); EXPECT_EQ( a3.getElement( 1 ), 8 ); EXPECT_EQ( a3.getElement( 2 ), 9 ); + + */ } TYPED_TEST( ArrayTest, setSize ) @@ -532,13 +534,15 @@ TYPED_TEST( ArrayTest, evaluate ) using IndexType = typename ArrayType::IndexType; ArrayType u( 10 ); - auto f = [] __cuda_callable__ ( IndexType i ) + + // TODO: Move to ArrayView + /*auto f = [] __cuda_callable__ ( IndexType i ) { return 3 * i % 4; }; u.evaluate( f ); for( int i = 0; i < 10; i++ ) - EXPECT_EQ( u.getElement( i ), 3 * i % 4 ); + EXPECT_EQ( u.getElement( i ), 3 * i % 4 );*/ } TYPED_TEST( ArrayTest, SaveAndLoad ) -- GitLab From 8ec568835dd529a0c3d4611b562eafb96976957e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Mon, 8 Apr 2019 22:10:15 +0200 Subject: [PATCH 51/72] [WIP] Fixing Array tast. --- src/UnitTests/Containers/ArrayTest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index efaeac38b..28fa8c5cb 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.h @@ -466,7 +466,7 @@ TYPED_TEST( ArrayTest, assignmentOperator ) v = 72; //.setValue( 0 ); for( int i = 0; i < 10; i++ ) - EXPECT_EQ( v[ i ], 72 ); + EXPECT_EQ( v.getElement( i ), 72 ); v = u; EXPECT_EQ( u, v ); -- GitLab From f93155b969528d02dadab3edf96c5f081eba4177 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Tue, 9 Apr 2019 14:15:05 +0200 Subject: [PATCH 52/72] Writing ArrayView documentation plus few changes in Array. --- src/Examples/Containers/CMakeLists.txt | 15 +- src/TNL/Containers/Array.h | 52 +-- src/TNL/Containers/Array.hpp | 34 +- src/TNL/Containers/ArrayView.h | 295 +++++++++++++++-- src/TNL/Containers/ArrayView_impl.h | 392 ----------------------- src/UnitTests/Containers/ArrayTest.h | 17 - src/UnitTests/Containers/ArrayViewTest.h | 19 ++ 7 files changed, 341 insertions(+), 483 deletions(-) delete mode 100644 src/TNL/Containers/ArrayView_impl.h diff --git a/src/Examples/Containers/CMakeLists.txt b/src/Examples/Containers/CMakeLists.txt index 7c5b616a4..577c8c70c 100644 --- a/src/Examples/Containers/CMakeLists.txt +++ b/src/Examples/Containers/CMakeLists.txt @@ -6,10 +6,21 @@ ELSE() ADD_CUSTOM_COMMAND( COMMAND ArrayExample > ArrayExample.out OUTPUT ArrayExample.out ) ENDIF() +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE( ArrayViewExampleCuda ArrayViewExample.cu ) + ADD_CUSTOM_COMMAND( COMMAND ArrayExampleCuda > 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 ) + ArrayExampleCuda.out + ArrayViewExampleCuda.out ) ELSE() ADD_CUSTOM_TARGET( RunContainersExamples ALL DEPENDS - ArrayExample.out ) + ArrayExample.out + ArrayViewExample.out ) ENDIF() diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index bf40c5a7a..223057c3b 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -261,7 +261,7 @@ class Array : public Object /** * \brief Swaps this array with another. * - * The swap is done by swaping the meta-data, i.e. pointers and sizes. + * 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. */ @@ -331,6 +331,9 @@ class Array : public Object /** * \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. @@ -380,7 +383,7 @@ class Array : public Object Array& operator = ( Array&& array ); /** - * \brief Assigns either TNL array or single value. + * \brief Assigns either array-like container 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, @@ -419,12 +422,12 @@ class Array : public Object Array& operator = ( const std::vector< InValue >& vector ); /** - * \brief This function checks whether this array is equal to \e array. + * \brief Comparison operator with another array-like container. * - * \tparam ArrayT is type of 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 arrays are equal and false otherwise. + * \return True if both arrays are equal element-wise and false otherwise. */ template< typename ArrayT > bool operator == ( const ArrayT& array ) const; @@ -435,7 +438,7 @@ class Array : public Object * \tparam ArrayT Type of array. * \param array Reference to an array. * - * \return True if arrays are not equal and false otherwise. + * \return True if both arrays are not equal element-wise and false otherwise. */ template< typename ArrayT > bool operator != ( const ArrayT& array ) const; @@ -452,21 +455,9 @@ class Array : public Object Index end = -1 ); /** - * \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 in this array. + * \brief Checks if there is an element with value \e v. * - * By default, the methods checks all array elements. By setting indexes + * 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. @@ -474,16 +465,24 @@ class Array : public Object * \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 array contains only given value in given interval. + * \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 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 Index begin = 0, @@ -491,9 +490,14 @@ class Array : public Object /** * \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. * diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index cd970adcd..d7cc4d234 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -73,6 +73,7 @@ Array( const Array< Value, Device, Index >& array ) allocationPointer( nullptr ), referenceCounter( 0 ) { + //this->bind( array ); this->setSize( array.getSize() ); Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), array.getData(), array.getSize() ); } @@ -580,28 +581,6 @@ void Array< Value, Device, Index >::setValue( const ValueType& e, Algorithms::ArrayOperations< Device >::setMemory( &this->getData()[ begin ], e, end - begin ); } -template< typename Value, - typename Device, - typename Index > - template< typename Function > -void Array< 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." ); - - 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 > @@ -634,14 +613,15 @@ containsOnlyValue( const Value& v, return Algorithms::ArrayOperations< Device >::containsOnlyValue( &this->getData()[ begin ], end - begin, v ); } -/*template< typename Value, +template< typename Value, typename Device, typename Index > -Array< Value, Device, Index >::operator bool() const +bool +Array< Value, Device, Index >:: +empty() const { - return data != 0; -}*/ - + return data; +} template< typename Value, typename Device, diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 9aee7f35e..3c30b0429 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -72,6 +72,13 @@ public: using HostType = ArrayView< Value, Devices::Host, Index >; using CudaType = ArrayView< Value, Devices::Cuda, 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. * @@ -141,93 +148,339 @@ public: __cuda_callable__ ArrayView( Array< Value_, Device, Index >& array ); - template< int Size, typename Value_ > // template catches both const and non-const qualified Value + /** + * \brief Constructor for initialization with static array. + * + * This method can be called from device kernels. + * + * \tparam Size is size of the static array. + * \tparam Value_ can be both const and non-const qualified Value. + * + * \param array is a static array the array view is initialized with. + */ + template< int Size, typename 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 Copy constructor from constant Array. + * + * This constructor will be used only when Value is const-qualified + * (const views are initializable by const references). + * + * This method can be called from device kernels. + * + * \tparam Value_ can be both const and non-const qualified Value + * \param array is an array the array view is initialized with. + */ + template< typename Value_ > __cuda_callable__ ArrayView( const Array< Value_, Device, Index >& array ); + /** + * \brief Constructor for initialization with static array. + * + * This method can be called from device kernels. + * + * \tparam Size is size of the static array. + * \tparam Value_ can be both const and non-const qualified Value. + * + * \param array is a static array the array view is initialized with. + */ 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) + /** + * \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 ); - - // Copy-assignment does deep copy, just like regular array, but the sizes - // must match (i.e. copy-assignment cannot resize). + /** + * \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; + /** + * \brief Comparison operator with another array view \e view. + * + * \tparam Value_ is the value type of the right-hand-side array view. + * \tparam Device_ is the device type of the right-hand-side array view. + * \tparam Index_ is the index type of the right-hand-side array view. + * \param view is reference to the right-hand-side array view. + * + * \return True if both array views are equal element-wise and false otherwise. + */ 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 view \e view. + * + * \tparam Value_ is the value type of the right-hand-side array view. + * \tparam Device_ is the device type of the right-hand-side array view. + * \tparam Index_ is the index type of the right-hand-side array view. + * \param view is reference to the right-hand-side array view. + * + * \return True if both array views are not equal element-wise and false otherwise. + */ template< typename Value_, typename Device_, typename Index_ > bool operator!=( const ArrayView< Value_, Device_, Index_ >& view ) 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 ); + + /** + * \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 ); - // Checks if there is an element with given value in this array + /** + * \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; protected: //! Pointer to allocated data @@ -243,4 +496,4 @@ std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Ind } // namespace Containers } // namespace TNL -#include +#include diff --git a/src/TNL/Containers/ArrayView_impl.h b/src/TNL/Containers/ArrayView_impl.h deleted file mode 100644 index 35230f2d2..000000000 --- a/src/TNL/Containers/ArrayView_impl.h +++ /dev/null @@ -1,392 +0,0 @@ -/*************************************************************************** - ArrayView_impl.h - description - ------------------- - begin : Sep 1, 2018 - copyright : (C) 2018 by Tomas Oberhuber et al. - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -#include - -#include -#include - -#include "ArrayView.h" - -namespace TNL { -namespace Containers { - -// explicit initialization by raw data pointer and size -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( Value* data, Index size ) : data(data), size(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." ); -} - -// initialization from other array containers (using shallow copy) -template< typename Value, - typename Device, - typename Index > - template< typename Value_ > -__cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( Array< Value_, Device, Index >& array ) -{ - this->bind( array.getData(), array.getSize() ); -} - -template< typename Value, - typename Device, - typename Index > - template< int Size, typename Value_ > -__cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( StaticArray< Size, Value_ >& array ) -{ - this->bind( array.getData(), 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() ); -} - -template< typename Value, - typename Device, - typename Index > - template< int Size, typename Value_ > -__cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( const StaticArray< Size, Value_ >& array ) -{ - this->bind( array.getData(), Size ); -} - -// methods for rebinding (reinitialization) -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -void -ArrayView< Value, Device, Index >:: -bind( Value* data, Index 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." ); - - this->data = data; - this->size = size; -} - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -void ArrayView< Value, Device, Index >::bind( ArrayView view ) -{ - bind( view.getData(), view.getSize() ); -} - - -// Copy-assignment does deep copy, just like regular array, but the sizes -// must match (i.e. copy-assignment cannot resize). -template< typename Value, - typename Device, - typename Index > -ArrayView< Value, Device, Index >& -ArrayView< Value, Device, Index >:: -operator=( const ArrayView& view ) -{ - TNL_ASSERT_EQ( getSize(), view.getSize(), "The sizes of the array views must be equal, views are not resizable." ); - if( getSize() > 0 ) - Algorithms::ArrayOperations< Device >::copyMemory( getData(), view.getData(), getSize() ); - 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 -ArrayView< Value, Device, Index >:: -getType() -{ - return String( "Containers::ArrayView< " ) + ", " + - TNL::getType< Value >() + ", " + - Device::getDeviceType() + ", " + - TNL::getType< Index >() + " >"; -} - - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -void -ArrayView< Value, Device, Index >:: -swap( ArrayView& array ) -{ - TNL::swap( data, array.data ); - TNL::swap( size, array.size ); -} - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -void -ArrayView< Value, Device, Index >:: -reset() -{ - data = nullptr; - size = 0; -} - - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -const -Value* ArrayView< Value, Device, Index >:: -getData() const -{ - return data; -} - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -Value* -ArrayView< Value, Device, Index >:: -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 > -__cuda_callable__ -Index -ArrayView< Value, Device, Index >:: -getSize() const -{ - return size; -} - -template< typename Value, - typename Device, - typename Index > -void -ArrayView< Value, Device, Index >:: -setElement( Index i, Value value ) -{ - TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); - TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); - return Algorithms::ArrayOperations< Device >::setMemoryElement( &data[ i ], value ); -} - -template< typename Value, - typename Device, - typename Index > -Value -ArrayView< Value, Device, Index >:: -getElement( Index i ) const -{ - TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); - TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); - return Algorithms::ArrayOperations< Device >::getMemoryElement( &data[ i ] ); -} - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -Value& ArrayView< Value, Device, Index >:: -operator[]( Index i ) -{ - TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); - TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); - return data[ i ]; -} - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -const -Value& ArrayView< Value, Device, Index >:: -operator[]( Index i ) const -{ - TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); - TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); - return data[ i ]; -} - -template< typename Value, - typename Device, - typename Index > - template< typename Value_, typename Device_, typename Index_ > -bool -ArrayView< Value, Device, Index >:: -operator==( const ArrayView< Value_, Device_, Index_ >& view ) const -{ - if( view.getSize() != getSize() ) - return false; - if( getSize() == 0 ) - return true; - return Algorithms::ArrayOperations< Device, Device_ >::compareMemory( getData(), view.getData(), getSize() ); -} - -template< typename Value_, - typename Device_, - typename Index_ > - template< typename ArrayT > -bool -ArrayView< Value_, Device_, Index_ >:: -operator == ( const ArrayT& array ) const -{ - if( array.getSize() != this->getSize() ) - return false; - if( this->getSize() == 0 ) - return true; - 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_ > -bool -ArrayView< Value, Device, Index >:: -operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const -{ - return ! ( *this == view ); -} - -template< typename Value_, - typename Device_, - typename Index_ > - template< typename ArrayT > -bool -ArrayView< Value_, Device_, Index_ >:: -operator != ( const ArrayT& array ) const -{ - return ! ( *this == array ); -} - -template< typename Value, - typename Device, - typename Index > -void -ArrayView< Value, Device, Index >:: -setValue( Value value ) -{ - TNL_ASSERT_GT( size, 0, "Attempted to set value to an empty array view." ); - Algorithms::ArrayOperations< Device >::setMemory( getData(), value, getSize() ); -} - -template< typename Value, - typename Device, - typename Index > -bool -ArrayView< Value, Device, Index >:: -containsValue( Value value ) const -{ - return Algorithms::ArrayOperations< Device >::containsValue( data, size, value ); -} - -template< typename Value, - typename Device, - typename Index > -bool -ArrayView< Value, Device, Index >:: -containsOnlyValue( Value value ) const -{ - return Algorithms::ArrayOperations< Device >::containsOnlyValue( data, size, value ); -} - -template< typename Value, - typename Device, - typename Index > -ArrayView< Value, Device, Index >:: -operator bool() const -{ - return data; -} - - -template< typename Value, typename Device, typename Index > -std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Index >& v ) -{ - str << "[ "; - if( v.getSize() > 0 ) - { - str << v.getElement( 0 ); - for( Index i = 1; i < v.getSize(); i++ ) - str << ", " << v.getElement( i ); - } - str << " ]"; - return str; -} - -} // namespace Containers -} // namespace TNL diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index 28fa8c5cb..ccbea647a 100644 --- a/src/UnitTests/Containers/ArrayTest.h +++ b/src/UnitTests/Containers/ArrayTest.h @@ -528,23 +528,6 @@ TYPED_TEST( ArrayTest, assignmentOperatorWithDifferentType ) testArrayAssignmentWithDifferentType< ArrayType >(); } -TYPED_TEST( ArrayTest, evaluate ) -{ - using ArrayType = typename TestFixture::ArrayType; - using IndexType = typename ArrayType::IndexType; - ArrayType u( 10 ); - - - // TODO: Move to ArrayView - /*auto f = [] __cuda_callable__ ( IndexType i ) - { - return 3 * i % 4; - }; - u.evaluate( f ); - for( int i = 0; i < 10; i++ ) - EXPECT_EQ( u.getElement( i ), 3 * i % 4 );*/ -} - TYPED_TEST( ArrayTest, SaveAndLoad ) { using ArrayType = typename TestFixture::ArrayType; diff --git a/src/UnitTests/Containers/ArrayViewTest.h b/src/UnitTests/Containers/ArrayViewTest.h index 7f3cc7bb3..df62e10dc 100644 --- a/src/UnitTests/Containers/ArrayViewTest.h +++ b/src/UnitTests/Containers/ArrayViewTest.h @@ -306,6 +306,25 @@ TYPED_TEST( ArrayViewTest, elementwiseAccess ) testArrayViewElementwiseAccess( ArrayType() ); } +TYPED_TEST( ArrayViewTest, evaluate ) +{ + using ArrayType = typename TestFixture::ArrayType; + using IndexType = typename ArrayType::IndexType; + using ViewType = ArrayView< Value, Devices::Cuda, Index >; + ArrayType u( 10 ); + 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, containsValue ) { using ArrayType = typename TestFixture::ArrayType; -- GitLab From db7a6e8db72ea6ee3a94ecc19a2abfafb6cddce1 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Tue, 9 Apr 2019 14:15:46 +0200 Subject: [PATCH 53/72] Fixing Multimap unit test. --- src/UnitTests/Containers/Multimaps/MultimapTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp index b0ff7cf81..4612c1dd3 100644 --- a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp +++ b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp @@ -42,7 +42,7 @@ 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 ] ); @@ -81,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 ); -- GitLab From 221fc89e25e7f9498a24efb2f3a6844b030f3a13 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Tue, 9 Apr 2019 14:16:19 +0200 Subject: [PATCH 54/72] Adding ArrayView example. --- src/Examples/Containers/ArrayViewExample.cpp | 85 ++++++++++++++++++++ src/Examples/Containers/ArrayViewExample.cu | 1 + 2 files changed, 86 insertions(+) create mode 100644 src/Examples/Containers/ArrayViewExample.cpp create mode 120000 src/Examples/Containers/ArrayViewExample.cu diff --git a/src/Examples/Containers/ArrayViewExample.cpp b/src/Examples/Containers/ArrayViewExample.cpp new file mode 100644 index 000000000..88ee81f86 --- /dev/null +++ b/src/Examples/Containers/ArrayViewExample.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include + +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; + ArrayType a1( size ), a2( size ); + + /*** + * You may initiate the array using setElement + */ + for( int i = 0; i< size; i++ ) + a1.setElement( i, i ); + + /*** + * You may also assign value to all array elements ... + */ + a2 = 0.0; + + /*** + * ... 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 = v; + a1 = l; + + /*** + * 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; + + /*** + * More efficient way of array elements manipulation is with the lambda functions + */ + ArrayType a3( size ); + 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 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 000000000..10c7b94b2 --- /dev/null +++ b/src/Examples/Containers/ArrayViewExample.cu @@ -0,0 +1 @@ +ArrayViewExample.cpp \ No newline at end of file -- GitLab From 2d51d1acabbcfb7da9ed5c3683d21d1afee5d3aa Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Tue, 9 Apr 2019 19:29:54 +0200 Subject: [PATCH 55/72] [WIP] Fixing ArrayView and Array after revision changes. --- src/Examples/Containers/ArrayExample.cpp | 13 +- src/Examples/Containers/ArrayViewExample.cpp | 26 +-- src/Examples/Containers/CMakeLists.txt | 2 +- .../Containers/Algorithms/ArrayAssignment.h | 10 + src/TNL/Containers/Array.h | 130 +++++------ src/TNL/Containers/Array.hpp | 8 +- src/TNL/Containers/ArrayView.h | 209 ++++++++++-------- src/TNL/Object.h | 4 + src/TNL/Object.hpp | 17 ++ src/UnitTests/Containers/ArrayViewTest.h | 5 +- src/UnitTests/ObjectTest.cpp | 18 ++ 11 files changed, 258 insertions(+), 184 deletions(-) diff --git a/src/Examples/Containers/ArrayExample.cpp b/src/Examples/Containers/ArrayExample.cpp index 7d26a8fcd..5ab191202 100644 --- a/src/Examples/Containers/ArrayExample.cpp +++ b/src/Examples/Containers/ArrayExample.cpp @@ -46,21 +46,10 @@ void arrayExample() if( a1.containsOnlyValue( 0 ) ) std::cout << "a2 contains only value 0." << std::endl; - /*** - * More efficient way of array elements manipulation is with the lambda functions - */ - ArrayType a3( size ); - 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 data with the swap method. */ - a1.swap( a3 ); + a1.swap( a2 ); /*** * Of course, you may save it to file and load again diff --git a/src/Examples/Containers/ArrayViewExample.cpp b/src/Examples/Containers/ArrayViewExample.cpp index 88ee81f86..087dc19c6 100644 --- a/src/Examples/Containers/ArrayViewExample.cpp +++ b/src/Examples/Containers/ArrayViewExample.cpp @@ -2,6 +2,7 @@ #include #include #include +#include using namespace TNL; using namespace std; @@ -15,29 +16,23 @@ void arrayViewExample() const int size = 10; using ArrayType = Containers::Array< int, Device >; using IndexType = typename ArrayType::IndexType; - ArrayType a1( size ), a2( size ); + using ViewType = Containers::ArrayView< int, Device >; + ArrayType _a1( size ), _a2( size ); + ViewType a1( _a1 ), a2( _a2 ); /*** - * You may initiate the array using setElement + * 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 elements ... + * You may also assign value to all array view elements ... */ a2 = 0.0; /*** - * ... 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 = v; - a1 = l; - - /*** - * Simple array values checks can be done as follows ... + * Simple array view values checks can be done as follows ... */ if( a1.containsValue( 1 ) ) std::cout << "a1 contains value 1." << std::endl; @@ -47,9 +42,10 @@ void arrayViewExample() std::cout << "a2 contains only value 0." << std::endl; /*** - * More efficient way of array elements manipulation is with the lambda functions + * More efficient way of array view elements manipulation is with the lambda functions */ - ArrayType a3( size ); + ArrayType _a3( size ); + ViewType a3( _a3 ); auto f1 = [] __cuda_callable__ ( IndexType i ) -> int { return 2 * i;}; a3.evaluate( f1 ); @@ -58,7 +54,7 @@ void arrayViewExample() std::cerr << "Something is wrong!!!" << std::endl; /*** - * You may swap array data with the swap method. + * You may swap array view data with the swap method. */ a1.swap( a3 ); diff --git a/src/Examples/Containers/CMakeLists.txt b/src/Examples/Containers/CMakeLists.txt index 577c8c70c..b70b12670 100644 --- a/src/Examples/Containers/CMakeLists.txt +++ b/src/Examples/Containers/CMakeLists.txt @@ -8,7 +8,7 @@ ENDIF() IF( BUILD_CUDA ) CUDA_ADD_EXECUTABLE( ArrayViewExampleCuda ArrayViewExample.cu ) - ADD_CUSTOM_COMMAND( COMMAND ArrayExampleCuda > ArrayViewExampleCuda.out OUTPUT ArrayViewExampleCuda.out ) + 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 ) diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 28f7557f3..04760503c 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -50,8 +50,14 @@ 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." ); ArrayOperations< typename Array::DeviceType, typename T::DeviceType >::template copyMemory< typename Array::ValueType, typename T::ValueType, typename Array::IndexType > ( a.getArrayData(), t.getArrayData(), t.getSize() ); @@ -66,6 +72,10 @@ template< typename Array, typename T > struct ArrayAssignment< Array, T, false > { + static void resize( Array& a, const T& t ) + { + TNL_ASSERT_TRUE( !a.empty(), "Cannot assign value to empty array." ); + }; static void assign( Array& a, const T& t ) { ArrayOperations< typename Array::DeviceType >::template diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 223057c3b..a3f667d6d 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -26,14 +26,14 @@ namespace Containers { template< int, typename > class StaticArray; /** - * \brief Array is responsible for memory management, basic elements - * manipulation and I/O operations. + * \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. * - * In the \e Device type, the Array remembers where the memory is allocated. + * 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[] @@ -44,7 +44,7 @@ template< int, typename > class StaticArray; * 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. + * 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 @@ -55,7 +55,7 @@ template< int, typename > class StaticArray; * * \par Example * \include ArrayExample.cpp - * + * * See also \ref Containers::ArravView, \ref Containers::Vector, \ref Containers::VectorView. */ template< typename Value, @@ -89,12 +89,12 @@ class Array : public Object /** * \brief Constructor with data pointer and size. * - * In this case, the Array just encapsulates the pointer \e data. No + * 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. */ @@ -113,7 +113,7 @@ class Array : public Object * * The constructor does not make a deep copy, but binds to the supplied array. * 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. @@ -124,14 +124,14 @@ class Array : public Object /** * \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 > @@ -139,7 +139,7 @@ class Array : public Object /** * \brief Initialize the array from std::list. - * + * * @param list Input STL list. */ template< typename InValue > @@ -147,7 +147,7 @@ class Array : public Object /** * \brief Initialize the array from std::vector. - * + * * @param vector Input STL vector. */ template< typename InValue > @@ -155,28 +155,28 @@ class Array : public Object /** * \brief Returns type of array in C++ style. - * + * * \return String with array type. */ static String getType(); /** * \brief Returns type of array in C++ style. - * + * * \return String with array type. */ virtual String getTypeVirtual() const; /** * \brief Returns type of array in C++ style where device is always \ref Devices::Host. - * + * * \return String with serialization array type. */ static String getSerializationType(); /** * \brief Returns type of array in C++ style where device is always \ref Devices::Host. - * + * * \return String with serialization array type. */ virtual String getSerializationTypeVirtual() const; @@ -196,7 +196,7 @@ class Array : public Object * \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; @@ -205,7 +205,7 @@ class Array : public Object * \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 is any array type having method \ref getSize(). * \param array is reference to the source array. */ @@ -217,9 +217,9 @@ class Array : public Object * * Releases old data and binds this array with new \e _data. Also sets new * \e _size of this array. - * + * * This method is obsolete, use \ref ArrayView instead. - * + * * \param _data Pointer to new data. * \param _size Size of new _data. Number of elements. */ @@ -231,9 +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. @@ -249,9 +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. */ @@ -262,7 +262,7 @@ class Array : public Object * \brief Swaps this array with another. * * 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 ); @@ -276,53 +276,53 @@ class Array : public Object /** * \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 Data pointer getter. - * + * * This method can be called from device kernels. - * + * * \return Pointer to array data. */ __cuda_callable__ Value* getData(); /** * \brief Data pointer getter for constant instances. - * + * * Use this method in algorithms where you want to emphasize that - * C-style array pointer is required. - * + * 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. - * + * 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. * * 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. */ @@ -333,9 +333,9 @@ class Array : public Object * * 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; @@ -345,9 +345,9 @@ class Array : public Object * * 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 ); @@ -357,9 +357,9 @@ class Array : public Object * * 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; @@ -368,7 +368,7 @@ class Array : public Object * \brief Assigns \e array to this array, replacing its current contents. * * \param array is reference to the array. - * + * * \return Reference to this array. */ Array& operator = ( const Array& array ); @@ -377,7 +377,7 @@ class Array : public Object * \brief Move contents of \e array to this array. * * \param array is reference to the array. - * + * * \return Reference to this array. */ Array& operator = ( Array&& array ); @@ -387,15 +387,15 @@ class Array : public Object * * 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 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 + * 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 > @@ -403,7 +403,7 @@ class Array : public Object /** * \brief Assigns STL list to this array. - * + * * \param list is STL list * * \return Reference to this array. @@ -413,9 +413,9 @@ class Array : public Object /** * \brief Assigns STL vector to this array. - * + * * \param vector is STL vector - * + * * \return Reference to this array. */ template< typename InValue > @@ -426,7 +426,7 @@ class Array : public Object * * \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 > @@ -437,7 +437,7 @@ class Array : public Object * * \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 > @@ -459,12 +459,12 @@ class Array : public Object * * 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, @@ -476,12 +476,12 @@ class Array : public Object * * 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, @@ -490,14 +490,14 @@ class Array : public Object /** * \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. * @@ -519,6 +519,8 @@ 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. */ void boundLoad( File& file ); diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index d7cc4d234..c62c1c8b8 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -482,7 +482,7 @@ operator = ( const Array< Value, Device, Index >& array ) copyMemory( this->getData(), array.getData(), array.getSize() ); - return ( *this ); + return *this; } template< typename Value, @@ -501,6 +501,7 @@ operator = ( Array< Value, Device, Index >&& array ) array.data = nullptr; array.allocationPointer = nullptr; array.referenceCounter = nullptr; + return *this; } @@ -512,8 +513,9 @@ Array< Value, Device, Index >& Array< Value, Device, Index >:: operator = ( const T& data ) { + Algorithms::ArrayAssignment< ThisType, T >::resize( *this, data ); Algorithms::ArrayAssignment< ThisType, T >::assign( *this, data ); - return ( *this ); + return *this; } template< typename Value, @@ -526,6 +528,7 @@ operator = ( const std::list< InValue >& list ) { this->setSize( list.size() ); Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list ); + return *this; } template< typename Value, @@ -539,6 +542,7 @@ 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, diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 3c30b0429..353988c4f 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -36,7 +36,7 @@ class StaticArray; * \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. + * 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[] @@ -47,16 +47,16 @@ class StaticArray; * 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. + * 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. */ @@ -71,17 +71,19 @@ public: using IndexType = Index; using HostType = ArrayView< Value, Devices::Host, Index >; using CudaType = ArrayView< Value, Devices::Cuda, Index >; + using ThisType = ArrayView< Value, Device, Index >; + using SerializationType = Array< Value, Devices::Host, Index >; /** * \brief Returns type of array view in C++ style. - * + * * \return String with array view type. */ - static String getType(); - + static String getType(); + /** * \brief Basic constructor for empty ArrayView. - * + * * This method can be called from device kernels. */ __cuda_callable__ @@ -89,9 +91,9 @@ public: /** * \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 */ @@ -103,9 +105,9 @@ public: * 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__ @@ -113,11 +115,11 @@ public: /** * \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_ > @@ -127,9 +129,9 @@ public: /** * \brief Default move-constructor. - * + * * This method can be called from device kernels. - * + * * \param view is ArrayView to be moved to this ArrayView. */ __cuda_callable__ @@ -137,11 +139,11 @@ public: /** * \brief Constructor for initialization from other array containers. - * + * * It makes shallow copy only. - * + * * This method can be called from device kernels. - * + * * \tparam Value_ can be both const and non-const qualified Value. */ template< typename Value_ > @@ -150,12 +152,12 @@ public: /** * \brief Constructor for initialization with static array. - * + * * This method can be called from device kernels. - * + * * \tparam Size is size of the static array. * \tparam Value_ can be both const and non-const qualified Value. - * + * * \param array is a static array the array view is initialized with. */ template< int Size, typename Value_ > @@ -164,12 +166,12 @@ public: /** * \brief Copy constructor from constant Array. - * + * * This constructor will be used only when Value is const-qualified * (const views are initializable by const references). - * + * * This method can be called from device kernels. - * + * * \tparam Value_ can be both const and non-const qualified Value * \param array is an array the array view is initialized with. */ @@ -179,12 +181,12 @@ public: /** * \brief Constructor for initialization with static array. - * + * * This method can be called from device kernels. - * + * * \tparam Size is size of the static array. * \tparam Value_ can be both const and non-const qualified Value. - * + * * \param array is a static array the array view is initialized with. */ template< int Size, typename Value_ > // template catches both const and non-const qualified Value @@ -193,9 +195,9 @@ public: /** * \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. */ @@ -204,23 +206,23 @@ public: /** * \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 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 ); @@ -230,15 +232,15 @@ public: * * 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 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 + * 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 > @@ -248,19 +250,19 @@ public: * \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__ @@ -268,9 +270,9 @@ public: /** * \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__ @@ -278,9 +280,9 @@ public: /** * \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__ @@ -288,35 +290,35 @@ public: /** * \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. - * + * 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. - * + * 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__ @@ -327,10 +329,10 @@ public: * * 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 ); /** @@ -340,7 +342,7 @@ public: * 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; @@ -351,11 +353,11 @@ public: * 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 ); @@ -365,11 +367,11 @@ public: * 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; @@ -380,9 +382,9 @@ public: * \tparam Device_ is the device type of the right-hand-side array view. * \tparam Index_ is the index type of the right-hand-side array view. * \param view is reference to the right-hand-side array view. - * + * * \return True if both array views are equal element-wise and false otherwise. - */ + */ template< typename Value_, typename Device_, typename Index_ > bool operator==( const ArrayView< Value_, Device_, Index_ >& view ) const; @@ -391,11 +393,11 @@ public: * * \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; + bool operator == ( const ArrayT& array ) const; /** * \brief Comparison negation operator with another array view \e view. @@ -404,7 +406,7 @@ public: * \tparam Device_ is the device type of the right-hand-side array view. * \tparam Index_ is the index type of the right-hand-side array view. * \param view is reference to the right-hand-side array view. - * + * * \return True if both array views are not equal element-wise and false otherwise. */ template< typename Value_, typename Device_, typename Index_ > @@ -415,9 +417,9 @@ public: * * \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; @@ -429,7 +431,7 @@ public: * \param v Reference to a value. */ void setValue( Value value ); - + /** * \brief Sets the array elements using given lambda function. * @@ -440,21 +442,21 @@ public: template< typename Function > void evaluate( Function& f, const Index begin = 0, - Index end = -1 ); + 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; /** @@ -462,26 +464,55 @@ public: * * 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; /** * \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 Value* data = nullptr; diff --git a/src/TNL/Object.h b/src/TNL/Object.h index c66e5ccfc..92ed9fef7 100644 --- a/src/TNL/Object.h +++ b/src/TNL/Object.h @@ -170,6 +170,10 @@ String getObjectType( const String& fileName ); 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 diff --git a/src/TNL/Object.hpp b/src/TNL/Object.hpp index d4057c96b..1e83f036f 100644 --- a/src/TNL/Object.hpp +++ b/src/TNL/Object.hpp @@ -151,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/UnitTests/Containers/ArrayViewTest.h b/src/UnitTests/Containers/ArrayViewTest.h index df62e10dc..046d10619 100644 --- a/src/UnitTests/Containers/ArrayViewTest.h +++ b/src/UnitTests/Containers/ArrayViewTest.h @@ -309,10 +309,13 @@ TYPED_TEST( ArrayViewTest, elementwiseAccess ) TYPED_TEST( ArrayViewTest, evaluate ) { using ArrayType = typename TestFixture::ArrayType; + using ValueType = typename ArrayType::ValueType; + using DeviceType = typename ArrayType::DeviceType; using IndexType = typename ArrayType::IndexType; - using ViewType = ArrayView< Value, Devices::Cuda, Index >; + using ViewType = ArrayView< ValueType, DeviceType, IndexType >; ArrayType u( 10 ); ViewType v( u ); + auto f = [] __cuda_callable__ ( IndexType i ) { return 3 * i % 4; diff --git a/src/UnitTests/ObjectTest.cpp b/src/UnitTests/ObjectTest.cpp index 21b12f958..ac0281afa 100644 --- a/src/UnitTests/ObjectTest.cpp +++ b/src/UnitTests/ObjectTest.cpp @@ -75,6 +75,24 @@ TEST( ObjectTest, parseObjectTypeTest ) expected = { "A", "b", "c ", "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 -- GitLab From 0f2800df822320840b136bcacb1a23f000c09aaa Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Tue, 9 Apr 2019 19:52:54 +0200 Subject: [PATCH 56/72] [WIP] Restoring renamed ArrayView.hpp. --- src/TNL/Containers/ArrayView.hpp | 460 +++++++++++++++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100644 src/TNL/Containers/ArrayView.hpp diff --git a/src/TNL/Containers/ArrayView.hpp b/src/TNL/Containers/ArrayView.hpp new file mode 100644 index 000000000..ad89dd7b6 --- /dev/null +++ b/src/TNL/Containers/ArrayView.hpp @@ -0,0 +1,460 @@ +/*************************************************************************** + ArrayView_impl.h - description + ------------------- + begin : Sep 1, 2018 + copyright : (C) 2018 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include + +#include +#include + +#include "ArrayView.h" + +namespace TNL { +namespace Containers { + +template< typename Value, + typename Device, + typename Index > +String +ArrayView< Value, Device, Index >:: +getType() +{ + return String( "Containers::ArrayView< " ) + ", " + + TNL::getType< Value >() + ", " + + Device::getDeviceType() + ", " + + TNL::getType< Index >() + " >"; +} + +// explicit initialization by raw data pointer and size +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +ArrayView< Value, Device, Index >:: +ArrayView( Value* data, Index size ) : data(data), size(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." ); +} + +// initialization from other array containers (using shallow copy) +template< typename Value, + typename Device, + typename Index > + template< typename Value_ > +__cuda_callable__ +ArrayView< Value, Device, Index >:: +ArrayView( Array< Value_, Device, Index >& array ) +{ + this->bind( array.getData(), array.getSize() ); +} + +template< typename Value, + typename Device, + typename Index > + template< int Size, typename Value_ > +__cuda_callable__ +ArrayView< Value, Device, Index >:: +ArrayView( StaticArray< Size, Value_ >& array ) +{ + this->bind( array.getData(), 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() ); +} + +template< typename Value, + typename Device, + typename Index > + template< int Size, typename Value_ > +__cuda_callable__ +ArrayView< Value, Device, Index >:: +ArrayView( const StaticArray< Size, Value_ >& array ) +{ + this->bind( array.getData(), Size ); +} + +// methods for rebinding (reinitialization) +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +void +ArrayView< Value, Device, Index >:: +bind( Value* data, Index 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." ); + + this->data = data; + this->size = size; +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +void ArrayView< Value, Device, Index >::bind( ArrayView view ) +{ + bind( view.getData(), view.getSize() ); +} + +// Copy-assignment does deep copy, just like regular array, but the sizes +// must match (i.e. copy-assignment cannot resize). +template< typename Value, + typename Device, + typename Index > +ArrayView< Value, Device, Index >& +ArrayView< Value, Device, Index >:: +operator=( const ArrayView& view ) +{ + TNL_ASSERT_EQ( getSize(), view.getSize(), "The sizes of the array views must be equal, views are not resizable." ); + if( getSize() > 0 ) + Algorithms::ArrayOperations< Device >::copyMemory( getData(), view.getData(), getSize() ); + return *this; +} + +template< typename Value, + typename Device, + typename Index > + template< typename T > +ArrayView< Value, Device, Index >& +ArrayView< Value, Device, Index >:: +operator = ( const T& data ) +{ + Algorithms::ArrayAssignment< ThisType, T >::assign( *this, data ); + return *this; +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +void +ArrayView< Value, Device, Index >:: +swap( ArrayView& array ) +{ + TNL::swap( data, array.data ); + TNL::swap( size, array.size ); +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +void +ArrayView< Value, Device, Index >:: +reset() +{ + data = nullptr; + size = 0; +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +const +Value* ArrayView< Value, Device, Index >:: +getData() const +{ + return data; +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +Value* +ArrayView< Value, Device, Index >:: +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 > +__cuda_callable__ +Index +ArrayView< Value, Device, Index >:: +getSize() const +{ + return size; +} + +template< typename Value, + typename Device, + typename Index > +void +ArrayView< Value, Device, Index >:: +setElement( Index i, Value value ) +{ + TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); + TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); + return Algorithms::ArrayOperations< Device >::setMemoryElement( &data[ i ], value ); +} + +template< typename Value, + typename Device, + typename Index > +Value +ArrayView< Value, Device, Index >:: +getElement( Index i ) const +{ + TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); + TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); + return Algorithms::ArrayOperations< Device >::getMemoryElement( &data[ i ] ); +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +Value& ArrayView< Value, Device, Index >:: +operator[]( Index i ) +{ + TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); + TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); + return data[ i ]; +} + +template< typename Value, + typename Device, + typename Index > +__cuda_callable__ +const +Value& ArrayView< Value, Device, Index >:: +operator[]( Index i ) const +{ + TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); + TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." ); + return data[ i ]; +} + +template< typename Value, + typename Device, + typename Index > + template< typename Value_, typename Device_, typename Index_ > +bool +ArrayView< Value, Device, Index >:: +operator==( const ArrayView< Value_, Device_, Index_ >& view ) const +{ + if( view.getSize() != getSize() ) + return false; + if( getSize() == 0 ) + return true; + return Algorithms::ArrayOperations< Device, Device_ >::compareMemory( getData(), view.getData(), getSize() ); +} + +template< typename Value_, + typename Device_, + typename Index_ > + template< typename ArrayT > +bool +ArrayView< Value_, Device_, Index_ >:: +operator == ( const ArrayT& array ) const +{ + if( array.getSize() != this->getSize() ) + return false; + if( this->getSize() == 0 ) + return true; + 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_ > +bool +ArrayView< Value, Device, Index >:: +operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const +{ + return ! ( *this == view ); +} + +template< typename Value_, + typename Device_, + typename Index_ > + template< typename ArrayT > +bool +ArrayView< Value_, Device_, Index_ >:: +operator != ( const ArrayT& array ) const +{ + return ! ( *this == array ); +} + +template< typename Value, + typename Device, + typename Index > +void +ArrayView< Value, Device, Index >:: +setValue( Value value ) +{ + TNL_ASSERT_GT( size, 0, "Attempted to set value to an empty array view." ); + 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 > +bool +ArrayView< Value, Device, Index >:: +containsValue( Value value ) const +{ + return Algorithms::ArrayOperations< Device >::containsValue( data, size, value ); +} + +template< typename Value, + typename Device, + typename Index > +bool +ArrayView< Value, Device, Index >:: +containsOnlyValue( Value value ) const +{ + return Algorithms::ArrayOperations< Device >::containsOnlyValue( data, size, value ); +} + +template< typename Value, + typename Device, + typename Index > +bool +ArrayView< Value, Device, Index >:: +empty() const +{ + return data; +} + +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 ) +{ + str << "[ "; + if( v.getSize() > 0 ) + { + str << v.getElement( 0 ); + for( Index i = 1; i < v.getSize(); i++ ) + str << ", " << v.getElement( i ); + } + str << " ]"; + return str; +} + +} // namespace Containers +} // namespace TNL -- GitLab From 886e5ceaa3e5c96ee5f45aa6e04da66fbe653eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Tue, 9 Apr 2019 19:59:10 +0200 Subject: [PATCH 57/72] Removed ThisType from Array and ArrayView --- src/TNL/Containers/Array.h | 1 - src/TNL/Containers/Array.hpp | 4 ++-- src/TNL/Containers/ArrayView.h | 1 - src/TNL/Containers/ArrayView.hpp | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index a3f667d6d..e09858bd5 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -68,7 +68,6 @@ class Array : public Object using ValueType = Value; using DeviceType = Device; using IndexType = Index; - using ThisType = Containers::Array< ValueType, DeviceType, IndexType >; using HostType = Containers::Array< Value, Devices::Host, Index >; using CudaType = Containers::Array< Value, Devices::Cuda, Index >; diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index c62c1c8b8..c9a458ff5 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -513,8 +513,8 @@ Array< Value, Device, Index >& Array< Value, Device, Index >:: operator = ( const T& data ) { - Algorithms::ArrayAssignment< ThisType, T >::resize( *this, data ); - Algorithms::ArrayAssignment< ThisType, T >::assign( *this, data ); + Algorithms::ArrayAssignment< Array, T >::resize( *this, data ); + Algorithms::ArrayAssignment< Array, T >::assign( *this, data ); return *this; } diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 353988c4f..abf05bfc2 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -71,7 +71,6 @@ public: using IndexType = Index; using HostType = ArrayView< Value, Devices::Host, Index >; using CudaType = ArrayView< Value, Devices::Cuda, Index >; - using ThisType = ArrayView< Value, Device, Index >; using SerializationType = Array< Value, Devices::Host, Index >; /** diff --git a/src/TNL/Containers/ArrayView.hpp b/src/TNL/Containers/ArrayView.hpp index ad89dd7b6..f08eeec2f 100644 --- a/src/TNL/Containers/ArrayView.hpp +++ b/src/TNL/Containers/ArrayView.hpp @@ -140,7 +140,7 @@ ArrayView< Value, Device, Index >& ArrayView< Value, Device, Index >:: operator = ( const T& data ) { - Algorithms::ArrayAssignment< ThisType, T >::assign( *this, data ); + Algorithms::ArrayAssignment< ArrayView, T >::assign( *this, data ); return *this; } -- GitLab From 206d69a6f782997cb9b29f5b0e3c36780df37bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Tue, 9 Apr 2019 22:13:03 +0200 Subject: [PATCH 58/72] Fixing ArrayView evaluate test. --- src/UnitTests/Containers/ArrayViewTest.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/UnitTests/Containers/ArrayViewTest.h b/src/UnitTests/Containers/ArrayViewTest.h index 046d10619..50c8d624b 100644 --- a/src/UnitTests/Containers/ArrayViewTest.h +++ b/src/UnitTests/Containers/ArrayViewTest.h @@ -306,20 +306,20 @@ TYPED_TEST( ArrayViewTest, elementwiseAccess ) testArrayViewElementwiseAccess( ArrayType() ); } -TYPED_TEST( ArrayViewTest, evaluate ) +template< typename ArrayType > +void ArrayViewEvaluateTest( ArrayType& u ) { - using ArrayType = typename TestFixture::ArrayType; using ValueType = typename ArrayType::ValueType; using DeviceType = typename ArrayType::DeviceType; using IndexType = typename ArrayType::IndexType; using ViewType = ArrayView< ValueType, DeviceType, IndexType >; - ArrayType u( 10 ); ViewType v( u ); - + auto f = [] __cuda_callable__ ( IndexType i ) { return 3 * i % 4; }; + v.evaluate( f ); for( int i = 0; i < 10; i++ ) { @@ -328,6 +328,13 @@ TYPED_TEST( ArrayViewTest, evaluate ) } } +TYPED_TEST( ArrayViewTest, evaluate ) +{ + using ArrayType = typename TestFixture::ArrayType; + ArrayType u( 10 ); + ArrayViewEvaluateTest( u ); +} + TYPED_TEST( ArrayViewTest, containsValue ) { using ArrayType = typename TestFixture::ArrayType; -- GitLab From fc4f37ae243050cebc4205f8634ca8a008e37b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Tue, 9 Apr 2019 23:03:33 +0200 Subject: [PATCH 59/72] Removed TypeTraits.h - obsolete, not used even in ArrayAssignment now --- src/TNL/Containers/Array.h | 1 - src/TNL/Containers/ArrayView.h | 1 - src/TNL/Containers/DistributedArray.h | 1 - src/TNL/Containers/DistributedArrayView.h | 1 - src/TNL/Containers/DistributedVector.h | 1 - src/TNL/Containers/DistributedVectorView.h | 1 - .../Multimaps/EllpackIndexMultimapValues.h | 1 - .../StaticEllpackIndexMultimapValues.h | 1 - src/TNL/Containers/Vector.h | 1 - src/TNL/Containers/VectorView.h | 1 - src/TNL/TypeTraits.h | 21 ------------------- 11 files changed, 31 deletions(-) delete mode 100644 src/TNL/TypeTraits.h diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index e09858bd5..6a7e88e56 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -14,7 +14,6 @@ #include #include #include -#include #include namespace TNL { diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index abf05bfc2..f8453f0f4 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -12,7 +12,6 @@ #pragma once -#include #include #include diff --git a/src/TNL/Containers/DistributedArray.h b/src/TNL/Containers/DistributedArray.h index 22e13fbac..d653fc571 100644 --- a/src/TNL/Containers/DistributedArray.h +++ b/src/TNL/Containers/DistributedArray.h @@ -14,7 +14,6 @@ #include // std::add_const -#include #include #include #include diff --git a/src/TNL/Containers/DistributedArrayView.h b/src/TNL/Containers/DistributedArrayView.h index c2ac79ec5..e9e9e0a48 100644 --- a/src/TNL/Containers/DistributedArrayView.h +++ b/src/TNL/Containers/DistributedArrayView.h @@ -12,7 +12,6 @@ #pragma once -#include #include namespace TNL { diff --git a/src/TNL/Containers/DistributedVector.h b/src/TNL/Containers/DistributedVector.h index 819e6962c..86dc66a28 100644 --- a/src/TNL/Containers/DistributedVector.h +++ b/src/TNL/Containers/DistributedVector.h @@ -12,7 +12,6 @@ #pragma once -#include #include #include diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h index 4e18a86c8..e36e60e00 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -12,7 +12,6 @@ #pragma once -#include #include #include diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h index ae0df5ee5..42addccd1 100644 --- a/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h +++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimapValues.h @@ -13,7 +13,6 @@ #include #include -#include #include namespace TNL { diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h index ad6ba7f5e..1b88f0816 100644 --- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h +++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimapValues.h @@ -13,7 +13,6 @@ #include #include -#include #include namespace TNL { diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h index b66adf9f1..e116508ba 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -10,7 +10,6 @@ #pragma once -#include #include namespace TNL { diff --git a/src/TNL/Containers/VectorView.h b/src/TNL/Containers/VectorView.h index 49c12ee68..6ae0bcb81 100644 --- a/src/TNL/Containers/VectorView.h +++ b/src/TNL/Containers/VectorView.h @@ -12,7 +12,6 @@ #pragma once -#include #include namespace TNL { diff --git a/src/TNL/TypeTraits.h b/src/TNL/TypeTraits.h deleted file mode 100644 index 05e3a6c29..000000000 --- a/src/TNL/TypeTraits.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************** - TypeTraits.h - description - ------------------- - begin : Mar 24, 2019 - copyright : (C) 2019 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -namespace TNL { - - template< typename T > - struct IsArray - { - static constexpr bool value = false; - }; - -} // namespace TNL \ No newline at end of file -- GitLab From fb5a983ebe5d8748b45f3420909ce2a8c469b772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Tue, 9 Apr 2019 23:13:01 +0200 Subject: [PATCH 60/72] Fixed missing and unused includes in Array and ArrayView --- src/TNL/Containers/Array.h | 2 ++ src/TNL/Containers/Array.hpp | 6 +++--- src/TNL/Containers/ArrayView.h | 1 + src/TNL/Containers/ArrayView.hpp | 4 ++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 6a7e88e56..360e0345e 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -12,9 +12,11 @@ #include #include + #include #include #include +#include namespace TNL { /** diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index c9a458ff5..1f83b24d0 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -11,17 +11,17 @@ #pragma once #include + #include -#include #include -#include #include #include #include #include -#include #include +#include "Array.h" + namespace TNL { namespace Containers { diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index f8453f0f4..1ea6febbb 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -12,6 +12,7 @@ #pragma once +#include #include #include diff --git a/src/TNL/Containers/ArrayView.hpp b/src/TNL/Containers/ArrayView.hpp index f08eeec2f..8d6673aee 100644 --- a/src/TNL/Containers/ArrayView.hpp +++ b/src/TNL/Containers/ArrayView.hpp @@ -13,7 +13,11 @@ #include #include +#include #include +#include +#include +#include #include "ArrayView.h" -- GitLab From 2781e3e8fff42b470c0e644f281570a4b50c743f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Tue, 9 Apr 2019 23:20:29 +0200 Subject: [PATCH 61/72] Fixed spaces in Array and ArrayView --- src/TNL/Containers/Array.h | 21 ++++++++++----------- src/TNL/Containers/Array.hpp | 28 ++++++++++++++-------------- src/TNL/Containers/ArrayView.h | 4 ++-- src/TNL/Containers/ArrayView.hpp | 4 ++-- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 360e0345e..30aee6628 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -350,7 +350,7 @@ class Array : public Object * * \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. @@ -362,7 +362,7 @@ class Array : public Object * * \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. @@ -371,7 +371,7 @@ class Array : public Object * * \return Reference to this array. */ - Array& operator = ( const Array& array ); + Array& operator=( const Array& array ); /** * \brief Move contents of \e array to this array. @@ -380,7 +380,7 @@ class Array : public Object * * \return Reference to this array. */ - Array& operator = ( Array&& array ); + Array& operator=( Array&& array ); /** * \brief Assigns either array-like container or single value. @@ -399,7 +399,7 @@ class Array : public Object * \return Reference to this array. */ template< typename T > - Array& operator = ( const T& data ); + Array& operator=( const T& data ); /** * \brief Assigns STL list to this array. @@ -409,7 +409,7 @@ class Array : public Object * \return Reference to this array. */ template< typename InValue > - Array& operator = ( const std::list< InValue >& list ); + Array& operator=( const std::list< InValue >& list ); /** * \brief Assigns STL vector to this array. @@ -419,7 +419,7 @@ class Array : public Object * \return Reference to this array. */ template< typename InValue > - Array& operator = ( const std::vector< InValue >& vector ); + Array& operator=( const std::vector< InValue >& vector ); /** * \brief Comparison operator with another array-like container. @@ -430,7 +430,7 @@ class Array : public Object * \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. @@ -441,7 +441,7 @@ class Array : public Object * \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 elements to given value. @@ -565,10 +565,9 @@ class Array : public Object }; 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 diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 1f83b24d0..40a01bc8c 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -73,7 +73,6 @@ Array( const Array< Value, Device, Index >& array ) allocationPointer( nullptr ), referenceCounter( 0 ) { - //this->bind( array ); this->setSize( array.getSize() ); Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), array.getData(), array.getSize() ); } @@ -276,7 +275,7 @@ Index Array< Value, Device, Index >:: getSize() const { - return this -> size; + return this->size; } template< typename Value, @@ -447,7 +446,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." ); @@ -460,7 +459,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." ); @@ -472,7 +471,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() ) @@ -490,7 +489,7 @@ template< typename Value, typename Index > Array< Value, Device, Index >& Array< Value, Device, Index >:: -operator = ( Array< Value, Device, Index >&& array ) +operator=( Array< Value, Device, Index >&& array ) { this->size = array.size; this->data = array.data; @@ -511,7 +510,7 @@ template< typename Value, template< typename T > Array< Value, Device, Index >& Array< Value, Device, Index >:: -operator = ( const T& data ) +operator=( const T& data ) { Algorithms::ArrayAssignment< Array, T >::resize( *this, data ); Algorithms::ArrayAssignment< Array, T >::assign( *this, data ); @@ -524,7 +523,7 @@ template< typename Value, template< typename InValue > Array< Value, Device, Index >& Array< Value, Device, Index >:: -operator = ( const std::list< InValue >& list ) +operator=( const std::list< InValue >& list ) { this->setSize( list.size() ); Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list ); @@ -537,7 +536,7 @@ template< typename Value, template< typename InValue > Array< Value, Device, Index >& Array< Value, Device, Index >:: -operator = ( const std::vector< InValue >& vector ) +operator=( const std::vector< InValue >& vector ) { if( this->getSize() != vector.size() ) this->setSize( vector.size() ); @@ -551,7 +550,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; @@ -567,9 +566,11 @@ 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, @@ -687,7 +688,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 ) @@ -700,6 +701,5 @@ std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index return str; } - } // namespace Containers } // namespace TNL diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 1ea6febbb..57b958421 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -396,7 +396,7 @@ public: * \return True if both array views are equal element-wise and false otherwise. */ template< typename ArrayT > - bool operator == ( const ArrayT& array ) const; + bool operator==( const ArrayT& array ) const; /** * \brief Comparison negation operator with another array view \e view. @@ -420,7 +420,7 @@ public: * \return True if both array views 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 view elements to given value. diff --git a/src/TNL/Containers/ArrayView.hpp b/src/TNL/Containers/ArrayView.hpp index 8d6673aee..f66fbe2e3 100644 --- a/src/TNL/Containers/ArrayView.hpp +++ b/src/TNL/Containers/ArrayView.hpp @@ -297,7 +297,7 @@ template< typename Value_, template< typename ArrayT > bool ArrayView< Value_, Device_, Index_ >:: -operator == ( const ArrayT& array ) const +operator==( const ArrayT& array ) const { if( array.getSize() != this->getSize() ) return false; @@ -326,7 +326,7 @@ template< typename Value_, template< typename ArrayT > bool ArrayView< Value_, Device_, Index_ >:: -operator != ( const ArrayT& array ) const +operator!=( const ArrayT& array ) const { return ! ( *this == array ); } -- GitLab From dbc325abf5dc726e08b43f428ae7ad1ee8c09565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Tue, 9 Apr 2019 23:28:47 +0200 Subject: [PATCH 62/72] Simplified comparison operators in ArrayView --- src/TNL/Containers/ArrayView.h | 26 -------------------------- src/TNL/Containers/ArrayView.hpp | 30 ++---------------------------- 2 files changed, 2 insertions(+), 54 deletions(-) diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 57b958421..db2f1d106 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -374,19 +374,6 @@ public: __cuda_callable__ const Value& operator[]( Index i ) const; - /** - * \brief Comparison operator with another array view \e view. - * - * \tparam Value_ is the value type of the right-hand-side array view. - * \tparam Device_ is the device type of the right-hand-side array view. - * \tparam Index_ is the index type of the right-hand-side array view. - * \param view is reference to the right-hand-side array view. - * - * \return True if both array views are equal element-wise and false otherwise. - */ - 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. * @@ -398,19 +385,6 @@ public: template< typename ArrayT > bool operator==( const ArrayT& array ) const; - /** - * \brief Comparison negation operator with another array view \e view. - * - * \tparam Value_ is the value type of the right-hand-side array view. - * \tparam Device_ is the device type of the right-hand-side array view. - * \tparam Index_ is the index type of the right-hand-side array view. - * \param view is reference to the right-hand-side array view. - * - * \return True if both array views are not equal element-wise and false otherwise. - */ - template< typename Value_, typename Device_, typename Index_ > - bool operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const; - /** * \brief Comparison negation operator with another array-like container \e array. * diff --git a/src/TNL/Containers/ArrayView.hpp b/src/TNL/Containers/ArrayView.hpp index f66fbe2e3..b31797752 100644 --- a/src/TNL/Containers/ArrayView.hpp +++ b/src/TNL/Containers/ArrayView.hpp @@ -279,24 +279,9 @@ operator[]( Index i ) const template< typename Value, typename Device, typename Index > - template< typename Value_, typename Device_, typename Index_ > -bool -ArrayView< Value, Device, Index >:: -operator==( const ArrayView< Value_, Device_, Index_ >& view ) const -{ - if( view.getSize() != getSize() ) - return false; - if( getSize() == 0 ) - return true; - return Algorithms::ArrayOperations< Device, Device_ >::compareMemory( getData(), view.getData(), getSize() ); -} - -template< typename Value_, - typename Device_, - typename Index_ > template< typename ArrayT > bool -ArrayView< Value_, Device_, Index_ >:: +ArrayView< Value, Device, Index >:: operator==( const ArrayT& array ) const { if( array.getSize() != this->getSize() ) @@ -312,20 +297,9 @@ operator==( const ArrayT& array ) const template< typename Value, typename Device, typename Index > - template< typename Value_, typename Device_, typename Index_ > -bool -ArrayView< Value, Device, Index >:: -operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const -{ - return ! ( *this == view ); -} - -template< typename Value_, - typename Device_, - typename Index_ > template< typename ArrayT > bool -ArrayView< Value_, Device_, Index_ >:: +ArrayView< Value, Device, Index >:: operator!=( const ArrayT& array ) const { return ! ( *this == array ); -- GitLab From 17bea751fbc4301fcd945c8c4379453c7364d639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Tue, 9 Apr 2019 23:41:41 +0200 Subject: [PATCH 63/72] Moved ArrayView::SerializationType from public interface into private section --- src/TNL/Containers/ArrayView.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index db2f1d106..e6a9a5fb8 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -65,13 +65,13 @@ template< typename Value, 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 SerializationType = Array< Value, Devices::Host, Index >; /** * \brief Returns type of array view in C++ style. -- GitLab From 0a4527d08b2565e33ffedfe1c3c23d20675f2f08 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Wed, 10 Apr 2019 13:33:45 +0200 Subject: [PATCH 64/72] Fixing Array - constructors and method empty. --- src/Examples/Containers/ArrayExample.cpp | 8 ++++-- .../Containers/Algorithms/ArrayAssignment.h | 4 +-- src/TNL/Containers/Array.hpp | 9 +++--- src/TNL/Containers/ArrayView.h | 24 ++++++++-------- src/TNL/Containers/ArrayView.hpp | 2 +- src/UnitTests/Containers/ArrayTest.h | 28 +++++++++++-------- 6 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/Examples/Containers/ArrayExample.cpp b/src/Examples/Containers/ArrayExample.cpp index 5ab191202..9dcfd7cbd 100644 --- a/src/Examples/Containers/ArrayExample.cpp +++ b/src/Examples/Containers/ArrayExample.cpp @@ -22,20 +22,24 @@ void arrayExample() */ 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 = v; 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 ... */ diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 04760503c..170d3e253 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -54,7 +54,7 @@ struct ArrayAssignment< Array, T, true > { 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." ); @@ -74,10 +74,10 @@ struct ArrayAssignment< Array, T, false > { static void resize( Array& a, const T& t ) { - TNL_ASSERT_TRUE( !a.empty(), "Cannot assign value to empty array." ); }; 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() ); diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 40a01bc8c..915e3a975 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -142,7 +142,7 @@ Array( const std::initializer_list< InValue >& list ) // 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 >::copyMemory( this->getData(), &( *list.begin() ), list.size() ); + Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), &( *list.begin() ), list.size() ); } template< typename Value, @@ -172,7 +172,7 @@ Array( const std::vector< InValue >& vector ) referenceCounter( 0 ) { this->setSize( vector.size() ); - Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), vector.data(), vector.size() ); + Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), vector.data(), vector.size() ); } template< typename Value, @@ -622,10 +622,11 @@ template< typename Value, typename Device, typename Index > bool +__cuda_callable__ Array< Value, Device, Index >:: empty() const { - return data; + return ( data == nullptr ); } template< typename Value, @@ -635,7 +636,7 @@ void Array< Value, Device, Index >::save( File& file ) const { Object::save( file ); file.save( &this->size ); - if( this->size != 0 ) + if( this->size != 0 ) Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size ); } diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index e6a9a5fb8..68b548747 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -26,7 +26,7 @@ template< int Size, typename Value > class StaticArray; /** - * \brief ArrayView serves for accessing array of data allocated by TNL::Array or + * \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 @@ -39,17 +39,17 @@ class StaticArray; * 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). 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 + * 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. diff --git a/src/TNL/Containers/ArrayView.hpp b/src/TNL/Containers/ArrayView.hpp index b31797752..3d4862922 100644 --- a/src/TNL/Containers/ArrayView.hpp +++ b/src/TNL/Containers/ArrayView.hpp @@ -364,7 +364,7 @@ bool ArrayView< Value, Device, Index >:: empty() const { - return data; + return ( data == nullptr ); } template< typename Value, diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h index ccbea647a..3790b35dc 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 #include @@ -146,7 +146,7 @@ TYPED_TEST( ArrayTest, constructors ) { using ArrayType = typename TestFixture::ArrayType; - /* ArrayType u; + ArrayType u; EXPECT_EQ( u.getSize(), 0 ); ArrayType v( 10 ); @@ -177,7 +177,7 @@ TYPED_TEST( ArrayTest, constructors ) v.reset(); EXPECT_EQ( w.getSize(), 10 ); - ArrayType a1 = { 1, 2, 3 }; + ArrayType a1 { 1, 2, 3 }; EXPECT_EQ( a1.getElement( 0 ), 1 ); EXPECT_EQ( a1.getElement( 1 ), 2 ); EXPECT_EQ( a1.getElement( 2 ), 3 ); @@ -194,8 +194,6 @@ TYPED_TEST( ArrayTest, constructors ) EXPECT_EQ( a3.getElement( 0 ), 7 ); EXPECT_EQ( a3.getElement( 1 ), 8 ); EXPECT_EQ( a3.getElement( 2 ), 9 ); - - */ } TYPED_TEST( ArrayTest, setSize ) @@ -217,12 +215,16 @@ TYPED_TEST( ArrayTest, setSize ) 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 ) @@ -300,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 ); } -- GitLab From be983607e41a4f8f8b34d0f687a18dbe0c8a6c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Wed, 10 Apr 2019 14:31:06 +0200 Subject: [PATCH 65/72] Added getView() and getConstView() methods to Array, ArrayView, Vector, VectorView, DistributedArray, DistributedArrayView, DistributedVector and DistributedVectorView NDArray-style... TODO: update documentation and examples --- src/TNL/Containers/Array.h | 26 ++++++- src/TNL/Containers/Array.hpp | 37 +++++++++ src/TNL/Containers/ArrayView.h | 75 ++++--------------- src/TNL/Containers/ArrayView.hpp | 57 ++++---------- src/TNL/Containers/DistributedArray.h | 29 +++++-- src/TNL/Containers/DistributedArrayView.h | 33 +++++--- .../Containers/DistributedArrayView_impl.h | 48 ++++++------ src/TNL/Containers/DistributedArray_impl.h | 46 +++++++++++- src/TNL/Containers/DistributedVector.h | 24 +++++- src/TNL/Containers/DistributedVectorView.h | 14 ++++ .../Containers/DistributedVectorView_impl.h | 24 ++++++ src/TNL/Containers/DistributedVector_impl.h | 42 +++++++++++ src/TNL/Containers/Vector.h | 36 +++++++-- src/TNL/Containers/VectorView.h | 14 ++++ src/TNL/Containers/VectorView_impl.h | 20 +++++ src/TNL/Containers/Vector_impl.h | 38 ++++++++++ src/TNL/Matrices/DistributedSpMV.h | 3 +- src/TNL/Matrices/Matrix_impl.h | 2 +- src/TNL/Matrices/ThreePartVector.h | 2 +- src/TNL/Solvers/Linear/GMRES_impl.h | 6 +- src/UnitTests/Containers/ArrayViewTest.h | 34 +++++---- 21 files changed, 436 insertions(+), 174 deletions(-) diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 30aee6628..829ae5585 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -14,9 +14,7 @@ #include #include -#include -#include -#include +#include namespace TNL { /** @@ -71,6 +69,8 @@ class Array : public Object 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. @@ -258,6 +258,26 @@ class Array : public Object template< int Size > void bind( StaticArray< Size, Value >& 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. * diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index 915e3a975..a3107fbc4 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -356,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, diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h index 68b548747..91de01dac 100644 --- a/src/TNL/Containers/ArrayView.h +++ b/src/TNL/Containers/ArrayView.h @@ -12,6 +12,8 @@ #pragma once +#include // std::add_const + #include #include #include @@ -22,9 +24,6 @@ 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 @@ -72,6 +71,8 @@ public: 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. @@ -136,62 +137,6 @@ public: __cuda_callable__ ArrayView( ArrayView&& view ) = default; - /** - * \brief Constructor for initialization from other array containers. - * - * It makes shallow copy only. - * - * This method can be called from device kernels. - * - * \tparam Value_ can be both const and non-const qualified Value. - */ - template< typename Value_ > - __cuda_callable__ - ArrayView( Array< Value_, Device, Index >& array ); - - /** - * \brief Constructor for initialization with static array. - * - * This method can be called from device kernels. - * - * \tparam Size is size of the static array. - * \tparam Value_ can be both const and non-const qualified Value. - * - * \param array is a static array the array view is initialized with. - */ - template< int Size, typename Value_ > - __cuda_callable__ - ArrayView( StaticArray< Size, Value_ >& array ); - - /** - * \brief Copy constructor from constant Array. - * - * This constructor will be used only when Value is const-qualified - * (const views are initializable by const references). - * - * This method can be called from device kernels. - * - * \tparam Value_ can be both const and non-const qualified Value - * \param array is an array the array view is initialized with. - */ - template< typename Value_ > - __cuda_callable__ - ArrayView( const Array< Value_, Device, Index >& array ); - - /** - * \brief Constructor for initialization with static array. - * - * This method can be called from device kernels. - * - * \tparam Size is size of the static array. - * \tparam Value_ can be both const and non-const qualified Value. - * - * \param array is a static array the array view is initialized with. - */ - template< int Size, typename Value_ > // template catches both const and non-const qualified Value - __cuda_callable__ - ArrayView( const StaticArray< Size, Value_ >& array ); - /** * \brief Method for rebinding (reinitialization). * @@ -216,6 +161,18 @@ public: __cuda_callable__ void bind( 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; + /** * \brief Assignment operator. * diff --git a/src/TNL/Containers/ArrayView.hpp b/src/TNL/Containers/ArrayView.hpp index 3d4862922..a32c2c5f0 100644 --- a/src/TNL/Containers/ArrayView.hpp +++ b/src/TNL/Containers/ArrayView.hpp @@ -50,75 +50,50 @@ ArrayView( Value* data, Index size ) : data(data), size(size) "ArrayView was initialized with a positive address and zero size or zero address and positive size." ); } -// initialization from other array containers (using shallow copy) +// methods for rebinding (reinitialization) template< typename Value, typename Device, typename Index > - template< typename Value_ > __cuda_callable__ +void ArrayView< Value, Device, Index >:: -ArrayView( Array< Value_, Device, Index >& array ) +bind( Value* data, Index 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." ); -template< typename Value, - typename Device, - typename Index > - template< int Size, typename Value_ > -__cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( StaticArray< Size, Value_ >& array ) -{ - this->bind( array.getData(), Size ); + this->data = data; + this->size = size; } template< typename Value, typename Device, typename Index > - template< typename Value_ > __cuda_callable__ -ArrayView< Value, Device, Index >:: -ArrayView( const Array< Value_, Device, Index >& array ) +void ArrayView< Value, Device, Index >::bind( ArrayView view ) { - this->bind( array.getData(), array.getSize() ); + bind( view.getData(), view.getSize() ); } template< typename Value, typename Device, typename Index > - template< int Size, typename Value_ > -__cuda_callable__ +typename ArrayView< Value, Device, Index >::ViewType ArrayView< Value, Device, Index >:: -ArrayView( const StaticArray< Size, Value_ >& array ) +getView() { - this->bind( array.getData(), Size ); + return *this; } -// methods for rebinding (reinitialization) template< typename Value, typename Device, typename Index > -__cuda_callable__ -void +typename ArrayView< Value, Device, Index >::ConstViewType ArrayView< Value, Device, Index >:: -bind( Value* data, Index 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." ); - - this->data = data; - this->size = size; -} - -template< typename Value, - typename Device, - typename Index > -__cuda_callable__ -void ArrayView< Value, Device, Index >::bind( ArrayView view ) +getConstView() const { - bind( view.getData(), view.getSize() ); + return *this; } // Copy-assignment does deep copy, just like regular array, but the sizes diff --git a/src/TNL/Containers/DistributedArray.h b/src/TNL/Containers/DistributedArray.h index d653fc571..f624100cb 100644 --- a/src/TNL/Containers/DistributedArray.h +++ b/src/TNL/Containers/DistributedArray.h @@ -15,9 +15,7 @@ #include // std::add_const #include -#include -#include -#include +#include 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 e9e9e0a48..6995cf03e 100644 --- a/src/TNL/Containers/DistributedArrayView.h +++ b/src/TNL/Containers/DistributedArrayView.h @@ -12,7 +12,9 @@ #pragma once -#include +#include +#include +#include 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 8fa18cbff..ad4a38b11 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 aab55bd71..34e8e041b 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 86dc66a28..3e110b127 100644 --- a/src/TNL/Containers/DistributedVector.h +++ b/src/TNL/Containers/DistributedVector.h @@ -13,7 +13,7 @@ #pragma once #include -#include +#include 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 e36e60e00..f95a01720 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -37,6 +37,8 @@ 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 >; + using ConstViewType = DistributedVectorView< typename std::add_const< Real >::type, Device, Index >; // inherit all constructors and assignment operators from ArrayView using BaseType::DistributedArrayView; @@ -46,6 +48,18 @@ public: 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 cd1fd1619..0639b2f8e 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 a44baa936..239239ead 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/Vector.h b/src/TNL/Containers/Vector.h index e116508ba..cc703dda8 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -11,6 +11,7 @@ #pragma once #include +#include namespace TNL { namespace Containers { @@ -27,13 +28,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 +53,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. * diff --git a/src/TNL/Containers/VectorView.h b/src/TNL/Containers/VectorView.h index 6ae0bcb81..1e5f07048 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 39b6f703e..af4df8537 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/Containers/Vector_impl.h b/src/TNL/Containers/Vector_impl.h index 683821514..5cd8c8df6 100644 --- a/src/TNL/Containers/Vector_impl.h +++ b/src/TNL/Containers/Vector_impl.h @@ -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 > diff --git a/src/TNL/Matrices/DistributedSpMV.h b/src/TNL/Matrices/DistributedSpMV.h index a96f028bc..f70773c1f 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/Matrix_impl.h b/src/TNL/Matrices/Matrix_impl.h index 9f0ed2e76..815e0e7d8 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, diff --git a/src/TNL/Matrices/ThreePartVector.h b/src/TNL/Matrices/ThreePartVector.h index b492879bd..6afc2dd11 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/Solvers/Linear/GMRES_impl.h b/src/TNL/Solvers/Linear/GMRES_impl.h index 17f8dd1f3..4731ccaf7 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/UnitTests/Containers/ArrayViewTest.h b/src/UnitTests/Containers/ArrayViewTest.h index 50c8d624b..061a2f5ef 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(); @@ -342,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 ); @@ -361,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 ); @@ -386,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 ); @@ -435,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 ); @@ -460,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; @@ -501,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 ); -- GitLab From 311b2717da592824f9f5aaf624761c0ad424a39c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Wed, 10 Apr 2019 14:36:59 +0200 Subject: [PATCH 66/72] Fixed DistributedArrayTest --- src/UnitTests/Containers/DistributedArrayTest.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/UnitTests/Containers/DistributedArrayTest.h b/src/UnitTests/Containers/DistributedArrayTest.h index 169a98b7a..381539af6 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 ) -- GitLab From 605ee8d5c8129588040bf97b665d29184fa153a4 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber Date: Wed, 10 Apr 2019 16:23:36 +0200 Subject: [PATCH 67/72] [WIP] Vector revision. --- src/TNL/Containers/Array.h | 8 +- src/TNL/Containers/Vector.h | 155 +++++++++++++++++++++++++++++++++++- 2 files changed, 158 insertions(+), 5 deletions(-) diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h index 829ae5585..fd6a1ac4e 100644 --- a/src/TNL/Containers/Array.h +++ b/src/TNL/Containers/Array.h @@ -154,28 +154,28 @@ class Array : public Object Array( const std::vector< InValue >& vector ); /** - * \brief Returns type of array in C++ style. + * \brief Returns array type in C++ style. * * \return String with array type. */ static String getType(); /** - * \brief Returns type of array in C++ style. + * \brief Returns array type in C++ style. * * \return String with array type. */ virtual String getTypeVirtual() const; /** - * \brief Returns type of array in C++ style where device is always \ref Devices::Host. + * \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 type of array in C++ style where device is always \ref Devices::Host. + * \brief Returns array type in C++ style where device is always \ref Devices::Host. * * \return String with serialization array type. */ diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h index cc703dda8..9b9d06d8f 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -17,7 +17,11 @@ 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 @@ -301,6 +305,155 @@ public: void computeExclusivePrefixSum( const IndexType begin, const IndexType end ); }; +/** + * \brief Returns the maximum value out of all vector elements. + * + */ +template< typename Real, + typename Device, + typename Index, + typename ResultType = Real > +ResultType max( const Vector< Real, Device, Index>& v ); + +/** + * \brief Returns the minimum value out of all vector elements. + * + */ +template< typename Real, + typename Device, + typename Index, + typename ResultType = Real > +ResultType min( const Vector< Real, Device, Index>& v ); + +/** + * \brief Returns the maximum absolute value out of all vector elements. + * + */ +template< typename Real, + typename Device, + typename Index, + typename ResultType = Real > +ResultType absMax( const Vector< Real, Device, Index>& v ); + +/** + * \brief Returns the minimum absolute value out of all vector elements. + * + */ +template< typename Real, + typename Device, + typename Index, + typename ResultType = Real > +ResultType absMin( const Vector< Real, Device, Index>& v ); + +/** + * \brief Returns the length of this vector in p-dimensional vector space. + * + * \tparam + * \param p Number specifying the dimension of vector space. + * + */ +template< typename Real, + typename Device, + typename Index, + typename Scalar, + typename ResultType = Real > +ResultType lpNorm( const Vector< Real, Device, Index>& v, const Scalar p ); + +/** + * \brief Returns sum of all vector elements. + * + */ +template< typename Real, + typename Device, + typename Index, +template< typename ResultType = RealType > +ResultType sum( const Vector< Real, Device, Index>& v ); + +/** + * \brief Returns maximal difference between elements of this vector and vector \e v. + * + * \tparam Vector Type of vector. + * \param v Reference to another vector of the same size as this vector. + * + */ +template< typename Real, + typename Device, + typename Index, + typename Vector_, + typename ResultType = Real> +ResultType differenceMax( const Vector< Real, Device, Index>& v, const Vector_& v2 ); + +/** + * \brief Returns minimal difference between elements of this vector and vector \e v. + * + * \tparam Vector Type of vector. + * \param v Reference to another vector of the same size as this vector. + * + */ +template< typename Real, + typename Device, + typename Index, + typename Vector_, + typename ResultType = Real > +ResultType differenceMin( const Vector< Real, Device, Index>& v, const Vector& v2 ); + +/** + * \brief Returns maximal absolute difference between elements of this vector and vector \e v. + * + * \tparam Vector Type of vector. + * \param v Reference to another vector of the same size as this vector. + * + */ +template< typename Real, + typename Device, + typename Index, + typename Vector_, + typename ResultType = Real > +ResultType differenceAbsMax( const Vector< Real, Device, Index>& v, const Vector& v2 ); + +/** + * \brief Returns minimal absolute difference between elements of this vector and vector \e v. + * + * \tparam Vector Type of vector. + * \param v Reference to another vector of the same size as this vector. + * + */ +template< typename Real, + typename Device, + typename Index, + typename Vector_ > +Real differenceAbsMin( const Vector< Real, Device, Index>& v, const Vector& v2 ); + +/** + * \brief Returns difference between L^p norms of this vector and vector \e v. + * + * See also \ref lpNorm. + * + * \param v Reference to another vector. + * \param p Number specifying the dimension of vector space. + * + */ +template< typename Real, + typename Device, + typename Index, + typename Vector_, + typename Scalar, + typename ResultType = RealType > +ResultType differenceLpNorm( const Vector< Real, Device, Index>& v, const Vector& v2, const Scalar p ); + +/** + * \brief Returns difference between sums of elements of this vector and vector \e v. + * + * \param v Reference to another vector. + * + */ +template< typename Real, + typename Device, + typename Index, + typename Vector_, + typename ResultType = RealType > +ResultType differenceSum( const Vector< Real, Device, Index>& v, const Vector& v2 ); + } // namespace Containers } // namespace TNL -- GitLab From 6dbb8715c95297fb491fddfdb447fb122700e51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Wed, 10 Apr 2019 16:24:21 +0200 Subject: [PATCH 68/72] Fixed constructors of DistributedVectorView --- src/TNL/Containers/DistributedVectorView.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h index f95a01720..1bffaf825 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -44,6 +44,18 @@ public: 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; -- GitLab From 94cff5f14c1d560f0bc940384d5ac0f86b8771a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 10 Apr 2019 18:26:31 +0200 Subject: [PATCH 69/72] Renaming Vector_impl.h to Vector.hpp and deleting vector operation functions. --- src/TNL/Containers/Vector.h | 151 +----------------- .../Containers/{Vector_impl.h => Vector.hpp} | 3 - 2 files changed, 1 insertion(+), 153 deletions(-) rename src/TNL/Containers/{Vector_impl.h => Vector.hpp} (99%) diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h index 9b9d06d8f..30e399312 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -305,156 +305,7 @@ public: void computeExclusivePrefixSum( const IndexType begin, const IndexType end ); }; -/** - * \brief Returns the maximum value out of all vector elements. - * - */ -template< typename Real, - typename Device, - typename Index, - typename ResultType = Real > -ResultType max( const Vector< Real, Device, Index>& v ); - -/** - * \brief Returns the minimum value out of all vector elements. - * - */ -template< typename Real, - typename Device, - typename Index, - typename ResultType = Real > -ResultType min( const Vector< Real, Device, Index>& v ); - -/** - * \brief Returns the maximum absolute value out of all vector elements. - * - */ -template< typename Real, - typename Device, - typename Index, - typename ResultType = Real > -ResultType absMax( const Vector< Real, Device, Index>& v ); - -/** - * \brief Returns the minimum absolute value out of all vector elements. - * - */ -template< typename Real, - typename Device, - typename Index, - typename ResultType = Real > -ResultType absMin( const Vector< Real, Device, Index>& v ); - -/** - * \brief Returns the length of this vector in p-dimensional vector space. - * - * \tparam - * \param p Number specifying the dimension of vector space. - * - */ -template< typename Real, - typename Device, - typename Index, - typename Scalar, - typename ResultType = Real > -ResultType lpNorm( const Vector< Real, Device, Index>& v, const Scalar p ); - -/** - * \brief Returns sum of all vector elements. - * - */ -template< typename Real, - typename Device, - typename Index, -template< typename ResultType = RealType > -ResultType sum( const Vector< Real, Device, Index>& v ); - -/** - * \brief Returns maximal difference between elements of this vector and vector \e v. - * - * \tparam Vector Type of vector. - * \param v Reference to another vector of the same size as this vector. - * - */ -template< typename Real, - typename Device, - typename Index, - typename Vector_, - typename ResultType = Real> -ResultType differenceMax( const Vector< Real, Device, Index>& v, const Vector_& v2 ); - -/** - * \brief Returns minimal difference between elements of this vector and vector \e v. - * - * \tparam Vector Type of vector. - * \param v Reference to another vector of the same size as this vector. - * - */ -template< typename Real, - typename Device, - typename Index, - typename Vector_, - typename ResultType = Real > -ResultType differenceMin( const Vector< Real, Device, Index>& v, const Vector& v2 ); - -/** - * \brief Returns maximal absolute difference between elements of this vector and vector \e v. - * - * \tparam Vector Type of vector. - * \param v Reference to another vector of the same size as this vector. - * - */ -template< typename Real, - typename Device, - typename Index, - typename Vector_, - typename ResultType = Real > -ResultType differenceAbsMax( const Vector< Real, Device, Index>& v, const Vector& v2 ); - -/** - * \brief Returns minimal absolute difference between elements of this vector and vector \e v. - * - * \tparam Vector Type of vector. - * \param v Reference to another vector of the same size as this vector. - * - */ -template< typename Real, - typename Device, - typename Index, - typename Vector_ > -Real differenceAbsMin( const Vector< Real, Device, Index>& v, const Vector& v2 ); - -/** - * \brief Returns difference between L^p norms of this vector and vector \e v. - * - * See also \ref lpNorm. - * - * \param v Reference to another vector. - * \param p Number specifying the dimension of vector space. - * - */ -template< typename Real, - typename Device, - typename Index, - typename Vector_, - typename Scalar, - typename ResultType = RealType > -ResultType differenceLpNorm( const Vector< Real, Device, Index>& v, const Vector& v2, const Scalar p ); - -/** - * \brief Returns difference between sums of elements of this vector and vector \e v. - * - * \param v Reference to another vector. - * - */ -template< typename Real, - typename Device, - typename Index, - typename Vector_, - typename ResultType = RealType > -ResultType differenceSum( const Vector< Real, Device, Index>& v, const Vector& v2 ); - } // namespace Containers } // namespace TNL -#include +#include diff --git a/src/TNL/Containers/Vector_impl.h b/src/TNL/Containers/Vector.hpp similarity index 99% rename from src/TNL/Containers/Vector_impl.h rename to src/TNL/Containers/Vector.hpp index 5cd8c8df6..5f15d9bae 100644 --- a/src/TNL/Containers/Vector_impl.h +++ b/src/TNL/Containers/Vector.hpp @@ -212,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 > @@ -222,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 > @@ -232,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 > -- GitLab From d6c5d2299e3a2baff434cf08c4271c3b7c3cd686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 10 Apr 2019 20:47:17 +0200 Subject: [PATCH 70/72] Fixed array assignement. --- src/TNL/Containers/Algorithms/ArrayAssignment.h | 17 +++++------------ src/TNL/Containers/Array.hpp | 1 - 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 170d3e253..0d3a9b145 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -50,17 +50,13 @@ 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." ); - ArrayOperations< typename Array::DeviceType, typename T::DeviceType >::template - copyMemory< typename Array::ValueType, typename T::ValueType, typename Array::IndexType > - ( a.getArrayData(), t.getArrayData(), t.getSize() ); + a.setSize( t.getSize() ); + 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() ); }; }; @@ -72,9 +68,6 @@ 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." ); diff --git a/src/TNL/Containers/Array.hpp b/src/TNL/Containers/Array.hpp index a3107fbc4..61c4db1da 100644 --- a/src/TNL/Containers/Array.hpp +++ b/src/TNL/Containers/Array.hpp @@ -549,7 +549,6 @@ Array< Value, Device, Index >& Array< Value, Device, Index >:: operator=( const T& data ) { - Algorithms::ArrayAssignment< Array, T >::resize( *this, data ); Algorithms::ArrayAssignment< Array, T >::assign( *this, data ); return *this; } -- GitLab From 80b422a783adaf2ebe15aa2c205271d8b2cf2075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= Date: Wed, 10 Apr 2019 21:03:54 +0200 Subject: [PATCH 71/72] One more fix of array assignment. --- src/TNL/Containers/Algorithms/ArrayAssignment.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h index 0d3a9b145..62ab43a84 100644 --- a/src/TNL/Containers/Algorithms/ArrayAssignment.h +++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h @@ -50,9 +50,14 @@ template< typename Array, typename T > struct ArrayAssignment< Array, T, true > { - static void assign( Array& a, const T& t ) + 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 > @@ -68,6 +73,9 @@ 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." ); -- GitLab From 5c33197563071d81a108a9d5d6e827e4818ab0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= Date: Wed, 10 Apr 2019 21:03:43 +0200 Subject: [PATCH 72/72] Fixed typo in DistributedVectorView --- src/TNL/Containers/DistributedVectorView.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h index 1bffaf825..7fc3778b4 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -37,8 +37,8 @@ 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 >; - using ConstViewType = DistributedVectorView< typename std::add_const< Real >::type, Device, Index >; + 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; -- GitLab