diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build diff --git a/CMakeLists.txt b/CMakeLists.txt index ecf946d..772ae0e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,6 @@ SET(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install/" CACHE PATH "installation project( SerialBox ) enable_language (Fortran) find_package( Boost ) -include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ) set(ENABLE_DOC "OFF" CACHE BOOL "enable building doc" ) if(ENABLE_DOC) @@ -45,13 +44,6 @@ if( CMAKE_HOST_UNIX ) set ( CMAKE_EXE_LINKER_FLAGS "${CMAKE_LINK_FLAGS} ${CMAKE_THREAD_LIBS_INIT}") endif() -# Single precision -set( SINGLEPRECISION "OFF" CACHE BOOL "Single precision" ) -if( SINGLEPRECISION ) - add_definitions( -DSINGLEPRECISION ) -endif( SINGLEPRECISION ) - - # OSX specific configuration if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") @@ -64,13 +56,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_MACOSX_RPATH "${CMAKE_INSTALL_RPATH}") endif () -# Serialization -include_directories( SYSTEM libs/libjson ) -include_directories( libs/sha256 ) -include_directories( libs/gmock-gtest) -include_directories( src) - - # Python installation path set (PYTHON_PATH "python") diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..d3328fd --- /dev/null +++ b/ChangeLog @@ -0,0 +1,8 @@ +# Release 0.1 + + * Seamlessly support single precision and double precision floating point values + * Fix issue with files larger than 2 GiB + * Support variable declaration in multiple lines in pp_ser + * Correctly install utils_ppser fortran module + * Python can access global metainformation of serializers, register fields + with nontrivial halo and use handle single precision numpy fields diff --git a/fortran/CMakeLists.txt b/fortran/CMakeLists.txt index 7c8ee52..ea07548 100644 --- a/fortran/CMakeLists.txt +++ b/fortran/CMakeLists.txt @@ -1,10 +1,11 @@ + +SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp ") set( SOURCES "m_serialize.f90" + "utils_ppser.f90" ) -add_library(fortranser_files OBJECT ${SOURCES}) - add_library( FortranSer STATIC ${SOURCES} ) diff --git a/libs/libjson/_internal/Source/JSONNode.h b/libs/libjson/_internal/Source/JSONNode.h index 7812753..4ced605 100644 --- a/libs/libjson/_internal/Source/JSONNode.h +++ b/libs/libjson/_internal/Source/JSONNode.h @@ -161,7 +161,7 @@ class JSONNode { json_string as_string(void) const json_nothrow json_read_priority; - int as_int(void) const json_nothrow json_read_priority; + json_int_t as_int(void) const json_nothrow json_read_priority; json_number as_float(void) const json_nothrow json_read_priority; bool as_bool(void) const json_nothrow json_read_priority; @@ -666,9 +666,9 @@ inline void JSONNode::set_name(const json_string & newname) json_nothrow{ return static_cast(*internal); } - inline int JSONNode::as_int(void) const json_nothrow { + inline json_int_t JSONNode::as_int(void) const json_nothrow { JSON_CHECK_INTERNAL(); - return static_cast(*internal); + return static_cast(*internal); } inline json_number JSONNode::as_float(void) const json_nothrow { diff --git a/libs/libjson/_internal/Source/internalJSONNode.h b/libs/libjson/_internal/Source/internalJSONNode.h index 2dd3a1e..8372a13 100644 --- a/libs/libjson/_internal/Source/internalJSONNode.h +++ b/libs/libjson/_internal/Source/internalJSONNode.h @@ -156,8 +156,8 @@ class internalJSONNode { DECL_CAST_OP(short) DECL_CAST_OP(int) DECL_CAST_OP(long) + DECL_CAST_OP(long long) #ifndef JSON_ISO_STRICT - DECL_CAST_OP(long long) operator long double() const json_nothrow; #endif operator float() const json_nothrow; @@ -466,11 +466,9 @@ inline JSONNode * internalJSONNode::at(json_index_t pos) json_nothrow { IMP_SMALLER_INT_CAST_OP(unsigned short, USHRT_MAX, 0) IMP_SMALLER_INT_CAST_OP(int, INT_MAX, INT_MIN) IMP_SMALLER_INT_CAST_OP(unsigned int, UINT_MAX, 0) + IMP_SMALLER_INT_CAST_OP(long long, LLONG_MAX, LLONG_MIN) + IMP_SMALLER_INT_CAST_OP(unsigned long long, ULLONG_MAX, 0) - #ifndef JSON_ISO_STRICT - IMP_SMALLER_INT_CAST_OP(long, LONG_MAX, LONG_MIN) - IMP_SMALLER_INT_CAST_OP(unsigned long, ULONG_MAX, 0) - #endif #endif inline internalJSONNode::operator json_string() const json_nothrow { diff --git a/libs/libjson/longint.patch b/libs/libjson/longint.patch new file mode 100644 index 0000000..4a9cdd0 --- /dev/null +++ b/libs/libjson/longint.patch @@ -0,0 +1,53 @@ +diff --git a/libs/libjson/_internal/Source/JSONNode.h b/libs/libjson/_internal/Source/JSONNode.h +index 7812753..4ced605 100644 +--- a/libs/libjson/_internal/Source/JSONNode.h ++++ b/libs/libjson/_internal/Source/JSONNode.h +@@ -161,7 +161,7 @@ public: + + + json_string as_string(void) const json_nothrow json_read_priority; +- int as_int(void) const json_nothrow json_read_priority; ++ json_int_t as_int(void) const json_nothrow json_read_priority; + json_number as_float(void) const json_nothrow json_read_priority; + bool as_bool(void) const json_nothrow json_read_priority; + +@@ -666,9 +666,9 @@ inline void JSONNode::set_name(const json_string & newname) json_nothrow{ + return static_cast(*internal); + } + +- inline int JSONNode::as_int(void) const json_nothrow { ++ inline json_int_t JSONNode::as_int(void) const json_nothrow { + JSON_CHECK_INTERNAL(); +- return static_cast(*internal); ++ return static_cast(*internal); + } + + inline json_number JSONNode::as_float(void) const json_nothrow { +diff --git a/libs/libjson/_internal/Source/internalJSONNode.h b/libs/libjson/_internal/Source/internalJSONNode.h +index 2dd3a1e..8372a13 100644 +--- a/libs/libjson/_internal/Source/internalJSONNode.h ++++ b/libs/libjson/_internal/Source/internalJSONNode.h +@@ -156,8 +156,8 @@ public: + DECL_CAST_OP(short) + DECL_CAST_OP(int) + DECL_CAST_OP(long) ++ DECL_CAST_OP(long long) + #ifndef JSON_ISO_STRICT +- DECL_CAST_OP(long long) + operator long double() const json_nothrow; + #endif + operator float() const json_nothrow; +@@ -466,11 +466,9 @@ inline JSONNode * internalJSONNode::at(json_index_t pos) json_nothrow { + IMP_SMALLER_INT_CAST_OP(unsigned short, USHRT_MAX, 0) + IMP_SMALLER_INT_CAST_OP(int, INT_MAX, INT_MIN) + IMP_SMALLER_INT_CAST_OP(unsigned int, UINT_MAX, 0) ++ IMP_SMALLER_INT_CAST_OP(long long, LLONG_MAX, LLONG_MIN) ++ IMP_SMALLER_INT_CAST_OP(unsigned long long, ULLONG_MAX, 0) + +- #ifndef JSON_ISO_STRICT +- IMP_SMALLER_INT_CAST_OP(long, LONG_MAX, LONG_MIN) +- IMP_SMALLER_INT_CAST_OP(unsigned long, ULONG_MAX, 0) +- #endif + #endif + + inline internalJSONNode::operator json_string() const json_nothrow { diff --git a/python/pp_ser.py b/python/pp_ser.py index 12254fe..2043777 100755 --- a/python/pp_ser.py +++ b/python/pp_ser.py @@ -3,6 +3,8 @@ #See LICENSE.txt for more information from __future__ import print_function +import linecache + """ pp_ser.py @@ -438,6 +440,7 @@ def __ser_data(self, args, isacc = False): self.__calls.add(self.methods['dataread']) self.__calls.add(self.methods['getmode']) l = '' + l = '! file: ' + self.infile + ' lineno: #' + str(self.__linenum) + '\n' tab = '' if if_statement: l += 'IF (' + if_statement + ') THEN\n' @@ -643,25 +646,52 @@ def __re_endmodule(self): self.__module = '' return m + def __check_intent_in(self, line): + lhs = re.sub(r'!.*', '', line) # Remove comments at end of the line + var_with_dim = [x.strip().replace(' ', '') for x in re.split(r',(?![^(]*\))', lhs)] + var = [re.sub(r'\(.*?\)', '', x) for x in var_with_dim] + fields_in_this_line = [x for x in self.intentin_to_remove if x in var] + self.intentin_removed.extend([x for x in fields_in_this_line if x not in self.intentin_removed]) + + if fields_in_this_line: + l = '#ifdef ' + self.ifdef + '\n' + r = re.compile(r', *intent *\(in\)', re.IGNORECASE) + l += r.sub('', self.__line) + l += '#else\n' + self.__line + '#endif\n' + self.__line = l + return fields_in_this_line + + def __re_def(self): r = re.compile(r'.*intent *\(in\)[^:]*::\s*([^!]*)\s*.*', re.IGNORECASE) + r_cont = re.compile(r'.*intent *\(in\)[^:]*::\s*([^!]*)\s*.*&', re.IGNORECASE) + + # Line contains intent with continuation + m_cont = r_cont.search(self.__line) m = r.search(self.__line) - if m: + if m_cont: + splitted = self.__line.split('::') + splitted[1] = re.sub(r'!.*', '', splitted[1]) # Remove comments at end of the line + if not self.__check_intent_in(splitted[1]): + # look ahead to find the variable + lookahead_index = self.__linenum + # set to line after the intent declaration + lookahead_index += 1 + # look ahead + nextline = linecache.getline(os.path.join(self.infile), lookahead_index) + while nextline: + self.__check_intent_in(nextline) + if(nextline.find('&')!=-1): + lookahead_index += 1 + nextline = linecache.getline(os.path.join(self.infile), lookahead_index) + else: + nextline = None + + # Match a standard declaration with variable and intent on the same line + elif m: splitted = self.__line.split('::') splitted[1] = re.sub(r'!.*', '', splitted[1]) # Remove comments at end of the line - var_with_dim = [x.strip().replace(' ', '') for x in re.split(r',(?![^(]*\))', splitted[1])] - var = [re.sub(r'\(.*?\)', '', x) for x in var_with_dim] - fields_in_this_line = [x for x in self.intentin_to_remove if x in var] - self.intentin_removed.extend([x for x in fields_in_this_line if x not in self.intentin_removed]) - - if fields_in_this_line: - l = '#ifdef ' + self.ifdef + '\n' - r = re.compile(r', *intent *\(in\)', re.IGNORECASE) - l += r.sub('', self.__line) - l += '#else\n' + self.__line + '#endif\n' - - self.__line = l - return fields_in_this_line + self.__check_intent_in(splitted[1]) return m # evaluate one line diff --git a/python/serialbox/serialization.py b/python/serialbox/serialization.py index 5b57886..ec71d08 100644 --- a/python/serialbox/serialization.py +++ b/python/serialbox/serialization.py @@ -52,7 +52,9 @@ def type2dtype(typestr, typesize): 'int4' : np.int32, 'int8' : np.int64, 'float4' : np.float32, - 'double8' : np.float64 + 'float324' : np.float32, + 'double8' : np.float64, + 'float648' : np.float64 } try: return conv["{0}{1}".format(typestr,typesize)] @@ -62,6 +64,15 @@ def type2dtype(typestr, typesize): # Extract wrapper functions fs_create_serializer = wrapper.fs_create_serializer ; fs_create_serializer.restype = ctypes.c_void_p fs_destroy_serializer = wrapper.fs_destroy_serializer +fs_serializer_metainfo_size = wrapper.fs_serializer_metainfo_size ; fs_serializer_metainfo_size.restype = ctypes.c_int +fs_serializer_metainfo_key_lengths = wrapper.fs_serializer_metainfo_key_lengths +fs_serializer_metainfo_get_keys = wrapper.fs_serializer_metainfo_get_keys +fs_serializer_metainfo_get_types = wrapper.fs_serializer_metainfo_get_types +fs_get_serializer_metainfo_b = wrapper.fs_get_serializer_metainfo_b +fs_get_serializer_metainfo_i = wrapper.fs_get_serializer_metainfo_i +fs_get_serializer_metainfo_f = wrapper.fs_get_serializer_metainfo_f +fs_get_serializer_metainfo_d = wrapper.fs_get_serializer_metainfo_d +fs_get_serializer_metainfo_s = wrapper.fs_get_serializer_metainfo_s fs_add_serializer_metainfo_b = wrapper.fs_add_serializer_metainfo_b fs_add_serializer_metainfo_i = wrapper.fs_add_serializer_metainfo_i fs_add_serializer_metainfo_f = wrapper.fs_add_serializer_metainfo_f @@ -91,7 +102,7 @@ def type2dtype(typestr, typesize): fs_duplicate_savepoint = wrapper.fs_duplicate_savepoint ; fs_duplicate_savepoint.restype = ctypes.c_void_p fs_destroy_savepoint = wrapper.fs_destroy_savepoint fs_reinitialize_savepoint = wrapper.fs_reinitialize_savepoint -fs_savepoint_metainfo = wrapper.fs_savepoint_metainfo ; fs_savepoint_metainfo.restype = ctypes.c_int +fs_savepoint_metainfo_size = wrapper.fs_savepoint_metainfo_size ; fs_savepoint_metainfo_size.restype = ctypes.c_int fs_savepoint_name_length = wrapper.fs_savepoint_name_length ; fs_savepoint_name_length.restype = ctypes.c_int fs_savepoint_get_name = wrapper.fs_savepoint_get_name fs_savepoint_key_lengths = wrapper.fs_savepoint_key_lengths @@ -273,7 +284,7 @@ def name(self): @property def metainfo_tuples(self): # Retrieve key lengths - n_keys = int(fs_savepoint_metainfo(self.savepoint)) + n_keys = int(fs_savepoint_metainfo_size(self.savepoint)) key_lengths = (ctypes.c_int*n_keys)() fs_savepoint_key_lengths(self.savepoint, key_lengths) @@ -292,7 +303,7 @@ def metainfo_tuples(self): @property def metainfo(self): # Retrieve key lengths - n_keys = int(fs_savepoint_metainfo(self.savepoint)) + n_keys = int(fs_savepoint_metainfo_size(self.savepoint)) key_lengths = (ctypes.c_int*n_keys)() fs_savepoint_key_lengths(self.savepoint, key_lengths) @@ -350,9 +361,6 @@ def add_metainfo(self, key, value): else: raise AttributeError("Error: type of value not supported") - def metainfo_number(self): - return int(fs_savepoint_metainfo(self.savepoint)) - class serializer(object): def __init__(self, directory, prefix, openmode): @@ -401,7 +409,9 @@ def load_field(self, name, savepoint): return field def save_field(self, name, field, savepoint): - self.register_field(name, field) + if name not in self.fieldnames: + self.register_field(name, field) + name, namelength = extract_string(name) # Extract strides @@ -410,15 +420,28 @@ def save_field(self, name, field, savepoint): fs_write_field(self.serializer, savepoint.savepoint, name, namelength, field.ctypes.data, strides[0], strides[1], strides[2], strides[3]) - def register_field(self, name, field): + def register_field(self, name, field, **kwargs): name, namelength = extract_string(name) dtype, dtypelength = extract_string(field.dtype.name) size = [field.shape[i] if i < len(field.shape) else 1 for i in range(4)] + # Extract halo + iminushalo = kwargs.get('iminushalo', 0) + iplushalo = kwargs.get('iplushalo', 0) + jminushalo = kwargs.get('jminushalo', 0) + jplushalo = kwargs.get('jplushalo', 0) + kminushalo = kwargs.get('kminushalo', 0) + kplushalo = kwargs.get('kplushalo', 0) + lminushalo = kwargs.get('lminushalo', 0) + lplushalo = kwargs.get('lplushalo', 0) + + # Call C routine fs_register_field(self.serializer, name, namelength, dtype, dtypelength, field.dtype.itemsize, size[0], size[1], size[2], size[3], - 0, 0, 0, 0, 0, 0, 0, 0) + iminushalo, iplushalo, jminushalo, jplushalo, + kminushalo, kplushalo, lminushalo, lplushalo + ) @property def fieldnames(self): @@ -426,10 +449,11 @@ def fieldnames(self): n_fields = fs_fields(self.serializer) name_lengths = (ctypes.c_int*n_fields)() fs_fieldname_lengths(self.serializer, name_lengths) + name_length = max(name_lengths)+1 # Get field names names = ((ctypes.c_char_p)*n_fields)() - names[:] = [('\0'*name_lengths[i]).encode() for i in range(n_fields)] + names[:] = [('\0'*name_length).encode() for i in range(n_fields)] fs_get_fieldnames(self.serializer, names) return [n.decode() for n in names] @@ -438,6 +462,49 @@ def fieldnames(self): def fieldinfos(self): return [self._fieldinfo(f) for f in self.fieldnames] + @property + def metainfo(self): + # Retrieve key lengths + n_keys = int(fs_serializer_metainfo_size(self.serializer)) + key_lengths = (ctypes.c_int*n_keys)() + fs_serializer_metainfo_key_lengths(self.serializer, key_lengths) + + # Retrieve keys + keys = ((ctypes.c_char_p)*n_keys)() + keys[:] = [('\0'*key_lengths[i]).encode() for i in range(n_keys)] + fs_serializer_metainfo_get_keys(self.serializer, keys) + + # Retrieve types + types = (ctypes.c_int*n_keys)() + fs_serializer_metainfo_get_types(self.serializer, types) + + metainfo = {} + for i in range(n_keys): + keystr = keys[i].decode() + key, keylength = extract_string(keystr) + if (types[i] == -1): + v = ctypes.c_bool() + f = fs_get_serializer_metainfo_b(self.serializer, key, keylength, ctypes.pointer(v)) + metainfo[keystr] = v.value + elif (types[i] == -2): + v = ctypes.c_int() + f = fs_get_serializer_metainfo_i(self.serializer, key, keylength, ctypes.pointer(v)) + metainfo[keystr] = v.value + elif (types[i] == -3): + v = ctypes.c_float() + f = fs_get_serializer_metainfo_f(self.serializer, key, keylength, ctypes.pointer(v)) + metainfo[keystr] = v.value + elif (types[i] == -4): + v = ctypes.c_double() + f = fs_get_serializer_metainfo_d(self.serializer, key, keylength, ctypes.pointer(v)) + metainfo[keystr] = v.value + elif (types[i] >= 0): + v = ctypes.create_string_buffer(types[i]) + f = fs_get_serializer_metainfo_s(self.serializer, key, keylength, v) + metainfo[keystr] = v.value.decode() + + return metainfo + def add_metainfo(self, key, value): key, keylength = extract_string(key) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 203a5d2..d0e1458 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,11 @@ +include_directories( SYSTEM ${Boost_INCLUDE_DIRS} ) + +# Serialization +include_directories( SYSTEM ${CMAKE_SOURCE_DIR}/libs/libjson ) +include_directories( ${CMAKE_SOURCE_DIR}/libs/sha256 ) +include_directories( ${CMAKE_SOURCE_DIR}/libs/gmock-gtest) +include_directories( ${CMAKE_SOURCE_DIR}/src) + add_subdirectory( utils ) add_subdirectory( serializer ) add_subdirectory( wrapper ) diff --git a/src/serializer/CMakeLists.txt b/src/serializer/CMakeLists.txt index 2394608..dda4d35 100644 --- a/src/serializer/CMakeLists.txt +++ b/src/serializer/CMakeLists.txt @@ -14,7 +14,6 @@ set( set( GENERIC_HEADERS - "Definitions.h" "SerializationException.h" "TypeName.h" "MetainfoSet.h" diff --git a/src/serializer/CentralizedFileFormat.cpp b/src/serializer/CentralizedFileFormat.cpp index 432749b..f8e37dd 100644 --- a/src/serializer/CentralizedFileFormat.cpp +++ b/src/serializer/CentralizedFileFormat.cpp @@ -111,7 +111,7 @@ void CentralizedFileFormat::CleanTables() pOffsetTable_->Cleanup(); } -int CentralizedFileFormat::OpenStreamAppend(std::ofstream& stream, const std::string& fieldName, const Savepoint&) const +OffsetTable::offset_t CentralizedFileFormat::OpenStreamAppend(std::ofstream& stream, const std::string& fieldName, const Savepoint&) const { // Discard savepoint because we are just appending data to the file @@ -129,10 +129,13 @@ void CentralizedFileFormat::OpenStreamRead(std::ifstream& stream, const std::str fname << directory_ << "/" << prefix_ << "_" << fieldName << ".dat"; // Check if field is already saved at savepoint and get offset - const int offset = pOffsetTable_->GetOffset(savepoint, fieldName); - if (offset < 0) + OffsetTable::offset_t offset; + try { + offset = pOffsetTable_->GetOffset(savepoint, fieldName); + } + catch (SerializationException) { - // Throw exception + // Throw more detailed exception std::ostringstream errorstr; errorstr << "Error: field " << fieldName << " is not saved into serializer " << "at savepoint " << savepoint.ToString(); diff --git a/src/serializer/CentralizedFileFormat.h b/src/serializer/CentralizedFileFormat.h index 1e184c1..96ffa37 100644 --- a/src/serializer/CentralizedFileFormat.h +++ b/src/serializer/CentralizedFileFormat.h @@ -42,7 +42,7 @@ namespace ser { virtual void CleanTables(); - virtual int OpenStreamAppend(std::ofstream& stream, const std::string& fieldName, const Savepoint& savepoint) const; + virtual OffsetTable::offset_t OpenStreamAppend(std::ofstream& stream, const std::string& fieldName, const Savepoint& savepoint) const; virtual void OpenStreamRead(std::ifstream& stream, const std::string& fieldName, const Savepoint& savepoint) const; diff --git a/src/serializer/Definitions.h b/src/serializer/Definitions.h deleted file mode 100644 index 952bd9b..0000000 --- a/src/serializer/Definitions.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -//This file is released under terms of BSD license` -//See LICENSE.txt for more information - -namespace ser { - // define the floating point type -#ifdef SINGLEPRECISION - typedef float Real; -#else - typedef double Real; -#endif - typedef const Real ConstReal; - -} //namespace ser diff --git a/src/serializer/FileFormat.h b/src/serializer/FileFormat.h index c69d1f2..75509c7 100644 --- a/src/serializer/FileFormat.h +++ b/src/serializer/FileFormat.h @@ -4,6 +4,7 @@ //See LICENSE.txt for more information #include +#include "OffsetTable.h" namespace ser { @@ -53,7 +54,7 @@ namespace ser { * * @return The offset from the beginning of the file is returned */ - virtual int OpenStreamAppend(std::ofstream& stream, const std::string& fieldName, const Savepoint& savepoint) const =0; + virtual OffsetTable::offset_t OpenStreamAppend(std::ofstream& stream, const std::string& fieldName, const Savepoint& savepoint) const =0; /** * Opens a stream for reading data diff --git a/src/serializer/IJKBoundary.h b/src/serializer/IJKBoundary.h index 5030f5a..0391b97 100644 --- a/src/serializer/IJKBoundary.h +++ b/src/serializer/IJKBoundary.h @@ -3,8 +3,6 @@ //This file is released under terms of BSD license` //See LICENSE.txt for more information -#include "Definitions.h" - namespace ser{ /** diff --git a/src/serializer/IJKSize.h b/src/serializer/IJKSize.h index 04f0d04..6de10f5 100644 --- a/src/serializer/IJKSize.h +++ b/src/serializer/IJKSize.h @@ -4,7 +4,6 @@ //See LICENSE.txt for more information #include -#include "Definitions.h" namespace ser { /** diff --git a/src/serializer/KBoundary.h b/src/serializer/KBoundary.h index a8ee099..040203e 100644 --- a/src/serializer/KBoundary.h +++ b/src/serializer/KBoundary.h @@ -3,7 +3,6 @@ //This file is released under terms of BSD license` //See LICENSE.txt for more information -#include "Definitions.h" namespace ser { /** diff --git a/src/serializer/MetainfoSet.cpp b/src/serializer/MetainfoSet.cpp index fb510a0..1e44709 100644 --- a/src/serializer/MetainfoSet.cpp +++ b/src/serializer/MetainfoSet.cpp @@ -288,31 +288,6 @@ float MetainfoSet::AsDouble(const std::string& key) const return (double)0.; } -Real MetainfoSet::AsReal(const std::string& key) const -{ - std::map::const_iterator iter = checkKeyExists(key); - const boost::any& a = iter->second; - const std::type_info& t = a.type(); - - if(t == typeid(bool)) return boost::any_cast(a); - else if(t == typeid(int)) return boost::any_cast(a); - else if(t == typeid(float)) return boost::any_cast(a); - else if(t == typeid(double)) return boost::any_cast(a); - else if(t == typeid(std::string)) - { - Real v; - std::stringstream ss; - ss << boost::any_cast(a); - ss >> v; - return v; - } - - // Reaching this point is a bug. - std::cerr << "Bug in MetainfoSet: type of '" << key << "' not recognized\n"; - std::exit(1); - return (Real)0.; -} - std::string MetainfoSet::AsString(const std::string& key) const { std::ostringstream ss; @@ -361,7 +336,7 @@ std::vector< JSONNode> MetainfoSet::GenerateNodes() const void MetainfoSet::AddNode(const JSONNode& node) { - Real r; + JSON_NUMBER_TYPE r; switch (node.type()) { case JSON_BOOL: @@ -370,7 +345,7 @@ void MetainfoSet::AddNode(const JSONNode& node) return AddMetainfo(node.name(), node.as_string()); case JSON_NUMBER: r = node.as_float(); - if (r == static_cast(static_cast(r))) + if (r == static_cast(static_cast(r))) return AddMetainfo(node.name(), static_cast(r)); else return AddMetainfo(node.name(), r); diff --git a/src/serializer/MetainfoSet.h b/src/serializer/MetainfoSet.h index 7135abf..7809d8f 100644 --- a/src/serializer/MetainfoSet.h +++ b/src/serializer/MetainfoSet.h @@ -11,7 +11,6 @@ #include "boost/any.hpp" #include "boost/type_traits/is_same.hpp" -#include "Definitions.h" #include "SerializationException.h" #include "libjson.h" @@ -247,10 +246,11 @@ namespace ser { float AsDouble(const std::string& key) const; /** - * Extracts a value in Real representation. + * Extracts a value in RealType representation, where RealType is + * either `float` or `double`. * - * If the type is different than Real, the function converts the - * value to Real. + * If the type is different than RealType, the function converts the + * value to RealType. * * @throw SerializationException The key does not exist * @@ -258,7 +258,15 @@ namespace ser { * * @return The value of the metainfo is returned as copy */ - Real AsReal(const std::string& key) const; + template + RealType AsReal(const std::string& key) const + { + BOOST_STATIC_ASSERT(boost::is_same::value + || boost::is_same::value); + + if (boost::is_same::value) return AsFloat(key); + else if (boost::is_same::value) return AsDouble(key); + } /** * Extracts a value assuming its type is string. diff --git a/src/serializer/OffsetTable.cpp b/src/serializer/OffsetTable.cpp index 335747c..5b805f6 100644 --- a/src/serializer/OffsetTable.cpp +++ b/src/serializer/OffsetTable.cpp @@ -101,7 +101,7 @@ int OffsetTable::GetSavepointID(const Savepoint& savepoint) const return (iter == savepointIndex_.end() ? -1 : iter->second); } -int OffsetTable::GetOffset(const Savepoint& savepoint, const std::string& fieldName) const +OffsetTable::offset_t OffsetTable::GetOffset(const Savepoint& savepoint, const std::string& fieldName) const { // Find savepoint ID std::map::const_iterator iter = savepointIndex_.find(savepoint); @@ -118,7 +118,7 @@ int OffsetTable::GetOffset(const Savepoint& savepoint, const std::string& fieldN return GetOffset(iter->second, fieldName); } -int OffsetTable::GetOffset(int savepointID, const std::string& fieldName) const +OffsetTable::offset_t OffsetTable::GetOffset(int savepointID, const std::string& fieldName) const { // Check that ID is valid if (static_cast(savepointID) >= entries_.size()) @@ -131,17 +131,24 @@ int OffsetTable::GetOffset(int savepointID, const std::string& fieldName) const throw exception; } - // Check that field is saved at savepoint or return -1 - // If there is return offset + // Check that field is saved at savepoint const OffsetTableEntry& entry = entries_[savepointID]; const_iterator iter = entry.find(fieldName); if (iter == entry.end()) - return -1; - else - return iter->second.offset; + { + std::ostringstream msg; + msg << "Error: field " << fieldName << " is not registered at the savepoint " + << savepoints_[savepointID].ToString() << "\n"; + SerializationException exception; + exception.Init(msg.str()); + throw exception; + } + + // Return offset + return iter->second.offset; } -int OffsetTable::AlreadySerialized(const std::string& fieldName, const std::string& checksum) const +bool OffsetTable::AlreadySerialized(const std::string& fieldName, const std::string& checksum, OffsetTable::offset_t& offset) const { // Loop backwards for (std::vector::const_reverse_iterator iter = entries_.rbegin(); iter != entries_.rend(); ++iter) @@ -150,9 +157,12 @@ int OffsetTable::AlreadySerialized(const std::string& fieldName, const std::stri if (entry == iter->end()) continue; if (entry->second.checksum == checksum) - return entry->second.offset; + { + offset = entry->second.offset; + return true; + } } - return -1; + return false; } std::string OffsetTable::ToString() const @@ -270,7 +280,7 @@ void OffsetTable::TableFromJSON(const JSONNode& node) // Interpret offsets and add records for (JSONNode::const_iterator o_iter = offsetsnode.begin(); o_iter != offsetsnode.end(); ++o_iter) { - int offset = (*o_iter)[0].as_int(); + const offset_t offset = (*o_iter)[0].as_int(); const std::string checksum = (*o_iter)[1].as_string(); AddFieldRecord(savepointID, o_iter->name(), offset, checksum); } diff --git a/src/serializer/OffsetTable.h b/src/serializer/OffsetTable.h index be6a5b8..41de115 100644 --- a/src/serializer/OffsetTable.h +++ b/src/serializer/OffsetTable.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "Savepoint.h" @@ -22,8 +23,11 @@ namespace ser{ */ class OffsetTable { - typedef int offset_t; + public: + typedef std::streamoff offset_t; typedef std::string checksum_t; + + private: typedef struct { offset_t offset; checksum_t checksum; } OffsetTableEntryValue; typedef std::map OffsetTableEntry; typedef OffsetTableEntry::const_iterator const_iterator; @@ -87,27 +91,29 @@ namespace ser{ * is returned, but no exception is thrown. * * @throw SerializationException The savepoint is not registered in the table + * or the the specified field is not registered at the given savepoint * * @param savepoint Guess what... * @param fieldName Idem * - * @return The offset is returned if the record is found, otherwise a negative - * value is returned. + * @return The offset is returned if the record is found. */ - int GetOffset(const Savepoint& savepoint, const std::string& fieldName) const; - int GetOffset(int savepointID, const std::string& fieldName) const; + offset_t GetOffset(const Savepoint& savepoint, const std::string& fieldName) const; + offset_t GetOffset(int savepointID, const std::string& fieldName) const; /** * Checks if an entry of the field with the same checksum exists. This can be used * to avoid storing to the disk if the same state of a field is already stored. + * In case the record is found, the corresponding offset will be stored in the + * given variable, otherwise its value is not modified. * * @param fieldName The name of the field * @param checksum The checksum of the content + * @param[out] offset The offset of the found record, if any, is stored here * - * @return The offset of the already serialized field is returned if found. - * Otherwise, a negative value is returned. + * @return True is returned iff a record is found */ - int AlreadySerialized(const std::string& fieldName, const std::string& checksum) const; + bool AlreadySerialized(const std::string& fieldName, const std::string& checksum, offset_t& offset) const; /** * Produces a string represetation of the table diff --git a/src/serializer/Serializer.cpp b/src/serializer/Serializer.cpp index ee2ce63..bd06c7b 100644 --- a/src/serializer/Serializer.cpp +++ b/src/serializer/Serializer.cpp @@ -168,9 +168,11 @@ void Serializer::WriteField(const std::string& fieldName, const Savepoint& savep savepointID = offsetTable_.AddNewSavepoint(savepoint); // Check if field is already saved at savepoint - if (offsetTable_.GetOffset(savepointID, fieldName) >= 0) + try { - // Throw exception + offsetTable_.GetOffset(savepointID, fieldName); + + // Field is already there: throw exception std::ostringstream errorstr; errorstr << "Error: field " << fieldName << " was already saved into " << "serializer at savepoint " << savepoint.ToString(); @@ -178,6 +180,11 @@ void Serializer::WriteField(const std::string& fieldName, const Savepoint& savep exception.Init(errorstr.str()); throw exception; } + catch (SerializationException&) + { + // Field is not there (or savepoint does not exist) + // No error, continue + } // Obtain buffer and checksum std::vector binaryData; @@ -185,11 +192,11 @@ void Serializer::WriteField(const std::string& fieldName, const Savepoint& savep info.iSize(), info.jSize(), info.kSize(), info.lSize(), iStride, jStride, kStride, lStride, binaryData); - // Control in offset table if data must be stored - int offset = offsetTable_.AlreadySerialized(fieldName, checksum); - - if (offset < 0) + // Check in offset table if data must be stored + OffsetTable::offset_t offset; + if (!offsetTable_.AlreadySerialized(fieldName, checksum, offset)) { + // Record is not found: we need to write the data // Open file stream std::ofstream fs; offset = pFileFormat_->OpenStreamAppend(fs, fieldName, savepoint); @@ -233,8 +240,26 @@ void Serializer::ReadField(const std::string& fieldName, const Savepoint& savepo // Search in previous savepoints if (alsoPrevious) { - while(savepointID >= 0 && offsetTable_.GetOffset(savepointID, fieldName) < 0) - --savepointID; + OffsetTable::offset_t offset; + bool found = false; + while(!found) + { + try + { + offsetTable_.GetOffset(savepointID, fieldName); + + // Field is found + found = true; + break; + } + catch (SerializationException&) + { + // Field is not found: proceed with previous savepoint + } + + if(--savepointID < 0) + break; + } if (savepointID < 0) { diff --git a/src/wrapper/SerializationWrapper.cpp b/src/wrapper/SerializationWrapper.cpp index d2c51d5..871671c 100644 --- a/src/wrapper/SerializationWrapper.cpp +++ b/src/wrapper/SerializationWrapper.cpp @@ -67,6 +67,70 @@ char fs_serializer_openmode(void* serializer) return ' '; } +int fs_serializer_metainfo_size(void* serializer) +{ + return reinterpret_cast(serializer)->globalMetainfo().size(); +} + +void fs_serializer_metainfo_key_lengths(void* serializer, int* lengths) +{ + const std::vector keys = reinterpret_cast(serializer)->globalMetainfo().keys(); + const int N = keys.size(); + for (int i = 0; i < N; ++i) + lengths[i] = keys.at(i).size(); +} + +void fs_serializer_metainfo_get_keys(void* serializer, char** keys) +{ + const std::vector mkeys = reinterpret_cast(serializer)->globalMetainfo().keys(); + const int N = mkeys.size(); + + for (int i = 0; i < N; ++i) + { + std::strcpy(keys[i], mkeys.at(i).c_str()); + } +} + +void fs_serializer_metainfo_get_types(void* serializer, int* types) +{ + const std::vector mtypes = reinterpret_cast(serializer)->globalMetainfo().types(); + const int N = mtypes.size(); + for (int i = 0; i < N; ++i) + types[i] = mtypes.at(i); +} + +void fs_get_serializer_metainfo_b(void* serializer, const char* name, int name_length, bool* value) +{ + Serializer& sp = *reinterpret_cast(serializer); + sp.globalMetainfo().ExtractValue(std::string(name, name_length), *value); +} + +void fs_get_serializer_metainfo_i(void* serializer, const char* name, int name_length, int* value) +{ + Serializer& sp = *reinterpret_cast(serializer); + sp.globalMetainfo().ExtractValue(std::string(name, name_length), *value); +} + +void fs_get_serializer_metainfo_f(void* serializer, const char* name, int name_length, float* value) +{ + Serializer& sp = *reinterpret_cast(serializer); + sp.globalMetainfo().ExtractValue(std::string(name, name_length), *value); +} + +void fs_get_serializer_metainfo_d(void* serializer, const char* name, int name_length, double* value) +{ + Serializer& sp = *reinterpret_cast(serializer); + sp.globalMetainfo().ExtractValue(std::string(name, name_length), *value); +} + +void fs_get_serializer_metainfo_s(void* serializer, const char* name, int name_length, char* value) +{ + Serializer& sp = *reinterpret_cast(serializer); + std::string v; + sp.globalMetainfo().ExtractValue(std::string(name, name_length), v); + std::strcpy(value, v.c_str()); +} + void fs_add_serializer_metainfo_b(void* serializer, const char* name, int name_length, bool value) { reinterpret_cast(serializer)->AddMetainfo(std::string(name, name_length), value); @@ -373,7 +437,7 @@ void fs_get_savepoint_metainfo_s(void* savepoint, const char* name, int name_len std::strcpy(value, v.c_str()); } -int fs_savepoint_metainfo(void* savepoint) +int fs_savepoint_metainfo_size(void* savepoint) { return reinterpret_cast(savepoint)->metainfo().size(); } diff --git a/src/wrapper/SerializationWrapper.h b/src/wrapper/SerializationWrapper.h index 529eaad..3b9014b 100644 --- a/src/wrapper/SerializationWrapper.h +++ b/src/wrapper/SerializationWrapper.h @@ -10,10 +10,15 @@ extern "C" char openmode); void fs_destroy_serializer(void* serializer); char fs_serializer_openmode(void* serializer); - //int fs_serializer_metainfo(void* savepoint); - //void fs_serializer_metainfo_key_lengths(void* savepoint, int* lengths); - //void fs_serializer_metainfo_get_keys(void* savepoint, char** lengths); - //void fs_serializer_metainfo_get_types(void* savepoint, int* types); + int fs_serializer_metainfo_size(void* savepoint); + void fs_serializer_metainfo_key_lengths(void* savepoint, int* lengths); + void fs_serializer_metainfo_get_keys(void* savepoint, char** lengths); + void fs_serializer_metainfo_get_types(void* savepoint, int* types); + void fs_get_serializer_metainfo_b(void* serializer, const char* name, int name_length, bool* value); + void fs_get_serializer_metainfo_i(void* serializer, const char* name, int name_length, int* value); + void fs_get_serializer_metainfo_f(void* serializer, const char* name, int name_length, float* value); + void fs_get_serializer_metainfo_d(void* serializer, const char* name, int name_length, double* value); + void fs_get_serializer_metainfo_s(void* serializer, const char* name, int name_length, char* value); void fs_add_serializer_metainfo_b(void* serializer, const char* name, int name_length, bool value); void fs_add_serializer_metainfo_i(void* serializer, const char* name, int name_length, int value); void fs_add_serializer_metainfo_f(void* serializer, const char* name, int name_length, float value); @@ -58,7 +63,7 @@ extern "C" void* fs_duplicate_savepoint(void* savepoint); void fs_destroy_savepoint(void* savepoint); void fs_reinitialize_savepoint(void* savepoint, const char* name, int name_length); - int fs_savepoint_metainfo(void* savepoint); + int fs_savepoint_metainfo_size(void* savepoint); int fs_savepoint_name_length(void* savepoint); void fs_savepoint_get_name(void* savepoint, char* name); void fs_savepoint_key_lengths(void* savepoint, int* lengths); diff --git a/test/build.sh b/test/build.sh index 2b2122b..0b12879 100755 --- a/test/build.sh +++ b/test/build.sh @@ -9,13 +9,11 @@ exitError() cmakeConfigure() { - local enable_single=$1 - local fcomp=$2 - local idir=$3 + local fcomp=$1 + local idir=$2 # construct cmake arguments local CMAKEARGS=(.. - "-DSINGLEPRECISION=${enable_single}" "-DCMAKE_Fortran_COMPILER=${fcomp}" "-DCMAKE_INSTALL_PREFIX=${idir}" "-DCMAKE_CXX_COMPILER=g++" @@ -31,7 +29,7 @@ cmakeConfigure() echo "TEST $@" -TEMP=`getopt -o h,f:,s,i:,z --long single,fcompiler:,idir:,local \ +TEMP=`getopt -o h,f:,i:,z --long fcompiler:,idir:,local \ -n 'build' -- "$@"` if [ $? -ne 0 ] then @@ -42,7 +40,6 @@ eval set -- "$TEMP" while true; do case "$1" in - --single|-s) single_precision="ON"; shift;; --fcompiler|-f ) fortran_compiler="$2"; shift 2;; --idir|-i) install_dir="$2"; shift 2;; --local) install_local="yes"; shift;; @@ -52,10 +49,6 @@ while true; do esac done -if [[ -z ${single_precision} ]] ; then - single_precision="OFF" -fi - if [[ -z ${fortran_compiler} ]] ; then exitError 4410 ${LINENO} "compiler option has to be specified" fi @@ -76,7 +69,7 @@ if [[ ${install_local} == "yes" ]]; then install_dir=${base_path}/install fi -cmakeConfigure "${single_precision}" "${fortran_compiler}" "${install_dir}" +cmakeConfigure "${fortran_compiler}" "${install_dir}" make install diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index e5259e2..021d7df 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,4 +1,6 @@ +include_directories( SYSTEM ${CMAKE_SOURCE_DIR}/libs/libjson ) +include_directories( ${CMAKE_SOURCE_DIR}/src) add_executable( dump diff --git a/tools/compare.cpp b/tools/compare.cpp index ba9f46f..6df6653 100644 --- a/tools/compare.cpp +++ b/tools/compare.cpp @@ -84,9 +84,9 @@ bool compareData(const Serializer& serializer1, const Serializer& serializer2, { int index = i * jSize * kSize * lSize + j * kSize * lSize + k * lSize + l; - const Real val = data1[index]; - const Real ref = data2[index]; - const Real err = std::fabs(ref) > 1. ? + const double val = static_cast(data1[index]); + const double ref = static_cast(data2[index]); + const double err = std::fabs(ref) > 1. ? std::fabs((ref - val) / ref) : std::fabs(ref - val); const bool f = err > tolerance // Error is too large (e.g. val is infinite, ref is not) @@ -137,8 +137,8 @@ void printDifference(const Serializer& serializer1, const Serializer& serializer { ++nErrors; - const Real val = data1[index]; - const Real ref = data2[index]; + const double val = static_cast(data1[index]); + const double ref = static_cast(data2[index]); maxAbsError = std::max(maxAbsError, std::fabs(val - ref)); maxRelError = std::max(maxRelError, std::fabs((val - ref) / ref)); } @@ -225,6 +225,12 @@ int compare(const std::string& directory1, const std::string& basename1, if (!equal) printDifference(serializer1, serializer2, savepoints[i], info1, info2, bounds, failed); } + else if (info1.type() == "float") + { + equal = compareData(serializer1, serializer2, savepoints[i], info1, info2, bounds, tolerance, failed); + if (!equal) + printDifference(serializer1, serializer2, savepoints[i], info1, info2, bounds, failed); + } else { std::cerr << "Unsupported type: " << info1.type() << std::endl; diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 3fb4825..a96d630 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -1,2 +1,7 @@ + +include_directories( SYSTEM ${CMAKE_SOURCE_DIR}/libs/libjson ) +include_directories( ${CMAKE_SOURCE_DIR}/src) +include_directories( ${CMAKE_SOURCE_DIR}/libs/gmock-gtest) + add_subdirectory(serializer) add_subdirectory(wrapper) diff --git a/unittest/serializer/BinarySerializerUnittest.cpp b/unittest/serializer/BinarySerializerUnittest.cpp index d8984bb..6ed35e2 100644 --- a/unittest/serializer/BinarySerializerUnittest.cpp +++ b/unittest/serializer/BinarySerializerUnittest.cpp @@ -10,7 +10,7 @@ using namespace ser; -TEST(BinarySerializerUnittest, TestItAll) +TEST(BinarySerializerUnittest, TestItAllDouble) { BinarySerializer bs; bs.Init(); @@ -73,3 +73,66 @@ TEST(BinarySerializerUnittest, TestItAll) delete[] pDataCheck; } +TEST(BinarySerializerUnittest, TestItAllFloat) +{ + BinarySerializer bs; + bs.Init(); + + // Create some data (layout: JKIL, plus one stride in l) + const int isize = 5, jsize = 6, ksize = 9, lsize = 8; + const int lstride = 2, istride = lstride*lsize, kstride = istride*isize, jstride = kstride*ksize; + const int allocsize = jstride*jsize; + ASSERT_EQ(5*6*9*8*2, allocsize); + float *pData = new float[allocsize]; + float *pDataCheck = new float[allocsize]; + + for (int i = 0; i < isize; ++i) + for (int j = 0; j < jsize; ++j) + for (int k = 0; k < ksize; ++k) + for (int l = 0; l < lsize; ++l) + { + pData[i*istride + j*jstride + l*lstride + k*kstride] + = i*3. + j*2.5 - k*10.25 + l*6.825; + } + + // Serialize array + std::vector sVector; + const std::string checksum = + bs.WriteArray(pData, sizeof(float), isize, jsize, ksize, lsize, + istride*sizeof(float), jstride*sizeof(float), kstride*sizeof(float), lstride*sizeof(float), sVector); + + // Check binary data + const float* sData = reinterpret_cast(sVector.data()); + for (int l = 0; l < lsize; ++l) + for (int k = 0; k < ksize; ++k) + for (int j = 0; j < jsize; ++j) + for (int i = 0; i < isize; ++i) + { + ASSERT_EQ(pData[i*istride + j*jstride + l*lstride + k*kstride], *sData); + sData += 1; + } + + // Check checksum + ASSERT_EQ(computeChecksum(sVector.data(), sVector.size()), checksum); + + // Prepare string stream + bs.ReadArray(pDataCheck, sizeof(float), isize, jsize, ksize, lsize, + istride*sizeof(float), jstride*sizeof(float), kstride*sizeof(float), lstride*sizeof(float), sVector); + + // Check reconstructed array + for (int i = 0; i < isize; ++i) + for (int j = 0; j < jsize; ++j) + for (int k = 0; k < ksize; ++k) + for (int l = 0; l < lsize; ++l) + { + ASSERT_EQ( + pData [i*istride + j*jstride + l*lstride + k*kstride], + pDataCheck[i*istride + j*jstride + l*lstride + k*kstride] + ); + } + + // Release memory + delete[] pData; + delete[] pDataCheck; +} + diff --git a/unittest/serializer/FieldsTableUnittest.cpp b/unittest/serializer/FieldsTableUnittest.cpp index 0d7e775..ece6ad2 100644 --- a/unittest/serializer/FieldsTableUnittest.cpp +++ b/unittest/serializer/FieldsTableUnittest.cpp @@ -37,10 +37,11 @@ TEST_F(FieldsTableUnittest, Serilalize) info1.AddMetainfo("ADV", true); info2.Init( - "Field2", "double", 8, 3, + "Field2", "float", 4, 3, 38, 24, 61, 1, 3, 3, 3, 3, 0, 1, 0, 0); - info2.AddMetainfo("Init", 7.4); + info2.AddMetainfo("InitD", 7.25); + info2.AddMetainfo("InitF", 7.25f); // Registering fields into table table.RegisterField(info1); @@ -89,11 +90,13 @@ TEST_F(FieldsTableUnittest, Serilalize) ASSERT_EQ(node[1]["__jplushalosize"].as_int(), 3); ASSERT_EQ(node[1]["__kminushalosize"].as_int(), 0); ASSERT_EQ(node[1]["__kplushalosize"].as_int(), 1); - ASSERT_EQ(node[1]["Init"].as_float(), 7.4); + ASSERT_EQ(node[1]["InitD"].as_float(), 7.25); + ASSERT_EQ(node[1]["InitF"].as_float(), 7.25f); } TEST_F(FieldsTableUnittest, DeserilalizeField) { + // Double const std::string field_txt = "{" " \"__name\" : \"Field1\"," @@ -132,6 +135,46 @@ TEST_F(FieldsTableUnittest, DeserilalizeField) ASSERT_EQ(0, info1.kMinusHaloSize()); ASSERT_EQ(0, info1.kPlusHaloSize()); ASSERT_EQ(true, info1.metainfo().AsBool("ADV")); + + // Float + const std::string field_txt2 = + "{" + " \"__name\" : \"Field2\"," + " \"__id\" : 0," + " \"__elementtype\" : \"float\", " + " \"__bytesperelement\" : 4," + " \"__rank\" : 3," + " \"__isize\" : 38," + " \"__jsize\" : 24," + " \"__ksize\" : 60," + " \"__iminushalosize\" : 3," + " \"__iplushalosize\" : 3," + " \"__jminushalosize\" : 3," + " \"__jplushalosize\" : 3," + " \"__kminushalosize\" : 0," + " \"__kplushalosize\" : 0," + " \"Init\" : 8.125" + "}" + ; + + JSONNode node2 = libjson::parse(field_txt2); + DataFieldInfo info2; + info2.FromJSON(node2); + + ASSERT_EQ("Field2", info2.name()); + ASSERT_EQ("float", info2.type()); + ASSERT_EQ(4, info2.bytesPerElement()); + ASSERT_EQ(3, info2.rank()); + ASSERT_EQ(38, info2.iSize()); + ASSERT_EQ(24, info2.jSize()); + ASSERT_EQ(60, info2.kSize()); + ASSERT_EQ(3, info2.iMinusHaloSize()); + ASSERT_EQ(3, info2.iPlusHaloSize()); + ASSERT_EQ(3, info2.jMinusHaloSize()); + ASSERT_EQ(3, info2.jPlusHaloSize()); + ASSERT_EQ(0, info2.kMinusHaloSize()); + ASSERT_EQ(0, info2.kPlusHaloSize()); + ASSERT_EQ(8.125f, info2.metainfo().AsFloat("Init")); } TEST_F(FieldsTableUnittest, DeserilalizeTable) @@ -213,6 +256,6 @@ TEST_F(FieldsTableUnittest, DeserilalizeTable) ASSERT_EQ(3, info.jPlusHaloSize()); ASSERT_EQ(0, info.kMinusHaloSize()); ASSERT_EQ(1, info.kPlusHaloSize()); - ASSERT_EQ(7.25, info.metainfo().AsReal("Init")); + ASSERT_EQ(7.25, info.metainfo().AsReal("Init")); } diff --git a/unittest/serializer/OffsetTableUnittest.cpp b/unittest/serializer/OffsetTableUnittest.cpp index e1e841d..b020935 100644 --- a/unittest/serializer/OffsetTableUnittest.cpp +++ b/unittest/serializer/OffsetTableUnittest.cpp @@ -27,7 +27,7 @@ TEST_F(OffsetTableUnittest, Savepoint) sp.AddMetainfo("LargeTimeStep", 1); sp.AddMetainfo("RKStageNumber", 2); sp.AddMetainfo("ldyn_bbc", false); - sp.AddMetainfo("hd", (Real).5); + sp.AddMetainfo("hd", .5); JSONNode node = sp.ToJSON(); @@ -43,7 +43,7 @@ TEST_F(OffsetTableUnittest, Savepoint) sp3.AddMetainfo("LargeTimeStep", 1); sp3.AddMetainfo("RKStageNumber", 3); sp3.AddMetainfo("ldyn_bbc", false); - sp3.AddMetainfo("hd", (Real).5); + sp3.AddMetainfo("hd", .5); ASSERT_NE(sp, sp3); Savepoint sp4; @@ -73,24 +73,27 @@ TEST_F(OffsetTableUnittest, Checksum) sp0.AddMetainfo("ldyn_bbc", false); sp1.Init("DycoreUnittest.DoStep-out"); sp1.AddMetainfo("LargeTimeStep", 2); - sp1.AddMetainfo("hd", (Real).5); + sp1.AddMetainfo("hd", .5); // Test that offset table recognizes checksums OffsetTable table; table.AddNewSavepoint(sp0, 0); table.AddNewSavepoint(sp1, 1); - int offset; + OffsetTable::offset_t offset; - ASSERT_EQ(-1, offset = table.AlreadySerialized("Field1", computeChecksum(data, 4))); + ASSERT_FALSE(table.AlreadySerialized("Field1", computeChecksum(data, 4), offset)); ASSERT_NO_THROW(table.AddFieldRecord(0, "Field1", 0, computeChecksum(data, 4))); - ASSERT_EQ(-1, offset = table.AlreadySerialized("Field1", computeChecksum(data, 8))); + ASSERT_FALSE(table.AlreadySerialized("Field1", computeChecksum(data, 8), offset)); ASSERT_NO_THROW(table.AddFieldRecord(1, "Field1", 100, computeChecksum(data, 8))); - ASSERT_EQ(-1, offset = table.AlreadySerialized("Field2", computeChecksum(data, 8))); + ASSERT_FALSE(table.AlreadySerialized("Field2", computeChecksum(data, 8), offset)); ASSERT_NO_THROW(table.AddFieldRecord(0, "Field2", 200, computeChecksum(data, 8))); - ASSERT_EQ( 0, table.AlreadySerialized("Field1", computeChecksum(data,4))); - ASSERT_EQ(100, table.AlreadySerialized("Field1", computeChecksum(data,8))); - ASSERT_EQ(200, table.AlreadySerialized("Field2", computeChecksum(data,8))); + ASSERT_TRUE(table.AlreadySerialized("Field1", computeChecksum(data, 4), offset)); + ASSERT_EQ(0, offset); + ASSERT_TRUE(table.AlreadySerialized("Field1", computeChecksum(data, 8), offset)); + ASSERT_EQ(100, offset); + ASSERT_TRUE(table.AlreadySerialized("Field2", computeChecksum(data, 8), offset)); + ASSERT_EQ(200, offset); ASSERT_NO_THROW(table.AddFieldRecord(1, "Field2", 200, computeChecksum(data, 8))); ASSERT_EQ( 0, table.GetOffset(sp0, "Field1")); @@ -108,10 +111,10 @@ TEST_F(OffsetTableUnittest, TableToJSON) sp0.AddMetainfo("ldyn_bbc", false); sp1.Init("DycoreUnittest.DoStep-out"); sp1.AddMetainfo("LargeTimeStep", 2); - sp1.AddMetainfo("hd", (Real).5); + sp1.AddMetainfo("hd", .5); // Just for the sake of getting some valid checksums - double somedata[] = { 1.1, 2.2, 3.3, 4.4 }; + float somedata[] = { 1.1f, 2.2f, 3.3f, 4.4f }; // Fill table OffsetTable table; @@ -165,15 +168,20 @@ TEST_F(OffsetTableUnittest, TableToJSON) ASSERT_EQ(1, table2.GetSavepointID(sp[1])); // Check methods + OffsetTable::offset_t offset; ASSERT_EQ( 0, table2.GetOffset(sp0, "Field1")); ASSERT_EQ( 0, table2.GetOffset(sp0, "Field2")); ASSERT_EQ(100, table2.GetOffset(sp1, "Field1")); ASSERT_EQ(100, table2.GetOffset(sp1, "Field2")); - ASSERT_EQ( 0, table2.AlreadySerialized("Field1", computeChecksum(somedata, 4))); - ASSERT_EQ(100, table2.AlreadySerialized("Field1", computeChecksum(somedata, 12))); - ASSERT_EQ( 0, table2.AlreadySerialized("Field2", computeChecksum(somedata, 8))); - ASSERT_EQ(100, table2.AlreadySerialized("Field2", computeChecksum(somedata, 16))); - ASSERT_EQ( -1, table2.AlreadySerialized("Field1", computeChecksum(somedata, 8))); - ASSERT_EQ( -1, table2.AlreadySerialized("Field2", computeChecksum(somedata, 4))); + ASSERT_TRUE(table2.AlreadySerialized("Field1", computeChecksum(somedata, 4), offset)); + ASSERT_EQ( 0, offset); + ASSERT_TRUE(table2.AlreadySerialized("Field1", computeChecksum(somedata, 12), offset)); + ASSERT_EQ(100, offset); + ASSERT_TRUE(table2.AlreadySerialized("Field2", computeChecksum(somedata, 8), offset)); + ASSERT_EQ( 0, offset); + ASSERT_TRUE(table2.AlreadySerialized("Field2", computeChecksum(somedata, 16), offset)); + ASSERT_EQ(100, offset); + ASSERT_FALSE(table2.AlreadySerialized("Field1", computeChecksum(somedata, 8), offset)); + ASSERT_FALSE(table2.AlreadySerialized("Field2", computeChecksum(somedata, 4), offset)); } diff --git a/unittest/serializer/SerializerUnittest.cpp b/unittest/serializer/SerializerUnittest.cpp index 604bcc7..10a1641 100644 --- a/unittest/serializer/SerializerUnittest.cpp +++ b/unittest/serializer/SerializerUnittest.cpp @@ -31,45 +31,51 @@ TEST_F(SerializerUnittest, Write) // Create 4D field with JILK storage plus stride 2 const int isize = 6, jsize = 8, ksize = 7, lsize = 4; const int kstride = 2, lstride = kstride*ksize, istride = lstride*lsize, jstride = istride*isize; - const int ibstride = istride*sizeof(double), jbstride = jstride*sizeof(double), - kbstride = kstride*sizeof(double), lbstride = lstride*sizeof(double); + const int ibstrided = istride*sizeof(double), jbstrided = jstride*sizeof(double), + kbstrided = kstride*sizeof(double), lbstrided = lstride*sizeof(double); + const int ibstridef = istride*sizeof(float), jbstridef = jstride*sizeof(float), + kbstridef = kstride*sizeof(float), lbstridef = lstride*sizeof(float); const int allocsize = jstride*jsize; - std::vector data(allocsize); + std::vector dataD(allocsize); + std::vector dataF(allocsize); for (int i = 0; i < isize; ++i) for (int j = 0; j < jsize; ++j) for (int k = 0; k < ksize; ++k) for (int l = 0; l < lsize; ++l) { - data[i*istride + j*jstride + k*kstride + l*lstride] + dataD[i*istride + j*jstride + k*kstride + l*lstride] + = i*12.25 + j*k*1. - 2.75 / (l+10.); + dataF[i*istride + j*jstride + k*kstride + l*lstride] = i*12.25 + j*k*1. - 2.75 / (l+10.); } // Register various versions of this field serializer.RegisterField("ik" , "double", 8, isize, 1, ksize, 1, 0, 0, 0, 0, 0, 0, 0, 0); - serializer.RegisterField("jk" , "double", 8, 1, jsize, ksize, 1, 0, 0, 0, 0, 0, 0, 0, 0); + serializer.RegisterField("jk" , "float" , 4, 1, jsize, ksize, 1, 0, 0, 0, 0, 0, 0, 0, 0); serializer.RegisterField("ikl" , "double", 8, isize, 1, ksize, lsize, 0, 0, 0, 0, 0, 0, 0, 0); - serializer.RegisterField("ijkl", "double", 8, isize, jsize, ksize, lsize, 0, 0, 0, 0, 0, 0, 0, 0); + serializer.RegisterField("ijkl", "float" , 4, isize, jsize, ksize, lsize, 0, 0, 0, 0, 0, 0, 0, 0); // Setting a savepoint and serializing all fields Savepoint sp; sp.Init("MySavepoint"); sp.AddMetainfo("Value", 3.125); + sp.AddMetainfo("ValueF", 3.625f); sp.AddMetainfo("MyName", "Andrea Arteaga"); sp.AddMetainfo("MyAge", 26); sp.AddMetainfo("ILikeThis", true); const int ilevel = 3, jlevel = 0, llevel = 2; - const double* pIKData = data.data() + jstride*jlevel + lstride*llevel; - const double* pJKData = data.data() + istride*ilevel + lstride*llevel; - const double* pIKLData = data.data() + jstride*jlevel; - const double* pIJKLData = data.data(); + const double* pIKData = dataD.data() + jstride*jlevel + lstride*llevel; + const float* pJKData = dataF.data() + istride*ilevel + lstride*llevel; + const double* pIKLData = dataD.data() + jstride*jlevel; + const float* pIJKLData = dataF.data(); - serializer.WriteField( "ik", sp, pIKData, ibstride, jbstride, kbstride, lbstride); - serializer.WriteField( "jk", sp, pJKData, ibstride, jbstride, kbstride, lbstride); - serializer.WriteField( "ikl", sp, pIKLData, ibstride, jbstride, kbstride, lbstride); - serializer.WriteField("ijkl", sp, pIJKLData, ibstride, jbstride, kbstride, lbstride); + serializer.WriteField( "ik", sp, pIKData, ibstrided, jbstrided, kbstrided, lbstrided); + serializer.WriteField( "jk", sp, pJKData, ibstridef, jbstridef, kbstridef, lbstridef); + serializer.WriteField( "ikl", sp, pIKLData, ibstrided, jbstrided, kbstrided, lbstrided); + serializer.WriteField("ijkl", sp, pIJKLData, ibstridef, jbstridef, kbstridef, lbstridef); // Check metainfo std::ifstream dbfs("Data.json"); @@ -92,6 +98,7 @@ TEST_F(SerializerUnittest, Write) ASSERT_EQ(std::string("MySavepoint"), offsettable[0]["__name"].as_string()); ASSERT_EQ(0, offsettable[0]["__id"].as_int()); ASSERT_EQ(3.125, offsettable[0]["Value"].as_float()); + ASSERT_EQ(3.625f, offsettable[0]["ValueF"].as_float()); ASSERT_EQ(std::string("Andrea Arteaga"), offsettable[0]["MyName"].as_string()); ASSERT_EQ(26, offsettable[0]["MyAge"].as_int()); ASSERT_TRUE(offsettable[0]["ILikeThis"].as_bool()); @@ -116,7 +123,7 @@ TEST_F(SerializerUnittest, Write) { const int j = jlevel, l = llevel; const double value = *(pNewData + k*isize + i); - const double reference = data[i*istride + j*jstride + k*kstride + l*lstride]; + const double reference = dataD[i*istride + j*jstride + k*kstride + l*lstride]; ASSERT_EQ(reference, value) << "i=" << i << ", k=" << k; } } @@ -128,20 +135,20 @@ TEST_F(SerializerUnittest, Write) fs.seekg(0, fs.end); int filelength = fs.tellg(); fs.seekg(0, fs.beg); - ASSERT_EQ(sizeof(double)*jsize*ksize, filelength); + ASSERT_EQ(sizeof(float)*jsize*ksize, filelength); std::vector rawdata(filelength); fs.read(rawdata.data(), filelength); fs.close(); // Check data - const double* pNewData = reinterpret_cast(rawdata.data()); + const float* pNewData = reinterpret_cast(rawdata.data()); for (int j = 0; j < jsize; ++j) for (int k = 0; k < ksize; ++k) { const int i = ilevel, l = llevel; - const double value = *(pNewData + k*jsize + j); - const double reference = data[i*istride + j*jstride + k*kstride + l*lstride]; + const float value = *(pNewData + k*jsize + j); + const float reference = dataF[i*istride + j*jstride + k*kstride + l*lstride]; ASSERT_EQ(reference, value) << "j=" << j << ", k=" << k; } } @@ -167,7 +174,7 @@ TEST_F(SerializerUnittest, Write) { const int j = jlevel; const double value = *(pNewData + l*ksize*isize + k*isize + i); - const double reference = data[i*istride + j*jstride + k*kstride + l*lstride]; + const double reference = dataD[i*istride + j*jstride + k*kstride + l*lstride]; ASSERT_EQ(reference, value) << "i=" << i << ", k=" << k << ", l=" << l; } } @@ -179,27 +186,28 @@ TEST_F(SerializerUnittest, Write) fs.seekg(0, fs.end); int filelength = fs.tellg(); fs.seekg(0, fs.beg); - ASSERT_EQ(sizeof(double)*isize*jsize*ksize*lsize, filelength); + ASSERT_EQ(sizeof(float)*isize*jsize*ksize*lsize, filelength); std::vector rawdata(filelength); fs.read(rawdata.data(), filelength); fs.close(); // Check data - const double* pNewData = reinterpret_cast(rawdata.data()); + const float* pNewData = reinterpret_cast(rawdata.data()); for (int i = 0; i < isize; ++i) for (int j = 0; j < jsize; ++j) for (int k = 0; k < ksize; ++k) for (int l = 0; l < lsize; ++l) { - const double value = *(pNewData + l*ksize*jsize*isize + k*jsize*isize + j*isize + i); - const double reference = data[i*istride + j*jstride + k*kstride + l*lstride]; + const float value = *(pNewData + l*ksize*jsize*isize + k*jsize*isize + j*isize + i); + const float reference = dataF[i*istride + j*jstride + k*kstride + l*lstride]; ASSERT_EQ(reference, value) << "i=" << i << ", j=" << j << ", k=" << k << ", l=" << l; } } // Second savepoint: some fields are rewritten, others are kept the same - data[0] += 1.; + dataD[0] += 1.; + dataF[0] += 1.; // ik does not change // jk does not change // ikl changes @@ -207,10 +215,10 @@ TEST_F(SerializerUnittest, Write) sp.Init("SecondSavepoint"); - serializer.WriteField( "ik", sp, pIKData, ibstride, jbstride, kbstride, lbstride); - serializer.WriteField( "jk", sp, pJKData, ibstride, jbstride, kbstride, lbstride); - serializer.WriteField( "ikl", sp, pIKLData, ibstride, jbstride, kbstride, lbstride); - serializer.WriteField("ijkl", sp, pIJKLData, ibstride, jbstride, kbstride, lbstride); + serializer.WriteField( "ik", sp, pIKData, ibstrided, jbstrided, kbstrided, lbstrided); + serializer.WriteField( "jk", sp, pJKData, ibstridef, jbstridef, kbstridef, lbstridef); + serializer.WriteField( "ikl", sp, pIKLData, ibstrided, jbstrided, kbstrided, lbstrided); + serializer.WriteField("ijkl", sp, pIJKLData, ibstridef, jbstridef, kbstridef, lbstridef); // Load offsettable again dbfs.open("Data.json"); @@ -239,9 +247,9 @@ TEST_F(SerializerUnittest, Write) const std::string fieldname = offsettable[1]["__offsets"][i].name(); int filelength_expect; if (fieldname == "ik") filelength_expect = 1*sizeof(double)*isize* 1 *ksize* 1 ; - if (fieldname == "jk") filelength_expect = 1*sizeof(double)* 1 *jsize*ksize* 1 ; + if (fieldname == "jk") filelength_expect = 1*sizeof(float )* 1 *jsize*ksize* 1 ; if (fieldname == "ikl") filelength_expect = 2*sizeof(double)*isize* 1 *ksize*lsize; - if (fieldname == "ijkl") filelength_expect = 2*sizeof(double)*isize*jsize*ksize*lsize; + if (fieldname == "ijkl") filelength_expect = 2*sizeof(float )*isize*jsize*ksize*lsize; std::ifstream fs(("Data_" + fieldname + ".dat").c_str(), std::ios::binary); fs.seekg(0, fs.end); diff --git a/unittest/wrapper/FieldUnittest.cpp b/unittest/wrapper/FieldUnittest.cpp index b02169f..fd09629 100644 --- a/unittest/wrapper/FieldUnittest.cpp +++ b/unittest/wrapper/FieldUnittest.cpp @@ -203,7 +203,7 @@ TEST_F(FieldUnittest, Register) TEST_F(FieldUnittest, FieldMetainfo) { fs_register_field(&ser, "field1", 6, "int" , 3, 4, 42, 1, 80, 1, 3, 3, 0, 0, 0, 1, 0, 0); - fs_register_field(&ser, "field2", 6, "double", 6, 8, 1, 28, 80, 12, 0, 0, 2, 2, 0, 0, 1, 1); + fs_register_field(&ser, "field2", 6, "float", 5, 4, 1, 28, 80, 12, 0, 0, 2, 2, 0, 0, 1, 1); // Add some metainfo fs_add_field_metainfo_b(&ser, "field1", 6, "FirstField", 10, true); diff --git a/unittest/wrapper/ReadWriteUnittest.cpp b/unittest/wrapper/ReadWriteUnittest.cpp index 1c55239..e3d10c3 100644 --- a/unittest/wrapper/ReadWriteUnittest.cpp +++ b/unittest/wrapper/ReadWriteUnittest.cpp @@ -13,13 +13,14 @@ class ReadWriteUnittest: public ::testing::Test { // These vectors are used as Fortran-style storage std::vector fieldInt2, fieldInt3; - std::vector fieldReal1, fieldReal3; + std::vector fieldDouble1, fieldDouble3; + std::vector fieldFloat1, fieldFloat3; std::vector fieldcheckInt2, fieldcheckInt3; - std::vector fieldcheckReal1, fieldcheckReal3; + std::vector fieldcheckDouble1, fieldcheckDouble3; + std::vector fieldcheckFloat1, fieldcheckFloat3; - std::string realtype; int iSize, jSize, kSize; - int intSize, realSize; + int intSize, doubleSize, floatSize; Serializer ser; Savepoint sp; @@ -29,23 +30,23 @@ class ReadWriteUnittest: public ::testing::Test { jSize = 18; kSize = 10; -#ifdef _SINGLEPRECISION_ - realtype = "float"; -#else - realtype = "double"; -#endif intSize = sizeof(int); - realSize = sizeof(Real); + doubleSize = sizeof(double); + floatSize = sizeof(float); // Allocate fields fieldInt2.resize(iSize*kSize); fieldInt3.resize(iSize*jSize*kSize); - fieldReal1.resize(jSize); - fieldReal3.resize(iSize*jSize*kSize); + fieldDouble1.resize(jSize); + fieldDouble3.resize(iSize*jSize*kSize); + fieldFloat1.resize(jSize); + fieldFloat3.resize(iSize*jSize*kSize); fieldcheckInt2.resize(iSize*kSize); fieldcheckInt3.resize(iSize*jSize*kSize); - fieldcheckReal1.resize(jSize); - fieldcheckReal3.resize(iSize*jSize*kSize); + fieldcheckDouble1.resize(jSize); + fieldcheckDouble3.resize(iSize*jSize*kSize); + fieldcheckFloat1.resize(jSize); + fieldcheckFloat3.resize(iSize*jSize*kSize); // Initialize serialization objects ser.Init("./", "ReadWriteUnittest", SerializerOpenModeWrite); @@ -54,8 +55,10 @@ class ReadWriteUnittest: public ::testing::Test { // Register fields ser.RegisterField("int3", "int", intSize, iSize, jSize, kSize, 1, 0, 0, 0, 0, 0, 0, 0, 0); ser.RegisterField("int2", "int", intSize, iSize, 1, kSize, 1, 0, 0, 0, 0, 0, 0, 0, 0); - ser.RegisterField("real3", realtype, realSize, iSize, jSize, kSize, 1, 0, 0, 0, 0, 0, 0, 0, 0); - ser.RegisterField("real1", realtype, realSize, 1, jSize, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); + ser.RegisterField("double3", "double", doubleSize, iSize, jSize, kSize, 1, 0, 0, 0, 0, 0, 0, 0, 0); + ser.RegisterField("double1", "double", doubleSize, 1, jSize, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); + ser.RegisterField("float3", "float", floatSize, iSize, jSize, kSize, 1, 0, 0, 0, 0, 0, 0, 0, 0); + ser.RegisterField("float1", "float", floatSize, 1, jSize, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0); FillFields(); } @@ -65,8 +68,10 @@ class ReadWriteUnittest: public ::testing::Test { std::remove("ReadWriteUnittest.json"); std::remove("ReadWriteUnittest_int3.dat"); std::remove("ReadWriteUnittest_int2.dat"); - std::remove("ReadWriteUnittest_real3.dat"); - std::remove("ReadWriteUnittest_real1.dat"); + std::remove("ReadWriteUnittest_double3.dat"); + std::remove("ReadWriteUnittest_double1.dat"); + std::remove("ReadWriteUnittest_float3.dat"); + std::remove("ReadWriteUnittest_float1.dat"); } void FillFields() { @@ -75,7 +80,8 @@ class ReadWriteUnittest: public ::testing::Test { for (int k = 0; k < kSize; ++k) { fieldInt3[i + j*iSize + k*iSize*jSize] = i + 2*j - 12*k*i; - fieldReal3[i + j*iSize + k*iSize*jSize] = 1.125*i + 2.25*j - 12.5*k*i; + fieldDouble3[i + j*iSize + k*iSize*jSize] = 1.125*i + 2.25*j - 12.5*k*i; + fieldFloat3[i + j*iSize + k*iSize*jSize] = 1.5f*i + 4.25f*j - 16.0f*k*i; } for (int i = 0; i < iSize; ++i) @@ -86,7 +92,8 @@ class ReadWriteUnittest: public ::testing::Test { for (int j = 0; j < jSize; ++j) { - fieldReal1[j] = j*j+2.875; + fieldDouble1[j] = j*j+2.875; + fieldFloat1[j] = j*j+3.5f; } } @@ -113,20 +120,26 @@ TEST_F(ReadWriteUnittest, Write) // Write fields fs_write_field(&ser, &sp, "int3", 4, fieldInt3.data(), intSize, intSize*iSize, intSize*iSize*jSize, 0); fs_write_field(&ser, &sp, "int2", 4, fieldInt2.data(), intSize, 0, intSize*iSize, 0); - fs_write_field(&ser, &sp, "real3", 5, fieldReal3.data(), realSize, realSize*iSize, realSize*iSize*jSize, 0); - fs_write_field(&ser, &sp, "real1", 5, fieldReal1.data(), 0, realSize, 0, 0); + fs_write_field(&ser, &sp, "double3", 7, fieldDouble3.data(), doubleSize, doubleSize*iSize, doubleSize*iSize*jSize, 0); + fs_write_field(&ser, &sp, "double1", 7, fieldDouble1.data(), 0, doubleSize, 0, 0); + fs_write_field(&ser, &sp, "float3", 6, fieldFloat3.data(), floatSize, floatSize*iSize, floatSize*iSize*jSize, 0); + fs_write_field(&ser, &sp, "float1", 6, fieldFloat1.data(), 0, floatSize, 0, 0); // Load with C++ ser.ReadField("int3", sp, fieldcheckInt3.data(), intSize, intSize*iSize, intSize*iSize*jSize, 0); ser.ReadField("int2", sp, fieldcheckInt2.data(), intSize, 0, intSize*iSize, 0); - ser.ReadField("real3", sp, fieldcheckReal3.data(), realSize, realSize*iSize, realSize*iSize*jSize, 0); - ser.ReadField("real1", sp, fieldcheckReal1.data(), 0, realSize, 0, 0); + ser.ReadField("double3", sp, fieldcheckDouble3.data(), doubleSize, doubleSize*iSize, doubleSize*iSize*jSize, 0); + ser.ReadField("double1", sp, fieldcheckDouble1.data(), 0, doubleSize, 0, 0); + ser.ReadField("float3", sp, fieldcheckFloat3.data(), floatSize, floatSize*iSize, floatSize*iSize*jSize, 0); + ser.ReadField("float1", sp, fieldcheckFloat1.data(), 0, floatSize, 0, 0); // Check ASSERT_TRUE(CheckVector(fieldInt3, fieldcheckInt3)); ASSERT_TRUE(CheckVector(fieldInt2, fieldcheckInt2)); - ASSERT_TRUE(CheckVector(fieldReal3, fieldcheckReal3)); - ASSERT_TRUE(CheckVector(fieldReal1, fieldcheckReal1)); + ASSERT_TRUE(CheckVector(fieldDouble3, fieldcheckDouble3)); + ASSERT_TRUE(CheckVector(fieldDouble1, fieldcheckDouble1)); + ASSERT_TRUE(CheckVector(fieldFloat3, fieldcheckFloat3)); + ASSERT_TRUE(CheckVector(fieldFloat1, fieldcheckFloat1)); } /** @@ -138,19 +151,25 @@ TEST_F(ReadWriteUnittest, Read) // Write with C++ ser.WriteField("int3", sp, fieldInt3.data(), intSize, intSize*iSize, intSize*iSize*jSize, 0); ser.WriteField("int2", sp, fieldInt2.data(), intSize, 0, intSize*iSize, 0); - ser.WriteField("real3", sp, fieldReal3.data(), realSize, realSize*iSize, realSize*iSize*jSize, 0); - ser.WriteField("real1", sp, fieldReal1.data(), 0, realSize, 0, 0); + ser.WriteField("double3", sp, fieldDouble3.data(), doubleSize, doubleSize*iSize, doubleSize*iSize*jSize, 0); + ser.WriteField("double1", sp, fieldDouble1.data(), 0, doubleSize, 0, 0); + ser.WriteField("float3", sp, fieldFloat3.data(), floatSize, floatSize*iSize, floatSize*iSize*jSize, 0); + ser.WriteField("float1", sp, fieldFloat1.data(), 0, floatSize, 0, 0); // Load fields fs_read_field(&ser, &sp, "int3", 4, fieldcheckInt3.data(), intSize, intSize*iSize, intSize*iSize*jSize, 0); fs_read_field(&ser, &sp, "int2", 4, fieldcheckInt2.data(), intSize, 0, intSize*iSize, 0); - fs_read_field(&ser, &sp, "real3", 5, fieldcheckReal3.data(), realSize, realSize*iSize, realSize*iSize*jSize, 0); - fs_read_field(&ser, &sp, "real1", 5, fieldcheckReal1.data(), 0, realSize, 0, 0); + fs_read_field(&ser, &sp, "double3", 7, fieldcheckDouble3.data(), doubleSize, doubleSize*iSize, doubleSize*iSize*jSize, 0); + fs_read_field(&ser, &sp, "double1", 7, fieldcheckDouble1.data(), 0, doubleSize, 0, 0); + fs_read_field(&ser, &sp, "float3", 6, fieldcheckFloat3.data(), floatSize, floatSize*iSize, floatSize*iSize*jSize, 0); + fs_read_field(&ser, &sp, "float1", 6, fieldcheckFloat1.data(), 0, floatSize, 0, 0); // Check ASSERT_TRUE(CheckVector(fieldInt3, fieldcheckInt3)); ASSERT_TRUE(CheckVector(fieldInt2, fieldcheckInt2)); - ASSERT_TRUE(CheckVector(fieldReal3, fieldcheckReal3)); - ASSERT_TRUE(CheckVector(fieldReal1, fieldcheckReal1)); + ASSERT_TRUE(CheckVector(fieldDouble3, fieldcheckDouble3)); + ASSERT_TRUE(CheckVector(fieldDouble1, fieldcheckDouble1)); + ASSERT_TRUE(CheckVector(fieldFloat3, fieldcheckFloat3)); + ASSERT_TRUE(CheckVector(fieldFloat1, fieldcheckFloat1)); } diff --git a/unittest/wrapper/SavepointUnittest.cpp b/unittest/wrapper/SavepointUnittest.cpp index 24a5873..822163a 100644 --- a/unittest/wrapper/SavepointUnittest.cpp +++ b/unittest/wrapper/SavepointUnittest.cpp @@ -56,7 +56,7 @@ TEST(SavepointUnittest, Metainfo) fs_add_savepoint_metainfo_s(&sp, "MyOS", 4, "GNU/Linux", 9); // Get metainfo number - ASSERT_EQ(6, fs_savepoint_metainfo(&sp)); + ASSERT_EQ(6, fs_savepoint_metainfo_size(&sp)); // Get keys of metainfo int key_length[6];