Skip to content

Support for writing integer, float and other type fields  #8

Open
@suvarchal

Description

@suvarchal

From api, it seems multio currently supports only writing fields of type double(?) :

int multio_write_field(multio_handle_t* mio, multio_metadata_t* md, const double* data, int size) {
return wrapApiFunction([mio, md, data, size]() {
ASSERT(mio);
ASSERT(md);
eckit::Buffer field_vals{reinterpret_cast<const char*>(data), size * sizeof(double)};
mio->dispatch(*md, std::move(field_vals), Message::Tag::Field);
});
}

This corroborates with examples like nemo-replay that all fields written seem to be of type double.

I can imagine a need (not just imagine i want :) ) to store fields which are say float/singlep or integer type, which seems missing right now but i am sure multio can be easily extended for that. But nevertheless I wonder if there is any grib thing/magic that facilitates using doubles but data types are automatically converted? Grib is still a territory i have very little understanding, but the issue is indeed true for raw encoding.

While it is easy to add more functions for this purpose with signature like int multio_write_field_integer(multio_handle_t* mio, multio_metadata_t* md, const int* data, int size) in api/multo_c.cc but number of functions for all types a user desires can be long and more over can have fragmentation over names and need to write corresponding bindings in Fortran. So i thought why not use a generic write in c-api like (note size is now sizeof instead of size):

int multio_write_field_generic(multio_handle_t* mio, multio_metadata_t* md, const void* data, size_t size) {
    return wrapApiFunction([mio, md, data, size]() {
        ASSERT(mio);
        ASSERT(md);

        eckit::Buffer field_vals{reinterpret_cast<const char*>(data), size};

        mio->dispatch(*md, std::move(field_vals), Message::Tag::Field);
    });
}

the advantage of such generic function is that I used this to bind for multiple types in Fortran api (and in corresponding wrapping interfaces) for instance:

                bind(c, name='multio_write_field_generic')
            use, intrinsic :: iso_c_binding
            implicit none
            type(c_ptr), intent(in), value :: handle
            type(c_ptr), intent(in), value :: metadata
            integer, dimension(*), intent(in) :: data
            integer(8), intent(in), value :: size
            integer(c_int) :: err
        end function
    function multio_write_field_integer(handle, metadata, data, size) result(err)
        class(multio_handle), intent(inout) :: handle
        class(multio_metadata), intent(in) :: metadata
        integer :: err

        integer, dimension(*), intent(in) :: data
        integer(8), intent(in), value :: size
        err = c_multio_write_field_integer(handle%impl, metadata%impl, data, size)
    end function

and this works.

multio_fapi.f90 can have these bindings for commonly used types like single-precision or integers but it can also be delegated to the users of the library how they may chose to bind, for instance it enables Fortran binding to custom derived types.

I would like to know your take on this and if you find it a fit I could happily author a PR based on what you think, but wouldn't mind you doing it as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions