Skip to content
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

Reduce memory usage #143

Closed
EwoutH opened this issue Sep 23, 2024 · 8 comments
Closed

Reduce memory usage #143

EwoutH opened this issue Sep 23, 2024 · 8 comments
Labels
enhancement New feature or request

Comments

@EwoutH
Copy link
Contributor

EwoutH commented Sep 23, 2024

An UXsim simulation on my model took 4-6 GB for a few hundreds of thousands of vehicles, with vehicle logging off.

I profiled the memory in a small run, with as result:

[ Top 10 Memory Usage ]
.virtualenvs\Py312\src\uxsim\uxsim\uxsim.py:1431: size=1388 MiB, count=72, average=19.3 MiB
AppData\Local\Programs\Python\Python312\Lib\copy.py:71: size=90.7 MiB, count=962, average=96.6 KiB
.virtualenvs\Py312\src\uxsim\uxsim\uxsim.py:951: size=78.5 MiB, count=150008, average=549 B
.virtualenvs\Py312\src\uxsim\uxsim\uxsim.py:659: size=27.5 MiB, count=3272, average=8800 B
.virtualenvs\Py312\src\uxsim\uxsim\uxsim.py:620: size=27.5 MiB, count=3272, average=8800 B

The upper line indicates a huge amount of memory (1388 MiB, for a small run) is used here:

s.route_pref = np.where(next_node_mask,

I don't know that much about memory profiling, but this might be a leak or at least something we can optimise. I will try to get some more details.

@EwoutH
Copy link
Contributor Author

EwoutH commented Sep 24, 2024

The s.route_pref is in my model about 40MB, which is unnecessarily large, because float numbers between 0.0 and 1.0 don't need float64 precision.

The bigger problem is that it doesn't get recycled / collected however, but just keeps growing:

image

This is "just" two hours of simulation, taking already 1GB.

@toruseo
Copy link
Owner

toruseo commented Sep 24, 2024

I got time for quick comments.

Thanks for investigating. I didnt notice this issue. I agree that this must be solved.

But it is very weird that RouteChoice.route_pref consumes such a huge memory. It is always overwritten when updating. If the reason was RouteChoice.dist_record, it is understandable as it stores all historical dist matrix. If this is the case, you can just comment out dist_record recording process.

@EwoutH
Copy link
Contributor Author

EwoutH commented Oct 1, 2024

For longer simulations, it might be interesting if vehicles can be deleted after they have ended their trips. That could save a lot of memory when no individual vehicle data is needed.

image

@EwoutH
Copy link
Contributor Author

EwoutH commented Oct 2, 2024

Even with the PRs applied, there's still definitely a memory leak in UXsim somewhere. When running multiple scenarios sequentially, the UXsim World (and probably some of its components) don't get garbage collected properly.

### Running the model from 5 to 24 with av_cost_0.25_av_vot_0.25_av_density_0.5_induced_1.5
Model step (sim time: 5.000, uw time: 0.0).       time| # of vehicles| ave speed| computation time
       0 s|        0 vehs|   0.0 m/s|     7.33 s
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
  File "C:\Users\Ewout\AppData\Local\Programs\Python\Python312\Lib\multiprocessing\pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
                    ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Ewout\AppData\Local\Programs\Python\Python312\Lib\multiprocessing\pool.py", line 48, in mapstar
    return list(map(*args))
           ^^^^^^^^^^^^^^^^
  File "C:\Users\Ewout\Documents\GitHub\urban-self-driving-effects\model\model.py", line 258, in run_experiment
    simulator.run_until(model.end_time)
  File "C:\Users\Ewout\.virtualenvs\Py312\Lib\site-packages\mesa\experimental\devs\simulator.py", line 81, in run_until
    event.execute()
  File "C:\Users\Ewout\.virtualenvs\Py312\Lib\site-packages\mesa\experimental\devs\eventlist.py", line 84, in execute
    fn(*self.function_args, **self.function_kwargs)
  File "C:\Users\Ewout\Documents\GitHub\urban-self-driving-effects\model\model.py", line 205, in req_exec_simulation
    self.uw.exec_simulation(until_t=self.uw_time)
  File "C:\Users\Ewout\.virtualenvs\Py312\src\uxsim\uxsim\uxsim.py", line 2002, in exec_simulation
    W.ROUTECHOICE.route_search_all(noise=W.DUO_NOISE)
  File "C:\Users\Ewout\.virtualenvs\Py312\src\uxsim\uxsim\uxsim.py", line 1361, in route_search_all
    s.adj_mat_time = np.zeros([len(s.W.NODES), len(s.W.NODES)], dtype=np.float32)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
numpy._core._exceptions._ArrayMemoryError: Unable to allocate 9.46 MiB for an array with shape (1575, 1575) and data type float32
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Ewout\Documents\GitHub\urban-self-driving-effects\model\model.py", line 360, in <module>
    pool.map(run_experiment, combinations_to_run)
  File "C:\Users\Ewout\AppData\Local\Programs\Python\Python312\Lib\multiprocessing\pool.py", line 367, in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Ewout\AppData\Local\Programs\Python\Python312\Lib\multiprocessing\pool.py", line 774, in get
    raise self._value
numpy._core._exceptions._ArrayMemoryError: Unable to allocate 9.46 MiB for an array with shape (1575, 1575) and data type float32

@toruseo toruseo added the enhancement New feature or request label Oct 3, 2024
@toruseo
Copy link
Owner

toruseo commented Oct 3, 2024

Now I remember that each vehicle holds its own route_pref to represent possibly heterogeneous route choice. In a large network, its total size may become huge.

Adding an option to deleting it after vehicle's trip is considerable

EwoutH added a commit to EwoutH/urban-self-driving-effects that referenced this issue Oct 3, 2024
Use new reduce_memory_delete_vehicle_route_pref=True argument when initializing the UXsim world to reduce the memory usage. Without this, each vehicle holds its own route_pref to represent possibly heterogeneous route choice. In a large network, its total size may become huge. This deletes it after each vehicle's trip done.

See:
- toruseo/UXsim#143 (comment)
- toruseo/UXsim#149

Rebased the time_bin_mem_opt branch: https://github.com/EwoutH/uxsim@time_bin_mem_opt#egg=uxsim

In-place updates to route_pref (#146) is now also included.
@EwoutH
Copy link
Contributor Author

EwoutH commented Oct 3, 2024

Thanks! I'm running more simulations tonight, I enabled it, curious if / how much it will help.

Another option that would be useful for me is just deleting the vehicle altogether after its finished. Especially for longer simulations that should help memory from inflating. Especially if you don't need data from Vehicle objects or have already saved them while/before finishing.

With #130 area_to_pandas only needs link data, and no vehicle data anymore, which adds an additional use case in which vehicles can just be thrown away after completing their journey.

Could just be another boolean switch like remove_vehicle_on_completion.

@toruseo
Copy link
Owner

toruseo commented Oct 3, 2024

I think deleting vehicle is too drastic (we will need to add a lot of exception-catching codes to fully support that function), and I dont want to add it as a default function. This is a traffic simulator after all; deleting traffic is not an option.

Maybe it can be added to user-side codes by using user_function that monitors Vehicle.state variable (if it is "end", del the object)

@toruseo
Copy link
Owner

toruseo commented Nov 13, 2024

Regarding this and related issues and PRs on the performance improvements, I think most of the feasible options have been implemented. So, I am closing them.

Of course, I understand that the current version is far from perfect and there is a lot of room for improvement. Feel free to re-open them or propose new ideas.

Thanks for the suggestions and contributions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants