BlockDifferentiator

public class BlockDifferentiator

Object that knows how to differentiate Basic Blocks.

IMPORTANT NOTICE: It is necessary that a good instruction split has been done beforehand, before the zone numbering, i.e. during the unit.preprocess() in CallGraph.terminateTypesAndZones(). Otherwise, the beforeActiv and afterActiv information may be insufficient for variables that are written many times by a same instruction. OPEN PROBLEM: split, as defined here in BlockDifferentiator.splitForADReverse(), was meant to make use of the activity analysis, some day, probably by not splitting call arguments that are passive. This will not be possible if splitting is done long before activity analysis, in CallGraph.terminateTypesAndZones(). If this original instruction split was well done, then one could get rid of the split defined here in BlockDifferentiator.splitForADReverse().

Fields

adEnv

protected DifferentiationEnv adEnv

Global environment for differentiation.

inUseNewSymbolHolders

protected TapList<NewSymbolHolder> inUseNewSymbolHolders

numRebase

protected int numRebase

Temporary only for debug of ADMM.

Constructors

BlockDifferentiator

protected BlockDifferentiator(DifferentiationEnv adEnv)

Methods

addFuturePlainNodeBwd

protected void addFuturePlainNodeBwd(Tree tree, InstructionMask whereMask, boolean loopIfMultiDir, TapList<Tree> treesRead, TapList<Tree> treesWritten, TapList<Tree> treesReadBis, TapList<Tree> treesWrittenBis, boolean followPointers, boolean hiddenDep, String description, boolean isMainCorrespondent)

PREpend a new instruction (“tree”) at the head of the list of future instructions of the BWD DIFF block of curBlock. The new instruction will contain “tree”, optionally controlled by mask “whereMask”, and repeated over multi-directions if “loopIfMultiDir” is true. Future possible reordering is constrained by the list of (derivative) expressions possibly/partly read by this new instruction “treesRead” (“treesReadBis”), and similarly possibly/partly written expressions “treesWritten” (“treesWrittenBis”), plus possible hidden dependencies (e.g. files read/write, stack push/pop) through “hiddenDep”.

Parameters
  • followPointers – when true, consider that read/written trees also concern destination zones through pointers.

  • hiddenDep – when true, consider this tree also reads and/or writes some internal hidden variable, e.g. stack.

  • description – a description of this new instruction, for debug -traceDifferentiation.

  • isMainCorrespondent – when true, HTML display shows this new instruction as the target of curInstruction.

addFuturePlainNodeFwd

protected void addFuturePlainNodeFwd(Tree tree, InstructionMask whereMask, boolean loopIfMultiDir, TapList<Tree> treesRead, TapList<Tree> treesWritten, TapList<Tree> treesReadBis, TapList<Tree> treesWrittenBis, boolean followPointers, boolean hiddenDep, String description, boolean isMainCorrespondent)

Append a new instruction (“tree”) at the tail of the list of future instructions of the FWD DIFF block of curBlock. The new instruction will contain “tree”, optionally controlled by mask “whereMask”, and repeated over multi-directions if “loopIfMultiDir” is true. Future possible reordering is constrained by the list of (derivative) expressions possibly/partly read by this new instruction “treesRead” (“treesReadBis”), and similarly possibly/partly written expressions “treesWritten” (“treesWrittenBis”), plus possible hidden dependencies (e.g. files read/write, stack push/pop) through “hiddenDep”.

Parameters
  • followPointers – when true, consider that read/written trees also concern destination zones through pointers.

  • hiddenDep – when true, consider this tree also reds and/or writes some internal hidden variable, e.g. stack.

  • description – a description of this new instruction, for debug -traceDifferentiation.

  • isMainCorrespondent – when true, HTML display shows this new instruction as the target of curInstruction.

addFutureSetDiffNodeBwd

protected void addFutureSetDiffNodeBwd(DiffAssignmentNode adjAssign, String description)

PREpend a new “diffvar=expression” instruction at the head of the list of future instructions of the BWD DIFF block of curBlock. The new instruction to add is described by “adjAssign” (see DiffAssignmentNode).

Parameters
  • adjAssign – the description of the new derivative instruction to be PREpend’ed.

  • description – a textual description of the diff assigned variable, for debug -traceDifferentiation.

addInUseNewSymbolHolder

protected void addInUseNewSymbolHolder(NewSymbolHolder tmpVarHolder)

buildDiffPreInitsForTangent

