Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
6956 Discussions

Memory growing when using MKL DFT descriptor in a C++ class

nicpac22
Beginner
850 Views

Hi,

I've recently noticed an issue when using a MKL DFT_DESCRIPTOR_HANDLE in a C++ class where the memory usage continually increases as I create and dereference objects of the class.  I believe I may just be using the MKL DFT handle incorrectly but could use some advice on what I'm doing wrong.  The basic problem is that I have a need for a DFT handle within a C++ class and I have a vector of objects of the class.  I periodically resize the vector to 0, destructing all objects, then resize it to some new size, creating new objects.  When I check the intel memory manager usage between resizes, I can see it slowly increasing which leads me to believe I'm not appropriately freeing the memory, despite calling DftiFreeDescriptor in the class destructor.  For illustration purposes, I've created a contrived example using a simple dft wrapper class (attached).

I'm using ubuntu 13.10 32-bit on an intel core i5 M460 cpu.  I've tried compiling with composer xe 2013.3.163 and composer xe 2013_sp1.1.106 (MKL v11.1) and gotten the same result.  I am compiling with the following flags:

icpc -openmp -I/usr/include/i386-linux-gnu/ -I/usr/include/i386-linux-gnu/c++/4.8/ -xHost -I$MKLROOT/include -L$MKLROOT/lib/ia32 imkl_dft_test.cpp -o imkl_dft_test -lmkl_intel -lmkl_core -lmkl_intel_thread -lpthread -lm

Any advice would be greatly appreciated.

Thanks,

Nick

 

0 Kudos
4 Replies
nicpac22
Beginner
850 Views

Update: I realized I did not implement an explicit copy constructor in my previous example which may cause DFT handles to be dereferenced without being freed on resizing the vector.  After adding a copy constructor, however, I was still having an issue with growing memory.  What I found is that if I did both a create descriptor and a commit in the constructor, everything worked fine with no evidence of a leak as opposed to the previous implementation where it was possible to call 2 create descriptors in a row prior to calling commit.  This makes me think there is some amount of memory that gets allocated with DftiCreateDescriptor that does not get relinquished until DftiFreeDescriptor is called.  I was wondering if someone else can verify this.  I've attached 2 pieces of code, one which always commits a descriptor after creating it (so that free descriptor is always called) and another which allows descriptors to be created without committing, which can result in dereferencing the object without calling commit or free.

Is this behavior expected?  I know it is not normal to have a case where you would create a descriptor and not use it, but it still seems like this shouldn't leave memory behind.  I could understand if I was calling commit and not freeing, but for merely creating I wouldn't think there would be memory left behind.  For reference the attached file imkl_dft_test_1.cpp implements creation without commiting and imkl_dft_test_2.cpp calls a commit after each create.

0 Kudos
Ying_H_Intel
Employee
850 Views

Hi Nicpac22

Just quick update. We will investigate the code and get back to you if any updates.

And you may try mkl_free_buffers() as the mentioned in the article: http://software.intel.com/en-us/articles/memory-leak-when-using-intel-mkl

Best Regards,

Ying  

 

0 Kudos
Ying_H_Intel
Employee
850 Views

Hi Nicpac22, 

With the DFT handle, the basic rule is that the Create and free should be matched each other.  The DFT handle can't be changed/Reset by any external ways.

As i understand,

in test case 1, you have continuous two DftiCreate call , which have memory allocation

DftiCreateDescriptor ( (&_dft,DFTI_SINGLE,DFTI_COMPLEX,1,128); 

_status = DftiCreateDescriptor(&_dft,DFTI_SINGLE,DFTI_COMPLEX,1,dftSize);  // dftSize=65536. 

to rewrite the Handle. But only one  DftiFree.  Which cause memory leak. 

In test case 2,  The call model are 

DftiCreateDescriptor ( (&_dft,DFTI_SINGLE,DFTI_COMPLEX,1,128); 

_status = DftiFreeDescriptor(&_dft); 

_status = DftiCreateDescriptor(&_dft,DFTI_SINGLE,DFTI_COMPLEX,1,dftSize);  // dftSize=65536. 

 DftiFreeDescriptor(&_dft);

So the memory are released correctly.   ( the operation of commit was added or not is not a condition of free descriptor). 

Best Regards,

Ying 

 

0 Kudos
nicpac22
Beginner
850 Views

Hi Ying,

Thank you very much for the reply.  I thought at one point I had tried calling DftiFreeDescriptor on a handle which had been created but not committed and it resulted in a segfault, however when I just tried implementing your suggestion under IMKL v11.1 update 1, it worked fine with no error.  The segfault behavior I noticed was on an entirely different system at my office which was using an older version of IMKL, was a 64-bit AVX processor, and was running a different version of Linux, so perhaps whatever caused the issue has been fixed since then.  In any case, thank you for your help, I did not realize that memory was actually allocated by DftiCreateDescriptor as I thought it just initialized some parameters about the DFT and all memory allocation was performed by commit.  Now that I know that create allocates some memory I will make sure to always call free after each create.

Thanks,

Nick

0 Kudos
Reply