qutip / qutip

QuTiP: Quantum Toolbox in Python
https://qutip.org
BSD 3-Clause "New" or "Revised" License
1.69k stars 635 forks source link

What is rhs_xxx.pyx or cqobjevo_compiled_xxx.pyx file? #1684

Closed KosukeMizuno closed 2 years ago

KosukeMizuno commented 3 years ago

Is your feature request related to a problem? Please describe.

Sometimes qutip.mesolver generate rhs_**.pyx or cqobjevo_compiled_coeff_**.pyx files. According to the docstring of solver.Options and rhs_generate, I guess rhs-things relate to string-format time-dependent Hamiltonian, but I couldn't find description about such files. I didn't know even a meaning of 'rhs' (abbreviation?). So I suggest to add documents about them.

Especially, I have the following question:

Saving solver result with pickle module, and loading it sometimes fail, for example: (I'm so sorry I haven't reproduce this behavior with simplest code, so the following is a dummy-code)

out = mesolve(...)
with open(filename, 'wb') as f:
    pickle.dump(out, f)
Exception ignored in: <function QobjEvo.__del__ at 0x7f9e406f4310>
Traceback (most recent call last):
  File "/home/mizuno.kosuke/venvs/default/lib/python3.8/site-packages/qutip/qobjevo.py", line 624, in __del__
    for file_ in self.coeff_files:
AttributeError: 'QobjEvo' object has no attribute 'coeff_files'
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-22-e4ad332ebfe3> in <module>
      2 p_json = Path(filename)
      3 with p_json.with_suffix('.result.pkl').open('rb') as f:
----> 4     res = pickle.load(f)

ModuleNotFoundError: No module named 'cqobjevo_compiled_coeff_877182617539010'

Note: I used pickle module instead of qsave/qload. I guess it's no difference because qsave uses pickle module internally.

Ericgig commented 3 years ago

rhs_**.pyx or cqobjevo_compiled_coeff_**.pyx are cython compiled function for string-format time-dependent systems. rhs_**.pyx create a function for the right hand side (rhs) of the equation solved by the solver. It's now mostly used in brmesolve.

cqobjevo_compiled_coeff_**.pyx is used in QobjEvo with string coefficient.

Which version are you using? QobjEvo should not be found in Results and QobjEvo can be pickle in recent version...

KosukeMizuno commented 3 years ago

I'm sorry to forgot to show qutip version. Software versions are following:

Software    Version
nqoc    0.1.0 at 0bac33500206ac35617a8c02401dff390b2bc00b master
QuTiP   4.6.2
Numpy   1.20.3
SciPy   1.6.3
matplotlib  3.4.2
Cython  0.29.23
Number of CPUs  96
BLAS Info   OPENBLAS
IPython 7.24.1
Python  3.8.10 (default, Jul 6 2021, 20:53:23) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
OS  posix [linux]

so qutip is latest one. I mainly use mesolve and paralell_map (I haven't use brmesolve).

KosukeMizuno commented 3 years ago

I can reproduce this problem. (Note: environment is different of my previous reply, but qutip is latest 4.6.2)

I attached a notebook: https://gist.github.com/KosukeMizuno/5f879603b6343a18fdf0dc50f3f8b7b0#file-checkpyx-ipynb

How to reproduce:

  1. run this notebook
    • A cqobjevo_compiled_coeff_xxx.pyx file is generated at cell[2].
  2. save output by pickle (cell[4])
  3. load pickled file (cell[5])
    • it succeeds.
  4. restart kernel
    • At this timing, pyx file was automatically removed.
  5. run cell[5] (load pickled file)
    • it fails.
Exception ignored in: <function QobjEvo.__del__ at 0x000001E0295BC4C0>
Traceback (most recent call last):
  File "c:\users\mizuno\research\py38\lib\site-packages\qutip\qobjevo.py", line 624, in __del__
    for file_ in self.coeff_files:
AttributeError: 'QobjEvo' object has no attribute 'coeff_files'
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-1-ca5f267c7a72> in <module>
      1 with Path('mesolvedat.pkl').open('rb') as f:
----> 2     out2 = pickle.load(f)

ModuleNotFoundError: No module named 'cqobjevo_compiled_coeff_5082571634280'
Ericgig commented 3 years ago

Looking at it, the issue is in sesolve which is called by mesovle when no c_ops are passed. It save the Hamiltonian in the results.

If you do

if hasattr(out, 'SolverSystem'):
    out.SolverSystem = None

before pickling, it should work.

But I would suggest to extract the states as numpy arrays and use numpy.save. With it, the data should stay readable even if you update numpy or python, while any qutip (or scipy) update could make it impossible to unpickle Qobj.

KosukeMizuno commented 3 years ago

At this time, I use your treatment, and it works. Thank you very much.