MCPcopy Create free account
hub / github.com/pydata/numexpr / _mutate

Function _mutate

numexpr3/ne3compiler.py:947–1009  ·  view source on GitHub ↗

Used for intermediate assignment targets. This takes the valueReg and mutates targetReg into it. Cases: 1. targetReg is KIND_ARRAY or KIND_SCALAR in which case it has been pre-allocated and is a secondary return. 2. targetReg is KIND_NAMED in which case it's a _na

(self: NumExpr, targetNode: ast.AST, valueReg: NumReg)

Source from the content-addressed store, hash-verified

945 return self.assignTarget
946
947def _mutate(self: NumExpr, targetNode: ast.AST, valueReg: NumReg) -> NumReg:
948 '''
949 Used for intermediate assignment targets. This takes the valueReg and
950 mutates targetReg into it.
951
952 Cases:
953 1. targetReg is KIND_ARRAY or KIND_SCALAR in which case it has been
954 pre-allocated and is a secondary return.
955 2. targetReg is KIND_NAMED in which case it's a _named_ temporary. I.e.
956 a temporary that we cannot re-use because it was assigned as an
957 intermediate assignment target.
958
959 In some cases this will require a new temporary. For example, if the output
960 dtype is smaller than the valueReg.dchar it can't be mutated to a named
961 output.
962 '''
963 # print(f'Mutating: {targetNode} and {valueReg}')
964
965 if isinstance(targetNode, ast.Name):
966 if valueReg.kind & (_KIND_ARRAY|_KIND_SCALAR):
967 # This is a copy, like NumExpr( 'y=x' )
968 targetReg = _ASTAssembler[type(targetNode)](self, targetNode)
969 targetReg.dchar = valueReg.dchar
970 return self._copy(targetReg, valueReg)
971 # else KIND_TEMP|KIND_NAMED
972 nodeId = targetNode.id
973 if nodeId in self.registers:
974 # Pre-existing, pre-known output.
975 # Often in-line operation, e.g. NumExpr('b=2*b')
976 # Should we count how many times each temporary is used?
977 # As this is a case where if the temp is used twice we can't
978 # get rid of it, but if it's used once we can pop it.
979 targetReg = self.registers[nodeId]
980 # Intermediate assignment targets keep their KIND
981 program = self._codeStream.getbuffer()
982 oldToken = program[_RET_LOC]
983 program[_RET_LOC] = targetReg._num
984 return targetReg
985
986 if valueReg.itemsize <= _DCHAR_ITEMSIZE[self.assignDChar]:
987 # Can mutate as the valueReg temporary's itemsize is less-than-equal to
988 # the output array's.
989 self.registers.pop(valueReg.name)
990 valueReg.name = nodeId
991 if nodeId in self.local_dict: # Pre-allocated array found
992 nodeRef = self.local_dict[nodeId]
993 if type(nodeRef) != np.ndarray: nodeRef = np.asarray( nodeRef )
994 valueReg.ref = nodeRef if np.isscalar(nodeRef) else weakref.ref(nodeRef)
995
996 valueReg.kind = _KIND_RETURN
997 self.assignTarget = self.registers[nodeId] = valueReg
998 return valueReg
999
1000 else:
1001 # Else mutate valueRegister into assignTarget
1002 # TODO: rewind
1003 raise NotImplementedError('TODO: rewind program')
1004

Callers 1

_assignFunction · 0.85

Calls 1

_copyMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…