From 6ff810e94af84ae47e3a1bd06a4abdf12de49ea0 Mon Sep 17 00:00:00 2001 From: Viktor Gal Date: Wed, 21 Feb 2018 21:51:23 +0100 Subject: [PATCH] for the current way of serialization we need to split Serializable classes for container types --- examples/meta/generator/translate.py | 29 +++++++++++----------- src/interfaces/swig/Library.i | 14 +++++------ src/shogun/io/Serializable.h | 37 +++++++++++++++++++++++----- src/shogun/lib/DynamicObjectArray.h | 24 ++++++++++++------ 4 files changed, 69 insertions(+), 35 deletions(-) diff --git a/examples/meta/generator/translate.py b/examples/meta/generator/translate.py index 10b4c4a16ac..c5817e86b13 100644 --- a/examples/meta/generator/translate.py +++ b/examples/meta/generator/translate.py @@ -81,7 +81,7 @@ def getSGTypesToStore(): def getSGTypeToStoreMethodName(sgType): """ Translates given SG* type into meta language type """ assert sgType in getSGTypesToStore() - + if sgType=="RealVector": return "real_vector" elif sgType=="FloatVector": @@ -90,10 +90,10 @@ def getSGTypeToStoreMethodName(sgType): return "real_matrix" elif sgType=="FloatMatrix": return "float_matrix" - + else: raise RuntimeError("Given Shogun type \"%s\" cannot be translated to meta type", sgType) - + def getVarsToStore(program): """ Extracts all variables in program that should be stored """ @@ -293,18 +293,19 @@ def injectVarsStoring(self, statementList, programName, varsToStore): sgType = vartypeAST[list(vartypeAST.keys())[0]] assert sgType in getBasicTypesToStore() or sgType in getSGTypesToStore() + appendElementIdentifier = "append_element" if "cpp" in self.targetDict["FileExtension"]: - methodNameSuffix = "<%s>" % self.targetDict["Type"][sgType] - else: - if sgType in getBasicTypesToStore(): - methodNameSuffix = sgType - elif sgType in getSGTypesToStore(): - methodNameSuffix = getSGTypeToStoreMethodName(sgType) - methodNameSuffix = "_%s" % methodNameSuffix + if sgType.endswith("Vector"): + suffix = self.targetDict["Type"][sgType].replace("SGVector", "") + elif sgType.endswith("Matrix"): + suffix = self.targetDict["Type"][sgType].replace("SGMatrix", "") + else: + suffix = "<%s>" % self.targetDict["Type"][sgType] + appendElementIdentifier += suffix methodCall = { "MethodCall": [{"Identifier": storage}, - {"Identifier": "append_element%s" % methodNameSuffix}, + {"Identifier": appendElementIdentifier}, {"ArgumentList": [varnameIdentifierExpr, varnameExpr]}] } @@ -489,7 +490,7 @@ def translateInit(self, init): ) normalArgs = [ - arg for arg in initialisation["ArgumentList"] + arg for arg in initialisation["ArgumentList"] if not "KeywordArgument" in arg ] kwargsString = self.translateKwargs( @@ -560,7 +561,7 @@ def translateExpr(self, expr, returnKwargs=False): elif key == "StringLiteral": template = Template(self.targetDict["Expr"]["StringLiteral"]) return template.substitute(literal=expr[key]) - + elif key == "CharLiteral": template = Template(self.targetDict["Expr"]["CharLiteral"]) return template.substitute(literal=expr[key]) @@ -651,7 +652,7 @@ def translateGlobalCall(self, globalCall, returnKwargs): ) normalArgs = [ - arg for arg in argsList["ArgumentList"] + arg for arg in argsList["ArgumentList"] if not "KeywordArgument" in arg ] kwargsString = self.translateKwargs( diff --git a/src/interfaces/swig/Library.i b/src/interfaces/swig/Library.i index b3d0a446aef..6342de7291d 100644 --- a/src/interfaces/swig/Library.i +++ b/src/interfaces/swig/Library.i @@ -402,13 +402,12 @@ namespace shogun { /* Specialize DynamicObjectArray::append_element function */ #ifdef USE_FLOAT64 - %template(append_element_real) CDynamicObjectArray::append_element; - %template(append_element_real_vector) CDynamicObjectArray::append_element, SGVector>; - %template(append_element_real_matrix) CDynamicObjectArray::append_element, SGMatrix>; + %template(append_element) CDynamicObjectArray::append_element; + %template(append_element) CDynamicObjectArray::append_element; #ifdef SWIGOCTAVE /* (Octave converts single element arrays to scalars and our typemaps take that for real) */ %extend CDynamicObjectArray { - bool append_element_real_vector(float64_t v, const char* name="") + bool append_element(float64_t v, const char* name="") { SGVector wrap(1); wrap[0] = v; @@ -418,12 +417,11 @@ namespace shogun #endif #endif #ifdef USE_FLOAT32 - %template(append_element_float) CDynamicObjectArray::append_element; - %template(append_element_float_vector) CDynamicObjectArray::append_element, SGVector>; - %template(append_element_float_matrix) CDynamicObjectArray::append_element, SGMatrix>; + %template(append_element) CDynamicObjectArray::append_element; + %template(append_element) CDynamicObjectArray::append_element; #endif #ifdef USE_INT32 - %template(append_element_int) CDynamicObjectArray::append_element; + %template(append_element) CDynamicObjectArray::append_element; #endif } %include diff --git a/src/shogun/io/Serializable.h b/src/shogun/io/Serializable.h index 402f1d5fc05..a1d393ea435 100644 --- a/src/shogun/io/Serializable.h +++ b/src/shogun/io/Serializable.h @@ -71,13 +71,20 @@ template class CSerializable: public CSGObject * @param value Value to serialize as CSGObject. * @param value_name Name under which value is registered. */ - CSerializable(T value, const char* value_name="") + CSerializable(T value, const char* value_name=""): CSGObject() { init(); m_value = value; - m_value_name = value_name; + //FIXME: add support for std::string serialization } + /** + * Get stored value + * + * @return stored value + */ + virtual T get_value() const { return m_value; } + /** @return name of the CSGObject, without C prefix */ virtual const char* get_name() const { return "Serializable"; } @@ -86,18 +93,36 @@ template class CSerializable: public CSGObject { set_generic::value_type>(); m_value = 0; - m_value_name = "Unnamed"; - SG_ADD(&m_value, "value", "Serialized value", MS_NOT_AVAILABLE); } protected: /** Serialized value. */ T m_value; +}; + +// FIXME: once the class factory is refactored this should be dropped and +// CSerializable should be use directly +template class CVectorSerializable: public CSerializable> +{ +public: + CVectorSerializable() : CSerializable>() {} + CVectorSerializable(SGVector value, const char* value_name=""): CSerializable>(value, value_name) {} + virtual ~CVectorSerializable() {} - /** Name of serialized value */ - const char* m_value_name; + /** @return name of the CSGObject, without C prefix */ + virtual const char* get_name() const { return "VectorSerializable"; } }; +template class CMatrixSerializable: public CSerializable> +{ +public: + CMatrixSerializable() : CSerializable>() {} + CMatrixSerializable(SGMatrix value, const char* value_name=""): CSerializable>(value, value_name) {} + virtual ~CMatrixSerializable() {} + + /** @return name of the CSGObject, without C prefix */ + virtual const char* get_name() const { return "MatrixSerializable"; } +}; }; #endif // SHOGUN_SERIALIZABLE_H_ diff --git a/src/shogun/lib/DynamicObjectArray.h b/src/shogun/lib/DynamicObjectArray.h index 4f2020310ff..ffae2c7805c 100644 --- a/src/shogun/lib/DynamicObjectArray.h +++ b/src/shogun/lib/DynamicObjectArray.h @@ -1,8 +1,8 @@ /* * This software is distributed under BSD 3-clause license (see LICENSE file). * - * Authors: Soeren Sonnenburg, Heiko Strathmann, Evgeniy Andreev, - * Sergey Lisitsyn, Leon Kuchenbecker, Yuyu Zhang, Thoralf Klein, + * Authors: Soeren Sonnenburg, Heiko Strathmann, Evgeniy Andreev, + * Sergey Lisitsyn, Leon Kuchenbecker, Yuyu Zhang, Thoralf Klein, * Fernando Iglesias, Björn Esser */ @@ -277,15 +277,25 @@ class CDynamicObjectArray : public CSGObject return success; } - template ::type>::value, T>::type> + template ::value>> inline bool append_element(T e, const char* name="") { auto serialized_element = new CSerializable(e, name); - bool success = m_array.append_element(serialized_element); - if (success) - SG_REF(serialized_element); + return append_element(serialized_element); + } - return success; + template + inline bool append_element(SGVector e, const char* name="") + { + auto serialized_element = new CVectorSerializable(e, name); + return append_element(serialized_element); + } + + template + inline bool append_element(SGMatrix e, const char* name="") + { + auto serialized_element = new CMatrixSerializable(e, name); + return append_element(serialized_element); } /** append array element to the end of array