...

May 21, 2026 ยท View on GitHub

ExaGO Python Bindings

Overview

The ExaGO Python bindings use an object-oriented API slightly different from the C++ API. The C++ API uses the application type in uppercase as the prefix for its methods, where they are native methods in Python. To view the implementation of this wrapper, see /interfaces/python/exago_python.cpp.

For example, solving an OPF from C++ might look like this:

#include <opflow.h>
#include <exago_config.h>

static char help[] = "User example calling OPFLOW.\n";
static char appname[] = "opflow";

int main(int argc, char** argv) {

  /* Initialize ExaGO application */
  PetscErrorCode ierr;
  OPFLOW opflow;
  MPI_Comm comm = MPI_COMM_WORLD;
  ierr = ExaGOInitialize(comm, &argc, &argv, appname, help);

  /* Create OPFLOW object */
  ierr = OPFLOWCreate(comm, &opflow);
  ExaGOCheckError(ierr);

  /* Read network data */
  ierr = OPFLOWReadMatPowerData(opflow, "datafiles/case9/case9mod.m");
  ExaGOCheckError(ierr);

  /* Solve */
  ierr = OPFLOWSolve(opflow);
  ExaGOCheckError(ierr);

  /* Print solution */
  ierr = OPFLOWPrintSolution(opflow);
  ExaGOCheckError(ierr);

  /* Destroy OPFLOW object */
  ierr = OPFLOWDestroy(&opflow);
  ExaGOCheckError(ierr);

  /* Clean up resources */
  ExaGOFinalize();

  return 0;
}

While a version of the same driver that uses the Python bindings looks like this:

import exago
exago.initialize("opflow")
opf = exago.OPFLOW()
opf.read_mat_power_data('datafiles/case9/case9mod.m')
opf.solve()
opf.print_solution()
del opf
exago.finalize()

Note that the Python bindings use snake case in accordance with standard Python naming conventions. Translating between the C++ API and the Python API should be relatively straightforward.
ExaGO Python instances must be destroyed, using del, before calling exago.finalize(), like calling *Destroy() with the C++ API. Failure to do so will cause segmentation faults or other memory errors.

If you identify components of the C++ API that you need to call from Python, please open an issue on our issues page.

Building with MPI

ExaGO depends on mpi4py when running through the python interface.

When running exago, you may need to disable threading through mpi4py before importing exago:

import mpi4py.rc
mpi4py.rc.threads = False
from mpi4py import MPI
import exago
comm = MPI.COMM_WORLD
exago.initialize("app", comm)
# ...
exago.finalize()

Additionally linting tools may re-order your imports, and so you may need to add appropriate comments in order to avoid this:

import mpi4py.rc
mpi4py.rc.threads = False
from mpi4py import MPI # noqa
import exago # noqa

Bindings Tables

ExaGO

C++ APIPython APINotes
ExaGOInitializeexago.initialize
ExaGOFinalizeexago.finalize
exago.prefixReturns the path to the installation directory of ExaGO (for finding mat power data files, etc)
OutputFormat enumexago.OutputFormat enumOutput format type for functions like save_solution. Possible values for this enum can be found in the next section.

PFLOW

C++ APIPython APINotes
PFLOWexago.PFLOW classFrom here below, pflow objects are instances of the Python exago.PFLOW class. The same is the case for opflow, scopflow, tcopflow, and sopflow.
PFLOWReadMatPowerDatapflow.read_mat_power_data
PFLOWSolvepflow.solve

OPFLOW

The following table assumes opflow = exago.OPFLOW().

