From c655838ec6a951660dfab215cb0d1e8e20bf5dc2 Mon Sep 17 00:00:00 2001 From: Jean-Philippe ARGAUD Date: Fri, 25 Apr 2014 14:31:06 +0200 Subject: [PATCH] Improving calculation cache management --- src/daComposant/daCore/AssimilationStudy.py | 13 +++++ src/daComposant/daCore/BasicObjects.py | 52 ++++++++----------- .../daNumerics/ApproximatedDerivatives.py | 32 ++---------- 3 files changed, 41 insertions(+), 56 deletions(-) diff --git a/src/daComposant/daCore/AssimilationStudy.py b/src/daComposant/daCore/AssimilationStudy.py index 112d75a..b9010d8 100644 --- a/src/daComposant/daCore/AssimilationStudy.py +++ b/src/daComposant/daCore/AssimilationStudy.py @@ -262,6 +262,8 @@ class AssimilationStudy: "withAvoidingRedundancy" :True, "withToleranceInRedundancy" :1.e-18, "withLenghtOfRedundancy" :-1, + "withmpEnabled" :False, + "withmpWorkers" :None, } """ if (type(asFunction) is type({})) and \ @@ -273,6 +275,8 @@ class AssimilationStudy: if not asFunction.has_key("withAvoidingRedundancy"): asFunction["withAvoidingRedundancy"] = True if not asFunction.has_key("withToleranceInRedundancy"): asFunction["withToleranceInRedundancy"] = 1.e-18 if not asFunction.has_key("withLenghtOfRedundancy"): asFunction["withLenghtOfRedundancy"] = -1 + if not asFunction.has_key("withmpEnabled"): asFunction["withmpEnabled"] = False + if not asFunction.has_key("withmpWorkers"): asFunction["withmpWorkers"] = None from daNumerics.ApproximatedDerivatives import FDApproximation FDA = FDApproximation( Function = asFunction["Direct"], @@ -282,6 +286,8 @@ class AssimilationStudy: avoidingRedundancy = asFunction["withAvoidingRedundancy"], toleranceInRedundancy = asFunction["withToleranceInRedundancy"], lenghtOfRedundancy = asFunction["withLenghtOfRedundancy"], + mpEnabled = asFunction["withmpEnabled"], + mpWorkers = asFunction["withmpWorkers"], ) self.__HO["Direct"] = Operator( fromMethod = FDA.DirectOperator ) self.__HO["Tangent"] = Operator( fromMethod = FDA.TangentOperator ) @@ -359,6 +365,8 @@ class AssimilationStudy: "withAvoidingRedundancy" :True, "withToleranceInRedundancy" :1.e-18, "withLenghtOfRedundancy" :-1, + "withmpEnabled" :False, + "withmpWorkers" :None, } """ if (type(asFunction) is type({})) and \ @@ -370,6 +378,8 @@ class AssimilationStudy: if not asFunction.has_key("withAvoidingRedundancy"): asFunction["withAvoidingRedundancy"] = True if not asFunction.has_key("withToleranceInRedundancy"): asFunction["withToleranceInRedundancy"] = 1.e-18 if not asFunction.has_key("withLenghtOfRedundancy"): asFunction["withLenghtOfRedundancy"] = -1 + if not asFunction.has_key("withmpEnabled"): asFunction["withmpEnabled"] = False + if not asFunction.has_key("withmpWorkers"): asFunction["withmpWorkers"] = None from daNumerics.ApproximatedDerivatives import FDApproximation FDA = FDApproximation( Function = asFunction["Direct"], @@ -379,6 +389,8 @@ class AssimilationStudy: avoidingRedundancy = asFunction["withAvoidingRedundancy"], toleranceInRedundancy = asFunction["withToleranceInRedundancy"], lenghtOfRedundancy = asFunction["withLenghtOfRedundancy"], + mpEnabled = asFunction["withmpEnabled"], + mpWorkers = asFunction["withmpWorkers"], ) self.__EM["Direct"] = Operator( fromMethod = FDA.DirectOperator ) self.__EM["Tangent"] = Operator( fromMethod = FDA.TangentOperator ) @@ -782,6 +794,7 @@ class AssimilationStudy: dans la variable de type dictionnaire "StoredVariables", qui contient en particulier des objets de Persistence pour les analyses, OMA... """ + Operator.CM.clearCache() self.shape_validate() # self.__algorithm.run( diff --git a/src/daComposant/daCore/BasicObjects.py b/src/daComposant/daCore/BasicObjects.py index 10b93fa..cb1d074 100644 --- a/src/daComposant/daCore/BasicObjects.py +++ b/src/daComposant/daCore/BasicObjects.py @@ -49,39 +49,33 @@ class CacheManager: self.clearCache() def clearCache(self): - self.__listOPCP = [] # Operator Previous Calculated Points - self.__listOPCR = [] # Operator Previous Calculated Results - self.__listOPCN = [] # Operator Previous Calculated Point Norms - self.__ac = False - self.__iac = -1 + self.__listOPCV = [] # Operator Previous Calculated Points, Results, Point Norms + # logging.debug("CM Tolerance de determination des doublons : %.2e"%self.__tolerBP) def wasCalculatedIn(self, xValue, info="" ): - self.__ac, self.__iac = False, -1 - for i in xrange(len(self.__listOPCP)-1,-1,-1): - if xValue.size != self.__listOPCP[i].size: + __alc = False + __HxV = None + for i in xrange(min(len(self.__listOPCV),self.__lenghtOR)-1,-1,-1): + if xValue.size != self.__listOPCV[i][0].size: + # logging.debug("CM Différence de la taille %s de X et de celle %s du point %i déjà calculé"%(xValue.shape,i,self.__listOPCP[i].shape)) continue - if numpy.linalg.norm(numpy.ravel(xValue) - self.__listOPCP[i]) < self.__tolerBP * self.__listOPCN[i]: - self.__ac, self.__iac = True, i + if numpy.linalg.norm(numpy.ravel(xValue) - self.__listOPCV[i][0]) < self.__tolerBP * self.__listOPCV[i][2]: + __alc = True + __HxV = self.__listOPCV[i][1] + # logging.debug("CM Cas%s déja calculé, portant le numéro %i"%(info,i)) break - return self.__ac - - def getValueInX(self, info="" ): - if self.__ac and (-1 < self.__iac < len(self.__listOPCR)): - __HX = self.__listOPCR[self.__iac] - self.__ac, self.__iac = False, -1 - return __HX - else: - raise ValueError("CM Cas%s non encore disponible, vérifier au préalable son existence"%info) + return __alc, __HxV def storeValueInX(self, xValue, HxValue ): if self.__lenghtOR < 0: self.__lenghtOR = 2 * xValue.size + 2 - if len(self.__listOPCP) > self.__lenghtOR: - self.__listOPCP.pop(0) - self.__listOPCR.pop(0) - self.__listOPCN.pop(0) - self.__listOPCP.append( copy.copy(numpy.ravel(xValue)) ) - self.__listOPCR.append( copy.copy(HxValue) ) - self.__listOPCN.append( numpy.linalg.norm(xValue) ) + while len(self.__listOPCV) > self.__lenghtOR: + # logging.debug("CM Réduction de la liste des cas à %i éléments par suppression du premier"%self.__lenghtOR) + self.__listOPCV.pop(0) + self.__listOPCV.append( ( + copy.copy(numpy.ravel(xValue)), + copy.copy(HxValue), + numpy.linalg.norm(xValue), + ) ) # ============================================================================== class Operator: @@ -127,14 +121,14 @@ class Operator: Arguments : - xValue : argument adapté pour appliquer l'opérateur """ - if self.__AvoidRC and Operator.CM.wasCalculatedIn(xValue): - __alreadyCalculated = True + if self.__AvoidRC: + __alreadyCalculated, __HxV = Operator.CM.wasCalculatedIn(xValue) else: __alreadyCalculated = False # if __alreadyCalculated: self.__addOneCacheCall() - HxValue = Operator.CM.getValueInX() + HxValue = __HxV else: if self.__Matrix is not None: self.__addOneMatrixCall() diff --git a/src/daComposant/daNumerics/ApproximatedDerivatives.py b/src/daComposant/daNumerics/ApproximatedDerivatives.py index f78a74a..3292f4e 100644 --- a/src/daComposant/daNumerics/ApproximatedDerivatives.py +++ b/src/daComposant/daNumerics/ApproximatedDerivatives.py @@ -49,6 +49,8 @@ class FDApproximation: avoidingRedundancy = True, toleranceInRedundancy = 1.e-18, lenghtOfRedundancy = -1, + mpEnabled = False, + mpWorkers = None, ): self.__userOperator = Operator( fromMethod = Function ) self.__userFunction = self.__userOperator.appliedTo @@ -56,11 +58,7 @@ class FDApproximation: if avoidingRedundancy: self.__avoidRC = True self.__tolerBP = float(toleranceInRedundancy) - self.__lenghtRH = int(lenghtOfRedundancy) self.__lenghtRJ = int(lenghtOfRedundancy) - self.__listDPCP = [] # Direct Operator Previous Calculated Points - self.__listDPCR = [] # Direct Operator Previous Calculated Results - self.__listDPCN = [] # Direct Operator Previous Calculated Point Norms self.__listJPCP = [] # Jacobian Previous Calculated Points self.__listJPCI = [] # Jacobian Previous Calculated Increment self.__listJPCR = [] # Jacobian Previous Calculated Results @@ -95,28 +93,9 @@ class FDApproximation: """ Calcul du direct à l'aide de la fonction fournie. """ + logging.debug("FDA Calcul DirectOperator (explicite)") _X = numpy.asmatrix(numpy.ravel( X )).T - # - __alreadyCalculated = False - if self.__avoidRC: - __alreadyCalculated, __i = self.__doublon__(_X, self.__listDPCP, self.__listDPCN, " H") - # - if __alreadyCalculated: - logging.debug("FDA Calcul DirectOperator (par récupération du doublon %i)"%__i) - _HX = self.__listDPCR[__i] - else: - logging.debug("FDA Calcul DirectOperator (explicite)") - _HX = numpy.ravel(self.__userFunction( _X )) - if self.__avoidRC: - if self.__lenghtRH < 0: self.__lenghtRH = 2 * _X.size - if len(self.__listDPCP) > self.__lenghtRH: - logging.debug("FDA Réduction de la liste de H à %i éléments"%self.__lenghtRH) - self.__listDPCP.pop(0) - self.__listDPCR.pop(0) - self.__listDPCN.pop(0) - self.__listDPCP.append( copy.copy(_X) ) - self.__listDPCR.append( copy.copy(_HX) ) - self.__listDPCN.append( numpy.linalg.norm(_X) ) + _HX = numpy.ravel(self.__userFunction( _X )) # return _HX @@ -212,8 +191,7 @@ class FDApproximation: _Jacobienne = numpy.matrix( numpy.vstack( _Jacobienne ) ).T if self.__avoidRC: if self.__lenghtRJ < 0: self.__lenghtRJ = 2 * _X.size - if len(self.__listJPCP) > self.__lenghtRJ: - logging.debug("FDA Réduction de la liste de J à %i éléments"%self.__lenghtRJ) + while len(self.__listJPCP) > self.__lenghtRJ: self.__listJPCP.pop(0) self.__listJPCI.pop(0) self.__listJPCR.pop(0) -- 2.39.2