Skip to content

Commit

Permalink
Open Rao integration (#868)
Browse files Browse the repository at this point in the history
Signed-off-by: Bertrand Rix <[email protected]>
  • Loading branch information
obrix authored Dec 17, 2024
1 parent d980e81 commit cb622d2
Show file tree
Hide file tree
Showing 24 changed files with 1,097 additions and 20 deletions.
20 changes: 20 additions & 0 deletions cpp/powsybl-cpp/powsybl-cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1647,4 +1647,24 @@ JavaHandle runVoltageInitializer(bool debug, const JavaHandle& networkHandle, co
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::runVoltageInitializer, debug, networkHandle, paramsHandle);
}

JavaHandle createRao() {
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::createRao);
}

RaoComputationStatus getRaoResultStatus(const JavaHandle& raoResult) {
return pypowsybl::PowsyblCaller::get()->callJava<RaoComputationStatus>(::getRaoResultStatus, raoResult);
}

JavaHandle getCrac(const JavaHandle& raoContext) {
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::getCrac, raoContext);
}

JavaHandle getRaoResult(const JavaHandle& raoContext) {
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::getRaoResult, raoContext);
}

JavaHandle createDefaultRaoParameters() {
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::createDefaultRaoParameters);
}

}
7 changes: 7 additions & 0 deletions cpp/powsybl-cpp/powsybl-cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -845,5 +845,12 @@ SeriesArray* getFeederResults(const JavaHandle& shortCircuitAnalysisResult, bool
SeriesArray* getShortCircuitLimitViolations(const JavaHandle& shortCircuitAnalysisResult);
SeriesArray* getShortCircuitBusResults(const JavaHandle& shortCircuitAnalysisResult, bool withFortescueResult);

// OpenRao
JavaHandle createRao();
JavaHandle getCrac(const JavaHandle& raoContext);
JavaHandle getRaoResult(const JavaHandle& raoContext);
RaoComputationStatus getRaoResultStatus(const JavaHandle& raoResult);
JavaHandle createDefaultRaoParameters();

}
#endif //PYPOWSYBL_H
3 changes: 1 addition & 2 deletions cpp/pypowsybl-cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ include_directories(${POWSYBL_CPP_SOURCE_DIR} ${PYPOWSYBL_JAVA_SOURCE_DIR} ${PYP
link_directories(${PYPOWSYBL_JAVA_LIBRARY_DIR})
pybind11_add_module(_pypowsybl pylogging.cpp bindings.cpp)

add_dependencies(_pypowsybl native-image math-native)
add_dependencies(math-native native-image)
add_dependencies(_pypowsybl native-image)

# Fix related to issue describred here https://github.com/actions/runner-images/issues/10004#issuecomment-2156109231
# Should fix incompatibility between MSVC runtime 14.40.XXX and previous version
Expand Down
70 changes: 69 additions & 1 deletion cpp/pypowsybl-cpp/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ pypowsybl::JavaHandle loadNetworkFromBinaryBuffersPython(std::vector<py::buffer>

py::bytes saveNetworkToBinaryBufferPython(const pypowsybl::JavaHandle& network, const std::string& format, const std::map<std::string, std::string>& parameters, pypowsybl::JavaHandle* reportNode);

void setCracSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& crac);
void setGlskSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& glsk);
void runRaoWithParameters(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const pypowsybl::JavaHandle& parametersHandle);
pypowsybl::JavaHandle loadRaoParametersFromBuffer(const py::buffer& parameters);

py::bytes saveRaoParametersToBinaryBuffer(const pypowsybl::JavaHandle& rao_parameters);
py::bytes saveRaoResultsToBinaryBuffer(const pypowsybl::JavaHandle& raoContext, const pypowsybl::JavaHandle& crac);

template<typename T>
void bindArray(py::module_& m, const std::string& className) {
py::class_<T>(m, className.c_str())
Expand Down Expand Up @@ -711,6 +719,10 @@ PYBIND11_MODULE(_pypowsybl, m) {
.value("ANY_VIOLATION_CONDITION", condition_type::ANY_VIOLATION_CONDITION)
.value("AT_LEAST_ONE_VIOLATION_CONDITION", condition_type::AT_LEAST_ONE_VIOLATION_CONDITION);

py::enum_<RaoComputationStatus>(m, "RaoComputationStatus")
.value("DEFAULT", RaoComputationStatus::DEFAULT)
.value("FAILURE", RaoComputationStatus::FAILURE);

py::class_<network_metadata, std::shared_ptr<network_metadata>>(m, "NetworkMetadata")
.def_property_readonly("id", [](const network_metadata& att) {
return att.id;
Expand Down Expand Up @@ -1091,6 +1103,21 @@ PYBIND11_MODULE(_pypowsybl, m) {
m.def("get_short_circuit_limit_violations", &pypowsybl::getShortCircuitLimitViolations, "gets the limit violations of a short-circuit analysis", py::arg("result"));
m.def("get_short_circuit_bus_results", &pypowsybl::getShortCircuitBusResults, "gets the bus results of a short-circuit analysis", py::arg("result"), py::arg("with_fortescue_result"));

m.def("create_rao", &pypowsybl::createRao, "Create rao context");
m.def("run_rao", ::runRaoWithParameters, py::call_guard<py::gil_scoped_release>(), "Run a rao from buffered inputs",
py::arg("network"), py::arg("rao_context"), py::arg("parameters"));
m.def("set_crac_source", ::setCracSource, py::call_guard<py::gil_scoped_release>(), "Set crac source",
py::arg("network"), py::arg("rao_context"), py::arg("crac_source"));
m.def("set_glsk_source", ::setGlskSource, py::call_guard<py::gil_scoped_release>(), "Set glsk source",
py::arg("network"), py::arg("rao_context"), py::arg("glsk_source"));
m.def("get_crac", &pypowsybl::getCrac, "Get crac associated to the rao context", py::arg("rao_context"));
m.def("get_rao_result", &pypowsybl::getRaoResult, "Get rao result associated to the rao context", py::arg("rao_context"));
m.def("create_default_rao_parameters", &pypowsybl::createDefaultRaoParameters, "Create a default rao parameter");
m.def("load_rao_parameters", ::loadRaoParametersFromBuffer, "Load rao parameters from a buffer", py::arg("parameters_buffer"));
m.def("serialize_rao_parameters", ::saveRaoParametersToBinaryBuffer, "Serialize rao parameters to a buffer", py::arg("rao_parameters"));
m.def("serialize_rao_results_to_buffer", ::saveRaoResultsToBinaryBuffer, "Run a rao", py::arg("rao_result"), py::arg("crac"));
m.def("get_rao_result_status", &pypowsybl::getRaoResultStatus, "Get the status of a rao result", py::arg("rao_result"));

}

void setLogLevelFromPythonLogger(pypowsybl::GraalVmGuard* guard, exception_handler* exc) {
Expand Down Expand Up @@ -1146,6 +1173,47 @@ py::bytes saveNetworkToBinaryBufferPython(const pypowsybl::JavaHandle& network,
parameterValuesPtr.get(), parameterValues.size(), reportNode == nullptr ? nullptr : *reportNode);
py::gil_scoped_acquire acquire;
py::bytes bytes((char*) byteArray->ptr, byteArray->length);
pypowsybl::PowsyblCaller::get()->callJava<>(::freeNetworkBinaryBuffer, byteArray);
pypowsybl::PowsyblCaller::get()->callJava<>(::freeBinaryBuffer, byteArray);
return bytes;
}

void setCracSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& crac) {
py::buffer_info cracInfo = crac.request();
pypowsybl::PowsyblCaller::get()->callJava<>(::setCracBufferedSource,
networkHandle, raoHandle, static_cast<char*>(cracInfo.ptr), cracInfo.size);
}

void setGlskSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& glsk) {
py::buffer_info glskInfo = glsk.request();
pypowsybl::PowsyblCaller::get()->callJava<>(::setGlskBufferedSource,
networkHandle, raoHandle,
static_cast<char*>(glskInfo.ptr), glskInfo.size);
}

void runRaoWithParameters(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const pypowsybl::JavaHandle& parametersHandle) {
pypowsybl::PowsyblCaller::get()->callJava<>(::runRao,
networkHandle, raoHandle, parametersHandle);
}

py::bytes saveRaoResultsToBinaryBuffer(const pypowsybl::JavaHandle& raoResult, const pypowsybl::JavaHandle& crac) {
array* byteArray = pypowsybl::PowsyblCaller::get()->callJava<array*>(::serializeRaoResultsToBuffer, raoResult, crac);
py::gil_scoped_acquire acquire;
py::bytes bytes((char*) byteArray->ptr, byteArray->length);
pypowsybl::PowsyblCaller::get()->callJava<>(::freeBinaryBuffer, byteArray);
return bytes;
}

pypowsybl::JavaHandle loadRaoParametersFromBuffer(const py::buffer& parameters) {
py::buffer_info parametersInfo = parameters.request();
return pypowsybl::PowsyblCaller::get()->callJava<pypowsybl::JavaHandle>(::loadRaoParameters,
static_cast<char*>(parametersInfo.ptr), parametersInfo.size);
}

py::bytes saveRaoParametersToBinaryBuffer(const pypowsybl::JavaHandle& rao_parameters) {
array* byteArray = pypowsybl::PowsyblCaller::get()->callJava<array*>(::serializeRaoParameters, rao_parameters);
py::gil_scoped_acquire acquire;
py::bytes bytes((char*) byteArray->ptr, byteArray->length);
pypowsybl::PowsyblCaller::get()->callJava<>(::freeBinaryBuffer, byteArray);
return bytes;
}

40 changes: 28 additions & 12 deletions cpp/pypowsybl-java/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,43 @@ set(PYPOWSYBL_JAVA_LIB ${CMAKE_SHARED_LIBRARY_PREFIX}pypowsybl-java${CMAKE_SHARE

if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
set(OS_BITS 64)
set(ARCH_ID "x86-64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64")
set(OS_BITS arm64)
set(ARCH_ID "aarch64")
else()
set(OS_BITS 32)
set(ARCH_ID "x86-32")
endif()

# extract needed native libraries from jar for current platform
# jars have been previously copied by maven build
macro(extract_and_install_native_lib jar_file jar_entry library_file)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(NATIVE_LIB_INSTALL_EXTRA_COMMAND COMMAND install_name_tool -id @loader_path/${library_file} ${CMAKE_CURRENT_BINARY_DIR}/${jar_entry}/${library_file})
endif()

add_custom_target(native-install-${library_file} ALL COMMAND ${CMAKE_COMMAND} -E tar x ${jar_file} ${jar_entry}/${library_file} ${NATIVE_LIB_INSTALL_EXTRA_COMMAND})
add_dependencies(native-install-${library_file} mvn)
if(DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
add_custom_command(TARGET native-install-${library_file} POST_BUILD ${POWSYBL_CPP_INSTALL_EXTRA_COMMAND} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${jar_entry}/${library_file} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
endif()
endmacro()

set(math-native-jar ${PYPOWSYBL_JAVA_SRC_DIR}/target/dependency/powsybl-math-native.jar)
set(ortools-jar ${PYPOWSYBL_JAVA_SRC_DIR}/target/dependency/ortools-${CMAKE_SYSTEM_NAME}-${ARCH_ID}.jar)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(POWSYBL_MATH_NATIVE_LIB math.dll)
set(POWSYBL_MATH_NATIVE_JAR_ENTRY_DIR natives/windows_${OS_BITS})
extract_and_install_native_lib(${math-native-jar} natives/windows_${OS_BITS} math.dll)
extract_and_install_native_lib(${ortools-jar} ortools-win32-${ARCH_ID} jniortools.dll)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(POWSYBL_MATH_NATIVE_LIB libmath.so)
set(POWSYBL_MATH_NATIVE_JAR_ENTRY_DIR natives/linux_${OS_BITS})
extract_and_install_native_lib(${math-native-jar} natives/linux_${OS_BITS} libmath.so)
extract_and_install_native_lib(${ortools-jar} ortools-linux-${ARCH_ID} libjniortools.so)
extract_and_install_native_lib(${ortools-jar} ortools-linux-${ARCH_ID} libortools.so.9)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(POWSYBL_MATH_NATIVE_LIB libmath.dylib)
set(POWSYBL_MATH_NATIVE_JAR_ENTRY_DIR natives/osx_${OS_BITS})
extract_and_install_native_lib(${math-native-jar} natives/osx_${OS_BITS} libmath.dylib)
extract_and_install_native_lib(${ortools-jar} ortools-darwin-${ARCH_ID} libjniortools.dylib)
extract_and_install_native_lib(${ortools-jar} ortools-darwin-${ARCH_ID} libortools.9.dylib)
else()
message(FATAL_ERROR "System not supported: ${CMAKE_SYSTEM_NAME}")
endif()
Expand All @@ -44,7 +66,6 @@ endif()
# linking with our shared library
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(NATIVE_IMAGE_INSTALL_EXTRA_COMMAND COMMAND install_name_tool -id @loader_path/${PYPOWSYBL_JAVA_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB})
set(MATH_NATIVE_INSTALL_EXTRA_COMMAND COMMAND install_name_tool -id @loader_path/${POWSYBL_MATH_NATIVE_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${POWSYBL_MATH_NATIVE_JAR_ENTRY_DIR}/${POWSYBL_MATH_NATIVE_LIB})
endif()

ExternalProject_Add(mvn
Expand Down Expand Up @@ -78,11 +99,6 @@ ExternalProject_Add(native-image
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_OLD_LIB} ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${NATIVE_IMAGE_INSTALL_EXTRA_COMMAND}
)

# extract powsybl math native from jar for current platform
# powsybl-math-native.jar has been previously copied by maven build
add_custom_target(math-native ALL COMMAND ${CMAKE_COMMAND} -E tar x ${PYPOWSYBL_JAVA_SRC_DIR}/target/dependency/powsybl-math-native.jar ${POWSYBL_MATH_NATIVE_JAR_ENTRY_DIR}/${POWSYBL_MATH_NATIVE_LIB} ${MATH_NATIVE_INSTALL_EXTRA_COMMAND})

if(DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
add_custom_command(TARGET native-image POST_BUILD ${POWSYBL_CPP_INSTALL_EXTRA_COMMAND} COMMAND ${CMAKE_COMMAND} -E copy ${PYPOWSYBL_JAVA_BIN_DIR}/${PYPOWSYBL_JAVA_LIB} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
add_custom_command(TARGET math-native POST_BUILD ${POWSYBL_CPP_INSTALL_EXTRA_COMMAND} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${POWSYBL_MATH_NATIVE_JAR_ENTRY_DIR}/${POWSYBL_MATH_NATIVE_LIB} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
endif(DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
5 changes: 5 additions & 0 deletions cpp/pypowsybl-java/powsybl-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,3 +456,8 @@ typedef enum {
NO_GENERATION,
ALL_BUSES,
} VoltageInitializerReactiveSlackBusesMode;

typedef enum {
DEFAULT = 0,
FAILURE,
} RaoComputationStatus;
Loading

0 comments on commit cb622d2

Please sign in to comment.