power-grid-model 1.12.58__py3-none-win_amd64.whl → 1.12.60__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of power-grid-model might be problematic. Click here for more details.

Files changed (59) hide show
  1. power_grid_model/__init__.py +54 -54
  2. power_grid_model/_core/__init__.py +3 -3
  3. power_grid_model/_core/buffer_handling.py +493 -493
  4. power_grid_model/_core/data_handling.py +141 -141
  5. power_grid_model/_core/data_types.py +132 -132
  6. power_grid_model/_core/dataset_definitions.py +109 -109
  7. power_grid_model/_core/enum.py +226 -226
  8. power_grid_model/_core/error_handling.py +206 -206
  9. power_grid_model/_core/errors.py +130 -130
  10. power_grid_model/_core/index_integer.py +17 -17
  11. power_grid_model/_core/options.py +71 -71
  12. power_grid_model/_core/power_grid_core.py +563 -563
  13. power_grid_model/_core/power_grid_dataset.py +535 -535
  14. power_grid_model/_core/power_grid_meta.py +243 -243
  15. power_grid_model/_core/power_grid_model.py +686 -686
  16. power_grid_model/_core/power_grid_model_c/__init__.py +3 -3
  17. power_grid_model/_core/power_grid_model_c/bin/power_grid_model_c.dll +0 -0
  18. power_grid_model/_core/power_grid_model_c/get_pgm_dll_path.py +63 -63
  19. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/basics.h +255 -255
  20. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/buffer.h +108 -108
  21. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset.h +316 -316
  22. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset_definitions.h +1052 -1052
  23. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/handle.h +99 -99
  24. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/meta_data.h +189 -189
  25. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/model.h +125 -125
  26. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/options.h +142 -142
  27. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/serialization.h +118 -118
  28. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c.h +36 -36
  29. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/basics.hpp +65 -65
  30. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/buffer.hpp +61 -61
  31. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/dataset.hpp +220 -220
  32. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/handle.hpp +108 -108
  33. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/meta_data.hpp +84 -84
  34. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/model.hpp +63 -63
  35. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/options.hpp +52 -52
  36. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/serialization.hpp +124 -124
  37. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/utils.hpp +81 -81
  38. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp.hpp +19 -19
  39. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelConfigVersion.cmake +3 -3
  40. power_grid_model/_core/serialization.py +317 -317
  41. power_grid_model/_core/typing.py +20 -20
  42. power_grid_model/_core/utils.py +798 -798
  43. power_grid_model/data_types.py +321 -321
  44. power_grid_model/enum.py +27 -27
  45. power_grid_model/errors.py +37 -37
  46. power_grid_model/typing.py +43 -43
  47. power_grid_model/utils.py +473 -473
  48. power_grid_model/validation/__init__.py +25 -25
  49. power_grid_model/validation/_rules.py +1171 -1171
  50. power_grid_model/validation/_validation.py +1172 -1172
  51. power_grid_model/validation/assertions.py +93 -93
  52. power_grid_model/validation/errors.py +602 -602
  53. power_grid_model/validation/utils.py +313 -313
  54. {power_grid_model-1.12.58.dist-info → power_grid_model-1.12.60.dist-info}/METADATA +1 -1
  55. power_grid_model-1.12.60.dist-info/RECORD +65 -0
  56. power_grid_model-1.12.58.dist-info/RECORD +0 -65
  57. {power_grid_model-1.12.58.dist-info → power_grid_model-1.12.60.dist-info}/WHEEL +0 -0
  58. {power_grid_model-1.12.58.dist-info → power_grid_model-1.12.60.dist-info}/entry_points.txt +0 -0
  59. {power_grid_model-1.12.58.dist-info → power_grid_model-1.12.60.dist-info}/licenses/LICENSE +0 -0