C++ APIPython APINotes
OPFLOWexago.OPFLOW class
OPFLOWObjectiveType enumexago.OPFLOWObjectiveType enumMore details and possible values for this enum can be found in the next section.
OPFLOWInitializationType enumexago.OPFLOWInitializationType enumMore details and possible values for this enum can be found in the next section.
OPFLOWGenBusVoltageType enumexago.OPFLOWGenBusVoltageType enumMore details and possible values for this enum can be found in the next section.
OPFLOWSetObjectiveTypeopflow.set_objective_type
OPFLOWSetInitializationTypeopflow.set_initialization_type
OPFLOWSetGenBusVoltageTypeopflow.set_gen_bus_voltage_type
OPFLOWSetModelopflow.set_modeloptions are "PBPOLRAJAHIOP", "POWER_BALANCE_HIOP", and "POWER_BALANCE_POLAR"
OPFLOWSetSolveropflow.set_solveroptions are "IPOPT", "HIOP", and "HIOPSPARSE"
OPFLOWHasGenSetPointopflow.set_has_gen_set_point
OPFLOWSetHIOPComputeModeopflow.set_hiop_compute_modeoptions are "CPU" or "GPU"
OPFLOWSetHIOPMemSpaceopflow.set_hiop_mem_spaceoptions are "DEFAULT", "HOST", "UM", and "DEVICE"
OPFLOWHasLoadLossopflow.set_has_loadloss
OPFLOWIgnoreLineflowConstraintsopflow.set_ignore_lineflow_constraints
OPFLOWHasBusPowerImbalanceopflow.set_has_bus_power_imbalance
OPFLOWUseAGCopflow.set_use_agc
OPFLOWSetHIOPVerbosityLevelopflow.set_hiop_verbosity_levelinteger between 0 and 10
OPFLOWSetLoadLossPenaltyopflow.set_loadloss_penalty
OPFLOWSetBusPowerImbalancePenaltyopflow.set_bus_power_imbalance_penalty
OPFLOWSetToleranceopflow.set_tolerance
OPFLOWSetWeightopflow.set_weight
PSSetGenPowerLimitsopflow.ps_set_gen_power_limits
OPFLOWGetToleranceopflow.get_tolerance
OPFLOWGetHIOPComputeModeopflow.get_hiop_compute_mode
OPFLOWGetHIOPMemSpaceopflow.get_hiop_mem_space
OPFLOWGetModelopflow.get_model
OPFLOWGetSolveropflow.get_solver
OPFLOWGetConvergenceStatusopflow.get_convergence_status
OPFLOWGetObjectiveTypeopflow.get_objective_type
OPFLOWGetInitializationTypeopflow.get_initialization_type
OPFLOWGetGenBusVoltageTypeopflow.get_gen_bus_voltage_type
OPFLOWGetHasGenSetPointopflow.get_has_gen_set_point
OPFLOWGetLoadlossPenaltyopflow.get_loadloss_penalty
OPFLOWGetIgnoreLineflowConstraintsopflow.get_ignore_lineflow_constraints
OPFLOWGetHasLoadlossopflow.get_has_loadloss
OPFLOWGetHasBusPowerImbalanceopflow.get_has_bus_power_imbalance
OPFLOWGetUseAGCopflow.get_use_agc
OPFLOWGetHIOPVerbosityLevelopflow.get_hiop_verbosity_level
OPFLOWGetBusPowerImbalancePenaltyopflow.get_bus_power_imbalance_penalty
PSGetGenDispatchopflow.get_gen_dispatch
OPFLOWGetObjectiveTypesopflow.get_objective_types
OPFLOWGetInitializationTypesopflow.get_initialization_types
OPFLOWGetGenBusVoltageTypesopflow.get_gen_bus_voltage_types
OPFLOWGetObjectiveopflow.get_objective
OPFLOWSolveopflow.solve
OPFLOWPrintSolutionopflow.print_solution
OPFLOWSaveSolutionopflow.save_solution
OPFLOWReadMatPowerDataopflow.read_mat_power_data
OPFLOWSolutionToPSopflow.solution_to_ps
OPFLOWSetUpPSopflow.set_up_ps
OPFLOWSkipOptionsopflow.skip_options
OPFLOWSetLinesMonitoredImplemented as two different methods:
opflow.set_lines_monitored([...])Specify a list of line kvlevels (type float) to monitor
opflow.set_lines_monitored(n, "file")Read n line kvlevels from a file (n=-1 for all).

SCOPFLOW

The following table assumes scopflow = exago.SCOPFLOW().

C++ APIPython APINotes
SCOPFLOWexago.SCOPFLOW class
ContingencyFileInputFormat enumexago.ContingencyFileInputFormat enumMore details and possible values for this enum can be found in the next section. Currently, this can only be used as a Python enum. A string representation is not available.
SCOPFLOWSetModelset_model
SCOPFLOWSetNetworkDataset_network_data
SCOPFLOWSetLoadProfilesset_load_profiles
SCOPFLOWSetNumContingenciesset_num_contingencies
SCOPFLOWSetContingencyDataset_contingency_data
SCOPFLOWSetPLoadDataset_pload_data
SCOPFLOWSetQLoadDataset_qload_data
SCOPFLOWSetWindGenProfileset_wind_gen_profile
SCOPFLOWSetTimeStepset_time_step
SCOPFLOWSetDurationset_duration
SCOPFLOWSetTimeStepandDurationset_time_step_and_duration
SCOPFLOWSetToleranceset_tolerance
SCOPFLOWSetVerbosityLevelset_verbosity_level
SCOPFLOWSetComputeModeset_compute_mode
SCOPFLOWSetSolverset_solver
SCOPFLOWSetSubproblemModelset_subproblem_model
SCOPFLOWSetSubproblemSolverset_subproblem_solver
SCOPFLOWSetInitilizationTypeset_initialization_type
SCOPFLOWSetGenBusVoltageTypeset_gen_bus_voltage_type
SCOPFLOWEnableMultiPeriodenable_multi_period
SCOPFLOWEnablePowerImbalanceVariablesenable_power_imbalance_variables
SCOPFLOWIgnoreLineflowConstraintsignore_lineflow_constraints
SCOPFLOWGetToleranceget_tolerance
SCOPFLOWGetNumIterationsget_num_iterations
SCOPFLOWGetConvergenceStatusget_convergence_status
SCOPFLOWGetTotalObjectiveget_total_objective
SCOPFLOWGetBaseObjectiveget_base_objective
SCOPFLOWSetUpset_up
SCOPFLOWSolvesolve
SCOPFLOWPrintSolutionprint_solution
SCOPFLOWSaveSolutionsave_solution
SCOPFLOWSaveSolutionDefaultsave_solution_default
SCOPFLOWSaveSolutionAllsave_solution_all
SCOPFLOWSaveSolutionAllDefaultsave_solution_all_default

SOPFLOW

The following table assumes sopflow = exago.SOPFLOW().

C++ APIPython APINotes
SCOPFLOWexago.SCOPFLOW class
ScenarioFileInputFormat enumScenarioFileInputFormat enumMore details and possible values for this enum can be found in the next section. Currently, this can only be used as a Python enum. A string representation is not available.
ScenarioUncertaintyType enumScenarioUncertaintyType enumMore details and possible values for this enum can be found in the next section. Currently, this can only be used as a Python enum. A string representation is not available.
SOPFLOWSetModelset_model
SOPFLOWSetNetworkDataset_network_data
SOPFLOWSetContingencyDataset_contingency_data
SOPFLOWSetNumContingenciesset_num_contingencies
SOPFLOWSetScenarioDataset_scenario_data
SOPFLOWSetNumScenariosset_num_scenarios
SOPFLOWSetWindGenProfileset_wind_gen_profile
SOPFLOWSetTimeStepandDurationset_time_step_and_duration
SOPFLOWSetToleranceset_tolerance
SOPFLOWSetSubproblemVerbosityLevelset_subproblem_verbosity_level
SOPFLOWSetSubproblemComputeModeset_subproblem_compute_mode
SOPFLOWSetSubproblemModelset_subproblem_model
SOPFLOWSetSubproblemSolverset_subproblem_solver
SOPFLOWSetSolverset_solver
SOPFLOWSetInitializationTypeset_initialization_type
SOPFLOWSetGenBusVoltageTypeset_gen_bus_voltage_type
SOPFLOWSetLoadProfilesset_load_profiles
SOPFLOWSetLoadProfilesset_ignore_lineflow_constraints
SOPFLOWEnableMultiContingencyenable_multi_contingency
SOPFLOWFlattenContingenciesflatten_contingencies
SOPFLOWGetNumScenariosget_num_scenarios
SOPFLOWGetNumIterationsget_num_iterations
SOPFLOWGetConvergenceStatusget_convergence_status
SOPFLOWGetTotalObjectiveget_total_objective
SOPFLOWGetConvergenceStatusget_converged_status
SOPFLOWGetToleranceget_tolerance
SOPFLOWSetUpsetup
SOPFLOWSolvesolve
SOPFLOWPrintSolutionprint_solution
SOPFLOWSaveSolutionsave_solution
SOPFLOWSaveSolutionAllsave_solution_all

TCOPFLOW

The following table assumes tcopflow = exago.TCOPFLOW().

C++ APIPython APINotes
TCOPFLOWexago.TCOPFLOW class
TCOPFLOWSetModelset_model
TCOPFLOWSetNetworkDataset_network_data
TCOPFLOWSetSolverset_solver
TCOPFLOWSetToleranceset_tolerance
TCOPFLOWSetTimeStepandDurationset_timestep_and_duration
TCOPFLOWSetLoadProfilesset_load_profiles
TCOPFLOWSetWindGenProfileswind_gen_profiles
TCOPFLOWSetupsetup
TCOPFLOWSolvesolve
TCOPFLOWGetConvergenceStatusget_convergence_status
TCOPFLOWGetObjectiveget_objective
TCOPFLOWGetNumIterationsget_num_iterations
TCOPFLOWSetToleranceset_tolerance
TCOPFLOWGetToleranceget_tolerance
TCOPFLOWPrintSolutionprint_solution
TCOPFLOWSaveSolutionsave_solution
TCOPFLOWSavesolutionAllsave_solution_all

Enums

OutputFormat is the enum that specifies the output format in functions like opflow.save_solution.

Instances can be constructed directly through the exago library (i.e. exago.OutputFormat.CSV).

OPFLOW has several type settings that are represented by enums: OPFLOWObjectiveType, OPFLOWInitializationType, and OPFLOWGenBusVoltageType.

The possible values for the current enums are as follows:

OutputFormat

  • CSV
  • MATPOWER

OPFLOWObjectiveType

  • MIN_GEN_COST
  • MIN_GENSETPOINT_DEVIATION
  • NO_OB

OPFLOWInitializationType

  • OPFLOWINIT_FROMFILE
  • OPFLOWINIT_MIDPOINT
  • OPFLOWINIT_ACPF
  • OPFLOW_FLATSTART

OPFLOWGenBusVoltageType

  • VARIABLE_WITHIN_BOUNDS
  • FIXED_WITHIN_QBOUNDS
  • FIXED_AT_SETPOINT

ContingencyFileInputFormat

  • NATIVE
  • PSSE

ScenarioFileInputFormat

  • NATIVE_SINGLEPERIOD
  • NATIVE_MULTIPERIOD

ScenarioUncertaintyType

  • NONE
  • WIND
  • LOAD

Note: getters for the possible values of ContingencyFileInputeFormat, ScenarioFileInputFormat, ScenarioUncertaintyType are not currently available

Instances can be constructed directly through the exago library (i.e. exago.OPFLOWObjectiveType.MIN_GEN_COST or exago.MIN_GEN_COST) Setter functions for these OPFLOW Type configurations can take an integer, an instance of the exago enum, or a string that describes the enum (i.e. 'MIN_GEN_COST'). The rest currently only accept an instance of the exago enum.

The possible values for these OPFLOW Type enums can be retrieved through opflow.get_xxx_types() (i.e. opflow.get_gen_bus_voltage_types()). The opflow.get_xxx_types functions yield a list of the enum values.

Below are some code examples of how to get and use these values.

Code Examples

Set with a string

>>> opflow.set_initialization_type('OPFLOWINIT_FROMFILE')
>>> opflow.get_initialization_type()
OPFLOWInitializationType.OPFLOWINIT_FROMFILE

Set with an integer

>>> opflow.set_initialization_type(1)
>>> opflow.get_initialization_type()
OPFLOWInitializationType.OPFLOWINIT_FROMFILE

Set with an enum instance

>>> opflow.set_initialization_type(exago.OPFLOWInitializationType.OPFLOWINIT_FROMFILE)
>>> opflow.get_initialization_type()
OPFLOWInitializationType.OPFLOWINIT_FROMFILE

Set via getter function:

>>> types = opflow.get_objective_types()
[<OPFLOWObjectiveType.MIN_GEN_COST: 0>, <OPFLOWObjectiveType.MIN_GENSETPOINT_DEVIATION: 1>, <OPFLOWObjectiveType.NO_OBJ: 2>]
>>> opflow.set_objective_type(types[0])
>>> opflow.get_objective_type()
OPFLOWObjectiveType.MIN_GEN_COST

See the OPFLOW testing file for more usage examples.

Building

This documentation only applies to ExaGO >=v1.2.1.

When building ExaGO, enable the CMake option EXAGO_ENABLE_PYTHON. For example,

cmake .. \
  -D... # Set other ExaGO configuration options
  -DEXAGO_ENABLE_PYTHON=ON # Make sure Python bindings are enabled
make -j 12 install

This will install the Python bindings into the installation prefix in the standard Python library suffix.

Using Python 3.8.0 on a Power9 system, ExaGO will install the Python bindings library exago.cpython-38-powerpc64le-linux-gnu.so into <install-prefix>/lib/python3.8/site-packages/exago.cpython-38-powerpc64le-linux-gnu.so

Environment

Currently ExaGO requires Python version greater than 3.6. Once Python is available in your environment (module load python), you will need to add the ExaGO Python libraries to your PYTHONPATH according to your target Python version:

# For Python 3.6
export PYTHONPATH=/<exago_install>/lib/python3.6/site-packages:$PYTHONPATH
# For Python 3.7
export PYTHONPATH=/<exago_install>/lib/python3.7/site-packages:$PYTHONPATH

For ExaGO installations in non-standard locations, the LD_LIBRARY_PATH (DYLD_LIBRARY_PATH for MacOS) will also need to point to the ExaGO install location:

# For MacOS
export DYLD_LIBRARY_PATH=/<exago_install>/lib:$DYLD_LIBRARY_PATH
# For linux
export LD_LIBRARY_PATH=/<exago_install>/lib:$LD_LIBRARY_PATH

A sample opflow script test.py is provided, with exago.prefix() providing the path to the installation directory of ExaGO. For more example usage and for the tests that cover this code, see tests/interfaces/python.

History

ExaGO pre v1.1 had optional Python bindings that could be enabled. HiOp, a critical dependency, updated to Umpire v6 when GPU and RAJA options were enabled. Because Umpire after v6 ships with CUDA device code, a final device link step was required for any libraries/executables. This drastically complicated the ctypes Python bindings, which relied on calling out to the shared library directly.

ExaGO v1.2.1 was the first version to ship Python bindings that used Pybind11, which creates a shared library directly importable from Python, which simplified the user experience and made it possible to call ExaGO from Python when only static libraries are generated.