Skip to content

[AutoDiff] Fixes memory leaks in autodiff linear map context allocation builtins #67944

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

Merged
merged 3 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/swift/AST/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -985,14 +985,14 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTaskInGroup,
/// is a pure value and therefore we can consider it as readnone).
BUILTIN_MISC_OPERATION_WITH_SILGEN(GlobalStringTablePointer, "globalStringTablePointer", "n", Special)

// autoDiffCreateLinearMapContext: (Builtin.Word) -> Builtin.NativeObject
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffCreateLinearMapContext, "autoDiffCreateLinearMapContext", "", Special)
// autoDiffCreateLinearMapContextWithType: (T.Type) -> Builtin.NativeObject
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffCreateLinearMapContextWithType, "autoDiffCreateLinearMapContextWithType", "", Special)

// autoDiffProjectTopLevelSubcontext: (Builtin.NativeObject) -> Builtin.RawPointer
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffProjectTopLevelSubcontext, "autoDiffProjectTopLevelSubcontext", "n", Special)

// autoDiffAllocateSubcontext: (Builtin.NativeObject, Builtin.Word) -> Builtin.RawPointer
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffAllocateSubcontext, "autoDiffAllocateSubcontext", "", Special)
// autoDiffAllocateSubcontextWithType: (Builtin.NativeObject, T.Type) -> Builtin.RawPointer
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffAllocateSubcontextWithType, "autoDiffAllocateSubcontextWithType", "", Special)

/// Build a Builtin.Executor value from an "ordinary" serial executor
/// reference.
Expand Down
16 changes: 8 additions & 8 deletions include/swift/Runtime/RuntimeFunctions.def
Original file line number Diff line number Diff line change
Expand Up @@ -2273,12 +2273,12 @@ FUNCTION(TaskGroupDestroy,
ATTRS(NoUnwind),
EFFECT(Concurrency))

// AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContext(size_t);
FUNCTION(AutoDiffCreateLinearMapContext,
swift_autoDiffCreateLinearMapContext, SwiftCC,
// AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContextWithType(const Metadata *);
FUNCTION(AutoDiffCreateLinearMapContextWithType,
swift_autoDiffCreateLinearMapContextWithType, SwiftCC,
DifferentiationAvailability,
RETURNS(RefCountedPtrTy),
ARGS(SizeTy),
ARGS(TypeMetadataPtrTy),
ATTRS(NoUnwind, ArgMemOnly),
EFFECT(AutoDiff))

Expand All @@ -2291,12 +2291,12 @@ FUNCTION(AutoDiffProjectTopLevelSubcontext,
ATTRS(NoUnwind, ArgMemOnly),
EFFECT(AutoDiff))

// void *swift_autoDiffAllocateSubcontext(AutoDiffLinearMapContext *, size_t);
FUNCTION(AutoDiffAllocateSubcontext,
swift_autoDiffAllocateSubcontext, SwiftCC,
// void *swift_autoDiffAllocateSubcontextWithType(AutoDiffLinearMapContext *, const Metadata *);
FUNCTION(AutoDiffAllocateSubcontextWithType,
swift_autoDiffAllocateSubcontextWithType, SwiftCC,
DifferentiationAvailability,
RETURNS(Int8PtrTy),
ARGS(RefCountedPtrTy, SizeTy),
ARGS(RefCountedPtrTy, TypeMetadataPtrTy),
ATTRS(NoUnwind, ArgMemOnly),
EFFECT(AutoDiff))

Expand Down
11 changes: 6 additions & 5 deletions lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1609,7 +1609,8 @@ static ValueDecl *getBuildComplexEqualitySerialExecutorRef(ASTContext &ctx,
static ValueDecl *getAutoDiffCreateLinearMapContext(ASTContext &ctx,
Identifier id) {
return getBuiltinFunction(
id, {BuiltinIntegerType::getWordType(ctx)}, ctx.TheNativeObjectType);
ctx, id, _thin, _generics(_unrestricted),
_parameters(_metatype(_typeparam(0))), _nativeObject);
}

static ValueDecl *getAutoDiffProjectTopLevelSubcontext(ASTContext &ctx,
Expand All @@ -1621,8 +1622,8 @@ static ValueDecl *getAutoDiffProjectTopLevelSubcontext(ASTContext &ctx,
static ValueDecl *getAutoDiffAllocateSubcontext(ASTContext &ctx,
Identifier id) {
return getBuiltinFunction(
id, {ctx.TheNativeObjectType, BuiltinIntegerType::getWordType(ctx)},
ctx.TheRawPointerType);
ctx, id, _thin, _generics(_unrestricted),
_parameters(_nativeObject, _metatype(_typeparam(0))), _rawPointer);
}

static ValueDecl *getPoundAssert(ASTContext &Context, Identifier Id) {
Expand Down Expand Up @@ -2966,13 +2967,13 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
case BuiltinValueKind::HopToActor:
return getHopToActor(Context, Id);

case BuiltinValueKind::AutoDiffCreateLinearMapContext:
case BuiltinValueKind::AutoDiffCreateLinearMapContextWithType:
return getAutoDiffCreateLinearMapContext(Context, Id);

case BuiltinValueKind::AutoDiffProjectTopLevelSubcontext:
return getAutoDiffProjectTopLevelSubcontext(Context, Id);

case BuiltinValueKind::AutoDiffAllocateSubcontext:
case BuiltinValueKind::AutoDiffAllocateSubcontextWithType:
return getAutoDiffAllocateSubcontext(Context, Id);
}

Expand Down
16 changes: 9 additions & 7 deletions lib/IRGen/GenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1307,9 +1307,10 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
return;
}

if (Builtin.ID == BuiltinValueKind::AutoDiffCreateLinearMapContext) {
auto topLevelSubcontextSize = args.claimNext();
out.add(emitAutoDiffCreateLinearMapContext(IGF, topLevelSubcontextSize)
if (Builtin.ID == BuiltinValueKind::AutoDiffCreateLinearMapContextWithType) {
auto topLevelSubcontextMetaType = args.claimNext();
out.add(emitAutoDiffCreateLinearMapContextWithType(
IGF, topLevelSubcontextMetaType)
.getAddress());
return;
}
Expand All @@ -1322,12 +1323,13 @@ void irgen::emitBuiltinCall(IRGenFunction &IGF, const BuiltinInfo &Builtin,
return;
}

if (Builtin.ID == BuiltinValueKind::AutoDiffAllocateSubcontext) {
if (Builtin.ID == BuiltinValueKind::AutoDiffAllocateSubcontextWithType) {
Address allocatorAddr(args.claimNext(), IGF.IGM.RefCountedStructTy,
IGF.IGM.getPointerAlignment());
auto size = args.claimNext();
out.add(
emitAutoDiffAllocateSubcontext(IGF, allocatorAddr, size).getAddress());
auto subcontextMetatype = args.claimNext();
out.add(emitAutoDiffAllocateSubcontextWithType(IGF, allocatorAddr,
subcontextMetatype)
.getAddress());
return;
}

Expand Down
20 changes: 12 additions & 8 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5479,11 +5479,13 @@ IRGenFunction::getFunctionPointerForResumeIntrinsic(llvm::Value *resume) {
return fnPtr;
}

Address irgen::emitAutoDiffCreateLinearMapContext(
IRGenFunction &IGF, llvm::Value *topLevelSubcontextSize) {
Address irgen::emitAutoDiffCreateLinearMapContextWithType(
IRGenFunction &IGF, llvm::Value *topLevelSubcontextMetatype) {
topLevelSubcontextMetatype = IGF.Builder.CreateBitCast(
topLevelSubcontextMetatype, IGF.IGM.TypeMetadataPtrTy);
auto *call = IGF.Builder.CreateCall(
IGF.IGM.getAutoDiffCreateLinearMapContextFunctionPointer(),
{topLevelSubcontextSize});
IGF.IGM.getAutoDiffCreateLinearMapContextWithTypeFunctionPointer(),
{topLevelSubcontextMetatype});
call->setDoesNotThrow();
call->setCallingConv(IGF.IGM.SwiftCC);
return Address(call, IGF.IGM.RefCountedStructTy,
Expand All @@ -5500,11 +5502,13 @@ Address irgen::emitAutoDiffProjectTopLevelSubcontext(
return Address(call, IGF.IGM.Int8Ty, IGF.IGM.getPointerAlignment());
}

Address irgen::emitAutoDiffAllocateSubcontext(
IRGenFunction &IGF, Address context, llvm::Value *size) {
Address irgen::emitAutoDiffAllocateSubcontextWithType(
IRGenFunction &IGF, Address context, llvm::Value *subcontextMetatype) {
subcontextMetatype =
IGF.Builder.CreateBitCast(subcontextMetatype, IGF.IGM.TypeMetadataPtrTy);
auto *call = IGF.Builder.CreateCall(
IGF.IGM.getAutoDiffAllocateSubcontextFunctionPointer(),
{context.getAddress(), size});
IGF.IGM.getAutoDiffAllocateSubcontextWithTypeFunctionPointer(),
{context.getAddress(), subcontextMetatype});
call->setDoesNotThrow();
call->setCallingConv(IGF.IGM.SwiftCC);
return Address(call, IGF.IGM.Int8Ty, IGF.IGM.getPointerAlignment());
Expand Down
11 changes: 7 additions & 4 deletions lib/IRGen/GenCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,15 @@ namespace irgen {
CanSILFunctionType fnType, Explosion &result,
Explosion &error);

Address emitAutoDiffCreateLinearMapContext(
IRGenFunction &IGF, llvm::Value *topLevelSubcontextSize);
Address emitAutoDiffCreateLinearMapContextWithType(
IRGenFunction &IGF, llvm::Value *topLevelSubcontextMetatype);

Address emitAutoDiffProjectTopLevelSubcontext(
IRGenFunction &IGF, Address context);
Address emitAutoDiffAllocateSubcontext(
IRGenFunction &IGF, Address context, llvm::Value *size);

Address
emitAutoDiffAllocateSubcontextWithType(IRGenFunction &IGF, Address context,
llvm::Value *subcontextMetatype);

FunctionPointer getFunctionPointerForDispatchCall(IRGenModule &IGM,
const FunctionPointer &fn);
Expand Down
5 changes: 2 additions & 3 deletions lib/SIL/IR/OperandOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, InitializeDistributedRemoteActor)
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse,
InitializeNonDefaultDistributedActor)

BUILTIN_OPERAND_OWNERSHIP(PointerEscape, AutoDiffAllocateSubcontext)
BUILTIN_OPERAND_OWNERSHIP(PointerEscape, AutoDiffAllocateSubcontextWithType)
BUILTIN_OPERAND_OWNERSHIP(PointerEscape, AutoDiffProjectTopLevelSubcontext)

// FIXME: ConvertTaskToJob is documented as taking NativePointer. It's operand's
Expand All @@ -955,8 +955,7 @@ BUILTIN_OPERAND_OWNERSHIP(BitwiseEscape, BuildComplexEqualitySerialExecutorRef)
BUILTIN_OPERAND_OWNERSHIP(BitwiseEscape, BuildDefaultActorExecutorRef)
BUILTIN_OPERAND_OWNERSHIP(BitwiseEscape, BuildMainActorExecutorRef)

BUILTIN_OPERAND_OWNERSHIP(TrivialUse, AutoDiffCreateLinearMapContext)

BUILTIN_OPERAND_OWNERSHIP(TrivialUse, AutoDiffCreateLinearMapContextWithType)
#undef BUILTIN_OPERAND_OWNERSHIP

#define SHOULD_NEVER_VISIT_BUILTIN(ID) \
Expand Down
4 changes: 2 additions & 2 deletions lib/SIL/IR/ValueOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,9 +571,9 @@ CONSTANT_OWNERSHIP_BUILTIN(None, InitializeDefaultActor)
CONSTANT_OWNERSHIP_BUILTIN(None, DestroyDefaultActor)
CONSTANT_OWNERSHIP_BUILTIN(None, InitializeDistributedRemoteActor)
CONSTANT_OWNERSHIP_BUILTIN(None, InitializeNonDefaultDistributedActor)
CONSTANT_OWNERSHIP_BUILTIN(Owned, AutoDiffCreateLinearMapContext)
CONSTANT_OWNERSHIP_BUILTIN(Owned, AutoDiffCreateLinearMapContextWithType)
CONSTANT_OWNERSHIP_BUILTIN(None, AutoDiffProjectTopLevelSubcontext)
CONSTANT_OWNERSHIP_BUILTIN(None, AutoDiffAllocateSubcontext)
CONSTANT_OWNERSHIP_BUILTIN(None, AutoDiffAllocateSubcontextWithType)
CONSTANT_OWNERSHIP_BUILTIN(None, GetCurrentExecutor)
CONSTANT_OWNERSHIP_BUILTIN(None, ResumeNonThrowingContinuationReturning)
CONSTANT_OWNERSHIP_BUILTIN(None, ResumeThrowingContinuationReturning)
Expand Down
4 changes: 2 additions & 2 deletions lib/SIL/Utils/MemAccessUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2567,8 +2567,8 @@ static void visitBuiltinAddress(BuiltinInst *builtin,
case BuiltinValueKind::CancelAsyncTask:
case BuiltinValueKind::CreateAsyncTask:
case BuiltinValueKind::CreateAsyncTaskInGroup:
case BuiltinValueKind::AutoDiffCreateLinearMapContext:
case BuiltinValueKind::AutoDiffAllocateSubcontext:
case BuiltinValueKind::AutoDiffCreateLinearMapContextWithType:
case BuiltinValueKind::AutoDiffAllocateSubcontextWithType:
case BuiltinValueKind::InitializeDefaultActor:
case BuiltinValueKind::InitializeDistributedRemoteActor:
case BuiltinValueKind::InitializeNonDefaultDistributedActor:
Expand Down
16 changes: 7 additions & 9 deletions lib/SILGen/SILGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1708,16 +1708,15 @@ static ManagedValue emitBuiltinHopToActor(SILGenFunction &SGF, SILLocation loc,
return ManagedValue::forObjectRValueWithoutOwnership(SGF.emitEmptyTuple(loc));
}

static ManagedValue emitBuiltinAutoDiffCreateLinearMapContext(
static ManagedValue emitBuiltinAutoDiffCreateLinearMapContextWithType(
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
ArrayRef<ManagedValue> args, SGFContext C) {
ASTContext &ctx = SGF.getASTContext();
auto *builtinApply = SGF.B.createBuiltin(
loc,
ctx.getIdentifier(
getBuiltinName(BuiltinValueKind::AutoDiffCreateLinearMapContext)),
SILType::getNativeObjectType(ctx),
subs,
ctx.getIdentifier(getBuiltinName(
BuiltinValueKind::AutoDiffCreateLinearMapContextWithType)),
SILType::getNativeObjectType(ctx), subs,
/*args*/ {args[0].getValue()});
return SGF.emitManagedRValueWithCleanup(builtinApply);
}
Expand All @@ -1736,16 +1735,15 @@ static ManagedValue emitBuiltinAutoDiffProjectTopLevelSubcontext(
return ManagedValue::forObjectRValueWithoutOwnership(builtinApply);
}

static ManagedValue emitBuiltinAutoDiffAllocateSubcontext(
static ManagedValue emitBuiltinAutoDiffAllocateSubcontextWithType(
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
ArrayRef<ManagedValue> args, SGFContext C) {
ASTContext &ctx = SGF.getASTContext();
auto *builtinApply = SGF.B.createBuiltin(
loc,
ctx.getIdentifier(
getBuiltinName(BuiltinValueKind::AutoDiffAllocateSubcontext)),
SILType::getRawPointerType(ctx),
subs,
getBuiltinName(BuiltinValueKind::AutoDiffAllocateSubcontextWithType)),
SILType::getRawPointerType(ctx), subs,
/*args*/ {args[0].borrow(SGF, loc).getValue(), args[1].getValue()});
return ManagedValue::forObjectRValueWithoutOwnership(builtinApply);
}
Expand Down
41 changes: 28 additions & 13 deletions lib/SILOptimizer/Differentiation/VJPCloner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#define DEBUG_TYPE "differentiation"

#include "swift/AST/Types.h"

#include "swift/SILOptimizer/Differentiation/VJPCloner.h"
#include "swift/SILOptimizer/Analysis/DifferentiableActivityAnalysis.h"
#include "swift/SILOptimizer/Differentiation/ADContext.h"
Expand Down Expand Up @@ -118,15 +120,21 @@ class VJPCloner::Implementation final
auto pullbackTupleType =
remapASTType(pullbackInfo.getLinearMapTupleType(returnBB)->getCanonicalType());
Builder.setInsertionPoint(vjp->getEntryBlock());
auto topLevelSubcontextSize = emitMemoryLayoutSize(
Builder, original->getLocation(), pullbackTupleType);

auto pbTupleMetatypeType =
CanMetatypeType::get(pullbackTupleType, MetatypeRepresentation::Thick);
auto pbTupleMetatypeSILType =
SILType::getPrimitiveObjectType(pbTupleMetatypeType);
auto pbTupleMetatype =
Builder.createMetatype(original->getLocation(), pbTupleMetatypeSILType);

// Create an context.
pullbackContextValue = Builder.createBuiltin(
original->getLocation(),
getASTContext().getIdentifier(
getBuiltinName(BuiltinValueKind::AutoDiffCreateLinearMapContext)),
SILType::getNativeObjectType(getASTContext()),
SubstitutionMap(), {topLevelSubcontextSize});
getASTContext().getIdentifier(getBuiltinName(
BuiltinValueKind::AutoDiffCreateLinearMapContextWithType)),
SILType::getNativeObjectType(getASTContext()), SubstitutionMap(),
{pbTupleMetatype});
borrowedPullbackContextValue = Builder.createBeginBorrow(
original->getLocation(), pullbackContextValue);
LLVM_DEBUG(getADDebugStream()
Expand All @@ -148,8 +156,8 @@ class VJPCloner::Implementation final
return builtinAutoDiffAllocateSubcontextGenericSignature;
auto &ctx = getASTContext();
auto *decl = cast<FuncDecl>(getBuiltinValueDecl(
ctx, ctx.getIdentifier(
getBuiltinName(BuiltinValueKind::AutoDiffAllocateSubcontext))));
ctx, ctx.getIdentifier(getBuiltinName(
BuiltinValueKind::AutoDiffAllocateSubcontextWithType))));
builtinAutoDiffAllocateSubcontextGenericSignature =
decl->getGenericSignature();
assert(builtinAutoDiffAllocateSubcontextGenericSignature);
Expand Down Expand Up @@ -1067,14 +1075,21 @@ EnumInst *VJPCloner::Implementation::buildPredecessorEnumValue(
assert(enumEltType == rawPtrType);
auto pbTupleType =
remapASTType(pullbackInfo.getLinearMapTupleType(predBB)->getCanonicalType());
SILValue pbTupleSize =
emitMemoryLayoutSize(Builder, loc, pbTupleType);

auto pbTupleMetatypeType =
CanMetatypeType::get(pbTupleType, MetatypeRepresentation::Thick);
auto pbTupleMetatypeSILType =
SILType::getPrimitiveObjectType(pbTupleMetatypeType);
auto pbTupleMetatype =
Builder.createMetatype(original->getLocation(), pbTupleMetatypeSILType);

auto rawBufferValue = builder.createBuiltin(
loc,
getASTContext().getIdentifier(
getBuiltinName(BuiltinValueKind::AutoDiffAllocateSubcontext)),
getASTContext().getIdentifier(getBuiltinName(
BuiltinValueKind::AutoDiffAllocateSubcontextWithType)),
rawPtrType, SubstitutionMap(),
{borrowedPullbackContextValue, pbTupleSize});
{borrowedPullbackContextValue, pbTupleMetatype});

auto typedBufferValue =
builder.createPointerToAddress(
loc, rawBufferValue, pbTupleVal->getType().getAddressType(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ static bool isBarrier(SILInstruction *inst) {
case BuiltinValueKind::COWBufferForReading:
case BuiltinValueKind::GetCurrentAsyncTask:
case BuiltinValueKind::GetCurrentExecutor:
case BuiltinValueKind::AutoDiffCreateLinearMapContext:
case BuiltinValueKind::AutoDiffCreateLinearMapContextWithType:
case BuiltinValueKind::EndAsyncLet:
case BuiltinValueKind::EndAsyncLetLifetime:
case BuiltinValueKind::CreateTaskGroup:
Expand Down Expand Up @@ -199,7 +199,7 @@ static bool isBarrier(SILInstruction *inst) {
case BuiltinValueKind::ResumeThrowingContinuationReturning:
case BuiltinValueKind::ResumeThrowingContinuationThrowing:
case BuiltinValueKind::AutoDiffProjectTopLevelSubcontext:
case BuiltinValueKind::AutoDiffAllocateSubcontext:
case BuiltinValueKind::AutoDiffAllocateSubcontextWithType:
case BuiltinValueKind::AddressOfBorrowOpaque:
case BuiltinValueKind::UnprotectedAddressOfBorrowOpaque:
return true;
Expand Down
Loading