protected void buildDiffPreInitsForTangent(Tree lhs, Tree rhs, Tree srcDecl, BoolVector beforeActiv, BoolVector afterActiv, BoolVector beforeReqX, BoolVector afterReqX, boolean onlyOnLocals, TapList<ZoneInfo> toInitialized)
Parameters
  • onlyOnLocals – flag (not clearly justified) that restricts initialization to local arrays and possibly to the function result when it is an array. Currently, it is used to reduce the number of redundant diff arrays initialization in tangent mode, that are requested by buildDiffPreInitsForTangent().

  • toInitialized – if given non-null, will contain upon exit the list of all ZoneInfo for which the diff has been initialized.

collectTrueTrees

protected TapList<Tree> collectTrueTrees(BoolVector boolVector, int[] map, SymbolTable srcSymbolTable)
Returns

a list of expression Trees that represent all zones with a “true” in boolVector.

debugLabel

protected static Tree debugLabel(String name, int num)

differentiateBlock

protected void differentiateBlock(Block block, Block fwdBlock, Block bwdBlock, int differentiationMode, ToBool lastTestLive)

Fill “fwdBlock” and “bwdBlock” with the differentiation of “block” in the given “differentiationMode”.

Parameters
  • differentiationMode – in {TANGENT_MODE, DifferentiationConstants.ADJOINT_MODE, DifferentiationConstants.ADJOINT_SPLIT_MODE}

  • lastTestLive – upon return, will be filled with true iff the last instruction of “block” is a test and it is live.

differentiateCommonName

protected String differentiateCommonName(String commonName, int diffSort)

Generate a differentiated common name, avoiding common names already in use.

Parameters
  • commonName – the original common name.

  • diffSort – the sort of differentiation (e.g. ORIGCOPY, TANGENT, ADJOINT).

Returns

the differentiated common name.

differentiateDeclarationsOfBlock

protected void differentiateDeclarationsOfBlock(Block diffBlock, int differentiationMode, Unit unit, SymbolTable originalST, SymbolTable curDiffST, int origLanguage, boolean forInterface)

diffBlock is a Block of the differentiated code, but it still contains only the declarations copied from its original source block. This method inserts the corresponding declarations for the differentiated variables,types,etc…

Parameters
  • originalST – The original SymbolTable of the original source Block

  • forInterface – true when we are differentiating an INTERFACE declaration, in which case we don’t want to differentiate formal arguments that are only active inside the diff routine and therefore have no diff formal argument.

getForcedScopingNames

protected static TapList<String> getForcedScopingNames(Block usageBlock)

When usageBlock is inside the scope of an OMP PARALLEL region.

Returns

the list of variable names for which the adjoint scoping is forced by a user-given directive “$AD OMP …”. This list has been attached to the controlling OMP PARALLEL Tree.

getOnlyReadSmallActivePrimals

protected static BoolVector getOnlyReadSmallActivePrimals(Block usageBlock)

When usageBlock is inside the scope of an OMP PARALLEL region.

Returns

the BoolVector of the “onlyReadSmallActivePrimals” that has been attached to the OMP PARALLEL Tree, which contains the zones for which we decided for a REDUCTION(+) adjoint.

makeDiffInitialization

protected Tree[] makeDiffInitialization(Tree exprToInitialize, ZoneInfo fromZoneInfo, SymbolTable defSymbolTable, SymbolTable usageSymbolTable, SymbolTable otherUsageSymbolTable, boolean protectAccesses, TapList ignoreStructure, boolean ignorePointed)

Builds a (block of) trees that reset to zero all memory cells of the derivative of “exprToInitialize”. Returns an array of such blocks, one per diff replica (in general 1).

Parameters
  • fromZoneInfo – When non-null, indicates that we want to initialize a complete zone.

Returns

an instruction that resets to zero all memory cells of the derivative of “exprToInitialize”.

makeDiffInitializationOneReplica

protected Tree makeDiffInitializationOneReplica(Tree exprToInitialize, SymbolTable defSymbolTable, SymbolTable usageSymbolTable, SymbolTable otherUsageSymbolTable, boolean protectAccesses, TapList ignoreStructure, boolean ignorePointed)

Same as makeDiffInitialization(), but builds only ONE replica of the diff initialization instruction, i.e. the replica for the current adEnv.iReplic. Outside -diffReplica mode, this is equivalent to makeDiffInitialization(). This is used only in NewBlockGraphNode.buildInstruction, and it would be nicer that it does NOT call makeDiffInitialization() !

