From e3b2866236998031349544d9fd504b61b3702a58 Mon Sep 17 00:00:00 2001 From: Phil Miller Date: Mon, 25 Aug 2025 11:36:28 -0700 Subject: [PATCH 1/4] Bump version in interface to 3.0 to reflect API breakage and intention for major version --- bmi.sidl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bmi.sidl b/bmi.sidl index 9c3b0fb..30766a8 100644 --- a/bmi.sidl +++ b/bmi.sidl @@ -1,8 +1,8 @@ // // The Basic Model Interface (BMI) // -package csdms version 2.1-dev.0 { - interface bmi { +package csdms version 3.0-alpha1 { + interface bmi3 { // Model and BMI metadata int get_bmi_version(out string version); From 99a2bc6b1a319930e2b49affaa285b725667c0a7 Mon Sep 17 00:00:00 2001 From: Phil Miller Date: Fri, 21 Aug 2026 08:47:47 -0700 Subject: [PATCH 2/4] Move get_component_name over to metadata functions --- docs/source/bmi.info_funcs.md | 39 ------------------------------- docs/source/bmi.metadata_funcs.md | 39 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/docs/source/bmi.info_funcs.md b/docs/source/bmi.info_funcs.md index 31efc1a..98deb05 100644 --- a/docs/source/bmi.info_funcs.md +++ b/docs/source/bmi.info_funcs.md @@ -7,45 +7,6 @@ and the model's {term}`exchange items ` -- the variables that the model can use from and provide to other models that have a BMI. -(get-component-name)= - -## *get_component_name* - -::::{tab-set} -:sync-group: lang - -:::{tab-item} SIDL -:sync: sidl -```java -int get_component_name(out string name); -``` -::: - -:::{tab-item} Python -:sync: python -```python -def get_component_name(self) -> str: -``` -::: -:::{tab-item} c -:sync: c -```c -int get_component_name(void *self, char *name); -``` -::: -:::: - -This function supplies the name of the model component as a string. -There are no restrictions on the name, -but it should be unique to prevent conflicts with other components. - -**Implementation notes** - -- In C and Fortran, the *name* argument is a a character array, and an integer - status code indicating success (zero) or failure (nonzero) is returned. -- In C++, Java, and Python, this argument is omitted, and a string -- a basic type - in these languages -- is returned from the function. - (get-input-item-count)= ## *get_input_item_count* diff --git a/docs/source/bmi.metadata_funcs.md b/docs/source/bmi.metadata_funcs.md index 6980d13..9db9647 100644 --- a/docs/source/bmi.metadata_funcs.md +++ b/docs/source/bmi.metadata_funcs.md @@ -44,3 +44,42 @@ This function supplies the version of BMI implemented as a string. status code indicating success (zero) or failure (nonzero) is returned. - In C++, Java, and Python, this argument is omitted, and a string -- a basic type in these languages -- is returned from the function. + +(get-component-name)= + +## *get_component_name* + +::::{tab-set} +:sync-group: lang + +:::{tab-item} SIDL +:sync: sidl +```java +int get_component_name(out string name); +``` +::: + +:::{tab-item} Python +:sync: python +```python +def get_component_name(self) -> str: +``` +::: +:::{tab-item} c +:sync: c +```c +int get_component_name(void *self, char *name); +``` +::: +:::: + +This function supplies the name of the model component as a string. +There are no restrictions on the name, +but it should be unique to prevent conflicts with other components. + +**Implementation notes** + +- In C and Fortran, the *name* argument is a a character array, and an integer + status code indicating success (zero) or failure (nonzero) is returned. +- In C++, Java, and Python, this argument is omitted, and a string -- a basic type + in these languages -- is returned from the function. From a02217a915680b0b0d820c2438ecbeefd824b4a8 Mon Sep 17 00:00:00 2001 From: Phil Miller Date: Mon, 25 Aug 2025 11:36:34 -0700 Subject: [PATCH 3/4] Preliminary wording for defining sets of variables exported by a model --- bmi.sidl | 8 +- docs/source/bmi.info_funcs.md | 136 +++++++--------------------------- docs/source/bmi.spec.md | 6 +- 3 files changed, 31 insertions(+), 119 deletions(-) diff --git a/bmi.sidl b/bmi.sidl index 30766a8..8e5dfee 100644 --- a/bmi.sidl +++ b/bmi.sidl @@ -15,10 +15,10 @@ package csdms version 3.0-alpha1 { // Model information int get_component_name(out string name); - int get_input_item_count(out int count); - int get_output_item_count(out int count); - int get_input_var_names(out array names); - int get_output_var_names(out array names); + + // Variable set information + int get_varset_member_count(in string set_name, out int count); + int get_varset_members(in string set_name, out array names); // Variable information int get_var_grid(in string name, out int grid); diff --git a/docs/source/bmi.info_funcs.md b/docs/source/bmi.info_funcs.md index 98deb05..e764c91 100644 --- a/docs/source/bmi.info_funcs.md +++ b/docs/source/bmi.info_funcs.md @@ -7,121 +7,83 @@ and the model's {term}`exchange items ` -- the variables that the model can use from and provide to other models that have a BMI. -(get-input-item-count)= +(get-varset-member-count)= -## *get_input_item_count* +## *get_varset_member_count* ::::{tab-set} :sync-group: lang :::{tab-item} SIDL :sync: sidl -```java -int get_input_item_count(out int count); -``` -::: -:::{tab-item} Python -:sync: python -```python -def get_input_item_count(self) -> int: -``` -::: -:::{tab-item} c -:sync: c -```c -int get_input_item_count(void *self, int *count); -``` -::: -:::: - -The number of variables the model can use from other models -implementing a BMI. -Also the number of variables that can be set with {ref}`set-value`. - -**Implementation notes** - -- In C++, Java, and Python, the argument is omitted and the count is returned - from the function. -- In C and Fortran, an integer status code indicating success (zero) or failure - (nonzero) is returned. - -(get-output-item-count)= - -## *get_output_item_count* - -::::{tab-set} -:sync-group: lang - -:::{tab-item} SIDL -:sync: sidl ```java -int get_output_item_count(out int count); +int get_varset_member_count(in string set_name, out int count); ``` ::: - :::{tab-item} Python :sync: python ```python -def get_output_item_count(self) -> int: +def get_varset_member_count(self, set_name: str) -> int: ``` ::: :::{tab-item} c :sync: c ```c -int get_output_item_count(void *self, int *count); +int get_varset_member_count(void *self, const char *name, int *count); ``` ::: :::: -The number of variables the model can provide other models -implementing a BMI. -Also the number of variables that can be retrieved with {ref}`get-value`. +Gets the number of exchange items in a particular set exposed by the model. **Implementation notes** -- In C++, Java, and Python, the argument is omitted and the count is - returned from the function. -- In C and Fortran, an integer status code indicating success (zero) or failure - (nonzero) is returned. +- In C++, Java, and Python, the *count* argument is omitted and the count + is returned from the function. +- In C and Fortran, an integer status code indicating success (BMI_SUCCESS) or + failure (BMI_FAILURE) is returned. -(get-input-var-names)= +(get-varset-members)= -## *get_input_var_names* +## *get_varset_members* ::::{tab-set} :sync-group: lang :::{tab-item} SIDL :sync: sidl + ```java -int get_input_var_names(out array names); +int get_varset_members(in string set_name, out array names); ``` ::: :::{tab-item} Python :sync: python ```python -def get_input_var_names(self) -> tuple[str, ...]: +def get_varset_members(self, set_name: str) -> tuple[str, ...]: ``` ::: :::{tab-item} c :sync: c ```c -int get_input_var_names(void *self, char **names); +int get_varset_members(void *self, const char *name, char const* const* members); ``` ::: :::: -Gets an array of names for the variables the model can use from other -models implementing a BMI. -The length of the array is given by {ref}`get-input-item-count`. +Gets an array of names for the variables the model publishes in the requested set. +The length of the array is given by {ref}`get-varset-member-count`. The names are preferably in the form of CSDMS {term}`Standard Names`. -Standard Names enable a modeling framework to determine whether an -input variable in one model is equivalent to, or compatible with, -an output variable in another model. +Standard Names enable a modeling framework to determine whether a +variable in one model is equivalent to, or compatible with, +a corresponding variable in another model. This allows the framework to automatically connect components. Standard Names do not have to be used within the model. +Available variable sets are defined by this specification, extensions, +or private conventions between the caller and model. + **Implementation notes** - In C and Fortran, the names are passed back as an array of character @@ -135,53 +97,5 @@ Standard Names do not have to be used within the model. function in a tuple, a standard container in the language. - A model might have no input variables. -(get-output-var-names)= - -## *get_output_var_names* - -::::{tab-set} -:sync-group: lang - -:::{tab-item} SIDL -:sync: sidl -```java -int get_output_var_names(out array names); -``` +:::{include} links.md ::: - -:::{tab-item} Python -:sync: python -```python -def get_output_var_names(self) -> tuple[str, ...]: -``` -::: -:::{tab-item} c -:sync: c -```c -int get_output_var_names(void *self, char **names); -``` -::: -:::: - -Gets an array of names for the variables the model can provide to other -models implementing a BMI. -The length of the array is given by {ref}`get-output-item-count`. -The names are preferably in the form of CSDMS {term}`Standard Names`. -Standard Names enable a modeling framework to determine whether an -input variable in one model is equivalent to, or compatible with, -an output variable in another model. -This allows the framework to automatically connect components. -Standard Names do not have to be used within the model. - -**Implementation notes** - -- In C and Fortran, the names are passed back as an array of character - pointers (because the variable names could have differing lengths), and an - integer status code indicating success (zero) or failure (nonzero) is returned. -- In C++, the argument is omitted and the names are returned from the - function in a vector, a standard container in the language. -- In Java, the argument is omitted and the names are returned from the - function in a string array, a standard container in the language. -- In Python, the argument is omitted and the names are returned from the - function in a tuple, a standard container in the language. -- A model may have no output variables. diff --git a/docs/source/bmi.spec.md b/docs/source/bmi.spec.md index c94eace..8f01edc 100644 --- a/docs/source/bmi.spec.md +++ b/docs/source/bmi.spec.md @@ -35,10 +35,8 @@ grouped by functional category. | {ref}`update-until` | Advance model state until the given time. | | {ref}`finalize` | Perform tear-down tasks for the model. | | {ref}`get-component-name` | Name of the model. | -| {ref}`get-input-item-count` | Count of a model's input variables. | -| {ref}`get-output-item-count` | Count of a model's output variables. | -| {ref}`get-input-var-names` | List of a model's input variables. | -| {ref}`get-output-var-names` | List of a model's output variables. | +| {ref}`get-varset-item-count` | Count of a model's variables in a set. | +| {ref}`get-varset-members` | List of a model's variables in a set. | | {ref}`get-var-grid` | Get the grid identifier for a variable. | | {ref}`get-var-type` | Get the data type of a variable. | | {ref}`get-var-units` | Get the units of a variable. | From 5393121a5f0484d53c698ebc26e22ffd1cba7d35 Mon Sep 17 00:00:00 2001 From: Phil Miller Date: Fri, 21 Aug 2026 08:42:18 -0700 Subject: [PATCH 4/4] Rearrange variable functions --- docs/source/bmi.var_funcs.md | 177 +++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 82 deletions(-) diff --git a/docs/source/bmi.var_funcs.md b/docs/source/bmi.var_funcs.md index b22d754..d02de3f 100644 --- a/docs/source/bmi.var_funcs.md +++ b/docs/source/bmi.var_funcs.md @@ -1,63 +1,75 @@ (var-funcs)= +(var-enumeration-funcs)= + +# Variable enumeration functions + +These functions supply the model's {term}`exchange items ` -- +the variables that the model can use from and provide to +other models that have a BMI. + + + + +(var-information-funcs)= + # Variable information functions These BMI functions provide information -about a particular input or output variable. +about a particular variable. They must accommodate any variable returned from the -{ref}`get-input-var-names` or {ref}`get-output-var-names` functions -- +{ref}`get-varset-members` function -- the variable name is used as an argument in each function. Based on the information returned, type or unit conversions can be applied when necessary. -(get-var-grid)= +(get-var-type)= -## *get_var_grid* +## *get_var_type* ::::{tab-set} :sync-group: lang :::{tab-item} SIDL :sync: sidl - ```java -int get_var_grid(in string name, out int grid); +int get_var_type(in string name, out string type); ``` ::: + :::{tab-item} Python :sync: python ```python -def get_var_grid(self, name: str) -> int: +def get_var_type(self, name: str) -> str: ``` ::: :::{tab-item} c :sync: c ```c -int get_var_grid(void *self, const char *name, int *grid); +int get_var_type(void *self, const char *name, char *type); ``` ::: :::: -Each input and output variable is defined on a grid. -(Available grid types are listed in the {ref}`grid-funcs` section.) -The `get_var_grid` function provides the identifier (an integer) for this grid. -The identifier can be passed to the BMI -{ref}`grid information ` functions -to get the details of a particular grid; -e.g., *x*- and *y*-coordinates, size, type, etc. -A model can have one or more grids. +The `get_var_type` function provides the data type of the +variable as it's stored in memory by the model. +The data type is returned as a string. +Use of native language type names is encouraged; +e.g., in C, use `int`, `float`, and `double`, +while in Fortran, use `integer`, `real`, and `double precision`. **Implementation notes** -- Grid identifiers start at 0. -- In C++, Java, and Python, the *grid* argument is omitted and the grid - identifier is returned from the function. -- In C and Fortran, an integer status code indicating success (zero) or - failure (nonzero) is returned. +- In C++, Java, and Python, the *type* argument is omitted and the variable + type name is returned from the function as a string. +- In C and Fortran, an integer status code indicating success (zero) or failure + (nonzero) is returned. +- In Java, only [primitive types] (e.g., `int`, `double`), not + [wrapper classes] (e.g., `Integer`, `Double`), are supported. -(get-var-type)= +(get-var-itemsize)= -## *get_var_type* +## *get_var_itemsize* ::::{tab-set} :sync-group: lang @@ -65,167 +77,168 @@ A model can have one or more grids. :::{tab-item} SIDL :sync: sidl ```java -int get_var_type(in string name, out string type); +int get_var_itemsize(in string name, out int size); ``` ::: :::{tab-item} Python :sync: python ```python -def get_var_type(self, name: str) -> str: +def get_var_itemsize(self, name: str) -> int: ``` ::: :::{tab-item} c :sync: c ```c -int get_var_type(void *self, const char *name, char *type); +int get_var_itemsize(void *self, const char *name, int *size); ``` ::: :::: -The `get_var_type` function provides the data type of the -variable as it's stored in memory by the model. -The data type is returned as a string. -Use of native language type names is encouraged; -e.g., in C, use `int`, `float`, and `double`, -while in Fortran, use `integer`, `real`, and `double precision`. +The `get_var_itemsize` function provides the size, in bytes, +of a single element of the variable. +For example, if data for a variable are stored as 64-bit integers, +`get_var_itemsize` would return 8. **Implementation notes** -- In C++, Java, and Python, the *type* argument is omitted and the variable - type name is returned from the function as a string. +- In C++, Java, and Python, the *size* argument is omitted and the item size + is returned from the function. - In C and Fortran, an integer status code indicating success (zero) or failure (nonzero) is returned. -- In Java, only [primitive types] (e.g., `int`, `double`), not - [wrapper classes] (e.g., `Integer`, `Double`), are supported. -(get-var-units)= +(get-var-nbytes)= -## *get_var_units* +## *get_var_nbytes* ::::{tab-set} :sync-group: lang :::{tab-item} SIDL :sync: sidl - ```java -int get_var_units(in string name, out string units); +int get_var_nbytes(in string name, out int nbytes); ``` ::: + :::{tab-item} Python :sync: python ```python -def get_var_units(self, name: str) -> str: +def get_var_nbytes(self, name: str) -> int: ``` ::: :::{tab-item} c :sync: c ```c -int get_var_units(void *self, const char *name, char *units); +int get_var_nbytes(void *self, const char *name, int *nbytes); ``` ::: :::: -Get the units of the given variable. -Standard unit names, in lower case, should be used, -such as `"meters"` or `"seconds"`. -Standard abbreviations, such as `"m"` for meters, are -also supported. For variables with compound units, each unit name -is separated by a single space, with exponents other than 1 placed -immediately after the name, as in `"m s-1"` for velocity, -`"W m-2"` for an energy flux, or `"km2"` for an area. -The abbreviations used in the BMI are derived from -Unidata's [UDUNITS] package. -See, for example, [The Units Database] for a -full description of valid unit names and a list of supported units. +The `get_var_nbytes` function provides the total amount of memory used to store +a variable; i.e., the number of items multiplied by the size of each item. **Implementation notes** -- Dimensionless quantities should use `""` or `"1"` as the unit. -- Variables without units should use `"none"`. -- In C++, Java, and Python, the *units* argument is omitted and the variable - units name is returned from the function as a string. +- In C++, Java, and Python, the *nbytes* argument is omitted and the total + amount of memory used by the variable is returned from the function. - In C and Fortran, an integer status code indicating success (zero) or failure (nonzero) is returned. -(get-var-itemsize)= +(get-var-units)= -## *get_var_itemsize* +## *get_var_units* ::::{tab-set} :sync-group: lang :::{tab-item} SIDL :sync: sidl + ```java -int get_var_itemsize(in string name, out int size); +int get_var_units(in string name, out string units); ``` ::: - :::{tab-item} Python :sync: python ```python -def get_var_itemsize(self, name: str) -> int: +def get_var_units(self, name: str) -> str: ``` ::: :::{tab-item} c :sync: c ```c -int get_var_itemsize(void *self, const char *name, int *size); +int get_var_units(void *self, const char *name, char *units); ``` ::: :::: -The `get_var_itemsize` function provides the size, in bytes, -of a single element of the variable. -For example, if data for a variable are stored as 64-bit integers, -`get_var_itemsize` would return 8. +Get the units of the given variable. +Standard unit names, in lower case, should be used, +such as `"meters"` or `"seconds"`. +Standard abbreviations, such as `"m"` for meters, are +also supported. For variables with compound units, each unit name +is separated by a single space, with exponents other than 1 placed +immediately after the name, as in `"m s-1"` for velocity, +`"W m-2"` for an energy flux, or `"km2"` for an area. +The abbreviations used in the BMI are derived from +Unidata's [UDUNITS] package. +See, for example, [The Units Database] for a +full description of valid unit names and a list of supported units. **Implementation notes** -- In C++, Java, and Python, the *size* argument is omitted and the item size - is returned from the function. +- Dimensionless quantities should use `""` or `"1"` as the unit. +- Variables without units should use `"none"`. +- In C++, Java, and Python, the *units* argument is omitted and the variable + units name is returned from the function as a string. - In C and Fortran, an integer status code indicating success (zero) or failure (nonzero) is returned. -(get-var-nbytes)= +(get-var-grid)= -## *get_var_nbytes* +## *get_var_grid* ::::{tab-set} :sync-group: lang :::{tab-item} SIDL :sync: sidl + ```java -int get_var_nbytes(in string name, out int nbytes); +int get_var_grid(in string name, out int grid); ``` ::: - :::{tab-item} Python :sync: python ```python -def get_var_nbytes(self, name: str) -> int: +def get_var_grid(self, name: str) -> int: ``` ::: :::{tab-item} c :sync: c ```c -int get_var_nbytes(void *self, const char *name, int *nbytes); +int get_var_grid(void *self, const char *name, int *grid); ``` ::: :::: -The `get_var_nbytes` function provides the total amount of memory used to store -a variable; i.e., the number of items multiplied by the size of each item. +Each input and output variable is defined on a grid. +(Available grid types are listed in the {ref}`grid-funcs` section.) +The `get_var_grid` function provides the identifier (an integer) for this grid. +The identifier can be passed to the BMI +{ref}`grid information ` functions +to get the details of a particular grid; +e.g., *x*- and *y*-coordinates, size, type, etc. +A model can have one or more grids. **Implementation notes** -- In C++, Java, and Python, the *nbytes* argument is omitted and the total - amount of memory used by the variable is returned from the function. -- In C and Fortran, an integer status code indicating success (zero) or failure - (nonzero) is returned. +- Grid identifiers start at 0. +- In C++, Java, and Python, the *grid* argument is omitted and the grid + identifier is returned from the function. +- In C and Fortran, an integer status code indicating success (zero) or + failure (nonzero) is returned. (get-var-location)=