Commit 4a10ec64 authored by Cianciosa, Mark's avatar Cianciosa, Mark
Browse files

Add fortran binding for converge items.

parent 0b962a44
Loading
Loading
Loading
Loading
+196 −0
Original line number Diff line number Diff line
@@ -74,6 +74,9 @@
         PROCEDURE :: get_max_concurrency => graph_context_get_max_concurrency
         PROCEDURE :: set_device_number => graph_context_set_device_number
         PROCEDURE :: add_pre_item => graph_context_add_pre_item
         PROCEDURE :: add_item => graph_context_add_item
         PROCEDURE :: add_converge_item => graph_context_add_converge_item
         PROCEDURE :: df => graph_context_df
      END TYPE

!*******************************************************************************
@@ -842,6 +845,96 @@
         INTEGER(C_LONG), VALUE               :: num_particles
         END SUBROUTINE

!-------------------------------------------------------------------------------
!>  @brief Add workflow item.
!>
!>  @param[in] c             The graph C context.
!>  @param[in] inputs        Array of input nodes.
!>  @param[in] num_inputs    Number of inputs.
!>  @param[in] outputs       Array of output nodes.
!>  @param[in] num_outputs   Number of outputs.
!>  @param[in] map_inputs    Array of map input nodes.
!>  @param[in] map_outputs   Array of map output nodes.
!>  @param[in] num_maps      Number of maps.
!>  @param[in] random_state  Optional random state, can be NULL if not used.
!>  @param[in] name          Name for the kernel.
!>  @param[in] num_particles Number of elements to operate on.
!-------------------------------------------------------------------------------
         SUBROUTINE graph_add_item(c, inputs, num_inputs,                      &
                                   outputs, num_outputs,                       &
                                   map_inputs, map_outputs, num_maps,          &
                                   random_state, name, num_particles)          &
         BIND(C, NAME='graph_add_item')
         USE, INTRINSIC :: ISO_C_BINDING
         IMPLICIT NONE
         TYPE(C_PTR), VALUE                   :: c
         INTEGER(C_INTPTR_T), VALUE           :: inputs
         INTEGER(C_LONG), VALUE               :: num_inputs
         INTEGER(C_INTPTR_T), VALUE           :: outputs
         INTEGER(C_LONG), VALUE               :: num_outputs
         INTEGER(C_INTPTR_T), VALUE           :: map_inputs
         INTEGER(C_INTPTR_T), VALUE           :: map_outputs
         INTEGER(C_LONG), VALUE               :: num_maps
         TYPE(C_PTR), VALUE                   :: random_state
         CHARACTER(kind=C_CHAR), DIMENSION(*) :: name
         INTEGER(C_LONG), VALUE               :: num_particles
         END SUBROUTINE

!-------------------------------------------------------------------------------
!>  @brief Add workflow converge item.
!>
!>  @param[in] c             The graph C context.
!>  @param[in] inputs        Array of input nodes.
!>  @param[in] num_inputs    Number of inputs.
!>  @param[in] outputs       Array of output nodes.
!>  @param[in] num_outputs   Number of outputs.
!>  @param[in] map_inputs    Array of map input nodes.
!>  @param[in] map_outputs   Array of map output nodes.
!>  @param[in] num_maps      Number of maps.
!>  @param[in] random_state  Optional random state, can be NULL if not used.
!>  @param[in] name          Name for the kernel.
!>  @param[in] num_particles Number of elements to operate on.
!>  @param[in] tol           Tolarance to converge the function to.
!>  @param[in] max_iter      Maximum number of iterations before giving up.
!-------------------------------------------------------------------------------
         SUBROUTINE graph_add_converge_item(c, inputs, num_inputs,             &
                                            outputs, num_outputs,              &
                                            map_inputs, map_outputs, num_maps, &
                                            random_state, name, num_particles, &
                                            tol, max_iter)                     &
         BIND(C, NAME='graph_add_converge_item')
         USE, INTRINSIC :: ISO_C_BINDING
         IMPLICIT NONE
         TYPE(C_PTR), VALUE                   :: c
         INTEGER(C_INTPTR_T), VALUE           :: inputs
         INTEGER(C_LONG), VALUE               :: num_inputs
         INTEGER(C_INTPTR_T), VALUE           :: outputs
         INTEGER(C_LONG), VALUE               :: num_outputs
         INTEGER(C_INTPTR_T), VALUE           :: map_inputs
         INTEGER(C_INTPTR_T), VALUE           :: map_outputs
         INTEGER(C_LONG), VALUE               :: num_maps
         TYPE(C_PTR), VALUE                   :: random_state
         CHARACTER(kind=C_CHAR), DIMENSION(*) :: name
         INTEGER(C_LONG), VALUE               :: num_particles
         REAL(C_DOUBLE), VALUE                :: tol
         INTEGER(C_LONG), VALUE               :: max_iter
         END SUBROUTINE

!-------------------------------------------------------------------------------
!>  @brief Take derivative ∂f∂x.
!>
!>  @param[in] c     The graph C context.
!>  @param[in] fnode The function expression to take the derivative of.
!>  @param[in] xnode The expression to take the derivative with respect to.
!-------------------------------------------------------------------------------
         TYPE(C_PTR) FUNCTION graph_df(c, fnode, xnode)                        &
         BIND(C, NAME='graph_df')
         USE, INTRINSIC :: ISO_C_BINDING
         TYPE(C_PTR), VALUE :: c
         TYPE(C_PTR), VALUE :: fnode
         TYPE(C_PTR), VALUE :: xnode
         END FUNCTION

      END INTERFACE

      CONTAINS
@@ -1868,4 +1961,107 @@

      END SUBROUTINE

!-------------------------------------------------------------------------------
!>  @brief Add workflow item.
!>
!>  @param[in,out] this          @ref graph_context instance.
!>  @param[in]     inputs        Array of input nodes.
!>  @param[in]     outputs       Array of output nodes.
!>  @param[in]     map_inputs    Array of map input nodes.
!>  @param[in]     map_outputs   Array of map output nodes.
!>  @param[in]     random_state  Optional random state, can be NULL if not used.
!>  @param[in]     name          Name for the kernel.
!>  @param[in]     num_particles Number of elements to operate on.
!-------------------------------------------------------------------------------
      SUBROUTINE graph_context_add_item(this, inputs, outputs,                 &
                                        map_inputs, map_outputs,               &
                                        random_state, name, num_particles)

      IMPLICIT NONE

!  Declare Arguments
      CLASS(graph_context), INTENT(INOUT)           :: this
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: inputs
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: outputs
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: map_inputs
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: map_outputs
      TYPE(C_PTR), INTENT(IN)                       :: random_state
      CHARACTER(kind=C_CHAR,len=*), INTENT(IN)      :: name
      INTEGER(C_LONG), INTENT(IN)                   :: num_particles

!  Start of executable.
      CALL graph_add_item(this%c_context,                                      &
                          LOC(inputs), INT(SIZE(inputs), KIND=C_LONG),         &
                          LOC(outputs), INT(SIZE(outputs), KIND=C_LONG),       &
                          LOC(map_inputs), LOC(map_outputs),                   &
                          INT(SIZE(map_inputs), KIND=C_LONG),                  &
                          random_state, name, num_particles)

      END SUBROUTINE

!-------------------------------------------------------------------------------
!>  @brief Add workflow converge item.
!>
!>  @param[in,out] this          @ref graph_context instance.
!>  @param[in]     inputs        Array of input nodes.
!>  @param[in]     outputs       Array of output nodes.
!>  @param[in]     map_inputs    Array of map input nodes.
!>  @param[in]     map_outputs   Array of map output nodes.
!>  @param[in]     random_state  Optional random state, can be NULL if not used.
!>  @param[in]     name          Name for the kernel.
!>  @param[in]     num_particles Number of elements to operate on.
!-------------------------------------------------------------------------------
      SUBROUTINE graph_context_add_converge_item(this, inputs, outputs,        &
                                                 map_inputs, map_outputs,      &
                                                 random_state, name,           &
                                                 num_particles, tol, max_iter)

      IMPLICIT NONE

!  Declare Arguments
      CLASS(graph_context), INTENT(INOUT)           :: this
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: inputs
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: outputs
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: map_inputs
      INTEGER(C_INTPTR_T), DIMENSION(:), INTENT(IN) :: map_outputs
      TYPE(C_PTR), INTENT(IN)                       :: random_state
      CHARACTER(kind=C_CHAR,len=*), INTENT(IN)      :: name
      INTEGER(C_LONG), INTENT(IN)                   :: num_particles
      REAL(C_DOUBLE), VALUE                         :: tol
      INTEGER(C_LONG), VALUE                        :: max_iter

!  Start of executable.
      CALL graph_add_converge_item(this%c_context, LOC(inputs),                &
                                   INT(SIZE(inputs), KIND=C_LONG),             &
                                   LOC(outputs),                               &
                                   INT(SIZE(outputs), KIND=C_LONG),            &
                                   LOC(map_inputs), LOC(map_outputs),          &
                                   INT(SIZE(map_inputs), KIND=C_LONG),         &
                                   random_state, name, num_particles,          &
                                   tol, max_iter)

      END SUBROUTINE

!-------------------------------------------------------------------------------
!>  @brief Take derivative ∂f∂x.
!>
!>  @param[in,out] this  @ref graph_context instance.
!>  @param[in]     fnode The function expression to take the derivative of.
!>  @param[in]     xnode The expression to take the derivative with respect to.
!-------------------------------------------------------------------------------
         FUNCTION graph_context_df(this, fnode, xnode)

         IMPLICIT NONE

!  Declare Arguments
         TYPE(C_PTR)                         :: graph_context_df
         CLASS(graph_context), INTENT(INOUT) :: this
         TYPE(C_PTR), INTENT(IN)             :: fnode
         TYPE(C_PTR), INTENT(IN)             :: xnode

!  Start of executable.
         graph_context_df = graph_df(this%c_context, fnode, xnode)

         END FUNCTION

      END MODULE
+161 −21
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@
      REAL(C_FLOAT), DIMENSION(1)   :: value
      TYPE(C_PTR)                   :: px
      TYPE(C_PTR)                   :: y
      TYPE(C_PTR)                   :: dydx
      TYPE(C_PTR)                   :: dydm
      TYPE(C_PTR)                   :: dydb
      TYPE(C_PTR)                   :: dydy
      TYPE(C_PTR)                   :: one
      TYPE(C_PTR)                   :: zero
      INTEGER(C_LONG)               :: size
@@ -86,6 +90,10 @@
      REAL(C_FLOAT), DIMENSION(3,3) :: buffer2D
      TYPE(C_PTR)                   :: p2
      TYPE(C_PTR)                   :: j
      TYPE(C_PTR)                   :: z
      TYPE(C_PTR)                   :: root
      TYPE(C_PTR)                   :: root2
      TYPE(C_PTR)                   :: dz

!  Start of executable code.
      graph => graph_float_context(use_safe_math)
@@ -105,6 +113,11 @@

      y = graph%add(graph%mul(m, x), b)

      dydx = graph%df(y, x);
      dydm = graph%df(y, m);
      dydb = graph%df(y, b);
      dydy = graph%df(y, y);

      one = graph%constant(1.0_C_DOUBLE)
      zero = graph%constant(0.0_C_DOUBLE)

