57 use,
intrinsic :: iso_c_binding, only : c_ptr
65 logical,
private,
allocatable :: inuse(:)
67 integer,
private :: n_entries = 0
69 integer,
private :: n_inuse = 0
71 integer,
private :: expansion_size = 10
75 procedure,
private, pass(this) ::
expand
182 integer,
optional,
intent(in) :: size
183 integer,
optional,
intent(in) :: expansion_size
184 type(
dofmap_t),
target,
intent(in),
optional :: dof
190 if (
present(size)) s =
size
191 if (
present(dof)) this%dof => dof
193 allocate(this%entries(s))
194 allocate(this%inuse(s))
195 this%inuse(:) = .false.
197 this%expansion_size = 10
198 if (
present(expansion_size)) this%expansion_size = expansion_size
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.")
212 deallocate(this%inuse)
215 if (
allocated(this%entries))
then
216 do i = 1, this%n_entries
217 call this%entries(i)%free()
220 deallocate(this%entries)
223 if (
associated(this%dof))
nullify(this%dof)
228 this%expansion_size = 10
238 type(
dofmap_t),
target,
intent(in) :: dof
240 if (
associated(this%dof, dof))
then
242 else if (
associated(this%dof))
then
243 call neko_error(
"scratch_registry::set_dofmap: "&
244 //
"Dofmap is already assigned to scratch registry.")
263 n = count(this%inuse)
271 if (
allocated(this%entries))
then
272 n =
size(this%entries)
283 n = this%expansion_size
289 integer,
intent(in) :: index
297 logical,
allocatable :: temp2(:)
303 call move_alloc(this%entries, temp)
304 call move_alloc(this%inuse, temp2)
307 allocate(this%entries(n + this%expansion_size))
308 allocate(this%inuse(n + this%expansion_size), source = .false.)
312 call this%entries(i)%move_from(temp(i))
313 this%inuse(i) = temp2(i)
318 if (
allocated(temp))
deallocate(temp)
319 if (
allocated(temp2))
deallocate(temp2)
331 real(kind=
rp),
pointer,
dimension(:),
intent(inout) :: v
332 integer,
intent(inout) :: index
333 integer,
intent(in) :: n
334 logical,
intent(in) :: clear
337 associate(entries => this%entries, n_entries => this%n_entries, &
338 n_inuse => this%n_inuse)
340 do index = 1, this%get_size()
341 if (.not. this%inuse(index))
then
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
350 v_scratch => entries(index)%get_host_array()
351 if (v_scratch%size() .ne. n)
then
356 if (clear)
call rzero(v_scratch%x, v_scratch%size())
357 this%inuse(index) = .true.
358 this%n_inuse = this%n_inuse + 1
366 index = n_entries + 1
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()
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
393 associate(entries => this%entries, n_entries => this%n_entries, &
394 n_inuse => this%n_inuse)
396 do index = 1, this%get_size()
397 if (.not. this%inuse(index))
then
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
406 v_tmp => entries(index)%get_device_array()
407 if (v_tmp%size() .ne. n)
then
413 if (clear)
call device_rzero(v, n)
414 this%inuse(index) = .true.
415 this%n_inuse = this%n_inuse + 1
422 index = n_entries + 1
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()
442 type(vector_t),
pointer,
intent(inout) :: v
443 integer,
intent(inout) :: index
444 integer,
intent(in) :: n
445 logical,
intent(in) :: clear
447 associate(entries => this%entries, n_entries => this%n_entries, &
448 n_inuse => this%n_inuse)
450 do index = 1, this%get_size()
451 if (.not. this%inuse(index))
then
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
460 v => entries(index)%get_vector()
461 if (v%size() .ne. n)
then
466 if (clear)
call vector_rzero(v)
467 this%inuse(index) = .true.
468 this%n_inuse = this%n_inuse + 1
474 index = n_entries + 1
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()
493 type(matrix_t),
pointer,
intent(inout) :: m
494 integer,
intent(inout) :: index
495 integer,
intent(in) :: nrows, ncols
496 logical,
intent(in) :: clear
498 associate(entries => this%entries, n_entries => this%n_entries, &
499 n_inuse => this%n_inuse)
501 do index = 1, this%get_size()
502 if (.not. this%inuse(index))
then
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
511 m => entries(index)%get_matrix()
512 if (m%get_nrows() .ne. nrows .or. &
513 m%get_ncols() .ne. ncols)
then
518 if (clear)
call matrix_rzero(m)
519 this%inuse(index) = .true.
520 this%n_inuse = this%n_inuse + 1
526 index = n_entries + 1
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()
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
551 associate(entries => this%entries, n_entries => this%n_entries, &
552 n_inuse => this%n_inuse)
554 do index = 1, this%get_size()
555 if (.not. this%inuse(index))
then
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
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
572 if (clear .and. neko_bcknd_device .eq. 1)
then
573 call device_rzero(t%x_d, t%size())
575 call rzero(t%x, t%size())
577 this%inuse(index) = .true.
578 this%n_inuse = this%n_inuse + 1
584 index = n_entries + 1
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()
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
610 associate(entries => this%entries, n_entries => this%n_entries, &
611 n_inuse => this%n_inuse)
613 do index = 1, this%get_size()
614 if (.not. this%inuse(index))
then
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
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
632 if (clear .and. neko_bcknd_device .eq. 1)
then
633 call device_rzero(t%x_d, t%size())
635 call rzero(t%x, t%size())
637 this%inuse(index) = .true.
638 this%n_inuse = this%n_inuse + 1
644 index = n_entries + 1
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()
661 type(field_t),
pointer,
intent(inout) :: f
662 integer,
intent(inout) :: index
663 logical,
intent(in) :: clear
664 character(len=10) :: name
666 if (.not.
associated(this%dof))
then
667 call neko_error(
"scratch_registry::request_field_stored_dof: "&
668 //
"No dofmap assigned to scratch registry.")
671 associate(entries => this%entries, n_entries => this%n_entries, &
672 n_inuse => this%n_inuse)
674 do index = 1, this%get_size()
675 if (.not. this%inuse(index))
then
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
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
694 index = n_entries + 1
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()
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
719 associate(entries => this%entries, n_entries => this%n_entries, &
720 n_inuse => this%n_inuse)
722 do index = 1, this%get_size()
723 if (.not. this%inuse(index))
then
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
733 f => entries(index)%get_field()
734 if (.not.
associated(f%dof, dof))
then
739 if (clear)
call field_rzero(f)
740 this%inuse(index) = .true.
741 this%n_inuse = this%n_inuse + 1
747 index = n_entries + 1
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()
763 integer,
intent(inout) :: index
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.")
770 this%inuse(index) = .false.
771 this%n_inuse = this%n_inuse - 1
778 integer,
intent(inout) :: indices(:)
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.")
787 this%inuse(indices(i)) = .false.
789 this%n_inuse = this%n_inuse -
size(indices)
796 integer,
intent(inout) :: index
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.")
803 this%inuse(index) = .false.
804 this%n_inuse = this%n_inuse - 1
811 integer,
intent(inout) :: indices(:)
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.")
820 this%inuse(indices(i)) = .false.
822 this%n_inuse = this%n_inuse -
size(indices)
829 integer,
intent(inout) :: index
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.")
836 this%inuse(index) = .false.
837 this%n_inuse = this%n_inuse - 1
844 integer,
intent(inout) :: indices(:)
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.")
853 this%inuse(indices(i)) = .false.
855 this%n_inuse = this%n_inuse -
size(indices)
862 integer,
intent(inout) :: index
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.")
869 this%inuse(index) = .false.
870 this%n_inuse = this%n_inuse - 1
877 integer,
intent(inout) :: indices(:)
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.")
886 this%inuse(indices(i)) = .false.
888 this%n_inuse = this%n_inuse -
size(indices)
895 integer,
intent(inout) :: index
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.")
902 this%inuse(index) = .false.
903 this%n_inuse = this%n_inuse - 1
910 integer,
intent(inout) :: indices(:)
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.")
919 this%inuse(indices(i)) = .false.
921 this%n_inuse = this%n_inuse -
size(indices)
928 integer,
intent(inout) :: index
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.")
935 this%inuse(index) = .false.
936 this%n_inuse = this%n_inuse - 1
943 integer,
intent(inout) :: indices(:)
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.")
952 this%inuse(indices(i)) = .false.
954 this%n_inuse = this%n_inuse -
size(indices)
961 integer,
intent(inout) :: index
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.")
968 this%inuse(index) = .false.
969 this%n_inuse = this%n_inuse - 1
976 integer,
intent(inout) :: indices(:)
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.")
985 this%inuse(indices(i)) = .false.
987 this%n_inuse = this%n_inuse -
size(indices)
994 integer,
intent(inout) :: index
996 this%inuse(index) = .false.
997 this%n_inuse = this%n_inuse - 1
1004 integer,
intent(inout) :: indices(:)
1007 do i = 1,
size(indices)
1008 this%inuse(indices(i)) = .false.
1010 this%n_inuse = this%n_inuse -
size(indices)
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.
subroutine, public field_rzero(a, n)
Zero a real vector.
Module containing host-only array type.
subroutine, public rzero(a, n)
Zero a real vector.
subroutine, public matrix_rzero(a, n)
Zero a real matrix .
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
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 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.
subroutine, public vector_rzero(a, n)
Zero a real vector.
Device-only temporary array.
Host-only temporary array.