Neko  0.8.1
A portable framework for high-order spectral element flow simulations
htable.f90
Go to the documentation of this file.
1 ! Copyright (c) 2019-2023, 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 !
36 module htable
37  use num_types
38  use utils
39  use point, only : point_t
40  use tuple, only : tuple_i4_t, tuple4_i4_t, tuple_t
41  use math, only : neko_m_ln2
42  use, intrinsic :: iso_c_binding, only : c_ptr, c_associated
43  implicit none
44  private
45 
47  type :: h_tuple_t
48  logical :: valid = .false.
49  logical :: skip = .false.
50  class(*), allocatable :: key
51  class(*), allocatable :: data
52  end type h_tuple_t
53 
55  type, public, abstract :: htable_t
56  integer, private :: size
57  integer, private :: entries
58  type(h_tuple_t), private, allocatable :: t(:)
59  contains
60  procedure(htable_hash), pass(this), deferred :: hash
61  procedure, public, pass(this) :: clear => htable_clear
62  procedure, public, pass(this) :: free => htable_free
63  procedure, public, pass(this) :: num_entries => htable_num_entries
64  procedure, public, pass(this) :: get_size => htable_size
65  end type htable_t
66 
67  abstract interface
68  pure function htable_hash(this, k, c) result(hash)
69  import htable_t
70  class(htable_t), intent(in) :: this
71  class(*), intent(in) :: k
72  integer, value :: c
73  integer :: hash
74  end function htable_hash
75  end interface
76 
77  !
78  ! Implementations
79  !
80 
82  type, public, extends(htable_t) :: htable_i4_t
83  contains
84  procedure, pass(this) :: init => htable_i4_init
85  procedure, pass(this) :: set => htable_i4_set
86  procedure, pass(this) :: get => htable_i4_get
87  procedure, pass(this) :: hash => htable_i4_hash
88  procedure, pass(this) :: remove => htable_i4_remove
89  end type htable_i4_t
90 
92  type, public, extends(htable_t) :: htable_i8_t
93  contains
94  procedure, pass(this) :: init => htable_i8_init
95  procedure, pass(this) :: set => htable_i8_set
96  procedure, pass(this) :: get => htable_i8_get
97  procedure, pass(this) :: hash => htable_i8_hash
98  procedure, pass(this) :: remove => htable_i8_remove
99  end type htable_i8_t
100 
102  type, public, extends(htable_t) :: htable_r8_t
103  contains
104  procedure, pass(this) :: init => htable_r8_init
105  procedure, pass(this) :: set => htable_r8_set
106  procedure, pass(this) :: get => htable_r8_get
107  procedure, pass(this) :: hash => htable_r8_hash
108  procedure, pass(this) :: remove => htable_r8_remove
109  end type htable_r8_t
110 
112  type, public, extends(htable_t) :: htable_pt_t
113  contains
114  procedure, pass(this) :: init => htable_pt_init
115  procedure, pass(this) :: set => htable_pt_set
116  procedure, pass(this) :: get => htable_pt_get
117  procedure, pass(this) :: hash => htable_pt_hash
118  procedure, pass(this) :: remove => htable_pt_remove
119  end type htable_pt_t
120 
122  type, public, extends(htable_t) :: htable_i4t2_t
123  contains
124  procedure, pass(this) :: init => htable_i4t2_init
125  procedure, pass(this) :: set => htable_i4t2_set
126  procedure, pass(this) :: get => htable_i4t2_get
127  procedure, pass(this) :: hash => htable_i4t2_hash
128  procedure, pass(this) :: remove => htable_i4t2_remove
129  end type htable_i4t2_t
130 
132  type, public, extends(htable_t) :: htable_i4t4_t
133  contains
134  procedure, pass(this) :: init => htable_i4t4_init
135  procedure, pass(this) :: set => htable_i4t4_set
136  procedure, pass(this) :: get => htable_i4t4_get
137  procedure, pass(this) :: hash => htable_i4t4_hash
138  procedure, pass(this) :: remove => htable_i4t4_remove
139  end type htable_i4t4_t
140 
142  type, public, extends(htable_t) :: htable_cptr_t
143  contains
144  procedure, pass(this) :: init => htable_cptr_init
145  procedure, pass(this) :: set => htable_cptr_set
146  procedure, pass(this) :: get => htable_cptr_get
147  procedure, pass(this) :: hash => htable_cptr_hash
148  procedure, pass(this) :: remove => htable_cptr_remove
149  end type htable_cptr_t
150 
151  !
152  ! Iterators
153  !
154 
156  type, public, abstract :: htable_iter_t
157  integer, private :: n
158  class(htable_t), pointer :: t
159  contains
160  procedure, public, pass(this) :: next => htable_iter_next
161  procedure, public, pass(this) :: reset => htable_iter_reset
162  procedure, public, pass(this) :: data => htable_iter_data
163  end type htable_iter_t
164 
166  type, public, extends(htable_iter_t) :: htable_iter_i4_t
167  contains
168  procedure, pass(this) :: init => htable_iter_i4_init
169  procedure, pass(this) :: value => htable_iter_i4_value
170  procedure, pass(this) :: key => htable_iter_i4_key
172  end type htable_iter_i4_t
173 
175  type, public, extends(htable_iter_t) :: htable_iter_i8_t
176  contains
177  procedure, pass(this) :: init => htable_iter_i8_init
178  procedure, pass(this) :: value => htable_iter_i8_value
179  procedure, pass(this) :: key => htable_iter_i8_key
181  end type htable_iter_i8_t
182 
184  type, public, extends(htable_iter_t) :: htable_iter_r8_t
185  contains
186  procedure, pass(this) :: init => htable_iter_r8_init
187  procedure, pass(this) :: value => htable_iter_r8_value
188  procedure, pass(this) :: key => htable_iter_r8_key
190  end type htable_iter_r8_t
191 
193  type, public, extends(htable_iter_t) :: htable_iter_pt_t
194  contains
195  procedure, pass(this) :: init => htable_iter_pt_init
196  procedure, pass(this) :: value => htable_iter_pt_value
197  procedure, pass(this) :: key => htable_iter_pt_key
199  end type htable_iter_pt_t
200 
202  type, public, extends(htable_iter_t) :: htable_iter_i4t2_t
203  contains
204  procedure, pass(this) :: init => htable_iter_i4t2_init
205  procedure, pass(this) :: value => htable_iter_i4t2_value
206  procedure, pass(this) :: key => htable_iter_i4t2_key
208  end type htable_iter_i4t2_t
209 
211  type, public, extends(htable_iter_t) :: htable_iter_i4t4_t
212  contains
213  procedure, pass(this) :: init => htable_iter_i4t4_init
214  procedure, pass(this) :: value => htable_iter_i4t4_value
215  procedure, pass(this) :: key => htable_iter_i4t4_key
217  end type htable_iter_i4t4_t
218 
220  type, public, extends(htable_iter_t) :: htable_iter_cptr_t
221  contains
222  procedure, pass(this) :: init => htable_iter_cptr_init
223  procedure, pass(this) :: value => htable_iter_cptr_value
224  procedure, pass(this) :: key => htable_iter_cptr_key
226  end type htable_iter_cptr_t
227 
228  !
229  ! Type wrappers
230  !
231  type, public :: h_cptr_t
232  type(c_ptr) :: ptr
233  end type h_cptr_t
234 
235 contains
236 
238  subroutine htable_init(this, size, key, data)
239  class(htable_t), intent(inout) :: this
240  integer, value :: size
241  class(*), target, intent(in) :: key
242  class(*), target, intent(in), optional :: data
243  class(*), pointer :: dp
244  integer :: i
245 
246 
247  call htable_free(this)
248 
249  if (size .lt. 4) then
250  size = 4
251  end if
252 
253  size = ishft(1, ceiling(log(dble(size)) / neko_m_ln2))
254 
255  allocate(this%t(0:size))
256  this%t(:)%valid = .false.
257  this%size = size
258  this%entries = 0
259 
260  dp => key
261  if (present(data)) then
262  dp => data
263  end if
264 
265  do i = 0, size
266  allocate(this%t(i)%key, source=key)
267  allocate(this%t(i)%data, source=dp)
268  end do
269  end subroutine htable_init
270 
272  subroutine htable_free(this)
273  class(htable_t), intent(inout) :: this
274  integer i
275 
276  if (allocated(this%t)) then
277  do i = 0, this%size
278  deallocate(this%t(i)%key)
279  deallocate(this%t(i)%data)
280  end do
281  deallocate(this%t)
282  end if
283 
284  this%size = 0
285  this%entries = 0
286 
287  end subroutine htable_free
288 
290  subroutine htable_clear(this)
291  class(htable_t), intent(inout) :: this
292 
293  if (allocated(this%t)) then
294  this%t(:)%valid = .false.
295  this%entries = 0
296  else
297  call neko_error("Hash table not allocated")
298  end if
299 
300  end subroutine htable_clear
301 
303  pure function htable_num_entries(this) result(entries)
304  class(htable_t), intent(in) :: this
305  integer :: entries
306  entries = this%entries
307  end function htable_num_entries
308 
310  pure function htable_size(this) result(size)
311  class(htable_t), intent(in) :: this
312  integer :: size
313  size = this%size
314  end function htable_size
315 
316 
318  recursive subroutine htable_set(this, key, data)
319  class(htable_t), intent(inout) :: this
320  class(*), intent(inout) :: key
321  class(*), intent(inout) :: data
322  class(htable_t), allocatable :: tmp
323  integer index, i, c
324 
325  c = 0
326  i = log(1.0/this%size)/log(0.6)
327  !i = (this%size-1)/10
328  index = 0
329 
330  do while (i .ge. 0)
331  index = this%hash(key, c**2)
332  if (index .lt. 0) then
333  call neko_error("Invalid hash generated")
334  end if
336  if ((.not. this%t(index)%valid) .or. &
337  htable_eq_key(this, index, key)) then
338  call htable_set_key(this, index, key)
339  call htable_set_data(this, index, data)
340  if (.not. this%t(index)%valid) then
341  this%entries = this%entries + 1
342  end if
343  this%t(index)%valid = .true.
344  this%t(index)%skip = .false.
345  return
346  end if
347  i = i - 1
348  c = c + 1
349  end do
350 
351  select type(key)
352  type is (integer)
353  allocate(htable_i4_t::tmp)
354  type is (integer(i8))
355  allocate(htable_i8_t::tmp)
356  type is (double precision)
357  allocate(htable_r8_t::tmp)
358  type is (point_t)
359  allocate(htable_pt_t::tmp)
360  type is (tuple_i4_t)
361  allocate(htable_i4t2_t::tmp)
362  type is (tuple4_i4_t)
363  allocate(htable_i4t4_t::tmp)
364  type is (h_cptr_t)
365  allocate(htable_cptr_t::tmp)
366  class default
367  call neko_error('Invalid htable key')
368  end select
369 
370  call htable_init(tmp, ishft(this%size, 1), key, data)
371 
372  do i = 0, this%size - 1
373  if (this%t(i)%valid) then
374  call htable_set(tmp, this%t(i)%key, this%t(i)%data)
375  end if
376  end do
377  this%size = tmp%size
378  call move_alloc(tmp%t, this%t)
379 
380  call htable_set(this, key, data)
381 
382  end subroutine htable_set
383 
385  function htable_get(this, key, data) result(rcode)
386  class(htable_t), intent(inout) :: this
387  class(*), intent(inout) :: key
388  class(*), intent(inout) :: data
389  integer :: rcode
390  integer :: index, i, c
391 
392  c = 0
393  i = this%size - 1
394 
395  do while (i .ge. 0)
396  index = this%hash(key, c**2)
397  if (index .lt. 0) then
398  call neko_error("Invalid hash generated")
399  end if
400 
401  if (.not. this%t(index)%valid .and. &
402  .not. this%t(index)%skip) then
403  rcode = 1
404  return
405  else if ((this%t(index)%valid) .and. &
406  htable_eq_key(this, index, key)) then
407  call htable_get_data(this, index, data)
408  rcode = 0
409  return
410  end if
411  i = i - 1
412  c = c + 1
413  end do
414  rcode = 1
415  end function htable_get
416 
418  subroutine htable_remove(this, key)
419  class(htable_t), intent(inout) :: this
420  class(*), intent(inout) :: key
421  integer :: index, i, c
422 
423  c = 0
424  i = this%size - 1
425 
426  do while (i .ge. 0)
427  index = this%hash(key, c**2)
428  if (index .lt. 0) then
429  call neko_error("Invalid hash generated")
430  end if
431 
432  if ((this%t(index)%valid) .and. &
433  htable_eq_key(this, index, key)) then
434  this%t(index)%valid = .false.
435  this%t(index)%skip = .true.
436  this%entries = this%entries - 1
437  return
438  end if
439  i = i - 1
440  c = c + 1
441  end do
442  end subroutine htable_remove
443 
445  subroutine htable_set_data(this, idx, data)
446  class(htable_t), target, intent(inout) :: this
447  integer, intent(in) :: idx
448  class(*), intent(in) :: data
449  class(*), pointer :: hdp
450 
451  hdp => this%t(idx)%data
452  select type (data)
453  type is (integer)
454  select type(hdp)
455  type is (integer)
456  hdp = data
457  end select
458  type is (integer(i8))
459  select type(hdp)
460  type is (integer(i8))
461  hdp = data
462  end select
463  type is (double precision)
464  select type(hdp)
465  type is (double precision)
466  hdp = data
467  end select
468  type is (point_t)
469  select type(hdp)
470  type is (point_t)
471  hdp = data
472  end select
473  class is (tuple_t)
474  select type(hdp)
475  type is (tuple_i4_t)
476  hdp = data
477  type is (tuple4_i4_t)
478  hdp = data
479  end select
480  type is (h_cptr_t)
481  select type(hdp)
482  type is (h_cptr_t)
483  hdp = data
484  end select
485  class default
486  call neko_error('Invalid htable data (set)')
487  end select
488  end subroutine htable_set_data
489 
491  subroutine htable_get_data(this, idx, data)
492  class(htable_t), intent(in) :: this
493  integer, intent(in) :: idx
494  class(*), intent(inout) :: data
495 
496  select type (hdp=>this%t(idx)%data)
497  type is (integer)
498  select type(data)
499  type is (integer)
500  data = hdp
501  end select
502  type is (integer(i8))
503  select type(data)
504  type is (integer(i8))
505  data = hdp
506  end select
507  type is (double precision)
508  select type(data)
509  type is (double precision)
510  data = hdp
511  end select
512  type is (point_t)
513  select type(data)
514  type is (point_t)
515  data = hdp
516  end select
517  class is (tuple_t)
518  select type(data)
519  type is (tuple_i4_t)
520  data = hdp
521  type is (tuple4_i4_t)
522  data = hdp
523  end select
524  type is (h_cptr_t)
525  select type (data)
526  type is (h_cptr_t)
527  data = hdp
528  end select
529  class default
530  call neko_error('Invalid htable data (get)')
531  end select
532  end subroutine htable_get_data
533 
535  pure function htable_eq_key(this, idx, key) result(res)
536  class(htable_t), intent(in) :: this
537  integer, intent(in) :: idx
538  class(*), intent(in) :: key
539  logical :: res
540 
541  res = .true.
542  select type (kp=>this%t(idx)%key)
543  type is (integer)
544  select type(key)
545  type is (integer)
546  res = (kp .eq. key)
547  end select
548  type is (integer(i8))
549  select type(key)
550  type is (integer(i8))
551  res = (kp .eq. key)
552  end select
553  type is (double precision)
554  select type(key)
555  type is (double precision)
556  res = (kp .eq. key)
557  end select
558  type is (point_t)
559  select type (key)
560  type is (point_t)
561  res = (kp .eq. key)
562  end select
563  class is (tuple_t)
564  select type (key)
565  type is (tuple_i4_t)
566  res = (key .eq. kp)
567  type is (tuple4_i4_t)
568  res = (key .eq. kp)
569  end select
570  type is (h_cptr_t)
571  select type (key)
572  type is (h_cptr_t)
573  res = c_associated(kp%ptr, key%ptr)
574  end select
575  end select
576  end function htable_eq_key
577 
579  subroutine htable_set_key(this, idx, key)
580  class(htable_t), target, intent(inout) :: this
581  integer, intent(in) :: idx
582  class(*), intent(in) :: key
583  class(*), pointer :: kp
584 
585  kp => this%t(idx)%key
586  select type(key)
587  type is (integer)
588  select type(kp)
589  type is (integer)
590  kp = key
591  end select
592  type is (integer(i8))
593  select type(kp)
594  type is (integer(i8))
595  kp = key
596  end select
597  type is (double precision)
598  select type(kp)
599  type is (double precision)
600  kp = key
601  end select
602  type is (point_t)
603  select type (kp)
604  type is (point_t)
605  kp = key
606  end select
607  class is (tuple_t)
608  select type(kp)
609  type is (tuple_i4_t)
610  kp = key
611  type is (tuple4_i4_t)
612  kp = key
613  end select
614  type is (h_cptr_t)
615  select type(kp)
616  type is (h_cptr_t)
617  kp = key
618  end select
619  class default
620  call neko_error('Invalid htable key (set)')
621  end select
622  end subroutine htable_set_key
623 
625  function htable_iter_next(this) result(valid)
626  class(htable_iter_t), intent(inout) :: this
627  logical :: valid
628 
629  this%n = this%n + 1
630  do while ((.not. this%t%t(this%n)%valid) .and. (this%n .lt. this%t%size))
631  this%n = this%n + 1
632  end do
633 
634  valid = (this%n .lt. this%t%size)
635  if (.not. valid) this%n = -1
636 
637  end function htable_iter_next
638 
640  subroutine htable_iter_reset(this)
641  class(htable_iter_t), intent(inout) :: this
642  this%n = -1
643  end subroutine htable_iter_reset
644 
649  subroutine htable_iter_data(this, data)
650  class(htable_iter_t), target, intent(inout) :: this
651  class(*), intent(inout) :: data
652  class(*), pointer :: hdp
653 
654  hdp => this%t%t(this%n)%data
655  select type(hdp)
656  type is (integer)
657  select type (data)
658  type is (integer)
659  data = hdp
660  end select
661  type is (integer(i8))
662  select type (data)
663  type is (integer(i8))
664  data = hdp
665  end select
666  type is (double precision)
667  select type(data)
668  type is (double precision)
669  data = hdp
670  end select
671  type is (point_t)
672  select type (data)
673  type is (point_t)
674  data = hdp
675  end select
676  class is (tuple_t)
677  select type (data)
678  type is (tuple_i4_t)
679  data = hdp
680  type is (tuple4_i4_t)
681  data = hdp
682  end select
683  type is (h_cptr_t)
684  select type (data)
685  type is (h_cptr_t)
686  data = hdp
687  end select
688  class default
689  call neko_error('Invalid htable data (iter)')
690  end select
691 
692  end subroutine htable_iter_data
693 
694  !
695  ! Integer based implementation
696  !
698  subroutine htable_i4_init(this, size, data)
699  class(htable_i4_t), intent(inout) :: this
700  integer, value :: size
701  class(*), intent(inout), optional :: data
702  integer :: key
703 
704  if (present(data)) then
705  call htable_init(this, size, key, data)
706  else
707  call htable_init(this, size, key)
708  end if
709 
710  end subroutine htable_i4_init
711 
713  subroutine htable_i4_set(this, key, data)
714  class(htable_i4_t), intent(inout) :: this
715  integer, intent(inout) :: key
716  class(*), intent(inout) :: data
717 
718  call htable_set(this, key, data)
719 
720  end subroutine htable_i4_set
721 
723  function htable_i4_get(this, key, data) result(rcode)
724  class(htable_i4_t), intent(inout) :: this
725  integer, intent(inout) :: key
726  class(*), intent(inout) :: data
727  integer :: rcode
728 
729  rcode = htable_get(this, key, data)
730 
731  end function htable_i4_get
732 
734  pure function htable_i4_hash(this, k, c) result(hash)
735  class(htable_i4_t), intent(in) :: this
736  class(*), intent(in) :: k
737  integer, value :: c
738  integer :: hash
739  integer(kind=i8) :: tmp
740  integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
741  integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
742  integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
743  integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
744  integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
745  integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
746 
747  select type(k)
748  type is (integer)
749  tmp = int(k, i8)
750  tmp = (k + m1) + ishft(k, 12)
751  tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
752  tmp = (tmp + m3) + ishft(tmp, 5)
753  tmp = ieor((tmp + m4), ishft(tmp, 9))
754  tmp = (tmp + m5) + ishft(tmp, 3)
755  tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
756  tmp = modulo(tmp + int(c, i8), int(this%size, i8))
757  hash = int(tmp, i4)
758  class default
759  hash = -1
760  end select
761  end function htable_i4_hash
762 
764  subroutine htable_i4_remove(this, key)
765  class(htable_i4_t), intent(inout) :: this
766  integer, intent(inout) :: key
767 
768  call htable_remove(this, key)
769 
770  end subroutine htable_i4_remove
771 
773  subroutine htable_iter_i4_init(this, t)
774  class(htable_iter_i4_t), intent(inout) :: this
775  type(htable_i4_t), target, intent(inout) :: t
776 
777  this%t => t
778  this%n = -1
779 
780  end subroutine htable_iter_i4_init
781 
783  subroutine htable_iter_i4_free(this)
784  type(htable_iter_i4_t), intent(inout) :: this
785  nullify(this%t)
786  end subroutine htable_iter_i4_free
787 
789  function htable_iter_i4_value(this) result(value)
790  class(htable_iter_i4_t), target, intent(inout) :: this
791  integer, pointer :: value
792 
793  select type (hdp => this%t%t(this%n)%data)
794  type is (integer)
795  value => hdp
796  class default
797  call neko_error('Key and data of different kind (i4)')
798  end select
799 
800  end function htable_iter_i4_value
801 
803  function htable_iter_i4_key(this) result(key)
804  class(htable_iter_i4_t), target, intent(inout) :: this
805  integer, pointer :: key
806 
807  select type (kp => this%t%t(this%n)%key)
808  type is (integer)
809  key => kp
810  class default
811  call neko_error('Invalid key (i4)')
812  end select
813 
814  end function htable_iter_i4_key
815 
816  !
817  ! Integer*8 based implementation
818  !
820  subroutine htable_i8_init(this, size, data)
821  class(htable_i8_t), intent(inout) :: this
822  integer, value :: size
823  class(*), intent(inout), optional :: data
824  integer(kind=i8) :: key
825 
826  if (present(data)) then
827  call htable_init(this, size, key, data)
828  else
829  call htable_init(this, size, key)
830  end if
831 
832  end subroutine htable_i8_init
833 
835  subroutine htable_i8_set(this, key, data)
836  class(htable_i8_t), intent(inout) :: this
837  integer(kind=i8), intent(inout) :: key
838  class(*), intent(inout) :: data
839 
840  call htable_set(this, key, data)
841 
842  end subroutine htable_i8_set
843 
845  function htable_i8_get(this, key, data) result(rcode)
846  class(htable_i8_t), intent(inout) :: this
847  integer(kind=i8), intent(inout) :: key
848  class(*), intent(inout) :: data
849  integer :: rcode
850 
851  rcode = htable_get(this, key, data)
852 
853  end function htable_i8_get
854 
856  pure function htable_i8_hash(this, k, c) result(hash)
857  class(htable_i8_t), intent(in) :: this
858  class(*), intent(in) :: k
859  integer, value :: c
860  integer :: hash
861  integer(kind=i8) :: tmp
862  integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
863  integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
864  integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
865  integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
866  integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
867  integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
868 
869  select type(k)
870  type is (integer(i8))
871  tmp = (k + m1) + ishft(k, 12)
872  tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
873  tmp = (tmp + m3) + ishft(tmp, 5)
874  tmp = ieor((tmp + m4), ishft(tmp, 9))
875  tmp = (tmp + m5) + ishft(tmp, 3)
876  tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
877  hash = int(modulo(tmp, int(this%size, i8)), i4)
879  hash = int(modulo((k * 2654435761_i8) + int(c, i8), &
880  int(this%size, i8)), i4)
881  class default
882  hash = -1
883  end select
884  end function htable_i8_hash
885 
887  subroutine htable_i8_remove(this, key)
888  class(htable_i8_t), intent(inout) :: this
889  integer(kind=i8), intent(inout) :: key
890 
891  call htable_remove(this, key)
892 
893  end subroutine htable_i8_remove
894 
896  subroutine htable_iter_i8_init(this, t)
897  class(htable_iter_i8_t), intent(inout) :: this
898  type(htable_i8_t), target, intent(inout) :: t
899 
900  this%t => t
901  this%n = -1
902 
903  end subroutine htable_iter_i8_init
904 
906  subroutine htable_iter_i8_free(this)
907  type(htable_iter_i8_t), intent(inout) :: this
908  nullify(this%t)
909  end subroutine htable_iter_i8_free
910 
912  function htable_iter_i8_value(this) result(value)
913  class(htable_iter_i8_t), target, intent(inout) :: this
914  integer(kind=i8), pointer :: value
915 
916 
917  select type (hdp => this%t%t(this%n)%data)
918  type is (integer(i8))
919  value => hdp
920  class default
921  call neko_error('Key and data of different kind (i8)')
922  end select
923 
924  end function htable_iter_i8_value
925 
927  function htable_iter_i8_key(this) result(key)
928  class(htable_iter_i8_t), target, intent(inout) :: this
929  integer(kind=i8), pointer :: key
930 
931  ! We should not need this extra select block, and it works great
932  ! without it for GNU, Intel and NEC, but breaks horribly on Cray
933  ! (>11.0.x) when using high opt. levels.
934  select type(hti => this)
935  type is(htable_iter_i8_t)
936  select type (kp => hti%t%t(this%n)%key)
937  type is (integer(i8))
938  key => kp
939  class default
940  call neko_error('Invalid key (i8)')
941  end select
942  class default
943  call neko_error('Corrupt htable iter. (i8)')
944  end select
945 
946  end function htable_iter_i8_key
947 
948 
949  !
950  ! Double precision based implementation
951  !
953  subroutine htable_r8_init(this, size, data)
954  class(htable_r8_t), intent(inout) :: this
955  integer, value :: size
956  class(*), intent(inout), optional :: data
957  real(kind=dp) :: key
958 
959  if (present(data)) then
960  call htable_init(this, size, key, data)
961  else
962  call htable_init(this, size, key)
963  end if
964 
965  end subroutine htable_r8_init
966 
968  subroutine htable_r8_set(this, key, data)
969  class(htable_r8_t), intent(inout) :: this
970  real(kind=dp), intent(inout) :: key
971  class(*), intent(inout) :: data
972 
973  call htable_set(this, key, data)
974 
975  end subroutine htable_r8_set
976 
978  function htable_r8_get(this, key, data) result(rcode)
979  class(htable_r8_t), intent(inout) :: this
980  real(kind=dp), intent(inout) :: key
981  class(*), intent(inout) :: data
982  integer :: rcode
983 
984  rcode = htable_get(this, key, data)
985 
986  end function htable_r8_get
987 
989  pure function htable_r8_hash(this, k, c) result(hash)
990  class(htable_r8_t), intent(in) :: this
991  class(*), intent(in) :: k
992  integer, value :: c
993  integer :: hash
994  select type(k)
995  type is (double precision)
996  hash = modulo(floor((2d0 * abs(fraction(k)) - 1d0) * 2**16) + c, this%size)
997  class default
998  hash = -1
999  end select
1000  end function htable_r8_hash
1001 
1003  subroutine htable_r8_remove(this, key)
1004  class(htable_r8_t), intent(inout) :: this
1005  real(kind=dp), intent(inout) :: key
1006 
1007  call htable_remove(this, key)
1008 
1009  end subroutine htable_r8_remove
1010 
1011 
1013  subroutine htable_iter_r8_init(this, t)
1014  class(htable_iter_r8_t), intent(inout) :: this
1015  type(htable_r8_t), target, intent(inout) :: t
1016 
1017  this%t => t
1018  this%n = -1
1019 
1020  end subroutine htable_iter_r8_init
1021 
1023  subroutine htable_iter_r8_free(this)
1024  type(htable_iter_r8_t), intent(inout) :: this
1025  nullify(this%t)
1026  end subroutine htable_iter_r8_free
1027 
1029  function htable_iter_r8_value(this) result(value)
1030  class(htable_iter_r8_t), target, intent(inout) :: this
1031  real(kind=dp), pointer :: value
1032 
1033  select type (hdp => this%t%t(this%n)%data)
1034  type is (double precision)
1035  value => hdp
1036  class default
1037  call neko_error('Key and data of different kind (r8)')
1038  end select
1039 
1040  end function htable_iter_r8_value
1041 
1043  function htable_iter_r8_key(this) result(key)
1044  class(htable_iter_r8_t), target, intent(inout) :: this
1045  real(kind=dp), pointer :: key
1046 
1047  select type (kp => this%t%t(this%n)%key)
1048  type is (double precision)
1049  key => kp
1050  class default
1051  call neko_error('Invalid key (r8)')
1052  end select
1053 
1054  end function htable_iter_r8_key
1055 
1056  !
1057  ! Point based implementation
1058  !
1060  subroutine htable_pt_init(this, size, data)
1061  class(htable_pt_t), intent(inout) :: this
1062  integer, value :: size
1063  class(*), intent(inout), optional :: data
1064  type(point_t) :: key
1065 
1066  if (present(data)) then
1067  call htable_init(this, size, key, data)
1068  else
1069  call htable_init(this, size, key)
1070  end if
1071 
1072  end subroutine htable_pt_init
1073 
1075  subroutine htable_pt_set(this, key, data)
1076  class(htable_pt_t), intent(inout) :: this
1077  type(point_t), intent(inout) :: key
1078  class(*), intent(inout) :: data
1079 
1080  call htable_set(this, key, data)
1081 
1082  end subroutine htable_pt_set
1083 
1085  function htable_pt_get(this, key, data) result(rcode)
1086  class(htable_pt_t), intent(inout) :: this
1087  type(point_t), intent(inout) :: key
1088  class(*), intent(inout) :: data
1089  integer :: rcode
1090 
1091  rcode = htable_get(this, key, data)
1092 
1093  end function htable_pt_get
1094 
1096  pure function htable_pt_hash(this, k, c) result(hash)
1097  class(htable_pt_t), intent(in) :: this
1098  class(*), intent(in) :: k
1099  integer, value :: c
1100  integer :: hash, i
1101  integer(kind=i8) :: hash2, tmp, mult
1102  integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
1103  integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
1104  integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
1105  integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
1106  integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
1107  integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
1108 
1109  select type(k)
1110  type is (point_t)
1111  mult = 1000003
1112  hash2 = int(z'345678')
1113  do i = 1, 3
1114  tmp = transfer(k%x(i), tmp)
1115  tmp = (tmp + m1) + ishft(tmp, 12)
1116  tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1117  tmp = (tmp + m3) + ishft(tmp, 5)
1118  tmp = ieor((tmp + m4), ishft(tmp, 9))
1119  tmp = (tmp + m5) + ishft(tmp, 3)
1120  tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1121  hash2 = ieor(hash2, tmp) * mult
1122  mult = mult + 82520 + 8
1123  end do
1124  hash2 = hash2 + 97531
1125  hash2 = modulo(hash2 + int(c, i8), int(this%size,i8))
1126  hash = int(hash2, i4)
1127  class default
1128  hash = -1
1129  end select
1130 
1131  end function htable_pt_hash
1132 
1134  subroutine htable_pt_remove(this, key)
1135  class(htable_pt_t), intent(inout) :: this
1136  type(point_t), intent(inout) :: key
1137 
1138  call htable_remove(this, key)
1139 
1140  end subroutine htable_pt_remove
1141 
1142 
1144  subroutine htable_iter_pt_init(this, t)
1145  class(htable_iter_pt_t), intent(inout) :: this
1146  type(htable_pt_t), target, intent(inout) :: t
1147 
1148  this%t => t
1149  this%n = -1
1150 
1151  end subroutine htable_iter_pt_init
1152 
1154  subroutine htable_iter_pt_free(this)
1155  type(htable_iter_pt_t), intent(inout) :: this
1156  nullify(this%t)
1157  end subroutine htable_iter_pt_free
1158 
1160  function htable_iter_pt_value(this) result(value)
1161  class(htable_iter_pt_t), target, intent(inout) :: this
1162  type(point_t), pointer :: value
1163 
1164  select type (hdp => this%t%t(this%n)%data)
1165  type is (point_t)
1166  value => hdp
1167  class default
1168  call neko_error('Key and data of different kind (pt)')
1169  end select
1170 
1171  end function htable_iter_pt_value
1172 
1174  function htable_iter_pt_key(this) result(key)
1175  class(htable_iter_pt_t), target, intent(inout) :: this
1176  type(point_t), pointer :: key
1177 
1178  select type (kp => this%t%t(this%n)%key)
1179  type is (point_t)
1180  key => kp
1181  class default
1182  call neko_error('Invalid key (pt)')
1183  end select
1184 
1185  end function htable_iter_pt_key
1186 
1187  !
1188  ! Integer 2-tuple based implementation
1189  !
1191  subroutine htable_i4t2_init(this, size, data)
1192  class(htable_i4t2_t), intent(inout) :: this
1193  integer, value :: size
1194  class(*), intent(inout), optional :: data
1195  type(tuple_i4_t) :: key
1196 
1197  if (present(data)) then
1198  call htable_init(this, size, key, data)
1199  else
1200  call htable_init(this, size, key)
1201  end if
1202 
1203  end subroutine htable_i4t2_init
1204 
1206  subroutine htable_i4t2_set(this, key, data)
1207  class(htable_i4t2_t), intent(inout) :: this
1208  type(tuple_i4_t), intent(inout) :: key
1209  class(*), intent(inout) :: data
1210 
1211  call htable_set(this, key, data)
1212 
1213  end subroutine htable_i4t2_set
1214 
1216  function htable_i4t2_get(this, key, data) result(rcode)
1217  class(htable_i4t2_t), intent(inout) :: this
1218  type(tuple_i4_t), intent(inout) :: key
1219  class(*), intent(inout) :: data
1220  integer :: rcode
1221 
1222  rcode = htable_get(this, key, data)
1223 
1224  end function htable_i4t2_get
1225 
1227  pure function htable_i4t2_hash(this, k, c) result(hash)
1228  class(htable_i4t2_t), intent(in) :: this
1229  class(*), intent(in) :: k
1230  integer, value :: c
1231  integer :: i, hash
1232  integer(kind=i8) :: tmp, hash2, mult
1233  integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
1234  integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
1235  integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
1236  integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
1237  integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
1238  integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
1239 
1240  select type(k)
1241  type is (tuple_i4_t)
1242  mult = int(1000003, i8)
1243  hash2 = int(z'345678', i8)
1244  do i = 1, 2
1245  tmp = int(k%x(i), i8)
1246  tmp = (tmp + m1) + ishft(tmp, 12)
1247  tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1248  tmp = (tmp + m3) + ishft(tmp, 5)
1249  tmp = ieor((tmp + m4), ishft(tmp, 9))
1250  tmp = (tmp + m5) + ishft(tmp, 3)
1251  tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1252  hash2 = ieor(hash2, tmp) * mult
1253  mult = mult + 82520_i8 + 4_i8
1254  end do
1255  hash2 = hash2 + 97531_i8
1256  hash2 = modulo(hash2 + int(c, i8), int(this%size, i8))
1257  hash = int(hash2, i4)
1258  class default
1259  hash = -1
1260  end select
1261  end function htable_i4t2_hash
1262 
1264  subroutine htable_i4t2_remove(this, key)
1265  class(htable_i4t2_t), intent(inout) :: this
1266  type(tuple_i4_t), intent(inout) :: key
1267 
1268  call htable_remove(this, key)
1269 
1270  end subroutine htable_i4t2_remove
1271 
1273  subroutine htable_iter_i4t2_init(this, t)
1274  class(htable_iter_i4t2_t), intent(inout) :: this
1275  type(htable_i4t2_t), target, intent(inout) :: t
1276 
1277  this%t => t
1278  this%n = -1
1279 
1280  end subroutine htable_iter_i4t2_init
1281 
1283  subroutine htable_iter_i4t2_free(this)
1284  type(htable_iter_i4t2_t), intent(inout) :: this
1285  nullify(this%t)
1286  end subroutine htable_iter_i4t2_free
1287 
1289  function htable_iter_i4t2_value(this) result(value)
1290  class(htable_iter_i4t2_t), intent(inout) :: this
1291  type(tuple_i4_t), pointer :: value
1292 
1293  select type (hdp => this%t%t(this%n)%data)
1294  type is (tuple_i4_t)
1295  value => hdp
1296  class default
1297  call neko_error('Key and data of different kind (i4t2)')
1298  end select
1299 
1300  end function htable_iter_i4t2_value
1301 
1303  function htable_iter_i4t2_key(this) result(key)
1304  class(htable_iter_i4t2_t), intent(inout) :: this
1305  type(tuple_i4_t), pointer :: key
1306 
1307  select type (kp => this%t%t(this%n)%key)
1308  type is (tuple_i4_t)
1309  key => kp
1310  class default
1311  call neko_error('Invalid key (i4t2)')
1312  end select
1313 
1314  end function htable_iter_i4t2_key
1315 
1316  !
1317  ! Integer 4-tuple based implementation
1318  !
1320  subroutine htable_i4t4_init(this, size, data)
1321  class(htable_i4t4_t), intent(inout) :: this
1322  integer, value :: size
1323  class(*), intent(inout), optional :: data
1324  type(tuple4_i4_t) :: key
1325 
1326  if (present(data)) then
1327  call htable_init(this, size, key, data)
1328  else
1329  call htable_init(this, size, key)
1330  end if
1331 
1332  end subroutine htable_i4t4_init
1333 
1335  subroutine htable_i4t4_set(this, key, data)
1336  class(htable_i4t4_t), intent(inout) :: this
1337  type(tuple4_i4_t), intent(inout) :: key
1338  class(*), intent(inout) :: data
1339 
1340  call htable_set(this, key, data)
1341 
1342  end subroutine htable_i4t4_set
1343 
1345  function htable_i4t4_get(this, key, data) result(rcode)
1346  class(htable_i4t4_t), intent(inout) :: this
1347  type(tuple4_i4_t), intent(inout) :: key
1348  class(*), intent(inout) :: data
1349  integer :: rcode
1350 
1351  rcode = htable_get(this, key, data)
1352 
1353  end function htable_i4t4_get
1354 
1356  pure function htable_i4t4_hash(this, k, c) result(hash)
1357  class(htable_i4t4_t), intent(in) :: this
1358  class(*), intent(in) :: k
1359  integer, value :: c
1360  integer :: i, hash
1361  integer(kind=i8) :: tmp, hash2, mult
1362  integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
1363  integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
1364  integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
1365  integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
1366  integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
1367  integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
1368 
1369  select type(k)
1370  type is (tuple4_i4_t)
1371  mult = int(1000003, i8)
1372  hash2 = int(z'345678', i8)
1373  do i = 1, 4
1374  tmp = int(k%x(i), i8)
1375  tmp = (tmp + m1) + ishft(tmp, 12)
1376  tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1377  tmp = (tmp + m3) + ishft(tmp, 5)
1378  tmp = ieor((tmp + m4), ishft(tmp, 9))
1379  tmp = (tmp + m5) + ishft(tmp, 3)
1380  tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1381  hash2 = ieor(hash2, tmp) * mult
1382  mult = mult + 82520_i8 + 8_i8
1383  end do
1384  hash2 = hash2 + 97531_i8
1385  hash2 = modulo(hash2 + int(c, i8), int(this%size, i8))
1386  hash = int(hash2, i4)
1387  class default
1388  hash = -1
1389  end select
1390  end function htable_i4t4_hash
1391 
1393  subroutine htable_i4t4_remove(this, key)
1394  class(htable_i4t4_t), intent(inout) :: this
1395  type(tuple4_i4_t), intent(inout) :: key
1396 
1397  call htable_remove(this, key)
1398 
1399  end subroutine htable_i4t4_remove
1400 
1402  subroutine htable_iter_i4t4_init(this, t)
1403  class(htable_iter_i4t4_t), intent(inout) :: this
1404  type(htable_i4t4_t), target, intent(inout) :: t
1405 
1406  this%t => t
1407  this%n = -1
1408 
1409  end subroutine htable_iter_i4t4_init
1410 
1412  subroutine htable_iter_i4t4_free(this)
1413  type(htable_iter_i4t4_t), intent(inout) :: this
1414  nullify(this%t)
1415  end subroutine htable_iter_i4t4_free
1416 
1418  function htable_iter_i4t4_value(this) result(value)
1419  class(htable_iter_i4t4_t), target, intent(inout) :: this
1420  type(tuple4_i4_t), pointer :: value
1421 
1422  select type (hdp => this%t%t(this%n)%data)
1423  type is (tuple4_i4_t)
1424  value => hdp
1425  class default
1426  call neko_error('Key and data of different kind (i4t4)')
1427  end select
1428 
1429  end function htable_iter_i4t4_value
1430 
1432  function htable_iter_i4t4_key(this) result(key)
1433  class(htable_iter_i4t4_t), target, intent(inout) :: this
1434  type(tuple4_i4_t), pointer :: key
1435 
1436  ! We should not need this extra select block, and it works great
1437  ! without it for GNU, Intel and NEC, but breaks horribly on Cray
1438  ! (>11.0.x) when using high opt. levels.
1439  select type(hti => this)
1440  type is(htable_iter_i4t4_t)
1441  select type (kp => hti%t%t(this%n)%key)
1442  type is (tuple4_i4_t)
1443  key => kp
1444  class default
1445  call neko_error('Invalid key (i4t4)')
1446  end select
1447  class default
1448  call neko_error('Corrupt htable iter. (i4t4)')
1449  end select
1450 
1451  end function htable_iter_i4t4_key
1452 
1453  !
1454  ! C pointer based implementation
1455  !
1457  subroutine htable_cptr_init(this, size, data)
1458  class(htable_cptr_t), intent(inout) :: this
1459  integer, value :: size
1460  class(*), intent(inout), optional :: data
1461  type(h_cptr_t) :: key
1462 
1463  if (present(data)) then
1464  call htable_init(this, size, key, data)
1465  else
1466  call htable_init(this, size, key)
1467  end if
1468 
1469  end subroutine htable_cptr_init
1470 
1472  subroutine htable_cptr_set(this, key, data)
1473  class(htable_cptr_t), target, intent(inout) :: this
1474  type(h_cptr_t), intent(inout) :: key
1475  class(*), intent(inout) :: data
1476 
1477  call htable_set(this, key, data)
1478 
1479  end subroutine htable_cptr_set
1480 
1482  function htable_cptr_get(this, key, data) result(rcode)
1483  class(htable_cptr_t), target, intent(inout) :: this
1484  type(h_cptr_t), intent(inout) :: key
1485  class(*), intent(inout) :: data
1486  integer :: rcode
1487 
1488  rcode = htable_get(this, key, data)
1489 
1490  end function htable_cptr_get
1491 
1493  pure function htable_cptr_hash(this, k, c) result(hash)
1494  class(htable_cptr_t), intent(in) :: this
1495  class(*), intent(in) :: k
1496  integer, value :: c
1497  integer :: hash
1498  integer(kind=i8) :: k_int
1499 
1500  select type(k)
1501  type is (h_cptr_t)
1502  k_int = transfer(k%ptr, k_int)
1503  hash = int(modulo(k_int * 2654435761_i8 + int(c, i8),&
1504  int(this%size, i8)), i4)
1505  class default
1506  hash = -1
1507  end select
1508  end function htable_cptr_hash
1509 
1511  subroutine htable_cptr_remove(this, key)
1512  class(htable_cptr_t), target, intent(inout) :: this
1513  type(h_cptr_t), intent(inout) :: key
1514 
1515  call htable_remove(this, key)
1516 
1517  end subroutine htable_cptr_remove
1518 
1520  subroutine htable_iter_cptr_init(this, t)
1521  class(htable_iter_cptr_t), intent(inout) :: this
1522  type(htable_cptr_t), target, intent(inout) :: t
1523 
1524  this%t => t
1525  this%n = -1
1526 
1527  end subroutine htable_iter_cptr_init
1528 
1530  subroutine htable_iter_cptr_free(this)
1531  type(htable_iter_cptr_t), intent(inout) :: this
1532  nullify(this%t)
1533  end subroutine htable_iter_cptr_free
1534 
1536  function htable_iter_cptr_value(this) result(value)
1537  class(htable_iter_cptr_t), target, intent(inout) :: this
1538  class(*), pointer :: hdp
1539  type(h_cptr_t), pointer :: value
1540 
1541  hdp => this%t%t(this%n)%data
1542  select type (hdp)
1543  type is (h_cptr_t)
1544  value => hdp
1545  class default
1546  call neko_error('Key and data of different kind (cptr)')
1547  end select
1548 
1549  end function htable_iter_cptr_value
1550 
1552  function htable_iter_cptr_key(this) result(key)
1553  class(htable_iter_cptr_t), target, intent(inout) :: this
1554  class(*), pointer :: kp
1555  type(h_cptr_t), pointer :: key
1556 
1557  kp => this%t%t(this%n)%key
1558  select type (kp)
1559  type is (h_cptr_t)
1560  key => kp
1561  class default
1562  call neko_error('Invalid key (cptr)')
1563  end select
1564 
1565  end function htable_iter_cptr_key
1566 
1567 end module htable
Implements a hash table ADT.
Definition: htable.f90:36
subroutine htable_i4t4_init(this, size, data)
Initialize an integer 4-tuple hash table.
Definition: htable.f90:1321
subroutine htable_iter_r8_init(this, t)
Initialize a double precision based hash table iterator.
Definition: htable.f90:1014
subroutine htable_clear(this)
Clear all entries in a hash table.
Definition: htable.f90:291
subroutine htable_pt_init(this, size, data)
Initialize a point based hash table.
Definition: htable.f90:1061
type(tuple_i4_t) function, pointer htable_iter_i4t2_key(this)
Return the current key of integer based 2-tuple hash table iterator.
Definition: htable.f90:1304
subroutine htable_iter_i8_free(this)
Destroy an integer*8 based hash table iterator.
Definition: htable.f90:907
subroutine htable_i4_set(this, key, data)
Insert an integer into the hash table.
Definition: htable.f90:714
type(tuple4_i4_t) function, pointer htable_iter_i4t4_value(this)
Return the current value of integer based 4-tuple hash table iterator.
Definition: htable.f90:1419
integer function, pointer htable_iter_i4_value(this)
Return the current value of the integer based hash table iterator.
Definition: htable.f90:790
subroutine htable_r8_init(this, size, data)
Initialize a double precision based hash table.
Definition: htable.f90:954
integer(kind=i8) function, pointer htable_iter_i8_key(this)
Return the current key of the integer*8 based hash table iterator.
Definition: htable.f90:928
type(point_t) function, pointer htable_iter_pt_key(this)
Return the current key of the point based hash table iterator.
Definition: htable.f90:1175
pure integer function htable_r8_hash(this, k, c)
Hash function for a double precision based hash table.
Definition: htable.f90:990
subroutine htable_cptr_init(this, size, data)
Initialize a C pointer based hash table.
Definition: htable.f90:1458
pure integer function htable_i4_hash(this, k, c)
Hash function for an integer based hash table.
Definition: htable.f90:735
subroutine htable_iter_cptr_free(this)
Destroy a C pointer based hash table iterator.
Definition: htable.f90:1531
subroutine htable_iter_pt_free(this)
Destroy a point based hash table iterator.
Definition: htable.f90:1155
subroutine htable_i4t4_set(this, key, data)
Insert an integer 4-tuple into the hash table.
Definition: htable.f90:1336
subroutine htable_i8_init(this, size, data)
Initialize an integer*8 based hash table.
Definition: htable.f90:821
subroutine htable_pt_remove(this, key)
Remove a point with key key from the hash table.
Definition: htable.f90:1135
subroutine htable_cptr_remove(this, key)
Remove a C pointer with key key from the hash table.
Definition: htable.f90:1512
subroutine htable_free(this)
Destroy a hash table.
Definition: htable.f90:273
subroutine htable_iter_data(this, data)
Return the data at the current iterator position.
Definition: htable.f90:650
pure integer function htable_size(this)
Return total size of htable.
Definition: htable.f90:311
subroutine htable_get_data(this, idx, data)
Return data at idx in value.
Definition: htable.f90:492
integer function htable_r8_get(this, key, data)
Retrive a double precision float with key key from the hash table.
Definition: htable.f90:979
pure integer function htable_i8_hash(this, k, c)
Hash function for an integer*8 based hash table.
Definition: htable.f90:857
subroutine htable_i4t4_remove(this, key)
Remove an integer 4-tuple with key key from the hash table.
Definition: htable.f90:1394
integer function htable_get(this, key, data)
Retrieve data associated with key into the hash table.
Definition: htable.f90:386
integer function htable_i8_get(this, key, data)
Retrive an integer*8 with key key from the hash table.
Definition: htable.f90:846
integer function htable_pt_get(this, key, data)
Retrive a point with key key from the hash table.
Definition: htable.f90:1086
subroutine htable_remove(this, key)
Remove a key from the hash table.
Definition: htable.f90:419
subroutine htable_set_data(this, idx, data)
Set data at idx to value.
Definition: htable.f90:446
real(kind=dp) function, pointer htable_iter_r8_key(this)
Return the current key of the double precision based hash table iterator.
Definition: htable.f90:1044
subroutine htable_iter_pt_init(this, t)
Initialize a point based hash table iterator.
Definition: htable.f90:1145
integer function htable_i4_get(this, key, data)
Retrive an integer with key key from the hash table.
Definition: htable.f90:724
type(h_cptr_t) function, pointer htable_iter_cptr_value(this)
Return the current value of C pointer based hash table iterator.
Definition: htable.f90:1537
type(tuple_i4_t) function, pointer htable_iter_i4t2_value(this)
Return the current value of integer based 2-tuple hash table iterator.
Definition: htable.f90:1290
logical function htable_iter_next(this)
Advance the iterator to the next valid table entry.
Definition: htable.f90:626
integer function htable_cptr_get(this, key, data)
Retrive a C pointer with key key from the hash table.
Definition: htable.f90:1483
subroutine htable_i8_set(this, key, data)
Insert an integer*8 into the hash table.
Definition: htable.f90:836
subroutine htable_r8_remove(this, key)
Remove a double precision key key from the hash table.
Definition: htable.f90:1004
subroutine htable_iter_i4t2_free(this)
Destroy an integer 2-tuple based hash table iterator.
Definition: htable.f90:1284
subroutine htable_r8_set(this, key, data)
Insert a double precision key (with data) into the hash table.
Definition: htable.f90:969
type(point_t) function, pointer htable_iter_pt_value(this)
Return the current value of the point based hash table iterator.
Definition: htable.f90:1161
integer function htable_i4t4_get(this, key, data)
Retrive an integer 4-tuple with key key from the hash table.
Definition: htable.f90:1346
subroutine htable_i4t2_set(this, key, data)
Insert an integer 2-tuple into the hash table.
Definition: htable.f90:1207
pure integer function htable_num_entries(this)
Return number of entries in the table.
Definition: htable.f90:304
type(tuple4_i4_t) function, pointer htable_iter_i4t4_key(this)
Return the current key of integer based 4-tuple hash table iterator.
Definition: htable.f90:1433
recursive subroutine htable_set(this, key, data)
Insert tuple (key, value) into the hash table.
Definition: htable.f90:319
pure logical function htable_eq_key(this, idx, key)
Compare key at idx to key.
Definition: htable.f90:536
subroutine htable_i4t2_remove(this, key)
Remove an integer 2-tuple with key key from the hash table.
Definition: htable.f90:1265
subroutine htable_set_key(this, idx, key)
Set key at idx to key.
Definition: htable.f90:580
subroutine htable_iter_i8_init(this, t)
Initialize an integer*8 based hash table iterator.
Definition: htable.f90:897
pure integer function htable_i4t4_hash(this, k, c)
Hash function for an integer 4-tuple hash table.
Definition: htable.f90:1357
pure integer function htable_pt_hash(this, k, c)
Hash function for a point based hash table.
Definition: htable.f90:1097
integer function, pointer htable_iter_i4_key(this)
Return the current key of the integer based hash table iterator.
Definition: htable.f90:804
subroutine htable_iter_i4_init(this, t)
Initialize an integer based hash table iterator.
Definition: htable.f90:774
subroutine htable_init(this, size, key, data)
Initialize a hash table of type data.
Definition: htable.f90:239
subroutine htable_i4t2_init(this, size, data)
Initialize an integer 2-tuple hash table.
Definition: htable.f90:1192
subroutine htable_cptr_set(this, key, data)
Insert a C pointer into the hash table.
Definition: htable.f90:1473
subroutine htable_iter_i4t4_free(this)
Destroy an integer 4-tuple based hash table iterator.
Definition: htable.f90:1413
subroutine htable_i4_remove(this, key)
Remove an integer with key key from the hash table.
Definition: htable.f90:765
subroutine htable_iter_cptr_init(this, t)
Initialize a C pointer based hash table iterator.
Definition: htable.f90:1521
integer(kind=i8) function, pointer htable_iter_i8_value(this)
Return the current value of the integer*8 based hash table iterator.
Definition: htable.f90:913
integer function htable_i4t2_get(this, key, data)
Retrive an integer 2-tuple with key key from the hash table.
Definition: htable.f90:1217
subroutine htable_iter_i4t4_init(this, t)
Initialize an integer 4-tuple based hash table iterator.
Definition: htable.f90:1403
subroutine htable_i8_remove(this, key)
Remove an integer*8 with key key from the hash table.
Definition: htable.f90:888
subroutine htable_i4_init(this, size, data)
Initialize an integer based hash table.
Definition: htable.f90:699
pure integer function htable_cptr_hash(this, k, c)
Hash function for an integer 4-tuple hash table.
Definition: htable.f90:1494
subroutine htable_pt_set(this, key, data)
Insert a point key (with data) into the hash table.
Definition: htable.f90:1076
subroutine htable_iter_reset(this)
Reset an iterator.
Definition: htable.f90:641
subroutine htable_iter_i4_free(this)
Destroy an integer based hash table iterator.
Definition: htable.f90:784
type(h_cptr_t) function, pointer htable_iter_cptr_key(this)
Return the current key of a C pointer based hash table iterator.
Definition: htable.f90:1553
subroutine htable_iter_r8_free(this)
Destroy a double precision based hash table iterator.
Definition: htable.f90:1024
pure integer function htable_i4t2_hash(this, k, c)
Hash function for an integer 2-tuple hash table.
Definition: htable.f90:1228
subroutine htable_iter_i4t2_init(this, t)
Initialize an integer 2-tuple based hash table iterator.
Definition: htable.f90:1274
real(kind=dp) function, pointer htable_iter_r8_value(this)
Return the current value of the double precision based hash table iterator.
Definition: htable.f90:1030
Definition: math.f90:60
real(kind=rp), parameter, public neko_m_ln2
Definition: math.f90:70
integer, parameter, public i8
Definition: num_types.f90:7
integer, parameter, public i4
Definition: num_types.f90:6
integer, parameter, public dp
Definition: num_types.f90:9
Implements a point.
Definition: point.f90:35
Implements a n-tuple.
Definition: tuple.f90:34
Utilities.
Definition: utils.f90:35
Hash table entry, tuple (key, data)
Definition: htable.f90:47
C pointer based hash table.
Definition: htable.f90:142
Integer based hash table.
Definition: htable.f90:82
Integer 2-tuple based hash table.
Definition: htable.f90:122
Integer 4-tuple based hash table.
Definition: htable.f90:132
Integer*8 based hash table.
Definition: htable.f90:92
Iterator for a C pointer based hash table.
Definition: htable.f90:220
Iterator for an integer based hash table.
Definition: htable.f90:166
Iterator for an integer based 2-tuple hash table.
Definition: htable.f90:202
Iterator for an integer based 4-tuple hash table.
Definition: htable.f90:211
Iterator for an integer*8 based hash table.
Definition: htable.f90:175
Iterator for a point based hash table.
Definition: htable.f90:193
Iterator for a double precision based hash table.
Definition: htable.f90:184
Base type for a hash table iterator.
Definition: htable.f90:156
Point based hash table.
Definition: htable.f90:112
Double precision based hash table.
Definition: htable.f90:102
Base type for a hash table.
Definition: htable.f90:55
A point in with coordinates .
Definition: point.f90:43
Integer based 4-tuple.
Definition: tuple.f90:69
Integer based 2-tuple.
Definition: tuple.f90:51
Base type for an n-tuple.
Definition: tuple.f90:41