Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## 0.2.0

Targets powerio C ABI version 4 (powerio v0.3.0); an older library or artifact
is refused at first use. Breaking.

- `to_dense` renames: `reference_bus → ref_bus_index`, `n_components →
n_islands` (both topology scalars; `ref_bus_index` is a dense 0-based index,
unlike the 1-based ids in `branch.from`/`to`).
- `PowerIO.warnings(net)`: the fidelity warnings a lossy reader attaches to the
handle, sized exactly. Unexported: `text, warnings = convert_file(...)` stays
the documented destructuring idiom.
- Zero-copy `to_arrow(...; copy=false)` columns are `ArrowColumn`s that root
the shared producer buffers, so a column extracted from its `ArrowTable`
stays valid on its own. `close(t)` releases the buffers eagerly; the table is
no longer a finalizable object, so 0.1.0 code calling `finalize(t)` must move
to `close(t)`.
- Use after free hardening: every helper that lowers a `NetworkHandle` to a raw
pointer runs its ccalls under `GC.@preserve`; dense extractors pass caps and
verify the returned totals.

## 0.1.0

- `read_gridfm` / `read_gridfm_scenarios` read a gridfm-datakit Parquet dataset
Expand Down
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ After each powerio binary release:
regenerates Artifacts.toml from the release tarballs and opens a PR when
anything changed. If the release bumped `PIO_ABI_VERSION`, update the
constant and the affected ccalls in that PR (see "ABI lockstep" above).
Never register a version whose `PIO_ABI_VERSION` does not match the ABI of
the tarballs Artifacts.toml points at: the bundled artifact would fail the
load handshake, so the registered package errors at first use for everyone
on the default install path.
2. Merge the artifacts PR if one was opened, then dispatch "Register Package"
with the new version (no leading v, or major/minor/patch to bump). It
commits the Project.toml bump to main and posts the
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PowerIO"
uuid = "05ed8b54-f668-4096-9d0d-e8c3dd9dc169"
authors = ["Sam Talkington <samtalki@users.noreply.github.com>"]
version = "0.1.0"
version = "0.2.0"

