C$Procedure ZZSPKSB1 ( S/P Kernel, solar system barycenter )

      SUBROUTINE ZZSPKSB1 ( TARG, ET, REF, STARG )

C$ Abstract
C
C     SPICE Private routine intended solely for the support of SPICE
C     routines.  Users should not call this routine directly due
C     to the volatile nature of this routine.
C
C     Return the state (position and velocity) of a target body
C     relative to the solar system barycenter.
C
C$ Disclaimer
C
C     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
C     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
C     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
C     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
C     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
C     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
C     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
C     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
C     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
C     SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
C
C     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
C     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
C     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
C     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
C     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
C     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
C
C     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
C     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
C     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
C     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
C
C$ Required_Reading
C
C     SPK
C
C$ Keywords
C
C     EPHEMERIS
C
C$ Declarations

      IMPLICIT NONE
      INTEGER               TARG
      DOUBLE PRECISION      ET
      CHARACTER*(*)         REF
      DOUBLE PRECISION      STARG    ( 6 )

C$ Brief_I/O
C
C     Variable  I/O  Description
C     --------  ---  --------------------------------------------------
C     TARG       I   Target body.
C     ET         I   Target epoch.
C     REF        I   Target reference frame.
C     STARG      O   State of target.
C
C$ Detailed_Input
C
C     TARG        is the standard NAIF ID code for a target body.
C
C     ET          is the epoch (ephemeris time) at which the state
C                 of the target body is to be computed.
C
C     REF         is the name of the  reference frame to which the
C                 vectors returned by the routine should be rotated.
C                 This may be any frame supported by the SPICELIB frame
C                 system, including dynamic and other non-inertial
C                 frames.
C
C$ Detailed_Output
C
C     STARG       contains the position and velocity of the target
C                 body, relative to the solar system barycenter,
C                 at epoch ET. These vectors are rotated into the
C                 specified  reference frame. Units are always
C                 km and km/sec.
C
C$ Parameters
C
C     None.
C
C$ Exceptions
C
C     1) If insufficient information has not bee "loaded" via the
C        routine SPKLEF or the PCK kernel loaders, the problem will
C        be diagnosed by a routine in the call tree of this routine.
C
C$ Files
C
C     See: $Restrictions.
C
C$ Particulars
C
C     In order to compute the state of one body relative to another,
C     the states of the two bodies must be known relative to a third
C     body. One simple solution is to use the solar system barycenter
C     as the third body.
C
C     Ephemeris data from more than one segment may be required
C     to determine the state of a body relative to the barycenter.
C     ZZSPKSB1 reads as many segments as necessary, from as many
C     files as necessary, using files that have been loaded by
C     previous calls to SPKLEF (load ephemeris file).
C
C$ Examples
C
C     In the following code fragment, ZZSPKSB1 is used to display
C     the distance from Earth (Body 399) to Mars (body 499) at
C     a series of epochs.
C
C        CALL SPKLEF ( 'DE125.SPK', HANDLE )
C         .
C         .
C
C        EARTH = 399
C        MARS  = 499
C
C        DO WHILE ( EPOCH .LE. END )
C           CALL ZZSPKSB1 ( EARTH, EPOCH, 'J2000', SEARTH )
C           CALL ZZSPKSB1 ( MARS,  EPOCH, 'J2000', SMARS  )
C
C           CALL VSUB ( SMARS, SEARTH, SMARS )
C           WRITE (*,*) EPOCH, VNORM ( SMARS )
C
C           EPOCH = EPOCH + DELTA
C        END DO
C
C$ Restrictions
C
C     1) SPICE Private routine.
C
C     2) The ephemeris files to be used by ZZSPKSB1 must be loaded
C        by SPKLEF before ZZSPKSB1 is called.
C
C$ Literature_References
C
C     NAIF Document 168.0, "S- and P- Kernel (SPK) Specification and
C     User's Guide"
C
C$ Author_and_Institution
C
C     W.L. Taber      (JPL)
C     I.M. Underwood  (JPL)
C
C$ Version
C
C-    SPICELIB Version 1.0.0, 12-DEC-2004 (NJB)
C
C        Based on SPICELIB Version 2.0.2, 20-NOV-2004  (NJB)
C
C-&

C$ Index_Entries
C
C     state relative to solar system barycenter
C
C-&

C$ Revisions
C
C-    SPICELIB Version 2.0.0, 19-SEP-1995  (WLT)
C
C        The routine was simplified by replacing all of the
C        main body of code with a call to SPKGEO.  By making
C        this change the routine now supports non-inertial frames.
C
C-&

C
C     SPICELIB functions
C
      LOGICAL               RETURN

C
C     Local variables
C
      DOUBLE PRECISION      LT
      INTEGER               BARY

C
C     Standard SPICE error handling.
C
      IF ( RETURN () ) THEN
         RETURN
      ELSE
         CALL CHKIN ( 'ZZSPKSB1' )
      END IF

      BARY = 0

      CALL ZZSPKGO1 ( TARG, ET, REF, BARY, STARG, LT )

      CALL CHKOUT ( 'ZZSPKSB1' )
      RETURN
      END


! Copyright 2012-2018, University of Strathclyde
! Authors: Jonathan Smith (Tech-X UK Ltd) & Lawrence T. Campbell
! License: BSD-3-Clause

!> @author
!> Jonathan Smith (Tech-X UK Ltd)
!> @brief
!> This module contains the routines for writing the dumps and integrated data
!> individually from each process in hdf5 format - so multiple files are written
!> for each of the field mesh, the macroparticles, and integrated data, and they
!> must be stitched together in post.
!>
!> Routines originally written by Jonathan Smith (Tech-X UK Ltd)

module hdf5PuffID

use paratype
use HDF5
use globals
use ParallelInfoType
use lattice
USE ParallelSetUp
USE ArrayFunctions
USE TypesandConstants
Use avWrite
use hdf5PuffLow

contains

!> Output the electron bean macroparticle
!! 6D phase space coordinates (plus weight) in Puffin.
!! For one file per rank only at the moment
!! @params unused tArrayE global array (to this rank)
!! containing particles and layout of data in sV.
!! @params sElX_G, particle x coordinate
!! @params sElY_G, particle y coordinate
!! @params sElZ2_G, particle z2 (displacement from bunch centre)
!! @params iNumberElectrons_G number of electrons (global) on this rank
!! @todo Individual and collective writing to combined file to come
!! For collective write, we want to work out how many particles on
!! each rank, what the cumulative num electrons is, and then determine
!! the array slice based on that.

  subroutine outputH5BeamFilesID(time, sz_loc, iL, error)

    implicit none

    real(kind=wp),intent(in) :: time !< Current time
    real(kind=wp),intent(in) :: sz_loc
    integer(kind=ip), intent(in) :: iL !< Lattice element number
    integer(HID_T) :: file_id        !< File identifier
    integer(HID_T) :: dset_id        !< Dataset identifier
    integer(HID_T) :: dspace_id      !< Dataspace identifier in memory
    integer(HID_T) :: filespace      !< Dataspace identifier in file
    integer(HID_T) :: attr_id        !< Attribute identifier
    integer(HID_T) :: aspace_id      !< Attribute Dataspace identifier
    integer(HID_T) :: atype_id       !< Attribute Data type identifier
    integer(HID_T) :: group_id       !< Group identifier
!    logical, intent(in) :: qSeparate !<May reinstitute this.
    CHARACTER(LEN=9), PARAMETER :: dsetname = "electrons" !< Dataset name
    CHARACTER(LEN=30) :: aname   !< Attribute name
    character(1024_IP) :: filename
!    logical, intent(inout) :: qOK
!    integer(HSIZE_T), DIMENSION(1) :: dims = (/iGloNumElectrons_G/) ! Dataset dimensions
    integer(HSIZE_T), dimension(2) :: dims   !< dims of ptcl dataset (coords*numelecs)
    integer(HSIZE_T), dimension(2) :: doffset!< Offset for write, could be rank dependent
    integer(HSIZE_T), dimension(2) :: dsize  !< Size of hyperslab to write
    integer     ::  rank = 2                 !< Particle Dataset rank
    integer     ::  arank = 1                !< Attribute rank - 1 is vector
    integer(HSIZE_T), dimension(1) :: adims  !< Attribute dims
    integer(HSIZE_T), dimension(1) :: attr_data_int !< For integer attribs (numdims)
    integer     :: numSpatialDims    !< Attr content, and also num elsewhere
!assumed 3D sim. May be 1D.
!    TYPE(C_PTR) :: f_ptr
    real(kind=wp) :: attr_data_double
    character(len=100) :: attr_data_string
    character(len=16) :: scaleToSIstring
    integer(HSIZE_T) :: attr_string_len
    character(len=4), parameter :: timegrpname = "time"  ! Group name
    character(len=12), parameter :: limgrpname = "globalLimits"  ! Group name
    real(kind=wp), allocatable :: limdata (:)  ! Data to write
    ! Local vars
    !integer(kind=ip) :: iep
    integer :: error ! Error flag

    if (qONED_G) then
      numSpatialDims=1
    else
      numSpatialDims=3
    end if
!    print*,'Writing electron data on rank', tProcInfo_G%rank

    attr_data_int(1)=numSpatialDims
    adims(1)=1
    adims = (/1/)
    dims = (/7,iNumberElectrons_G/) ! Dataset dimensions
    doffset=(/0,0/)
    dsize=(/1,iNumberElectrons_G/)
    attr_data_string="electrons_x,electrons_y,electrons_z,electrons_px," // &
      "electrons_py,electrons_gamma,electrons_weight"
    attr_string_len=94

! Prepare filename

    filename = ( trim(adjustl(zFilename_G)) // '_electrons_' // &
                 trim(adjustl(IntegerToString(tProcInfo_G%Rank))) // &
		 '_' // trim(adjustl(IntegerToString(iCSteps))) // '.h5' )

    CALL h5open_f(error)
!    Print*,'hdf5_puff:outputH5BeamFiles(file opened)'

! Create a new file using default properties.
    CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(file created)'

! Create the big dataspace in the file.
    CALL h5screate_simple_f(rank, dims, filespace, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(filespace created)'

! Create the dataset with default properties.
    CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_DOUBLE, filespace, &
       dset_id, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(dataset created)'
    CALL h5sclose_f(filespace, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(filespace closed)'

! Create a smaller space to buffer the data writes
    CALL h5screate_simple_f(rank, dsize, dspace_id, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(memory dataspace allocated)'
! Select hyperslab in the file.
    CALL H5Dget_space_f(dset_id, filespace, error)
    CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, doffset, &
       dsize, error)
    CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, sElX_G, dims, error, &
       file_space_id = filespace, mem_space_id = dspace_id)

! End access to the dataset and release resources used by it.
    CALL h5sclose_f(filespace, error)
!    CALL h5sclose_f(dspace_id, error)

! repeat for some next y dataset
    doffset=(/1,0/)
    CALL H5Dget_space_f(dset_id, filespace, error)
    CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, doffset, &
       dsize, error)
    CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, sElY_G, dims, error, &
       file_space_id = filespace, mem_space_id = dspace_id)
! was       dspace_id, filespace)
    CALL h5sclose_f(filespace, error)

!
! repeat for some next z dataset
    doffset=(/2,0/)
    CALL H5Dget_space_f(dset_id, filespace, error)
    CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, doffset, &
       dsize, error)
    CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, sElZ2_G, dims, error, &
       file_space_id = filespace, mem_space_id = dspace_id)
! was       dspace_id, filespace)
    CALL h5sclose_f(filespace, error)

! repeat for some next px dataset
    doffset=(/3,0/)
    CALL H5Dget_space_f(dset_id, filespace, error)
    CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, doffset, &
       dsize, error)
    CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, sElPX_G, dims, error, &
       file_space_id = filespace, mem_space_id = dspace_id)
! was       dspace_id, filespace)
    CALL h5sclose_f(filespace, error)

! repeat for some next py dataset
    doffset=(/4,0/)
    CALL H5Dget_space_f(dset_id, filespace, error)
    CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, doffset, &
       dsize, error)
    CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, sElPY_G, dims, error, &
       file_space_id = filespace, mem_space_id = dspace_id)
! was       dspace_id, filespace)
    CALL h5sclose_f(filespace, error)

! repeat for some next gamma dataset (actually beta*gamma)
    doffset=(/5,0/)

    CALL H5Dget_space_f(dset_id, filespace, error)
    CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, doffset, &
       dsize, error)
    CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, sElgam_G, dims, error, &
       file_space_id = filespace, mem_space_id = dspace_id)
! was       dspace_id, filespace)
    CALL h5sclose_f(filespace, error)
!
!
! put Chi in the file, slightly redundant as charge on a macroparticle
! doesn't increase or decrease through the simulation. But does make
! Everything self contained. Perhaps we use in future a funky h5 technique
! to point this column at a separate file which holds the data, reducing
! the size of this column from every written file.
    doffset=(/6,0/)

    CALL H5Dget_space_f(dset_id, filespace, error)
    CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, doffset, &
       dsize, error)
    CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, s_chi_bar_G, dims, error, &
       file_space_id = filespace, mem_space_id = dspace_id)
! was       dspace_id, filespace)
    CALL h5sclose_f(filespace, error)
! Terminate access to the data space.
!
    CALL h5sclose_f(dspace_id, error)
!
! ATTRIBUTES FOR PARTICLE DATASET
!
! simple dataset for array of vals
!    CALL h5screate_simple_f(arank, adims, aspace_id, error)

! scalar dataset for simpler values
    CALL h5screate_f(H5S_SCALAR_F, aspace_id, error)
!
! Create datatype for the attribute.
!
    CALL h5tcopy_f(H5T_NATIVE_INTEGER, atype_id, error)
!    CALL h5tset_size_f(atype_id, attrlen, error)
!
! Create dataset attribute.
!
    aname = "vsNumSpatialDims"
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
! Write the attribute data.
    CALL h5awrite_f(attr_id, atype_id, numSpatialDims, adims, error) !
! Close the attribute.
    CALL h5aclose_f(attr_id, error)
! next attribute
    aname="numSpatialDims"
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
    CALL h5awrite_f(attr_id, atype_id, numSpatialDims, adims, error)
    CALL h5aclose_f(attr_id, error)
    CALL h5tclose_f(atype_id, error)

! integers done, move onto floats
    CALL h5tcopy_f(H5T_NATIVE_DOUBLE, atype_id, error)
!    aname="time"
!    attr_data_double=time
!    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
!    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
!    CALL h5aclose_f(attr_id, error)
! then
    aname="mass"
!    attr_data_double=9.10938356E-31
    attr_data_double=m_e
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
    CALL h5aclose_f(attr_id, error)
    aname="charge"
