co_reduce_s.f90 Source File


This file depends on

sourcefile~~co_reduce_s.f90~~EfferentGraph sourcefile~co_reduce_s.f90 co_reduce_s.f90 sourcefile~prif_private_s.f90 prif_private_s.f90 sourcefile~co_reduce_s.f90->sourcefile~prif_private_s.f90 sourcefile~prif.f90 prif.F90 sourcefile~prif_private_s.f90->sourcefile~prif.f90

Contents

Source Code


Source Code

! Copyright (c), The Regents of the University of California
! Terms of use are as specified in LICENSE.txt
submodule(prif:prif_private_s) co_reduce_s
  use iso_c_binding, only : &
    c_loc, c_funloc, c_associated, c_f_pointer, c_f_procpointer, c_char, c_double, &
    c_float, c_int32_t

  implicit none

  character(kind=c_char,len=5), parameter :: dummy = "     "

  abstract interface

    pure function c_int32_t_operation(lhs, rhs) result(lhs_op_rhs)
      import c_int32_t
      implicit none
      integer(c_int32_t), intent(in) :: lhs, rhs
      integer(c_int32_t) lhs_op_rhs
    end function

    pure function c_int64_t_operation(lhs, rhs) result(lhs_op_rhs)
      import c_int64_t
      implicit none
      integer(c_int64_t), intent(in) :: lhs, rhs
      integer(c_int64_t) lhs_op_rhs
    end function

    pure function c_float_operation(lhs, rhs) result(lhs_op_rhs)
      import c_float
      implicit none
      real(c_float), intent(in) :: lhs, rhs
      real(c_float) lhs_op_rhs
    end function

    pure function c_double_operation(lhs, rhs) result(lhs_op_rhs)
      import c_double
      implicit none
      real(c_double), intent(in) :: lhs, rhs
      real(c_double) lhs_op_rhs
    end function

    pure function c_bool_operation(lhs, rhs) result(lhs_op_rhs)
      import c_bool
      implicit none
      logical(c_bool), intent(in) :: lhs, rhs
      logical(c_bool) lhs_op_rhs
    end function

    function c_char_operation(lhs, rhs) result(lhs_op_rhs)
      import c_char
      implicit none
      character(kind=c_char,len=*), intent(in) :: lhs, rhs
      character(kind=c_char,len=len(lhs)) :: lhs_op_rhs
    end function

    pure function c_float_complex_operation(lhs, rhs) result(lhs_op_rhs)
      import c_float
      implicit none
      complex(c_float), intent(in) :: lhs, rhs
      complex(c_float) lhs_op_rhs
    end function

    pure function c_double_complex_operation(lhs, rhs) result(lhs_op_rhs)
      import c_double
      implicit none
      complex(c_double), intent(in) :: lhs, rhs
      complex(c_double) lhs_op_rhs
    end function

  end interface

contains

  module procedure prif_co_reduce

    procedure(c_int32_t_operation), pointer :: int32_op => null()
    procedure(c_int64_t_operation), pointer :: int64_op => null()
    procedure(c_float_operation), pointer :: float_op => null()
    procedure(c_double_operation), pointer :: double_op => null()
    procedure(c_bool_operation), pointer :: bool_op => null()
    procedure(c_char_operation), pointer :: char_op => null()
    procedure(c_float_complex_operation), pointer :: float_complex_op => null()
    procedure(c_double_complex_operation), pointer :: double_complex_op => null()

    if (present(stat)) stat=0
    call assert(c_associated(operation), "caf_co_reduce: c_associated(operation)")

    if (caf_same_cfi_type(a, 0)) then
      call c_f_procpointer(operation, int32_op)
      call caf_co_reduce(a, optional_value(result_image), &
        int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_int32_t), c_null_ptr, current_team%info%gex_team)
    else if (caf_same_cfi_type(a, 0_c_int64_t)) then
      call c_f_procpointer(operation, int64_op)
      call caf_co_reduce(a, optional_value(result_image), &
        int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_int64_t), c_null_ptr, current_team%info%gex_team)
    else if (caf_same_cfi_type(a, 1._c_double)) then
      call c_f_procpointer(operation, double_op)
      call caf_co_reduce(a, optional_value(result_image), &
        int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_double), c_null_ptr, current_team%info%gex_team)
    else if (caf_same_cfi_type(a, 1._c_float)) then
      call c_f_procpointer(operation, float_op)
      call caf_co_reduce(a, optional_value(result_image), &
        int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_float), c_null_ptr, current_team%info%gex_team)
    else if (caf_same_cfi_type(a, .true._c_bool)) then
      call c_f_procpointer(operation, bool_op)
      call caf_co_reduce(a, optional_value(result_image), &
        int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_bool), c_null_ptr, current_team%info%gex_team)
    else if (caf_is_f_string(a)) then
      block
        integer(c_size_t), target :: len_a
        len_a = caf_elem_len(a)
        call c_f_procpointer(operation, char_op)
        call caf_co_reduce(a, optional_value(result_image), &
          int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_char), c_loc(len_a), current_team%info%gex_team)
      end block
    else if (caf_same_cfi_type(a, (0._c_float, 0._c_float))) then
      call c_f_procpointer(operation, float_complex_op)
      call caf_co_reduce(a, optional_value(result_image), &
        int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_float_complex), c_null_ptr, current_team%info%gex_team)
    else if (caf_same_cfi_type(a, (0._c_double, 0._c_double))) then
      call c_f_procpointer(operation, double_complex_op)
      call caf_co_reduce(a, optional_value(result_image), &
        int(product(shape(a)), c_size_t), c_funloc(Coll_ReduceSub_c_double_complex), c_null_ptr, current_team%info%gex_team)
    else
      call prif_error_stop(.false._c_bool, stop_code_char="caf_co_reduce: unsupported type")
    end if

  contains

    subroutine Coll_ReduceSub_c_int32_t(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data
      integer(c_int32_t), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
      integer(c_size_t) i

      call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_int32_t: operands associated")

      call c_f_pointer(arg1, lhs, [count])
      call c_f_pointer(arg2_and_out, rhs_and_result, [count])

      do concurrent(i=1:count)
        rhs_and_result(i) = int32_op(lhs(i), rhs_and_result(i))
      end do
    end subroutine

    subroutine Coll_ReduceSub_c_int64_t(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data
      integer(c_int64_t), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
      integer(c_size_t) i

      call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_int64_t: operands associated")

      call c_f_pointer(arg1, lhs, [count])
      call c_f_pointer(arg2_and_out, rhs_and_result, [count])

      do concurrent(i=1:count)
        rhs_and_result(i) = int64_op(lhs(i), rhs_and_result(i))
      end do
    end subroutine

    subroutine Coll_ReduceSub_c_double(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data
      real(c_double), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
      integer(c_size_t) i

      call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_double: operands associated")

      call c_f_pointer(arg1, lhs, [count])
      call c_f_pointer(arg2_and_out, rhs_and_result, [count])

      do concurrent(i=1:count)
        rhs_and_result(i) = double_op(lhs(i), rhs_and_result(i))
      end do
    end subroutine

    subroutine Coll_ReduceSub_c_float(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data
      real(c_float), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
      integer(c_size_t) i

      call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_float: operands associated")

      call c_f_pointer(arg1, lhs, [count])
      call c_f_pointer(arg2_and_out, rhs_and_result, [count])

      do concurrent(i=1:count)
        rhs_and_result(i) = float_op(lhs(i), rhs_and_result(i))
      end do
    end subroutine

    subroutine Coll_ReduceSub_c_double_complex(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data
      complex(c_double), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
      integer(c_size_t) i

      call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_dobule_complex: operands associated")

      call c_f_pointer(arg1, lhs, [count])
      call c_f_pointer(arg2_and_out, rhs_and_result, [count])

      do concurrent(i=1:count)
        rhs_and_result(i) = double_complex_op(lhs(i), rhs_and_result(i))
      end do
    end subroutine

    subroutine Coll_ReduceSub_c_float_complex(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data
      complex(c_float), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
      integer(c_size_t) i

      call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_float_complex: operands associated")

      call c_f_pointer(arg1, lhs, [count])
      call c_f_pointer(arg2_and_out, rhs_and_result, [count])

      do concurrent(i=1:count)
        rhs_and_result(i) = float_complex_op(lhs(i), rhs_and_result(i))
      end do
    end subroutine

    subroutine Coll_ReduceSub_c_bool(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data
      logical(c_bool), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()
      integer(c_size_t) i

      call assert(all([c_associated(arg1), c_associated(arg2_and_out)]), "Coll_ReduceSub_c_bool: operands associated")

      call c_f_pointer(arg1, lhs, [count])
      call c_f_pointer(arg2_and_out, rhs_and_result, [count])

      do concurrent(i=1:count)
        rhs_and_result(i) = bool_op(lhs(i), rhs_and_result(i))
      end do
    end subroutine

    subroutine Coll_ReduceSub_c_char(arg1, arg2_and_out, count, cdata) bind(C)
      type(c_ptr), value :: arg1         !! "Left" operands
      type(c_ptr), value :: arg2_and_out !! "Right" operands and result
      integer(c_size_t), value :: count  !! Operand count
      type(c_ptr), value ::  cdata       !! Client data

      integer(c_int), pointer :: arglen=>null()

      associate(c_associated_args => [c_associated(arg1), c_associated(arg2_and_out), c_associated(cdata)])
        call assert(all(c_associated_args), "Coll_ReduceSub_c_char: all(c_associated_args)")
      end associate

      call c_f_pointer(cdata, arglen)
      block
        character(kind=c_char, len=arglen), pointer :: lhs(:)=>null(), rhs_and_result(:)=>null()

        call c_f_pointer(arg1, lhs, [count])
        call c_f_pointer(arg2_and_out, rhs_and_result, [count])

        block
          integer(c_size_t) i

          do i=1, count
            rhs_and_result(i) = char_op(lhs(i), rhs_and_result(i))
          end do
        end block
      end block

    end subroutine

  end procedure

end submodule co_reduce_s