Profile in Notebook#

Profiling with Python CProfiler#

Before getting started, this example requires the config flag PFlow.init_tds to be 0, which is the default value.

import andes
from andes.utils.paths import get_case

case_path = get_case('kundur/kundur_full.xlsx')

Passing profile=True, no_output = True to run will enable the profiler and have the results printed.

ss = andes.run(case_path, profile=True, routine='tds', no_output=True)
Working directory: "/home/hacui/repos/andes/examples"
Loaded config from file "/home/hacui/.andes/andes.rc"
Loaded generated Python code in "/home/hacui/.andes/pycode".
Parsing input file "/home/hacui/repos/andes/andes/cases/kundur/kundur_full.xlsx"...
Input file parsed in 0.2928 seconds.
System internal structure set up in 0.0339 seconds.
-> System connectivity check results:
  No islanded bus detected.
  A total of 1 island(s) detected.
  Each island has a slack bus correctly defined and enabled.

-> Power flow calculation
   Sparse solver: KLU
 Solution method: NR method
Numba compilation initiated with caching.
Power flow initialized in 0.2752 seconds.
0: |F(x)| = 14.9282832
1: |F(x)| = 3.608627841
2: |F(x)| = 3.371691245
3: |F(x)| = 3.38335788
4: |F(x)| = 1.643469337
5: |F(x)| = 0.2341714002
6: |F(x)| = 0.03397375079
7: |F(x)| = 0.0009863888463
8: |F(x)| = 1.354810848e-06
9: |F(x)| = 2.629008122e-12
Converged in 10 iterations in 0.0072 seconds.

-> Time Domain Simulation Summary:
Sparse Solver: KLU
Simulation time: 0.0-20.0 s.
Fixed step size: h=33.33 ms. Shrink if not converged.
Numba compilation initiated with caching.
PQ.vcmp out of limits <vmin>

 idx  | Flag | Input Value | Limit
------+------+-------------+------
 PQ_1 | zl   | 0.833       | 0.900


Initialization for dynamics completed in 0.1149 seconds.
Initialization was successful.
<Toggle 1>: Line.Line_8 status changed to 0 at t=2.0 sec.            
100%|███████████████████████████████| 100/100 [00:00<00:00, 142.57%/s]
Simulation completed in 0.7017 seconds.


         2468624 function calls (2438847 primitive calls) in 1.587 seconds

   Ordered by: cumulative time
   List reduced from 7730 to 40 due to restriction <40>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.004    0.004    0.824    0.824 /home/hacui/repos/andes/andes/routines/tds.py:280(run)
      603    0.000    0.000    0.687    0.001 /home/hacui/repos/andes/andes/routines/tds.py:416(itm_step)
      603    0.048    0.000    0.687    0.001 /home/hacui/repos/andes/andes/routines/daeint.py:27(step)
    10103    0.052    0.000    0.611    0.000 /home/hacui/repos/andes/andes/system.py:1658(call_models)
     2003    0.006    0.000    0.546    0.000 /home/hacui/repos/andes/andes/routines/tds.py:703(fg_update)
 1164/205    0.003    0.000    0.498    0.002 <frozen importlib._bootstrap>:1002(_find_and_load)
 1097/139    0.002    0.000    0.496    0.004 <frozen importlib._bootstrap>:967(_find_and_load_unlocked)
   988/57    0.001    0.000    0.493    0.009 <frozen importlib._bootstrap_external>:844(exec_module)
  1465/57    0.000    0.000    0.493    0.009 <frozen importlib._bootstrap>:220(_call_with_frames_removed)
 1070/139    0.002    0.000    0.491    0.004 <frozen importlib._bootstrap>:659(_load_unlocked)
 1062/115    0.002    0.000    0.490    0.004 {built-in method builtins.exec}
        1    0.000    0.000    0.479    0.479 /home/hacui/repos/andes/andes/main.py:270(load)
        1    0.000    0.000    0.293    0.293 /home/hacui/repos/andes/andes/io/__init__.py:98(parse)
        1    0.000    0.000    0.292    0.292 /home/hacui/repos/andes/andes/io/xlsx.py:87(read)
        1    0.000    0.000    0.285    0.285 /home/hacui/repos/andes/andes/routines/pflow.py:169(run)
       61    0.000    0.000    0.283    0.005 /home/hacui/repos/andes/andes/utils/lazyimport.py:61(__maybe_import__)
       60    0.000    0.000    0.281    0.005 /home/hacui/repos/andes/andes/utils/lazyimport.py:73(__getattr__)
     2014    0.001    0.000    0.276    0.000 /home/hacui/repos/andes/andes/system.py:1004(g_update)
        1    0.000    0.000    0.276    0.276 /home/hacui/repos/andes/andes/routines/pflow.py:62(init)
    20095    0.127    0.000    0.259    0.000 /home/hacui/repos/andes/andes/core/model.py:1324(g_update)
        2    0.000    0.000    0.213    0.106 /home/hacui/repos/andes/andes/system.py:757(init)
  356/229    0.001    0.000    0.211    0.001 {built-in method builtins.__import__}
       43    0.000    0.000    0.202    0.005 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/pandas/util/_decorators.py:302(wrapper)
        2    0.000    0.000    0.199    0.099 /home/hacui/repos/andes/andes/system.py:682(_init_numba)
       15    0.000    0.000    0.198    0.013 /home/hacui/repos/andes/andes/core/model.py:1698(numba_jitify)
       36    0.000    0.000    0.198    0.006 /home/hacui/repos/andes/andes/core/model.py:2019(to_jit)
        1    0.000    0.000    0.191    0.191 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/numba/__init__.py:1(<module>)
