Skip to content
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

fix memleak #69

Merged
merged 1 commit into from
Nov 25, 2020
Merged

fix memleak #69

merged 1 commit into from
Nov 25, 2020

Conversation

ivanallen
Copy link

Fix memory leak.

Copy link
Contributor

@ljn917 ljn917 left a comment

Choose a reason for hiding this comment

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

Class defer seems to be duplicating the function of std::unique_ptr. I don't know how @serizba feels about it.

include/cppflow/tensor.h Show resolved Hide resolved
include/cppflow/tensor.h Show resolved Hide resolved
@ivanallen
Copy link
Author

Class defer seems to be duplicating the function of std::unique_ptr. I don't know how @serizba feels about it.

Emm... It's not really the same thing. defer is more general.

@ljn917
Copy link
Contributor

ljn917 commented Nov 7, 2020 via email

include/cppflow/tensor.h Show resolved Hide resolved
include/cppflow/tensor.h Show resolved Hide resolved
include/cppflow/model.h Show resolved Hide resolved
@serizba
Copy link
Owner

serizba commented Nov 12, 2020

@ivanallen @ljn917

I do not have a strong opinion on the topic either. I will accept the request if you both agree on it. If you think that just using unique_ptr may work, that would be perhaps cleaner.

@ljn917
Copy link
Contributor

ljn917 commented Nov 22, 2020

@ivanallen I am sorry that I didn't get much time to test this, my apologies. The other span PR may take some time too...

@serizba I think this is good to go. Although gcc's leak sanitizer still shows leaks in libcuda.so, I think it is false positive. cuda-memcheck --leak-check full ./example did not show any leak with the load_model example. I attached the leaks reported by gcc's leak sanitizer at the end to avoid further confusion.

If you still prefer std::unique_ptr over defer. We can define std::vecotr<std::unique_ptr<TF_Tenosr, decltype(&TF_DeleteTensor)>> inp_val_ptr;, then emplace_back each elements of inp_val into inp_val_ptr as @ivanallen suggested. Again, both solutions are acceptable in my opinion.

=================================================================
==685408==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 896 byte(s) in 16 object(s) allocated from:
    #0 0x7f60ce44c587 in __interceptor_calloc (/lib64/libasan.so.6+0xab587)
    #1 0x7f60a8f0a128  (/lib64/libcuda.so.1+0x1c8128)

Indirect leak of 1536 byte(s) in 16 object(s) allocated from:
    #0 0x7f60ce44c587 in __interceptor_calloc (/lib64/libasan.so.6+0xab587)
    #1 0x7f60a8f0a14a  (/lib64/libcuda.so.1+0x1c814a)

Indirect leak of 345 byte(s) in 16 object(s) allocated from:
    #0 0x7f60ce44c3cf in __interceptor_malloc (/lib64/libasan.so.6+0xab3cf)
    #1 0x7f60a90b99dd  (/lib64/libcuda.so.1+0x3779dd)

Indirect leak of 300 byte(s) in 15 object(s) allocated from:
    #0 0x7f60ce44c3cf in __interceptor_malloc (/lib64/libasan.so.6+0xab3cf)
    #1 0x7f60a901d654  (/lib64/libcuda.so.1+0x2db654)

Indirect leak of 83 byte(s) in 4 object(s) allocated from:
    #0 0x7f60ce44c3cf in __interceptor_malloc (/lib64/libasan.so.6+0xab3cf)
    #1 0x7f60a901d984  (/lib64/libcuda.so.1+0x2db984)
=================================================================

@ivanallen
Copy link
Author

Thanks, @ljn917 @serizba!

I list the difference between defer and unique_ptr. Both solutions are okay for me, but we need to reach a consensus.

  • use defer
    std::vector<TF_Tensor*> inp_val(inputs.size());

+   defer d([&inp_val]{
+       for (auto* tf_tensor : inp_val) TF_DeleteTensor(tf_tensor);
+   });
  • use unique_ptr
+   std::vecotr<std::unique_ptr<TF_Tenosr, decltype(&TF_DeleteTensor)>> inp_val_ptr;
    std::vector<TF_Tensor*> inp_val(inputs.size());

    //...
    for (...) {
       // ...
       auto inp_tensor = TFE_TensorHandleResolve(std::get<1>(inputs[i]).tfe_handle.get(), context::get_status());
+      inp_val_ptr.emplace_back(inp_tensor, TF_DeleteTensor);
+      inp_val[i] = inp_tensor; // copy raw pointer to anther vector
    }

   //...

@ljn917
Copy link
Contributor

ljn917 commented Nov 23, 2020

I think @serizba should be the person to make the final decision here :)

@serizba
Copy link
Owner

serizba commented Nov 24, 2020

Thanks for showing both options @ivanallen,

Now I think that perhaps using defer is cleaner. It adds a nice way of cleaning an object, and the class may be convenient in other future occasions too. Having a duplicate vector just to store the deleters seems a bit confusing.

@serizba serizba mentioned this pull request Nov 24, 2020
Copy link
Author

@ivanallen ivanallen left a comment

Choose a reason for hiding this comment

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

New problems will be resolved in a new pull request.

@serizba serizba merged commit 2d6f941 into serizba:cppflow2 Nov 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants