I have a code that makes extensive use of a type, let say, for simplicity:
type, public :: my_type
real, allocatable, dimension(:) :: x
real, allocatable, dimension(:,:) :: coeffs
end type my_type
...
type(my_type) :: data
Later in the code, we need to write data%x
and data%coeffs
to a file.
Whether the user wants it or not, this file could be written in a standard unformatted binary file and recently we add the possibility to write the file in HDF5 format.
In this case, when creating the data sets for data%x
or data%coeffs
, I need to pass a pointer, pointing on them, as argument to some hdf5 subroutines. This pointer can be defined as follow:
f_ptr = c_loc( data%x(1) )
But to do that, I should have given the target attribute to x
and coeffs
in my_type
definition.
My questions are then:
- is it safe to give this target attribute, just in case, even if, in the end, the user does not want to use HDF5 format ?
- Would it have an impact on performance ?
- Would it be better to make, in the routine that writes the data, a local copy of
data%x
anddata%coeffs
to same shape arrays with the target attribute and then point at them and pass the pointer to hdf5 subroutines ?
If it helps, this code can be compiled either with gfortran
or ifort
.
Thanks in advance !
CodePudding user response:
It is safe; maybe; there's no need to make a copy.
Typically you would pass data%x
(and then data%coeffs
) to a procedure that does the HDF5 dataset writing as a actual argument, say associated with a dummy array arg
. If so, just give arg
the TARGET attribute.
call write_array_to_hdf5_file(data%x, ...)
subroutine write_array_to_hdf5_file(arg, ...)
real, intent(in), target :: arg(:)
...
call h5d_write_f(..., c_loc(arg))
If the actual argument does not have the target attribute, then pointers associated with arg
become undefined when the write_array_to_hdf5_file
procedure finishes execution.
CodePudding user response:
I think you have misunderstood how target
works in Fortran. If I have not misunderstood you, you want to make data%x
and data%coeffs
targets, by giving the x
and coeffs
member variables the target
attribute, as
type, public :: my_type
real, allocatable, dimension(:), target :: x
real, allocatable, dimension(:,:), target :: coeffs
end type my_type
type(my_type) :: data
but this is not valid syntax. To quote Intel:
The TARGET attribute can be specified in a type declaration statement or a TARGET statement
This means the target
attribute can only be applied to instances of variables, not to their definitions.
And so to make data%x
and data%coeffs
targets, you should instead give data
the target
attribute, as
type, public :: my_type
real, allocatable, dimension(:) :: x
real, allocatable, dimension(:,:) :: coeffs
end type my_type
type(my_type), target :: data
This hopefully also answers your question on usage; you only need to give the target
attribute to those instances of my_type
which need it.