diff options
Diffstat (limited to 'doc/source/reference/c-api/data_memory.rst')
-rw-r--r-- | doc/source/reference/c-api/data_memory.rst | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/doc/source/reference/c-api/data_memory.rst b/doc/source/reference/c-api/data_memory.rst index 2084ab5d0..cab587efc 100644 --- a/doc/source/reference/c-api/data_memory.rst +++ b/doc/source/reference/c-api/data_memory.rst @@ -159,3 +159,87 @@ A better technique would be to use a ``PyCapsule`` as a base object: return NULL; } ... + +Example of memory tracing with ``np.lib.tracemalloc_domain`` +------------------------------------------------------------ + +Note that since Python 3.6 (or newer), the builtin ``tracemalloc`` module can be used to +track allocations inside NumPy. NumPy places its CPU memory allocations into the +``np.lib.tracemalloc_domain`` domain. +For additional information, check: `https://docs.python.org/3/library/tracemalloc.html`. + +Here is an example on how to use ``np.lib.tracemalloc_domain``: + +.. code-block:: python + + """ + The goal of this example is to show how to trace memory + from an application that has NumPy and non-NumPy sections. + We only select the sections using NumPy related calls. + """ + + import tracemalloc + import numpy as np + + # Flag to determine if we select NumPy domain + use_np_domain = True + + nx = 300 + ny = 500 + + # Start to trace memory + tracemalloc.start() + + # Section 1 + # --------- + + # NumPy related call + a = np.zeros((nx,ny)) + + # non-NumPy related call + b = [i**2 for i in range(nx*ny)] + + snapshot1 = tracemalloc.take_snapshot() + # We filter the snapshot to only select NumPy related calls + np_domain = np.lib.tracemalloc_domain + dom_filter = tracemalloc.DomainFilter(inclusive=use_np_domain, + domain=np_domain) + snapshot1 = snapshot1.filter_traces([dom_filter]) + top_stats1 = snapshot1.statistics('traceback') + + print("================ SNAPSHOT 1 =================") + for stat in top_stats1: + print(f"{stat.count} memory blocks: {stat.size / 1024:.1f} KiB") + print(stat.traceback.format()[-1]) + + # Clear traces of memory blocks allocated by Python + # before moving to the next section. + tracemalloc.clear_traces() + + # Section 2 + #---------- + + # We are only using NumPy + c = np.sum(a*a) + + snapshot2 = tracemalloc.take_snapshot() + top_stats2 = snapshot2.statistics('traceback') + + print() + print("================ SNAPSHOT 2 =================") + for stat in top_stats2: + print(f"{stat.count} memory blocks: {stat.size / 1024:.1f} KiB") + print(stat.traceback.format()[-1]) + + tracemalloc.stop() + + print() + print("============================================") + print("\nTracing Status : ", tracemalloc.is_tracing()) + + try: + print("\nTrying to Take Snapshot After Tracing is Stopped.") + snap = tracemalloc.take_snapshot() + except Exception as e: + print("Exception : ", e) + |