Message Boards Message Boards

3
|
6491 Views
|
8 Replies
|
17 Total Likes
View groups...
Share
Share this post:

Memory usage/Leak Graphics 3D and tubes

I have generated around 60000 streamlines representing human brain white matter.

I plot a subselection of them using Graphics3D and the Line or Tube graphics primitives.

Plotting 10000 lines goes very smoothly. It takes a few seconds to pop up on the screen but once the graphics is there, its very responsive (rotating etc.).

enter image description here

Once the graphics is loaded in the notebook it uses around 500MB of memory on the mathematical front end.

enter image description here

With plotting tubes, I have much more difficulties. At first, it crashed the frontend while only rendering 100 tubes (vs 10000 lines). I noticed the crash was caused by memory depletion since the front end used all my available memory. By reducing the vertices used to render the tubes in Graphics 3D from {40,2} to {5,1} this issue was solved.

I can now render 1000 tubes without Mathematica crashing. Although the frontend still uses over2GB of memory. Which is almost 5x more than needed for rendering 10000 Lines.

enter image description here

enter image description here

However, the image is not really responsive. Each time I try to rotate it takes 1-2s for it to become responsive and after a couple of rotations, the Mathematica frontend quits responding altogether.

After monitoring my memory usage by Mathematica I noticed that each time I start to rotate the graphics and after I release my mouse button (which activates the antialiasing) the memory used by mathematical jumps up by 1-2GB after each mouse click. After 4 rotations my memory was almost full.

enter image description here

after I remove the Graphics from the notebook the memory is freed up again.

enter image description here

I'm running Mathematica 12.3 on windows 10 using an NVIDEA Quadro M1200

Is there anyone who can reproduce this behavior or can explain why this is happening? I have attached the notebook with the data and the code that shows this behavior.

Attachments:
POSTED BY: Martijn Froeling
8 Replies

Dear @Martijn, I agree with Ahmed -- it would be lovely to see your work published on Community -- looks very impressive.

POSTED BY: Vitaliy Kaurov

Hi Ahmed and Vitaly,

I made a post of the context of this problem here.

POSTED BY: Martijn Froeling

Very nice work Martijn. I am interested (and I am sure many other members) to see the final work and code. Would be nice to share it with us once finished.

POSTED BY: Ahmed Elbanna
Posted 3 years ago

Other than the CapForm and JoinForm setting which makes memory consumption difference, the "TubePoints" setting {5, 1} is an invalid specification which causes data cache invalidation all the time. Use {5, 2} instead will improve the rotation performance greatly.

POSTED BY: Yuzhu Lu

Thanks, I will give it a try!

POSTED BY: Martijn Froeling

Yes!! that solved all the issues I had. And somehow it also fixed the issue with the wrong colors with grouped primitives.

So in summary, I now us the following:

Graphics3D[{CapForm["Square"] ,JoinForm["Miter"] ,Tube[...], Method -> {"TubePoints" -> {6, 2}}]

With the grouped primitives it allows for very smooth images and image manipulation even up to 5000 tracts and tubes simultaneously.

Here are some nice images as a thank you.

enter image description here enter image description here enter image description here

POSTED BY: Martijn Froeling

Thank you Martijn for reporting this. It has been passed to Wolfram teams for evaluation.

POSTED BY: Moderation Team

Thanks!

I have looked a bit further to understand what is going on. I think one of the major memory use was for the default JoinForm["Round"] which uses a sphere to render the joints. By using CapForm["Square"] and JoinForm["Miter"] the memory usage dropped considerably.

Furthermore, the Graphics Primitives can be generated in two ways:

  1. where each line/tube is a individual primitive
  2. All lines/tubes are wrapped in one primitive

    tt = RandomSample[trc, 250];
    cc = MakeColor /@ tt;
    (*tubes*)
    tt1 = {CapForm["Square"], JoinForm["Miter"], 
       MapThread[Tube[#1, .5, VertexColors -> #2] &, {tt, cc}, 1]};
    tt2 = {CapForm["Square"], JoinForm["Miter"], 
       Tube[tt, .5, VertexColors -> cc]};
    (*lines*)
    ll1 = {CapForm["Square"], JoinForm["Miter"], 
       MapThread[Line[#1, VertexColors -> #2] &, {tt, cc}, 1]};
    ll2 = {CapForm["Square"], JoinForm["Miter"], 
       Line[tt, VertexColors -> cc]};
    

Whit this it seem that the Tube rendering is much more responsive so I could test the following.

vp = {1.3, -2.4, 2};
va = 15. Degree;
vv = {0, 0, 1};
opts = Sequence[{Method -> {"TubePoints" -> {6, 1}}, 
    Lighting -> light, ImageSize -> 400, SphericalRegion -> True,
    ViewPoint -> Dynamic[vp], ViewAngle -> Dynamic[va], 
    ViewVertical -> Dynamic[vv], Boxed -> False, 
    Background -> Lighter@Gray,
    LabelStyle -> Directive[{Bold, 16, White}]}];

Grid@{{Graphics3D[ll1, opts, PlotLabel -> "Individual"], 
    Graphics3D[ll2, opts, PlotLabel -> "Group"]},
   {Graphics3D[tt1, opts, PlotLabel -> "Individual"], 
    Graphics3D[tt2, opts, PlotLabel -> "Group"]}}

Which gives this figure

enter image description here

However, as is indicated by the Black arrows, the coloring of the grouped primitives sometimes fails, while the individual primitives don't.

The memory usages is reduced considerably but still increases with rotation.

enter image description here

And as the only figure that does this is the Tubes with individual primitives. Once I delete that figure from the grid the memory drops to the starting memory. With that figure removed, I can do whatever I want without increasing memory usage.

enter image description here

enter image description here

So for now if I want to render the colors correctly I should use the individual primitives but with memory leaks after rotation. But if I want to rotate I use the grouped primitives and accept the wrong coloring.

So the workaround I have now is to manipulate the images using lines and switching to the tube render once I'm happy with the view.

Manipulate[
 {Graphics3D[ll2, opts], Graphics3D[tt1, opts]}[[n]]
 , {n, {1 -> "Lines", 2 -> "Tubes"}}]

Each time I switch back to lines the memory is cleared.

POSTED BY: Martijn Froeling
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract