35 use,
intrinsic :: iso_c_binding, only : c_ptr, c_null_ptr, c_associated, &
53 integer :: n_elements = 0
54 integer,
allocatable ::
mask(:)
55 type(c_ptr) :: mask_d = c_null_ptr
56 logical :: is_set_ = .false.
93 class(
mask_t),
intent(inout) :: this
94 integer,
intent(in) :: n_elements
96 this%is_set_ = .false.
97 if (n_elements .eq. this%n_elements)
return
100 allocate(this%mask(n_elements))
103 call device_map(this%mask, this%mask_d, n_elements)
106 this%n_elements = n_elements
111 class(
mask_t),
intent(inout) :: this
113 if (
allocated(this%mask))
then
114 deallocate(this%mask)
117 if (c_associated(this%mask_d))
then
122 this%mask_d = c_null_ptr
123 this%is_set_ = .false.
128 class(
mask_t),
intent(inout) :: this
129 integer,
intent(in) :: n_elements
130 integer,
intent(in) :: mask_array(n_elements)
132 call this%allocate(n_elements)
134 this%mask = mask_array
136 call device_memcpy(this%mask, this%mask_d, this%n_elements, &
141 this%is_set_ = .true.
146 class(
mask_t),
intent(inout) :: this
147 integer,
intent(in) :: n_elements
148 type(c_ptr),
intent(inout):: mask_array_d
149 integer(kind=c_size_t) :: size_c
151 size_c = n_elements * int(4, c_size_t)
153 call this%allocate(n_elements)
158 this%mask = this%mask - 1
160 this%is_set_ = .true.
165 class(
mask_t),
intent(inout) :: this
166 class(
mask_t),
intent(inout) :: other
167 integer(kind=c_size_t) :: size_c
169 call this%allocate(other%n_elements)
171 size_c = other%n_elements * int(4, c_size_t)
173 this%mask = other%mask
179 this%n_elements = other%n_elements
180 this%is_set_ = other%is_set_
185 class(
mask_t),
intent(inout) :: this
186 class(
mask_t),
intent(in) :: other
187 integer,
intent(in) :: total_elements
189 logical,
allocatable :: found(:)
190 integer,
allocatable :: new_mask(:)
191 integer :: i, j, k, v, new_size
193 allocate(found(total_elements))
197 do i = 1, other%size()
199 if (v >= 1 .and. v <= total_elements) found(v) = .true.
204 do j = 1, total_elements
205 if (.not. found(j)) new_size = new_size + 1
208 allocate(new_mask(new_size))
212 do j = 1, total_elements
213 if (.not. found(j))
then
219 call this%init_from_array(new_mask, new_size)
224 class(
mask_t),
intent(in) :: this
225 integer :: n_elements
227 n_elements = this%n_elements
232 class(
mask_t),
intent(in) :: this
235 is_set = this%is_set_
240 class(
mask_t),
intent(in),
target :: this
241 integer,
pointer :: mask_array(:)
243 if (.not. this%is_set())
call neko_error(
"Mask is not set.")
245 mask_array => this%mask
250 class(
mask_t),
intent(in),
target :: this
251 integer,
intent(in) :: index
252 integer :: mask_value
254 if (.not. this%is_set())
call neko_error(
"Mask is not set.")
255 if (index < 1 .or. index > this%n_elements)
then
256 call neko_error(
"Index out of bounds in mask_get_i")
259 mask_value = this%mask(index)
264 class(
mask_t),
intent(in) :: this
265 type(c_ptr) :: mask_array_d
267 if (.not. this%is_set())
call neko_error(
"Mask is not set.")
269 mask_array_d = this%mask_d
274 class(
mask_t),
intent(inout) :: this
275 integer,
intent(in) :: n_elements
276 integer,
intent(in) :: mask_array(n_elements)
278 call this%allocate(n_elements)
280 this%mask = mask_array
287 this%is_set_ = .true.
292 class(
mask_t),
intent(inout) :: this
293 integer,
intent(in) :: n_elements
294 type(c_ptr),
intent(inout) :: mask_array_d
295 integer(kind=c_size_t) :: size_c
297 call this%allocate(n_elements)
298 size_c = n_elements * int(4, c_size_t)
304 this%mask = this%mask - 1
306 this%is_set_ = .true.
Map a Fortran array to a device (allocate and associate)
Copy data between host and device (or device and device)
Device abstraction, common interface for various accelerators.
integer, parameter, public device_to_device
integer, parameter, public host_to_device
subroutine, public device_free(x_d)
Deallocate memory on the device.
integer, parameter, public device_to_host
Object for handling masks in Neko.
subroutine invert_mask(this, other, total_elements)
Invert the contents of another mask object.
pure logical function mask_is_set(this)
Check if the mask is set.
integer function, dimension(:), pointer mask_get(this)
Get the mask array.
subroutine init_from_array(this, mask_array, n_elements)
Initialize the mask from a 1-indexed host array.
subroutine init_from_mask(this, other)
Initialize the mask from another mask object.
pure integer function mask_size(this)
Get the size of the mask.
subroutine mask_allocate(this, n_elements)
Allocate the mask object.
integer function mask_get_i(this, index)
Get the mask array.
subroutine mask_set_d(this, mask_array_d, n_elements)
Set the mask from a 0-indexed device array.
subroutine mask_free(this)
Free the mask object.
subroutine mask_set(this, mask_array, n_elements)
Set the mask from a 1-indexed host array.
type(c_ptr) function mask_get_d(this)
Get the device pointer to the mask array.
subroutine init_from_array_device(this, mask_array_d, n_elements)
Initialize the mask from a 0-indexed device array.
integer, parameter neko_bcknd_device
Type for consistently handling masks in Neko. This type encapsulates the mask array and its associate...