Hi,
I am trying to set up some sort of a subjective experiment where I’ll ask some observers to compare various 3D objects (loaded as STL meshes).
I’m running the app locally, it all works (almost) fine, except that the memory usage keeps going up, and I end up with a segmentation fault (when too many volumes are loaded).
I’m not sure I quite understand streamlit’s caching mechanism, I’ve tried quite a few things, but I always end up with a memory crash.
My code looks like that (my apologies, it’s a bit long) :
import streamlit as st
import pyvista as pv
from stpyvista import stpyvista
st.set_page_config(layout="wide", initial_sidebar_state="collapsed")
cnt = st.session_state.count
#st.write(cnt)
#@st.cache_resource
def read_and_display_stl(plname):
plotter = pv.Plotter(window_size=[320,320])
mesh = pv.read(plname)
mesh['myscalar'] = mesh.points[:, 2] * mesh.points[:, 0]
## Add mesh to the plotter
plotter.add_mesh(mesh, scalars='myscalar')
plotter.view_isometric()
plotter.background_color = 'gainsboro'
return(plotter)
# Create side-by-side columns
col10, col20, col30 = st.columns(3)
if cnt < st.session_state.nb_im:
with col20:
plotter0 = read_and_display_stl(st.session_state.pl[cnt*4+1])
## Send to streamlit
stpyvista(plotter0, key=str(cnt))
col1, col2, col3 = st.columns(3)
with col1:
plotter1 = read_and_display_stl(st.session_state.pl[cnt*4+2])
## Send to streamlit
stpyvista(plotter1, key=str(cnt+1))
option1 = st.selectbox('Bifurcation # 1',
['Choose a score',1,2,3], index = None, key='selection1')
Score1=option1
with col2:
plotter2 = read_and_display_stl(st.session_state.pl[cnt*4+3])
## Send to streamlit
stpyvista(plotter2, key=str(cnt+2))
option2 = st.selectbox('Bifurcation # 2',
['Choose a score',1,2,3], index = None, key='selection2')
Score2=option2
with col3:
plotter3 = read_and_display_stl(st.session_state.pl[cnt*4+4])
## Send to streamlit
stpyvista(plotter3, key=str(cnt+3))
option3 = st.selectbox('Bifurcation # 3',
['Choose a score',1,2,3], index = None, key='selection3')
Score3=option3
st.markdown("""---""")
if cnt == st.session_state.nb_im:
st.session_state.count = 0
st.session_state.PL = []
del st.session_state["count"]
del st.session_state["pl"]
st.switch_page("pages/end.py")
def update_counter():
st.session_state.count += 1
if (st.session_state.count >= 1):
with open("./outputs/" + st.session_state.key + ".txt", "a") as myfile:
myfile.write("%s\t%s\t%s\n" %(st.session_state.pl[(st.session_state.count-1)*4+2],
st.session_state.pl[(st.session_state.count-1)*4+3],
st.session_state.pl[(st.session_state.count-1)*4+4]))
myfile.write("%s\t%s\t%s\n" %(Score1, Score2, Score3))
def reset_selectboxes():
st.session_state.selection1 = 'Choose a score'
st.session_state.selection2 = 'Choose a score'
st.session_state.selection3 = 'Choose a score'
def master_callback():
update_counter()
#st.cache_data.clear()
#st.cache_resource.clear()
#read_and_display_stl.clear()
reset_selectboxes()
runButton = st.button("Validate", on_click=master_callback)
Basically, the protocol is as follows: the observers will see 4 volumes displayed on the monitor, one on top, which is the reference, and three below, in a row that they’ll need to sort in resembling order (using a selectbox).
I’ve plotted the memory usage, and it seems the memory is never freed (see attached image).
Any help would be hugely appreciated, I’ve been struggling on this for a while now.
Best regards.
Florent