Skip to content

Commit

Permalink
Merge branch '120-add-a-failure-refactoring-status-entry-upon-ambiguo…
Browse files Browse the repository at this point in the history
…us-fqn' into patch
  • Loading branch information
khatchad authored Nov 10, 2023
2 parents 2f49d0c + c4ddc17 commit b38e2a0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -758,13 +758,18 @@ private boolean matches(exprType lhsParamExpr, String lhsParamName, LocalPointer
/**
* Discovers if this {@link Function} is hybrid. If so, populated this {@link Function}'s {@link HybridizationParameters}.
*/
public void computeHybridization(IProgressMonitor monitor) throws BadLocationException {
public void computeHybridization(IProgressMonitor monitor) throws BadLocationException, UndeterminableHybridizationException {
// TODO: Consider mechanisms other than decorators (e.g., higher order functions; #3).
monitor.beginTask("Computing hybridization ...", IProgressMonitor.UNKNOWN);

FunctionDefinition functionDefinition = this.getFunctionDefinition();
decoratorsType[] decoratorArray = functionDefinition.getFunctionDef().decs;

// if this function is decorated with "tf.function."
Boolean hybrid = null;

boolean issuedInfo = false;

if (decoratorArray != null) {
String containingModuleName = this.getContainingModuleName();
File containingFile = this.getContainingFile();
Expand All @@ -779,9 +784,6 @@ public void computeHybridization(IProgressMonitor monitor) throws BadLocationExc
IDocument document = this.getContainingDocument();
PySelection selection = null;

// if this function is decorated with "tf.function."
boolean hybrid = false;

try {
selection = Util.getSelection(decorator, document);
hybrid = isHybrid(decorator, containingModuleName, containingFile, selection, nature, monitor);
Expand All @@ -799,20 +801,21 @@ public void computeHybridization(IProgressMonitor monitor) throws BadLocationExc
LOG.info(String.format(
"Encountered potentially generated decorator: %s in selection: %s, module: %s, file: %s, and project; %s.",
decoratorFunctionRepresentation, selectedText, containingModuleName, containingFileName, project));
issuedInfo = true;
} else if (Util.isBuiltIn(decorator)) {
// Since tf.function isn't built-in, skip built-in decorators.
LOG.info(String.format(
"Encountered potentially built-in decorator: %s in selection: %s, module: %s, file: %s, and project; %s.",
decoratorFunctionRepresentation, selectedText, containingModuleName, containingFileName, project));
} else {
issuedInfo = true;
} else
LOG.warn(String.format(
"Can't determine if decorator: %s in selection: %s, module: %s, file: %s, and project; %s is hybrid.",
decoratorFunctionRepresentation, selectedText, containingModuleName, containingFileName,
nature.getProject()), e);
}
}

if (hybrid) {
if (hybrid != null && hybrid) {
this.setIsHybrid(TRUE);
LOG.info(this + " is hybrid.");

Expand All @@ -828,6 +831,9 @@ public void computeHybridization(IProgressMonitor monitor) throws BadLocationExc
}
}

if (decoratorArray != null && decoratorArray.length > 0 && hybrid == null && !issuedInfo)
throw new UndeterminableHybridizationException();

this.setIsHybrid(FALSE);
LOG.info(this + " is not hybrid.");
monitor.done();
Expand Down Expand Up @@ -861,11 +867,15 @@ private static boolean isHybrid(decoratorsType decorator, String containingModul
}

public void addFailure(PreconditionFailure failure, String message) {
RefactoringStatusContext context = new FunctionStatusContext();
this.addFailure(failure, message, context);
}

public void addFailure(PreconditionFailure failure, String message, RefactoringStatusContext context) {
// If is side-effects is filled, we can't set a precondition failure that we can't determine them.
assert this.getHasPythonSideEffects() == null
|| failure != PreconditionFailure.UNDETERMINABLE_SIDE_EFFECTS : "Can't both have side-effects filled and have tem undterminable.";

RefactoringStatusContext context = new FunctionStatusContext();
this.getStatus().addEntry(RefactoringStatus.ERROR, message, context, PLUGIN_ID, failure.getCode(), this);
}

Expand All @@ -878,7 +888,7 @@ public void addWarning(String message) {
* Check refactoring preconditions.
*/
public void check() {
if (!this.getIsHybrid()) { // Eager. Table 1.
if (this.getIsHybrid() != null && !this.getIsHybrid()) { // Eager. Table 1.
this.setRefactoring(CONVERT_EAGER_FUNCTION_TO_HYBRID);

if (this.getLikelyHasTensorParameter()) {
Expand All @@ -894,7 +904,7 @@ public void check() {
if (this.getHasPythonSideEffects() != null && this.getHasPythonSideEffects())
this.addFailure(PreconditionFailure.HAS_PYTHON_SIDE_EFFECTS, "Can't hybridize a function with Python side-effects.");
}
} else { // Hybrid. Use table 2.
} else if (this.getIsHybrid() != null) { // Hybrid. Use table 2.
this.setRefactoring(OPTIMIZE_HYBRID_FUNCTION);

if (!this.getLikelyHasTensorParameter()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ public enum PreconditionFailure {

HAS_NO_TENSOR_PARAMETERS(6),

HAS_TENSOR_PARAMETERS(7);
HAS_TENSOR_PARAMETERS(7),

/**
* Can't determine whether the decorator actually refers to the real tf.function. It may not (and we've found cases of this in
* mead-baseline).
*/
UNDETERMINABLE_HYBRID_DECORATOR(8);

static {
// check that the codes are unique.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package edu.cuny.hunter.hybridize.core.analysis;

public class UndeterminableHybridizationException extends Exception {

private static final long serialVersionUID = -7461244972182215002L;

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import edu.cuny.hunter.hybridize.core.analysis.Function;
import edu.cuny.hunter.hybridize.core.analysis.FunctionDefinition;
import edu.cuny.hunter.hybridize.core.analysis.PreconditionFailure;
import edu.cuny.hunter.hybridize.core.analysis.UndeterminableHybridizationException;
import edu.cuny.hunter.hybridize.core.analysis.UndeterminablePythonSideEffectsException;
import edu.cuny.hunter.hybridize.core.descriptors.HybridizeFunctionRefactoringDescriptor;
import edu.cuny.hunter.hybridize.core.messages.Messages;
Expand Down Expand Up @@ -231,6 +232,9 @@ private RefactoringStatus checkFunctions(IProgressMonitor monitor) throws Operat
func.computeHybridization(subMonitor.split(IProgressMonitor.UNKNOWN));
} catch (BadLocationException e) {
throw new RuntimeException("Could not compute hybridization for: " + func + ".", e);
} catch (UndeterminableHybridizationException e) {
LOG.warn("Unable to infer hybridization of: " + func + ".", e);
func.addFailure(PreconditionFailure.UNDETERMINABLE_HYBRID_DECORATOR, "Can't compute whether " + func + " is hybrid.");
}

try {
Expand All @@ -241,7 +245,8 @@ private RefactoringStatus checkFunctions(IProgressMonitor monitor) throws Operat

// Check Python side-effects.
try {
if (this.getAlwaysCheckPythonSideEffects() || func.getIsHybrid() || func.getLikelyHasTensorParameter())
if (this.getAlwaysCheckPythonSideEffects() || (func.getIsHybrid() != null && func.getIsHybrid())
|| func.getLikelyHasTensorParameter())
func.inferPythonSideEffects(callGraph, builder.getPointerAnalysis());
} catch (UndeterminablePythonSideEffectsException e) {
LOG.warn("Unable to infer side-effects of: " + func + ".", e);
Expand Down

0 comments on commit b38e2a0

Please sign in to comment.