3655/2445    0.002    0.000    0.184    0.000 <frozen importlib._bootstrap>:1033(_handle_fromlist)
        1    0.000    0.000    0.182    0.182 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/pandas/io/excel/_base.py:330(read_excel)
    94/93    0.000    0.000    0.181    0.002 /home/hacui/mambaforge/envs/a/lib/python3.9/importlib/__init__.py:109(import_module)
    94/93    0.000    0.000    0.180    0.002 <frozen importlib._bootstrap>:1018(_gcd_import)
        1    0.000    0.000    0.153    0.153 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/pandas/io/excel/_base.py:1166(__init__)
        1    0.000    0.000    0.151    0.151 /home/hacui/repos/andes/andes/system.py:93(__init__)
        1    0.000    0.000    0.151    0.151 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/pandas/io/excel/_openpyxl.py:506(__init__)
       26    0.000    0.000    0.150    0.006 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/numba/core/dispatcher.py:340(_compile_for_args)
        4    0.000    0.000    0.141    0.035 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/pandas/compat/_optional.py:64(import_optional_dependency)
       26    0.000    0.000    0.138    0.005 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/numba/core/dispatcher.py:864(compile)
        1    0.000    0.000    0.138    0.138 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/openpyxl/__init__.py:4(<module>)
       26    0.000    0.000    0.135    0.005 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/numba/core/caching.py:636(load_overload)
        1    0.000    0.000    0.131    0.131 /home/hacui/mambaforge/envs/a/lib/python3.9/site-packages/openpyxl/workbook/__init__.py:4(<module>)


-> Single process finished in 1.7134 seconds.

Profiling with line_profiler.#

line_profiler provides line-based profiling results for functions.

Install with pip install line_profiler and restart the notebook.

import andes
from andes.utils.paths import get_case

case_path = get_case('kundur/kundur_full.xlsx')

Profile power flow#

Pass the function name to profile to the magic %lprun, followed by a call to the function itself or an upper-level function.

Results will be shown in a popup window.

%load_ext line_profiler

%lprun -f andes.routines.pflow.PFlow.run andes.run(case_path, no_output=True, default_config=True)
Working directory: "/home/hacui/repos/andes/examples"
Reloaded generated Python code of module "pycode".
Parsing input file "/home/hacui/repos/andes/andes/cases/kundur/kundur_full.xlsx"...
Input file parsed in 0.0882 seconds.
System internal structure set up in 0.0450 seconds.
-> System connectivity check results:
  No islanded bus detected.
  A total of 1 island(s) detected.
  Each island has a slack bus correctly defined and enabled.

