Skip to content

Commit 9513534

Browse files
committed
ArrayProxy updated to use the new API functions
The new functions move some operations to the engine and reduce memory allocations.
1 parent 74d7fe0 commit 9513534

File tree

8 files changed

+268
-36
lines changed

8 files changed

+268
-36
lines changed

altdss/ArrayProxy.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def to_array(self):
1010
return self._batch._get_batch_float_prop(self._idx)
1111

1212
def to_list(self):
13-
return self._batch._get_batch_float_prop(self._idx)
13+
return self._batch._get_batch_float_prop_as_list(self._idx)
1414

1515
def __call__(self):
1616
return self.to_array()
@@ -60,11 +60,11 @@ def __iadd__(self, other, flags=0):
6060
if len(other) != len(batch):
6161
raise ValueError(f"Number of elements ({len(other)}) doesn't match the batch size ({len(batch)})")
6262

63-
data = self.to_array() + other
64-
data, data_ptr, _ = batch._prepare_float64_array(data)
65-
batch._lib.Batch_SetFloat64Array(
63+
data, data_ptr, _ = batch._prepare_float64_array(other)
64+
batch._lib.Batch_Float64Array(
6665
*ptr_cnt,
6766
self._idx,
67+
self._lib.BatchOperation_Increment,
6868
data_ptr,
6969
flags
7070
)
@@ -77,7 +77,7 @@ def __isub__(self, other, flags=0):
7777
7878
Use `isub` instead of the `-=` operator in order to specify SetterFlags.
7979
'''
80-
return self.__iadd__(-other, flags)
80+
return self.__iadd__(-np.asarray(other), flags)
8181

8282
def __imul__(self, other, flags=0):
8383
'''
@@ -100,18 +100,18 @@ def __imul__(self, other, flags=0):
100100
if len(other) != len(batch):
101101
raise ValueError(f"Number of elements ({len(other)}) doesn't match the batch size ({len(batch)})")
102102

103-
data = self.to_array() * other
104-
data, data_ptr, _ = batch._prepare_float64_array(data)
105-
batch._lib.Batch_SetFloat64Array(
103+
data, data_ptr, _ = batch._prepare_float64_array(other)
104+
batch._lib.Batch_Float64Array(
106105
*ptr_cnt,
107106
self._idx,
107+
self._lib.BatchOperation_Multiply,
108108
data_ptr,
109109
flags
110110
)
111111
batch._check_for_error()
112112
return self
113113

114-
def __idiv__(self, other, flags=0):
114+
def __itruediv__(self, other, flags=0):
115115
'''
116116
Inplace modification of the array. When possible, it runs the operation in the engine.
117117
@@ -123,27 +123,29 @@ def __idiv__(self, other, flags=0):
123123
self._lib.Batch_Float64(
124124
*ptr_cnt,
125125
self._idx,
126-
self._lib.BatchOperation_Multiply,
127-
1 / other,
126+
self._lib.BatchOperation_Divide,
127+
other,
128128
flags
129129
)
130130
return self
131131

132132
if len(other) != len(batch):
133133
raise ValueError(f"Number of elements ({len(other)}) doesn't match the batch size ({len(batch)})")
134134

135-
data = self.to_array() / other
136-
data, data_ptr, _ = batch._prepare_float64_array(data)
137-
batch._lib.Batch_SetFloat64Array(
135+
data, data_ptr, _ = batch._prepare_float64_array(other)
136+
batch._lib.Batch_Float64Array(
138137
*ptr_cnt,
139138
self._idx,
139+
self._lib.BatchOperation_Divide,
140140
data_ptr,
141141
flags
142142
)
143143
batch._check_for_error()
144144
return self
145145

146-
idiv = __idiv__
146+
147+
148+
idiv = __itruediv__
147149
imul = __imul__
148150
iadd = __iadd__
149151
isub = __isub__
@@ -209,11 +211,11 @@ def __iadd__(self, other, flags=0):
209211
if len(other) != len(batch):
210212
raise ValueError(f"Number of elements ({len(other)}) doesn't match the batch size ({len(batch)})")
211213

212-
data = self.to_array() + other
213-
data, data_ptr, _ = batch._api_util.prepare_int32_array(data)
214-
batch._lib.Batch_SetInt32Array(
214+
data, data_ptr, _ = batch._api_util.prepare_int32_array(other)
215+
batch._lib.Batch_Int32Array(
215216
*ptr_cnt,
216217
self._idx,
218+
self._lib.BatchOperation_Increment,
217219
data_ptr,
218220
flags
219221
)
@@ -226,7 +228,7 @@ def __isub__(self, other, flags=0):
226228
227229
Use `isub` instead of the `-=` operator in order to specify SetterFlags.
228230
'''
229-
return self.__iadd__(-other, flags)
231+
return self.__iadd__(-np.asarray(other), flags)
230232

231233
def __imul__(self, other, flags=0):
232234
'''
@@ -249,18 +251,18 @@ def __imul__(self, other, flags=0):
249251
if len(other) != len(batch):
250252
raise ValueError(f"Number of elements ({len(other)}) doesn't match the batch size ({len(batch)})")
251253

252-
data = self.to_array() * other
253-
data, data_ptr, _ = batch._prepare_int32_array(data)
254-
batch._lib.Batch_SetInt32Array(
254+
data, data_ptr, _ = batch._prepare_int32_array(other)
255+
batch._lib.Batch_Int32Array(
255256
*ptr_cnt,
256257
self._idx,
258+
self._lib.BatchOperation_Multiply,
257259
data_ptr,
258260
flags
259261
)
260262
batch._check_for_error()
261263
return self
262264

263-
def __idiv__(self, other, flags=0):
265+
def __ifloordiv__(self, other, flags=0):
264266
'''
265267
Inplace modification of the array. When possible, it runs the operation in the engine.
266268
@@ -272,27 +274,27 @@ def __idiv__(self, other, flags=0):
272274
self._lib.Batch_Int32(
273275
*ptr_cnt,
274276
self._idx,
275-
self._lib.BatchOperation_Multiply,
276-
1 / other,
277+
self._lib.BatchOperation_Divide,
278+
other,
277279
flags
278280
)
279281
return self
280282

281283
if len(other) != len(batch):
282284
raise ValueError(f"Number of elements ({len(other)}) doesn't match the batch size ({len(batch)})")
283285

284-
data = self.to_array() / other
285-
data, data_ptr, _ = batch._prepare_int32_array(data)
286-
self._lib.Batch_SetInt32Array(
286+
data, data_ptr, _ = batch._prepare_int32_array(other)
287+
self._lib.Batch_Int32Array(
287288
*ptr_cnt,
288289
self._idx,
290+
self._lib.BatchOperation_Divide,
289291
data_ptr,
290292
flags
291293
)
292294
batch._check_for_error()
293295
return self
294296

295-
idiv = __idiv__
297+
idiv = __floordiv__
296298
imul = __imul__
297299
iadd = __iadd__
298300
isub = __isub__

altdss/Batch.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def FullName(self) -> List[str]:
3131
self._check_for_error()
3232
return res
3333

34-
def _get_batch_float_func(self, funcname):
34+
def _get_batch_float64_func(self, funcname):
3535
func = self._ffi.addressof(self._api_util.lib_unpatched, funcname)
3636
res = self._get_float64_array(self._lib.Batch_GetFloat64FromFunc, *self._get_ptr_cnt(), func)
3737
self._check_for_error()
@@ -281,9 +281,10 @@ def _set_batch_float64_array(self, idx: int, value: Union[BatchFloat64ArrayProxy
281281
if data_cnt != len(self):
282282
raise ValueError("Number of elements must match")
283283

284-
self._lib.Batch_SetFloat64Array(
284+
self._lib.Batch_Float64Array(
285285
*ptr_cnt,
286286
idx,
287+
self._lib.BatchOperation_Set,
287288
data_ptr,
288289
flags
289290
)
@@ -312,9 +313,10 @@ def _set_batch_int32_array(self, idx: int, value: Union[BatchInt32ArrayProxy, in
312313
if data_cnt != len(self):
313314
raise ValueError("Number of elements must match")
314315

315-
self._lib.Batch_SetInt32Array(
316+
self._lib.Batch_Int32Array(
316317
*ptr_cnt,
317318
idx,
319+
self._lib.BatchOperation_Set,
318320
data_ptr,
319321
flags
320322
)

altdss/CircuitElement.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def NumConductors(self) -> int:
6363
'''
6464
return self._lib.Alt_CE_Get_NumConductors(self._ptr)
6565

66-
def NumPhases(self) -> int:
66+
def NumPhases(self) -> int: #TODO remove? Redundant
6767
'''
6868
Number of phases
6969

altdss/PDElement.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def AccumulatedL(self) -> Float64Array:
182182
183183
Original COM help: https://opendss.epri.com/AccumulatedL.html
184184
'''
185-
return self._get_batch_float_func("Alt_PDE_Get_AccumulatedL")
185+
return self._get_batch_float64_func("Alt_PDE_Get_AccumulatedL")
186186

187187
def Lambda(self) -> Float64Array:
188188
'''
@@ -192,7 +192,7 @@ def Lambda(self) -> Float64Array:
192192
193193
Original COM help: https://opendss.epri.com/Lambda1.html
194194
'''
195-
return self._get_batch_float_func("Alt_PDE_Get_Lambda")
195+
return self._get_batch_float64_func("Alt_PDE_Get_Lambda")
196196

197197
def NumCustomers(self) -> Int32Array:
198198
'''
@@ -238,7 +238,7 @@ def TotalMiles(self) -> Float64Array:
238238
239239
Original COM help: https://opendss.epri.com/TotalMiles1.html
240240
'''
241-
return self._get_batch_float_func("Alt_PDE_Get_TotalMiles")
241+
return self._get_batch_float64_func("Alt_PDE_Get_TotalMiles")
242242

243243
def SectionID(self) -> Int32Array:
244244
'''

docs/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ relevant. See [DSS C-API's repository](https://github.com/dss-extensions/dss_cap
1212

1313
- NonUniformBatch: allow `batch[idx]` to get a single element by index.
1414
- Setters: allow using `None` to clear object references (e.g. `altdss.Load[0].Daily = None`)
15+
- ArrayProxy:
16+
- Fix `BatchFloat64ArrayProxy.to_list()`. It was returning an array instead a list.
17+
- Accepts lists for in-place sub, e.g. `arrayProxy -= [1.1, 1.4]` now works as expected.
18+
- Use new low-level operations for in-place operations with array values
1519

1620

1721
## 0.2.1

tests/test_alt.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
cls = getattr(altdss, cname)
5151
if not len(cls):
5252
continue
53+
54+
_ = cls.to_json()
55+
56+
print(cls, cls._sync_cls_idx, len(cls))
5357

5458
print('=' * 40)
5559
c = cls[0]

0 commit comments

Comments
 (0)