Contract tensors by multiplying matrix representations. tensor_3(map_1, map_2) := alpha * tensor_1(notcontract_1, contract_1) * tensor_2(contract_2, notcontract_2) + beta * tensor_3(map_1, map_2)
Note
note 1: block sizes of the corresponding indices need to be the same in all tensors.
note 2: for best performance the tensors should have been created in matrix layouts compatible with the contraction, e.g. tensor_1 should have been created with either map1_2d == contract_1 and map2_2d == notcontract_1 or map1_2d == notcontract_1 and map2_2d == contract_1 (the same with tensor_2 and contract_2 / notcontract_2 and with tensor_3 and map_1 / map_2). Furthermore the two largest tensors involved in the contraction should map both to either tall or short matrices: the largest matrix dimension should be "on the same side" and should have identical distribution (which is always the case if the distributions were obtained with dbcsr_t_default_distvec).
note 3: if the same tensor occurs in multiple contractions, a different tensor object should be created for each contraction and the data should be copied between the tensors by use of dbcsr_t_copy. If the same tensor object is used in multiple contractions, matrix layouts are not compatible for all contractions (see note 2).
note 4: automatic optimizations are enabled by using the feature of batched contraction, see dbcsr_t_batched_contract_init, dbcsr_t_batched_contract_finalize. The arguments bounds_1, bounds_2, bounds_3 give the index ranges of the batches.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(dbcsr_scalar_type), | intent(in) | :: | alpha | |||
type(dbcsr_t_type), | intent(inout), | TARGET | :: | tensor_1 |
first tensor (in) |
|
type(dbcsr_t_type), | intent(inout), | TARGET | :: | tensor_2 |
second tensor (in) |
|
type(dbcsr_scalar_type), | intent(in) | :: | beta | |||
type(dbcsr_t_type), | intent(inout), | TARGET | :: | tensor_3 |
contracted tensor (out) |
|
integer, | intent(in), | DIMENSION(:) | :: | contract_1 |
indices of tensor_1 to contract |
|
integer, | intent(in), | DIMENSION(:) | :: | notcontract_1 |
indices of tensor_1 not to contract |
|
integer, | intent(in), | DIMENSION(:) | :: | contract_2 |
indices of tensor_2 to contract (1:1 with contract_1) |
|
integer, | intent(in), | DIMENSION(:) | :: | notcontract_2 |
indices of tensor_2 not to contract |
|
integer, | intent(in), | DIMENSION(:) | :: | map_1 |
which indices of tensor_3 map to non-contracted indices of tensor_1 (1:1 with notcontract_1) |
|
integer, | intent(in), | DIMENSION(:) | :: | map_2 |
which indices of tensor_3 map to non-contracted indices of tensor_2 (1:1 with notcontract_2) |
|
integer, | intent(in), | optional, | DIMENSION(2, SIZE(contract_1)) | :: | bounds_1 |
bounds corresponding to contract_1 AKA contract_2: start and end index of an index range over which to contract. For use in batched contraction. |
integer, | intent(in), | optional, | DIMENSION(2, SIZE(notcontract_1)) | :: | bounds_2 |
bounds corresponding to notcontract_1: start and end index of an index range. For use in batched contraction. |
integer, | intent(in), | optional, | DIMENSION(2, SIZE(notcontract_2)) | :: | bounds_3 |
bounds corresponding to notcontract_2: start and end index of an index range. For use in batched contraction. |
logical, | intent(in), | optional | :: | optimize_dist |
Whether distribution should be optimized internally. In the current implementation this guarantees optimal parameters only for dense matrices. |
|
type(dbcsr_t_pgrid_type), | intent(out), | optional, | POINTER | :: | pgrid_opt_1 |
Optionally return optimal process grid for tensor_1. This can be used to choose optimal process grids for subsequent tensor contractions with tensors of similar shape and sparsity. Under some conditions, pgrid_opt_1 can not be returned, in this case the pointer is not associated. |
type(dbcsr_t_pgrid_type), | intent(out), | optional, | POINTER | :: | pgrid_opt_2 |
Optionally return optimal process grid for tensor_2. |
type(dbcsr_t_pgrid_type), | intent(out), | optional, | POINTER | :: | pgrid_opt_3 |
Optionally return optimal process grid for tensor_3. |
real(kind=real_8), | intent(in), | optional | :: | filter_eps |
As in DBCSR mm |
|
integer(kind=int_8), | intent(out), | optional | :: | flop |
As in DBCSR mm |
|
logical, | intent(in), | optional | :: | move_data |
memory optimization: transfer data such that tensor_1 and tensor_2 are empty on return |
|
logical, | intent(in), | optional | :: | retain_sparsity |
enforce the sparsity pattern of the existing tensor_3; default is no |
|
integer, | intent(in), | optional | :: | unit_nr |
output unit for logging set it to -1 on ranks that should not write (and any valid unit number on ranks that should write output) if 0 on ALL ranks, no output is written |
|
logical, | intent(in), | optional | :: | log_verbose |
verbose logging (for testing only) |