mirror of
https://github.com/sfilippone/psblas3.git
synced 2026-10-18 03:42:09 +00:00
[UPDATE] User-friendly row queries on the nested matrix
Add get_owned_rows(i_field) and get_owned_row_count(i_field) to psb_d_nest_matrix: the list of GLOBAL row indices of a field owned by the calling process (i.e. the rows it is expected to insert through ins) and their count. They replace the descriptor-level idiom field_desc(i)%get_local_rows() / field_desc(i)%l2g(...) in user code, which leaked descriptor jargon into the build loop. The high-level tests (glob, rect, builder) are rewritten on the new queries; the low-level CG test intentionally keeps the descriptor path. README updated with the new queries and an example. Author: Simone Staccone (Stack-1)
This commit is contained in:
@@ -100,6 +100,10 @@ module psb_d_nest_builder_mod
|
||||
procedure, pass(op) :: ins => psb_d_nest_op_ins
|
||||
procedure, pass(op) :: asb => psb_d_nest_op_asb
|
||||
procedure, pass(op) :: free => psb_d_nest_op_free
|
||||
! user-friendly queries on the field row distribution (no descriptor
|
||||
! jargon needed: these replace field_desc(i)%get_local_rows() / %l2g(...))
|
||||
procedure, pass(op) :: get_owned_rows => psb_d_nest_op_get_owned_rows
|
||||
procedure, pass(op) :: get_owned_row_count => psb_d_nest_op_get_owned_row_count
|
||||
end type psb_d_nest_matrix
|
||||
|
||||
private
|
||||
@@ -306,6 +310,41 @@ contains
|
||||
op%assembled = .false.
|
||||
end subroutine psb_d_nest_op_free
|
||||
|
||||
! get_owned_rows: GLOBAL indices (in the field index space, 1..field size)
|
||||
! of the rows of field i_field owned by this process. This is the list of
|
||||
! rows the process is expected to insert through ins:
|
||||
!
|
||||
! my_rows = nested_matrix%get_owned_rows(1)
|
||||
! do k = 1, size(my_rows)
|
||||
! global_row = my_rows(k)
|
||||
! ...
|
||||
!
|
||||
! An empty array is returned for an out-of-range field index.
|
||||
function psb_d_nest_op_get_owned_rows(op, i_field) result(owned_global_rows)
|
||||
class(psb_d_nest_matrix), intent(in) :: op
|
||||
integer(psb_ipk_), intent(in) :: i_field
|
||||
integer(psb_lpk_), allocatable :: owned_global_rows(:)
|
||||
|
||||
if ((i_field < 1) .or. (i_field > op%n_fields) .or. &
|
||||
& (.not. allocated(op%field_desc))) then
|
||||
allocate(owned_global_rows(0))
|
||||
return
|
||||
end if
|
||||
owned_global_rows = op%field_desc(i_field)%get_global_indices(owned=.true.)
|
||||
end function psb_d_nest_op_get_owned_rows
|
||||
|
||||
! get_owned_row_count: how many rows of field i_field this process owns
|
||||
function psb_d_nest_op_get_owned_row_count(op, i_field) result(owned_row_count)
|
||||
class(psb_d_nest_matrix), intent(in) :: op
|
||||
integer(psb_ipk_), intent(in) :: i_field
|
||||
integer(psb_ipk_) :: owned_row_count
|
||||
|
||||
owned_row_count = 0
|
||||
if ((i_field < 1) .or. (i_field > op%n_fields) .or. &
|
||||
& (.not. allocated(op%field_desc))) return
|
||||
owned_row_count = op%field_desc(i_field)%get_local_rows()
|
||||
end function psb_d_nest_op_get_owned_row_count
|
||||
|
||||
!-----------------------------------------------------------------
|
||||
! private helpers: growing triplet buffer
|
||||
!-----------------------------------------------------------------
|
||||
|
||||
+19
-1
@@ -82,9 +82,27 @@ use psb_d_nest_mod
|
||||
|--------|---------|
|
||||
| `a_glob` | `type(psb_dspmat_type)` — the assembled global operator; pass it to `psb_spmm`, `psb_krylov`, `prec%build` |
|
||||
| `desc_glob` | `type(psb_desc_type)` — the composed global descriptor; pass it wherever a descriptor is expected |
|
||||
| `field_desc(i)` | `type(psb_desc_type)` — the descriptor of field `i` (query `%get_local_rows()`, `%l2g(...)` to find the rows owned by this process) |
|
||||
| `field_desc(i)` | `type(psb_desc_type)` — the descriptor of field `i` (advanced use; for the common queries see `get_owned_rows` below) |
|
||||
| `n_fields` | number of fields |
|
||||
|
||||
To know which rows it must insert, a process asks the matrix directly — no
|
||||
descriptor jargon needed:
|
||||
|
||||
```fortran
|
||||
integer(psb_lpk_), allocatable :: my_rows(:)
|
||||
|
||||
my_rows = nested_matrix%get_owned_rows(1) ! global rows of field 1 owned here
|
||||
do k = 1, size(my_rows)
|
||||
global_row = my_rows(k)
|
||||
... ! build the entries of this row
|
||||
end do
|
||||
```
|
||||
|
||||
| Query | Result |
|
||||
|-------|--------|
|
||||
| `nested_matrix%get_owned_rows(i_field)` | `integer(psb_lpk_), allocatable (:)` — the GLOBAL indices (in the field index space, 1..field size) of the rows of field `i_field` owned by this process |
|
||||
| `nested_matrix%get_owned_row_count(i_field)` | `integer(psb_ipk_)` — how many rows of field `i_field` this process owns |
|
||||
|
||||
Methods (collective over the communicator unless noted):
|
||||
|
||||
#### `call nested_matrix%init(ctxt, field_sizes, info)`
|
||||
|
||||
@@ -64,6 +64,7 @@ program psb_d_nest_builder_test
|
||||
real(psb_dpk_) :: insert_value(1)
|
||||
|
||||
integer(psb_lpk_), allocatable :: entry_rows(:), entry_cols(:)
|
||||
integer(psb_lpk_), allocatable :: field1_rows(:), field2_rows(:)
|
||||
real(psb_dpk_), allocatable :: entry_vals(:)
|
||||
|
||||
real(psb_dpk_) :: stop_tol, final_residual, norm_x_exact, solution_error
|
||||
@@ -87,8 +88,10 @@ program psb_d_nest_builder_test
|
||||
end if
|
||||
|
||||
! rows owned by this process in each field
|
||||
field1_local_rows = nested_matrix%field_desc(1)%get_local_rows()
|
||||
field2_local_rows = nested_matrix%field_desc(2)%get_local_rows()
|
||||
field1_rows = nested_matrix%get_owned_rows(1)
|
||||
field2_rows = nested_matrix%get_owned_rows(2)
|
||||
field1_local_rows = size(field1_rows)
|
||||
field2_local_rows = size(field2_rows)
|
||||
|
||||
!---------------------------------------------------------------
|
||||
! 2) insert the values, one block at a time (owned rows only)
|
||||
@@ -96,7 +99,7 @@ program psb_d_nest_builder_test
|
||||
! block (1,1) = 2I
|
||||
allocate(entry_rows(field1_local_rows), entry_cols(field1_local_rows), entry_vals(field1_local_rows))
|
||||
do i_local_row = 1, field1_local_rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, field1_global_row, info)
|
||||
field1_global_row = field1_rows(i_local_row)
|
||||
entry_rows(i_local_row)=field1_global_row; entry_cols(i_local_row)=field1_global_row
|
||||
entry_vals(i_local_row)=2.0_psb_dpk_
|
||||
end do
|
||||
@@ -106,7 +109,7 @@ program psb_d_nest_builder_test
|
||||
! block (2,2) = 2I
|
||||
allocate(entry_rows(field2_local_rows), entry_cols(field2_local_rows), entry_vals(field2_local_rows))
|
||||
do i_local_row = 1, field2_local_rows
|
||||
call nested_matrix%field_desc(2)%l2g(i_local_row, field2_global_row, info)
|
||||
field2_global_row = field2_rows(i_local_row)
|
||||
entry_rows(i_local_row)=field2_global_row; entry_cols(i_local_row)=field2_global_row
|
||||
entry_vals(i_local_row)=2.0_psb_dpk_
|
||||
end do
|
||||
@@ -117,7 +120,7 @@ program psb_d_nest_builder_test
|
||||
allocate(entry_rows(2*field1_local_rows), entry_cols(2*field1_local_rows), entry_vals(2*field1_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, field1_local_rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, field1_global_row, info)
|
||||
field1_global_row = field1_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = field1_global_row
|
||||
entry_cols(entry_idx) = field1_global_row
|
||||
@@ -136,7 +139,7 @@ program psb_d_nest_builder_test
|
||||
allocate(entry_rows(2*field2_local_rows), entry_cols(2*field2_local_rows), entry_vals(2*field2_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, field2_local_rows
|
||||
call nested_matrix%field_desc(2)%l2g(i_local_row, field2_global_row, info)
|
||||
field2_global_row = field2_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = field2_global_row
|
||||
entry_cols(entry_idx) = field2_global_row
|
||||
|
||||
@@ -69,6 +69,7 @@ program psb_d_nest_glob_test
|
||||
type(psb_d_vect_type) :: x_vec, y_nested, y_monolithic
|
||||
|
||||
integer(psb_lpk_), allocatable :: entry_rows(:), entry_cols(:)
|
||||
integer(psb_lpk_), allocatable :: field1_rows(:), field2_rows(:)
|
||||
real(psb_dpk_), allocatable :: entry_vals(:)
|
||||
real(psb_dpk_) :: insert_value(1)
|
||||
real(psb_dpk_) :: mismatch_norm
|
||||
@@ -86,8 +87,10 @@ program psb_d_nest_glob_test
|
||||
if (info /= psb_success_) then
|
||||
if (my_rank==0) write(*,*) 'FAIL: nested_matrix%init info=', info; goto 9999
|
||||
end if
|
||||
field1_local_rows = nested_matrix%field_desc(1)%get_local_rows()
|
||||
field2_local_rows = nested_matrix%field_desc(2)%get_local_rows()
|
||||
field1_rows = nested_matrix%get_owned_rows(1)
|
||||
field2_rows = nested_matrix%get_owned_rows(2)
|
||||
field1_local_rows = size(field1_rows)
|
||||
field2_local_rows = size(field2_rows)
|
||||
|
||||
!---------------------------------------------------------------
|
||||
! 2) insert the block values (owned rows only)
|
||||
@@ -97,7 +100,7 @@ program psb_d_nest_glob_test
|
||||
& entry_vals(3*field1_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, field1_local_rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, global_row, info)
|
||||
global_row = field1_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = global_row
|
||||
entry_cols(entry_idx) = global_row
|
||||
@@ -122,7 +125,7 @@ program psb_d_nest_glob_test
|
||||
allocate(entry_rows(field1_local_rows), entry_cols(field1_local_rows), entry_vals(field1_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, field1_local_rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, global_row, info)
|
||||
global_row = field1_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = global_row
|
||||
entry_cols(entry_idx) = global_row
|
||||
@@ -135,7 +138,7 @@ program psb_d_nest_glob_test
|
||||
allocate(entry_rows(field2_local_rows), entry_cols(field2_local_rows), entry_vals(field2_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, field2_local_rows
|
||||
call nested_matrix%field_desc(2)%l2g(i_local_row, global_row, info)
|
||||
global_row = field2_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = global_row
|
||||
entry_cols(entry_idx) = global_row
|
||||
@@ -158,7 +161,7 @@ program psb_d_nest_glob_test
|
||||
call psb_spall(monolithic_ref, nested_matrix%desc_glob, info, &
|
||||
& nnz=5*nested_matrix%desc_glob%get_local_rows())
|
||||
do i_local_row = 1, field1_local_rows ! field-1 rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, global_row, info)
|
||||
global_row = field1_rows(i_local_row)
|
||||
insert_value(1) = 2.0_psb_dpk_
|
||||
call psb_spins(1,[global_row],[global_row],insert_value,monolithic_ref,nested_matrix%desc_glob,info)
|
||||
if (global_row > 1) then
|
||||
@@ -174,7 +177,7 @@ program psb_d_nest_glob_test
|
||||
call psb_spins(1,[global_row],[global_col],insert_value,monolithic_ref,nested_matrix%desc_glob,info)
|
||||
end do
|
||||
do i_local_row = 1, field2_local_rows ! field-2 rows
|
||||
call nested_matrix%field_desc(2)%l2g(i_local_row, global_row, info)
|
||||
global_row = field2_rows(i_local_row)
|
||||
global_col = global_row
|
||||
insert_value(1) = 0.3_psb_dpk_ ! B
|
||||
call psb_spins(1,[field_size+global_row],[global_col],insert_value,monolithic_ref,nested_matrix%desc_glob,info)
|
||||
|
||||
@@ -65,6 +65,7 @@ program psb_d_nest_rect_test
|
||||
real(psb_dpk_) :: insert_value(1)
|
||||
|
||||
integer(psb_lpk_), allocatable :: entry_rows(:), entry_cols(:)
|
||||
integer(psb_lpk_), allocatable :: v_rows(:), q_rows(:)
|
||||
real(psb_dpk_), allocatable :: entry_vals(:)
|
||||
real(psb_dpk_) :: mismatch_norm
|
||||
real(psb_dpk_), parameter :: tolerance = 1.0e-10_psb_dpk_
|
||||
@@ -82,8 +83,10 @@ program psb_d_nest_rect_test
|
||||
if (info /= psb_success_) then
|
||||
if (my_rank==0) write(*,*) 'FAIL: nested_matrix%init info=', info; goto 9999
|
||||
end if
|
||||
v_local_rows = nested_matrix%field_desc(1)%get_local_rows()
|
||||
q_local_rows = nested_matrix%field_desc(2)%get_local_rows()
|
||||
v_rows = nested_matrix%get_owned_rows(1)
|
||||
q_rows = nested_matrix%get_owned_rows(2)
|
||||
v_local_rows = size(v_rows)
|
||||
q_local_rows = size(q_rows)
|
||||
|
||||
!---------------------------------------------------------------
|
||||
! 2) insert the blocks (owned rows only)
|
||||
@@ -92,7 +95,7 @@ program psb_d_nest_rect_test
|
||||
allocate(entry_rows(3*v_local_rows), entry_cols(3*v_local_rows), entry_vals(3*v_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, v_local_rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, v_global_row, info)
|
||||
v_global_row = v_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = v_global_row
|
||||
entry_cols(entry_idx) = v_global_row
|
||||
@@ -117,7 +120,7 @@ program psb_d_nest_rect_test
|
||||
allocate(entry_rows(v_local_rows), entry_cols(v_local_rows), entry_vals(v_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, v_local_rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, v_global_row, info)
|
||||
v_global_row = v_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = v_global_row
|
||||
entry_cols(entry_idx) = mod(v_global_row-1_psb_lpk_, q_size)+1
|
||||
@@ -130,7 +133,7 @@ program psb_d_nest_rect_test
|
||||
allocate(entry_rows(2*q_local_rows), entry_cols(2*q_local_rows), entry_vals(2*q_local_rows))
|
||||
entry_idx = 0
|
||||
do i_local_row = 1, q_local_rows
|
||||
call nested_matrix%field_desc(2)%l2g(i_local_row, q_global_row, info)
|
||||
q_global_row = q_rows(i_local_row)
|
||||
entry_idx = entry_idx + 1
|
||||
entry_rows(entry_idx) = q_global_row
|
||||
entry_cols(entry_idx) = q_global_row
|
||||
@@ -156,7 +159,7 @@ program psb_d_nest_rect_test
|
||||
call psb_spall(monolithic_ref, nested_matrix%desc_glob, info, &
|
||||
& nnz=6*nested_matrix%desc_glob%get_local_rows())
|
||||
do i_local_row = 1, v_local_rows ! V rows
|
||||
call nested_matrix%field_desc(1)%l2g(i_local_row, v_global_row, info)
|
||||
v_global_row = v_rows(i_local_row)
|
||||
insert_value(1)=2.0_psb_dpk_
|
||||
call psb_spins(1,[v_global_row],[v_global_row],insert_value,monolithic_ref,nested_matrix%desc_glob,info)
|
||||
if (v_global_row>1) then
|
||||
@@ -172,7 +175,7 @@ program psb_d_nest_rect_test
|
||||
call psb_spins(1,[v_global_row],[q_col],insert_value,monolithic_ref,nested_matrix%desc_glob,info)
|
||||
end do
|
||||
do i_local_row = 1, q_local_rows ! Q rows
|
||||
call nested_matrix%field_desc(2)%l2g(i_local_row, q_global_row, info)
|
||||
q_global_row = q_rows(i_local_row)
|
||||
insert_value(1)=0.3_psb_dpk_
|
||||
call psb_spins(1,[v_size+q_global_row],[q_global_row], insert_value,monolithic_ref,nested_matrix%desc_glob,info) ! col q
|
||||
call psb_spins(1,[v_size+q_global_row],[q_global_row+q_size],insert_value,monolithic_ref,nested_matrix%desc_glob,info) ! col q+nQ
|
||||
|
||||
Reference in New Issue
Block a user