program greg

	use iso_c_binding
	implicit none
	
	interface
		subroutine turn_magma_on() bind(c,name='magma_init')
		end subroutine turn_magma_on

		subroutine host_allocate(a,b) bind(c,name='magma_malloc_pinned')
			import :: c_ptr
			import :: c_int
			import :: c_double

			type(c_ptr) :: a(*)
			integer(c_int), value :: b


		end subroutine

		subroutine dsyevd(jobz, uplo, ny, a, lda, evals, work, lwork, iwork, liwork, info) bind(c,name='magma_dsyevd')

			import :: c_char
			import :: c_int
			import :: c_ptr
			import :: c_double

			integer(c_int), value 	:: jobz
			integer(c_int), value 	:: uplo
			integer(c_int), value   :: ny
			real(c_double)       	:: a(*)
			integer(c_int), value   :: lda
			real(c_double)         	:: evals(*)
			real(c_double)        	:: work(*)
			integer(c_int), value   :: lwork
			real(c_double)     	:: iwork(*)
			integer(c_int), value   :: liwork
			integer(c_int)	 	:: info     	

		end subroutine dsyevd	
	end interface

	integer :: jobz
	integer :: uplo
	integer :: ny
	real(8), allocatable, target :: a(:)
	integer :: lda
	real(8), allocatable, target :: evals(:)
	
	!real :: aux_work
	!integer :: aux_iwork
	
	real(8), allocatable, target :: work(:)
	integer :: lwork
	real(8), allocatable, target :: iwork(:)
	integer :: liwork
	integer :: info

	integer :: queue 
	
	!init stuff
	integer :: ione
        integer :: ISEED(4)
        integer :: n2
        real(8), allocatable, target :: h_A(:)
        
        integer :: i,j
        real(8) :: z
        real(8) :: inc
            
        jobz = 302
        uplo = 121
        ny = 4724
        lda = ny
        info = 0
        queue = -66
        ione = 1
        ISEED = (/0,0,0,1/)
        n2 = ny*ny
        
	call turn_magma_on()
	!Query for workspace sizes
        !call dsyevd(jobz, uplo, ny, c_loc(a), lda, c_loc(evals), c_loc(aux_work),  -1, c_loc(aux_iwork), -1, c_loc(info))
	liwork = 3 + 5*ny
   	lwork = 1 + 6*ny + 2*ny*ny
        
        !regular allocation
        allocate (a(0:(ny*lda)-1), h_A(0:(ny*lda)-1))
        allocate (work(0:lwork-1), iwork(0:liwork-1), evals(0:ny-1))
        
        !crazy allocation
        call host_allocate(c_loc(c_loc(h_A)), ny*ny*8)
	
	call host_allocate(c_loc(c_loc(evals)), ny*8)
	
	call host_allocate(c_loc(c_loc(a)), ny*ny*8)

	call host_allocate(c_loc(c_loc(work)), lwork*8)

	call host_allocate(c_loc(c_loc(iwork)), liwork*4)

	call dlarnv(ione, ISEED, n2, h_A);
	call dlacpy('Full', ny, ny, h_A, ny, a, ny );
               
	call dsyevd (jobz, uplo, ny, a, lda, evals, work, lwork, iwork, liwork, info)
	write (*,*) 'BOOYAH!!!!!!!!!!!!!!!!!!!', info

end program greg
