diff --git a/cpp/powsybl-cpp/powsybl-api.h b/cpp/powsybl-cpp/powsybl-api.h index d1eab1ba1a..834db3d0e8 100644 --- a/cpp/powsybl-cpp/powsybl-api.h +++ b/cpp/powsybl-cpp/powsybl-api.h @@ -314,6 +314,7 @@ typedef struct { typedef struct zone_struct { char* id; char** injections_ids; + int injections_ids_count; double* injections_shift_keys; int length; } zone; diff --git a/cpp/powsybl-cpp/powsybl-cpp.cpp b/cpp/powsybl-cpp/powsybl-cpp.cpp index f1bc033254..5f7afa5749 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.cpp +++ b/cpp/powsybl-cpp/powsybl-cpp.cpp @@ -172,14 +172,14 @@ std::map convertMapStructToStdMap(string_map* map) { } char* copyStringToCharPtr(const std::string& str) { - char* c = new char[str.size() + 1]; + char* c = initializeCharPointer(str.size() + 1); str.copy(c, str.size()); c[str.size()] = '\0'; return c; } char** copyVectorStringToCharPtrPtr(const std::vector& strings) { - char** charPtrPtr = new char*[strings.size()]; + char** charPtrPtr = initializeCharPointerPointer(strings.size()); for (int i = 0; i < strings.size(); i++) { charPtrPtr[i] = copyStringToCharPtr(strings[i]); } @@ -187,22 +187,19 @@ char** copyVectorStringToCharPtrPtr(const std::vector& strings) { } int* copyVectorInt(const std::vector& ints) { - int* intPtr = new int[ints.size()]; + int* intPtr = initializeIntPointer(ints.size()); std::copy(ints.begin(), ints.end(), intPtr); return intPtr; } double* copyVectorDouble(const std::vector& doubles) { - double* doublePtr = new double[doubles.size()]; + double* doublePtr = initializeDoublePointer(doubles.size()); std::copy(doubles.begin(), doubles.end(), doublePtr); return doublePtr; } void deleteCharPtrPtr(char** charPtrPtr, int length) { - for (int i = 0; i < length; i++) { - delete[] charPtrPtr[i]; - } - delete[] charPtrPtr; + freeCharPointerPointer(charPtrPtr); } void freeCString(char* str) { @@ -221,12 +218,6 @@ void copyCharPtrPtrToVector(char** src, int count, std::vector& des std::copy(src, src + count, std::back_inserter(dest)); } -void deleteLoadFlowParameters(loadflow_parameters* ptr) { - pypowsybl::deleteCharPtrPtr(ptr->countries_to_balance, ptr->countries_to_balance_count); - pypowsybl::deleteCharPtrPtr(ptr->provider_parameters_keys, ptr->provider_parameters_keys_count); - pypowsybl::deleteCharPtrPtr(ptr->provider_parameters_values, ptr->provider_parameters_values_count); -} - LoadFlowParameters::LoadFlowParameters(loadflow_parameters* src) { voltage_init_mode = static_cast(src->voltage_init_mode); transformer_voltage_control_on = (bool) src->transformer_voltage_control_on; @@ -269,19 +260,14 @@ void LoadFlowParameters::load_to_c_struct(loadflow_parameters& res) const { } std::shared_ptr LoadFlowParameters::to_c_struct() const { - loadflow_parameters* res = new loadflow_parameters(); + loadflow_parameters* res = PowsyblCaller::get()->callJava(::createLoadFlowParameters); load_to_c_struct(*res); //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](loadflow_parameters* ptr){ - deleteLoadFlowParameters(ptr); - delete ptr; + PowsyblCaller::get()->callJava(::freeLoadFlowParameters, ptr); }); } -void deleteLoadFlowValidationParameters(loadflow_validation_parameters* ptr) { - deleteLoadFlowParameters(&ptr->loadflow_parameters); -} - LoadFlowValidationParameters::LoadFlowValidationParameters(loadflow_validation_parameters* src): loadflow_parameters(&src->loadflow_parameters) { @@ -311,22 +297,15 @@ void LoadFlowValidationParameters::load_to_c_struct(loadflow_validation_paramete } std::shared_ptr LoadFlowValidationParameters::to_c_struct() const { - loadflow_validation_parameters* res = new loadflow_validation_parameters(); + loadflow_validation_parameters* res = PowsyblCaller::get()->callJava(::createValidationConfig); loadflow_parameters.load_to_c_struct(res->loadflow_parameters); load_to_c_struct(*res); //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](loadflow_validation_parameters* ptr){ - deleteLoadFlowValidationParameters(ptr); - delete ptr; + PowsyblCaller::get()->callJava(::freeValidationConfig, ptr); }); } -void deleteSecurityAnalysisParameters(security_analysis_parameters* ptr) { - deleteLoadFlowParameters(&ptr->loadflow_parameters); - pypowsybl::deleteCharPtrPtr(ptr->provider_parameters_keys, ptr->provider_parameters_keys_count); - pypowsybl::deleteCharPtrPtr(ptr->provider_parameters_values, ptr->provider_parameters_values_count); -} - SecurityAnalysisParameters::SecurityAnalysisParameters(security_analysis_parameters* src): loadflow_parameters(&src->loadflow_parameters) { @@ -340,7 +319,7 @@ SecurityAnalysisParameters::SecurityAnalysisParameters(security_analysis_paramet } std::shared_ptr SecurityAnalysisParameters::to_c_struct() const { - security_analysis_parameters* res = new security_analysis_parameters(); + security_analysis_parameters* res = PowsyblCaller::get()->callJava(::createSecurityAnalysisParameters); loadflow_parameters.load_to_c_struct(res->loadflow_parameters); res->flow_proportional_threshold = (double) flow_proportional_threshold; res->low_voltage_proportional_threshold = (double) low_voltage_proportional_threshold; @@ -353,17 +332,10 @@ std::shared_ptr SecurityAnalysisParameters::to_c_s res->provider_parameters_values_count = provider_parameters_values.size(); //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](security_analysis_parameters* ptr){ - deleteSecurityAnalysisParameters(ptr); - delete ptr; + PowsyblCaller::get()->callJava(::freeSecurityAnalysisParameters, ptr); }); } -void deleteSensitivityAnalysisParameters(sensitivity_analysis_parameters* ptr) { - deleteLoadFlowParameters(&ptr->loadflow_parameters); - pypowsybl::deleteCharPtrPtr(ptr->provider_parameters_keys, ptr->provider_parameters_keys_count); - pypowsybl::deleteCharPtrPtr(ptr->provider_parameters_values, ptr->provider_parameters_values_count); -} - SensitivityAnalysisParameters::SensitivityAnalysisParameters(sensitivity_analysis_parameters* src): loadflow_parameters(&src->loadflow_parameters) { @@ -372,7 +344,7 @@ SensitivityAnalysisParameters::SensitivityAnalysisParameters(sensitivity_analysi } std::shared_ptr SensitivityAnalysisParameters::to_c_struct() const { - sensitivity_analysis_parameters* res = new sensitivity_analysis_parameters(); + sensitivity_analysis_parameters* res = PowsyblCaller::get()->callJava(::createSensitivityAnalysisParameters); loadflow_parameters.load_to_c_struct(res->loadflow_parameters); res->provider_parameters_keys = pypowsybl::copyVectorStringToCharPtrPtr(provider_parameters_keys); res->provider_parameters_keys_count = provider_parameters_keys.size(); @@ -380,8 +352,7 @@ std::shared_ptr SensitivityAnalysisParameters:: res->provider_parameters_values_count = provider_parameters_values.size(); //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](sensitivity_analysis_parameters* ptr){ - deleteSensitivityAnalysisParameters(ptr); - delete ptr; + PowsyblCaller::get()->callJava(::freeSensitivityAnalysisParameters, ptr); }); } @@ -395,7 +366,7 @@ FlowDecompositionParameters::FlowDecompositionParameters(flow_decomposition_para } std::shared_ptr FlowDecompositionParameters::to_c_struct() const { - flow_decomposition_parameters* res = new flow_decomposition_parameters(); + flow_decomposition_parameters* res = PowsyblCaller::get()->callJava(::createFlowDecompositionParameters); res->enable_losses_compensation = (unsigned char) enable_losses_compensation; res->losses_compensation_epsilon = losses_compensation_epsilon; res->sensitivity_epsilon = sensitivity_epsilon; @@ -404,7 +375,7 @@ std::shared_ptr FlowDecompositionParameters::to_c res->sensitivity_variable_batch_size = (int) sensitivity_variable_batch_size; //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](flow_decomposition_parameters* ptr){ - delete ptr; + PowsyblCaller::get()->callJava(::freeFlowDecompositionParameters, ptr); }); } @@ -790,14 +761,15 @@ void addOperatorStrategy(const JavaHandle& analysisContext, std::string operator } ::zone* createZone(const std::string& id, const std::vector& injectionsIds, const std::vector& injectionsShiftKeys) { - auto z = new ::zone; + auto z = PowsyblCaller::get()->callJava(::createZonePointer); z->id = copyStringToCharPtr(id); z->length = injectionsIds.size(); - z->injections_ids = new char*[injectionsIds.size()]; + z->injections_ids = initializeCharPointerPointer(injectionsIds.size()); + z->injections_ids_count = injectionsIds.size(); for (int i = 0; i < injectionsIds.size(); i++) { z->injections_ids[i] = copyStringToCharPtr(injectionsIds[i]); } - z->injections_shift_keys = new double[injectionsShiftKeys.size()]; + z->injections_shift_keys = initializeDoublePointer(injectionsShiftKeys.size()); for (int i = 0; i < injectionsIds.size(); i++) { z->injections_shift_keys[i] = injectionsShiftKeys[i]; } @@ -805,12 +777,9 @@ ::zone* createZone(const std::string& id, const std::vector& inject } void deleteZone(::zone* z) { - delete[] z->id; - for (int i = 0; i < z->length; i++) { - delete[] z->injections_ids[i]; - } - delete[] z->injections_ids; - delete[] z->injections_shift_keys; + freeCharPointer(z->id); + freeCharPointerPointer(z->injections_ids); + freeDoublePointer(z->injections_shift_keys); } class ZonesPtr { @@ -1246,20 +1215,20 @@ void NadParameters::nad_to_c_struct(nad_parameters& res) const { } std::shared_ptr SldParameters::to_c_struct() const { - sld_parameters* res = new sld_parameters(); + sld_parameters* res = PowsyblCaller::get()->callJava(::createSldParameters); sld_to_c_struct(*res); //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](sld_parameters* ptr){ - delete ptr; + PowsyblCaller::get()->callJava(::freeSldParameters, ptr); }); } std::shared_ptr NadParameters::to_c_struct() const { - nad_parameters* res = new nad_parameters(); + nad_parameters* res = PowsyblCaller::get()->callJava(::createNadParameters); nad_to_c_struct(*res); //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](nad_parameters* ptr){ - delete ptr; + PowsyblCaller::get()->callJava(::freeNadParameters, ptr); }); } @@ -1381,7 +1350,7 @@ ShortCircuitAnalysisParameters::ShortCircuitAnalysisParameters(shortcircuit_anal } std::shared_ptr ShortCircuitAnalysisParameters::to_c_struct() const { - shortcircuit_analysis_parameters* res = new shortcircuit_analysis_parameters(); + shortcircuit_analysis_parameters* res = PowsyblCaller::get()->callJava(::createShortCircuitAnalysisParameters); res->with_voltage_result = (bool) with_voltage_result; res->with_feeder_result = (bool) with_feeder_result; res->with_limit_violations = (bool) with_limit_violations; @@ -1394,10 +1363,9 @@ std::shared_ptr ShortCircuitAnalysisParameters res->provider_parameters_values = pypowsybl::copyVectorStringToCharPtrPtr(provider_parameters_values); res->provider_parameters_values_count = provider_parameters_values.size(); - //Memory has been allocated here on C side, we need to clean it up on C side (not java side) return std::shared_ptr(res, [](shortcircuit_analysis_parameters* ptr){ deleteShortCircuitAnalysisParameters(ptr); - delete ptr; + PowsyblCaller::get()->callJava(::freeShortCircuitAnalysisParameters, ptr); }); } @@ -1596,4 +1564,60 @@ JavaHandle runVoltageInitializer(bool debug, const JavaHandle& networkHandle, co return pypowsybl::PowsyblCaller::get()->callJava(::runVoltageInitializer, debug, networkHandle, paramsHandle); } +SeriesArray* initializeSeriesArrayObject(int columnsNumber) { + return new SeriesArray(pypowsybl::PowsyblCaller::get()->callJava(::initializeSeriesArray, columnsNumber)); +} + +DataframesArray* initializeDataframesArray(int columnsNumber) { + return new DataframesArray(pypowsybl::PowsyblCaller::get()->callJava(::initializeDataframeArray, columnsNumber)); +} + +char** initializeCharPointerPointer(int size) { + return pypowsybl::PowsyblCaller::get()->callJava(::initializeCharCharPointer, size); +} + +void freeCharPointerPointer(char** charPointerPointer) { + pypowsybl::PowsyblCaller::get()->callJava(::freeCharCharPointer, charPointerPointer); +} + +char* initializeCharPointer(int size) { + return pypowsybl::PowsyblCaller::get()->callJava(::initializeCharPointer, size); +} + +void freeCharPointer(char* charPointer) { + pypowsybl::PowsyblCaller::get()->callJava(::freeCharPointer, charPointer); +} + +int* initializeIntPointer(int size) { + return pypowsybl::PowsyblCaller::get()->callJava(::initializeIntPointer, size); +} + +void freeIntPointer(int* intPointer) { + pypowsybl::PowsyblCaller::get()->callJava(::freeIntPointer, intPointer); +} + +double* initializeDoublePointer(double size) { + return pypowsybl::PowsyblCaller::get()->callJava(::initializeDoublePointer, size); +} + +void freeDoublePointer(double* doublePointer) { + pypowsybl::PowsyblCaller::get()->callJava(::freeDoublePointer, doublePointer); +} + +dataframe* initializeDataframePointer() { + return pypowsybl::PowsyblCaller::get()->callJava(::initializeDataframePointer); +} + +void freeDataframePointer(dataframe* dataframe) { + pypowsybl::PowsyblCaller::get()->callJava(::freeDataframePointer, dataframe); +} + +dataframe_array* initializeDataframeArrayPointer() { + return pypowsybl::PowsyblCaller::get()->callJava(::initializeDataframeArrayObject); +} + +void freeDataframeArrayPointer(dataframe_array* dataframe_array) { + pypowsybl::PowsyblCaller::get()->callJava(::freeDataframeArrayObject, dataframe_array); +} + } diff --git a/cpp/powsybl-cpp/powsybl-cpp.h b/cpp/powsybl-cpp/powsybl-cpp.h index 8fdcc2b3d2..203745f396 100644 --- a/cpp/powsybl-cpp/powsybl-cpp.h +++ b/cpp/powsybl-cpp/powsybl-cpp.h @@ -190,6 +190,7 @@ typedef Array PostContingencyResultArray; typedef Array OperatorStrategyResultArray; typedef Array LimitViolationArray; typedef Array SeriesArray; +typedef Array DataframesArray; template @@ -816,6 +817,19 @@ SeriesArray* getFaultResults(const JavaHandle& shortCircuitAnalysisResult, bool SeriesArray* getFeederResults(const JavaHandle& shortCircuitAnalysisResult, bool withFortescueResult); SeriesArray* getShortCircuitLimitViolations(const JavaHandle& shortCircuitAnalysisResult); SeriesArray* getShortCircuitBusResults(const JavaHandle& shortCircuitAnalysisResult, bool withFortescueResult); - +SeriesArray* initializeSeriesArrayObject(int columnsNumber); +DataframesArray* initializeDataframesArray(int columnsNumber); +char** initializeCharPointerPointer(int size); +void freeCharPointerPointer(char** charPointerPointer); +char* initializeCharPointer(int size); +void freeCharPointer(char* charPointer); +int* initializeIntPointer(int size); +void freeIntPointer(int* intPointer); +double* initializeDoublePointer(double size); +void freeDoublePointer(double* doublePointer); +dataframe* initializeDataframePointer(); +void freeDataframePointer(dataframe* dataframe); +dataframe_array* initializeDataframeArrayPointer(); +void freeDataframeArrayPointer(dataframe_array* dataframe_array); } #endif //PYPOWSYBL_H diff --git a/cpp/pypowsybl-cpp/bindings.cpp b/cpp/pypowsybl-cpp/bindings.cpp index ea374fbfd8..dfb59fd2b1 100644 --- a/cpp/pypowsybl-cpp/bindings.cpp +++ b/cpp/pypowsybl-cpp/bindings.cpp @@ -44,25 +44,13 @@ void bindArray(py::module_& m, const std::string& className) { } void deleteDataframe(dataframe* df) { - for (int indice = 0 ; indice < df->series_count; indice ++) { - series* column = df->series + indice; - if (column->type == 0) { - pypowsybl::deleteCharPtrPtr((char**) column->data.ptr, column->data.length); - } else if (column->type == 1) { - delete[] (double*) column->data.ptr; - } else if (column->type == 2 || column->type == 3) { - delete[] (int*) column->data.ptr; - } - delete[] column->name; - } - delete[] df->series; - delete df; + pypowsybl::freeDataframePointer(df); } std::shared_ptr createDataframe(py::list columnsValues, const std::vector& columnsNames, const std::vector& columnsTypes, const std::vector& isIndex) { int columnsNumber = columnsNames.size(); - std::shared_ptr dataframe(new ::dataframe(), ::deleteDataframe); - series* columns = new series[columnsNumber]; + std::shared_ptr dataframe(pypowsybl::initializeDataframePointer(), ::deleteDataframe); + series* columns = pypowsybl::initializeSeriesArrayObject(columnsNumber)->begin(); for (int indice = 0 ; indice < columnsNumber ; indice ++ ) { series* column = columns + indice; py::str name = (py::str) columnsNames[indice]; @@ -105,12 +93,13 @@ std::shared_ptr createDataframe(py::list columnsValues, const std::ve return dataframe; } +void deleteDataframeArrayObject(dataframe_array* df) { + pypowsybl::freeDataframeArrayPointer(df); +} + std::shared_ptr createDataframeArray(const std::vector& dataframes) { - std::shared_ptr dataframeArray(new dataframe_array(), [](dataframe_array* dataframeToDestroy){ - delete[] dataframeToDestroy->dataframes; - delete dataframeToDestroy; - }); - dataframe* dataframesFinal = new dataframe[dataframes.size()]; + std::shared_ptr dataframeArray(pypowsybl::initializeDataframeArrayPointer(), ::deleteDataframeArrayObject); + dataframe* dataframesFinal = pypowsybl::initializeDataframesArray(dataframes.size())->begin(); for (int indice = 0 ; indice < dataframes.size() ; indice ++) { dataframesFinal[indice] = *dataframes[indice]; } @@ -1053,8 +1042,8 @@ pypowsybl::JavaHandle loadNetworkFromBinaryBuffersPython(std::vector pypowsybl::ToCharPtrPtr parameterNamesPtr(parameterNames); pypowsybl::ToCharPtrPtr parameterValuesPtr(parameterValues); - char** dataPtrs = new char*[byteBuffers.size()]; - int* dataSizes = new int[byteBuffers.size()]; + char** dataPtrs = pypowsybl::initializeCharPointerPointer(byteBuffers.size()); + int* dataSizes = pypowsybl::initializeIntPointer(byteBuffers.size()); for(int i=0; i < byteBuffers.size(); ++i) { py::buffer_info info = byteBuffers[i].request(); dataPtrs[i] = static_cast(info.ptr); @@ -1064,8 +1053,8 @@ pypowsybl::JavaHandle loadNetworkFromBinaryBuffersPython(std::vector pypowsybl::JavaHandle networkHandle = pypowsybl::PowsyblCaller::get()->callJava(::loadNetworkFromBinaryBuffers, dataPtrs, dataSizes, byteBuffers.size(), parameterNamesPtr.get(), parameterNames.size(), parameterValuesPtr.get(), parameterValues.size(), (reportNode == nullptr) ? nullptr : *reportNode); - delete[] dataPtrs; - delete[] dataSizes; + pypowsybl::freeCharPointerPointer(dataPtrs); + pypowsybl::freeIntPointer(dataSizes); return networkHandle; } diff --git a/java/src/main/java/com/powsybl/python/InternCFunctions.java b/java/src/main/java/com/powsybl/python/InternCFunctions.java new file mode 100644 index 0000000000..963bfe9857 --- /dev/null +++ b/java/src/main/java/com/powsybl/python/InternCFunctions.java @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.python; + +import com.powsybl.python.commons.Directives; +import com.powsybl.python.commons.PyPowsyblApiHeader; +import org.graalvm.nativeimage.IsolateThread; +import org.graalvm.nativeimage.UnmanagedMemory; +import org.graalvm.nativeimage.c.CContext; +import org.graalvm.nativeimage.c.function.CEntryPoint; +import org.graalvm.nativeimage.c.struct.SizeOf; +import org.graalvm.nativeimage.c.type.CCharPointer; +import org.graalvm.nativeimage.c.type.CCharPointerPointer; +import org.graalvm.nativeimage.c.type.CDoublePointer; +import org.graalvm.nativeimage.c.type.CIntPointer; + +import static com.powsybl.python.commons.Util.doCatch; + +/** + * Defines the basic C functions for a network. + * + * @author Etienne Lesot + */ +@CContext(Directives.class) +public final class InternCFunctions { + + private InternCFunctions() { + } + + @CEntryPoint(name = "initializeSeriesArray") + public static PyPowsyblApiHeader.ArrayPointer initializeSeriesArray(IsolateThread thread, + int seriesCount, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> { + PyPowsyblApiHeader.SeriesPointer seriesPtr = UnmanagedMemory.calloc(seriesCount * SizeOf.get(PyPowsyblApiHeader.SeriesPointer.class)); + return PyPowsyblApiHeader.allocArrayPointer(seriesPtr, seriesCount); + }); + } + + @CEntryPoint(name = "initializeDataframeArray") + public static PyPowsyblApiHeader.ArrayPointer initializeDataframeArray(IsolateThread thread, + int dataframesCount, + PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> { + PyPowsyblApiHeader.DataframePointer seriesPtr = UnmanagedMemory.calloc(dataframesCount * SizeOf.get(PyPowsyblApiHeader.DataframePointer.class)); + return PyPowsyblApiHeader.allocArrayPointer(seriesPtr, dataframesCount); + }); + } + + @CEntryPoint(name = "initializeDataframeArrayObject") + public static PyPowsyblApiHeader.DataframeArrayPointer initializeDataframeArrayObject(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.calloc(SizeOf.get(PyPowsyblApiHeader.DataframeArrayPointer.class))); + } + + @CEntryPoint(name = "freeDataframeArrayObject") + public static void freeDataframeArray(IsolateThread thread, PyPowsyblApiHeader.DataframeArrayPointer cDataframeArray, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(cDataframeArray)); + } + + @CEntryPoint(name = "initializeDataframePointer") + public static PyPowsyblApiHeader.DataframePointer initializeDataframePointer(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.calloc(SizeOf.get(PyPowsyblApiHeader.DataframePointer.class))); + } + + @CEntryPoint(name = "freeDataframePointer") + public static void freeDataframePointer(IsolateThread thread, PyPowsyblApiHeader.DataframePointer cDataframe, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + doCatch(exceptionHandlerPtr, () -> { + freeDataframeContent(cDataframe); + UnmanagedMemory.free(cDataframe); + }); + } + + private static void freeDataframeContent(PyPowsyblApiHeader.DataframePointer dataframePointer) { + for (int i = 0; i < dataframePointer.getSeriesCount(); i++) { + PyPowsyblApiHeader.SeriesPointer attrMetadata = dataframePointer.getSeries().addressOf(i); + UnmanagedMemory.free(attrMetadata.getName()); + } + UnmanagedMemory.free(dataframePointer.getSeries()); + } + + @CEntryPoint(name = "initializeCharCharPointer") + public static CCharPointerPointer initializeCharCharPointer(IsolateThread thread, int size, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.calloc(size * SizeOf.get(CCharPointerPointer.class))); + } + + @CEntryPoint(name = "freeCharCharPointer") + public static void freeCharCharPointer(IsolateThread thread, CCharPointerPointer cCharPointerPointer, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(cCharPointerPointer)); + } + + @CEntryPoint(name = "initializeCharPointer") + public static CCharPointer initializeCharPointer(IsolateThread thread, int size, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.calloc(size * SizeOf.get(CCharPointer.class))); + } + + @CEntryPoint(name = "freeCharPointer") + public static void freeCharPointer(IsolateThread thread, CCharPointer cCharPointer, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(cCharPointer)); + } + + @CEntryPoint(name = "initializeIntPointer") + public static CIntPointer initializeIntPointer(IsolateThread thread, int size, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.calloc(size * SizeOf.get(CIntPointer.class))); + } + + @CEntryPoint(name = "freeIntPointer") + public static void freeIntPointer(IsolateThread thread, CIntPointer cIntPointer, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(cIntPointer)); + } + + @CEntryPoint(name = "initializeDoublePointer") + public static CDoublePointer initializeDoublePointer(IsolateThread thread, int size, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.calloc(size * SizeOf.get(CDoublePointer.class))); + } + + @CEntryPoint(name = "freeDoublePointer") + public static void freeDoublePointer(IsolateThread thread, CDoublePointer cDoublePointer, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.free(cDoublePointer)); + } +} diff --git a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java index f4ed6e184b..4da8cf876b 100644 --- a/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java +++ b/java/src/main/java/com/powsybl/python/commons/PyPowsyblApiHeader.java @@ -918,6 +918,12 @@ public interface ZonePointer extends PointerBase { @CField("injections_ids") void setInjectionsIds(CCharPointerPointer injectionsIds); + @CField("injections_ids_count") + int getInjectionsIdsCount(); + + @CField("injections_ids_count") + void setInjectionsIdsCount(int count); + @CField("injections_shift_keys") CDoublePointer getinjectionsShiftKeys(); diff --git a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java index 6449068282..c75f4e7d1c 100644 --- a/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java +++ b/java/src/main/java/com/powsybl/python/loadflow/LoadFlowCUtils.java @@ -117,5 +117,13 @@ public static void freeLoadFlowParametersContent(LoadFlowParametersPointer param UnmanagedMemory.free(parameters.getCountriesToBalance().read(i)); } UnmanagedMemory.free(parameters.getCountriesToBalance()); + for (int i = 0; i < parameters.getProviderParametersValuesCount(); i++) { + UnmanagedMemory.free(parameters.getProviderParametersValues().read(i)); + } + UnmanagedMemory.free(parameters.getProviderParametersValues()); + for (int i = 0; i < parameters.getProviderParametersKeysCount(); i++) { + UnmanagedMemory.free(parameters.getProviderParametersKeys().read(i)); + } + UnmanagedMemory.free(parameters.getProviderParametersKeys()); } } diff --git a/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java b/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java index 9b436c8511..b801350ae4 100644 --- a/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java +++ b/java/src/main/java/com/powsybl/python/sensitivity/SensitivityAnalysisCFunctions.java @@ -100,6 +100,22 @@ public static void setZones(IsolateThread thread, ObjectHandle sensitivityAnalys }); } + @CEntryPoint(name = "createZonePointer") + public static PyPowsyblApiHeader.ZonePointer createZonePointer(IsolateThread thread, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + return doCatch(exceptionHandlerPtr, () -> UnmanagedMemory.calloc(SizeOf.get(PyPowsyblApiHeader.ZonePointer.class))); + } + + @CEntryPoint(name = "freeZonePointer") + public static void freeZonePointer(IsolateThread thread, PyPowsyblApiHeader.ZonePointer zonePointer, PyPowsyblApiHeader.ExceptionHandlerPointer exceptionHandlerPtr) { + doCatch(exceptionHandlerPtr, () -> { + for (int i = 0; i < zonePointer.getInjectionsIdsCount(); i++) { + UnmanagedMemory.free(zonePointer.getInjectionsIds().read(i)); + } + UnmanagedMemory.free(zonePointer.getInjectionsIds()); + UnmanagedMemory.free(zonePointer); + }); + } + @CEntryPoint(name = "addFactorMatrix") public static void addFactorMatrix(IsolateThread thread, ObjectHandle sensitivityAnalysisContextHandle, CCharPointerPointer branchIdPtrPtr, int branchIdCount,