{"action":"created","issue":{"url":"https://api.github.com/repos/mfem/mfem/issues/64","repository_url":"https://api.github.com/repos/mfem/mfem","labels_url":"https://api.github.com/repos/mfem/mfem/issues/64/labels{/name}","comments_url":"https://api.github.com/repos/mfem/mfem/issues/64/comments","events_url":"https://api.github.com/repos/mfem/mfem/issues/64/events","html_url":"https://github.com/mfem/mfem/issues/64","id":157248235,"number":64,"title":"Memory leak in HypreLOBPCG","user":{"login":"martemyev","id":2182432,"avatar_url":"https://avatars.githubusercontent.com/u/2182432?v=3","gravatar_id":"","url":"https://api.github.com/users/martemyev","html_url":"https://github.com/martemyev","followers_url":"https://api.github.com/users/martemyev/followers","following_url":"https://api.github.com/users/martemyev/following{/other_user}","gists_url":"https://api.github.com/users/martemyev/gists{/gist_id}","starred_url":"https://api.github.com/users/martemyev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/martemyev/subscriptions","organizations_url":"https://api.github.com/users/martemyev/orgs","repos_url":"https://api.github.com/users/martemyev/repos","events_url":"https://api.github.com/users/martemyev/events{/privacy}","received_events_url":"https://api.github.com/users/martemyev/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-05-27T16:55:26Z","updated_at":"2016-05-27T17:18:10Z","closed_at":null,"body":"Hi All,\r\n\r\nI've recently come across a memory leak while using HypreLOBPCG, so I'm wondering if you'd like to look at it and check if it's fixable. Here is a minimal example showing the case, which is basically example 11 without comments and extra lines of code for mesh refinement and mesh initialization.\r\n```cxx\r\n// file lobpcg.cpp\r\n#include \"mfem.hpp\"\r\n#include <iostream>\r\nusing namespace std;\r\nusing namespace mfem;\r\n\r\nint main(int argc, char *argv[]) {\r\n   int num_procs, myid;\r\n   MPI_Init(&argc, &argv);\r\n   MPI_Comm_size(MPI_COMM_WORLD, &num_procs);\r\n   MPI_Comm_rank(MPI_COMM_WORLD, &myid);\r\n\r\n   int order = 1;\r\n   int nev = 5;\r\n\r\n   Mesh *mesh = new Mesh(10, 10, Element::QUADRILATERAL, 1);\r\n   int dim = mesh->Dimension();\r\n\r\n   ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);\r\n   delete mesh;\r\n\r\n   FiniteElementCollection *fec = new H1_FECollection(order, dim);\r\n   ParFiniteElementSpace *fespace = new ParFiniteElementSpace(pmesh, fec);\r\n   HYPRE_Int size = fespace->GlobalTrueVSize();\r\n   if (myid == 0)\r\n      cout << \"Number of unknowns: \" << size << endl;\r\n\r\n   ConstantCoefficient one(1.0);\r\n   Array<int> ess_bdr;\r\n   if (pmesh->bdr_attributes.Size()) {\r\n      ess_bdr.SetSize(pmesh->bdr_attributes.Max());\r\n      ess_bdr = 1;\r\n   }\r\n\r\n   ParBilinearForm *a = new ParBilinearForm(fespace);\r\n   a->AddDomainIntegrator(new DiffusionIntegrator(one));\r\n   if (pmesh->bdr_attributes.Size() == 0)\r\n      a->AddDomainIntegrator(new MassIntegrator(one));\r\n   a->Assemble();\r\n   a->EliminateEssentialBCDiag(ess_bdr, 1.0);\r\n   a->Finalize();\r\n\r\n   ParBilinearForm *m = new ParBilinearForm(fespace);\r\n   m->AddDomainIntegrator(new MassIntegrator(one));\r\n   m->Assemble();\r\n   // shift the eigenvalue corresponding to eliminated dofs to a large value\r\n   m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());\r\n   m->Finalize();\r\n\r\n   HypreParMatrix *A = a->ParallelAssemble();\r\n   HypreParMatrix *M = m->ParallelAssemble();\r\n\r\n   delete a;\r\n   delete m;\r\n\r\n   HypreBoomerAMG * amg = new HypreBoomerAMG(*A);\r\n   amg->SetPrintLevel(0);\r\n\r\n   HypreLOBPCG * lobpcg = new HypreLOBPCG(MPI_COMM_WORLD);\r\n   lobpcg->SetNumModes(nev);\r\n   lobpcg->SetPreconditioner(*amg);\r\n   lobpcg->SetMaxIter(100);\r\n   lobpcg->SetTol(1e-8);\r\n   lobpcg->SetPrecondUsageMode(1);\r\n   lobpcg->SetPrintLevel(1);\r\n   lobpcg->SetMassMatrix(*M);\r\n   lobpcg->SetOperator(*A);\r\n\r\n   Array<double> eigenvalues;\r\n   lobpcg->Solve();\r\n   lobpcg->GetEigenvalues(eigenvalues);\r\n   ParGridFunction x(fespace);\r\n\r\n   delete lobpcg;\r\n   delete amg;\r\n   delete M;\r\n   delete A;\r\n\r\n   delete fespace;\r\n   delete fec;\r\n   delete pmesh;\r\n\r\n   MPI_Finalize();\r\n   return 0;\r\n}\r\n```\r\n\r\nWhen I run it with 1 process and check memory leaks with valgrind there are lots of leaks caused by MPI implementation, which I ignore, and also there is the one from HypreLOBPCG:\r\n```\r\n==21789== 968 bytes in 1 blocks are definitely lost in loss record 246 of 266\r\n==21789==    at 0x4C29DB4: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)\r\n==21789==    by 0x677F80: hypre_CAlloc (in /u/artemyev/projects/mfem/examples/lobpcg)\r\n==21789==    by 0x680AA3: hypre_SeqVectorInitialize (in /u/artemyev/projects/mfem/examples/lobpcg)\r\n==21789==    by 0x68FC11: hypre_ParVectorInitialize (in /u/artemyev/projects/mfem/examples/lobpcg)\r\n==21789==    by 0x4DDDEE: mfem::HypreParVector::HypreParVector(ompi_communicator_t*, int, double*, int*) (hypre.cpp:73)\r\n==21789==    by 0x4E97A9: mfem::HypreLOBPCG::SetOperator(mfem::Operator&) (hypre.cpp:3070)\r\n==21789==    by 0x4C15C1: main (lobpcg.cpp:66)\r\n```\r\n\r\nSo I'm wondering if you want to check whether there is indeed a leak.\r\n\r\nThanks,\r\nMikhail"},"comment":{"url":"https://api.github.com/repos/mfem/mfem/issues/comments/222203628","html_url":"https://github.com/mfem/mfem/issues/64#issuecomment-222203628","issue_url":"https://api.github.com/repos/mfem/mfem/issues/64","id":222203628,"user":{"login":"mlstowell","id":6109571,"avatar_url":"https://avatars.githubusercontent.com/u/6109571?v=3","gravatar_id":"","url":"https://api.github.com/users/mlstowell","html_url":"https://github.com/mlstowell","followers_url":"https://api.github.com/users/mlstowell/followers","following_url":"https://api.github.com/users/mlstowell/following{/other_user}","gists_url":"https://api.github.com/users/mlstowell/gists{/gist_id}","starred_url":"https://api.github.com/users/mlstowell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlstowell/subscriptions","organizations_url":"https://api.github.com/users/mlstowell/orgs","repos_url":"https://api.github.com/users/mlstowell/repos","events_url":"https://api.github.com/users/mlstowell/events{/privacy}","received_events_url":"https://api.github.com/users/mlstowell/received_events","type":"User","site_admin":false},"created_at":"2016-05-27T17:18:10Z","updated_at":"2016-05-27T17:18:10Z","body":"Hello, Mikhail,\r\n\r\nThanks for catching this.  The vector being leaked is not supposed to have a data array.  It's just a dummy vector used to define the length and parallel partitioning of the eigenvectors.  Unfortunately it's created incorrectly so Hypre allocates a data array which is later replaced and lost.\r\n\r\nThe fix is to allocate this dummy vector with a fake data array.  I'll make the necessary changes at our end but you can fix your code quite easily.  On or near line 3075 of linalg/hypre.cpp you should find the following:\r\nx = new HypreParVector(comm,glbSize,NULL,part);\r\n\r\nChange this to:\r\ndouble x_dummy = 0.0;\r\nx = new HypreParVector(comm,glbSize,&x_dummy,part);\r\n\r\nThis will trick Hypre into thinking that a data array is not needed.\r\n\r\nThanks again,\r\nMark\r\n"}}
{"actor":{"display_login":"mlstowell"}}