def _specializeFreeVariablesAndEvaluate( self, foraExpression, renamedVariableMapping ): allAreIVC = True for _, v in renamedVariableMapping.iteritems(): if not isinstance(v, ForaNative.ImplValContainer): allAreIVC = False if allAreIVC: missingVariableDefinitions = [ x for x in foraExpression.freeVariables if x not in renamedVariableMapping ] if missingVariableDefinitions: raise pyfora.PythonToForaConversionError( ("An internal error occurred: we didn't provide a " + "definition for the following variables: %s" % missingVariableDefinitions + ". Most likely, there is a mismatch between our analysis of the " "python code and the generated FORA code underneath. Please file a bug report." )) #we need to determine whether we should bind the free variables in this expression as constants #inline in the code, or as class members. Binding them as constants speeds up the compiler, #but if we have the same function bound repeatedly with many constants, we'll end up #producing far too much code. This algorithm binds as constants the _First_ time we bind #a given expression with given arguments, and as members any future set of times. This #should cause it to bind modules and classes that don't have any data flowing through them #as constants, and closures and functions we're calling repeatedly using class members. shouldMapArgsAsConstants = True boundValues = tuple(renamedVariableMapping[k].hash for k in sorted(renamedVariableMapping)) if foraExpression.hash() not in self.boundExpressions: self.boundExpressions[foraExpression.hash()] = boundValues else: bound = self.boundExpressions[foraExpression.hash()] if boundValues != bound: shouldMapArgsAsConstants = False return ForaNative.evaluateRootLevelCreateObjectExpression( foraExpression, renamedVariableMapping, shouldMapArgsAsConstants ) else: #function that evaluates the CreateObject. #Args are the free variables, in lexical order expressionAsIVC = foraExpression.toFunctionImplval(False) args = [] for f in foraExpression.freeVariables: args.append(renamedVariableMapping[f]) res = ComputedValue.ComputedValue( args=(expressionAsIVC, Symbol_Call) + tuple(args) ) return res
def extractVectorContents(vectorIVC): if len(vectorIVC) == 0: return {'listContents': []} vec = ComputedValue.ComputedValueVector( vectorImplVal=vectorIVC) vecSlice = vec.entireSlice res = None preventPythonArrayExtraction = False #see if it's a string. This is the only way to be holding a Vector of char if vectorIVC.isVectorOfChar(): res = vecSlice.extractVectorDataAsNumpyArray() if res is not None: res = {'string': res.tostring()} #see if it's simple enough to transmit as numpy data if res is None and len(vectorIVC.getVectorElementsJOR() ) == 1 and len(vectorIVC) > 1: res = vecSlice.extractVectorDataAsNumpyArrayInChunks() if res is not None: firstElement = vecSlice.extractVectorItemAsIVC(0) if firstElement is None: #note we can't import this at the top of the file because this file gets imported #during the build process, which doesn't have pyfora installed. import pyfora.Exceptions as Exceptions raise Exceptions.ForaToPythonConversionError( "Shouldn't be possible to download data as numpy, and then not get the first value" ) res = { 'firstElement': firstElement, 'contentsAsNumpyArrays': res } else: if not vecSlice.vdmThinksIsLoaded(): #there's a race condition where the data could be loaded between now and #the call to 'extractVectorDataAsPythonArray'. This prevents it. preventPythonArrayExtraction = True #see if we can extract the data as a regular pythonlist if not preventPythonArrayExtraction and res is None: res = vecSlice.extractVectorDataAsPythonArray() if res is not None: res = {'listContents': res} if res is None: vecSlice.increaseRequestCount() return None return res
def extractVectorContents(vectorIVC): if len(vectorIVC) == 0: return [] vec = ComputedValue.ComputedValueVector( vectorImplVal=vectorIVC) vecSlice = vec.entireSlice if vectorIVC.isVectorOfChar(): res = vecSlice.extractVectorDataAsNumpyArray() if res is not None: res = res.tostring() else: res = vecSlice.extractVectorDataAsPythonArray() if res is None: vectorSlicesNeedingLoad.append(vecSlice) vecSlice.increaseRequestCount() return None return res
def createComputedValue(*strings): return ComputedValue.ComputedValue( args=tuple([(FORA.extractImplValContainer( ForaValue.FORAValue(FORA.eval(x))) if isinstance(x, str) else x) for x in strings]))