DBM: Add LIBTEST for dbm_multiply

This commit is contained in:
Ole Schütt 2022-06-26 19:15:22 +02:00 committed by Ole Schütt
parent db6112715a
commit 220241f295
14 changed files with 801 additions and 43 deletions

View file

@ -1,5 +1,5 @@
{
"description": "Distributed Block-sparse Matrix",
"requires": ["../base", "../mpiwrap", "../offload", "../common"],
"public": ["dbm_api.F"],
"public": ["dbm_api.F", "dbm_tests.F"],
}

449
src/dbm/dbm_tests.F Normal file
View file

@ -0,0 +1,449 @@
!--------------------------------------------------------------------------------------------------!
! CP2K: A general program to perform molecular dynamics simulations !
! Copyright 2000-2022 CP2K developers group <https://cp2k.org> !
! !
! SPDX-License-Identifier: BSD-3-Clause !
!--------------------------------------------------------------------------------------------------!
MODULE dbm_tests
USE OMP_LIB, ONLY: omp_get_wtime
USE dbm_api, ONLY: &
dbm_checksum, dbm_copy, dbm_create, dbm_create_from_template, dbm_distribution_new, &
dbm_distribution_obj, dbm_distribution_release, dbm_get_col_block_sizes, &
dbm_get_row_block_sizes, dbm_get_stored_coordinates, dbm_multiply, dbm_put_block, &
dbm_release, dbm_type
USE kinds, ONLY: dp,&
int_8
USE machine, ONLY: m_flush
USE message_passing, ONLY: mp_cart_create,&
mp_comm_free,&
mp_dims_create,&
mp_environ,&
mp_max,&
mp_sum,&
mp_sync
#include "../base/base_uses.f90"
IMPLICIT NONE
PRIVATE
PUBLIC :: dbm_run_tests, generate_larnv_seed
INTEGER, PRIVATE, SAVE :: randmat_counter = 0
CONTAINS
! **************************************************************************************************
!> \brief Tests the DBM library.
!> \param mp_group MPI communicator
!> \param io_unit Unit to write to, if not negative
!> \param matrix_sizes Size of matrices to test
!> \param trs Transposes of the two matrices
!> \param bs_m Block sizes of the 1. dimension
!> \param bs_n Block sizes of the 2. dimension
!> \param bs_k Block sizes of the 3. dimension
!> \param sparsities Sparsities of matrices to create
!> \param alpha Alpha value to use in multiply
!> \param beta Beta value to use in multiply
!> \param n_loops Number of repetition for each multiplication
!> \param eps Epsilon value for filtering
!> \param retain_sparsity Retain the result matrix's sparsity
!> \param always_checksum Checksum after each multiplication
!> \author Ole Schuett
! **************************************************************************************************
SUBROUTINE dbm_run_tests(mp_group, io_unit, matrix_sizes, trs, &
bs_m, bs_n, bs_k, sparsities, alpha, beta, &
n_loops, eps, retain_sparsity, always_checksum)
INTEGER, INTENT(IN) :: mp_group, io_unit
INTEGER, DIMENSION(:), INTENT(in) :: matrix_sizes
LOGICAL, DIMENSION(2), INTENT(in) :: trs
INTEGER, DIMENSION(:), POINTER :: bs_m, bs_n, bs_k
REAL(kind=dp), DIMENSION(3), INTENT(in) :: sparsities
REAL(kind=dp), INTENT(in) :: alpha, beta
INTEGER, INTENT(IN) :: n_loops
REAL(kind=dp), INTENT(in) :: eps
LOGICAL, INTENT(in) :: retain_sparsity, always_checksum
CHARACTER(len=*), PARAMETER :: routineN = 'dbm_run_tests'
INTEGER :: bmax, bmin, cart_group, handle, mynode, &
numnodes
INTEGER, CONTIGUOUS, DIMENSION(:), POINTER :: col_dist_a, col_dist_b, col_dist_c, &
row_dist_a, row_dist_b, row_dist_c, &
sizes_k, sizes_m, sizes_n
INTEGER, DIMENSION(2) :: mycoord, npdims
TYPE(dbm_distribution_obj) :: dist_a, dist_b, dist_c
TYPE(dbm_type), TARGET :: matrix_a, matrix_b, matrix_c
CALL timeset(routineN, handle)
! Create MPI processor grid.
CALL mp_environ(numnodes, mynode, mp_group)
npdims(:) = 0
CALL mp_dims_create(numnodes, npdims)
CALL mp_cart_create(mp_group, 2, npdims, mycoord, cart_group)
! Initialize random number generator.
randmat_counter = 12341313
! Create the row/column block sizes.
NULLIFY (sizes_k, sizes_m, sizes_n)
IF (ASSOCIATED(bs_m)) THEN
bmin = MINVAL(bs_m(2::2))
bmax = MAXVAL(bs_m(2::2))
CALL generate_mixed_block_sizes(sizes_m, matrix_sizes(1), bs_m)
ELSE
CALL generate_mixed_block_sizes(sizes_m, matrix_sizes(1), (/1, 13, 2, 5/))
bmin = 5; bmax = 13
END IF
IF (ASSOCIATED(bs_n)) THEN
bmin = MIN(bmin, MINVAL(bs_n(2::2)))
bmax = MAX(bmax, MAXVAL(bs_n(2::2)))
CALL generate_mixed_block_sizes(sizes_n, matrix_sizes(2), bs_n)
ELSE
CALL generate_mixed_block_sizes(sizes_n, matrix_sizes(2), (/1, 13, 2, 5/))
bmin = MIN(bmin, 5); bmax = MAX(bmax, 13)
END IF
IF (ASSOCIATED(bs_k)) THEN
bmin = MIN(bmin, MINVAL(bs_k(2::2)))
bmax = MAX(bmax, MAXVAL(bs_k(2::2)))
CALL generate_mixed_block_sizes(sizes_k, matrix_sizes(3), bs_k)
ELSE
CALL generate_mixed_block_sizes(sizes_k, matrix_sizes(3), (/1, 13, 2, 5/))
bmin = MIN(bmin, 5); bmax = MAX(bmax, 13)
END IF
! Create Matrix C
CALL generate_1d_dist(row_dist_c, SIZE(sizes_m), npdims(1), sizes_m)
CALL generate_1d_dist(col_dist_c, SIZE(sizes_n), npdims(2), sizes_n)
CALL dbm_distribution_new(dist_c, cart_group, row_dist_c, col_dist_c)
CALL dbm_create(matrix_c, "Matrix C", dist_c, sizes_m, sizes_n)
CALL fill_matrix(matrix_c, sparsity=sparsities(3), group=cart_group)
CALL dbm_distribution_release(dist_c)
! Create Matrix A
IF (trs(1)) THEN
CALL generate_1d_dist(row_dist_a, SIZE(sizes_k), npdims(1), sizes_k)
CALL generate_1d_dist(col_dist_a, SIZE(sizes_m), npdims(2), sizes_m)
CALL dbm_distribution_new(dist_a, cart_group, row_dist_a, col_dist_a)
CALL dbm_create(matrix_a, "Matrix A", dist_a, sizes_k, sizes_m)
CALL fill_matrix(matrix_a, sparsity=sparsities(1), group=cart_group)
DEALLOCATE (row_dist_a, col_dist_a)
ELSE
CALL generate_1d_dist(col_dist_a, SIZE(sizes_k), npdims(2), sizes_k)
CALL dbm_distribution_new(dist_a, cart_group, row_dist_c, col_dist_a)
CALL dbm_create(matrix_a, "Matrix A", dist_a, sizes_m, sizes_k)
CALL fill_matrix(matrix_a, sparsity=sparsities(1), group=cart_group)
DEALLOCATE (col_dist_a)
END IF
CALL dbm_distribution_release(dist_a)
! Create Matrix B
IF (trs(2)) THEN
CALL generate_1d_dist(row_dist_b, SIZE(sizes_n), npdims(1), sizes_n)
CALL generate_1d_dist(col_dist_b, SIZE(sizes_k), npdims(2), sizes_k)
CALL dbm_distribution_new(dist_b, cart_group, row_dist_b, col_dist_b)
CALL dbm_create(matrix_b, "Matrix B", dist_b, sizes_n, sizes_k)
CALL fill_matrix(matrix_b, sparsity=sparsities(2), group=cart_group)
DEALLOCATE (row_dist_b, col_dist_b)
ELSE
CALL generate_1d_dist(row_dist_b, SIZE(sizes_k), npdims(1), sizes_k)
CALL dbm_distribution_new(dist_b, cart_group, row_dist_b, col_dist_c)
CALL dbm_create(matrix_b, "Matrix B", dist_b, sizes_k, sizes_n)
CALL fill_matrix(matrix_b, sparsity=sparsities(2), group=cart_group)
DEALLOCATE (row_dist_b)
END IF
CALL dbm_distribution_release(dist_b)
DEALLOCATE (row_dist_c, col_dist_c, sizes_m, sizes_n, sizes_k)
! Prepare test parameters
IF (io_unit > 0) THEN
WRITE (io_unit, '(A,3(1X,I6),1X,A,2(1X,I5),1X,A,2(1X,L1))') &
"Testing with sizes", matrix_sizes(1:3), &
"min/max block sizes", bmin, bmax, "transposed?", trs(1:2)
END IF
CALL run_multiply_test(matrix_a, matrix_b, matrix_c, &
transa=trs(1), transb=trs(2), &
alpha=alpha, beta=beta, &
n_loops=n_loops, &
eps=eps, &
group=cart_group, &
io_unit=io_unit, &
always_checksum=always_checksum, &
retain_sparsity=retain_sparsity)
CALL dbm_release(matrix_a)
CALL dbm_release(matrix_b)
CALL dbm_release(matrix_c)
CALL mp_comm_free(cart_group)
CALL timestop(handle)
END SUBROUTINE dbm_run_tests
! **************************************************************************************************
!> \brief Runs the multiplication test.
!> \param matrix_a ...
!> \param matrix_b ...
!> \param matrix_c ...
!> \param transa ...
!> \param transb ...
!> \param alpha ...
!> \param beta ...
!> \param retain_sparsity ...
!> \param n_loops ...
!> \param eps ...
!> \param group ...
!> \param io_unit ...
!> \param always_checksum ...
!> \author Ole Schuett
! **************************************************************************************************
SUBROUTINE run_multiply_test(matrix_a, matrix_b, matrix_c, transa, transb, alpha, beta, &
retain_sparsity, n_loops, eps, group, io_unit, always_checksum)
TYPE(dbm_type), INTENT(inout) :: matrix_a, matrix_b, matrix_c
LOGICAL, INTENT(in) :: transa, transb
REAL(kind=dp), INTENT(in) :: alpha, beta
LOGICAL, INTENT(in) :: retain_sparsity
INTEGER, INTENT(IN) :: n_loops
REAL(kind=dp), INTENT(in) :: eps
INTEGER, INTENT(IN) :: group, io_unit
LOGICAL, INTENT(in) :: always_checksum
CHARACTER(len=*), PARAMETER :: routineN = 'run_multiply_test'
INTEGER :: handle, loop_iter, mynode, numnodes
INTEGER(kind=int_8) :: flop, flop_sum
REAL(kind=dp) :: cs, flops_all, t1, t2
TYPE(dbm_type) :: matrix_c_orig
CALL timeset(routineN, handle)
CALL mp_environ(numnodes, mynode, group)
CALL dbm_create_from_template(matrix_c_orig, "Original Matrix C", matrix_c)
CALL dbm_copy(matrix_c_orig, matrix_c)
DO loop_iter = 1, n_loops
CALL mp_sync(group)
t1 = -1*omp_get_wtime()
IF (eps < -0.0_dp) THEN
CALL dbm_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, &
retain_sparsity=retain_sparsity, flop=flop)
ELSE
CALL dbm_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, &
retain_sparsity=retain_sparsity, flop=flop, filter_eps=eps)
END IF
t1 = t1 + omp_get_wtime()
t2 = t2 + t1
flop_sum = flop_sum + flop
CALL mp_max(t1, group)
CALL mp_sum(flop, group)
t1 = MAX(t1, EPSILON(t1))
flops_all = REAL(flop, KIND=dp)/t1/numnodes/(1024*1024)
IF (io_unit .GT. 0) THEN
WRITE (io_unit, '(A,I5,A,I5,A,F12.3,A,I9,A)') &
" loop ", loop_iter, " with ", numnodes, " MPI ranks: using ", &
t1, "s ", INT(flops_all), " Mflops/rank"
CALL m_flush(io_unit)
END IF
IF (loop_iter .EQ. n_loops .OR. always_checksum) THEN
cs = dbm_checksum(matrix_c)
IF (io_unit > 0) THEN
WRITE (io_unit, *) "Final checksums", cs
END IF
END IF
CALL dbm_copy(matrix_c, matrix_c_orig)
END DO
CALL dbm_release(matrix_c_orig)
CALL timestop(handle)
END SUBROUTINE run_multiply_test
! **************************************************************************************************
!> \brief Fills give matrix with random blocks.
!> \param matrix ...
!> \param sparsity ...
!> \param group ...
! **************************************************************************************************
SUBROUTINE fill_matrix(matrix, sparsity, group)
TYPE(dbm_type), INTENT(inout) :: matrix
REAL(kind=dp), INTENT(in) :: sparsity
INTEGER, INTENT(IN) :: group
CHARACTER(len=*), PARAMETER :: routineN = 'fill_matrix'
INTEGER :: block_node, col, handle, mynode, ncol, &
nrow, numnodes, row
INTEGER(KIND=int_8) :: counter, ele, increment, nmax
INTEGER, DIMENSION(4) :: iseed, jseed
INTEGER, DIMENSION(:), POINTER :: col_block_sizes, row_block_sizes
REAL(kind=dp) :: my_sparsity
REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: block
REAL(kind=dp), DIMENSION(1) :: value
CALL timeset(routineN, handle)
CALL mp_environ(numnodes, mynode, group)
! Check that the counter was initialised (or has not overflowed)
CPASSERT(randmat_counter .NE. 0)
! the counter goes into the seed. Every new call gives a new random matrix
randmat_counter = randmat_counter + 1
IF (sparsity .GT. 1) THEN
my_sparsity = sparsity/100.0
ELSE
my_sparsity = sparsity
END IF
row_block_sizes => dbm_get_row_block_sizes(matrix)
col_block_sizes => dbm_get_col_block_sizes(matrix)
nrow = SIZE(row_block_sizes)
ncol = SIZE(col_block_sizes)
nmax = INT(nrow, KIND=int_8)*INT(ncol, KIND=int_8)
ele = -1
counter = 0
jseed = generate_larnv_seed(7, 42, 3, 42, randmat_counter)
DO
! find the next block to add, this is given by a geometrically distributed variable
! we number the blocks of the matrix and jump to the next one
CALL dlarnv(1, jseed, 1, value)
IF (my_sparsity > 0) THEN
increment = 1 + FLOOR(LOG(value(1))/LOG(my_sparsity), KIND=int_8)
ELSE
increment = 1
END IF
ele = ele + increment
IF (ele >= nmax) EXIT
counter = counter + 1
row = INT(ele/ncol) + 1
col = INT(MOD(ele, INT(ncol, KIND=KIND(ele)))) + 1
! Only deal with the local blocks.
CALL dbm_get_stored_coordinates(matrix, row, col, block_node)
IF (block_node == mynode) THEN
! fill based on a block based seed, makes this the same values in parallel
iseed = generate_larnv_seed(row, nrow, col, ncol, randmat_counter)
ALLOCATE (block(row_block_sizes(row), col_block_sizes(col)))
CALL dlarnv(1, iseed, SIZE(block), block)
CALL dbm_put_block(matrix, row, col, block)
DEALLOCATE (block)
END IF
END DO
CALL timestop(handle)
END SUBROUTINE fill_matrix
! **************************************************************************************************
!> \brief Assigns given elements to bins. Uses given element_sizes for load balancing.
!> \param bin_dist Distribution of elements to bins
!> \param nelements Number of elements
!> \param nbins Number of bins
!> \param element_sizes sizes of elements
!> \author Ole Schuett
! **************************************************************************************************
SUBROUTINE generate_1d_dist(bin_dist, nelements, nbins, element_sizes)
INTEGER, DIMENSION(:), INTENT(OUT), POINTER :: bin_dist
INTEGER, INTENT(IN) :: nelements, nbins
INTEGER, DIMENSION(:), INTENT(IN) :: element_sizes
INTEGER :: bin, i
INTEGER, DIMENSION(nbins) :: bin_counts
CPASSERT(SIZE(element_sizes) == nelements)
ALLOCATE (bin_dist(nelements))
bin_counts(:) = [(0, bin=0, nbins - 1)]
DO i = 1, nelements
bin = MINLOC(bin_counts, dim=1) ! greedy algorithm
bin_dist(i) = bin - 1
bin_counts(bin) = bin_counts(bin) + element_sizes(i)
END DO
END SUBROUTINE generate_1d_dist
! **************************************************************************************************
!> \brief Generates a block_sizes by "randomly" selecting from size_mix.
!> \param block_sizes ...
!> \param size_sum ...
!> \param size_mix ...
!> \author Ole Schuett
! **************************************************************************************************
SUBROUTINE generate_mixed_block_sizes(block_sizes, size_sum, size_mix)
INTEGER, DIMENSION(:), INTENT(inout), POINTER :: block_sizes
INTEGER, INTENT(in) :: size_sum
INTEGER, DIMENSION(:), INTENT(in) :: size_mix
INTEGER :: block_size, current_sum, ipass, nblocks, &
nsize_mix, selector
INTEGER, ALLOCATABLE, DIMENSION(:, :) :: mixer
CPASSERT(.NOT. ASSOCIATED(block_sizes))
nsize_mix = SIZE(size_mix)/2
ALLOCATE (mixer(3, nsize_mix))
! 1st pass to compute nblocks and allocate block_sizes, 2nd pass to fill block_sizes.
DO ipass = 1, 2
mixer(1, :) = size_mix(1:nsize_mix*2 - 1:2)
mixer(2, :) = size_mix(2:nsize_mix*2:2)
mixer(3, :) = 1
selector = 1
nblocks = 0
current_sum = 0
DO WHILE (current_sum < size_sum)
nblocks = nblocks + 1
block_size = MIN(mixer(2, selector), size_sum - current_sum)
IF (ipass == 2) THEN
block_sizes(nblocks) = block_size
END IF
current_sum = current_sum + block_size
mixer(3, selector) = mixer(3, selector) + 1
IF (mixer(3, selector) > mixer(1, selector)) THEN
mixer(3, selector) = 1
selector = MOD(selector, nsize_mix) + 1
END IF
END DO
IF (ipass == 1) THEN
ALLOCATE (block_sizes(nblocks))
END IF
END DO
current_sum = SUM(block_sizes)
CPASSERT(current_sum == size_sum)
END SUBROUTINE generate_mixed_block_sizes
! **************************************************************************************************
!> \brief Generate a seed respecting the lapack constraints,
!> - values between 0..4095 (2**12-1)
!> - iseed(4) odd
!> also try to avoid iseed that are zero.
!> Have but with a unique 2D mapping (irow,icol), and a 'mini-seed' ival
!>
!> \param irow 1..nrow
!> \param nrow ...
!> \param icol 1..ncol
!> \param ncol ...
!> \param ival mini-seed
!> \return a lapack compatible seed
!> \author Patrick Seewald
! **************************************************************************************************
FUNCTION generate_larnv_seed(irow, nrow, icol, ncol, ival) RESULT(iseed)
INTEGER, INTENT(IN) :: irow, nrow, icol, ncol, ival
INTEGER :: iseed(4)
INTEGER(KIND=int_8) :: map
map = ((irow - 1 + icol*INT(nrow, int_8))*(1 + MODULO(ival, 2**16)))*2 + 1 + 0*ncol ! ncol used
iseed(4) = INT(MODULO(map, 2_int_8**12)); map = map/2_int_8**12; ! keep odd
iseed(3) = INT(MODULO(IEOR(map, 3541_int_8), 2_int_8**12)); map = map/2_int_8**12
iseed(2) = INT(MODULO(IEOR(map, 1153_int_8), 2_int_8**12)); map = map/2_int_8**12
iseed(1) = INT(MODULO(IEOR(map, 2029_int_8), 2_int_8**12)); map = map/2_int_8**12
END FUNCTION generate_larnv_seed
END MODULE dbm_tests

