Skip to content

Commit c93cd2f

Browse files
committed
merge origin/main
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
2 parents 62c6cde + 00a7d2d commit c93cd2f

File tree

9 files changed

+336
-120
lines changed

9 files changed

+336
-120
lines changed

.github/workflows/citations.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
name: Validate citation
6+
7+
on:
8+
# run pipeline on push event of main branch, or when CITATIONS path has changed
9+
push:
10+
branches:
11+
- main
12+
paths:
13+
- CITATION.cff
14+
- .github/workflows/citations.yml
15+
pull_request:
16+
paths:
17+
- CITATION.cff
18+
- .github/workflows/citations.yml
19+
# run pipeline from another workflow
20+
workflow_call:
21+
# run this workflow manually from the Actions tab
22+
workflow_dispatch:
23+
24+
concurrency:
25+
group: ${{ github.workflow }}-${{ github.ref }}-citations
26+
cancel-in-progress: true
27+
28+
jobs:
29+
validate-citations:
30+
runs-on: ubuntu-24.04
31+
steps:
32+
- name: checkout
33+
uses: actions/checkout@v4
34+
- name: Install R
35+
run: |
36+
sudo apt-get update && sudo apt-get install -y r-base
37+
- name: Validate CITATION.cff
38+
uses: dieghernan/cff-validator@v4

CITATION.cff

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
cff-version: 1.2.0
6+
message: "If you are using Power Grid Model in your research work, please consider citing our library as below."
7+
8+
title: "PowerGridModel/power-grid-model-ds"
9+
url: "https://github.com/PowerGridModel/power-grid-model-ds"
10+
license: "MPL-2.0"
11+
authors:
12+
- family-names: "Schouten"
13+
given-names: "Jaap"
14+
email: Jaap.Schouten@Alliander.com
15+
affiliation: "Alliander"
16+
- family-names: "Baaijen"
17+
given-names: "Thijs"
18+
email: Thijs.Baaijen@Alliander.com
19+
affiliation: "Alliander"
20+
- family-names: "Koppen"
21+
given-names: "Vincent"
22+
email: Vincent.Koppen@Alliander.com
23+
- family-names: "Voort"
24+
name-particle: "van der"
25+
given-names: "Sven"
26+
email: Sven.van.der.Voort@Alliander.com
27+
- name: "Contributors to the LF Energy project Power Grid Model"
28+
contact:
29+
- name: "LF Energy project Power Grid Model"
30+
email: "powergridmodel@lists.lfenergy.org"
31+
32+
references:
33+
- title: "PowerGridModel/power-grid-model"
34+
repository-code: "https://github.com/PowerGridModel/power-grid-model"
35+
doi: "10.5281/zenodo.8054429"
36+
license: "MPL-2.0"
37+
type: software-code
38+
authors:
39+
- family-names: "Xiang"
40+
given-names: "Yu"
41+
email: "Tony.Xiang@Alliander.com"
42+
affiliation: "Alliander"
43+
- family-names: "Salemink"
44+
given-names: "Peter"
45+
email: "Peter.Salemink@Alliander.com"
46+
affiliation: "Alliander"
47+
- family-names: "Westering"
48+
name-particle: "van"
49+
given-names: "Werner"
50+
email: Werner.van.Westering@Alliander.com
51+
affiliation: "Alliander"
52+
- family-names: "Bharambe"
53+
given-names: "Nitish"
54+
email: "Nitish.Bharambe@Alliander.com"
55+
affiliation: "Alliander"
56+
- family-names: "Govers"
57+
given-names: "Martinus"
58+
email: "Martijn.Govers@Alliander.com"
59+
affiliation: "Alliander"
60+
orcid: "https://orcid.org/0009-0008-6890-8353"
61+
- family-names: "Bogaard"
62+
name-particle: "van den"
63+
given-names: "Jonas"
64+
email: "Jonas.van.den.Bogaard@Alliander.com"
65+
affiliation: "Alliander"
66+
- family-names: "Stoeller"
67+
given-names: "Bram"
68+
- family-names: "Wang"
69+
given-names: "Zhen"
70+
email: "Zhen.Wang@Alliander.com"
71+
affiliation: "Alliander"
72+
- family-names: "Guo"
73+
given-names: "Jerry"
74+
email: "Jerry.Jinfeng.Guo@Alliander.com"
75+
affiliation: "Alliander"
76+
- family-names: "Jagutis"
77+
given-names: "Laurynas"
78+
email: "Laurynas.Jagutis@Alliander.com"
79+
affiliation: "Alliander"
80+
- family-names: "Wang"
81+
given-names: "Chenguang"
82+
email: "Chenguang.Wang@Alliander.com"
83+
affiliation: "Alliander"
84+
- family-names: "Raalte"
85+
name-particle: "van"
86+
given-names: "Marc"
87+
email: "Marc.van.Raalte@Alliander.com"
88+
affiliation: "Alliander"
89+
- family-names: "Figueroa Manrique"
90+
given-names: "Santiago"
91+
email: "Santiago.Figueroa.Manrique@Alliander.com"
92+
affiliation: "Alliander"
93+
- name: "Contributors to the LF Energy project Power Grid Model"
94+
95+
- title: "Power grid model: A high-performance distribution grid calculation library"
96+
doi: "10.1049/icp.2023.0633"
97+
authors:
98+
- family-names: "Xiang"
99+
given-names: "Yu"
100+
email: Tony.Xiang@Alliander.com
101+
affiliation: "Alliander"
102+
- family-names: "Salemink"
103+
given-names: "Peter"
104+
email: Peter.Salemink@Alliander.com
105+
affiliation: "Alliander"
106+
- family-names: "Stoeller"
107+
given-names: "Bram"
108+
- family-names: "Bharambe"
109+
given-names: "Nitish"
110+
email: Nitish.Bharambe@Alliander.com
111+
affiliation: "Alliander"
112+
- family-names: "Westering"
113+
name-particle: "van"
114+
given-names: "Werner"
115+
email: Werner.van.Westering@Alliander.com
116+
affiliation: "Alliander"
117+
conference:
118+
name: "CIRED 2023 - The 27th International Conference and Exhibition on Electricity Distribution"
119+
type: conference-paper
120+
year: 2023
121+
volume: 2023
122+
pages: "1-5"
123+
124+
- title: "PowerGridModel/power-grid-model-io"
125+
repository-code: "https://github.com/PowerGridModel/power-grid-model-io"
126+
doi: "10.5281/zenodo.8059257"
127+
license: "MPL-2.0"
128+
type: software-code
129+
authors:
130+
- family-names: "Xiang"
131+
given-names: "Yu"
132+
email: "Tony.Xiang@Alliander.com"
133+
affiliation: "Alliander"
134+
- family-names: "Salemink"
135+
given-names: "Peter"
136+
email: "Peter.Salemink@Alliander.com"
137+
affiliation: "Alliander"
138+
- family-names: "Bharambe"
139+
given-names: "Nitish"
140+
email: "Nitish.Bharambe@Alliander.com"
141+
affiliation: "Alliander"
142+
- family-names: "Govers"
143+
given-names: "Martinus"
144+
email: "Martijn.Govers@Alliander.com"
145+
affiliation: "Alliander"
146+
orcid: "https://orcid.org/0009-0008-6890-8353"
147+
- family-names: "Bogaard"
148+
name-particle: "van den"
149+
given-names: "Jonas"
150+
email: "Jonas.van.den.Bogaard@Alliander.com"
151+
affiliation: "Alliander"
152+
- family-names: "Stoeller"
153+
given-names: "Bram"
154+
- family-names: "Wang"
155+
given-names: "Zhen"
156+
email: "Zhen.Wang@Alliander.com"
157+
affiliation: "Alliander"
158+
- family-names: "Guo"
159+
given-names: "Jerry"
160+
email: "Jerry.Jinfeng.Guo@Alliander.com"
161+
affiliation: "Alliander"
162+
- family-names: "Jagutis"
163+
given-names: "Laurynas"
164+
email: "Laurynas.Jagutis@Alliander.com"
165+
affiliation: "Alliander"
166+
- family-names: "Wang"
167+
given-names: "Chenguang"
168+
email: "Chenguang.Wang@Alliander.com"
169+
affiliation: "Alliander"
170+
- family-names: "Figueroa Manrique"
171+
given-names: "Santiago"
172+
email: "Santiago.Figueroa.Manrique@Alliander.com"
173+
affiliation: "Alliander"
174+
- name: "Contributors to the LF Energy project Power Grid Model"

tests/performance/_constants.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66
"dtype = [('id', '<i8'), ('test_int', '<i8'), ('test_float', '<f8'), ('test_str', '<U50'), ('test_bool', '?')]; "
77
)
88

9-
SETUP_CODES = {
10-
"structured": "import numpy as np;" + NUMPY_DTYPE + "input_array = np.zeros({array_size}, dtype=dtype)",
11-
"rec": "import numpy as np;" + NUMPY_DTYPE + "input_array = np.recarray(({array_size},),dtype=dtype)",
12-
"fancy": "from tests.conftest import FancyTestArray; input_array=FancyTestArray.zeros({array_size});"
13-
+ "import numpy as np;input_array.id = np.arange({array_size})",
9+
ARRAY_SETUP_CODES = {
10+
"structured": "import numpy as np;" + NUMPY_DTYPE + "input_array = np.zeros({size}, dtype=dtype)",
11+
"rec": "import numpy as np;" + NUMPY_DTYPE + "input_array = np.recarray(({size},),dtype=dtype)",
12+
"fancy": "from tests.conftest import FancyTestArray; input_array=FancyTestArray.zeros({size});"
13+
+ "import numpy as np;input_array.id = np.arange({size})",
1414
}
1515

1616
GRAPH_SETUP_CODES = {
1717
"rustworkx": "from power_grid_model_ds import Grid;"
1818
+ "from power_grid_model_ds.generators import RadialGridGenerator;"
1919
+ "from power_grid_model_ds.graph_models import RustworkxGraphModel;"
20-
+ "grid=RadialGridGenerator(nr_nodes={graph_size}, grid_class=Grid, graph_model=RustworkxGraphModel).run()",
20+
+ "grid=RadialGridGenerator(nr_nodes={size}, grid_class=Grid, graph_model=RustworkxGraphModel).run()",
2121
}
2222

2323
SINGLE_REPEATS = 1000

tests/performance/_helpers.py

Lines changed: 29 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,100 +4,57 @@
44

55
import inspect
66
import timeit
7-
from typing import Generator
7+
from itertools import product
8+
from typing import Generator, Union
89

9-
from tests.performance._constants import GRAPH_SETUP_CODES, SETUP_CODES
10-
11-
12-
def do_performance_test(code_to_test: str | dict[str, str], array_sizes: list[int], repeats: int):
13-
"""Run the performance test for the given code."""
1410

11+
def do_performance_test(
12+
code_to_test: Union[str, dict[str, str], list[str]],
13+
size_list: list[int],
14+
repeats: int,
15+
setup_codes: dict[str, str],
16+
):
17+
"""Generalized performance test runner."""
1518
print(f"{'-' * 20} {inspect.stack()[1][3]} {'-' * 20}")
1619

17-
for array_size in array_sizes:
20+
for size in size_list:
21+
formatted_setup_codes = {key: code.format(size=size) for key, code in setup_codes.items()}
1822
if isinstance(code_to_test, dict):
19-
code_to_test_list = [code_to_test[variant].format(array_size=array_size) for variant in SETUP_CODES]
20-
else:
21-
code_to_test_list = [code_to_test.format(array_size=array_size)] * len(SETUP_CODES)
22-
print(f"\n\tArray size: {array_size}\n")
23-
setup_codes = [setup_code.format(array_size=array_size) for setup_code in SETUP_CODES.values()]
24-
timings = _get_timings(setup_codes, code_to_test_list, repeats)
25-
26-
if code_to_test == "pass":
27-
_print_timings(timings, list(SETUP_CODES.keys()), setup_codes)
23+
code_to_test_list = [code_to_test[variant].format(size=size) for variant in setup_codes]
24+
test_generator = zip(formatted_setup_codes.items(), code_to_test_list)
25+
elif isinstance(code_to_test, list):
26+
code_to_test_list = [code.format(size=size) for code in code_to_test]
27+
test_generator = product(formatted_setup_codes.items(), code_to_test_list)
2828
else:
29-
_print_timings(timings, list(SETUP_CODES.keys()), code_to_test_list)
30-
print()
29+
test_generator = product(formatted_setup_codes.items(), [code_to_test.format(size=size)])
3130

31+
print(f"\n\tsize: {size}\n")
3232

33-
def do_graph_test(code_to_test: str | dict[str, str], graph_sizes: list[int], repeats: int):
34-
"""Run the performance test for the given code."""
33+
timings = _get_timings(test_generator, repeats=repeats)
34+
_print_timings(timings)
3535

36-
print(f"{'-' * 20} {inspect.stack()[1][3]} {'-' * 20}")
37-
38-
for graph_size in graph_sizes:
39-
if isinstance(code_to_test, dict):
40-
code_to_test_list = [code_to_test[variant] for variant in GRAPH_SETUP_CODES]
41-
else:
42-
code_to_test_list = [code_to_test] * len(GRAPH_SETUP_CODES)
43-
print(f"\n\tGraph size: {graph_size}\n")
44-
setup_codes = [setup_code.format(graph_size=graph_size) for setup_code in GRAPH_SETUP_CODES.values()]
45-
timings = _get_timings(setup_codes, code_to_test_list, repeats)
46-
47-
if code_to_test == "pass":
48-
_print_graph_timings(timings, list(GRAPH_SETUP_CODES.keys()), setup_codes)
49-
else:
50-
_print_graph_timings(timings, list(GRAPH_SETUP_CODES.keys()), code_to_test_list)
5136
print()
5237

5338

54-
def _print_test_code(code: str | dict[str, str], repeats: int):
55-
print(f"{'-' * 40}")
56-
if isinstance(code, dict):
57-
for variant, code_variant in code.items():
58-
print(f"{variant}")
59-
print(f"\t{code_variant} (x {repeats})")
60-
return
61-
print(f"{code} (x {repeats})")
62-
63-
64-
def _print_graph_timings(timings: Generator, graph_types: list[str], code_list: list[str]):
65-
for graph_type, timing, code in zip(graph_types, timings, code_list):
66-
if ";" in code:
67-
code = code.split(";")[-1]
68-
69-
code = code.replace("\n", " ").replace("\t", " ")
70-
code = f"{graph_type}: " + code
71-
72-
if isinstance(timing, Exception):
73-
print(f"\t\t{code.ljust(100)} | Not supported")
74-
continue
75-
print(f"\t\t{code.ljust(100)} | {sum(timing):.2f}s")
76-
77-
78-
def _print_timings(timings: Generator, array_types: list[str], code_list: list[str]):
79-
for array, timing, code in zip(array_types, timings, code_list):
80-
if ";" in code:
81-
code = code.split(";")[-1]
82-
83-
code = code.replace("\n", " ").replace("\t", " ")
84-
array_name = f"{array}_array"
85-
code = code.replace("input_array", array_name)
39+
def _print_timings(timings: Generator):
40+
for key, code, timing in timings:
41+
code = code.split(";")[-1].replace("\n", " ").replace("\t", " ")
42+
code = f"{key}: {code}"
8643

8744
if isinstance(timing, Exception):
8845
print(f"\t\t{code.ljust(100)} | Not supported")
8946
continue
9047
print(f"\t\t{code.ljust(100)} | {sum(timing):.2f}s")
9148

9249

93-
def _get_timings(setup_codes: list[str], test_codes: list[str], repeats: int):
50+
def _get_timings(test_generator, repeats: int):
9451
"""Return a generator with the timings for each array type."""
95-
for setup_code, test_code in zip(setup_codes, test_codes):
52+
for (key, setup_code), test_code in test_generator:
9653
if test_code == "pass":
97-
yield timeit.repeat(setup_code, number=repeats)
54+
yield key, "intialise", timeit.repeat(setup_code, number=repeats)
9855
else:
9956
try:
100-
yield timeit.repeat(test_code, setup_code, number=repeats)
57+
yield key, test_code, timeit.repeat(test_code, setup_code, number=repeats)
10158
# pylint: disable=broad-exception-caught
10259
except Exception as error: # noqa
103-
yield error
60+
yield key, test_code, error

0 commit comments

Comments
 (0)