14
$\begingroup$

I am running Mathematica 13.2 on a Mac OS Monterey. I have a large code that manipulates graphs both in graph form and as adjacency matrices, computes some graph properties, and returns a list. It has been leaking memory and after some effort I was able to isolate the problem to the the built in function GraphAutomorphismGroup. Here is a simplified code that illustrates the problem.

I started a new notebook and executed the following:

In[8]:= Quit[];
In[1]:= $HistoryLength = 0;
In[2]:= Names[$Context <> "*"]
        MemoryInUse[]

Out[2]= {}

Out[3]= 81382952

In[4]:= Clear[leakyFunction];
        leakyFunction[vCount_Integer] := 
           GroupOrder[
                GraphAutomorphismGroup[
                    RandomGraph[{vCount, RandomInteger[{0, vCount(vCount-1)/2}]}]]];
In[6]:= Names[$Context <> "*"]
        MemoryInUse[]
Out[6]= {"leakyFunction", "vCount"}

Out[7]= 80525080

So far so good. Now I ran the function I just defined some number of times in a Do loop outputting memory used during intermediate steps.

    In[8]:= Do[If[Mod[n, 2000] == 0, Print["mem ", MemoryInUse[]];];
               leakyFunction[12], {n, 10000}]
    During evaluation of In[8]:= mem 84044168
    During evaluation of In[8]:= mem 86922688
    During evaluation of In[8]:= mem 89563816
    During evaluation of In[8]:= mem 92306328
    During evaluation of In[8]:= mem 95014752

You see memory in use steadily marching up. I checked to see if there are any lingering variables but there were none.

    In[9]:= MemoryInUse[]
            Names[$Context <> "*"]
    Out[9]= 94977216
    Out[10]= {"leakyFunction", "n", "vCount"}

Clearing system cache frees up only a fraction of the memory eaten up

    In[11]:= ClearSystemCache[]
             MemoryInUse[]
    Out[12]= 90687256

I even tried CleanSlate[] and for a good measure, ClearInOut[] even though I have set $HistoryLengh = 0; at the start. Neither of these helped

    In[13]:= Needs["Utilities`CleanSlate`"]
    In[8]:= CleanSlate[];
            ClearInOut[];
            MemoryInUse[]
    During evaluation of In[8]:=   (CleanSlate) Contexts purged: {Global`}
    During evaluation of In[8]:=   (CleanSlate) Approximate kernel memory recovered: 0 Kb
    Out[1]= 90889808

Finally, I tried clearing InString and MessageList even though again I had no good reason to think that memory is eaten up here

    In[2]:= Unprotect[InString, MessageList];
            Clear[InString, MessageList];
            Protect[InString, MessageList];
            MemoryInUse[]
    Out[5]= 90916984

Finally, removing every variable in the context did nothing to free up the space.

    In[6]:= Scan[Remove, Names[$Context <> "*"]]
            MemoryInUse[]
   Out[7]= 90941904

I am at a loss as to what to try. Nothing short of Quit[] seems able to free up the space eaten up. The offending function seems to be GraphAutomorphismGroup, removing the GroupOrder won't make the problem go away.

Could anyone explain to me why this is happening, and if there is any solution or workaround? Thanks in advance!

UPDATE

A Wolfram Mathematica staff member got back to me regarding my report and said that "there does appear to be a memory leak with GraphAutomorphism" and that "the developers don't have a workaround for this." I guess we will have to wait at least until the next version for the issue to be fixed.

$\endgroup$
14
  • 2
    $\begingroup$ @VictorK. I actually tried the other possibilities before narrowing it down to GraphAutomorphismGroup. I should have stated that, but you also independently was able to establish that the issue is with GraphAutomorphismGroup. I regards to using MemoryConstrained, it's not ideal for what I'm trying to do if it aborts. $\endgroup$
    – Kassa
    Jan 19, 2023 at 1:35
  • 2
    $\begingroup$ there seem to be two more graph functions that leak memory (see my update) - could you please add them to your report to Wolfram? $\endgroup$
    – Victor K.
    Jan 19, 2023 at 2:11
  • 2
    $\begingroup$ Ok, yes I will do a follow up to Wolfram with the two additional graph functions you found. P.S. I love your leakingQ function :) $\endgroup$
    – Kassa
    Jan 19, 2023 at 2:21
  • 1
    $\begingroup$ @TugrulTemel, FWIW, I can "Send To" without any problems on macOS Big Sur, Wolfram Desktop 13.2 $\endgroup$
    – Victor K.
    Jan 19, 2023 at 2:43
  • 2
    $\begingroup$ @TugrulTemel, sending open MMA notebook through "Send To" didn't get stuck, but the email never arrives even though MMA claims the notebook has been sent. $\endgroup$
    – Kassa
    Jan 19, 2023 at 4:54

1 Answer 1

12
$\begingroup$

Here is another possible way to eliminate the impact of history, etc. The following code aborts on my machine after printing to the console three times.

MemoryConstrained[
 Do[If[Mod[n, 2000] == 0, Print["mem ", MemoryInUse[]];];
  leakyFunction[12], {n, 10000}],
 10000000]

Update. It seems to be the GraphAuthomorphismGroup indeed:

g = RandomGraph[{12, RandomInteger[{0, 12 (12 - 1)/2}]}];

MemoryConstrained[
 Do[
  GraphAutomorphismGroup[g], {n, 40000}
  ],
 5000000]

gets aborted after a couple of seconds.

Update 2. To help Wolfram debug their graph functions for memory leaking, I created the following code, and I'm only half-joking :).

leakingQ[f_, args___] := 
 With[{before = MemoryInUse[]}, f[args]; MemoryInUse[] - before > 0]

name[f_Symbol] := f
name[fn_Function] := fn /. {Function[f_[___]] :> f}

leakingGraphFns[g_] := 
 Cases[Table[{name[f], 
    leakingQ[f, g]}, {f, {Graph, Graph3D, GraphAssortativity, 
     GraphAutomorphismGroup, GraphCenter, GraphComplement, 
     GraphDensity, GraphDiameter, GraphDifference[#, #] &, 
     GraphDisjointUnion[#, #] &, GraphDistance[#, 1, 20] &, 
     GraphDistanceMatrix, GraphEmbedding, GraphIntersection[#, #] &, 
     GraphJoin[#, #] &, GraphPeriphery, GraphPlot, GraphPlot3D, 
     GraphPower[#, 2] &, GraphProduct[#, #] &, GraphQ, GraphRadius, 
     GraphReciprocity, GraphSum[#, #] &, GraphTree, 
     GraphUnion[#, #] &}}], {x_, True} :> x]
    
Quiet@Union@Flatten@Table[leakingGraphFns[RandomGraph[{20, 100}]], 100]

(* {GraphAutomorphismGroup,GraphComplement,GraphDisjointUnion,
GraphPlot,GraphPower,GraphProduct,GraphTree} *)

It can also be turned into a regression test easily - just check that the expression above returns an empty list.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.