-> Power flow calculation
   Sparse solver: KLU
 Solution method: NR method
Power flow initialized in 0.0064 seconds.
0: |F(x)| = 14.9282832
1: |F(x)| = 3.608627841
2: |F(x)| = 0.1701107882
3: |F(x)| = 0.002038626956
4: |F(x)| = 3.745103977e-07
Converged in 5 iterations in 0.0050 seconds.
-> Single process finished in 0.3018 seconds.

Alternatively, do

ss = andes.run(case_path, no_output=True, default_config=True)
Working directory: "/home/hacui/repos/andes/examples"
Reloaded generated Python code of module "pycode".
Parsing input file "/home/hacui/repos/andes/andes/cases/kundur/kundur_full.xlsx"...
Input file parsed in 0.0341 seconds.
System internal structure set up in 0.0315 seconds.
-> System connectivity check results:
  No islanded bus detected.
  A total of 1 island(s) detected.
  Each island has a slack bus correctly defined and enabled.

-> Power flow calculation
   Sparse solver: KLU
 Solution method: NR method
Power flow initialized in 0.0021 seconds.
0: |F(x)| = 14.9282832
1: |F(x)| = 3.608627841
2: |F(x)| = 0.1701107882
3: |F(x)| = 0.002038626956
4: |F(x)| = 3.745103977e-07
Converged in 5 iterations in 0.0030 seconds.
-> Single process finished in 0.1183 seconds.
ss.reset()
%lprun -f ss.PFlow.run ss.PFlow.run()
System internal structure set up in 0.0203 seconds.
-> System connectivity check results:
  No islanded bus detected.
  A total of 1 island(s) detected.
  Each island has a slack bus correctly defined and enabled.

-> Power flow calculation
   Sparse solver: KLU
 Solution method: NR method
Power flow initialized in 0.0059 seconds.
0: |F(x)| = 14.9282832
1: |F(x)| = 3.608627841
2: |F(x)| = 0.1701107882
3: |F(x)| = 0.002038626956
4: |F(x)| = 3.745103977e-07
Converged in 5 iterations in 0.0042 seconds.

To dig into the Newton Raphson iteration steps, profile each step instead with:

ss.reset()
%lprun -f ss.PFlow.nr_step ss.PFlow.run()
System internal structure set up in 0.0197 seconds.
-> System connectivity check results:
  No islanded bus detected.
  A total of 1 island(s) detected.
  Each island has a slack bus correctly defined and enabled.

-> Power flow calculation
   Sparse solver: KLU
 Solution method: NR method
Power flow initialized in 0.0059 seconds.
0: |F(x)| = 14.9282832
1: |F(x)| = 3.608627841
2: |F(x)| = 0.1701107882
3: |F(x)| = 0.002038626956
4: |F(x)| = 3.745103977e-07
Converged in 5 iterations in 0.0042 seconds.

Profile time-domain simulation#

%lprun -f ss.TDS.itm_step ss.TDS.run()
-> Time Domain Simulation Summary:
Sparse Solver: KLU
Simulation time: 0.0-20.0 s.
Fixed step size: h=33.33 ms. Shrink if not converged.
Initialization for dynamics completed in 0.0536 seconds.
Initialization was successful.
<Toggle 1>: Line.Line_8 status changed to 0 at t=2.0 sec.            
100%|███████████████████████████████| 100/100 [00:00<00:00, 101.60%/s]
Simulation completed in 0.9845 seconds.

Cleanup#

!andes misc -C
    _           _         | Version 1.5.7.post27.dev0+g9e0e253e
   /_\  _ _  __| |___ ___ | Python 3.9.7 on Linux, 12/14/2021 02:51:15 PM
  / _ \| ' \/ _` / -_|_-< | 
 /_/ \_\_||_\__,_\___/__/ | This program comes with ABSOLUTELY NO WARRANTY.

No output file found in the working directory.