!    attr_data_double=1.602176487E-19
    attr_data_double=q_e
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
    CALL h5aclose_f(attr_id, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(charge written)'
    aname="numTotalPhysicalParticles"
    attr_data_double=npk_bar_G*q_e
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
    CALL h5aclose_f(attr_id, error)

    call writeCommonAtts(dset_id, time, sz_loc, iL, aspace_id)

!    call addH5IntegerAttribute(dset_id, "iUnd_cr", iUnd_cr, aspace_id)
!    call addH5IntegerAttribute(dset_id, "iChic_cr", iChic_cr, aspace_id)
!    call addH5IntegerAttribute(dset_id, "iDrift_cr", iDrift_cr, aspace_id)
!    call addH5IntegerAttribute(dset_id, "iQuad_cr", iQuad_cr, aspace_id)
!    call addH5IntegerAttribute(dset_id, "iModulation_cr", iModulation_cr, aspace_id)
!    call addH5IntegerAttribute(dset_id, 'iL', iL, aspace_id)
!
!    aname="zbarInter"
!    attr_data_double=time !real(iCSteps,kind=wp)*sStepSize*lg_G
!    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
!    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
!    CALL h5aclose_f(attr_id, error)
!    aname="zInter"
!    attr_data_double=time*lg_G !real(iCSteps,kind=wp)*sStepSize*lg_G
!    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
!    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
!    CALL h5aclose_f(attr_id, error)
    aname="gainLength"
    attr_data_double=lg_G
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
    CALL h5aclose_f(attr_id, error)
    aname="cooperationLength"
    attr_data_double=lc_G
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
    CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
    CALL h5aclose_f(attr_id, error)
    CALL h5tclose_f(atype_id, error)

! then text attributes
    CALL h5tcopy_f(H5T_NATIVE_CHARACTER, atype_id, error)
    CALL h5tset_size_f(atype_id, attr_string_len, error)
    CALL h5tset_strpad_f(atype_id, H5T_STR_SPACEPAD_F, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(string padding enabled)'
    aname="vsLabels"
    CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
    CALL h5awrite_f(attr_id, atype_id, attr_data_string, adims, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(lables attribute written)'
    CALL h5aclose_f(attr_id, error)
    CALL addH5StringAttribute(dset_id,"vsType","variableWithMesh",aspace_id)
    CALL addH5StringAttribute(dset_id,"vsTimeGroup","time",aspace_id)
    CALL addH5StringAttribute(dset_id,"vsLimits","globalLimits",aspace_id)
!
! Terminate access to the dataset space, still using the scalar identifier
    CALL h5dclose_f(dset_id, error)

! Write time Group
    CALL writeH5TimeGroup(file_id, timegrpname, time, 'outputH5Beam', error)

! Write run info
    CALL writeH5RunInfo(file_id, time, sz_loc, iL, 'outputH5Beam', error)

! We make the limits
    CALL h5gcreate_f(file_id, limgrpname, group_id, error)
    CALL addH5StringAttribute(group_id,"vsType","limits",aspace_id)
    CALL addH5StringAttribute(group_id,"vsKind","Cartesian",aspace_id)
! end of scalars, need arrays (a vector) for the limits
    CALL h5sclose_f(aspace_id, error)

! And the limits themselves which require non-scalar attributes
! This is the 3D version.
    adims = (/numSpatialDims/)
    CALL h5screate_simple_f(arank, adims, aspace_id, error)
    aname="vsLowerBounds"
    CALL h5tcopy_f(H5T_NATIVE_DOUBLE, atype_id, error)
    CALL h5acreate_f(group_id, aname, atype_id, aspace_id, attr_id, error)
!    Print*,'hdf5_puff:outputH5BeamFiles(lower bounds attribute created)'
    ALLOCATE ( limdata(numSpatialDims))
    limdata(1)=-0.5*NX_G*sLengthOfElmX_G
! Particles inhabit a 3D physical space even for 1D simulations.
!    if (numSpatialDims .GT. 1) then
      limdata(2)=-0.5*NY_G*sLengthOfElmY_G
      limdata(3)=0.0
!    end if
    CALL h5awrite_f(attr_id, atype_id, limdata, adims, error)
    CALL h5aclose_f(attr_id, error)
    aname="vsUpperBounds"
    CALL h5acreate_f(group_id, aname, atype_id, aspace_id, attr_id, error)
    !Print*,'hdf5_puff:outputH5BeamFiles(upper bounds attribute created)'
    limdata(1)=0.5*NX_G*sLengthOfElmX_G
! Particles inhabit a 3D physical space even for 1D simulations.
!    if (numSpatialDims .GT. 1) then
      limdata(2)=0.5*NY_G*sLengthOfElmY_G
      limdata(3)=real((NZ2_G-1),kind=wp)*sLengthOfElmZ2_G
!    end if
    CALL h5awrite_f(attr_id, atype_id, limdata, adims, error)
! Close the attribute should be done above.
    CALL h5aclose_f(attr_id, error)
    DEALLOCATE ( limdata)
    CALL h5tclose_f(atype_id, error)
    CALL h5sclose_f(aspace_id, error)
    CALL h5gclose_f(group_id, error)

    aname="electrons_xSI"
    write(scaleToSIstring, '(E16.9)' ) (DSQRT(lg_G*lc_G))
    attr_data_string=("electrons_x*" // scaleToSIstring)
    attr_string_len=len(trim(adjustl(attr_data_string)))
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

! We make another group
    aname="electrons_ySI"
    attr_data_string=("electrons_y*" // scaleToSIstring)
    attr_string_len=len(trim(adjustl(attr_data_string)))
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

! We make another group
    aname="electrons_zSI"
    write(scaleToSIstring, '(E16.9)' ) lc_G
    attr_data_string=("electrons_z*" // scaleToSIstring)
    attr_string_len=len(trim(adjustl(attr_data_string)))
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)!
! Were there an SI version of this, we might be in the right place to use it

    aname="electrons_dxdzSI"
    write(scaleToSIstring, '(E16.9)' ) 2.0_wp * sRho_G * sKappa_G
    attr_data_string=("electrons_px*" // scaleToSIstring // "/electrons_gamma")
    attr_string_len=len(trim(adjustl(attr_data_string)))
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

    aname="electrons_dydzSI"
    write(scaleToSIstring, '(E16.9)' ) -2.0_wp * sRho_G * sKappa_G
    attr_data_string=("electrons_py*" // scaleToSIstring // "/electrons_gamma")
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

    aname="electrons_gammaSI"
    write(scaleToSIstring, '(E16.9)' ) sGammaR_G
    attr_data_string=("electrons_gamma*" // scaleToSIstring)
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

    aname="slice_nom_lamda"
! Todo: Actually needs to take account of slippage, and needs to identify
! which lamda was used (eg for 2 colour)
    write(scaleToSIstring, '(E16.9)' ) lam_r_G
    attr_data_string=("floor(electrons_zSI/" // scaleToSIstring // ")")
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

    aname="phi_lamda"
! Todo: Actually needs to take account of slippage, and needs to identify
! which lamda was used (eg for 2 colour)
    attr_data_string=("(electrons_zSI-(slice_nom_lamda*" // &
     scaleToSIstring // "))*6.283185307179586/" // scaleToSIstring)
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

    aname="electrons_numPhysicalParticles"
    write(scaleToSIstring, '(E16.9)' ) npk_bar_G
    attr_data_string=("electrons_weight*" // scaleToSIstring)
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

    aname="electrons_chargeSI"
    write(scaleToSIstring, '(E16.9)' ) npk_bar_G*q_e
    attr_data_string=("electrons_weight*" // scaleToSIstring)
    CALL addH5derivedVariable(file_id,aname,attr_data_string,error)

! Todo: write an expression for rms beam sizes
! Todo: write an expression for slice emittance

! Close the file.
    CALL h5fclose_f(file_id, error)

!Close the interface
    CALL h5close_f(error)

!    qOK = .true.
    goto 2000

!     Error Handler - Error log Subroutine in CIO.f90 line 709
1000 call Error_log('Error in hdf5_puff:outputBeamFiles',tErrorLog_G)
    print*,'Error in hdf5_puff:outputBeamFiles'
2000 continue
  end subroutine outputH5BeamFilesID

!> outputH5Field3DID is for writing the full field output.
!! This version dumps on each rank separately.
  subroutine outputH5Field3DID(time, sz_loc, iL, error, nlonglength, dsetname, rawdata, nlo, nhi, chkactiveflag)
    implicit none
    REAL(kind=WP), intent(in) :: time, sz_loc, rawdata(:) !< The data to write
    integer(kind=ip), intent(in) :: iL
    CHARACTER(*), intent(in) :: dsetname !< Dataset name
    INTEGER(kind=IP), intent(in) :: nlonglength !<number of cells in z in this section
    INTEGER(kind=IP), intent(in) :: nlo,nhi !< cell range in z in this raw data selection
    LOGICAL, intent(in) :: chkactiveflag !< flag determines whether to test for the entire field on every rank
    INTEGER(HID_T) :: file_id       !< File identifier
    INTEGER(HID_T) :: dset_id       !< Dataset identifier
    INTEGER(HID_T) :: dspace_id     !< Dataspace identifier in memory
    INTEGER(HID_T) :: filespace     !< Dataspace identifier in file
    INTEGER(HID_T) :: attr_id       !< Attribute identifier
    INTEGER(HID_T) :: aspace_id     !< Attribute Dataspace identifier
    INTEGER(HID_T) :: atype_id      !< Attribute Data type identifier
    INTEGER(HID_T) :: group_id      !< Group identifier
! may yet need this, but field data is not separated amongst cores
!    logical, intent(in) :: qSeparate
!    CHARACTER(LEN=5), PARAMETER :: dsetname = "aperp"     ! Dataset name
    CHARACTER(LEN=16) :: aname   ! Attribute name
!    character(1024_IP), intent(in) :: zDFName
    character(64_IP) :: filename
    INTEGER(HSIZE_T), DIMENSION(3) :: dims !<no longer includes component
! Data as component*reducedNX*reducedNY*reducedNZ2
! Not described as a parameter, so can prob modify
! for single component (rank 3 data) like charge
    INTEGER     ::   rank = 3               !< Dataset rank
    INTEGER(HSIZE_T), DIMENSION(1) :: adims !< Attribute dims
    REAL(kind=WP) :: attr_data_double       !< holder of attribute double data
    REAL(kind=WP), DIMENSION(3) :: ub       !< holder of attribute double data
    REAL(kind=WP), DIMENSION(3) :: lb       !< holder of attribute double data
    CHARACTER(LEN=100) :: attr_data_string  !< holder of attribute strings
    INTEGER(HSIZE_T) :: attr_string_len     !< length of attribute strings
    INTEGER(kind=IP) :: numSpatialDims      !< Attr content,
    INTEGER     ::  arank = 1               !< Attribute Dataset rank (1: vector)
    CHARACTER(LEN=4), PARAMETER :: timegrpname = "time"  !< Name of time group
    CHARACTER(LEN=12), PARAMETER :: limgrpname = "globalLimits"  !< Name of limits grp
    CHARACTER(LEN=10), PARAMETER :: meshScaledGrpname = "meshScaled" !< Name of mesh grp
    CHARACTER(LEN=6), PARAMETER :: meshSIGrpname = "meshSI"  !< Dummy scaled mesh grp name
    REAL(kind=WP), ALLOCATABLE :: limdata (:)  !< Data to write (diff for 1D and 3D)
    INTEGER(kind=IP), ALLOCATABLE :: numcelldata (:)  !< Mesh info for uniform grid
    ! Local vars
    integer :: error !< Error flag

! signature: nlonglength, dsetname, data, nlo, nhi, chkactiveflag
! tlflen, 'aperp_front_real', fr_rfield, [ffs,ffe], .false.
! tlflen, 'aperp_front_imag', fr_ifield, [ffs,ffe], .false.
! mainlen, 'aperp_active_real', ac_rfield, [fz2,ez2], .true.
! mainlen, 'aperp_active_imag', ac_ifield, [fz2,ez2], .true.
! tlelen, 'aperp_back_real', bk_rfield, [ees,eee], .false.
! tlelen, 'aperp_back_imag', bk_ifield, [ees,eee], .false.
! final argument  checks for all active field on single root node ...
! should say if qUnique or rank=0...

    if (qUnique .OR. (tProcInfo_G%qRoot)) then
    if (nlonglength.GT.0) then
    if (qONED_G) then
      numSpatialDims=1
      dims = (/1,1,nlonglength/) ! Dataset dimensions
    else
      numSpatialDims=3
      dims = (/nx_g,ny_g,nlonglength/) ! Dataset dimensions
    end if
!    print *,IntegerToString(size(fr_rfield)) // " vs " //trim(adjustl(IntegerToString(Nx_g*ny_g*nlonglength)))

!    Print*,('Spatialdims: ' // trim(IntegerToString(numSpatialDims)))
    filename = (trim(adjustl(zFilename_G)) // '_' // trim(adjustl(dsetname)) &
        // '_' // trim(adjustl(IntegerToString(tProcInfo_G%Rank))) &
        // '_' // trim(adjustl(IntegerToString(iStep))) // '.h5' )
      CALL h5open_f(error)
      CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, file_id, error)
      CALL h5screate_simple_f(rank, dims, filespace, error)
!      Print*,'hdf5_puff:outputH5FieldID(filespace created)'
      CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_DOUBLE, filespace, &
       dset_id, error)
!      Print*,'hdf5_puff:outputH5FieldID(dataset created)'
!      Print*,error
      CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, rawdata, dims, error)
!      Print*,'hdf5_puff:outputH5FieldID(write done)'
!      Print*,error
      CALL h5sclose_f(filespace, error)
!      Print*,'hdf5_puff:outputH5FieldID(filespace closed)'
!      Print*,error
      CALL h5screate_f(H5S_SCALAR_F, aspace_id, error)
!      Print*,'hdf5_puff:outputH5Field(scalar space created)'
!      CALL h5tcopy_f(H5T_NATIVE_DOUBLE, atype_id, error)

      call writeCommonAtts(dset_id, time, sz_loc, iL, aspace_id)

!      CALL addH5FloatAttribute(dset_id, "time", time,aspace_id)
!      CALL addH5FloatAttribute(dset_id, "zbarInter", time,aspace_id)
!      CALL addH5FloatAttribute(dset_id, "zInter", time*lg_G,aspace_id)
!
!      call addH5IntegerAttribute(dset_id, "iUnd_cr", iUnd_cr, aspace_id)
!      call addH5IntegerAttribute(dset_id, "iChic_cr", iChic_cr, aspace_id)
!      call addH5IntegerAttribute(dset_id, "iDrift_cr", iDrift_cr, aspace_id)
!      call addH5IntegerAttribute(dset_id, "iQuad_cr", iQuad_cr, aspace_id)
!      call addH5IntegerAttribute(dset_id, "iModulation_cr", iModulation_cr, aspace_id)
!      call addH5IntegerAttribute(dset_id, 'iL', iL, aspace_id)

!      CALL addH5FloatAttribute(dset_id, z, iStep*,aspace_id)
!      aname="time"
!      attr_data_double=time
!      CALL h5acreate_f(dset_id, aname, atype_id, aspace_id, attr_id, error)
!      CALL h5awrite_f(attr_id, atype_id, attr_data_double, adims, error)
!      CALL h5aclose_f(attr_id, error)
!      CALL h5tclose_f(atype_id, error)
      CALL addH5StringAttribute(dset_id,"vsLabels","aperp_front_realfield",aspace_id)
      CALL addH5StringAttribute(dset_id,"vsType","variable",aspace_id)
      CALL addH5StringAttribute(dset_id,"vsCentering","nodal",aspace_id)
      CALL addH5StringAttribute(dset_id,"vsIndexOrder","compMajorF",aspace_id)
      CALL addH5StringAttribute(dset_id,"vsTimeGroup",timegrpname,aspace_id)
      CALL addH5StringAttribute(dset_id,"vsLimits",limgrpname,aspace_id)
      CALL addH5StringAttribute(dset_id,"vsMesh",meshScaledGrpname,aspace_id)
      CALL addH5StringAttribute(dset_id,"vsAxisLabels","xbar,ybar,z2bar",aspace_id)
      CALL h5dclose_f(dset_id, error)
! Time Group
      CALL writeH5TimeGroup(file_id, timegrpname, time, &
	     'outH5Field3D', error)
      CALL writeH5RunInfo(file_id, time, sz_loc, iL, 'outH5Field3D', error)
      lb(1)=-0.5*NX_G*sLengthOfElmX_G
      lb(2)=-0.5*NY_G*sLengthOfElmY_G
      lb(3)=(nlo-1)*sLengthOfElmZ2_G
      ub(1)=0.5*NX_G*sLengthOfElmX_G
      ub(2)=0.5*NY_G*sLengthOfElmY_G
      ub(3)=nhi*sLengthOfElmZ2_G
      CALL write3DlimGrp(file_id,limgrpname,lb,ub)
      CALL write3DuniformMesh(file_id,meshScaledGrpname,lb,ub,(/nx_g,ny_g,nlonglength/))
      CALL h5fclose_f(file_id, error)
    end if
   end if
  end subroutine outputH5Field3DID

end module hdf5PuffID


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!  This file is AUTOMATICALLY GENERATED by:
!!  ../tools/fortran_wrappers.pl ../include/magma_d.i
!!  Do not edit.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

module magma_dfortran

use magma_param

implicit none

!---- Fortran interfaces to MAGMA subroutines ----
interface

subroutine magmaf_get_dlaex3_m_nb(  )
end subroutine magmaf_get_dlaex3_m_nb

integer function magmaf_get_dpotrf_nb( m )
    integer :: m
end function magmaf_get_dpotrf_nb

integer function magmaf_get_dgetrf_nb( m )
    integer :: m
end function magmaf_get_dgetrf_nb

integer function magmaf_get_dgetri_nb( m )
    integer :: m
end function magmaf_get_dgetri_nb

integer function magmaf_get_dgeqp3_nb( m )
    integer :: m
end function magmaf_get_dgeqp3_nb

integer function magmaf_get_dgeqrf_nb( m )
    integer :: m
end function magmaf_get_dgeqrf_nb

integer function magmaf_get_dgeqlf_nb( m )
    integer :: m
end function magmaf_get_dgeqlf_nb

integer function magmaf_get_dgehrd_nb( m )
    integer :: m
end function magmaf_get_dgehrd_nb

integer function magmaf_get_dsytrd_nb( m )
    integer :: m
end function magmaf_get_dsytrd_nb

integer function magmaf_get_dsytrf_nb( m )
    integer :: m
end function magmaf_get_dsytrf_nb

integer function magmaf_get_dsytrf_nopiv_nb( m )
    integer :: m
end function magmaf_get_dsytrf_nopiv_nb

integer function magmaf_get_dgelqf_nb( m )
    integer :: m
end function magmaf_get_dgelqf_nb

integer function magmaf_get_dgebrd_nb( m )
    integer :: m
end function magmaf_get_dgebrd_nb

integer function magmaf_get_dsygst_nb( m )
    integer :: m
end function magmaf_get_dsygst_nb

integer function magmaf_get_dgesvd_nb( m )
    integer :: m
end function magmaf_get_dgesvd_nb

integer function magmaf_get_dsygst_nb_m( m )
    integer :: m
end function magmaf_get_dsygst_nb_m

subroutine magmaf_get_dbulge_nb( m, nbthreads )
    integer          :: m
    integer          :: nbthreads
end subroutine magmaf_get_dbulge_nb

subroutine magmaf_dbulge_get_Vblksiz( m, nb, nbthreads )
    integer          :: m
    integer          :: nb
    integer          :: nbthreads
end subroutine magmaf_dbulge_get_Vblksiz

subroutine magmaf_get_dbulge_gcperf(  )
end subroutine magmaf_get_dbulge_gcperf

subroutine magmaf_dmove_eig( range, n, w, il, iu, vl, vu, m )
    character        :: range
    integer          :: n
    double precision :: w(*)
    integer          :: il(*)
    integer          :: iu(*)
    double precision :: vl
    double precision :: vu
    integer          :: m
end subroutine magmaf_dmove_eig

subroutine magmaf_dvrange( k, d, il, iu, vl, vu )
    integer          :: k
    double precision :: d(*)
    integer          :: il(*)
    integer          :: iu(*)
    double precision :: vl
    double precision :: vu
end subroutine magmaf_dvrange

subroutine magmaf_dirange( k, indxq, iil, iiu, il, iu )
    integer          :: k
    integer          :: indxq(*)
    integer          :: iil(*)
    integer          :: iiu(*)
    integer          :: il
    integer          :: iu
end subroutine magmaf_dirange

subroutine magmaf_dgebrd( m, n, A, lda, d, e, tauq, taup, work, lwork, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: d(*)
    double precision :: e(*)
    double precision :: tauq(*)
    double precision :: taup(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgebrd

subroutine magmaf_dgeev( jobvl, jobvr, n, A, lda, wr, wi, VL, ldvl, VR, ldvr, work,  &
        lwork, info )
    character        :: jobvl
    character        :: jobvr
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: wr(*)
    double precision :: wi(*)
    double precision :: VL(*)
    integer          :: ldvl
    double precision :: VR(*)
    integer          :: ldvr
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeev

subroutine magmaf_dgehrd( n, ilo, ihi, A, lda, tau, work, lwork, dT, info )
    integer          :: n
    integer          :: ilo
    integer          :: ihi
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    magma_devptr_t   :: dT
    integer          :: info
end subroutine magmaf_dgehrd

subroutine magmaf_dgehrd2( n, ilo, ihi, A, lda, tau, work, lwork, info )
    integer          :: n
    integer          :: ilo
    integer          :: ihi
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgehrd2

subroutine magmaf_dgelqf( m, n, A, lda, tau, work, lwork, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgelqf

subroutine magmaf_dgeqlf( m, n, A, lda, tau, work, lwork, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqlf

subroutine magmaf_dgeqp3( m, n, A, lda, jpvt, tau, work, lwork, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: jpvt(*)
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqp3

subroutine magmaf_dgeqrf( m, n, A, lda, tau, work, lwork, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqrf

subroutine magmaf_dgeqrf_ooc( m, n, A, lda, tau, work, lwork, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqrf_ooc

subroutine magmaf_dgeqrf4( ngpu, m, n, A, lda, tau, work, lwork, info )
    integer          :: ngpu
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqrf4

subroutine magmaf_dgesdd( jobz, m, n, A, lda, s, U, ldu, VT, ldvt, work, lwork, iwork,  &
        info )
    character        :: jobz
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: s(*)
    double precision :: U(*)
    integer          :: ldu
    double precision :: VT(*)
    integer          :: ldvt
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: info
end subroutine magmaf_dgesdd

subroutine magmaf_dgesv( n, nrhs, A, lda, ipiv, B, ldb, info )
    integer          :: n
    integer          :: nrhs
    double precision :: A(*)
    integer          :: lda
    integer          :: ipiv(*)
    double precision :: B(*)
    integer          :: ldb
    integer          :: info
end subroutine magmaf_dgesv

subroutine magmaf_dgesv_rbt( ref, n, nrhs, A, lda, B, ldb, info )
    character        :: ref
    integer          :: n
    integer          :: nrhs
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    integer          :: info
end subroutine magmaf_dgesv_rbt

subroutine magmaf_dgesvd( jobu, jobvt, m, n, A, lda, s, U, ldu, VT, ldvt, work, lwork,  &
        info )
    character        :: jobu
    character        :: jobvt
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: s(*)
    double precision :: U(*)
    integer          :: ldu
    double precision :: VT(*)
    integer          :: ldvt
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgesvd

subroutine magmaf_dgetf2_nopiv( m, n, A, lda, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dgetf2_nopiv

subroutine magmaf_dgetrf( m, n, A, lda, ipiv, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: ipiv(*)
    integer          :: info
end subroutine magmaf_dgetrf

subroutine magmaf_dgetrf_nopiv( m, n, A, lda, info )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dgetrf_nopiv

subroutine magmaf_dgetrf_piv( m, n, NB, A, lda, ipiv, info )
    integer          :: m
    integer          :: n
    integer          :: NB
    double precision :: A(*)
    integer          :: lda
    integer          :: ipiv(*)
    integer          :: info
end subroutine magmaf_dgetrf_piv

subroutine magmaf_dsyevd( jobz, uplo, n, A, lda, w, work, lwork, iwork, liwork, info )
    character        :: jobz
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevd

subroutine magmaf_dsyevdx( jobz, range, uplo, n, A, lda, vl, vu, il, iu, m, w, work,  &
        lwork, iwork, liwork, info )
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevdx

subroutine magmaf_dsyevdx_2stage( jobz, range, uplo, n, A, lda, vl, vu, il, iu, m, w,  &
        work, lwork, iwork, liwork, info )
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevdx_2stage

subroutine magmaf_dsygst( itype, uplo, n, A, lda, B, ldb, info )
    integer          :: itype
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    integer          :: info
end subroutine magmaf_dsygst

subroutine magmaf_dsygvd( itype, jobz, uplo, n, A, lda, B, ldb, w, work, lwork, iwork,  &
        liwork, info )
    integer          :: itype
    character        :: jobz
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsygvd

subroutine magmaf_dsygvdx( itype, jobz, range, uplo, n, A, lda, B, ldb, vl, vu, il, iu,  &
        m, w, work, lwork, iwork, liwork, info )
    integer          :: itype
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsygvdx

subroutine magmaf_dsygvdx_2stage( itype, jobz, range, uplo, n, A, lda, B, ldb, vl, vu,  &
        il, iu, m, w, work, lwork, iwork, liwork, info )
    integer          :: itype
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsygvdx_2stage

subroutine magmaf_dsysv( uplo, n, nrhs, A, lda, ipiv, B, ldb, info )
    character        :: uplo
    integer          :: n
    integer          :: nrhs
    double precision :: A(*)
    integer          :: lda
    integer          :: ipiv(*)
    double precision :: B(*)
    integer          :: ldb
    integer          :: info
end subroutine magmaf_dsysv

subroutine magmaf_dsytrd( uplo, n, A, lda, d, e, tau, work, lwork, info )
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: d(*)
    double precision :: e(*)
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dsytrd

subroutine magmaf_dsytrf( uplo, n, A, lda, ipiv, info )
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: ipiv(*)
    integer          :: info
end subroutine magmaf_dsytrf

subroutine magmaf_dsytrf_nopiv( uplo, n, a, lda, info )
    character        :: uplo
    integer          :: n
    double precision :: a(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dsytrf_nopiv

subroutine magmaf_dsytrd_sb2st( uplo, n, nb, Vblksiz, A, lda, d, e, V, ldv, TAU, compT,  &
        T, ldt )
    character        :: uplo
    integer          :: n
    integer          :: nb
    integer          :: Vblksiz
    double precision :: A(*)
    integer          :: lda
    double precision :: d(*)
    double precision :: e(*)
    double precision :: V(*)
    integer          :: ldv
    double precision :: TAU(*)
    integer          :: compT
    double precision :: T(*)
    integer          :: ldt
end subroutine magmaf_dsytrd_sb2st

subroutine magmaf_dsytrd_sy2sb( uplo, n, nb, A, lda, tau, work, lwork, dT, info )
    character        :: uplo
    integer          :: n
    integer          :: nb
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    magma_devptr_t   :: dT
    integer          :: info
end subroutine magmaf_dsytrd_sy2sb

subroutine magmaf_dlaln2( trans, na, nw, smin, ca, A, lda, d1, d2, B, ldb, wr, wi, X,  &
        ldx, scale, xnorm, info )
    integer          :: trans
    integer          :: na
    integer          :: nw
    double precision :: smin
    double precision :: ca
    double precision :: A(*)
    integer          :: lda
    double precision :: d1
    double precision :: d2
    double precision :: B(*)
    integer          :: ldb
    double precision :: wr
    double precision :: wi
    double precision :: X(*)
    integer          :: ldx
    double precision :: scale(*)
    double precision :: xnorm(*)
    integer          :: info
end subroutine magmaf_dlaln2

subroutine magmaf_dlaqtrsd( trans, n, T, ldt, x, ldx, cnorm, info )
    character        :: trans
    integer          :: n
    double precision :: T(*)
    integer          :: ldt
    double precision :: x(*)
    integer          :: ldx
    double precision :: cnorm(*)
    integer          :: info
end subroutine magmaf_dlaqtrsd

subroutine magmaf_dlauum( uplo, n, A, lda, info )
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dlauum

subroutine magmaf_dposv( uplo, n, nrhs, A, lda, B, ldb, info )
    character        :: uplo
    integer          :: n
    integer          :: nrhs
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    integer          :: info
end subroutine magmaf_dposv

subroutine magmaf_dpotrf( uplo, n, A, lda, info )
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dpotrf

subroutine magmaf_dpotri( uplo, n, A, lda, info )
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dpotri

subroutine magmaf_dstedx( range, n, vl, vu, il, iu, d, e, Z, ldz, rwork, lrwork, iwork,  &
        liwork, dwork, info )
    character        :: range
    integer          :: n
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    double precision :: d(*)
    double precision :: e(*)
    double precision :: Z(*)
    integer          :: ldz
    double precision :: rwork(*)
    integer          :: lrwork
    integer          :: iwork(*)
    integer          :: liwork
    magma_devptr_t   :: dwork
    integer          :: info
end subroutine magmaf_dstedx

subroutine magmaf_dtrevc3( side, howmany, select, n, T, ldt, VL, ldvl, VR, ldvr, mm,  &
        mout, work, lwork, info )
    character        :: side
    character        :: howmany
    integer          :: select(*)
    integer          :: n
    double precision :: T(*)
    integer          :: ldt
    double precision :: VL(*)
    integer          :: ldvl
    double precision :: VR(*)
    integer          :: ldvr
    integer          :: mm
    integer          :: mout(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dtrevc3

subroutine magmaf_dtrevc3_mt( side, howmany, select, n, T, ldt, VL, ldvl, VR, ldvr, mm,  &
        mout, work, lwork, info )
    character        :: side
    character        :: howmany
    integer          :: select(*)
    integer          :: n
    double precision :: T(*)
    integer          :: ldt
    double precision :: VL(*)
    integer          :: ldvl
    double precision :: VR(*)
    integer          :: ldvr
    integer          :: mm
    integer          :: mout(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dtrevc3_mt

subroutine magmaf_dtrtri( uplo, diag, n, A, lda, info )
    character        :: uplo
    character        :: diag
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dtrtri

subroutine magmaf_dorghr( n, ilo, ihi, A, lda, tau, dT, nb, info )
    integer          :: n
    integer          :: ilo
    integer          :: ihi
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    magma_devptr_t   :: dT
    integer          :: nb
    integer          :: info
end subroutine magmaf_dorghr

subroutine magmaf_dorgqr( m, n, k, A, lda, tau, dT, nb, info )
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    magma_devptr_t   :: dT
    integer          :: nb
    integer          :: info
end subroutine magmaf_dorgqr

subroutine magmaf_dorgqr2( m, n, k, A, lda, tau, info )
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    integer          :: info
end subroutine magmaf_dorgqr2

subroutine magmaf_dormbr( vect, side, trans, m, n, k, A, lda, tau, C, ldc, work, lwork,  &
        info )
    character        :: vect
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: C(*)
    integer          :: ldc
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dormbr

subroutine magmaf_dormlq( side, trans, m, n, k, A, lda, tau, C, ldc, work, lwork, info )
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: C(*)
    integer          :: ldc
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dormlq

subroutine magmaf_dormql( side, trans, m, n, k, A, lda, tau, C, ldc, work, lwork, info )
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: C(*)
    integer          :: ldc
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dormql

subroutine magmaf_dormqr( side, trans, m, n, k, A, lda, tau, C, ldc, work, lwork, info )
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: C(*)
    integer          :: ldc
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dormqr

subroutine magmaf_dormtr( side, uplo, trans, m, n, A, lda, tau, C, ldc, work, lwork, info  &
        )
    character        :: side
    character        :: uplo
    character        :: trans
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: C(*)
    integer          :: ldc
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dormtr

subroutine magmaf_dgeev_m( jobvl, jobvr, n, A, lda, wr, wi, VL, ldvl, VR, ldvr, work,  &
        lwork, info )
    character        :: jobvl
    character        :: jobvr
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: wr(*)
    double precision :: wi(*)
    double precision :: VL(*)
    integer          :: ldvl
    double precision :: VR(*)
    integer          :: ldvr
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeev_m

subroutine magmaf_dgehrd_m( n, ilo, ihi, A, lda, tau, work, lwork, T, info )
    integer          :: n
    integer          :: ilo
    integer          :: ihi
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    double precision :: T(*)
    integer          :: info
end subroutine magmaf_dgehrd_m

subroutine magmaf_dgetrf_m( ngpu, m, n, A, lda, ipiv, info )
    integer          :: ngpu
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: ipiv(*)
    integer          :: info
end subroutine magmaf_dgetrf_m

subroutine magmaf_dsyevd_m( ngpu, jobz, uplo, n, A, lda, w, work, lwork, iwork, liwork,  &
        info )
    integer          :: ngpu
    character        :: jobz
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevd_m

subroutine magmaf_dsyevdx_2stage_m( ngpu, jobz, range, uplo, n, A, lda, vl, vu, il, iu,  &
        m, w, work, lwork, iwork, liwork, info )
    integer          :: ngpu
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevdx_2stage_m

subroutine magmaf_dsyevdx_m( ngpu, jobz, range, uplo, n, A, lda, vl, vu, il, iu, m, w,  &
        work, lwork, iwork, liwork, info )
    integer          :: ngpu
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevdx_m

subroutine magmaf_dsygst_m( ngpu, itype, uplo, n, A, lda, B, ldb, info )
    integer          :: ngpu
    integer          :: itype
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    integer          :: info
end subroutine magmaf_dsygst_m

subroutine magmaf_dsygvd_m( ngpu, itype, jobz, uplo, n, A, lda, B, ldb, w, work, lwork,  &
        iwork, liwork, info )
    integer          :: ngpu
    integer          :: itype
    character        :: jobz
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsygvd_m

subroutine magmaf_dsygvdx_2stage_m( ngpu, itype, jobz, range, uplo, n, A, lda, B, ldb,  &
        vl, vu, il, iu, m, w, work, lwork, iwork, liwork, info )
    integer          :: ngpu
    integer          :: itype
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsygvdx_2stage_m

subroutine magmaf_dsygvdx_m( ngpu, itype, jobz, range, uplo, n, A, lda, B, ldb, vl, vu,  &
        il, iu, m, w, work, lwork, iwork, liwork, info )
    integer          :: ngpu
    integer          :: itype
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsygvdx_m

subroutine magmaf_dpotrf_m( ngpu, uplo, n, A, lda, info )
    integer          :: ngpu
    character        :: uplo
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: info
end subroutine magmaf_dpotrf_m

subroutine magmaf_dstedx_m( ngpu, range, n, vl, vu, il, iu, d, e, Z, ldz, rwork, lrwork,  &
        iwork, liwork, info )
    integer          :: ngpu
    character        :: range
    integer          :: n
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    double precision :: d(*)
    double precision :: e(*)
    double precision :: Z(*)
    integer          :: ldz
    double precision :: rwork(*)
    integer          :: lrwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dstedx_m

subroutine magmaf_dtrsm_m( ngpu, side, uplo, transa, diag, m, n, alpha, A, lda, B, ldb )
    integer          :: ngpu
    character        :: side
    character        :: uplo
    character        :: transa
    character        :: diag
    integer          :: m
    integer          :: n
    double precision :: alpha
    double precision :: A(*)
    integer          :: lda
    double precision :: B(*)
    integer          :: ldb
end subroutine magmaf_dtrsm_m

subroutine magmaf_dorghr_m( n, ilo, ihi, A, lda, tau, T, nb, info )
    integer          :: n
    integer          :: ilo
    integer          :: ihi
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: T(*)
    integer          :: nb
    integer          :: info
end subroutine magmaf_dorghr_m

subroutine magmaf_dorgqr_m( m, n, k, A, lda, tau, T, nb, info )
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: T(*)
    integer          :: nb
    integer          :: info
end subroutine magmaf_dorgqr_m

subroutine magmaf_dormqr_m( ngpu, side, trans, m, n, k, A, lda, tau, C, ldc, work, lwork,  &
        info )
    integer          :: ngpu
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: C(*)
    integer          :: ldc
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dormqr_m

subroutine magmaf_dormtr_m( ngpu, side, uplo, trans, m, n, A, lda, tau, C, ldc, work,  &
        lwork, info )
    integer          :: ngpu
    character        :: side
    character        :: uplo
    character        :: trans
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    double precision :: tau(*)
    double precision :: C(*)
    integer          :: ldc
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dormtr_m

subroutine magmaf_dgegqr_gpu( ikind, m, n, dA, ldda, dwork, work, info )
    integer          :: ikind
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dwork
    double precision :: work(*)
    integer          :: info
end subroutine magmaf_dgegqr_gpu

subroutine magmaf_dgelqf_gpu( m, n, dA, ldda, tau, work, lwork, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgelqf_gpu

subroutine magmaf_dgels_gpu( trans, m, n, nrhs, dA, ldda, dB, lddb, hwork, lwork, info )
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    double precision :: hwork(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgels_gpu

subroutine magmaf_dgels3_gpu( trans, m, n, nrhs, dA, ldda, dB, lddb, hwork, lwork, info )
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    double precision :: hwork(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgels3_gpu

subroutine magmaf_dgeqp3_gpu( m, n, dA, ldda, jpvt, tau, dwork, lwork, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: jpvt(*)
    double precision :: tau(*)
    magma_devptr_t   :: dwork
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqp3_gpu

subroutine magmaf_dgeqr2x_gpu( m, n, dA, ldda, dtau, dT, ddA, dwork, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dtau
    magma_devptr_t   :: dT
    magma_devptr_t   :: ddA
    magma_devptr_t   :: dwork
    integer          :: info
end subroutine magmaf_dgeqr2x_gpu

subroutine magmaf_dgeqr2x2_gpu( m, n, dA, ldda, dtau, dT, ddA, dwork, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dtau
    magma_devptr_t   :: dT
    magma_devptr_t   :: ddA
    magma_devptr_t   :: dwork
    integer          :: info
end subroutine magmaf_dgeqr2x2_gpu

subroutine magmaf_dgeqr2x3_gpu( m, n, dA, ldda, dtau, dT, ddA, dwork, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dtau
    magma_devptr_t   :: dT
    magma_devptr_t   :: ddA
    magma_devptr_t   :: dwork
    integer          :: info
end subroutine magmaf_dgeqr2x3_gpu

subroutine magmaf_dgeqr2x4_gpu( m, n, dA, ldda, dtau, dT, ddA, dwork, queue, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dtau
    magma_devptr_t   :: dT
    magma_devptr_t   :: ddA
    magma_devptr_t   :: dwork
    integer          :: queue
    integer          :: info
end subroutine magmaf_dgeqr2x4_gpu

subroutine magmaf_dgeqrf_gpu( m, n, dA, ldda, tau, dT, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dT
    integer          :: info
end subroutine magmaf_dgeqrf_gpu

subroutine magmaf_dgeqrf2_gpu( m, n, dA, ldda, tau, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    integer          :: info
end subroutine magmaf_dgeqrf2_gpu

subroutine magmaf_dgeqrf3_gpu( m, n, dA, ldda, tau, dT, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dT
    integer          :: info
end subroutine magmaf_dgeqrf3_gpu

subroutine magmaf_dgeqrs_gpu( m, n, nrhs, dA, ldda, tau, dT, dB, lddb, hwork, lwork, info  &
        )
    integer          :: m
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dT
    magma_devptr_t   :: dB
    integer          :: lddb
    double precision :: hwork(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqrs_gpu

subroutine magmaf_dgeqrs3_gpu( m, n, nrhs, dA, ldda, tau, dT, dB, lddb, hwork, lwork,  &
        info )
    integer          :: m
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dT
    magma_devptr_t   :: dB
    integer          :: lddb
    double precision :: hwork(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgeqrs3_gpu

subroutine magmaf_dgerbt_gpu( gen, n, nrhs, dA, ldda, dB, lddb, U, V, info )
    character        :: gen
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    double precision :: U(*)
    double precision :: V(*)
    integer          :: info
end subroutine magmaf_dgerbt_gpu

subroutine magmaf_dgessm_gpu( order, m, n, k, ib, ipiv, dL1, lddl1, dL, lddl, dA, ldda,  &
        info )
    character        :: order
    integer          :: m
    integer          :: n
    integer          :: k
    integer          :: ib
    integer          :: ipiv(*)
    magma_devptr_t   :: dL1
    integer          :: lddl1
    magma_devptr_t   :: dL
    integer          :: lddl
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dgessm_gpu

subroutine magmaf_dgesv_gpu( n, nrhs, dA, ldda, ipiv, dB, lddb, info )
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: ipiv(*)
    magma_devptr_t   :: dB
    integer          :: lddb
    integer          :: info
end subroutine magmaf_dgesv_gpu

subroutine magmaf_dgesv_nopiv_gpu( n, nrhs, dA, ldda, dB, lddb, info )
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    integer          :: info
end subroutine magmaf_dgesv_nopiv_gpu

subroutine magmaf_dgetf2_gpu( m, n, dA, ldda, ipiv, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: ipiv(*)
    integer          :: info
end subroutine magmaf_dgetf2_gpu

subroutine magmaf_dgetrf_gpu( m, n, dA, ldda, ipiv, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: ipiv(*)
    integer          :: info
end subroutine magmaf_dgetrf_gpu

subroutine magmaf_dgetrf_nopiv_gpu( m, n, dA, ldda, info )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dgetrf_nopiv_gpu

subroutine magmaf_dgetri_gpu( n, dA, ldda, ipiv, dwork, lwork, info )
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: ipiv(*)
    magma_devptr_t   :: dwork
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dgetri_gpu

subroutine magmaf_dgetrs_gpu( trans, n, nrhs, dA, ldda, ipiv, dB, lddb, info )
    character        :: trans
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: ipiv(*)
    magma_devptr_t   :: dB
    integer          :: lddb
    integer          :: info
end subroutine magmaf_dgetrs_gpu

subroutine magmaf_dgetrs_nopiv_gpu( trans, n, nrhs, dA, ldda, dB, lddb, info )
    character        :: trans
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    integer          :: info
end subroutine magmaf_dgetrs_nopiv_gpu

subroutine magmaf_dsyevd_gpu( jobz, uplo, n, dA, ldda, w, wA, ldwa, work, lwork, iwork,  &
        liwork, info )
    character        :: jobz
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: w(*)
    double precision :: wA(*)
    integer          :: ldwa
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevd_gpu

subroutine magmaf_dsyevdx_gpu( jobz, range, uplo, n, dA, ldda, vl, vu, il, iu, m, w, wA,  &
        ldwa, work, lwork, iwork, liwork, info )
    character        :: jobz
    character        :: range
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: vl
    double precision :: vu
    integer          :: il
    integer          :: iu
    integer          :: m
    double precision :: w(*)
    double precision :: wA(*)
    integer          :: ldwa
    double precision :: work(*)
    integer          :: lwork
    integer          :: iwork(*)
    integer          :: liwork
    integer          :: info
end subroutine magmaf_dsyevdx_gpu

subroutine magmaf_dsygst_gpu( itype, uplo, n, dA, ldda, dB, lddb, info )
    integer          :: itype
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    integer          :: info
end subroutine magmaf_dsygst_gpu

subroutine magmaf_dsytrd_gpu( uplo, n, dA, ldda, d, e, tau, wA, ldwa, work, lwork, info )
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: d(*)
    double precision :: e(*)
    double precision :: tau(*)
    double precision :: wA(*)
    integer          :: ldwa
    double precision :: work(*)
    integer          :: lwork
    integer          :: info
end subroutine magmaf_dsytrd_gpu

subroutine magmaf_dsytrd2_gpu( uplo, n, dA, ldda, d, e, tau, wA, ldwa, work, lwork,  &
        dwork, ldwork, info )
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: d(*)
    double precision :: e(*)
    double precision :: tau(*)
    double precision :: wA(*)
    integer          :: ldwa
    double precision :: work(*)
    integer          :: lwork
    magma_devptr_t   :: dwork
    integer          :: ldwork
    integer          :: info
end subroutine magmaf_dsytrd2_gpu

subroutine magmaf_dsytrf_nopiv_gpu( uplo, n, da, ldda, info )
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: da
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dsytrf_nopiv_gpu

subroutine magmaf_dlarf_gpu( m, n, dv, dtau, dC, lddc )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dv
    magma_devptr_t   :: dtau
    magma_devptr_t   :: dC
    integer          :: lddc
end subroutine magmaf_dlarf_gpu

subroutine magmaf_dlarfb_gpu( side, trans, direct, storev, m, n, k, dV, lddv, dT, lddt,  &
        dC, lddc, dwork, ldwork )
    character        :: side
    character        :: trans
    character        :: direct
    character        :: storev
    integer          :: m
    integer          :: n
    integer          :: k
    magma_devptr_t   :: dV
    integer          :: lddv
    magma_devptr_t   :: dT
    integer          :: lddt
    magma_devptr_t   :: dC
    integer          :: lddc
    magma_devptr_t   :: dwork
    integer          :: ldwork
end subroutine magmaf_dlarfb_gpu

subroutine magmaf_dlarfb_gpu_gemm( side, trans, direct, storev, m, n, k, dV, lddv, dT,  &
        lddt, dC, lddc, dwork, ldwork, dworkvt, ldworkvt )
    character        :: side
    character        :: trans
    character        :: direct
    character        :: storev
    integer          :: m
    integer          :: n
    integer          :: k
    magma_devptr_t   :: dV
    integer          :: lddv
    magma_devptr_t   :: dT
    integer          :: lddt
    magma_devptr_t   :: dC
    integer          :: lddc
    magma_devptr_t   :: dwork
    integer          :: ldwork
    magma_devptr_t   :: dworkvt
    integer          :: ldworkvt
end subroutine magmaf_dlarfb_gpu_gemm

subroutine magmaf_dlarfb2_gpu( m, n, k, dV, lddv, dT, lddt, dC, lddc, dwork, ldwork )
    integer          :: m
    integer          :: n
    integer          :: k
    magma_devptr_t   :: dV
    integer          :: lddv
    magma_devptr_t   :: dT
    integer          :: lddt
    magma_devptr_t   :: dC
    integer          :: lddc
    magma_devptr_t   :: dwork
    integer          :: ldwork
end subroutine magmaf_dlarfb2_gpu

subroutine magmaf_dlauum_gpu( uplo, n, dA, ldda, info )
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dlauum_gpu

subroutine magmaf_dposv_gpu( uplo, n, nrhs, dA, ldda, dB, lddb, info )
    character        :: uplo
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    integer          :: info
end subroutine magmaf_dposv_gpu

subroutine magmaf_dpotf2_gpu( uplo, n, dA, ldda, info )
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dpotf2_gpu

subroutine magmaf_dpotrf_gpu( uplo, n, dA, ldda, info )
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dpotrf_gpu

subroutine magmaf_dpotri_gpu( uplo, n, dA, ldda, info )
    character        :: uplo
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dpotri_gpu

subroutine magmaf_dpotrs_gpu( uplo, n, nrhs, dA, ldda, dB, lddb, info )
    character        :: uplo
    integer          :: n
    integer          :: nrhs
    magma_devptr_t   :: dA
    integer          :: ldda
    magma_devptr_t   :: dB
    integer          :: lddb
    integer          :: info
end subroutine magmaf_dpotrs_gpu

subroutine magmaf_dssssm_gpu( order, m1, n1, m2, n2, k, ib, dA1, ldda1, dA2, ldda2, dL1,  &
        lddl1, dL2, lddl2, ipiv, info )
    character        :: order
    integer          :: m1
    integer          :: n1
    integer          :: m2
    integer          :: n2
    integer          :: k
    integer          :: ib
    magma_devptr_t   :: dA1
    integer          :: ldda1
    magma_devptr_t   :: dA2
    integer          :: ldda2
    magma_devptr_t   :: dL1
    integer          :: lddl1
    magma_devptr_t   :: dL2
    integer          :: lddl2
    integer          :: ipiv(*)
    integer          :: info
end subroutine magmaf_dssssm_gpu

subroutine magmaf_dtrtri_gpu( uplo, diag, n, dA, ldda, info )
    character        :: uplo
    character        :: diag
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: info
end subroutine magmaf_dtrtri_gpu

subroutine magmaf_dorgqr_gpu( m, n, k, dA, ldda, tau, dT, nb, info )
    integer          :: m
    integer          :: n
    integer          :: k
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dT
    integer          :: nb
    integer          :: info
end subroutine magmaf_dorgqr_gpu

subroutine magmaf_dormql2_gpu( side, trans, m, n, k, dA, ldda, tau, dC, lddc, wA, ldwa,  &
        info )
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dC
    integer          :: lddc
    double precision :: wA(*)
    integer          :: ldwa
    integer          :: info
end subroutine magmaf_dormql2_gpu

subroutine magmaf_dormqr_gpu( side, trans, m, n, k, dA, ldda, tau, dC, lddc, hwork,  &
        lwork, dT, nb, info )
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dC
    integer          :: lddc
    double precision :: hwork(*)
    integer          :: lwork
    magma_devptr_t   :: dT
    integer          :: nb
    integer          :: info
end subroutine magmaf_dormqr_gpu

subroutine magmaf_dormqr2_gpu( side, trans, m, n, k, dA, ldda, tau, dC, lddc, wA, ldwa,  &
        info )
    character        :: side
    character        :: trans
    integer          :: m
    integer          :: n
    integer          :: k
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dC
    integer          :: lddc
    double precision :: wA(*)
    integer          :: ldwa
    integer          :: info
end subroutine magmaf_dormqr2_gpu

subroutine magmaf_dormtr_gpu( side, uplo, trans, m, n, dA, ldda, tau, dC, lddc, wA, ldwa,  &
        info )
    character        :: side
    character        :: uplo
    character        :: trans
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    double precision :: tau(*)
    magma_devptr_t   :: dC
    integer          :: lddc
    double precision :: wA(*)
    integer          :: ldwa
    integer          :: info
end subroutine magmaf_dormtr_gpu

subroutine magmaf_dnan_inf( uplo, m, n, A, lda, cnt_nan, cnt_inf )
    character        :: uplo
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
    integer          :: cnt_nan(*)
    integer          :: cnt_inf(*)
end subroutine magmaf_dnan_inf

subroutine magmaf_dnan_inf_gpu( uplo, m, n, dA, ldda, cnt_nan, cnt_inf )
    character        :: uplo
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
    integer          :: cnt_nan(*)
    integer          :: cnt_inf(*)
end subroutine magmaf_dnan_inf_gpu

subroutine magmaf_dprint( m, n, A, lda )
    integer          :: m
    integer          :: n
    double precision :: A(*)
    integer          :: lda
end subroutine magmaf_dprint

subroutine magmaf_dprint_gpu( m, n, dA, ldda )
    integer          :: m
    integer          :: n
    magma_devptr_t   :: dA
    integer          :: ldda
end subroutine magmaf_dprint_gpu

end interface

!---- Fortran-only subroutines (see ../tools/fortran_wrappers.pl to edit) ----
contains

subroutine magmaf_doff1d( ptrNew, ptrOld, inc, i)
    magma_devptr_t   :: ptrNew
    magma_devptr_t   :: ptrOld
    integer          :: inc, i

    ptrNew = ptrOld + (i-1) * inc * sizeof_double
end subroutine magmaf_doff1d

subroutine magmaf_doff2d( ptrNew, ptrOld, lda, i, j)
    magma_devptr_t   :: ptrNew
    magma_devptr_t   :: ptrOld
    integer          :: lda, i, j

    ptrNew = ptrOld + ((j-1) * lda + (i-1)) * sizeof_double
end subroutine magmaf_doff2d

end module magma_dfortran