View file

@ -15,7 +15,7 @@ MODULE dbt_test
#:set ndims = range(2,maxdim+1)
USE dbt_tas_base, ONLY: dbt_tas_info
USE dbt_tas_util, ONLY: generate_larnv_seed
USE dbm_tests, ONLY: generate_larnv_seed
USE dbt_methods, ONLY: &
dbt_copy, dbt_get_block, dbt_iterator_type, dbt_iterator_blocks_left, &
dbt_iterator_next_block, dbt_iterator_start, dbt_iterator_stop, &

View file

@ -15,6 +15,7 @@ MODULE dbt_tas_test
dbm_distribution_release, dbm_finalize, dbm_get_col_block_sizes, dbm_get_name, &
dbm_get_row_block_sizes, dbm_maxabs, dbm_multiply, dbm_redistribute, dbm_release, &
dbm_scale, dbm_type
USE dbm_tests, ONLY: generate_larnv_seed
USE dbt_tas_base, ONLY: &
dbt_tas_convert_to_dbm, dbt_tas_create, dbt_tas_distribution_new, dbt_tas_finalize, &
dbt_tas_get_stored_coordinates, dbt_tas_info, dbt_tas_nblkcols_total, &
@ -27,7 +28,6 @@ MODULE dbt_tas_test
dbt_tas_mp_comm
USE dbt_tas_types, ONLY: dbt_tas_distribution_type,&
dbt_tas_type
USE dbt_tas_util, ONLY: generate_larnv_seed
USE kinds, ONLY: dp,&
int_8
USE message_passing, ONLY: mp_cart_create,&

View file

@ -27,10 +27,7 @@ MODULE dbt_tas_util
CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dbt_tas_util'
PUBLIC :: &
array_eq, &
swap, &
generate_larnv_seed
PUBLIC :: array_eq, swap
INTERFACE swap
MODULE PROCEDURE swap_i8
@ -112,35 +109,4 @@ CONTAINS
! #endif
END FUNCTION
! **************************************************************************************************
!> \brief Generate a seed respecting the lapack constraints,
!> - values between 0..4095 (2**12-1)
!> - iseed(4) odd
!> also try to avoid iseed that are zero.
!> Have but with a unique 2D mapping (irow,icol), and a 'mini-seed' ival
!>
!> TODO: Move to some utility module.
!>
!> \param irow 1..nrow
!> \param nrow ...
!> \param icol 1..ncol
!> \param ncol ...
!> \param ival mini-seed
!> \return a lapack compatible seed
!> \author Patrick Seewald
! **************************************************************************************************
FUNCTION generate_larnv_seed(irow, nrow, icol, ncol, ival) RESULT(iseed)
INTEGER, INTENT(IN) :: irow, nrow, icol, ncol, ival
INTEGER :: iseed(4)
INTEGER(KIND=int_8) :: map
map = ((irow - 1 + icol*INT(nrow, int_8))*(1 + MODULO(ival, 2**16)))*2 + 1 + 0*ncol ! ncol used
iseed(4) = INT(MODULO(map, 2_int_8**12)); map = map/2_int_8**12; ! keep odd
iseed(3) = INT(MODULO(IEOR(map, 3541_int_8), 2_int_8**12)); map = map/2_int_8**12
iseed(2) = INT(MODULO(IEOR(map, 1153_int_8), 2_int_8**12)); map = map/2_int_8**12
iseed(1) = INT(MODULO(IEOR(map, 2029_int_8), 2_int_8**12)); map = map/2_int_8**12
END FUNCTION generate_larnv_seed
END MODULE

