-
Notifications
You must be signed in to change notification settings - Fork 417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optionally deep clone run outputs #1142
Comments
We do some fancy-ish things in which is called twice:
I wonder if this is only run in edit mode (and not as a script) that you are seeing this issue. and possible we need to clear the plots in run mode. @akshayka any thoughts? |
This does not happen with the way islands generates cells, but I just checked behavior with the script and I now have this error? Traceback (most recent call last):
File "/home/dylan/test.py", line 293, in <module>
objs, _ = app.run()
^^^^^^^^^
File "/home/dylan/src/marimo/marimo/_ast/app.py", line 335, in run
return self._run_sync()
^^^^^^^^^^^^^^^^
File "/home/dylan/src/marimo/marimo/_ast/app.py", line 267, in _run_sync
outputs[cid] = execute_cell(cell._cell, glbls)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/dylan/src/marimo/marimo/_ast/cell.py", line 444, in execute_cell
exec(cell.body, glbls)
File "/tmp/marimo_3443916/__marimo__cell_TqIu_.py", line 11, in <module>
File "/home/dylan/src/marimo/marimo/_plugins/ui/_core/ui_element.py", line 267, in value
== ctx.ui_element_registry.get_cell(self._id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/dylan/src/marimo/marimo/_plugins/ui/_core/registry.py", line 200, in get_cell
raise NotImplementedError
NotImplementedError |
@dmadisetti - this is likely from #1150. do you have a small snippet of the code to reproduce? |
Not exactly the same error: Traceback (most recent call last):
File "/home/dylan/1086.py", line 21, in <module>
app.run()
File "/home/dylan/src/marimo/marimo/_ast/app.py", line 335, in run
return self._run_sync()
^^^^^^^^^^^^^^^^
File "/home/dylan/src/marimo/marimo/_ast/app.py", line 267, in _run_sync
outputs[cid] = execute_cell(cell._cell, glbls)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/dylan/src/marimo/marimo/_ast/cell.py", line 445, in execute_cell
return eval(cell.last_expr, glbls)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/marimo_3531073/__marimo__cell_Hbol__output.py", line 7, in <module>
File "/home/dylan/downloads/manim/lib/python3.11/site-packages/matplotlib/pyplot.py", line 527, in show
return _get_backend_mod().show(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/dylan/src/marimo/marimo/_output/mpl.py", line 64, in show
_internal_show(manager.canvas)
File "/home/dylan/src/marimo/marimo/_output/mpl.py", line 47, in _internal_show
CellOp.broadcast_console_output(
File "/home/dylan/src/marimo/marimo/_messaging/ops.py", line 179, in broadcast_console_output
assert cell_id is not None
^^^^^^^^^^^^^^^^^^^
AssertionError might be worth adding this as a unit test: https://github.com/marimo-team/marimo/blob/main/marimo/_smoke_tests/bugs/1086.py I'll see if I can boil it down to something smaller, but the first stack track is just plots.py from the tutorial with the full source and initial output in the original summary |
|
@akshayka just squashed 3 related bugs. can you give it another shot with your own code? (we have it running again our tutorials now) |
Yes! This fixes the crash- this also fixes most of the redundant plots in tutorial. However, the shared axis object still has a global response: @app.cell # cell 14
def __(plt, x):
_, axis = plt.subplots()
axis.plot(x, x)
axis.plot(x, x**2)
axis
return axis, @app.cell # cell 15
def __(axis, x):
axis.plot(x, x**3)
axis
return |
OR, have the script response as being correct - plot 1: x, x^2
- plot 2: x, x^2, x^3
+ plot 1: x, x^2, x^3, x^4
+ plot 2: x, x^2, x^3, x^4
plot 3: x, x^2, x^3, x^4 code: import marimo
app = marimo.App()
@app.cell
def __(np):
x = np.linspace(start=-4, stop=4, num=100, dtype=float)
return x,
def __(plt, x):
_, axis = plt.subplots()
axis.plot(x, x)
axis.plot(x, x**2)
axis
return axis,
@app.cell
def __(axis, x):
axis.plot(x, x**3)
axis
return
@app.cell
def __(axis, x):
axis.plot(x, x**4)
axis
return
@app.cell
def __():
import marimo as mo
try:
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
missing_packages = False
except ModuleNotFoundError:
missing_packages = True
if not missing_packages:
matplotlib.rcParams['figure.figsize'] = (6, 2.4)
return mo, matplotlib, missing_packages, np, plt
import matplotlib.pyplot as plt
if __name__ == "__main__":
objs, v = app.run()
print(v)
for i, o in enumerate(objs):
# Unpack the Line2d cases
if isinstance(o, list):
o, = o
# Quick hack for testing
if "matplotlib" in str(type(o)):
o.get_figure().savefig(f"{i}.png") |
Don't they all share the same
Okay, I now see how providing a fresh figure isn't sufficient. Thanks for the example. This I suppose isn't specific to plots but really to any data structure that is mutated over and output in multiple cells.
|
Correct is relative to design, I think both cases are valid- but ideally you'd want consistency
global hidden state is really hard to get around- the data flow tutorial makes it pretty clear that objects are hard to handle, so this could just be covered under that disclaimer Just an aside, dataflow expectations for parallelism are definitely Case 1 |
Yeah, consistency is key. Export snapshots while running, so I think you get the same semantics as when running as an notebook (at least that's what happened when I ran it just now). But like you say the more important thing is to define the semantics and ensure consistency across different ways of running.
To double check -- what is Case 1? :) |
Oh woops. To be explicit: Case 1 graph TD;
cell1("Cell 1\nShows x, x^2")-->cell2("Cell 2\nShows x, x^2, x^3");
cell1-->cell3("Cell 3\nShows x, x^2, x^4");
Which can be made parallel because the tasks are independent Case 2 graph TD;
cell1("Cell 1\nShows x, x^2, x^3, x^4")-->cell2("Cell 2\nShows x, x^2, x^3, x^4");
cell3("Cell 3\nShows x, x^2, x^3, x^4");
cell2 --"order takes precedence in mutating axis"-->cell3;
Case 2 has a hidden dependency since the global object is built up. |
Okay great, yes — that makes total sense. On the same page. |
@akshayka I might take a stab at this over the weekend. I have something working that passes all unit tests with cloning on (except pickling, but I think that's the test env not being patched), but I want to write unit tests for it explicitly/ clean it up. FWIW, I haven't observed a noticeable overhead My change also solves some of the behavior I observed in #1509 and introduces a This is all under a user config flag, that I currently have as I want to get |
Nice! Is this just for
Could be
That would be awesome! |
Closing with #1580 |
Describe the bug
I noticed when I did the qmd export for quarto that plots don't properly work:
It looks like the plots all refer to the global
plt.gca
object rather than its snapshot at run.This doesn't affect the reactive notebook since the plot object is rendered to HTML, essentially creating a snapshot, and then the next cell is executed. However, in script mode the output is just a pointer to the current global state
Suggestion: I think deep copies can be expensive, so maybe an optional deep copy?
Environment
3.12-dev (I haven't pulled in a few days but I don't think you've made any changed that would affect this)
Code to reproduce
Relevant export test:
for completion the [plots.py](http://plots.py) tutorial
produces: 11.png 12.png 14.png 15.png 5.png 7.png
where 5 and 7 are the same, and the rest are the same
This isn't the same behavior as in the export, but similar, and still incorrect
The text was updated successfully, but these errors were encountered: