Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
scratch_registry.f90
Go to the documentation of this file.
1! Copyright (c) 2025-2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
38 use num_types, only : rp
40 use host_array, only : host_array_t
42 use field, only : field_t
43 use vector, only : vector_t
44 use matrix, only : matrix_t
45 use tensor3, only : tensor3_t
46 use tensor4, only : tensor4_t
47
48 use math, only : rzero
49 use device_math, only : device_rzero
50 use field_math, only : field_rzero
51 use vector_math, only : vector_rzero
52 use matrix_math, only : matrix_rzero
53
54 use dofmap, only : dofmap_t
55 use utils, only : neko_error
57 use, intrinsic :: iso_c_binding, only : c_ptr
58 implicit none
59 private
60
61 type, public :: scratch_registry_t
63 type(registry_entry_t), private, allocatable :: entries(:)
65 logical, private, allocatable :: inuse(:)
67 integer, private :: n_entries = 0
69 integer, private :: n_inuse = 0
71 integer, private :: expansion_size = 10
73 type(dofmap_t), pointer :: dof => null()
74 contains
75 procedure, private, pass(this) :: expand
77 procedure, pass(this) :: init => scratch_registry_init
79 procedure, pass(this) :: free => scratch_registry_free
81 procedure, pass(this) :: set_dofmap => scratch_registry_set_dofmap
83 procedure, pass(this) :: get_n_entries
85 procedure, pass(this) :: get_n_inuse
87 procedure, pass(this) :: get_expansion_size
89 procedure, pass(this) :: get_size
91 procedure, pass(this) :: get_inuse
92
94 procedure, pass(this) :: request_host_array
95 procedure, pass(this) :: relinquish_host_array_single
96 procedure, pass(this) :: relinquish_host_array_multiple
98 generic :: relinquish_host_array => relinquish_host_array_single, &
100
102 procedure, pass(this) :: request_device_array
103 procedure, pass(this) :: relinquish_device_array_single
104 procedure, pass(this) :: relinquish_device_array_multiple
106 generic :: relinquish_device_array => relinquish_device_array_single, &
108
110 procedure, pass(this) :: request_vector
111 procedure, pass(this) :: relinquish_vector_single
112 procedure, pass(this) :: relinquish_vector_multiple
114 generic :: relinquish_vector => relinquish_vector_single, &
116
118 procedure, pass(this) :: request_matrix
119 procedure, pass(this) :: relinquish_matrix_single
120 procedure, pass(this) :: relinquish_matrix_multiple
122 generic :: relinquish_matrix => relinquish_matrix_single, &
124
126 procedure, pass(this) :: request_tensor3
127 procedure, pass(this) :: relinquish_tensor3_single
128 procedure, pass(this) :: relinquish_tensor3_multiple
130 generic :: relinquish_tensor3 => relinquish_tensor3_single, &
132
134 procedure, pass(this) :: request_tensor4
135 procedure, pass(this) :: relinquish_tensor4_single
136 procedure, pass(this) :: relinquish_tensor4_multiple
138 generic :: relinquish_tensor4 => relinquish_tensor4_single, &
140
142 procedure, pass(this) :: request_field_stored_dof
144 procedure, pass(this) :: request_field_free_dof
145 procedure, pass(this) :: relinquish_field_single
146 procedure, pass(this) :: relinquish_field_multiple
148 generic :: request_field => request_field_stored_dof, &
151 generic :: relinquish_field => relinquish_field_single, &
153
155 generic :: request => request_host_array, request_device_array, &
158
160 procedure, pass(this) :: relinquish_single
162 procedure, pass(this) :: relinquish_multiple
164 generic :: relinquish => relinquish_single, relinquish_multiple
165 end type scratch_registry_t
166
169
170contains
171
180 subroutine scratch_registry_init(this, size, expansion_size, dof)
181 class(scratch_registry_t), intent(inout) :: this
182 integer, optional, intent(in) :: size
183 integer, optional, intent(in) :: expansion_size
184 type(dofmap_t), target, intent(in), optional :: dof
185 integer :: s
186
187 call this%free()
188
189 s = 10
190 if (present(size)) s = size
191 if (present(dof)) this%dof => dof
192
193 allocate(this%entries(s))
194 allocate(this%inuse(s))
195 this%inuse(:) = .false.
196
197 this%expansion_size = 10
198 if (present(expansion_size)) this%expansion_size = expansion_size
199
200 end subroutine scratch_registry_init
201
203 subroutine scratch_registry_free(this)
204 class(scratch_registry_t), intent(inout):: this
205 integer :: i
206
207 if (allocated(this%inuse)) then
208 if(any(this%inuse)) then
209 call neko_error("scratch_registry::free: " // &
210 "Cannot free scratch registry with in-use entries.")
211 end if
212 deallocate(this%inuse)
213 end if
214
215 if (allocated(this%entries)) then
216 do i = 1, this%n_entries
217 call this%entries(i)%free()
218 end do
219
220 deallocate(this%entries)
221 end if
222
223 if (associated(this%dof)) nullify(this%dof)
224
225 ! Reset to default values
226 this%n_entries = 0
227 this%n_inuse = 0
228 this%expansion_size = 10
229
230 end subroutine scratch_registry_free
231
236 subroutine scratch_registry_set_dofmap(this, dof)
237 class(scratch_registry_t), intent(inout) :: this
238 type(dofmap_t), target, intent(in) :: dof
239
240 if (associated(this%dof, dof)) then
241 return
242 else if (associated(this%dof)) then
243 call neko_error("scratch_registry::set_dofmap: "&
244 // "Dofmap is already assigned to scratch registry.")
245 end if
246
247 this%dof => dof
248 end subroutine scratch_registry_set_dofmap
249
251 pure function get_n_entries(this) result(n)
252 class(scratch_registry_t), intent(in) :: this
253 integer :: n
254
255 n = this%n_entries
256 end function get_n_entries
257
259 pure function get_n_inuse(this) result(n)
260 class(scratch_registry_t), intent(in) :: this
261 integer :: n, i
262
263 n = count(this%inuse)
264 end function get_n_inuse
265
267 pure function get_size(this) result(n)
268 class(scratch_registry_t), intent(in) :: this
269 integer :: n
270
271 if (allocated(this%entries)) then
272 n = size(this%entries)
273 else
274 n = 0
275 end if
276 end function get_size
277
279 pure function get_expansion_size(this) result(n)
280 class(scratch_registry_t), intent(in) :: this
281 integer :: n
282
283 n = this%expansion_size
284 end function get_expansion_size
285
287 pure logical function get_inuse(this, index)
288 class(scratch_registry_t), target, intent(in) :: this
289 integer, intent(in) :: index
290
291 get_inuse = this%inuse(index)
292 end function get_inuse
293
294 subroutine expand(this)
295 class(scratch_registry_t), intent(inout) :: this
296 type(registry_entry_t), allocatable :: temp(:)
297 logical, allocatable :: temp2(:)
298 integer :: i, n
299
300 n = this%get_size()
301
302 if (n .gt. 0) then
303 call move_alloc(this%entries, temp)
304 call move_alloc(this%inuse, temp2)
305 end if
306
307 allocate(this%entries(n + this%expansion_size))
308 allocate(this%inuse(n + this%expansion_size), source = .false.)
309
310 if (n .gt. 0) then
311 do i = 1, n
312 call this%entries(i)%move_from(temp(i))
313 this%inuse(i) = temp2(i)
314 call temp(i)%free()
315 end do
316 end if
317
318 if (allocated(temp)) deallocate(temp)
319 if (allocated(temp2)) deallocate(temp2)
320
321 end subroutine expand
322
329 subroutine request_host_array(this, v, index, n, clear)
330 class(scratch_registry_t), target, intent(inout) :: this
331 real(kind=rp), pointer, dimension(:), intent(inout) :: v
332 integer, intent(inout) :: index
333 integer, intent(in) :: n
334 logical, intent(in) :: clear
335 type(host_array_t), pointer :: v_scratch
336
337 associate(entries => this%entries, n_entries => this%n_entries, &
338 n_inuse => this%n_inuse)
339
340 do index = 1, this%get_size()
341 if (.not. this%inuse(index)) then
342
343 if (.not. entries(index)%is_allocated()) then
344 call entries(index)%init_host_array(n)
345 n_entries = n_entries + 1
346 else if (trim(entries(index)%get_type()) .ne. 'host_array') then
347 cycle
348 end if
349
350 v_scratch => entries(index)%get_host_array()
351 if (v_scratch%size() .ne. n) then
352 nullify(v_scratch)
353 cycle
354 end if
355
356 if (clear) call rzero(v_scratch%x, v_scratch%size())
357 this%inuse(index) = .true.
358 this%n_inuse = this%n_inuse + 1
359 v => v_scratch%x
360 nullify(v_scratch)
361 return
362 end if
363 end do
364
365 ! all existing host_arrays in use, we need to expand to add a new one
366 index = n_entries + 1
367 call this%expand()
368 n_entries = n_entries + 1
369 n_inuse = n_inuse + 1
370 this%inuse(n_entries) = .true.
371 call this%entries(n_entries)%init_host_array(n)
372 v_scratch => this%entries(n_entries)%get_host_array()
373 v => v_scratch%x
374 nullify(v_scratch)
375
376 end associate
377 end subroutine request_host_array
378
385 subroutine request_device_array(this, v, index, n, clear)
386 class(scratch_registry_t), target, intent(inout) :: this
387 type(c_ptr), intent(inout) :: v
388 integer, intent(inout) :: index
389 integer, intent(in) :: n
390 logical, intent(in) :: clear
391 type(device_array_t), pointer :: v_tmp
392
393 associate(entries => this%entries, n_entries => this%n_entries, &
394 n_inuse => this%n_inuse)
395
396 do index = 1, this%get_size()
397 if (.not. this%inuse(index)) then
398
399 if (.not. entries(index)%is_allocated()) then
400 call entries(index)%init_device_array(n)
401 n_entries = n_entries + 1
402 else if (trim(entries(index)%get_type()) .ne. 'device_array') then
403 cycle
404 end if
405
406 v_tmp => entries(index)%get_device_array()
407 if (v_tmp%size() .ne. n) then
408 nullify(v_tmp)
409 cycle
410 end if
411
412 v = v_tmp%x_d
413 if (clear) call device_rzero(v, n)
414 this%inuse(index) = .true.
415 this%n_inuse = this%n_inuse + 1
416 nullify(v_tmp)
417 return
418 end if
419 end do
420
421 ! all existing device_arrays in use, we need to expand to add a new one
422 index = n_entries + 1
423 call this%expand()
424 n_entries = n_entries + 1
425 n_inuse = n_inuse + 1
426 this%inuse(n_entries) = .true.
427 call this%entries(n_entries)%init_device_array(n)
428 v_tmp => this%entries(n_entries)%get_device_array()
429 v = v_tmp%x_d
430 nullify(v_tmp)
431
432 end associate
433 end subroutine request_device_array
434
440 subroutine request_vector(this, v, index, n, clear)
441 class(scratch_registry_t), target, intent(inout) :: this
442 type(vector_t), pointer, intent(inout) :: v
443 integer, intent(inout) :: index
444 integer, intent(in) :: n
445 logical, intent(in) :: clear
446
447 associate(entries => this%entries, n_entries => this%n_entries, &
448 n_inuse => this%n_inuse)
449
450 do index = 1, this%get_size()
451 if (.not. this%inuse(index)) then
452
453 if (.not. entries(index)%is_allocated()) then
454 call entries(index)%init_vector(n)
455 n_entries = n_entries + 1
456 else if (trim(entries(index)%get_type()) .ne. 'vector') then
457 cycle
458 end if
459
460 v => entries(index)%get_vector()
461 if (v%size() .ne. n) then
462 nullify(v)
463 cycle
464 end if
465
466 if (clear) call vector_rzero(v)
467 this%inuse(index) = .true.
468 this%n_inuse = this%n_inuse + 1
469 return
470 end if
471 end do
472
473 ! all existing vectors in use, we need to expand to add a new one
474 index = n_entries + 1
475 call this%expand()
476 n_entries = n_entries + 1
477 n_inuse = n_inuse + 1
478 this%inuse(n_entries) = .true.
479 call this%entries(n_entries)%init_vector(n)
480 v => this%entries(n_entries)%get_vector()
481
482 end associate
483 end subroutine request_vector
484
491 subroutine request_matrix(this, m, index, nrows, ncols, clear)
492 class(scratch_registry_t), target, intent(inout) :: this
493 type(matrix_t), pointer, intent(inout) :: m
494 integer, intent(inout) :: index
495 integer, intent(in) :: nrows, ncols
496 logical, intent(in) :: clear
497
498 associate(entries => this%entries, n_entries => this%n_entries, &
499 n_inuse => this%n_inuse)
500
501 do index = 1, this%get_size()
502 if (.not. this%inuse(index)) then
503
504 if (.not. entries(index)%is_allocated()) then
505 call entries(index)%init_matrix(nrows, ncols)
506 n_entries = n_entries + 1
507 else if (trim(entries(index)%get_type()) .ne. 'matrix') then
508 cycle
509 end if
510
511 m => entries(index)%get_matrix()
512 if (m%get_nrows() .ne. nrows .or. &
513 m%get_ncols() .ne. ncols) then
514 nullify(m)
515 cycle
516 end if
517
518 if (clear) call matrix_rzero(m)
519 this%inuse(index) = .true.
520 this%n_inuse = this%n_inuse + 1
521 return
522 end if
523 end do
524
525 ! all existing matrices in use, we need to expand to add a new one
526 index = n_entries + 1
527 call this%expand()
528 n_entries = n_entries + 1
529 n_inuse = n_inuse + 1
530 this%inuse(n_entries) = .true.
531 call this%entries(n_entries)%init_matrix(nrows, ncols)
532 m => this%entries(n_entries)%get_matrix()
533
534 end associate
535 end subroutine request_matrix
536
544 subroutine request_tensor3(this, t, index, n, m, l, clear)
545 class(scratch_registry_t), target, intent(inout) :: this
546 type(tensor3_t), pointer, intent(inout) :: t
547 integer, intent(inout) :: index
548 integer, intent(in) :: n, m, l
549 logical, intent(in) :: clear
550
551 associate(entries => this%entries, n_entries => this%n_entries, &
552 n_inuse => this%n_inuse)
553
554 do index = 1, this%get_size()
555 if (.not. this%inuse(index)) then
556
557 if (.not. entries(index)%is_allocated()) then
558 call entries(index)%init_tensor3(n, m, l)
559 n_entries = n_entries + 1
560 else if (trim(entries(index)%get_type()) .ne. 'tensor3') then
561 cycle
562 end if
563
564 t => entries(index)%get_tensor3()
565 if (t%get_n1() .ne. n .or. &
566 t%get_n2() .ne. m .or. &
567 t%get_n3() .ne. l) then
568 nullify(t)
569 cycle
570 end if
571
572 if (clear .and. neko_bcknd_device .eq. 1) then
573 call device_rzero(t%x_d, t%size())
574 else if (clear) then
575 call rzero(t%x, t%size())
576 end if
577 this%inuse(index) = .true.
578 this%n_inuse = this%n_inuse + 1
579 return
580 end if
581 end do
582
583 ! all existing matrices in use, we need to expand to add a new one
584 index = n_entries + 1
585 call this%expand()
586 n_entries = n_entries + 1
587 n_inuse = n_inuse + 1
588 this%inuse(n_entries) = .true.
589 call this%entries(n_entries)%init_tensor3(n, m, l)
590 t => this%entries(n_entries)%get_tensor3()
591
592 end associate
593 end subroutine request_tensor3
594
603 subroutine request_tensor4(this, t, index, n, m, l, k, clear)
604 class(scratch_registry_t), target, intent(inout) :: this
605 type(tensor4_t), pointer, intent(inout) :: t
606 integer, intent(inout) :: index
607 integer, intent(in) :: n, m, l, k
608 logical, intent(in) :: clear
609
610 associate(entries => this%entries, n_entries => this%n_entries, &
611 n_inuse => this%n_inuse)
612
613 do index = 1, this%get_size()
614 if (.not. this%inuse(index)) then
615
616 if (.not. entries(index)%is_allocated()) then
617 call entries(index)%init_tensor4(n, m, l, k)
618 n_entries = n_entries + 1
619 else if (trim(entries(index)%get_type()) .ne. 'tensor4') then
620 cycle
621 end if
622
623 t => entries(index)%get_tensor4()
624 if (t%get_n1() .ne. n .or. &
625 t%get_n2() .ne. m .or. &
626 t%get_n3() .ne. l .or. &
627 t%get_n4() .ne. k) then
628 nullify(t)
629 cycle
630 end if
631
632 if (clear .and. neko_bcknd_device .eq. 1) then
633 call device_rzero(t%x_d, t%size())
634 else if (clear) then
635 call rzero(t%x, t%size())
636 end if
637 this%inuse(index) = .true.
638 this%n_inuse = this%n_inuse + 1
639 return
640 end if
641 end do
642
643 ! all existing matrices in use, we need to expand to add a new one
644 index = n_entries + 1
645 call this%expand()
646 n_entries = n_entries + 1
647 n_inuse = n_inuse + 1
648 this%inuse(n_entries) = .true.
649 call this%entries(n_entries)%init_tensor4(n, m, l, k)
650 t => this%entries(n_entries)%get_tensor4()
651
652 end associate
653 end subroutine request_tensor4
654
659 subroutine request_field_stored_dof(this, f, index, clear)
660 class(scratch_registry_t), target, intent(inout) :: this
661 type(field_t), pointer, intent(inout) :: f
662 integer, intent(inout) :: index
663 logical, intent(in) :: clear
664 character(len=10) :: name
665
666 if (.not. associated(this%dof)) then
667 call neko_error("scratch_registry::request_field_stored_dof: "&
668 // "No dofmap assigned to scratch registry.")
669 end if
670
671 associate(entries => this%entries, n_entries => this%n_entries, &
672 n_inuse => this%n_inuse)
673
674 do index = 1, this%get_size()
675 if (.not. this%inuse(index)) then
676
677 if (.not. entries(index)%is_allocated()) then
678 write(name, "(A3,I0.3)") "wrk", index
679 call entries(index)%init_field(this%dof, trim(name))
680 n_entries = n_entries + 1
681 else if (entries(index)%get_type() .ne. 'field') then
682 cycle
683 end if
684
685 f => entries(index)%get_field()
686 if (clear) call field_rzero(f)
687 this%inuse(index) = .true.
688 this%n_inuse = this%n_inuse + 1
689 return
690 end if
691 end do
692
693 ! all existing fields in use, we need to expand to add a new one
694 index = n_entries + 1
695 call this%expand()
696 n_entries = n_entries + 1
697 n_inuse = n_inuse + 1
698 this%inuse(n_entries) = .true.
699 write (name, "(A3,I0.3)") "wrk", index
700 call this%entries(n_entries)%init_field(this%dof, trim(name))
701 f => this%entries(n_entries)%get_field()
702
703 end associate
704 end subroutine request_field_stored_dof
705
711 subroutine request_field_free_dof(this, f, index, dof, clear)
712 class(scratch_registry_t), target, intent(inout) :: this
713 type(field_t), pointer, intent(inout) :: f
714 integer, intent(inout) :: index
715 type(dofmap_t), target, intent(in) :: dof
716 logical, intent(in) :: clear
717 character(len=10) :: name
718
719 associate(entries => this%entries, n_entries => this%n_entries, &
720 n_inuse => this%n_inuse)
721
722 do index = 1, this%get_size()
723 if (.not. this%inuse(index)) then
724
725 if (.not. entries(index)%is_allocated()) then
726 write(name, "(A3,I0.3)") "wrk", index
727 call entries(index)%init_field(dof, trim(name))
728 n_entries = n_entries + 1
729 else if (entries(index)%get_type() .ne. 'field') then
730 cycle
731 end if
732
733 f => entries(index)%get_field()
734 if (.not. associated(f%dof, dof)) then
735 nullify(f)
736 cycle
737 end if
738
739 if (clear) call field_rzero(f)
740 this%inuse(index) = .true.
741 this%n_inuse = this%n_inuse + 1
742 return
743 end if
744 end do
745
746 ! all existing fields in use, we need to expand to add a new one
747 index = n_entries + 1
748 call this%expand()
749 n_entries = n_entries + 1
750 n_inuse = n_inuse + 1
751 this%inuse(n_entries) = .true.
752 write (name, "(A3,I0.3)") "wrk", index
753 call this%entries(n_entries)%init_field(dof, trim(name))
754 f => this%entries(n_entries)%get_field()
755
756 end associate
757 end subroutine request_field_free_dof
758
761 subroutine relinquish_host_array_single(this, index)
762 class(scratch_registry_t), target, intent(inout) :: this
763 integer, intent(inout) :: index
764
765 if (trim(this%entries(index)%get_type()) .ne. 'host_array') then
766 call neko_error("scratch_registry::relinquish_host_array_single: " &
767 // "Register entry is not a host_array.")
768 end if
769
770 this%inuse(index) = .false.
771 this%n_inuse = this%n_inuse - 1
772 end subroutine relinquish_host_array_single
773
776 subroutine relinquish_host_array_multiple(this, indices)
777 class(scratch_registry_t), target, intent(inout) :: this
778 integer, intent(inout) :: indices(:)
779 integer :: i
780
781 do i = 1, size(indices)
782 if (trim(this%entries(indices(i))%get_type()) .ne. 'host_array') then
783 call neko_error("scratch_registry::relinquish_host_array_single: " &
784 // "Register entry is not a host_array.")
785 end if
786
787 this%inuse(indices(i)) = .false.
788 end do
789 this%n_inuse = this%n_inuse - size(indices)
790 end subroutine relinquish_host_array_multiple
791
794 subroutine relinquish_device_array_single(this, index)
795 class(scratch_registry_t), target, intent(inout) :: this
796 integer, intent(inout) :: index
797
798 if (trim(this%entries(index)%get_type()) .ne. 'device_array') then
799 call neko_error("scratch_registry::relinquish_device_array_single: " &
800 // "Register entry is not a device_array.")
801 end if
802
803 this%inuse(index) = .false.
804 this%n_inuse = this%n_inuse - 1
805 end subroutine relinquish_device_array_single
806
809 subroutine relinquish_device_array_multiple(this, indices)
810 class(scratch_registry_t), target, intent(inout) :: this
811 integer, intent(inout) :: indices(:)
812 integer :: i
813
814 do i = 1, size(indices)
815 if (trim(this%entries(indices(i))%get_type()) .ne. 'device_array') then
816 call neko_error("scratch_registry::relinquish_device_array_single: " &
817 // "Register entry is not a device_array.")
818 end if
819
820 this%inuse(indices(i)) = .false.
821 end do
822 this%n_inuse = this%n_inuse - size(indices)
824
827 subroutine relinquish_vector_single(this, index)
828 class(scratch_registry_t), target, intent(inout) :: this
829 integer, intent(inout) :: index
830
831 if (trim(this%entries(index)%get_type()) .ne. 'vector') then
832 call neko_error("scratch_registry::relinquish_vector_single: " &
833 // "Register entry is not a vector.")
834 end if
835
836 this%inuse(index) = .false.
837 this%n_inuse = this%n_inuse - 1
838 end subroutine relinquish_vector_single
839
842 subroutine relinquish_vector_multiple(this, indices)
843 class(scratch_registry_t), target, intent(inout) :: this
844 integer, intent(inout) :: indices(:)
845 integer :: i
846
847 do i = 1, size(indices)
848 if (trim(this%entries(indices(i))%get_type()) .ne. 'vector') then
849 call neko_error("scratch_registry::relinquish_vector_single: " &
850 // "Register entry is not a vector.")
851 end if
852
853 this%inuse(indices(i)) = .false.
854 end do
855 this%n_inuse = this%n_inuse - size(indices)
856 end subroutine relinquish_vector_multiple
857
860 subroutine relinquish_matrix_single(this, index)
861 class(scratch_registry_t), target, intent(inout) :: this
862 integer, intent(inout) :: index
863
864 if (trim(this%entries(index)%get_type()) .ne. 'matrix') then
865 call neko_error("scratch_registry::relinquish_matrix_single: " &
866 // "Register entry is not a matrix.")
867 end if
868
869 this%inuse(index) = .false.
870 this%n_inuse = this%n_inuse - 1
871 end subroutine relinquish_matrix_single
872
875 subroutine relinquish_matrix_multiple(this, indices)
876 class(scratch_registry_t), target, intent(inout) :: this
877 integer, intent(inout) :: indices(:)
878 integer :: i
879
880 do i = 1, size(indices)
881 if (trim(this%entries(indices(i))%get_type()) .ne. 'matrix') then
882 call neko_error("scratch_registry::relinquish_matrix_single: " &
883 // "Register entry is not a matrix.")
884 end if
885
886 this%inuse(indices(i)) = .false.
887 end do
888 this%n_inuse = this%n_inuse - size(indices)
889 end subroutine relinquish_matrix_multiple
890
893 subroutine relinquish_tensor3_single(this, index)
894 class(scratch_registry_t), target, intent(inout) :: this
895 integer, intent(inout) :: index
896
897 if (trim(this%entries(index)%get_type()) .ne. 'tensor3') then
898 call neko_error("scratch_registry::relinquish_tensor3_single: " &
899 // "Register entry is not a tensor3.")
900 end if
901
902 this%inuse(index) = .false.
903 this%n_inuse = this%n_inuse - 1
904 end subroutine relinquish_tensor3_single
905
908 subroutine relinquish_tensor3_multiple(this, indices)
909 class(scratch_registry_t), target, intent(inout) :: this
910 integer, intent(inout) :: indices(:)
911 integer :: i
912
913 do i = 1, size(indices)
914 if (trim(this%entries(indices(i))%get_type()) .ne. 'tensor3') then
915 call neko_error("scratch_registry::relinquish_tensor3_single: " &
916 // "Register entry is not a tensor3.")
917 end if
918
919 this%inuse(indices(i)) = .false.
920 end do
921 this%n_inuse = this%n_inuse - size(indices)
922 end subroutine relinquish_tensor3_multiple
923
926 subroutine relinquish_tensor4_single(this, index)
927 class(scratch_registry_t), target, intent(inout) :: this
928 integer, intent(inout) :: index
929
930 if (trim(this%entries(index)%get_type()) .ne. 'tensor4') then
931 call neko_error("scratch_registry::relinquish_tensor4_single: " &
932 // "Register entry is not a tensor4.")
933 end if
934
935 this%inuse(index) = .false.
936 this%n_inuse = this%n_inuse - 1
937 end subroutine relinquish_tensor4_single
938
941 subroutine relinquish_tensor4_multiple(this, indices)
942 class(scratch_registry_t), target, intent(inout) :: this
943 integer, intent(inout) :: indices(:)
944 integer :: i
945
946 do i = 1, size(indices)
947 if (trim(this%entries(indices(i))%get_type()) .ne. 'tensor4') then
948 call neko_error("scratch_registry::relinquish_tensor4_single: " &
949 // "Register entry is not a tensor4.")
950 end if
951
952 this%inuse(indices(i)) = .false.
953 end do
954 this%n_inuse = this%n_inuse - size(indices)
955 end subroutine relinquish_tensor4_multiple
956
959 subroutine relinquish_field_single(this, index)
960 class(scratch_registry_t), target, intent(inout) :: this
961 integer, intent(inout) :: index
962
963 if (trim(this%entries(index)%get_type()) .ne. 'field') then
964 call neko_error("scratch_registry::relinquish_field_single: " &
965 // "Register entry is not a field.")
966 end if
967
968 this%inuse(index) = .false.
969 this%n_inuse = this%n_inuse - 1
970 end subroutine relinquish_field_single
971
974 subroutine relinquish_field_multiple(this, indices)
975 class(scratch_registry_t), target, intent(inout) :: this
976 integer, intent(inout) :: indices(:)
977 integer :: i
978
979 do i = 1, size(indices)
980 if (trim(this%entries(indices(i))%get_type()) .ne. 'field') then
981 call neko_error("scratch_registry::relinquish_field_single: " &
982 // "Register entry is not a field.")
983 end if
984
985 this%inuse(indices(i)) = .false.
986 end do
987 this%n_inuse = this%n_inuse - size(indices)
988 end subroutine relinquish_field_multiple
989
992 subroutine relinquish_single(this, index)
993 class(scratch_registry_t), target, intent(inout) :: this
994 integer, intent(inout) :: index
995
996 this%inuse(index) = .false.
997 this%n_inuse = this%n_inuse - 1
998 end subroutine relinquish_single
999
1002 subroutine relinquish_multiple(this, indices)
1003 class(scratch_registry_t), target, intent(inout) :: this
1004 integer, intent(inout) :: indices(:)
1005 integer :: i
1006
1007 do i = 1, size(indices)
1008 this%inuse(indices(i)) = .false.
1009 end do
1010 this%n_inuse = this%n_inuse - size(indices)
1011 end subroutine relinquish_multiple
1012
1013end module scratch_registry
Module containing device only array type.
subroutine, public device_rzero(a_d, n, strm)
Zero a real vector.
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
subroutine, public field_rzero(a, n)
Zero a real vector.
Defines a field.
Definition field.f90:34
Module containing host-only array type.
Definition math.f90:60
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:239
subroutine, public matrix_rzero(a, n)
Zero a real matrix .
Defines a matrix.
Definition matrix.f90:34
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Defines a registry entry for storing and requesting temporary objects This is used in the registries ...
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
subroutine request_field_free_dof(this, f, index, dof, clear)
Get a field from the registry by assigning it to a pointer.
subroutine relinquish_matrix_single(this, index)
Relinquish the use of a matrix in the registry.
pure logical function get_inuse(this, index)
Get the inuse status for a given index.
subroutine request_tensor3(this, t, index, n, m, l, clear)
Get a tensor3 from the registry by assigning it to a pointer.
pure integer function get_n_inuse(this)
Get the number of objects currently in use.
subroutine scratch_registry_free(this)
Destructor.
subroutine relinquish_matrix_multiple(this, indices)
Relinquish the use of multiple matrices in the registry.
subroutine relinquish_host_array_single(this, index)
Relinquish the use of a host_array in the registry.
pure integer function get_n_entries(this)
Get the number of objects stored in the registry.
subroutine relinquish_device_array_multiple(this, indices)
Relinquish the use of multiple device_arrays in the registry.
subroutine relinquish_tensor3_single(this, index)
Relinquish the use of a tensor3 in the registry.
subroutine request_host_array(this, v, index, n, clear)
Get a host array from the registry by assigning it to a pointer.
subroutine relinquish_field_single(this, index)
Relinquish the use of a field in the registry.
subroutine relinquish_host_array_multiple(this, indices)
Relinquish the use of multiple host_arrays in the registry.
pure integer function get_size(this)
Get the size of the objects array.
subroutine request_tensor4(this, t, index, n, m, l, k, clear)
Get a tensor4 from the registry by assigning it to a pointer.
subroutine relinquish_tensor3_multiple(this, indices)
Relinquish the use of multiple tensor3s in the registry.
subroutine scratch_registry_set_dofmap(this, dof)
Assign a dofmap to the scratch registry.
subroutine relinquish_field_multiple(this, indices)
Relinquish the use of multiple fields in the registry.
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
subroutine relinquish_vector_multiple(this, indices)
Relinquish the use of multiple vectors in the registry.
subroutine expand(this)
subroutine relinquish_device_array_single(this, index)
Relinquish the use of a device_array in the registry.
subroutine relinquish_tensor4_single(this, index)
Relinquish the use of a tensor4 in the registry.
subroutine relinquish_vector_single(this, index)
Relinquish the use of a vector in the registry.
subroutine request_matrix(this, m, index, nrows, ncols, clear)
Get a matrix from the registry by assigning it to a pointer.
subroutine request_vector(this, v, index, n, clear)
Get a vector from the registry by assigning it to a pointer.
subroutine request_device_array(this, v, index, n, clear)
Get a device array from the registry by assigning it to a pointer.
subroutine scratch_registry_init(this, size, expansion_size, dof)
Constructor, optionally taking initial registry and expansion size as argument.
subroutine relinquish_multiple(this, indices)
Relinquish the use of multiple objects in the registry.
subroutine relinquish_single(this, index)
Relinquish the use of an object in the registry.
subroutine request_field_stored_dof(this, f, index, clear)
Get a field from the registry by assigning it to a pointer.
subroutine relinquish_tensor4_multiple(this, indices)
Relinquish the use of multiple tensor4s in the registry.
pure integer function get_expansion_size(this)
Get the expansion size.
Defines a rank-3 tensor.
Definition tensor3.f90:34
Defines a rank-4 tensor.
Definition tensor4.f90:34
Utilities.
Definition utils.f90:35
subroutine, public vector_rzero(a, n)
Zero a real vector.
Defines a vector.
Definition vector.f90:34
Device-only temporary array.
Host-only temporary array.