View file

@ -51,6 +51,7 @@ MODULE library_tests
USE cp_realspace_grid_init, ONLY: init_input_type
USE dbcsr_api, ONLY: dbcsr_reset_randmat_seed,&
dbcsr_run_tests
USE dbm_tests, ONLY: dbm_run_tests
USE fft_tools, ONLY: BWFFT,&
FFT_RADIX_CLOSEST,&
FWFFT,&
@ -138,8 +139,8 @@ CONTAINS
LOGICAL :: explicit
TYPE(cp_logger_type), POINTER :: logger
TYPE(section_vals_type), POINTER :: cp_dbcsr_test_section, cp_fm_gemm_test_section, &
eigensolver_section, eri_mme_test_section, pw_transfer_section, rs_pw_transfer_section, &
shg_integrals_test_section
dbm_test_section, eigensolver_section, eri_mme_test_section, pw_transfer_section, &
rs_pw_transfer_section, shg_integrals_test_section
CALL timeset(routineN, handle)
@ -212,14 +213,19 @@ CONTAINS
END IF
! DBCSR tests
! matrix_multiplication
cp_dbcsr_test_section => section_vals_get_subs_vals(root_section, &
"TEST%CP_DBCSR")
cp_dbcsr_test_section => section_vals_get_subs_vals(root_section, "TEST%CP_DBCSR")
CALL section_vals_get(cp_dbcsr_test_section, explicit=explicit)
IF (explicit) THEN
CALL cp_dbcsr_tests(para_env, iw, cp_dbcsr_test_section)
END IF
! DBM tests
dbm_test_section => section_vals_get_subs_vals(root_section, "TEST%DBM")
CALL section_vals_get(dbm_test_section, explicit=explicit)
IF (explicit) THEN
CALL dbm_tests(para_env, iw, dbm_test_section)
END IF
CALL cp_print_key_finished_output(iw, logger, root_section, "TEST%PROGRAM_RUN_INFO")
CALL timestop(handle)
@ -1485,4 +1491,63 @@ CONTAINS
END DO
END SUBROUTINE cp_dbcsr_tests
! **************************************************************************************************
!> \brief Tests the DBM library.
!> \param para_env ...
!> \param iw ...
!> \param input_section ...
! **************************************************************************************************
SUBROUTINE dbm_tests(para_env, iw, input_section)
TYPE(cp_para_env_type), POINTER :: para_env
INTEGER :: iw
TYPE(section_vals_type), POINTER :: input_section
INTEGER :: i_rep, k, m, n, N_loop, n_rep
INTEGER, DIMENSION(:), POINTER :: bs_k, bs_m, bs_n
LOGICAL :: always_checksum, retain_sparsity, &
transa_p, transb_p
REAL(KIND=dp) :: alpha, beta, filter_eps, s_a, s_b, s_c
! ---------------------------------------------------------------------------
NULLIFY (bs_m, bs_n, bs_k)
CALL section_vals_get(input_section, n_repetition=n_rep)
CALL dbcsr_reset_randmat_seed()
DO i_rep = 1, n_rep
CALL section_vals_val_get(input_section, "N_loop", i_rep_section=i_rep, i_val=N_loop)
CALL section_vals_val_get(input_section, "K", i_rep_section=i_rep, i_val=k)
CALL section_vals_val_get(input_section, "N", i_rep_section=i_rep, i_val=n)
CALL section_vals_val_get(input_section, "M", i_rep_section=i_rep, i_val=m)
CALL section_vals_val_get(input_section, "transa", i_rep_section=i_rep, l_val=transa_p)
CALL section_vals_val_get(input_section, "transb", i_rep_section=i_rep, l_val=transb_p)
CALL section_vals_val_get(input_section, "bs_m", i_rep_section=i_rep, i_vals=bs_m)
CALL section_vals_val_get(input_section, "bs_n", i_rep_section=i_rep, i_vals=bs_n)
CALL section_vals_val_get(input_section, "bs_k", i_rep_section=i_rep, i_vals=bs_k)
CALL section_vals_val_get(input_section, "keepsparse", i_rep_section=i_rep, l_val=retain_sparsity)
CALL section_vals_val_get(input_section, "asparsity", i_rep_section=i_rep, r_val=s_a)
CALL section_vals_val_get(input_section, "bsparsity", i_rep_section=i_rep, r_val=s_b)
CALL section_vals_val_get(input_section, "csparsity", i_rep_section=i_rep, r_val=s_c)
CALL section_vals_val_get(input_section, "alpha", i_rep_section=i_rep, r_val=alpha)
CALL section_vals_val_get(input_section, "beta", i_rep_section=i_rep, r_val=beta)
CALL section_vals_val_get(input_section, "filter_eps", i_rep_section=i_rep, r_val=filter_eps)
CALL section_vals_val_get(input_section, "ALWAYS_CHECKSUM", i_rep_section=i_rep, l_val=always_checksum)
CALL dbm_run_tests(mp_group=para_env%group, &
io_unit=iw, &
matrix_sizes=(/m, n, k/), &
trs=(/transa_p, transb_p/), &
bs_m=bs_m, &
bs_n=bs_n, &
bs_k=bs_k, &
sparsities=(/s_a, s_b, s_c/), &
alpha=alpha, &
beta=beta, &
n_loops=n_loop, &
eps=filter_eps, &
retain_sparsity=retain_sparsity, &
always_checksum=always_checksum)
END DO
END SUBROUTINE dbm_tests
END MODULE library_tests

View file

@ -278,6 +278,10 @@ CONTAINS
CALL section_add_subsection(section, subsection)
CALL section_release(subsection)
CALL create_dbm_section(subsection)
CALL section_add_subsection(section, subsection)
CALL section_release(subsection)
CALL create_eri_mme_test_section(subsection)
CALL section_add_subsection(section, subsection)
CALL section_release(subsection)
@ -1228,4 +1232,121 @@ CONTAINS
END SUBROUTINE create_cp_dbcsr_section
! **************************************************************************************************
!> \brief Creates the DBM section for use in the test section.
!> \param section ...
!> \author Ole Schuett
! **************************************************************************************************
SUBROUTINE create_dbm_section(section)
TYPE(section_type), POINTER :: section
TYPE(keyword_type), POINTER :: keyword
CPASSERT(.NOT. ASSOCIATED(section))
CALL section_create(section, __LOCATION__, name="DBM", &
description="Benchmark and test the dbm routines", &
n_keywords=1, n_subsections=0, repeats=.TRUE.)
NULLIFY (keyword)
CALL keyword_create(keyword, __LOCATION__, name="N_LOOP", &
description="Number of operations being timed (useful for small matrices).", &
usage="N_LOOP 10", default_i_val=10)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="M", &
description="Dimension 1 of C", &
usage="A 1024", default_i_val=256)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="N", &
description="Dimension 2 of C", &
usage="A 1024", default_i_val=256)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="K", &
description="Inner dimension M ", &
usage="A 1024", default_i_val=256)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="TRANSA", &
description="Transpose matrix A", &
usage="TRANSA", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="TRANSB", &
description="Transpose matrix B", &
usage="TRANSB", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="BS_M", &
description="Row block sizes of C", n_var=-1, &
usage="BS_M 1 13 2 5", default_i_vals=(/1, 13, 2, 15/))
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="BS_N", &
description="Column block sizes of C", n_var=-1, &
usage="BS_N 1 13 2 5", default_i_vals=(/1, 13, 2, 15/))
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="BS_K", &
description="Block sizes of inner dimension", n_var=-1, &
usage="BS_K 1 13 2 5", default_i_vals=(/1, 13, 2, 15/))
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="KEEPSPARSE", &
description="Keep product sparse", &
usage="KEEPSPARSE", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="ASPARSITY", &
description="Sparsity of A matrix", &
usage="ASPARSITY 70", default_r_val=0.0_dp)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="BSPARSITY", &
description="Sparsity of B matrix", &
usage="ASPARSITY 80", default_r_val=0.0_dp)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="CSPARSITY", &
description="Sparsity of C matrix", &
usage="ASPARSITY 90", default_r_val=0.0_dp)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="ALPHA", &
description="Multiplication factor", &
usage="ALPHA 2.0", default_r_val=1.0_dp)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="BETA", &
description="Product premultiplication factor", &
usage="BETA 1.0", default_r_val=0.0_dp)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="FILTER_EPS", &
description="Threshold for on-the-fly and final filtering.", &
usage="FILTER_EPS 1.0", default_r_val=-1.0_dp)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
CALL keyword_create(keyword, __LOCATION__, name="ALWAYS_CHECKSUM", &
description="perform a checksum after each multiplication", &
usage="ALWAYS_CHECKSUM", default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
CALL section_add_keyword(section, keyword)
CALL keyword_release(keyword)
END SUBROUTINE create_dbm_section
END MODULE input_cp2k

View file

@ -11,6 +11,7 @@ test_pw_05.inp 0
test_cp_fm_gemm_01.inp 0
test_cp_fm_gemm_02.inp 0
eig.inp 0
dbcsr_mm_blas.inp 0
dbcsr_multistack.inp 0
dbcsr_types.inp 0
@ -26,6 +27,14 @@ dbcsr_types_04.inp 58 1.0E-14
dbcsr_types_05.inp 58 1.0E-14 272584373.29241335
dbcsr_io_1.inp 0
dbcsr_order_N.inp 58 1.0E-14 1910924.8949438382
dbm_blocks_01.inp 58 5.0E-14 20978908949.261906
dbm_blocks_02.inp 58 5.0E-14 21229174127.238159
dbm_blocks_03.inp 58 5.0E-14 21561533688.640675
dbm_blocks_04.inp 58 5.0E-14 21304439095.77774
dbm_blocks_05.inp 58 5.0E-14 21455488291.450737
dbm_order_N.inp 58 5.0E-14 1910924.8949438382
test_eri_mme_accuracy.inp 0
test_eri_mme_accuracy_longrange.inp 0
test_eri_mme_accuracy_yukawa.inp 0

View file

@ -0,0 +1,24 @@
&GLOBAL
PRINT_LEVEL MEDIUM
PROGRAM_NAME TEST
RUN_TYPE NONE
&TIMINGS
THRESHOLD 0.00000000001
&END
&END GLOBAL
&TEST
&DBM
K 800
M 800
N 800
TRANSA FALSE
TRANSB TRUE
N_LOOP 2
ASPARSITY 0.05
BSPARSITY 0.05
CSPARSITY 0.05
bs_m 1 13 1 5 1 24
bs_k 1 13 1 5 1 24
bs_n 1 13 1 5 1 24
&END
&END TEST

View file

@ -0,0 +1,24 @@
&GLOBAL
PRINT_LEVEL MEDIUM
PROGRAM_NAME TEST
RUN_TYPE NONE
&TIMINGS
THRESHOLD 0.00000000001
&END
&END GLOBAL
&TEST
&DBM
K 800
M 800
N 800
TRANSA FALSE
TRANSB TRUE
N_LOOP 2
ASPARSITY 0.05
BSPARSITY 0.05
CSPARSITY 0.05
bs_m 1 13 1 24 1 15
bs_k 1 13 1 24 1 15
bs_n 1 13 1 24 1 15
&END
&END TEST

View file

@ -0,0 +1,24 @@
&GLOBAL
PRINT_LEVEL MEDIUM
PROGRAM_NAME TEST
RUN_TYPE NONE
&TIMINGS
THRESHOLD 0.00000000001
&END
&END GLOBAL
&TEST
&DBM
K 800
M 800
N 800
TRANSA FALSE
TRANSB TRUE
N_LOOP 2
ASPARSITY 0.05
BSPARSITY 0.05
CSPARSITY 0.05
bs_m 1 13 1 24 1 54
bs_k 1 13 1 24 1 54
bs_n 1 13 1 24 1 54
&END
&END TEST

View file

@ -0,0 +1,24 @@
&GLOBAL
PRINT_LEVEL MEDIUM
PROGRAM_NAME TEST
RUN_TYPE NONE
&TIMINGS
THRESHOLD 0.00000000001
&END
&END GLOBAL
&TEST
&DBM
K 800
M 800
N 800
TRANSA FALSE
TRANSB TRUE
N_LOOP 2
ASPARSITY 0.05
BSPARSITY 0.05
CSPARSITY 0.05
bs_m 1 23
bs_k 1 23
bs_n 1 23
&END
&END TEST

View file

@ -0,0 +1,24 @@
&GLOBAL
PRINT_LEVEL MEDIUM
PROGRAM_NAME TEST
RUN_TYPE NONE
&TIMINGS
THRESHOLD 0.00000000001
&END
&END GLOBAL
&TEST
&DBM
K 800
M 800
N 800
TRANSA FALSE
TRANSB TRUE
N_LOOP 2
ASPARSITY 0.05
BSPARSITY 0.05
CSPARSITY 0.05
bs_m 1 26 1 13 1 54
bs_k 1 26 1 13 1 54
bs_n 1 26 1 13 1 54
&END
&END TEST

View file

@ -0,0 +1,28 @@
&GLOBAL
PRINT_LEVEL MEDIUM
PROGRAM_NAME TEST
RUN_TYPE NONE
&TIMINGS
THRESHOLD 0.00000000001
&END
&END GLOBAL
&TEST
! check we can do a really large, really sparse matrix in short time.
! good to catch non-O(N) behavior in dbcsr.
! matrix size and sparsity are such that the test is fast for O(N)
! but slow for O(N**foo)
&DBM
K 400000
M 400000
N 400000
TRANSA FALSE
TRANSB TRUE
N_LOOP 3
ASPARSITY 0.99999
BSPARSITY 0.99999
CSPARSITY 0.99999
bs_m 1 4
bs_n 1 4
bs_k 1 4
&END
&END TEST