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

Conversation

jkshtj
Copy link
Contributor

@jkshtj jkshtj commented Aug 15, 2023

When the differentiating a function containing loops, we allocate a linear map context object on the heap. This context object may store non-trivial objects, such as closures,that need to be freed explicitly, at program exit. This PR fixes the autodiff linear map context allocation builtins to destroy and deallocate any such objects.

Fixes #67323

@jkshtj jkshtj changed the title Fixes memory leaks in autodiff linear map context allocation builtins [Autodiff] Fixes memory leaks in autodiff linear map context allocation builtins Aug 15, 2023
@jkshtj
Copy link
Contributor Author

jkshtj commented Aug 15, 2023

@asl @BradLarson Could I get a review on this?

@BradLarson
Copy link
Contributor

@swift-ci Please test.

@@ -2273,12 +2273,12 @@ FUNCTION(TaskGroupDestroy,
ATTRS(NoUnwind),
EFFECT(Concurrency))

// AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContext(size_t);
// AutoDiffLinearMapContext *swift_autoDiffCreateLinearMapContext(const Metadata *);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, there will be no link errors for things compiled with old compiler and linked with new runtime and vice versa?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it slipped my mind and I meant to ask this. I wasn't able to figure out how to make this a link time error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The easiest way: rename functions :) Hard way: invent some backward compatibility scheme. @rxwei any suggestions? I think we do not care about ABI stability for now, isn't it?

Copy link
Contributor Author

@jkshtj jkshtj Aug 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't made a decision on this in the latest revision. Waiting on @rxwei's input. If breaking ABI is going to be a concern we could deprecate existing builtins instead of completely removing them.

Copy link
Contributor

@rxwei rxwei Aug 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be safe, we should add a new runtime function without modifying the signature of the old one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we deprecate the old ones as well? They do lead to memory leaks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by deprecate? We just don't call it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, this is not an API. There is not a real way to deprecate it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkshtj I believe what @rxwei means is as follows:

  • Add new functions, say swift_autoDiffCreateLinearMapContext2 etc. with the desired functionality
  • Keep old functions as-is

As a result: old code would still be able to run with the new runtime. The behavior will be the same, well, it will leak. The new code will call that new runtime functions and will be leak-less.

@jkshtj
Copy link
Contributor Author

jkshtj commented Aug 16, 2023

@asl as per offline discussion w/ @BradLarson, since we're already aware of the memory scaling issues with allocating loop context objects directly on the heap I have created a new revision to reintegrate BumpPtrAllocator in AutodiffLinearMapContext while still preventing memory leaks.

@asl
Copy link
Contributor

asl commented Aug 16, 2023

since we're already aware of the #34886 with allocating loop context objects directly on the heap

@jkshtj Well, this was quite different case, as the chain of boxes were explicitly created ;) Anyway, as we already discussed, as soon as you had the initial implementation on top of the boxes, it was possible to change the underlying implementation to something more lightweight, as we certainly did not want to reference count the pullback tuples.

@asl
Copy link
Contributor

asl commented Aug 16, 2023

@swift-ci please test

jkshtj added 2 commits August 17, 2023 13:15
This commit builds on top of a previous commit that fixed memory leak
issues in the autodiff loop context allocation builtins. The previous
commit allocated loop contexts in a box, which is known to have memory
scaling issues. This commit modifies AutoDiffLinearMapContext to perform
memory allocation using the BumpPtrAllocator, like it used to, while
introducing new bookkeeping logic that enables AutoDiffLinearMapContext
to prevent memory leaks, unlike before.
@BradLarson
Copy link
Contributor

@swift-ci Please test

@jkshtj jkshtj changed the title [Autodiff] Fixes memory leaks in autodiff linear map context allocation builtins [AutoDiff] Fixes memory leaks in autodiff linear map context allocation builtins Aug 18, 2023
@xedin xedin removed their request for review August 23, 2023 16:30
@asl
Copy link
Contributor

asl commented Aug 23, 2023

@swift-ci please test windows

@@ -994,6 +994,12 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffProjectTopLevelSubcontext, "autoDiffP
// autoDiffAllocateSubcontext: (Builtin.NativeObject, Builtin.Word) -> Builtin.RawPointer
BUILTIN_MISC_OPERATION_WITH_SILGEN(AutoDiffAllocateSubcontext, "autoDiffAllocateSubcontext", "", Special)

// autoDiffCreateLinearMapContext2: (T.Type) -> Builtin.NativeObject
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some bike-shedding: maybe rename these to autoDiffCreateLinearMapContextWithType etc.?

@@ -5500,8 +5501,9 @@ Address irgen::emitAutoDiffProjectTopLevelSubcontext(
return Address(call, IGF.IGM.Int8Ty, IGF.IGM.getPointerAlignment());
}

Address irgen::emitAutoDiffAllocateSubcontext(
IRGenFunction &IGF, Address context, llvm::Value *size) {
Address irgen::emitAutoDiffAllocateSubcontext(IRGenFunction &IGF,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to keep these functions after all? We are not going to call these builtins from the compiler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@@ -1625,6 +1625,20 @@ static ValueDecl *getAutoDiffAllocateSubcontext(ASTContext &ctx,
ctx.TheRawPointerType);
}

static ValueDecl *getAutoDiffCreateLinearMapContext2(ASTContext &ctx,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the functions above with old builtins are never called from the compiler, I'd steal their names for the helpers that call new builtins

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'll be better to keep the helpers symmetric with the names of the builtins. Otherwise autoDiffProjectTopLevelSubcontext will be the odd one out in different places.

@asl asl added the AutoDiff label Aug 23, 2023
…ld ones

This commit builds on top of a previous commit that fixed memory leak
issues in the autodiff loop context allocation builtins. The previous
commit changed the existing builtins. However, inorder to maintain ABI
compatibility and not break other consumers of autodiff, this commit
creates newly named builtins that don't leak memory and preserves the
older builtins.

As a result, now, code compiled with an older frontend and using a newer
stdlib will continue to work. But code compiled with a newer frontend
and using older stdlib will have undefined behavior.
@BradLarson
Copy link
Contributor

@swift-ci Please test

Copy link
Contributor

@asl asl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@asl asl merged commit d5a3e2e into swiftlang:main Aug 24, 2023
nate-chandler added a commit that referenced this pull request Aug 24, 2023
Resolve conflicts introduced in
#67944 as follows:

```
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 3c973b5884b..44cde707d17 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -2537,16 +2537,10 @@ FUNCTION(AutoDiffCreateLinearMapContextWithType,
          swift_autoDiffCreateLinearMapContextWithType, SwiftCC,
          DifferentiationAvailability,
          RETURNS(RefCountedPtrTy),
-<<<<<<< HEAD
-         ARGS(SizeTy),
+         ARGS(TypeMetadataPtrTy),
          ATTRS(NoUnwind),
          EFFECT(AutoDiff),
          MEMEFFECTS(ArgMemOnly))
-=======
-         ARGS(TypeMetadataPtrTy),
-         ATTRS(NoUnwind, ArgMemOnly),
-         EFFECT(AutoDiff))
->>>>>>> public-github/main

 // void *swift_autoDiffProjectTopLevelSubcontext(AutoDiffLinearMapContext *);
 FUNCTION(AutoDiffProjectTopLevelSubcontext,
@@ -2563,16 +2557,10 @@ FUNCTION(AutoDiffAllocateSubcontextWithType,
          swift_autoDiffAllocateSubcontextWithType, SwiftCC,
          DifferentiationAvailability,
          RETURNS(Int8PtrTy),
-<<<<<<< HEAD
-         ARGS(RefCountedPtrTy, SizeTy),
+         ARGS(RefCountedPtrTy, TypeMetadataPtrTy),
          ATTRS(NoUnwind),
          EFFECT(AutoDiff),
          MEMEFFECTS(ArgMemOnly))
-=======
-         ARGS(RefCountedPtrTy, TypeMetadataPtrTy),
-         ATTRS(NoUnwind, ArgMemOnly),
-         EFFECT(AutoDiff))
->>>>>>> public-github/main
```
@jkshtj jkshtj deleted the leaks branch March 13, 2024 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Autodiff] Memory leaks found under certain conditions.
4 participants