@@ -140,12 +153,34 @@
      p2 = graph%piecewise_2D(i, 1.0_C_DOUBLE, 0.0_C_DOUBLE,                   &
                              j, 1.0_C_DOUBLE, 0.0_C_DOUBLE, buffer2D)

      z = graph%variable(1_C_LONG, 'z' // C_NULL_CHAR)
      root = graph%sub(graph%pow(z, graph%constant(3.0_C_DOUBLE)),             &
                       graph%pow(z, graph%constant(2.0_C_DOUBLE)))
      root2 = graph%mul(root, root)
      dz = graph%sub(z, graph%div(root, graph%df(root, z)))

      CALL graph%set_device_number(graph%get_max_concurrency() - 1)

      CALL graph%add_pre_item(graph_null_array, (/ graph_ptr(rand) /),         &
                              graph_null_array, graph_null_array, state,       &
                              'c_binding_pre_kernel' // C_NULL_CHAR,           &
                              'f_binding_pre_kernel' // C_NULL_CHAR,           &
                              1_C_LONG)
      CALL graph%add_item((/ graph_ptr(x) /), (/                               &
         graph_ptr(y),                                                         &
         graph_ptr(dydx),                                                      &
         graph_ptr(dydm),                                                      &
         graph_ptr(dydb),                                                      &
         graph_ptr(dydy)                                                       &
      /), graph_null_array, graph_null_array, C_NULL_PTR,                      &
      'f_binding' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_item((/ graph_ptr(i), graph_ptr(j) /),                    &
                          (/ graph_ptr(p1), graph_ptr(p2) /),                  &
                          graph_null_array, graph_null_array, C_NULL_PTR,      &
                          'c_binding_piecewise' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_converge_item((/ graph_ptr(z) /), (/ graph_ptr(root2) /), &
                                   (/ graph_ptr(z) /), (/ graph_ptr(dz) /),    &
                                   C_NULL_PTR, "f_binding_converge", 1_C_LONG, &
                                   1.0E-30_C_DOUBLE, 1000_C_LONG)

      DEALLOCATE(graph)

@@ -175,6 +210,10 @@
      REAL(C_DOUBLE), DIMENSION(1)   :: value
      TYPE(C_PTR)                    :: px
      TYPE(C_PTR)                    :: y
      TYPE(C_PTR)                    :: dydx
      TYPE(C_PTR)                    :: dydm
      TYPE(C_PTR)                    :: dydb
      TYPE(C_PTR)                    :: dydy
      TYPE(C_PTR)                    :: one
      TYPE(C_PTR)                    :: zero
      INTEGER(C_LONG)                :: size
@@ -186,6 +225,10 @@
      REAL(C_DOUBLE), DIMENSION(3,3) :: buffer2D
      TYPE(C_PTR)                    :: p2
      TYPE(C_PTR)                    :: j
      TYPE(C_PTR)                    :: z
      TYPE(C_PTR)                    :: root
      TYPE(C_PTR)                    :: root2
      TYPE(C_PTR)                    :: dz

!  Start of executable code.
      graph => graph_double_context(use_safe_math)
@@ -205,6 +248,11 @@

      y = graph%add(graph%mul(m, x), b)

      dydx = graph%df(y, x);
      dydm = graph%df(y, m);
      dydb = graph%df(y, b);
      dydy = graph%df(y, y);

      one = graph%constant(1.0_C_DOUBLE)
      zero = graph%constant(0.0_C_DOUBLE)

@@ -240,12 +288,34 @@
      p2 = graph%piecewise_2D(i, 1.0_C_DOUBLE, 0.0_C_DOUBLE,                   &
                              j, 1.0_C_DOUBLE, 0.0_C_DOUBLE, buffer2D)

      z = graph%variable(1_C_LONG, 'z' // C_NULL_CHAR)
      root = graph%sub(graph%pow(z, graph%constant(3.0_C_DOUBLE)),             &
                 graph%pow(z, graph%constant(2.0_C_DOUBLE)))
      root2 = graph%mul(root, root)
      dz = graph%sub(z, graph%div(root, graph%df(root, z)))

      CALL graph%set_device_number(graph%get_max_concurrency() - 1)

      CALL graph%add_pre_item(graph_null_array, (/ graph_ptr(rand) /),         &
                              graph_null_array, graph_null_array, state,       &
                              'c_binding_pre_kernel' // C_NULL_CHAR,           &
                              'f_binding_pre_kernel' // C_NULL_CHAR,           &
                              1_C_LONG)
      CALL graph%add_item((/ graph_ptr(x) /), (/                               &
         graph_ptr(y),                                                         &
         graph_ptr(dydx),                                                      &
         graph_ptr(dydm),                                                      &
         graph_ptr(dydb),                                                      &
         graph_ptr(dydy)                                                       &
      /), graph_null_array, graph_null_array, C_NULL_PTR,                      &
      'f_binding' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_item((/ graph_ptr(i), graph_ptr(j) /),                    &
                          (/ graph_ptr(p1), graph_ptr(p2) /),                  &
                          graph_null_array, graph_null_array, C_NULL_PTR,      &
                          'c_binding_piecewise' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_converge_item((/ graph_ptr(z) /), (/ graph_ptr(root2) /), &
                                   (/ graph_ptr(z) /), (/ graph_ptr(dz) /),    &
                                   C_NULL_PTR, "f_binding_converge", 1_C_LONG, &
                                   1.0E-30_C_DOUBLE, 1000_C_LONG)

      DEALLOCATE(graph)

@@ -275,6 +345,10 @@
      COMPLEX(C_FLOAT_COMPLEX), DIMENSION(1)   :: value
      TYPE(C_PTR)                              :: px
      TYPE(C_PTR)                              :: y
      TYPE(C_PTR)                              :: dydx
      TYPE(C_PTR)                              :: dydm
      TYPE(C_PTR)                              :: dydb
      TYPE(C_PTR)                              :: dydy
      TYPE(C_PTR)                              :: one
      TYPE(C_PTR)                              :: zero
      INTEGER(C_LONG)                          :: size
@@ -286,6 +360,10 @@
      COMPLEX(C_FLOAT_COMPLEX), DIMENSION(3,3) :: buffer2D
      TYPE(C_PTR)                              :: p2
      TYPE(C_PTR)                              :: j
      TYPE(C_PTR)                              :: z
      TYPE(C_PTR)                              :: root
      TYPE(C_PTR)                              :: root2
      TYPE(C_PTR)                              :: dz

!  Start of executable code.
      graph => graph_complex_float_context(use_safe_math)
@@ -305,6 +383,11 @@

      y = graph%add(graph%mul(m, x), b)

      dydx = graph%df(y, x);
      dydm = graph%df(y, m);
      dydb = graph%df(y, b);
      dydy = graph%df(y, y);

      one = graph%constant(1.0_C_DOUBLE)
      zero = graph%constant(0.0_C_DOUBLE)

@@ -344,12 +427,34 @@
      p2 = graph%piecewise_2D(i, 1.0_C_DOUBLE, 0.0_C_DOUBLE,                   &
                              j, 1.0_C_DOUBLE, 0.0_C_DOUBLE, buffer2D)

      z = graph%variable(1_C_LONG, 'z' // C_NULL_CHAR)
      root = graph%sub(graph%pow(z, graph%constant(3.0_C_DOUBLE)),             &
                       graph%pow(z, graph%constant(2.0_C_DOUBLE)))
      root2 = graph%mul(root, root)
      dz = graph%sub(z, graph%div(root, graph%df(root, z)))

      CALL graph%set_device_number(graph%get_max_concurrency() - 1)

      CALL graph%add_pre_item(graph_null_array, (/ graph_ptr(rand) /),         &
                              graph_null_array, graph_null_array, state,       &
                              'c_binding_pre_kernel' // C_NULL_CHAR,           &
                              1_C_LONG)
      CALL graph%add_item((/ graph_ptr(x) /), (/                               &
         graph_ptr(y),                                                         &
         graph_ptr(dydx),                                                      &
         graph_ptr(dydm),                                                      &
         graph_ptr(dydb),                                                      &
         graph_ptr(dydy)                                                       &
      /), graph_null_array, graph_null_array, C_NULL_PTR,                      &
      'f_binding' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_item((/ graph_ptr(i), graph_ptr(j) /),                    &
                          (/ graph_ptr(p1), graph_ptr(p2) /),                  &
                          graph_null_array, graph_null_array, C_NULL_PTR,      &
                          'c_binding_piecewise' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_converge_item((/ graph_ptr(z) /), (/ graph_ptr(root2) /), &
                                   (/ graph_ptr(z) /), (/ graph_ptr(dz) /),    &
                                   C_NULL_PTR, "f_binding_converge", 1_C_LONG, &
                                   1.0E-30_C_DOUBLE, 1000_C_LONG)

      DEALLOCATE(graph)

@@ -379,6 +484,10 @@
      COMPLEX(C_DOUBLE_COMPLEX), DIMENSION(1)   :: value
      TYPE(C_PTR)                               :: px
      TYPE(C_PTR)                               :: y
      TYPE(C_PTR)                               :: dydx
      TYPE(C_PTR)                               :: dydm
      TYPE(C_PTR)                               :: dydb
      TYPE(C_PTR)                               :: dydy
      TYPE(C_PTR)                               :: one
      TYPE(C_PTR)                               :: zero
      INTEGER(C_LONG)                           :: size
@@ -390,6 +499,10 @@
      COMPLEX(C_DOUBLE_COMPLEX), DIMENSION(3,3) :: buffer2D
      TYPE(C_PTR)                               :: p2
      TYPE(C_PTR)                               :: j
      TYPE(C_PTR)                               :: z
      TYPE(C_PTR)                               :: root
      TYPE(C_PTR)                               :: root2
      TYPE(C_PTR)                               :: dz

!  Start of executable code.
      graph => graph_complex_double_context(use_safe_math)
@@ -409,6 +522,11 @@

      y = graph%add(graph%mul(m, x), b)

      dydx = graph%df(y, x);
      dydm = graph%df(y, m);
      dydb = graph%df(y, b);
      dydy = graph%df(y, y);

      one = graph%constant(1.0_C_DOUBLE)
      zero = graph%constant(0.0_C_DOUBLE)

@@ -448,12 +566,34 @@
      p2 = graph%piecewise_2D(i, 1.0_C_DOUBLE, 0.0_C_DOUBLE,                   &
                              j, 1.0_C_DOUBLE, 0.0_C_DOUBLE, buffer2D)

      z = graph%variable(1_C_LONG, 'z' // C_NULL_CHAR)
      root = graph%sub(graph%pow(z, graph%constant(3.0_C_DOUBLE)),             &
                       graph%pow(z, graph%constant(2.0_C_DOUBLE)))
      root2 = graph%mul(root, root)
      dz = graph%sub(z, graph%div(root, graph%df(root, z)))

      CALL graph%set_device_number(graph%get_max_concurrency() - 1)

      CALL graph%add_pre_item(graph_null_array, (/ graph_ptr(rand) /),         &
                              graph_null_array, graph_null_array, state,       &
                              'c_binding_pre_kernel' // C_NULL_CHAR,           &
                              'f_binding_pre_kernel' // C_NULL_CHAR,           &
                              1_C_LONG)
      CALL graph%add_item((/ graph_ptr(x) /), (/                               &
         graph_ptr(y),                                                         &
         graph_ptr(dydx),                                                      &
         graph_ptr(dydm),                                                      &
         graph_ptr(dydb),                                                      &
         graph_ptr(dydy)                                                       &
      /), graph_null_array, graph_null_array, C_NULL_PTR,                      &
      'f_binding' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_item((/ graph_ptr(i), graph_ptr(j) /),                    &
                          (/ graph_ptr(p1), graph_ptr(p2) /),                  &
                          graph_null_array, graph_null_array, C_NULL_PTR,      &
                          'c_binding_piecewise' // C_NULL_CHAR, 1_C_LONG)
      CALL graph%add_converge_item((/ graph_ptr(z) /), (/ graph_ptr(root2) /), &
                                   (/ graph_ptr(z) /), (/ graph_ptr(dz) /),    &
                                   C_NULL_PTR, "f_binding_converge", 1_C_LONG, &
                                   1.0E-30_C_DOUBLE, 1000_C_LONG)

      DEALLOCATE(graph)