18 module metadata_transfer_mod
21 use mpi,
only: mpi_type_create_struct, mpi_type_commit, mpi_integer, mpi_character, &
22 mpi_double, mpi_float, mpi_int, mpi_long_int, mpi_success, mpi_address_kind
25 use fms_mod,
only: string
35 integer,
parameter :: real8_type = 1
36 integer,
parameter :: real4_type = 2
37 integer,
parameter :: int8_type = 3
38 integer,
parameter :: int4_type = 4
39 integer,
parameter :: str_type = 5
41 integer,
parameter :: ATTR_NAME_MAX_LENGTH = 128
42 integer,
parameter :: ATTR_VALUE_MAX_LENGTH = 128
49 integer :: mpi_type_id = -1
51 integer :: attribute_length = -1
52 character(len=ATTR_NAME_MAX_LENGTH) :: attribute_name
54 procedure :: fms_metadata_broadcast
55 procedure :: fms_metadata_transfer_init
56 procedure :: get_attribute_name
57 procedure :: set_attribute_name
63 real(r8_kind) :: attribute_value(ATTR_VALUE_MAX_LENGTH)
65 procedure :: get_attribute_value => get_attribute_r8_value
66 procedure :: set_attribute_value => set_attribute_r8_value
71 real(r4_kind) :: attribute_value(ATTR_VALUE_MAX_LENGTH)
73 procedure :: get_attribute_value => get_attribute_r4_value
74 procedure :: set_attribute_value => set_attribute_r4_value
79 integer(i8_kind) :: attribute_value(ATTR_VALUE_MAX_LENGTH)
81 procedure :: get_attribute_value => get_attribute_i8_value
82 procedure :: set_attribute_value => set_attribute_i8_value
87 integer(i4_kind) :: attribute_value(ATTR_VALUE_MAX_LENGTH)
89 procedure :: get_attribute_value => get_attribute_i4_value
90 procedure :: set_attribute_value => set_attribute_i4_value
95 character(len=ATTR_VALUE_MAX_LENGTH) :: attribute_value
97 procedure :: get_attribute_value => get_attribute_str_value
98 procedure :: set_attribute_value => set_attribute_str_value
106 subroutine fms_metadata_transfer_init(this, dtype)
107 class(metadata_class),
intent(inout) :: this
108 integer,
intent(in) :: dtype
110 integer,
dimension(0:4) :: lengths, types
112 integer(KIND=MPI_ADDRESS_KIND),
dimension(0:4) :: displacements
113 integer :: ierror, mpi_id
121 displacements(0) = 0_mpi_address_kind
122 displacements(1) = displacements(0) + sizeof(0)
123 displacements(2) = displacements(1) + sizeof(0)
124 displacements(3) = displacements(2) + sizeof(
' ')*attr_name_max_length
125 displacements(4) = displacements(3) + sizeof(
' ')*attr_name_max_length
129 types = (/mpi_integer, mpi_integer, mpi_character, mpi_character, mpi_double/)
131 types = (/mpi_integer, mpi_integer, mpi_character, mpi_character, mpi_float/)
133 types = (/mpi_integer, mpi_integer, mpi_character, mpi_character, mpi_int/)
135 types = (/mpi_integer, mpi_integer, mpi_character, mpi_character, mpi_long_int/)
137 types = (/mpi_integer, mpi_integer, mpi_character, mpi_character, mpi_character/)
139 call mpp_error(fatal,
"fms_metadata_transfer_init:: given dtype argument contains a unsupported type")
143 lengths = (/1, 1, attr_name_max_length, attr_name_max_length, attr_value_max_length/)
145 call mpi_type_create_struct(4, lengths, displacements, types, mpi_id, ierror)
146 if(ierror /= mpi_success)
then
147 call mpp_error(fatal,
"fms_metadata_transfer_init: MPI_Type_create_struct failed")
149 call mpi_type_commit(mpi_id, ierror)
150 if(ierror /= mpi_success)
then
151 call mpp_error(fatal,
"fms_metadata_transfer_init: MPI_Type_commit failed")
153 this%mpi_type_id = mpi_id
155 call mpp_error(fatal,
"fms_metadata_transfer_init: MPI library not enabled, cannot initialize metadata transfer")
157 end subroutine fms_metadata_transfer_init
160 subroutine fms_metadata_broadcast(this)
161 class(metadata_class),
intent(inout) :: this
162 integer :: ierror, curr_comm_id
163 integer,
allocatable :: broadcasting_pes(:)
164 if (this%mpi_type_id .eq. -1)
then
165 call mpp_error(fatal,
"fms_metadata_broadcast: metadata_transfer not initialized")
168 allocate(broadcasting_pes(
mpp_npes()))
169 call mpp_get_current_pelist(broadcasting_pes, commid=curr_comm_id)
175 call mpi_bcast(this, 1, this%mpi_type_id, mpp_root_pe(), curr_comm_id, ierror)
177 call mpi_bcast(this, 1, this%mpi_type_id, mpp_root_pe(), curr_comm_id, ierror)
179 call mpi_bcast(this, 1, this%mpi_type_id, mpp_root_pe(), curr_comm_id, ierror)
181 call mpi_bcast(this, 1, this%mpi_type_id, mpp_root_pe(), curr_comm_id, ierror)
183 call mpi_bcast(this, 1, this%mpi_type_id, mpp_root_pe(), curr_comm_id, ierror)
185 if (ierror /= mpi_success)
then
186 call mpp_error(fatal,
"fms_metadata_broadcast: MPI_Bcast failed")
189 call mpp_error(fatal,
"fms_metadata_broadcast: MPI library not enabled")
193 end subroutine fms_metadata_broadcast
196 subroutine fms_metadata_broadcast_all(metadata_objs)
197 class(metadata_class),
intent(inout) :: metadata_objs(:)
200 do i=1,
size(metadata_objs)
201 if (metadata_objs(i)%mpi_type_id .eq. -1)
then
202 call mpp_error(fatal,
"fms_metadata_broadcast_all: metadata_transfer not initialized")
204 call metadata_objs(i)%fms_metadata_broadcast()
207 end subroutine fms_metadata_broadcast_all
210 function get_attribute_r8_value(this)
result(val)
211 class(metadata_r8_type),
intent(inout) :: this
212 real(r8_kind),
allocatable :: val(:)
213 val = this%attribute_value(1:this%attribute_length)
217 subroutine set_attribute_r8_value(this, val)
218 class(metadata_r8_type),
intent(inout) :: this
219 real(r8_kind),
intent(in) :: val(:)
220 if(
size(val) .gt. attr_value_max_length)
then
222 "metadata_transfer_mod: attribute value array exceeds max length of "//string(attr_name_max_length))
224 this%attribute_length =
size(val)
225 this%attribute_value(1:
size(val)) = val
229 function get_attribute_r4_value(this)
result(val)
230 class(metadata_r4_type),
intent(inout) :: this
231 real(r4_kind),
allocatable :: val(:)
232 val = this%attribute_value(1:this%attribute_length)
236 subroutine set_attribute_r4_value(this, val)
237 class(metadata_r4_type),
intent(inout) :: this
238 real(r4_kind),
intent(in) :: val(:)
239 if(
size(val) .gt. attr_value_max_length)
then
241 "metadata_transfer_mod: attribute value array exceeds max length of "//string(attr_name_max_length))
243 this%attribute_length =
size(val)
244 this%attribute_value(1:
size(val)) = val
248 function get_attribute_i8_value(this)
result(val)
249 class(metadata_i8_type),
intent(inout) :: this
250 integer(i8_kind),
allocatable :: val(:)
251 val = this%attribute_value(1:this%attribute_length)
255 subroutine set_attribute_i8_value(this, val)
256 class(metadata_i8_type),
intent(inout) :: this
257 integer(i8_kind),
intent(in) :: val(:)
258 if(
size(val) .gt. attr_value_max_length)
then
260 "metadata_transfer_mod: attribute value array exceeds max length of "//string(attr_name_max_length))
262 this%attribute_length =
size(val)
263 this%attribute_value(1:
size(val)) = val
267 function get_attribute_i4_value(this)
result(val)
268 class(metadata_i4_type),
intent(inout) :: this
269 integer(i4_kind),
allocatable :: val(:)
270 val = this%attribute_value(1:this%attribute_length)
274 subroutine set_attribute_i4_value(this, val)
275 class(metadata_i4_type),
intent(inout) :: this
276 integer(i4_kind),
intent(in) :: val(:)
277 if(
size(val) .gt. attr_value_max_length)
then
279 "metadata_transfer_mod: attribute value array exceeds max length of "//string(attr_name_max_length))
281 this%attribute_length =
size(val)
282 this%attribute_value(1:
size(val)) = val
286 function get_attribute_str_value(this)
result(val)
287 class(metadata_str_type),
intent(inout) :: this
288 character(len=:),
allocatable :: val
289 val = this%attribute_value(1:this%attribute_length)
293 subroutine set_attribute_str_value(this, val)
294 class(metadata_str_type),
intent(inout) :: this
295 character(len=*),
intent(in) :: val
296 if(len(val) .gt. attr_value_max_length)
then
298 "metadata_transfer_mod: attribute value array exceeds max length of "//string(attr_name_max_length))
300 this%attribute_length = len(val)
301 this%attribute_value(1:len(val)) = val
305 function get_attribute_name(this)
result(val)
306 class(metadata_class),
intent(inout) :: this
307 character(len=ATTR_NAME_MAX_LENGTH) :: val
308 val = trim(this%attribute_name)
312 subroutine set_attribute_name(this, val)
313 class(metadata_class),
intent(inout) :: this
314 character(len=*),
intent(in) :: val
315 if(len(val) .gt. attr_name_max_length)
then
317 "metadata_transfer_mod: attribute name exceeds max length of "//string(attr_value_max_length))
319 this%attribute_name = val
322 end module metadata_transfer_mod
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.