BMI Council meeting 2025-08

The primary topic of this meeting was the extension framework proposal developed by @PhilMiller and @Nels and described in csdms/bmi#186 and csdms/bmi#187. Phil led the discussion.

(My notes are sketchy. Please let me know if I got things wrong and I’ll edit the post.)

BMIv3: Defining sets of variables exported by a model (#186)

This PR replaces four existing BMI functions:

int get_input_item_count(out int count);
int get_output_item_count(out int count);
int get_input_var_names(out array<string, 1> names);
int get_output_var_names(out array<string, 1> names);

with two new ones:

int get_varset_member_count(in string set_name, out int count);
int get_varset_members(in string set_name, out array<string, 1> names);

These new functions define variable sets that extend beyond exchange items, and can be deemed input, output, or something else entirely; for example, Nels suggests:

get_varset_members(“parameters”, params);
get_varset_members(“input”, input);
get_varset_members(“options”, opts);

The categories can be codified outside the BMI specification itself, with BMI supporting working with general categories.

Discussion

Dominic: Will there be a BMI 2 to 3 code helper or documentation?
Phil: Yes, this could be an appendix to the documentation.

Scott: Comparison with variable roles. This makes it a little easier. The varset maps to a role, and may be more general than a role. We’ll need conventions for naming varsets.
Phil: Define namespaces for sets. Use bmi_ as namespace for official ones from the BMI Council.

Fred: Another way of framing variable sets would be as named structures.
Phil: We made an intentional decision to move away from hard names.

Dominic: Is time_step a parameter?
Phil: Defer to model because it could vary.

Nels: varset == { variables which have some relationship }

BMIv3: Extensions (#187)

Big changes to the initialize function to support extensions.

int initialize(in string config_file, in array<string, 1> requested_extensions, out array<string, 1> supported_extensions);

There are new parameters for requesting extensions the caller would like to use. If no extension is needed, pass a null.

Also, a new get_extension function:

int get_extension(void *self, char const *name, void **extension_object);

Phil and Nels explain that the extension object is opaque, like a BMI object. The extension is separate from BMI class definition, which has to be sacrosanct.

Discussion

Scott: It would be useful if a model could broadcast what extensions it supports.
Phil: Use a try statement. It adds work, but it pushes design toward correctness.

Fred: NextGen provides a lot of external metadata that’s not in the BMI specification. Can this information fit into the extension framework?
Phil: Yes, NextGen could produce a metadata extension.

Scott: Versioning of extensions?
Nels and Phil: Communicate as part of the extension name.
Scott: A model could support multiple versions of an extension.

Nels: A thought experiment: mass balance introspection as an example of an extension. Don’t prescribe how a model does mass balance, we just need to get the info into the framework.

Phil: Extensions take the pain away from the BMI Council. Allows the user community to do things.
Nels: Extensions are independent of core BMI. Keep BMI simple, changing as little as necessary.
Phil: Making it easy for modelers to adopt core.

Mark: Will we, the BMI Council, provide guidance on how to structure an extension, or should we just let users do what they want as long as they provide an extension object that the framework can work with?
Nels: I think it’s worth providing some examples and/or best practices at the very least.
Phil: Mechanism for exposing agreements of behavior between model and framework. Make it possible to agree on how interactions are better.

Council feedback

Phil: What do people think?

Dominic: I think the extension proposals sound general enough to be flexible for various use cases discussed and ones I can think of. I think as long as the BMI extensions are required not to undermine the existing BMI-ness of the model (i.e. preserve its expected properties) then that feels like enough (I don’t think the use cases described, e.g., mass balance would have an issue here).

Eric: It would helps to see examples. Will it work in practice? We could update the examples we’ve made, and maybe even try this on some BMI components.

Scott: Charge ahead! We’ve spent a lot of time talking about extensions.

Fred: Consistent with everything on the NextGen side.

Bert: Need to try with parallel.

Ryan: How will this work with Fortran? **void and null.

Phil: Yeah, this might be hard.

Nels: We should be able to do this.

Soren: How will this play with WRF-Hydro?

Nels: How to move forward? v3 alpha branch?

Nels: The BMI Council can be a maintainer of some extensions.

Nels: Refactor functionality out of core BMI.

Mark: Like grids!

Bert: Be careful with this!

Scott: Would prefer to move forward with new things rather than refactoring old stuff. Don’t sour our community with changes.

Summary

Phil: Next steps. Keep working on the extensions framework proposal. Work with NCAR and Bert. Get rough consensus in the Council.