-
Notifications
You must be signed in to change notification settings - Fork 10.6k
[AutoDiff] Update @differentiable attribute, refactor lookupFuncDecl method.
#17246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…` method. - Add adjoint access level check to @differentiable attribute. - If the original function is "exported" (public or @_versioned), then the adjoint must also be exported. - Generalize `lookupFuncDecl` function and add it as a method to `TypeChecker` so that it can be used for type-checking #adjoint expression in a later commit.
lib/Sema/TypeCheckExpr.cpp
Outdated
| } | ||
| // If function declaration could not be resolved, emit the appropriate | ||
| // diagnostic. | ||
| if (!resolvedFuncDecl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flip this and early return?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| std::function<void()> primalInvalidTypeContextDiagnostic = [&]() { | ||
| TC.diagnose(primalNameLoc, | ||
| diag::differentiable_attr_function_not_same_type_context, | ||
| primalSpecifier.Name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need a setInvalid here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think setInvalid is handled by the block below:
primal = TC.lookupFuncDecl(...)
if (!primal) {
attr->setInvalid();
return;
}If any diagnostic is emitted, primal will be nullptr and attr->setInvalid() will execute.
| notAFuncDecl = true; | ||
| continue; | ||
| } | ||
| if (hasValidTypeCtx.hasValue()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (hasValidTypeCtx && !(*hasValidTypeCtx)(funcDecl)) {
wrongTypeContext = true;
continue;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/Sema/TypeCheckExpr.cpp
Outdated
| // If function declaration could not be resolved, emit the appropriate | ||
| // diagnostic. | ||
| if (!resolvedFuncDecl) { | ||
| if (results.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of these if-elses, I would suggest
if (results.empty()) {
diagnose(...)
return;
}
if (ambiguousFuncDecl) {
ambiguousDiagnostic();
return;
}
...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| // the type context. | ||
| // This works around the fact that operators cannot be specified with a | ||
| // qualified name (i.e. only `(+)` works, `Float.(+)` doesn't). | ||
| if (funcName.isOperator() && lookupContext->isTypeContext()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about
if (funcName.isOperator() && lookupContext->isTypeContext())
if (auto tmp = lookupMember(lookupContext, lookupContext->getSelfTypeInContext(), funcName))
results = tmp;Before writing any empty() checks, I'd usually check whether tmp has operator bool() first. In this case LookupResult does have one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the tip! Done.
Addresses comments from @rxwei.
dan-zheng
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I'll add tests for @differentiable access control before merging.
| std::function<void()> primalInvalidTypeContextDiagnostic = [&]() { | ||
| TC.diagnose(primalNameLoc, | ||
| diag::differentiable_attr_function_not_same_type_context, | ||
| primalSpecifier.Name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think setInvalid is handled by the block below:
primal = TC.lookupFuncDecl(...)
if (!primal) {
attr->setInvalid();
return;
}If any diagnostic is emitted, primal will be nullptr and attr->setInvalid() will execute.
| // the type context. | ||
| // This works around the fact that operators cannot be specified with a | ||
| // qualified name (i.e. only `(+)` works, `Float.(+)` doesn't). | ||
| if (funcName.isOperator() && lookupContext->isTypeContext()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the tip! Done.
| notAFuncDecl = true; | ||
| continue; | ||
| } | ||
| if (hasValidTypeCtx.hasValue()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/Sema/TypeCheckExpr.cpp
Outdated
| } | ||
| // If function declaration could not be resolved, emit the appropriate | ||
| // diagnostic. | ||
| if (!resolvedFuncDecl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/Sema/TypeCheckExpr.cpp
Outdated
| // If function declaration could not be resolved, emit the appropriate | ||
| // diagnostic. | ||
| if (!resolvedFuncDecl) { | ||
| if (results.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
- Add @differentiable access control check to primal as well as adjoint. - Add @differentiable access control test. - Add diagnostic for differentiating void functions.
|
LGTM |
|
Good idea about renaming |
dd020fb to
aac118b
Compare
|
@swift-ci Please test tensorflow |
…` method. (#17246) * [AutoDiff] Update @differentiable attribute, refactor `lookupFuncDecl` method. - Add adjoint access level check to @differentiable attribute. - If the original function is "exported" (public or @_versioned), then the adjoint must also be exported. - Generalize `lookupFuncDecl` function and add it as a method to `TypeChecker` so that it can be used for type-checking #adjoint expression in a later commit. * Refactoring/clean up. Addresses comments from @rxwei. * Add/fix @differentiable attribute diagnostics, clean up. - Add @differentiable access control check to primal as well as adjoint. - Add @differentiable access control test. - Add diagnostic for differentiating void functions. * Preemptively rename @_versioned to @usableFromInline.
…` method. (#17246) * [AutoDiff] Update @differentiable attribute, refactor `lookupFuncDecl` method. - Add adjoint access level check to @differentiable attribute. - If the original function is "exported" (public or @_versioned), then the adjoint must also be exported. - Generalize `lookupFuncDecl` function and add it as a method to `TypeChecker` so that it can be used for type-checking #adjoint expression in a later commit. * Refactoring/clean up. Addresses comments from @rxwei. * Add/fix @differentiable attribute diagnostics, clean up. - Add @differentiable access control check to primal as well as adjoint. - Add @differentiable access control test. - Add diagnostic for differentiating void functions. * Preemptively rename @_versioned to @usableFromInline.
…` method. (#17246) * [AutoDiff] Update @differentiable attribute, refactor `lookupFuncDecl` method. - Add adjoint access level check to @differentiable attribute. - If the original function is "exported" (public or @_versioned), then the adjoint must also be exported. - Generalize `lookupFuncDecl` function and add it as a method to `TypeChecker` so that it can be used for type-checking #adjoint expression in a later commit. * Refactoring/clean up. Addresses comments from @rxwei. * Add/fix @differentiable attribute diagnostics, clean up. - Add @differentiable access control check to primal as well as adjoint. - Add @differentiable access control test. - Add diagnostic for differentiating void functions. * Preemptively rename @_versioned to @usableFromInline.
@differentiableattribute.adjoint must also be exported.
lookupFuncDeclfunction and add it as a method toTypeCheckerso that it can be used for type-checking
#adjointexpression in a latercommit.