@@ -1,563 +1,563 @@
1
- # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
-
5
- """
6
- Loader for the dynamic library
7
- """
8
-
9
- from collections.abc import Callable
10
- from ctypes import CDLL, POINTER, c_char, c_char_p, c_double, c_size_t, c_void_p
11
- from inspect import signature
12
- from itertools import chain
13
-
14
- from power_grid_model._core.index_integer import IdC, IdxC
15
- from power_grid_model._core.power_grid_model_c.get_pgm_dll_path import get_pgm_dll_path
16
-
17
- # integer index
18
- IdxPtr = POINTER(IdxC)
19
- """Pointer to index."""
20
- IdxDoublePtr = POINTER(IdxPtr)
21
- """Double pointer to index."""
22
- IDPtr = POINTER(IdC)
23
- """Raw pointer to ids."""
24
-
25
- # string data
26
- CStr = c_char_p
27
- """Null terminated string."""
28
- CStrPtr = POINTER(CStr)
29
- """Pointer to null terminated string."""
30
- CharPtr = POINTER(c_char)
31
- """Raw pointer to char."""
32
- CharDoublePtr = POINTER(CharPtr)
33
- """Double pointer to char."""
34
-
35
- # raw data
36
- VoidPtr = c_void_p
37
- """Raw void pointer."""
38
- VoidDoublePtr = POINTER(c_void_p)
39
- """Double pointer to void."""
40
-
41
- # functions with size_t return
42
- _FUNC_SIZE_T_RES = {"meta_class_size", "meta_class_alignment", "meta_attribute_offset"}
43
- _ARGS_TYPE_MAPPING = {bytes: CharPtr, str: CStr, int: IdxC, float: c_double}
44
-
45
- # The c_void_p is extended only for type hinting and type checking; therefore no public methods are required.
46
-
47
-
48
- class HandlePtr(c_void_p):
49
- """
50
- Pointer to handle
51
- """
52
-
53
-
54
- class OptionsPtr(c_void_p):
55
- """
56
- Pointer to option
57
- """
58
-
59
-
60
- class ModelPtr(c_void_p):
61
- """
62
- Pointer to model
63
- """
64
-
65
-
66
- class DatasetPtr(c_void_p):
67
- """
68
- Pointer to dataset
69
- """
70
-
71
-
72
- class ConstDatasetPtr(c_void_p):
73
- """
74
- Pointer to writable dataset
75
- """
76
-
77
-
78
- class MutableDatasetPtr(c_void_p):
79
- """
80
- Pointer to writable dataset
81
- """
82
-
83
-
84
- class WritableDatasetPtr(c_void_p):
85
- """
86
- Pointer to writable dataset
87
- """
88
-
89
-
90
- class DatasetInfoPtr(c_void_p):
91
- """
92
- Pointer to dataset info
93
- """
94
-
95
-
96
- class ComponentPtr(c_void_p):
97
- """
98
- Pointer to component
99
- """
100
-
101
-
102
- class AttributePtr(c_void_p):
103
- """
104
- Pointer to attribute
105
- """
106
-
107
-
108
- class DeserializerPtr(c_void_p):
109
- """
110
- Pointer to deserializer
111
- """
112
-
113
-
114
- class SerializerPtr(c_void_p):
115
- """
116
- Pointer to serializer
117
- """
118
-
119
-
120
- def _load_core() -> CDLL:
121
- """
122
-
123
- Returns: DLL/SO object
124
-
125
- """
126
- dll_path = get_pgm_dll_path()
127
- cdll = CDLL(str(dll_path))
128
- # assign return types
129
- # handle
130
- cdll.PGM_create_handle.argtypes = []
131
- cdll.PGM_create_handle.restype = HandlePtr
132
- cdll.PGM_destroy_handle.argtypes = [HandlePtr]
133
- cdll.PGM_destroy_handle.restype = None
134
- return cdll
135
-
136
-
137
- # load dll once
138
- _CDLL: CDLL = _load_core()
139
-
140
-
141
- def make_c_binding(func: Callable):
142
- """
143
- Descriptor to make the function to bind to C
144
-
145
- Args:
146
- func: method object from PowerGridCore
147
-
148
- Returns:
149
- Binded function
150
-
151
- """
152
- name = func.__name__
153
- sig = signature(func)
154
-
155
- # get and convert types, skip first argument, as it is self
156
- py_argnames = list(sig.parameters.keys())[1:]
157
- py_argtypes = [v.annotation for v in sig.parameters.values()][1:]
158
- py_restype = sig.return_annotation
159
- c_argtypes = [_ARGS_TYPE_MAPPING.get(x, x) for x in py_argtypes]
160
- c_restype = _ARGS_TYPE_MAPPING.get(py_restype, py_restype)
161
- if c_restype == IdxC and name in _FUNC_SIZE_T_RES:
162
- c_restype = c_size_t
163
- # set argument in dll
164
- # mostly with handle pointer, except destroy function
165
- is_destroy_func = "destroy" in name
166
- if is_destroy_func:
167
- getattr(_CDLL, f"PGM_{name}").argtypes = c_argtypes
168
- else:
169
- getattr(_CDLL, f"PGM_{name}").argtypes = [HandlePtr, *c_argtypes]
170
- getattr(_CDLL, f"PGM_{name}").restype = c_restype
171
-
172
- # binding function
173
- def cbind_func(self, *args, **kwargs):
174
- c_inputs = [] if "destroy" in name else [self._handle]
175
- args = chain(args, (kwargs[key] for key in py_argnames[len(args) :]))
176
- for arg in args:
177
- if isinstance(arg, str):
178
- c_inputs.append(arg.encode())
179
- else:
180
- c_inputs.append(arg)
181
-
182
- # call
183
- res = getattr(_CDLL, f"PGM_{name}")(*c_inputs)
184
- # convert to string for CStr
185
- if c_restype == CStr:
186
- res = res.decode() if res is not None else ""
187
- return res
188
-
189
- return cbind_func
190
-
191
-
192
- class PowerGridCore:
193
- """
194
- DLL caller
195
- """
196
-
197
- _handle: HandlePtr
198
- _instance: "PowerGridCore | None" = None
199
-
200
- # singleton of power grid core
201
- def __new__(cls, *args, **kwargs):
202
- if cls._instance is None:
203
- cls._instance = super().__new__(cls, *args, **kwargs)
204
- cls._instance._handle = _CDLL.PGM_create_handle()
205
- return cls._instance
206
-
207
- def __del__(self):
208
- _CDLL.PGM_destroy_handle(self._handle)
209
-
210
- # not copyable
211
- def __copy__(self):
212
- raise NotImplementedError("Class not copyable")
213
-
214
- def __deepcopy__(self, memodict):
215
- raise NotImplementedError("class not copyable")
216
-
217
- @make_c_binding
218
- def error_code(self) -> int: # type: ignore[empty-body]
219
- pass # pragma: no cover
220
-
221
- @make_c_binding
222
- def error_message(self) -> str: # type: ignore[empty-body]
223
- pass # pragma: no cover
224
-
225
- @make_c_binding
226
- def n_failed_scenarios(self) -> int: # type: ignore[empty-body]
227
- pass # pragma: no cover
228
-
229
- @make_c_binding
230
- def failed_scenarios(self) -> IdxPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
231
- pass # pragma: no cover
232
-
233
- @make_c_binding
234
- def batch_errors(self) -> CStrPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
235
- pass # pragma: no cover
236
-
237
- @make_c_binding
238
- def clear_error(self) -> None: # type: ignore[empty-body]
239
- pass # pragma: no cover
240
-
241
- @make_c_binding
242
- def meta_n_datasets(self) -> int: # type: ignore[empty-body]
243
- pass # pragma: no cover
244
-
245
- @make_c_binding
246
- def meta_get_dataset_by_idx(self, idx: int) -> DatasetPtr: # type: ignore[empty-body]
247
- pass # pragma: no cover
248
-
249
- @make_c_binding
250
- def meta_dataset_name(self, dataset: DatasetPtr) -> str: # type: ignore[empty-body]
251
- pass # pragma: no cover
252
-
253
- @make_c_binding
254
- def meta_n_components(self, dataset: DatasetPtr) -> int: # type: ignore[empty-body]
255
- pass # pragma: no cover
256
-
257
- @make_c_binding
258
- def meta_get_component_by_idx(self, dataset: DatasetPtr, idx: int) -> ComponentPtr: # type: ignore[empty-body]
259
- pass # pragma: no cover
260
-
261
- @make_c_binding
262
- def meta_component_name(self, component: ComponentPtr) -> str: # type: ignore[empty-body]
263
- pass # pragma: no cover
264
-
265
- @make_c_binding
266
- def meta_component_alignment(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
267
- pass # pragma: no cover
268
-
269
- @make_c_binding
270
- def meta_component_size(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
271
- pass # pragma: no cover
272
-
273
- @make_c_binding
274
- def meta_n_attributes(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
275
- pass # pragma: no cover
276
-
277
- @make_c_binding
278
- def meta_get_attribute_by_idx(self, component: ComponentPtr, idx: int) -> AttributePtr: # type: ignore[empty-body]
279
- pass # pragma: no cover
280
-
281
- @make_c_binding
282
- def meta_attribute_name(self, attribute: AttributePtr) -> str: # type: ignore[empty-body]
283
- pass # pragma: no cover
284
-
285
- @make_c_binding
286
- def meta_attribute_ctype(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
287
- pass # pragma: no cover
288
-
289
- @make_c_binding
290
- def meta_attribute_offset(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
291
- pass # pragma: no cover
292
-
293
- @make_c_binding
294
- def is_little_endian(self) -> int: # type: ignore[empty-body]
295
- pass # pragma: no cover
296
-
297
- @make_c_binding
298
- def create_options(self) -> OptionsPtr: # type: ignore[empty-body]
299
- pass # pragma: no cover
300
-
301
- @make_c_binding
302
- def destroy_options(self, opt: OptionsPtr) -> None: # type: ignore[empty-body]
303
- pass # pragma: no cover
304
-
305
- @make_c_binding
306
- def set_calculation_type(self, opt: OptionsPtr, calculation_type: int) -> None: # type: ignore[empty-body]
307
- pass # pragma: no cover
308
-
309
- @make_c_binding
310
- def set_calculation_method(self, opt: OptionsPtr, method: int) -> None: # type: ignore[empty-body]
311
- pass # pragma: no cover
312
-
313
- @make_c_binding
314
- def set_tap_changing_strategy(self, opt: OptionsPtr, tap_changing_strategy: int) -> None: # type: ignore[empty-body]
315
- pass # pragma: no cover
316
-
317
- @make_c_binding
318
- def set_short_circuit_voltage_scaling(self, opt: OptionsPtr, short_circuit_voltage_scaling: int) -> None: # type: ignore[empty-body]
319
- pass # pragma: no cover
320
-
321
- @make_c_binding
322
- def set_experimental_features(self, opt: OptionsPtr, experimental_features: int) -> None: # type: ignore[empty-body]
323
- pass # pragma: no cover
324
-
325
- @make_c_binding
326
- def set_symmetric(self, opt: OptionsPtr, sym: int) -> None: # type: ignore[empty-body]
327
- pass # pragma: no cover
328
-
329
- @make_c_binding
330
- def set_err_tol(self, opt: OptionsPtr, err_tol: float) -> None: # type: ignore[empty-body]
331
- pass # pragma: no cover
332
-
333
- @make_c_binding
334
- def set_max_iter(self, opt: OptionsPtr, max_iter: int) -> None: # type: ignore[empty-body]
335
- pass # pragma: no cover
336
-
337
- @make_c_binding
338
- def set_threading(self, opt: OptionsPtr, threading: int) -> None: # type: ignore[empty-body]
339
- pass # pragma: no cover
340
-
341
- @make_c_binding
342
- def create_model( # type: ignore[empty-body]
343
- self,
344
- system_frequency: float,
345
- input_data: ConstDatasetPtr, # type: ignore[valid-type]
346
- ) -> ModelPtr:
347
- pass # pragma: no cover
348
-
349
- @make_c_binding
350
- def update_model( # type: ignore[empty-body]
351
- self,
352
- model: ModelPtr,
353
- update_data: ConstDatasetPtr, # type: ignore[valid-type]
354
- ) -> None:
355
- pass # pragma: no cover
356
-
357
- @make_c_binding
358
- def copy_model(self, model: ModelPtr) -> ModelPtr: # type: ignore[empty-body]
359
- pass # pragma: no cover
360
-
361
- @make_c_binding
362
- def get_indexer(
363
- self,
364
- model: ModelPtr,
365
- component: str,
366
- size: int,
367
- ids: IDPtr, # type: ignore[valid-type]
368
- indexer: IdxPtr, # type: ignore[valid-type]
369
- ) -> None: # type: ignore[empty-body]
370
- pass # pragma: no cover
371
-
372
- @make_c_binding
373
- def destroy_model(self, model: ModelPtr) -> None: # type: ignore[empty-body]
374
- pass # pragma: no cover
375
-
376
- @make_c_binding
377
- def calculate( # type: ignore[empty-body]
378
- self,
379
- model: ModelPtr,
380
- opt: OptionsPtr,
381
- output_data: MutableDatasetPtr, # type: ignore[valid-type]
382
- update_data: ConstDatasetPtr, # type: ignore[valid-type]
383
- ) -> None:
384
- pass # pragma: no cover
385
-
386
- @make_c_binding
387
- def dataset_info_name(self, info: DatasetInfoPtr) -> str: # type: ignore[empty-body]
388
- pass # pragma: no cover
389
-
390
- @make_c_binding
391
- def dataset_info_is_batch(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
392
- pass # pragma: no cover
393
-
394
- @make_c_binding
395
- def dataset_info_batch_size(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
396
- pass # pragma: no cover
397
-
398
- @make_c_binding
399
- def dataset_info_n_components(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
400
- pass # pragma: no cover
401
-
402
- @make_c_binding
403
- def dataset_info_component_name(self, info: DatasetInfoPtr, component_idx: int) -> str: # type: ignore[empty-body]
404
- pass # pragma: no cover
405
-
406
- @make_c_binding
407
- def dataset_info_elements_per_scenario( # type: ignore[empty-body]
408
- self, info: DatasetInfoPtr, component_idx: int
409
- ) -> int:
410
- pass # pragma: no cover
411
-
412
- @make_c_binding
413
- def dataset_info_total_elements(self, info: DatasetInfoPtr, component_idx: int) -> int: # type: ignore[empty-body]
414
- pass # pragma: no cover
415
-
416
- @make_c_binding
417
- def dataset_info_has_attribute_indications( # type: ignore[empty-body]
418
- self, info: DatasetInfoPtr, component_idx: int
419
- ) -> int:
420
- pass # pragma: no cover
421
-
422
- @make_c_binding
423
- def dataset_info_n_attribute_indications( # type: ignore[empty-body]
424
- self, info: DatasetInfoPtr, component_idx: int
425
- ) -> int:
426
- pass # pragma: no cover
427
-
428
- @make_c_binding
429
- def dataset_info_attribute_name( # type: ignore[empty-body]
430
- self, info: DatasetInfoPtr, component_idx: int, attribute_idx: int
431
- ) -> str:
432
- pass # pragma: no cover
433
-
434
- @make_c_binding
435
- def create_dataset_mutable( # type: ignore[empty-body]
436
- self, dataset: str, is_batch: int, batch_size: int
437
- ) -> MutableDatasetPtr:
438
- pass # pragma: no cover
439
-
440
- @make_c_binding
441
- def destroy_dataset_mutable(self, dataset: MutableDatasetPtr) -> None: # type: ignore[empty-body]
442
- pass # pragma: no cover
443
-
444
- @make_c_binding
445
- def dataset_mutable_add_buffer( # type: ignore[empty-body] # noqa: PLR0913
446
- self,
447
- dataset: MutableDatasetPtr,
448
- component: str,
449
- elements_per_scenario: int,
450
- total_elements: int,
451
- indptr: IdxPtr, # type: ignore[valid-type]
452
- data: VoidPtr, # type: ignore[valid-type]
453
- ) -> None:
454
- pass # pragma: no cover
455
-
456
- @make_c_binding
457
- def dataset_mutable_add_attribute_buffer(
458
- self,
459
- dataset: MutableDatasetPtr,
460
- component: str,
461
- attribute: str,
462
- data: VoidPtr, # type: ignore[valid-type]
463
- ) -> None: # type: ignore[empty-body]
464
- pass # pragma: no cover
465
-
466
- @make_c_binding
467
- def dataset_mutable_get_info(self, dataset: MutableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
468
- pass # pragma: no cover
469
-
470
- @make_c_binding
471
- def create_dataset_const_from_mutable( # type: ignore[empty-body]
472
- self, mutable_dataset: MutableDatasetPtr
473
- ) -> ConstDatasetPtr:
474
- pass # pragma: no cover
475
-
476
- @make_c_binding
477
- def destroy_dataset_const(self, dataset: ConstDatasetPtr) -> None: # type: ignore[empty-body]
478
- pass # pragma: no cover
479
-
480
- @make_c_binding
481
- def dataset_const_get_info(self, dataset: ConstDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
482
- pass # pragma: no cover
483
-
484
- @make_c_binding
485
- def dataset_writable_get_info(self, dataset: WritableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
486
- pass # pragma: no cover
487
-
488
- @make_c_binding
489
- def dataset_writable_set_buffer(
490
- self,
491
- dataset: WritableDatasetPtr,
492
- component: str,
493
- indptr: IdxPtr, # type: ignore[valid-type]
494
- data: VoidPtr, # type: ignore[valid-type]
495
- ) -> None: # type: ignore[empty-body]
496
- pass # pragma: no cover
497
-
498
- @make_c_binding
499
- def dataset_writable_set_attribute_buffer(
500
- self,
501
- dataset: WritableDatasetPtr,
502
- component: str,
503
- attribute: str,
504
- data: VoidPtr, # type: ignore[valid-type]
505
- ) -> None: # type: ignore[empty-body]
506
- pass # pragma: no cover
507
-
508
- @make_c_binding
509
- def create_deserializer_from_binary_buffer( # type: ignore[empty-body]
510
- self, data: bytes, size: int, serialization_format: int
511
- ) -> DeserializerPtr:
512
- pass # pragma: no cover
513
-
514
- @make_c_binding
515
- def create_deserializer_from_null_terminated_string( # type: ignore[empty-body]
516
- self, data: str, serialization_format: int
517
- ) -> DeserializerPtr:
518
- pass # pragma: no cover
519
-
520
- @make_c_binding
521
- def deserializer_get_dataset(self, deserializer: DeserializerPtr) -> WritableDatasetPtr: # type: ignore[empty-body]
522
- pass # pragma: no cover
523
-
524
- @make_c_binding
525
- def deserializer_parse_to_buffer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
526
- pass # pragma: no cover
527
-
528
- @make_c_binding
529
- def destroy_deserializer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
530
- pass # pragma: no cover
531
-
532
- @make_c_binding
533
- def create_serializer( # type: ignore[empty-body]
534
- self, data: ConstDatasetPtr, serialization_format: int
535
- ) -> SerializerPtr:
536
- pass # pragma: no cover
537
-
538
- @make_c_binding
539
- def serializer_get_to_binary_buffer( # type: ignore[empty-body]
540
- self,
541
- serializer: SerializerPtr,
542
- use_compact_list: int,
543
- data: CharDoublePtr, # type: ignore[valid-type]
544
- size: IdxPtr, # type: ignore[valid-type]
545
- ) -> None:
546
- pass # pragma: no cover
547
-
548
- @make_c_binding
549
- def serializer_get_to_zero_terminated_string( # type: ignore[empty-body]
550
- self,
551
- serializer: SerializerPtr,
552
- use_compact_list: int,
553
- indent: int,
554
- ) -> str:
555
- pass # pragma: no cover
556
-
557
- @make_c_binding
558
- def destroy_serializer(self, serializer: SerializerPtr) -> None: # type: ignore[empty-body]
559
- pass # pragma: no cover
560
-
561
-
562
- # make one instance
563
- power_grid_core = PowerGridCore()
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
+ #
3
+ # SPDX-License-Identifier: MPL-2.0
4
+
5
+ """
6
+ Loader for the dynamic library
7
+ """
8
+
9
+ from collections.abc import Callable
10
+ from ctypes import CDLL, POINTER, c_char, c_char_p, c_double, c_size_t, c_void_p
11
+ from inspect import signature
12
+ from itertools import chain
13
+
14
+ from power_grid_model._core.index_integer import IdC, IdxC
15
+ from power_grid_model._core.power_grid_model_c.get_pgm_dll_path import get_pgm_dll_path
16
+
17
+ # integer index
18
+ IdxPtr = POINTER(IdxC)
19
+ """Pointer to index."""
20
+ IdxDoublePtr = POINTER(IdxPtr)
21
+ """Double pointer to index."""
22
+ IDPtr = POINTER(IdC)
23
+ """Raw pointer to ids."""
24
+
25
+ # string data
26
+ CStr = c_char_p
27
+ """Null terminated string."""
28
+ CStrPtr = POINTER(CStr)
29
+ """Pointer to null terminated string."""
30
+ CharPtr = POINTER(c_char)
31
+ """Raw pointer to char."""
32
+ CharDoublePtr = POINTER(CharPtr)
33
+ """Double pointer to char."""
34
+
35
+ # raw data
36
+ VoidPtr = c_void_p
37
+ """Raw void pointer."""
38
+ VoidDoublePtr = POINTER(c_void_p)
39
+ """Double pointer to void."""
40
+
41
+ # functions with size_t return
42
+ _FUNC_SIZE_T_RES = {"meta_class_size", "meta_class_alignment", "meta_attribute_offset"}
43
+ _ARGS_TYPE_MAPPING = {bytes: CharPtr, str: CStr, int: IdxC, float: c_double}
44
+
45
+ # The c_void_p is extended only for type hinting and type checking; therefore no public methods are required.
46
+
47
+
48
+ class HandlePtr(c_void_p):
49
+ """
50
+ Pointer to handle
51
+ """
52
+
53
+
54
+ class OptionsPtr(c_void_p):
55
+ """
56
+ Pointer to option
57
+ """
58
+
59
+
60
+ class ModelPtr(c_void_p):
61
+ """
62
+ Pointer to model
63
+ """
64
+
65
+
66
+ class DatasetPtr(c_void_p):
67
+ """
68
+ Pointer to dataset
69
+ """
70
+
71
+
72
+ class ConstDatasetPtr(c_void_p):
73
+ """
74
+ Pointer to writable dataset
75
+ """
76
+
77
+
78
+ class MutableDatasetPtr(c_void_p):
79
+ """
80
+ Pointer to writable dataset
81
+ """
82
+
83
+
84
+ class WritableDatasetPtr(c_void_p):
85
+ """
86
+ Pointer to writable dataset
87
+ """
88
+
89
+
90
+ class DatasetInfoPtr(c_void_p):
91
+ """
92
+ Pointer to dataset info
93
+ """
94
+
95
+
96
+ class ComponentPtr(c_void_p):
97
+ """
98
+ Pointer to component
99
+ """
100
+
101
+
102
+ class AttributePtr(c_void_p):
103
+ """
104
+ Pointer to attribute
105
+ """
106
+
107
+
108
+ class DeserializerPtr(c_void_p):
109
+ """
110
+ Pointer to deserializer
111
+ """
112
+
113
+
114
+ class SerializerPtr(c_void_p):
115
+ """
116
+ Pointer to serializer
117
+ """
118
+
119
+
120
+ def _load_core() -> CDLL:
121
+ """
122
+
123
+ Returns: DLL/SO object
124
+
125
+ """
126
+ dll_path = get_pgm_dll_path()
127
+ cdll = CDLL(str(dll_path))
128
+ # assign return types
129
+ # handle
130
+ cdll.PGM_create_handle.argtypes = []
131
+ cdll.PGM_create_handle.restype = HandlePtr
132
+ cdll.PGM_destroy_handle.argtypes = [HandlePtr]
133
+ cdll.PGM_destroy_handle.restype = None
134
+ return cdll
135
+
136
+
137
+ # load dll once
138
+ _CDLL: CDLL = _load_core()
139
+
140
+
141
+ def make_c_binding(func: Callable):
142
+ """
143
+ Descriptor to make the function to bind to C
144
+
145
+ Args:
146
+ func: method object from PowerGridCore
147
+
148
+ Returns:
149
+ Binded function
150
+
151
+ """
152
+ name = func.__name__
153
+ sig = signature(func)
154
+
155
+ # get and convert types, skip first argument, as it is self
156
+ py_argnames = list(sig.parameters.keys())[1:]
157
+ py_argtypes = [v.annotation for v in sig.parameters.values()][1:]
158
+ py_restype = sig.return_annotation
159
+ c_argtypes = [_ARGS_TYPE_MAPPING.get(x, x) for x in py_argtypes]
160
+ c_restype = _ARGS_TYPE_MAPPING.get(py_restype, py_restype)
161
+ if c_restype == IdxC and name in _FUNC_SIZE_T_RES:
162
+ c_restype = c_size_t
163
+ # set argument in dll
164
+ # mostly with handle pointer, except destroy function
165
+ is_destroy_func = "destroy" in name
166
+ if is_destroy_func:
167
+ getattr(_CDLL, f"PGM_{name}").argtypes = c_argtypes
168
+ else:
169
+ getattr(_CDLL, f"PGM_{name}").argtypes = [HandlePtr, *c_argtypes]
170
+ getattr(_CDLL, f"PGM_{name}").restype = c_restype
171
+
172
+ # binding function
173
+ def cbind_func(self, *args, **kwargs):
174
+ c_inputs = [] if "destroy" in name else [self._handle]
175
+ args = chain(args, (kwargs[key] for key in py_argnames[len(args) :]))
176
+ for arg in args:
177
+ if isinstance(arg, str):
178
+ c_inputs.append(arg.encode())
179
+ else:
180
+ c_inputs.append(arg)
181
+
182
+ # call
183
+ res = getattr(_CDLL, f"PGM_{name}")(*c_inputs)
184
+ # convert to string for CStr
185
+ if c_restype == CStr:
186
+ res = res.decode() if res is not None else ""
187
+ return res
188
+
189
+ return cbind_func
190
+
191
+
192
+ class PowerGridCore:
193
+ """
194
+ DLL caller
195
+ """
196
+
197
+ _handle: HandlePtr
198
+ _instance: "PowerGridCore | None" = None
199
+
200
+ # singleton of power grid core
201
+ def __new__(cls, *args, **kwargs):
202
+ if cls._instance is None:
203
+ cls._instance = super().__new__(cls, *args, **kwargs)
204
+ cls._instance._handle = _CDLL.PGM_create_handle()
205
+ return cls._instance
206
+
207
+ def __del__(self):
208
+ _CDLL.PGM_destroy_handle(self._handle)
209
+
210
+ # not copyable
211
+ def __copy__(self):
212
+ raise NotImplementedError("Class not copyable")
213
+
214
+ def __deepcopy__(self, memodict):
215
+ raise NotImplementedError("class not copyable")
216
+
217
+ @make_c_binding
218
+ def error_code(self) -> int: # type: ignore[empty-body]
219
+ pass # pragma: no cover
220
+
221
+ @make_c_binding
222
+ def error_message(self) -> str: # type: ignore[empty-body]
223
+ pass # pragma: no cover
224
+
225
+ @make_c_binding
226
+ def n_failed_scenarios(self) -> int: # type: ignore[empty-body]
227
+ pass # pragma: no cover
228
+
229
+ @make_c_binding
230
+ def failed_scenarios(self) -> IdxPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
231
+ pass # pragma: no cover
232
+
233
+ @make_c_binding
234
+ def batch_errors(self) -> CStrPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
235
+ pass # pragma: no cover
236
+
237
+ @make_c_binding
238
+ def clear_error(self) -> None: # type: ignore[empty-body]
239
+ pass # pragma: no cover
240
+
241
+ @make_c_binding
242
+ def meta_n_datasets(self) -> int: # type: ignore[empty-body]
243
+ pass # pragma: no cover
244
+
245
+ @make_c_binding
246
+ def meta_get_dataset_by_idx(self, idx: int) -> DatasetPtr: # type: ignore[empty-body]
247
+ pass # pragma: no cover
248
+
249
+ @make_c_binding
250
+ def meta_dataset_name(self, dataset: DatasetPtr) -> str: # type: ignore[empty-body]
251
+ pass # pragma: no cover
252
+
253
+ @make_c_binding
254
+ def meta_n_components(self, dataset: DatasetPtr) -> int: # type: ignore[empty-body]
255
+ pass # pragma: no cover
256
+
257
+ @make_c_binding
258
+ def meta_get_component_by_idx(self, dataset: DatasetPtr, idx: int) -> ComponentPtr: # type: ignore[empty-body]
259
+ pass # pragma: no cover
260
+
261
+ @make_c_binding
262
+ def meta_component_name(self, component: ComponentPtr) -> str: # type: ignore[empty-body]
263
+ pass # pragma: no cover
264
+
265
+ @make_c_binding
266
+ def meta_component_alignment(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
267
+ pass # pragma: no cover
268
+
269
+ @make_c_binding
270
+ def meta_component_size(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
271
+ pass # pragma: no cover
272
+
273
+ @make_c_binding
274
+ def meta_n_attributes(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
275
+ pass # pragma: no cover
276
+
277
+ @make_c_binding
278
+ def meta_get_attribute_by_idx(self, component: ComponentPtr, idx: int) -> AttributePtr: # type: ignore[empty-body]
279
+ pass # pragma: no cover
280
+
281
+ @make_c_binding
282
+ def meta_attribute_name(self, attribute: AttributePtr) -> str: # type: ignore[empty-body]
283
+ pass # pragma: no cover
284
+
285
+ @make_c_binding
286
+ def meta_attribute_ctype(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
287
+ pass # pragma: no cover
288
+
289
+ @make_c_binding
290
+ def meta_attribute_offset(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
291
+ pass # pragma: no cover
292
+
293
+ @make_c_binding
294
+ def is_little_endian(self) -> int: # type: ignore[empty-body]
295
+ pass # pragma: no cover
296
+
297
+ @make_c_binding
298
+ def create_options(self) -> OptionsPtr: # type: ignore[empty-body]
299
+ pass # pragma: no cover
300
+
301
+ @make_c_binding
302
+ def destroy_options(self, opt: OptionsPtr) -> None: # type: ignore[empty-body]
303
+ pass # pragma: no cover
304
+
305
+ @make_c_binding
306
+ def set_calculation_type(self, opt: OptionsPtr, calculation_type: int) -> None: # type: ignore[empty-body]
307
+ pass # pragma: no cover
308
+
309
+ @make_c_binding
310
+ def set_calculation_method(self, opt: OptionsPtr, method: int) -> None: # type: ignore[empty-body]
311
+ pass # pragma: no cover
312
+
313
+ @make_c_binding
314
+ def set_tap_changing_strategy(self, opt: OptionsPtr, tap_changing_strategy: int) -> None: # type: ignore[empty-body]
315
+ pass # pragma: no cover
316
+
317
+ @make_c_binding
318
+ def set_short_circuit_voltage_scaling(self, opt: OptionsPtr, short_circuit_voltage_scaling: int) -> None: # type: ignore[empty-body]
319
+ pass # pragma: no cover
320
+
321
+ @make_c_binding
322
+ def set_experimental_features(self, opt: OptionsPtr, experimental_features: int) -> None: # type: ignore[empty-body]
323
+ pass # pragma: no cover
324
+
325
+ @make_c_binding
326
+ def set_symmetric(self, opt: OptionsPtr, sym: int) -> None: # type: ignore[empty-body]
327
+ pass # pragma: no cover
328
+
329
+ @make_c_binding
330
+ def set_err_tol(self, opt: OptionsPtr, err_tol: float) -> None: # type: ignore[empty-body]
331
+ pass # pragma: no cover
332
+
333
+ @make_c_binding
334
+ def set_max_iter(self, opt: OptionsPtr, max_iter: int) -> None: # type: ignore[empty-body]
335
+ pass # pragma: no cover
336
+
337
+ @make_c_binding
338
+ def set_threading(self, opt: OptionsPtr, threading: int) -> None: # type: ignore[empty-body]
339
+ pass # pragma: no cover
340
+
341
+ @make_c_binding
342
+ def create_model( # type: ignore[empty-body]
343
+ self,
344
+ system_frequency: float,
345
+ input_data: ConstDatasetPtr, # type: ignore[valid-type]
346
+ ) -> ModelPtr:
347
+ pass # pragma: no cover
348
+
349
+ @make_c_binding
350
+ def update_model( # type: ignore[empty-body]
351
+ self,
352
+ model: ModelPtr,
353
+ update_data: ConstDatasetPtr, # type: ignore[valid-type]
354
+ ) -> None:
355
+ pass # pragma: no cover
356
+
357
+ @make_c_binding
358
+ def copy_model(self, model: ModelPtr) -> ModelPtr: # type: ignore[empty-body]
359
+ pass # pragma: no cover
360
+
361
+ @make_c_binding
362
+ def get_indexer(
363
+ self,
364
+ model: ModelPtr,
365
+ component: str,
366
+ size: int,
367
+ ids: IDPtr, # type: ignore[valid-type]
368
+ indexer: IdxPtr, # type: ignore[valid-type]
369
+ ) -> None: # type: ignore[empty-body]
370
+ pass # pragma: no cover
371
+
372
+ @make_c_binding
373
+ def destroy_model(self, model: ModelPtr) -> None: # type: ignore[empty-body]
374
+ pass # pragma: no cover
375
+
376
+ @make_c_binding
377
+ def calculate( # type: ignore[empty-body]
378
+ self,
379
+ model: ModelPtr,
380
+ opt: OptionsPtr,
381
+ output_data: MutableDatasetPtr, # type: ignore[valid-type]
382
+ update_data: ConstDatasetPtr, # type: ignore[valid-type]
383
+ ) -> None:
384
+ pass # pragma: no cover
385
+
386
+ @make_c_binding
387
+ def dataset_info_name(self, info: DatasetInfoPtr) -> str: # type: ignore[empty-body]
388
+ pass # pragma: no cover
389
+
390
+ @make_c_binding
391
+ def dataset_info_is_batch(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
392
+ pass # pragma: no cover
393
+
394
+ @make_c_binding
395
+ def dataset_info_batch_size(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
396
+ pass # pragma: no cover
397
+
398
+ @make_c_binding
399
+ def dataset_info_n_components(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
400
+ pass # pragma: no cover
401
+
402
+ @make_c_binding
403
+ def dataset_info_component_name(self, info: DatasetInfoPtr, component_idx: int) -> str: # type: ignore[empty-body]
404
+ pass # pragma: no cover
405
+
406
+ @make_c_binding
407
+ def dataset_info_elements_per_scenario( # type: ignore[empty-body]
408
+ self, info: DatasetInfoPtr, component_idx: int
409
+ ) -> int:
410
+ pass # pragma: no cover
411
+
412
+ @make_c_binding
413
+ def dataset_info_total_elements(self, info: DatasetInfoPtr, component_idx: int) -> int: # type: ignore[empty-body]
414
+ pass # pragma: no cover
415
+
416
+ @make_c_binding
417
+ def dataset_info_has_attribute_indications( # type: ignore[empty-body]
418
+ self, info: DatasetInfoPtr, component_idx: int
419
+ ) -> int:
420
+ pass # pragma: no cover
421
+
422
+ @make_c_binding
423
+ def dataset_info_n_attribute_indications( # type: ignore[empty-body]
424
+ self, info: DatasetInfoPtr, component_idx: int
425
+ ) -> int:
426
+ pass # pragma: no cover
427
+
428
+ @make_c_binding
429
+ def dataset_info_attribute_name( # type: ignore[empty-body]
430
+ self, info: DatasetInfoPtr, component_idx: int, attribute_idx: int
431
+ ) -> str:
432
+ pass # pragma: no cover
433
+
434
+ @make_c_binding
435
+ def create_dataset_mutable( # type: ignore[empty-body]
436
+ self, dataset: str, is_batch: int, batch_size: int
437
+ ) -> MutableDatasetPtr:
438
+ pass # pragma: no cover
439
+
440
+ @make_c_binding
441
+ def destroy_dataset_mutable(self, dataset: MutableDatasetPtr) -> None: # type: ignore[empty-body]
442
+ pass # pragma: no cover
443
+
444
+ @make_c_binding
445
+ def dataset_mutable_add_buffer( # type: ignore[empty-body] # noqa: PLR0913
446
+ self,
447
+ dataset: MutableDatasetPtr,
448
+ component: str,
449
+ elements_per_scenario: int,
450
+ total_elements: int,
451
+ indptr: IdxPtr, # type: ignore[valid-type]
452
+ data: VoidPtr, # type: ignore[valid-type]
453
+ ) -> None:
454
+ pass # pragma: no cover
455
+
456
+ @make_c_binding
457
+ def dataset_mutable_add_attribute_buffer(
458
+ self,
459
+ dataset: MutableDatasetPtr,
460
+ component: str,
461
+ attribute: str,
462
+ data: VoidPtr, # type: ignore[valid-type]
463
+ ) -> None: # type: ignore[empty-body]
464
+ pass # pragma: no cover
465
+
466
+ @make_c_binding
467
+ def dataset_mutable_get_info(self, dataset: MutableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
468
+ pass # pragma: no cover
469
+
470
+ @make_c_binding
471
+ def create_dataset_const_from_mutable( # type: ignore[empty-body]
472
+ self, mutable_dataset: MutableDatasetPtr
473
+ ) -> ConstDatasetPtr:
474
+ pass # pragma: no cover
475
+
476
+ @make_c_binding
477
+ def destroy_dataset_const(self, dataset: ConstDatasetPtr) -> None: # type: ignore[empty-body]
478
+ pass # pragma: no cover
479
+
480
+ @make_c_binding
481
+ def dataset_const_get_info(self, dataset: ConstDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
482
+ pass # pragma: no cover
483
+
484
+ @make_c_binding
485
+ def dataset_writable_get_info(self, dataset: WritableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
486
+ pass # pragma: no cover
487
+
488
+ @make_c_binding
489
+ def dataset_writable_set_buffer(
490
+ self,
491
+ dataset: WritableDatasetPtr,
492
+ component: str,
493
+ indptr: IdxPtr, # type: ignore[valid-type]
494
+ data: VoidPtr, # type: ignore[valid-type]
495
+ ) -> None: # type: ignore[empty-body]
496
+ pass # pragma: no cover
497
+
498
+ @make_c_binding
499
+ def dataset_writable_set_attribute_buffer(
500
+ self,
501
+ dataset: WritableDatasetPtr,
502
+ component: str,
503
+ attribute: str,
504
+ data: VoidPtr, # type: ignore[valid-type]
505
+ ) -> None: # type: ignore[empty-body]
506
+ pass # pragma: no cover
507
+
508
+ @make_c_binding
509
+ def create_deserializer_from_binary_buffer( # type: ignore[empty-body]
510
+ self, data: bytes, size: int, serialization_format: int
511
+ ) -> DeserializerPtr:
512
+ pass # pragma: no cover
513
+
514
+ @make_c_binding
515
+ def create_deserializer_from_null_terminated_string( # type: ignore[empty-body]
516
+ self, data: str, serialization_format: int
517
+ ) -> DeserializerPtr:
518
+ pass # pragma: no cover
519
+
520
+ @make_c_binding
521
+ def deserializer_get_dataset(self, deserializer: DeserializerPtr) -> WritableDatasetPtr: # type: ignore[empty-body]
522
+ pass # pragma: no cover
523
+
524
+ @make_c_binding
525
+ def deserializer_parse_to_buffer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
526
+ pass # pragma: no cover
527
+
528
+ @make_c_binding
529
+ def destroy_deserializer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
530
+ pass # pragma: no cover
531
+
532
+ @make_c_binding
533
+ def create_serializer( # type: ignore[empty-body]
534
+ self, data: ConstDatasetPtr, serialization_format: int
535
+ ) -> SerializerPtr:
536
+ pass # pragma: no cover
537
+
538
+ @make_c_binding
539
+ def serializer_get_to_binary_buffer( # type: ignore[empty-body]
540
+ self,
541
+ serializer: SerializerPtr,
542
+ use_compact_list: int,
543
+ data: CharDoublePtr, # type: ignore[valid-type]
544
+ size: IdxPtr, # type: ignore[valid-type]
545
+ ) -> None:
546
+ pass # pragma: no cover
547
+
548
+ @make_c_binding
549
+ def serializer_get_to_zero_terminated_string( # type: ignore[empty-body]
550
+ self,
551
+ serializer: SerializerPtr,
552
+ use_compact_list: int,
553
+ indent: int,
554
+ ) -> str:
555
+ pass # pragma: no cover
556
+
557
+ @make_c_binding
558
+ def destroy_serializer(self, serializer: SerializerPtr) -> None: # type: ignore[empty-body]
559
+ pass # pragma: no cover
560
+
561
+
562
+ # make one instance
563
+ power_grid_core = PowerGridCore()