[deps]
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
Expand Down
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Supported formats (each reads and writes, so any pair converts):
- [PowerWorld](https://www.powerworld.com/WebHelp/Content/MainDocumentation_HTML/Case_Formats.htm) `.aux`
- [PowerModels.jl](https://github.com/lanl-ansi/PowerModels.jl) network data JSON
- [egret](https://pypi.org/project/gridx-egret/) `ModelData` JSON
- [pandapower](https://www.pandapower.org/) network JSON

A same-format round trip is byte exact; cross-format conversion reports fields
the target cannot represent as warnings.
Expand Down Expand Up @@ -77,6 +78,7 @@ to_matpower(net) # ::String, byte exact when the input was MAT
to_json(net) # the JSON transport
to_format(net, "powermodels-json") # (text, warnings)
from_json(to_json(net)) # Network with a live handle
PowerIO.warnings(net) # fidelity warnings the reader attached to net
```

`to_normalized` derives a computation-ready copy: powers per unit, angles in
Expand All @@ -96,21 +98,23 @@ d = to_dense(net) # or to_dense("case14.m") for parse + extract
d.n, d.m, d.ng # bus / branch / generator counts
d.bus_ids # 1-based ids; row k of every per-bus table is bus_ids[k]
d.branch.from, d.branch.x # branch endpoints and reactances
d.reference_bus, d.n_components, d.is_radial
d.ref_bus_index, d.n_islands, d.is_radial
```

`to_arrow` brings one table across the Arrow C Data Interface (needs the library
Comment thread
samtalki marked this conversation as resolved.
built with `--features arrow`; `arrow_available()` reports it). By default it
returns a NamedTuple of **owned** Julia Vectors (Tables.jl-shaped, flows into
`Arrow.write`, `DataFrame`, etc.), so there is no lifetime caveat. `copy=false`
returns a zero-copy `ArrowTable` whose columns view the producer's memory; keep it
alive while reading them. For the numeric tables alone, `to_dense` is a copy-free,
`unsafe_wrap`-free fast path (the C ABI fills Julia-owned buffers).
returns a zero-copy `ArrowTable` whose columns view the producer's memory; each
column roots the shared buffers, so a column extracted from the table stays
valid on its own, and `close(z)` frees the buffers without waiting for GC. For
the numeric tables alone, `to_dense` is a copy-free, `unsafe_wrap`-free fast
path (the C ABI fills Julia-owned buffers).

```julia
t = to_arrow(net, :branch) # :bus, :branch, :gen, :load, :shunt; owned columns
t.from, t.x, t.tap
z = to_arrow(net, :branch; copy=false) # zero-copy views; keep `z` alive while reading
z = to_arrow(net, :branch; copy=false) # zero-copy views; close(z) releases eagerly
```

`read_gridfm` reads a gridfm-datakit Parquet dataset back into a `Network` — the
Expand Down
2 changes: 1 addition & 1 deletion docs/binary.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ per-platform binary; users never compile it.

1. A version tag on [eigenergy/powerio](https://github.com/eigenergy/powerio)
triggers its `release-binaries` workflow, which builds
`libpowerio_capi.<triplet>.tar.gz` with the `arrow` feature for Linux glibc
`libpowerio_capi.<triplet>.tar.gz` with the `arrow` and `gridfm` features for Linux glibc
(x86_64, aarch64), macOS (x86_64, arm64), and Windows (x86_64), and
attaches the five tarballs to the GitHub release. Each tarball
holds the cdylib under `lib/` (`bin/` on Windows), the C header under
Expand Down
25 changes: 13 additions & 12 deletions gen/build_tarballs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,30 @@
using BinaryBuilder

name = "PowerIO"
# Tracks the powerio-capi *crate* version (the binary), unified with the
# PowerIO.jl *package* version for the first release.
version = v"0.0.1"
# Tracks the powerio-capi *crate* version (the binary), not the PowerIO.jl
# package version: the binding is 0.2.0 while the v4 binary ships as powerio
# v0.3.0.
version = v"0.3.0"

# Must pin a commit reporting `PIO_ABI_VERSION` 3: the binding's load-time
# handshake refuses anything else, and `to_arrow` needs the Arrow export. Pinned
# to the v0.0.1 release tag (the right long-term anchor for a reproducible
# build and the Yggdrasil submission).
# Must pin a commit reporting `PIO_ABI_VERSION` 4: the binding's load-time
# handshake refuses anything else. Pinned to the powerio#116 head (the ABI v4
# lockstep partner of this release); move to the v0.3.0 release tag once it is
# cut (the right long-term anchor for a reproducible build and the Yggdrasil
# submission).
sources = [
GitSource("https://github.com/eigenergy/powerio.git",
"db944afe3819b2efd67060eda056003846f8e8ad"),
"b92d9abee9a8e22df5f79d3a9d41caf30813fa1f"),
]

# `cargo build` writes the cdylib under target/<rust_target>/release. Names differ
# per platform: lib*.so (linux), lib*.dylib (macos), *.dll (+ *.dll.a import lib)
# (windows, no lib prefix, ships under bin/). `install_license` keeps AutoMerge happy.
script = raw"""
cd $WORKSPACE/srcdir/powerio
# --features arrow ships pio_export_arrow (the zero-copy Arrow C Data Interface
# export to_arrow calls); --features gridfm ships pio_read_gridfm (the
# --features arrow ships pio_to_arrow (the zero-copy Arrow C Data Interface
# export to_arrow calls); --features gridfm ships pio_read_dir / pio_scenario_ids (the
# gridfm-datakit Parquet reader read_gridfm calls). The base ABI is identical
# without them. NOTE: the `sources` commit above must include pio_read_gridfm
# (powerio PR #70 and later) before re-cutting the artifact with gridfm enabled.
# without them.
cargo build --release -p powerio-capi --target ${rust_target} --features arrow,gridfm
out=target/${rust_target}/release
if [[ "${target}" == *-mingw32* ]]; then
Expand Down
Loading