mixedLanguage

protected boolean mixedLanguage(FunctionDecl funcDecl)
Parameters
  • funcDecl – interoperable procedure.

Returns

true if procedure definition and call belong to different languages.

patternsCalledByPattern

protected static TapList<ActivityPattern> patternsCalledByPattern(Unit calledUnit, ActivityPattern callingPattern)
Returns

the list of all ActivityPatterns of the given “calledUnit” that are used/called by the given “callingPattern” of the current Unit. If callingPattern is null (case of e.g. modules), then return all “active” activity patterns. If the calledUnit has a “not connected” ActivityPattern, it is returned too. Does NOT return those activity patterns that are not really active (i.e. that would cause no differentiation), i.e. a pattern with null in/out activity, ReqX, and AvlX.

pointerIsActiveHere

protected boolean pointerIsActiveHere(Tree varRef, BoolVector beforeActiv, BoolVector afterActiv, BoolVector beforeAvlX, BoolVector afterReqX)

popStaticSaves

protected void popStaticSaves()

prepareRestoreOperations

protected void prepareRestoreOperations(RefDescriptor refDescriptor, RefDescriptor refDescriptorRestore, int knownMultiplicity, SymbolTable fwdSymbolTable, SymbolTable bwdSymbolTable)

pushStaticSaves

protected void pushStaticSaves(TapTriplet<Boolean, TapList<RefDescriptor>, TapList<RefDescriptor>> staticSaves)

replaceAllocateInExprToInitialize

protected static Tree replaceAllocateInExprToInitialize(Tree exprToInitialize)

tangentDiffExpr

protected Tree[] tangentDiffExpr(ToObject<Tree> toPrimalExpr, BoolVector beforeActiv, TapPair<TapList<Tree>, TapList<Tree>> primRW, TapPair<TapList<Tree>, TapList<Tree>> diffRW)

tryStaticTape

protected RefDescriptor tryStaticTape(Block block, int knownMultiplicity, String staticVarName, WrapperTypeSpec staticVarRootType, SymbolTable fwdDiffSymbolTable, SymbolTable diffSymbolTable)

If at the current place “block” we can use static taping instead of a dynamic stack to store a tape value of type “staticVarRootType”.

Parameters
  • knownMultiplicity – a conventional integer meaningful only when block is the header of a loop L, and we are considering static taping: 1: even if L has dynamic length, this saving is done only once, therefore we can accept static taping for L 2: even if L is basically checkpointed (e.g. BINOMIAL_LOOP), this saving is done arbitrarily many times, therefore we must always reject static taping. 0: default, neutral value: when L has dynamic length, L will reject static taping as expected.

  • diffSymbolTable – the SymbolTable of the actual saving/restoring instruction.

Returns

a RefDescriptor for the local variable named “staticVarName” that will contain the stored value or null.

turnAssociationByAddressPrimal

protected Tree turnAssociationByAddressPrimal(Tree expr, SymbolTable srcSymbolTable, SymbolTable destSymbolTable, WrapperTypeSpec contextTypeSpec, boolean onlyPrimalCode)

Turns a source expr into the “same” non-diff expr, but based on the primal parts of AA diff variables. Example: turns x = 2*y into x.v = 2*y.v; Turns foo(x, y) into foo(x.v, y,v) according to functionTypeSpec of foo in the differentiated callGraph, turns x into x.v according to contextTypeSpec.

Parameters
  • contextTypeSpec – if the context is an argument of a function call, type of the formal argument, else null.

  • onlyPrimalCode – true if the intended behavior of this instruction is to compute only primal value.

Returns

The given expr, possibly modified.

updateAACopiedInstruction

protected void updateAACopiedInstruction(Instruction instruction, Block srcBlock, Block copyBlock, int rank)

For association by address differentiation mode.

Parameters
  • instruction – source Instruction.

  • srcBlock – source Block.

  • copyBlock – Block in the differentiated callGraph.

  • rank – of the instruction in the source Block.

updateAAInstructionMask

protected void updateAAInstructionMask(Instruction instruction, SymbolTable srcSymbolTable, SymbolTable destSymbolTable)

updateModulesAndCopiedUnitsInCopiedInterface

protected void updateModulesAndCopiedUnitsInCopiedInterface(Tree copyTree, SymbolTable diffSymbolTable, int diffMode)