Skip to content

Commit 1f2c28f

Browse files
committed
First draft of extensions core specification
1 parent e3b2866 commit 1f2c28f

File tree

2 files changed

+73
-4
lines changed

2 files changed

+73
-4
lines changed

bmi.sidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ package csdms version 3.0-alpha1 {
88
int get_bmi_version(out string version);
99

1010
// Model control: initialize, run, finalize (IRF)
11-
int initialize(in string config_file);
11+
int initialize(in string config_file, in array<string, 1> requested_extensions, out array<string, 1> supported_extensions);
1212
int update();
1313
int update_until(in double time);
1414
int finalize();

docs/source/bmi.control_funcs.md

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,50 @@ updating.
1919
:::{tab-item} SIDL
2020
:sync: sidl
2121
```java
22-
int initialize(in string config_file);
22+
int initialize(in string config_file, in array<string, 1> requested_extensions, out array<string, 1> supported_extensions);
2323
```
2424
:::
2525

2626
:::{tab-item} Python
2727
:sync: python
2828
```python
29-
def initialize(self, config_file: str) -> None:
29+
def initialize(self, config_file: str, requested_extensions: list[str]) -> list[str]:
3030
```
3131
:::
3232

3333
:::{tab-item} c
3434
:sync: c
3535
```c
36-
int initialize(void *self, char *config_file);
36+
int initialize(void *self, char *config_file, char const **requested_extensions, char const **supported_extensions);
3737
```
3838
:::
3939
::::
4040
4141
The `initialize` function accepts a string argument that gives the
4242
path to its {term}`configuration file`.
43+
4344
This function should perform all tasks that are to take place before
4445
entering the model's time loop. Models should be refactored, if
4546
necessary, to read their inputs (which could include filenames for
4647
other input files) from a configuration file.
48+
4749
BMI does not impose any constraint on how configuration files are
4850
formatted.
4951
52+
It also takes an array of strings `requested_extensions` describing
53+
the extensions that the caller would like to use if the the model
54+
supports it. The model should determine which extensions it can
55+
support, given its code and potentially the contents of the
56+
configuration file. The supported extensions should be listed in
57+
elements of the output array `supported_extensions`.
58+
59+
Use of extensions is completely optional within the scope of the core
60+
BMI specification. Individual callers or models may require particular
61+
extensions to provide their functionality. In the case where such an
62+
extension is missing from the requested or supported extensions arrays
63+
in or after the `initialize` call (respectively), the model or caller
64+
should fail accordingly.
65+
5066
**Implementation notes**
5167
5268
- Models should be refactored, if necessary, to use a configuration
@@ -58,6 +74,59 @@ formatted.
5874
a string -- a basic type in these languages.
5975
- In C and Fortran, an integer status code indicating success (zero) or failure (nonzero)
6076
is returned. In C++, Java, and Python, an exception is raised on failure.
77+
- In C, the length of `supported_extensions` is upper-bounded by
78+
`requested_extensions`, and so should be allocated
79+
accordingly. Models should copy pointers from `requested_extensions`
80+
to `supported_extensions` as appropriate. This allows the caller to
81+
retain ownership.
82+
83+
**Extensions Rationale**
84+
85+
- The set of extensions that a caller can support should
86+
be known in advance, since they will have their own semantics beyond
87+
those of this BMI specification. Thus, it does not make sense in
88+
this setting for models to advertise any extension that the caller
89+
does not support.
90+
- The set of extensions that a model supports may be
91+
determined by the particular configuration with which it's
92+
initialized. Thus, this cannot be queried before the `initialize()`
93+
function.
94+
- Extensions may require additional initialization steps. Thus, they
95+
are requested in the `initialize()` function to indicate which ones
96+
will be used if available. If they require added information or
97+
setup behavior from the caller, as described in their own
98+
specification, the caller is responsible for conforming to that
99+
specification.
100+
- If a caller requests a particular extension and a model indicates
101+
support for it, the model may ultimately *require* that the caller
102+
use the extension as it is specified. This implies, for instance,
103+
that an extension requiring additional setup before the model enters
104+
its time loop (e.g. setting an MPI communicator) may mean that the
105+
model will fail if that setup is not done before other BMI functions
106+
are called.
107+
108+
109+
(get-extension)=
110+
111+
## *get_extension*
112+
113+
:::{tab-item} c
114+
:sync: c
115+
```c
116+
int get_extension(void *self, char const *name, void **extension_object);
117+
```
118+
:::
119+
::::
120+
121+
For extensions specified to provide additional functions, these should
122+
be accessed by the caller obtaining an associated extension object
123+
with those functions as members.
124+
125+
**Implementation Notes**
126+
127+
- In C and C++, the `extension_object` instance is owned by the model
128+
object, and should be suitably handled by a call to `finalize(self)`
129+
or `model->Finalize()`, respectively.
61130

62131
(update)=
63132

0 commit comments

Comments
 (0)