LCOV - code coverage report
Current view: top level - src/pw - pw_fpga.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 4 15 26.7 %
Date: 2024-12-21 06:28:57 Functions: 2 7 28.6 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \note
      10             : !> This module contains routines necessary to operate on plane waves on INTEL
      11             : !> FPGAs using OpenCL. It depends at execution time on the board support
      12             : !> packages of the specific FPGA
      13             : !> \author Arjun Ramaswami
      14             : !> \author Robert Schade
      15             : ! **************************************************************************************************
      16             : 
      17             : MODULE pw_fpga
      18             :    USE ISO_C_BINDING,                   ONLY: C_CHAR,&
      19             :                                               C_DOUBLE_COMPLEX,&
      20             :                                               C_FLOAT_COMPLEX,&
      21             :                                               C_INT,&
      22             :                                               C_NULL_CHAR
      23             :    USE cp_files,                        ONLY: get_data_dir
      24             :    USE kinds,                           ONLY: dp,&
      25             :                                               sp
      26             : #include "../base/base_uses.f90"
      27             : 
      28             :    IMPLICIT NONE
      29             : 
      30             :    PRIVATE
      31             : 
      32             :    PUBLIC :: pw_fpga_init, pw_fpga_finalize
      33             :    PUBLIC :: pw_fpga_init_bitstream
      34             :    PUBLIC :: pw_fpga_r3dc1d_3d_sp, pw_fpga_c1dr3d_3d_sp
      35             :    PUBLIC :: pw_fpga_r3dc1d_3d_dp, pw_fpga_c1dr3d_3d_dp
      36             : 
      37             :    INTERFACE
      38             : ! **************************************************************************************************
      39             : !> \brief Initialize FPGA
      40             : !> \retval status if the routine failed or not
      41             : ! **************************************************************************************************
      42             :       FUNCTION pw_fpga_initialize() RESULT(stat) &
      43             :          BIND(C, name="pw_fpga_initialize_")
      44             :          IMPORT
      45             :          INTEGER(KIND=C_INT)                    :: stat
      46             :       END FUNCTION pw_fpga_initialize
      47             : 
      48             : ! **************************************************************************************************
      49             : !> \brief Destroy FPGA
      50             : ! **************************************************************************************************
      51             :       SUBROUTINE pw_fpga_final() &
      52             :          BIND(C, name="pw_fpga_final_")
      53             :       END SUBROUTINE pw_fpga_final
      54             : 
      55             :    END INTERFACE
      56             : 
      57             :    INTERFACE
      58             : ! **************************************************************************************************
      59             : !> \brief Check whether an fpga bitstream for the given FFT3d size is present & load binary if needed
      60             : !> \param data_path - path to the data directory
      61             : !> \param npts - fft3d size
      62             : !> \return res - true if fft3d size supported
      63             : ! **************************************************************************************************
      64             :       FUNCTION pw_fpga_check_bitstream(data_path, n) RESULT(res) &
      65             :          BIND(C, name="pw_fpga_check_bitstream_")
      66             :          IMPORT
      67             :          CHARACTER(KIND=C_CHAR)        :: data_path(*)
      68             :          INTEGER(KIND=C_INT)           :: n(3)
      69             :          INTEGER(KIND=C_INT)           :: res
      70             :       END FUNCTION pw_fpga_check_bitstream
      71             : 
      72             :    END INTERFACE
      73             : 
      74             :    INTERFACE
      75             : ! **************************************************************************************************
      76             : !> \brief single precision FFT3d using FPGA
      77             : !> \param dir - direction of FFT3d
      78             : !> \param npts - dimensions of FFT3d
      79             : !> \param single precision c_in...
      80             : ! **************************************************************************************************
      81             :       SUBROUTINE pw_fpga_fft3d_sp(dir, n, c_in_sp) &
      82             :          BIND(C, name="pw_fpga_fft3d_sp_")
      83             :          IMPORT
      84             :          INTEGER(KIND=C_INT), VALUE              :: dir
      85             :          INTEGER(KIND=C_INT)                     :: n(3)
      86             :          COMPLEX(KIND=C_FLOAT_COMPLEX)           :: c_in_sp(n(1), n(2), n(3))
      87             :       END SUBROUTINE pw_fpga_fft3d_sp
      88             :    END INTERFACE
      89             : 
      90             :    INTERFACE
      91             : ! **************************************************************************************************
      92             : !> \brief double precision FFT3d using FPGA
      93             : !> \param dir - direction of FFT3d
      94             : !> \param npts - dimensions of FFT3d
      95             : !> \param double precision c_in...
      96             : ! **************************************************************************************************
      97             :       SUBROUTINE pw_fpga_fft3d_dp(dir, n, c_in_dp) &
      98             :          BIND(C, name="pw_fpga_fft3d_dp_")
      99             :          IMPORT
     100             :          INTEGER(KIND=C_INT), VALUE              :: dir
     101             :          INTEGER(KIND=C_INT)                     :: n(3)
     102             :          COMPLEX(KIND=C_DOUBLE_COMPLEX)          :: c_in_dp(n(1), n(2), n(3))
     103             :       END SUBROUTINE pw_fpga_fft3d_dp
     104             :    END INTERFACE
     105             : 
     106             : CONTAINS
     107             : 
     108             : ! **************************************************************************************************
     109             : !> \brief Allocates resources on the fpga device
     110             : ! **************************************************************************************************
     111        9174 :    SUBROUTINE pw_fpga_init()
     112             : #if defined (__PW_FPGA)
     113             :       INTEGER :: stat
     114             : 
     115             : #if defined(__OFFLOAD) && !defined(__NO_OFFLOAD_PW)
     116             : #error "OFFLOAD and FPGA cannot be configured concurrently! Recompile with -D__NO_OFFLOAD_PW."
     117             :       CPABORT("OFFLOAD and FPGA cannot be configured concurrently! Recompile with -D__NO_OFFLOAD_PW.")
     118             : #endif
     119             :       stat = pw_fpga_initialize()
     120             :       IF (stat /= 0) &
     121             :          CPABORT("pw_fpga_init: failed")
     122             : #endif
     123             : 
     124             : #if (__PW_FPGA_SP && !(__PW_FPGA))
     125             : #error "Define both __PW_FPGA_SP and __PW_FPGA"
     126             :       CPABORT("Define both __PW_FPGA_SP and __PW_FPGA")
     127             : #endif
     128             : 
     129        9174 :    END SUBROUTINE pw_fpga_init
     130             : 
     131             : ! **************************************************************************************************
     132             : !> \brief Releases resources on the fpga device
     133             : ! **************************************************************************************************
     134        9174 :    SUBROUTINE pw_fpga_finalize()
     135             : #if defined (__PW_FPGA)
     136             :       CALL pw_fpga_final()
     137             : #endif
     138        9174 :    END SUBROUTINE pw_fpga_finalize
     139             : 
     140             : ! **************************************************************************************************
     141             : !> \brief perform an in-place double precision fft3d on the FPGA
     142             : !> \param n ...
     143             : !> \param c_out  ...
     144             : ! **************************************************************************************************
     145           0 :    SUBROUTINE pw_fpga_r3dc1d_3d_dp(n, c_out)
     146             :       INTEGER, DIMENSION(:), INTENT(IN)          :: n
     147             :       COMPLEX(KIND=dp), INTENT(INOUT)            :: c_out(n(1), n(2), n(3))
     148             : 
     149             : #if ! defined (__PW_FPGA)
     150             :       MARK_USED(c_out)
     151             :       MARK_USED(n)
     152             : #else
     153             :       INTEGER                                     :: handle3
     154             : 
     155             :       CHARACTER(len=*), PARAMETER :: routineX = 'fw_fft_fpga_r3dc1d_dp'
     156             : 
     157             :       CALL timeset(routineX, handle3)
     158             :       CALL pw_fpga_fft3d_dp(+1, n, c_out)
     159             :       CALL timestop(handle3)
     160             : 
     161             : #endif
     162           0 :    END SUBROUTINE
     163             : 
     164             : ! **************************************************************************************************
     165             : !> \brief perform an in-place double precision inverse fft3d on the FPGA
     166             : !> \param n ...
     167             : !> \param c_out  ...
     168             : ! **************************************************************************************************
     169           0 :    SUBROUTINE pw_fpga_c1dr3d_3d_dp(n, c_out)
     170             :       INTEGER, DIMENSION(:), INTENT(IN)                 :: n
     171             :       COMPLEX(KIND=dp), INTENT(INOUT)    :: c_out(n(1), n(2), n(3))
     172             : 
     173             : #if ! defined (__PW_FPGA)
     174             :       MARK_USED(c_out)
     175             :       MARK_USED(n)
     176             : #else
     177             :       INTEGER                                          :: handle3
     178             : 
     179             :       CHARACTER(len=*), PARAMETER :: routineX = 'bw_fft_fpga_c1dr3d_dp'
     180             : 
     181             :       CALL timeset(routineX, handle3)
     182             :       CALL pw_fpga_fft3d_dp(-1, n, c_out)
     183             :       CALL timestop(handle3)
     184             : 
     185             : #endif
     186           0 :    END SUBROUTINE
     187             : 
     188             : ! **************************************************************************************************
     189             : !> \brief perform an in-place single precision fft3d on the FPGA
     190             : !> \param n ...
     191             : !> \param c_out  ...
     192             : ! **************************************************************************************************
     193           0 :    SUBROUTINE pw_fpga_r3dc1d_3d_sp(n, c_out)
     194             :       INTEGER, DIMENSION(:), INTENT(IN)                 :: n
     195             :       COMPLEX(KIND=dp), INTENT(INOUT)             :: c_out(n(1), n(2), n(3))
     196             : 
     197             : #if ! defined (__PW_FPGA)
     198             :       MARK_USED(c_out)
     199             :       MARK_USED(n)
     200             : #else
     201             :       COMPLEX, DIMENSION(:, :, :), POINTER             :: c_in_sp
     202             :       INTEGER                                          :: handle3
     203             : 
     204             :       CHARACTER(len=*), PARAMETER :: routineX = 'fw_fft_fpga_r3dc1d_sp'
     205             : 
     206             :       ALLOCATE (c_in_sp(n(1), n(2), n(3)))
     207             :       ! pointer to single precision complex array
     208             :       c_in_sp = CMPLX(c_out, KIND=sp)
     209             : 
     210             :       CALL timeset(routineX, handle3)
     211             :       CALL pw_fpga_fft3d_sp(+1, n, c_in_sp)
     212             :       CALL timestop(handle3)
     213             : 
     214             :       ! typecast sp back to dp
     215             :       !c_out = CMPLX(real(c_in_sp), 0.0_dp, KIND=dp)
     216             :       c_out = CMPLX(c_in_sp, KIND=dp)
     217             : 
     218             :       DEALLOCATE (c_in_sp)
     219             : #endif
     220           0 :    END SUBROUTINE
     221             : 
     222             : ! **************************************************************************************************
     223             : !> \brief perform an in-place single precision inverse fft3d on the FPGA
     224             : !> \param n ...
     225             : !> \param c_out  ...
     226             : ! **************************************************************************************************
     227           0 :    SUBROUTINE pw_fpga_c1dr3d_3d_sp(n, c_out)
     228             :       INTEGER, DIMENSION(:), INTENT(IN)                 :: n
     229             :       COMPLEX(KIND=dp), INTENT(INOUT)             :: c_out(n(1), n(2), n(3))
     230             : 
     231             : #if ! defined (__PW_FPGA)
     232             :       MARK_USED(c_out)
     233             :       MARK_USED(n)
     234             : 
     235             : #else
     236             :       COMPLEX, DIMENSION(:, :, :), POINTER             :: c_in_sp
     237             :       INTEGER                                          :: handle3
     238             : 
     239             :       CHARACTER(len=*), PARAMETER :: routineX = 'bw_fft_fpga_c1dr3d_sp'
     240             : 
     241             :       ALLOCATE (c_in_sp(n(1), n(2), n(3)))
     242             :       ! pointer to single precision complex array
     243             :       c_in_sp = CMPLX(c_out, KIND=sp)
     244             : 
     245             :       CALL timeset(routineX, handle3)
     246             :       CALL pw_fpga_fft3d_sp(-1, n, c_in_sp)
     247             :       CALL timestop(handle3)
     248             : 
     249             :       ! typecast sp back to dp
     250             :       c_out = CMPLX(c_in_sp, KIND=dp)
     251             : 
     252             :       DEALLOCATE (c_in_sp)
     253             : #endif
     254           0 :    END SUBROUTINE
     255             : 
     256             : ! **************************************************************************************************
     257             : !> \brief  Invoke the pw_fpga_check_bitstream C function passing the path to the data dir
     258             : !> \param  n   - fft3d size
     259             : !> \return ...
     260             : !> \retval res - true if fft size found and initialized else false
     261             : ! **************************************************************************************************
     262           0 :    FUNCTION pw_fpga_init_bitstream(n) RESULT(res)
     263             :       INTEGER, DIMENSION(:), INTENT(IN)                 :: n
     264             :       INTEGER                                           :: res
     265             : 
     266             : #if ! defined (__PW_FPGA)
     267           0 :       res = 0
     268             :       MARK_USED(n)
     269             :       MARK_USED(res)
     270             : #else
     271             :       CHARACTER(len=100)                               :: data_path
     272             :       INTEGER                                          :: data_path_len
     273             : 
     274             :       data_path = TRIM(get_data_dir())//C_NULL_CHAR
     275             :       data_path_len = LEN_TRIM(data_path)
     276             : 
     277             :       res = pw_fpga_check_bitstream(data_path, n)
     278             : #endif
     279           0 :    END FUNCTION
     280             : 
     281             : END MODULE pw_fpga
     282             : 

Generated by: LCOV version 1.15