!> Test program for y = alpha * x + betha * y psb_geaxbpy routine !! Check the README.md to see all details about the tests. !! !! Authors: Luca Pepé Sciarria, Staccone Simone (Tor Vergata University) !! !! psb_geaxpby(alpha, x, beta, y, desc_a, info) !! !! Type: Synchronous. !! !! ====================================== !! | Data type | Precision | !! ====================================== !! | psb_spk_ | Short Precision Real | !! | psb_dpk_ | Long Precision Real | !! | psb_cpk_ | Short Precision Complex| !! | psb_zpk_ | Long Precision Complex | !! ====================================== !! Table 1: Data types !! !! ROUTINE PARAMETERS !! !! Input: !! !! alpha Description: the scalar α. !! Scope: global !! Type: required !! Intent: in !! Specified as: a number of the data type indicated in Table 1. !! !! x Description: the local portion of global dense matrix x. !! Scope: local !! Type: required !! Intent: in !! Specified as: a rank one or two array or an object of type psb_T_vect_type !! containing numbers of type specified in Table 1. The rank of x must be !! the same of y. !! !! beta Description: the scalar β. !! Scope: global !! Type: required !! Intent: in. !! Specified as: a number of the data type indicated in Table 1. !! !! y Description: the local portion of the global dense matrix y. !! Scope: local !! Type: required !! Intent: inout !! Specified as: a rank one or two array or an object of type psb_T_vect_type !! containing numbers of the type indicated in Table 1. The rank of y must !! be the same of x. !! !! desc_a Description: contains data structures for communications. !! Scope: local !! Type: required !! Intent: in !! Specified as: an object of type psb desc type. !! !! Output: !! !! y Description: the local portion of the global dense matrix y. !! Scope: local !! Type: required !! Intent: inout !! Specified as: a rank one or two array or an object of type psb_T_vect_type !! containing numbers of the type indicated in Table 1. The rank of y must !! be the same of x. !! !! info Description: Error code. !! Scope: local !! Type: required !! Intent: out. !! Specified as: An integer value; 0 means no error has been detected. !! program main use psb_base_mod use psb_util_mod use psb_test_utils implicit none ! MPI variables integer(psb_ipk_) :: my_rank, np ! Communicator variable type(psb_ctxt_type) :: ctxt ! parameters array character(len=64) :: x(4),y(4) real(psb_dpk_) :: alpha(3), beta(3) integer(psb_ipk_) :: arr_size integer(psb_ipk_) :: tests_number, count ! cycle indexes variables integer(psb_ipk_) :: i,j,k,h,l integer(psb_ipk_) :: info, ret, unit ! time stats variables character(len=8) :: date ! YYYYMMDD character(len=10) :: time ! HHMMSS.sss character(len=5) :: zones ! Time zone integer :: values(8) ! others character(len=:), allocatable :: output_file_name type(test_info_) :: test_info ! Initialize parameters x(1) = "vectors/x1.mtx" x(2) = "vectors/x2.mtx" x(3) = "vectors/x3.mtx" x(4) = "vectors/x4.mtx" y(1) = "vectors/y1.mtx" y(2) = "vectors/y2.mtx" y(3) = "vectors/y3.mtx" y(4) = "vectors/y4.mtx" alpha(1) = done alpha(2) = -done alpha(3) = dzero beta(1) = done beta(2) = -done beta(3) = dzero arr_size = 10000 tests_number = size(x) * size(y) * size(alpha) * size(beta) count = 0 !! Initialize test metadata test_info%total_tests = size(x) * size(y) test_info%threshold_type = GAMMA test_info%threshold = 0.0 test_info%kernel_name = "psb_geaxpby" call psb_test_init(test_info) if(test_info%my_rank == psb_root_) then psb_out_unit = test_info%output_unit call psb_test_generate_input_vectors(arr_size) end if call psb_bcast(test_info%ctxt,test_info%output_unit) call psb_barrier(test_info%ctxt) if(test_info%my_rank == psb_root_) write(*,'(A)') "[INFO] Starting test excecution ..." !call psb_init(ctxt) !call psb_info(ctxt,my_rank,np) ! call generate_vectors(arr_size) !call psb_bcast(ctxt,psb_out_unit) !call psb_barrier(ctxt) if(test_info%my_rank == psb_root_) write(*,'(A)') "[INFO] Starting single precision computation..." do i=1,size(x) do j=1,size(y) do k=1,size(alpha) do h=1,size(beta) call psb_geaxpby_kernel(x_file=x(i), y_file=y(j), alpha = real(alpha(k),psb_spk_),& & beta = real(beta(h),psb_spk_), arr_size = arr_size, ctxt = test_info%ctxt, ret = ret, & & output_file_name = output_file_name) if(test_info%my_rank == psb_root_) then count = count + 1 call date_and_time(date, time, zones, values) if(ret /= -1) then ! Success formatted output write(psb_out_unit,'("[", I4.4,"-",I2.2,"-",I2.2," ",I2.2,":",I2.2,":",I2.2,"] ",& & A,A,A,I0,A,I0,T110,A)') & & values(1), values(2), values(3), values(5), values(6), values(7), & & "Generation geaxpby single precision result file ", & & output_file_name , ' ', count , "/", tests_number, "[OK]" else ! Fail formatted output write(psb_out_unit,'("[", I4.4,"-",I2.2,"-",I2.2," ",I2.2,":",I2.2,":",I2.2,"] ",& & A,A,A,I0,A,I0,T110,A)') & & values(1), values(2), values(3), values(5), values(6), values(7), & & "Generation geaxpby single precision result file ", & & output_file_name , ' ', count , "/", tests_number, "[FAIL]" goto 9998 end if end if call psb_barrier(test_info%ctxt) end do end do end do end do if(test_info%my_rank == psb_root_) write(*,'(A)') "[INFO] Single precision computation completed succesfully!" if(test_info%my_rank == psb_root_) then write(psb_out_unit, *) '' count = 0 end if if(test_info%my_rank == psb_root_) write(*,'(A)') "[INFO] Starting double precision check..." call psb_barrier(test_info%ctxt) ! Here double precision comparison should be done do i=1,size(x) do j=1,size(y) do k=1,size(alpha) do h=1,size(beta) call psb_geaxpby_check(x_file=x(i), y_file=y(j), alpha = alpha(k), beta = beta(h), & & arr_size = arr_size, ctxt = test_info%ctxt, ret = ret, output_file_name = output_file_name) if(my_rank == psb_root_) then count = count + 1 call date_and_time(date, time, zones, values) if(ret == 0) then ! Success formatted output write(psb_out_unit,'("[", I4.4,"-",I2.2,"-",I2.2," ",I2.2,":",I2.2,":",I2.2,"] ",& & A,A,A,I0,A,I0,T110,A)') & & values(1), values(2), values(3), values(5), values(6), values(7), & & "Double precision check on file ", & & output_file_name , ' ', count , "/", tests_number, "[OK]" else ! Fail formatted output write(psb_out_unit,'("[", I4.4,"-",I2.2,"-",I2.2," ",I2.2,":",I2.2,":",I2.2,"] ",& & A,A,A,I0,A,I0,T110,A)') & & values(1), values(2), values(3), values(5), values(6), values(7), & & "Double precision check on file ", & & output_file_name , ' ', count , "/", tests_number, "[FAIL]" write(psb_out_unit,'(A,I0)') "[ERROR] Error at element ", abs(ret) write(psb_out_unit,'(A,F10.8)') "Alpha:", alpha(k) write(psb_out_unit,'(A,F15.8)') "Beta: ", beta(h) goto 9999 end if end if call psb_barrier(test_info%ctxt) end do end do end do end do if(test_info%my_rank == psb_root_) then write(*,'(A)') "[INFO] Duble precision check completed succesfully!" close(unit) end if call psb_exit(test_info%ctxt) return 9998 continue if(test_info%my_rank == psb_root_) then close(unit) write(*,'(A,I0,A,I0,A)') "[ERROR] Error in geaxpby single precision computation ", & & count, "/", tests_number, " see log file for details" end if 9999 continue if(test_info%my_rank == psb_root_) then close(unit) write(*,'(A,I0,A,I0,A)') "[ERROR] Error in geaxpby double precision check ", & & count, "/", tests_number, " see log file for details" end if call psb_test_exit(test_info) return contains !> @brief Function to excecute psb_geaxpby in single precision and !! save the results on file !! subroutine psb_geaxpby_kernel(x_file, y_file, alpha, beta, arr_size, ctxt, ret, output_file_name) ! implicit none ! input parameters character(len = *), intent(in) :: x_file, y_file real(psb_spk_), intent(in) :: alpha, beta integer(psb_ipk_), intent(in) :: arr_size type(psb_ctxt_type), intent(in) :: ctxt ! output parameters integer(psb_ipk_), intent(out) :: ret character(len=:), allocatable, intent(out) :: output_file_name ! vectors type(psb_s_vect_type) :: x, y ! matrix descriptor data structure type(psb_desc_type) :: desc_a ! communication context integer(psb_ipk_) :: my_rank, np, info, err_act ! variables outside PSLBALS data structures real(psb_spk_), allocatable :: x_global(:), y_global(:) integer(psb_ipk_) :: i ! others logical :: exists info = psb_success_ call psb_info(ctxt,my_rank,np) if (my_rank < 0) then ! This should not happen, but just in case call psb_error(ctxt) endif ! Generate random array for b using always the same seed if(my_rank == psb_root_) then allocate(x_global(arr_size)) allocate(y_global(arr_size)) call mm_array_read(x_global,info,filename=x_file) call mm_array_read(y_global,info,filename=y_file) end if ! Allocate descriptor as if it was a block rows distribution call psb_cdall(ctxt, desc_a, info,nl=arr_size/np) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error allocating desc_a data structure" goto 9999 end if call psb_cdasb(desc_a, info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error assembling desc_a data structure" goto 9999 end if call psb_geall(x,desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error allocating x data structure" goto 9999 end if ! Populate x class using data from x_global vector call psb_scatter(x_global,x,desc_a,info,root=psb_root_) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in psb_scatter to populate x data structure" goto 9999 end if call psb_geall(y,desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error allocating y data structure" goto 9999 end if ! Populate y class using data from y_global vector call psb_scatter(y_global,y,desc_a,info,root=psb_root_) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in psb_scatter to populate y data structure" goto 9999 end if ! y = alpha * x + beta * y call psb_geaxpby(alpha,x,beta,y,desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in psb_geaxpby routine" goto 9999 end if ! Make the root process be the one that saves everything on file if(np == 1) then ! Check if output directory exists inquire(file='serial/', exist=exists) if (.not.exists) then call system('mkdir serial/') end if output_file_name = "serial/" else ! Check if output directory exists inquire(file='parallel/', exist=exists) if (.not.exists) then call system('mkdir parallel/') end if output_file_name = "parallel/" end if output_file_name = output_file_name // "sol_" // x_file(9:10) // "_" // y_file(9:10) if(alpha == sone) then output_file_name = output_file_name // "_a1" else if(alpha == -sone) then output_file_name = output_file_name // "_a2" else if(alpha == szero) then output_file_name = output_file_name // "_a3" end if if(beta == sone) then output_file_name = output_file_name // "_b1.mtx" else if(beta == -sone) then output_file_name = output_file_name // "_b2.mtx" else if(beta == szero) then output_file_name = output_file_name // "_b3.mtx" end if ! gather the result combining all the partial ones call psb_gather(y_global, y, desc_a, info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error gathering global vector x to write on file" goto 9999 end if ! Save result to output file if(my_rank == psb_root_) then call mm_array_write(y_global,"Result vector",info,filename=output_file_name) end if ! Deallocate call psb_gefree(x, desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in vector x free routine" goto 9999 end if call psb_gefree(y, desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in vector y free routine" goto 9999 end if call psb_cdfree(desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in matrix descriptor free routine" goto 9999 end if if(my_rank == 0) then deallocate(x_global) deallocate(y_global) end if return ! Error handling 9999 ret = -1 stop end subroutine !> @brief Function to excecute psb_geaxpby in double precision and !! compare the results with the ones on file !! subroutine psb_geaxpby_check(x_file, y_file, alpha, beta, arr_size, ctxt, ret, output_file_name) use psb_base_mod use psb_util_mod implicit none ! input parameters character(len = *), intent(in) :: x_file, y_file real(psb_dpk_), intent(in) :: alpha, beta integer(psb_ipk_), intent(in) :: arr_size type(psb_ctxt_type), intent(in) :: ctxt ! output parameters integer(psb_ipk_), intent(out) :: ret character(len=:), allocatable, intent(out) :: output_file_name ! vectors type(psb_d_vect_type) :: x, y type(psb_s_vect_type) :: y_check ! matrix descriptor data structure type(psb_desc_type) :: desc_a ! communication context integer(psb_ipk_) :: my_rank, np, info, err_act ! variables outside PSLBALS data structures real(psb_dpk_), allocatable :: x_global(:), y_global(:) integer(psb_ipk_) :: i ! others logical :: exists info = psb_success_ call psb_info(ctxt,my_rank,np) if (my_rank < 0) then ! This should not happen, but just in case call psb_error(ctxt) endif ! Generate random array for b using always the same seed if(my_rank == psb_root_) then allocate(x_global(arr_size)) allocate(y_global(arr_size)) call mm_array_read(x_global,info,filename=x_file) call mm_array_read(y_global,info,filename=y_file) end if ! Allocate descriptor as if it was a block rows distribution call psb_cdall(ctxt, desc_a, info,nl=10000/np) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error allocating desc_a data structure" goto 9999 end if call psb_cdasb(desc_a, info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error assembling desc_a data structure" goto 9999 end if call psb_geall(x,desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error allocating x data structure" goto 9999 end if ! Populate x class using data from x_global vector call psb_scatter(x_global,x,desc_a,info,root=psb_root_) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in psb_scatter to populate x data structure" goto 9999 end if call psb_geall(y,desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error allocating y data structure" goto 9999 end if ! Populate y class using data from y_global vector call psb_scatter(y_global,y,desc_a,info,root=psb_root_) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in psb_scatter to populate y data structure" goto 9999 end if call psb_geall(y_check,desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error allocating y_check data structure" goto 9999 end if ! y = alpha * x + beta * y call psb_geaxpby(alpha,x,beta,y,desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in psb_geaxpby routine" goto 9999 end if ! gather the result combining all the partial ones call psb_gather(y_global, y, desc_a, info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error gathering global vector y used for comparison" goto 9999 end if if(my_rank == psb_root_) then ! Make the root process be the one that saves everything on file if(np == 1) then ! Check if output directory exists inquire(file='serial/', exist=exists) if(.not.exists) then write(psb_out_unit,'(A)') "Error in psb_geaxpby_check routine, no single precision result is saved on file" goto 9999 end if output_file_name = "serial/" else ! Check if output directory exists inquire(file='parallel/', exist=exists) if(.not.exists) then write(psb_out_unit,'(A)') "Error in psb_geaxpby_check routine, no single precision result is saved on file" goto 9999 end if output_file_name = "parallel/" end if output_file_name = output_file_name // "sol_" // x_file(9:10) // "_" // y_file(9:10) if(alpha == done) then output_file_name = output_file_name // "_a1" else if(alpha == -done) then output_file_name = output_file_name // "_a2" else if(alpha == dzero) then output_file_name = output_file_name // "_a3" end if if(beta == done) then output_file_name = output_file_name // "_b1.mtx" else if(beta == -done) then output_file_name = output_file_name // "_b2.mtx" else if(beta == dzero) then output_file_name = output_file_name // "_b3.mtx" end if ! Read single precision result from file call mm_array_read(y_check,info,filename=output_file_name) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in mm_array_read for y_check data structure" goto 9999 end if ! 5.96e-08 is 2^-24 (Single precision unit roundoff) ! 1.19e-07 is 2^-23 (Single precision unit interval) do i=1, arr_size !! write(*, *) abs(y_global(i) - y_check%v%v(i)) > 5.96D-08, & !! & y_global(i), y_check%v%v(i), output_file_name if(abs(y_global(i) - y_check%v%v(i)) > 1.19e-07) then ret = -i write(psb_out_unit, '(A,F10.8)') "Y computed in double precision: ", y_global(i) write(psb_out_unit, '(A,F10.8)') "Y read from single precision file: ", y_check%v%v(i) write(psb_out_unit, '(A,F10.8)') "Diff: ", abs(y_global(i) - y_check%v%v(i)) exit end if end do end if ! Deallocate call psb_gefree(x, desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in vector x free routine" goto 9999 end if call psb_gefree(y, desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in vector y free routine" goto 9999 end if call psb_gefree(y_check, desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in vector y_check free routine" goto 9999 end if call psb_cdfree(desc_a,info) if(info /= psb_success_) then write(psb_out_unit,'(A)') "Error in matrix descriptor free routine" goto 9999 end if if(my_rank == 0) then deallocate(x_global) deallocate(y_global) end if ret = 0 return ! Error handling 9999 ret = -1 stop end subroutine end program main