Skip to content

Commit

Permalink
Merge pull request #2858 from pnorbert/fortran-F90-strings
Browse files Browse the repository at this point in the history
Remove F2008 string allocation from Fortran binding. sadios2_availabl…
  • Loading branch information
eisenhauer authored Sep 10, 2021
2 parents 0689f6a + 7c9f87f commit 5fcc669
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 94 deletions.
67 changes: 12 additions & 55 deletions bindings/Fortran/f2c/adios2_f2c_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ void FC_GLOBAL(adios2_available_variables_f2c,
cnamelist *info = new (cnamelist);
info->names = adios2_available_variables(*io, &info->count);
*vars_count = static_cast<int>(info->count);

size_t maxlen = 0;
for (size_t i = 0; i < info->count; ++i)
{
Expand All @@ -247,47 +246,10 @@ void FC_GLOBAL(adios2_available_variables_f2c,
}
}
*max_var_name_len = static_cast<int>(maxlen);

*namestruct = static_cast<int64_t>(reinterpret_cast<std::uintptr_t>(info));
*ierr = 0;
}

void FC_GLOBAL(adios2_retrieve_variable_names_f2c,
ADIOS2_RETRIEVE_VARIABLE_NAMES_F2C)(int64_t *namestruct,
int *count,
int *max_name_len,
void *vnamelist, int *ierr,
int vnamelist_len)
{
cnamelist *info = reinterpret_cast<cnamelist *>(*namestruct);
int cnt = info->count;
if (cnt > *count)
{
cnt = *count;
}
if (info != NULL && static_cast<size_t>(*count) == info->count)
{
for (int i = 0; i < *count; i++)
{
char *fs = (char *)vnamelist + i * vnamelist_len;
size_t len = strlen(info->names[i]);
if (len > static_cast<size_t>(vnamelist_len))
{
len = static_cast<size_t>(vnamelist_len);
}
// copy C string without '\0'
strncpy(fs, info->names[i], len);
// pad with spaces
memset(fs + len, ' ', vnamelist_len - len);
}
*ierr = 0;
}
else
{
*ierr = 1;
}
}

void FC_GLOBAL(adios2_available_attributes_f2c,
ADIOS2_AVAILABLE_ATTRIBUTES_F2C)(adios2_io **io,
int64_t *namestruct,
Expand All @@ -314,35 +276,30 @@ void FC_GLOBAL(adios2_available_attributes_f2c,
*ierr = 0;
}

void FC_GLOBAL(adios2_retrieve_attribute_names_f2c,
ADIOS2_RETRIEVE_ATTRIBUTE_NAMES_F2C)(int64_t *namestruct,
int *count,
int *max_name_len,
void *anamelist, int *ierr,
int anamelist_len)
void FC_GLOBAL(adios2_retrieve_namelist_f2c,
ADIOS2_RETRIEVE_NAMELIST_F2C)(int64_t *namestruct,
void *namelist, int *ierr,
int namelist_len)
{
cnamelist *info = reinterpret_cast<cnamelist *>(*namestruct);
int cnt = info->count;
if (cnt > *count)
{
cnt = *count;
}
if (info != NULL && static_cast<size_t>(*count) == info->count)
if (info != NULL)
{
for (int i = 0; i < *count; i++)
for (size_t i = 0; i < info->count; i++)
{
char *fs = (char *)anamelist + i * anamelist_len;
char *fs = (char *)namelist + i * namelist_len;
size_t len = strlen(info->names[i]);
if (len > static_cast<size_t>(anamelist_len))
if (len > static_cast<size_t>(namelist_len))
{
len = static_cast<size_t>(anamelist_len);
len = static_cast<size_t>(namelist_len);
}
// copy C string without '\0'
strncpy(fs, info->names[i], len);
// pad with spaces
memset(fs + len, ' ', anamelist_len - len);
memset(fs + len, ' ', namelist_len - len);
}
*ierr = 0;
delete (info);
*namestruct = 0;
}
else
{
Expand Down
92 changes: 67 additions & 25 deletions bindings/Fortran/modules/adios2_io_mod.f90
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ module adios2_io_mod
external adios2_get_parameter_f2c
external adios2_get_parameter_length_f2c
external adios2_in_config_file_f2c
external adios2_available_variables_f2c
external adios2_available_attributes_f2c
external adios2_retrieve_namelist_f2c
external adios2_inquire_attribute_f2c
external adios2_inquire_variable_f2c
external adios2_io_engine_type_f2c
Expand Down Expand Up @@ -158,26 +161,53 @@ subroutine adios2_set_transport_parameter(io, transport_index, key, value, &
end subroutine


subroutine adios2_available_variables(io, nvars, varnamelist, ierr)
subroutine adios2_available_variables(io, namestruct, ierr)
type(adios2_io), intent(in) :: io
integer, intent(out) :: nvars
character(len=:), dimension(:), allocatable, intent(out) :: varnamelist
type(adios2_namestruct), intent(out) :: namestruct
integer, intent(out) :: ierr

integer(kind=8):: namestruct
integer :: count, max_name_len

call adios2_available_variables_f2c(io%f2c, namestruct, count, &
max_name_len, ierr)
call adios2_available_variables_f2c(io%f2c, namestruct%f2c, &
namestruct%count, namestruct%max_name_len, ierr)
if (ierr == 0) then
allocate(character(len=max_name_len) :: varnamelist(count))
namestruct%valid = .true.
endif
end subroutine

subroutine adios2_retrieve_names(namestruct, namelist, ierr)
type(adios2_namestruct), intent(inout) :: namestruct
character(*), dimension(*), intent(inout) :: namelist
integer, intent(out) :: ierr

call adios2_retrieve_variable_names_f2c(namestruct, count, &
max_name_len, varnamelist, ierr)
nvars = count
if (namestruct%valid .and. namestruct%f2c > 0_8) then
call adios2_retrieve_namelist_f2c(namestruct%f2c, namelist, ierr)
else
write(*,*) "ADIOS2 Fortran ERROR: invalid namestruct when calling adios2_retrieve_names()"
endif
namestruct%valid = .false.
end subroutine

!
! F2008 implementation that allows for allocating a character array inside
!
! subroutine adios2_available_variables(io, nvars, varnamelist, ierr)
! type(adios2_io), intent(in) :: io
! integer, intent(out) :: nvars
! character(len=:), dimension(:), allocatable, intent(out) :: varnamelist
! integer, intent(out) :: ierr

! integer(kind=8):: namestruct
! integer :: count, max_name_len

! call adios2_available_variables_f2c(io%f2c, namestruct, count, &
! max_name_len, ierr)
! if (ierr == 0) then
! allocate(character(len=max_name_len) :: varnamelist(count))
! endif

! call adios2_retrieve_variable_names_f2c(namestruct, varnamelist, ierr)
! nvars = count
! end subroutine


subroutine adios2_inquire_variable(variable, io, name, ierr)
type(adios2_variable), intent(out) :: variable
Expand Down Expand Up @@ -233,26 +263,38 @@ subroutine adios2_remove_all_variables(io, ierr)

end subroutine

subroutine adios2_available_attributes(io, nattrs, attrnamelist, ierr)
subroutine adios2_available_attributes(io, namestruct, ierr)
type(adios2_io), intent(in) :: io
integer, intent(out) :: nattrs
character(len=:), dimension(:), allocatable, intent(out) :: attrnamelist
type(adios2_namestruct), intent(out) :: namestruct
integer, intent(out) :: ierr

integer(kind=8):: namestruct
integer :: count, max_name_len

call adios2_available_attributes_f2c(io%f2c, namestruct, count, &
max_name_len, ierr)
call adios2_available_attributes_f2c(io%f2c, namestruct%f2c, &
namestruct%count, namestruct%max_name_len, ierr)
if (ierr == 0) then
allocate(character(len=max_name_len) :: attrnamelist(count))
namestruct%valid = .true.
endif

call adios2_retrieve_attribute_names_f2c(namestruct, count, &
max_name_len, attrnamelist, ierr)
nattrs = count
end subroutine

! subroutine adios2_available_attributes(io, nattrs, attrnamelist, ierr)
! type(adios2_io), intent(in) :: io
! integer, intent(out) :: nattrs
! character(len=:), dimension(:), allocatable, intent(out) :: attrnamelist
! integer, intent(out) :: ierr

! integer(kind=8):: namestruct
! integer :: count, max_name_len

! call adios2_available_attributes_f2c(io%f2c, namestruct, count, &
! max_name_len, ierr)
! if (ierr == 0) then
! allocate(character(len=max_name_len) :: attrnamelist(count))
! endif

! call adios2_retrieve_attribute_names_f2c(namestruct, count, &
! max_name_len, attrnamelist, ierr)
! nattrs = count
! end subroutine

subroutine adios2_inquire_attribute(attribute, io, name, ierr)
type(adios2_attribute), intent(out) :: attribute
type(adios2_io), intent(in) :: io
Expand Down
7 changes: 7 additions & 0 deletions bindings/Fortran/modules/adios2_parameters_mod.f90
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,11 @@ module adios2_parameters_mod
character(len=64):: type = ''
end type

type adios2_namestruct
integer(kind=8):: f2c = 0_8
logical :: valid = .false.
integer :: count
integer :: max_name_len
end type

end module
1 change: 1 addition & 0 deletions docs/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ dependencies:
- adios2-openmpi
- sphinx
- breathe=4.18.1
- funcparserlib>=0.3.6
- pip
- pip:
- blockdiag>=1.5.4
Expand Down
29 changes: 21 additions & 8 deletions testing/adios2/bindings/fortran/TestBPWriteReadAttributes.F90
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ program TestBPWriteAttributes
real, dimension(3) :: r32_array
real(kind=8), dimension(3):: r64_array

character(len=:), dimension(:), allocatable :: attrnamelist
integer :: nattrs
type(adios2_namestruct) :: namestruct
character(len=4096), dimension(:), allocatable :: attrnamelist


! Launch MPI
call MPI_Init(ierr)
Expand Down Expand Up @@ -109,15 +110,27 @@ program TestBPWriteAttributes

call adios2_open(bpReader, ioRead, 'fattr_types.bp', adios2_mode_read, ierr)

call adios2_available_attributes(ioRead, nattrs, attrnamelist, ierr)
if (ierr /= 0) stop 'adios2_available_variables returned with error'
write(*,*) 'Number of attributes = ', nattrs
if (nattrs /= 14) stop 'adios2_available_attributes returned not the expected 14'
do i=1,nattrs
write(*,'("Var[",i2,"] = ",a20)') i, attrnamelist(i)

! Test getting list of attribute names
call adios2_available_attributes(ioRead, namestruct, ierr)
if (ierr /= 0) stop 'adios2_available_attributes returned with error'
if (.not.namestruct%valid) stop 'adios2_available_attributes returned invalid struct'
write(*,*) 'Number of attributes = ', namestruct%count
write(*,*) 'Max name length = ', namestruct%max_name_len
if (namestruct%count /= 14) stop 'adios2_available_attributes returned not the expected 14'

allocate(attrnamelist(namestruct%count))

call adios2_retrieve_names(namestruct, attrnamelist, ierr)
if (ierr /= 0) stop 'adios2_retrieve_names returned with error'
do i=1,namestruct%count
write(*,'("Attr[",i2,"] = ",a20)') i, attrnamelist(i)
end do
deallocate(attrnamelist)

if (namestruct%f2c /= 0_8) stop 'namestruct f2c pointer is not null after adios2_retrieve_names()'
if (namestruct%valid) stop 'namestruct is not invalidated after adios2_retrieve_names()'


call adios2_inquire_attribute(attributes_in(1), ioRead, 'att_String', ierr)
call adios2_inquire_attribute(attributes_in(2), ioRead, 'att_i8', ierr)
Expand Down
22 changes: 16 additions & 6 deletions testing/adios2/bindings/fortran/TestBPWriteTypes.F90
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ program TestBPWriteTypes
integer(kind=4) :: ndims
integer(kind=8), dimension(:), allocatable :: shape_in

character(len=:), dimension(:), allocatable :: varnamelist
integer :: nvars
character(len=4096), dimension(:), allocatable :: varnamelist
type(adios2_namestruct) :: namestruct

#if ADIOS2_USE_MPI
! Launch MPI
Expand Down Expand Up @@ -235,15 +235,25 @@ program TestBPWriteTypes
call adios2_steps(nsteps, bpReader, ierr)
if(nsteps /= 3) stop 'ftypes.bp must have 3 steps'

call adios2_available_variables(ioRead, nvars, varnamelist, ierr)
call adios2_available_variables(ioRead, namestruct, ierr)
if (ierr /= 0) stop 'adios2_available_variables returned with error'
write(*,*) 'Number of variables = ', nvars
if (nvars /= 14) stop 'adios2_available_variables returned not the expected 14'
do i=1,nvars
if (.not.namestruct%valid) stop 'adios2_available_variables returned invalid struct'
write(*,*) 'Number of variables = ', namestruct%count
write(*,*) 'Max name length = ', namestruct%max_name_len
if (namestruct%count /= 14) stop 'adios2_available_variables returned not the expected 14'

allocate(varnamelist(namestruct%count))

call adios2_retrieve_names(namestruct, varnamelist, ierr)
if (ierr /= 0) stop 'adios2_retrieve_names returned with error'
do i=1,namestruct%count
write(*,'("Var[",i2,"] = ",a12)') i, varnamelist(i)
end do
deallocate(varnamelist)

if (namestruct%f2c /= 0_8) stop 'namestruct f2c pointer is not null after adios2_retrieve_names()'
if (namestruct%valid) stop 'namestruct is not invalidated after adios2_retrieve_names()'


call adios2_inquire_variable(variables(1), ioRead, "var_I8", ierr)
if (variables(1)%name /= 'var_I8') stop 'var_I8 not recognized'
Expand Down

0 comments on commit 5fcc669

Please sign in to comment.