other/s_sparsemat.f90
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | submodule(m_sparsemat) s_sparsemat | ||
| 2 | implicit none | ||
| 3 | contains | ||
| 4 | |||
| 5 | 3753 | module subroutine init_sparsemat(this, nr_rows, nr_cols, nr_nonzero) | |
| 6 | class(SparseMat), intent(inout) :: this | ||
| 7 | integer, intent(in) :: nr_rows, nr_cols, nr_nonzero | ||
| 8 | |||
| 9 | 3753 | this%nr_rows = nr_rows | |
| 10 | 3753 | this%nr_cols = nr_cols | |
| 11 | 3753 | this%nr_nonzero = nr_nonzero | |
| 12 | |||
| 13 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 3753 times.
|
3753 | if (allocated(this%row_starts_at_nz)) deallocate (this%row_starts_at_nz) |
| 14 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 3753 times.
|
3753 | if (allocated(this%col_idx)) deallocate (this%col_idx) |
| 15 |
1/2✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 3753 times.
|
3753 | if (allocated(this%values)) deallocate (this%values) |
| 16 | |||
| 17 |
7/14✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 3753 times.
✓ Branch 10 → 9 taken 3753 times.
✗ Branch 10 → 11 not taken.
✓ Branch 11 → 12 taken 3753 times.
✗ Branch 11 → 13 not taken.
✓ Branch 13 → 14 taken 3753 times.
✗ Branch 13 → 15 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 3753 times.
✗ Branch 17 → 18 not taken.
✓ Branch 17 → 19 taken 3753 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 3753 times.
|
11259 | allocate (this%row_starts_at_nz(0:nr_rows)) |
| 18 |
9/14✓ Branch 21 → 22 taken 2153 times.
✓ Branch 21 → 23 taken 1600 times.
✓ Branch 23 → 22 taken 1600 times.
✗ Branch 23 → 24 not taken.
✓ Branch 24 → 25 taken 3753 times.
✗ Branch 24 → 26 not taken.
✓ Branch 26 → 27 taken 1600 times.
✓ Branch 26 → 28 taken 2153 times.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 3753 times.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 3753 times.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 34 taken 3753 times.
|
11259 | allocate (this%col_idx(0:nr_nonzero - 1)) |
| 19 |
9/14✓ Branch 34 → 35 taken 2153 times.
✓ Branch 34 → 36 taken 1600 times.
✓ Branch 36 → 35 taken 1600 times.
✗ Branch 36 → 37 not taken.
✓ Branch 37 → 38 taken 3753 times.
✗ Branch 37 → 39 not taken.
✓ Branch 39 → 40 taken 1600 times.
✓ Branch 39 → 41 taken 2153 times.
✗ Branch 41 → 42 not taken.
✓ Branch 41 → 43 taken 3753 times.
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 45 taken 3753 times.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 47 taken 3753 times.
|
11259 | allocate (this%values(0:nr_nonzero - 1)) |
| 20 | |||
| 21 | 3753 | this%row_prev = -1 | |
| 22 | 3753 | this%nonzero_curr = -1 | |
| 23 | |||
| 24 | 3753 | this%row_starts_at_nz(nr_rows) = nr_nonzero | |
| 25 | 3753 | end subroutine init_sparsemat | |
| 26 | |||
| 27 | 2700679 | module subroutine insert_sparsemat(this, row, col, val) | |
| 28 | class(SparseMat), intent(inout) :: this | ||
| 29 | integer, intent(in) :: row, col | ||
| 30 | real(wp), intent(in) :: val | ||
| 31 | |||
| 32 | integer :: i | ||
| 33 | |||
| 34 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 10 taken 2700679 times.
|
2700679 | if (row < this%row_prev) then |
| 35 | write (*, '(A,I0,A,I0)') "ERROR in SparseMat::insert_sparsemat: insertion of values must be done in increasing order of"// & | ||
| 36 | ✗ | & " rows. Attempted to insert row ", row, " after row ", this%row_prev | |
| 37 | ✗ | error stop 1 | |
| 38 | end if | ||
| 39 |
1/2✗ Branch 10 → 11 not taken.
✓ Branch 10 → 21 taken 2700679 times.
|
2700679 | if (row > this%nr_rows) then |
| 40 | write (*, '(A,I0,A,I0)') "ERROR in SparseMat::insert_sparsemat: row index out of bounds. " & | ||
| 41 | ✗ | //"Attempted row ", row, " but matrix has only ", this%nr_rows, " rows (max index: ", this%nr_rows - 1, ")" | |
| 42 | ✗ | error stop 1 | |
| 43 | end if | ||
| 44 |
2/4✓ Branch 21 → 22 taken 2700679 times.
✗ Branch 21 → 23 not taken.
✗ Branch 22 → 23 not taken.
✓ Branch 22 → 31 taken 2700679 times.
|
2700679 | if (col < 0 .or. col > this%nr_cols - 1) then |
| 45 | write (*, '(A,I0,A,I0,A,I0)') "ERROR in SparseMat::insert_sparsemat: column index out of bounds. " & | ||
| 46 | ✗ | //"Column index ", col, " must be in range [0, ", this%nr_cols - 1, "]" | |
| 47 | ✗ | error stop 1 | |
| 48 | end if | ||
| 49 | |||
| 50 | 2700679 | this%nonzero_curr = this%nonzero_curr + 1 | |
| 51 |
1/2✗ Branch 31 → 32 not taken.
✓ Branch 31 → 40 taken 2700679 times.
|
2700679 | if (this%nonzero_curr > this%nr_nonzero) then |
| 52 | write (*, '(A,I0,A,I0)') "ERROR in SparseMat::insert_sparsemat: too many nonzero elements. " & | ||
| 53 | ✗ | //"Attempted to insert element ", this%nonzero_curr, " but matrix was allocated for only ", this%nr_nonzero, & | |
| 54 | ✗ | & " nonzero elements" | |
| 55 | ✗ | error stop 1 | |
| 56 | end if | ||
| 57 |
2/2✓ Branch 41 → 42 taken 408800 times.
✓ Branch 41 → 43 taken 2700679 times.
|
3109479 | do i = this%row_prev + 1, row |
| 58 | 3109479 | this%row_starts_at_nz(i) = this%nonzero_curr | |
| 59 | end do | ||
| 60 | |||
| 61 | 2700679 | this%row_prev = row | |
| 62 | |||
| 63 | ! Insert the value at the specified position | ||
| 64 | 2700679 | this%col_idx(this%nonzero_curr) = col | |
| 65 | 2700679 | this%values(this%nonzero_curr) = val | |
| 66 | 2700679 | end subroutine insert_sparsemat | |
| 67 | |||
| 68 | 3753 | module subroutine finalize_sparsemat(this) | |
| 69 | class(SparseMat), intent(inout) :: this | ||
| 70 | |||
| 71 | integer :: i | ||
| 72 | |||
| 73 | 3753 | this%nr_nonzero = this%nonzero_curr + 1 | |
| 74 | |||
| 75 |
2/2✓ Branch 3 → 4 taken 302258 times.
✓ Branch 3 → 5 taken 3753 times.
|
306011 | do i = this%row_prev + 1, this%nr_rows |
| 76 | 306011 | this%row_starts_at_nz(i) = this%nr_nonzero | |
| 77 | end do | ||
| 78 | 3753 | end subroutine finalize_sparsemat | |
| 79 | |||
| 80 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1127 times.
|
1127 | module subroutine get_dense_sparsemat(this, dense_mat) |
| 81 | class(SparseMat), intent(in) :: this | ||
| 82 | real(wp), intent(out) :: dense_mat(0:, 0:) | ||
| 83 | |||
| 84 | integer :: i, j | ||
| 85 | |||
| 86 |
2/4✓ Branch 4 → 5 taken 1127 times.
✗ Branch 4 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 17 taken 1127 times.
|
1127 | if (size(dense_mat, 1) /= this%nr_rows .or. size(dense_mat, 2) /= this%nr_cols) then |
| 87 | write (*, '(A,I0,A,I0,A,I0,A,I0)') "ERROR in SparseMat::get_dense_sparsemat: output matrix size does not match. " & | ||
| 88 | ✗ | //"Expected size ", this%nr_rows, " x ", this%nr_cols, " but got ", size(dense_mat, 1), " x ", size(dense_mat, 2) | |
| 89 | ✗ | error stop 1 | |
| 90 | end if | ||
| 91 | |||
| 92 |
4/4✓ Branch 18 → 19 taken 23070 times.
✓ Branch 18 → 23 taken 1127 times.
✓ Branch 20 → 21 taken 11346414 times.
✓ Branch 20 → 22 taken 23070 times.
|
11370611 | dense_mat = 0.0_wp |
| 93 | |||
| 94 |
2/2✓ Branch 24 → 25 taken 213650 times.
✓ Branch 24 → 30 taken 1127 times.
|
214777 | do i = 0, this%nr_rows - 1 |
| 95 |
2/2✓ Branch 26 → 27 taken 213650 times.
✓ Branch 26 → 29 taken 1023817 times.
|
1238594 | do j = this%row_starts_at_nz(i), this%row_starts_at_nz(i + 1) - 1 |
| 96 | 1237467 | dense_mat(i, this%col_idx(j)) = this%values(j) | |
| 97 | end do | ||
| 98 | end do | ||
| 99 | 1127 | end subroutine get_dense_sparsemat | |
| 100 | |||
| 101 |
1/2✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 5 not taken.
|
1 | module subroutine copy_sparsemat(out, in) |
| 102 | class(SparseMat), intent(out) :: out | ||
| 103 | type(SparseMat), intent(in) :: in | ||
| 104 | |||
| 105 | ! Copy the basic properties | ||
| 106 | 1 | out%nr_rows = in%nr_rows | |
| 107 | 1 | out%nr_cols = in%nr_cols | |
| 108 | 1 | out%nr_nonzero = in%nr_nonzero | |
| 109 | |||
| 110 | ! Allocate memory for the data arrays | ||
| 111 |
7/14✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
✓ Branch 7 → 6 taken 1 time.
✗ Branch 7 → 8 not taken.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 10 not taken.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 12 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 1 time.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 1 time.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 1 time.
|
3 | allocate (out%row_starts_at_nz(0:out%nr_rows)) |
| 112 |
7/14✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 1 time.
✓ Branch 20 → 19 taken 1 time.
✗ Branch 20 → 21 not taken.
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 23 not taken.
✓ Branch 23 → 24 taken 1 time.
✗ Branch 23 → 25 not taken.
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 1 time.
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 29 taken 1 time.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 1 time.
|
3 | allocate (out%col_idx(0:out%nr_nonzero - 1)) |
| 113 |
7/14✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 1 time.
✓ Branch 33 → 32 taken 1 time.
✗ Branch 33 → 34 not taken.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 36 not taken.
✓ Branch 36 → 37 taken 1 time.
✗ Branch 36 → 38 not taken.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 40 taken 1 time.
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 42 taken 1 time.
✗ Branch 42 → 43 not taken.
✓ Branch 42 → 44 taken 1 time.
|
3 | allocate (out%values(0:out%nr_nonzero - 1)) |
| 114 | |||
| 115 | ! Copy the data | ||
| 116 |
4/10✓ Branch 44 → 45 taken 1 time.
✗ Branch 44 → 46 not taken.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 52 taken 1 time.
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 48 not taken.
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 50 not taken.
✓ Branch 53 → 54 taken 4 times.
✓ Branch 53 → 55 taken 1 time.
|
6 | out%row_starts_at_nz = in%row_starts_at_nz |
| 117 |
4/10✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 57 not taken.
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 63 taken 1 time.
✗ Branch 57 → 58 not taken.
✗ Branch 57 → 59 not taken.
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 61 not taken.
✓ Branch 64 → 65 taken 5 times.
✓ Branch 64 → 66 taken 1 time.
|
7 | out%col_idx = in%col_idx |
| 118 |
4/10✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 68 not taken.
✗ Branch 67 → 68 not taken.
✓ Branch 67 → 74 taken 1 time.
✗ Branch 68 → 69 not taken.
✗ Branch 68 → 70 not taken.
✗ Branch 70 → 71 not taken.
✗ Branch 70 → 72 not taken.
✓ Branch 75 → 76 taken 5 times.
✓ Branch 75 → 77 taken 1 time.
|
7 | out%values = in%values |
| 119 | 1 | end subroutine copy_sparsemat | |
| 120 | |||
| 121 |
1/2✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 5 not taken.
|
1 | module subroutine hcat_sparsemat(out, A, B) |
| 122 | class(SparseMat), intent(out) :: out | ||
| 123 | type(SparseMat), intent(in) :: A, B | ||
| 124 | |||
| 125 | integer :: i, j, total_nz | ||
| 126 | |||
| 127 | ! Check that the number of rows match | ||
| 128 |
1/2✗ Branch 5 → 6 not taken.
✓ Branch 5 → 14 taken 1 time.
|
1 | if (A%nr_rows /= B%nr_rows) then |
| 129 | write (*, '(A,I0,A,I0)') "ERROR in SparseMat::hcat_sparsemat: number of rows do not match. " & | ||
| 130 | ✗ | //"Matrix A has ", A%nr_rows, " rows but Matrix B has ", B%nr_rows, " rows." | |
| 131 | ✗ | error stop 1 | |
| 132 | end if | ||
| 133 | |||
| 134 | ! Calculate total number of non-zero elements | ||
| 135 | 1 | total_nz = A%nr_nonzero + B%nr_nonzero | |
| 136 | |||
| 137 | ! Initialize the output sparse matrix | ||
| 138 | 1 | call out%init(A%nr_rows, A%nr_cols + B%nr_cols, total_nz) | |
| 139 | |||
| 140 | ! Fill in the data from matrices A and B | ||
| 141 |
2/2✓ Branch 16 → 17 taken 3 times.
✓ Branch 16 → 28 taken 1 time.
|
4 | do i = 0, A%nr_rows - 1 |
| 142 | |||
| 143 | ! Insert elements from matrix A | ||
| 144 |
2/2✓ Branch 18 → 19 taken 3 times.
✓ Branch 18 → 21 taken 3 times.
|
6 | do j = A%row_starts_at_nz(i), A%row_starts_at_nz(i + 1) - 1 |
| 145 | 6 | call out%insert(i, A%col_idx(j), A%values(j)) | |
| 146 | end do | ||
| 147 | |||
| 148 | ! Insert elements from matrix B with adjusted column indices | ||
| 149 |
2/2✓ Branch 23 → 24 taken 2 times.
✓ Branch 23 → 26 taken 3 times.
|
6 | do j = B%row_starts_at_nz(i), B%row_starts_at_nz(i + 1) - 1 |
| 150 | 5 | call out%insert(i, B%col_idx(j) + A%nr_cols, B%values(j)) | |
| 151 | end do | ||
| 152 | end do | ||
| 153 | |||
| 154 | ! Finalize the output sparse matrix | ||
| 155 | 1 | call out%finalize() | |
| 156 | 1 | end subroutine hcat_sparsemat | |
| 157 | |||
| 158 | 1949 | module subroutine destroy_sparsemat(this) | |
| 159 | class(SparseMat), intent(inout) :: this | ||
| 160 | |||
| 161 |
1/2✓ Branch 2 → 3 taken 1949 times.
✗ Branch 2 → 4 not taken.
|
1949 | if (allocated(this%row_starts_at_nz)) deallocate (this%row_starts_at_nz) |
| 162 |
1/2✓ Branch 4 → 5 taken 1949 times.
✗ Branch 4 → 6 not taken.
|
1949 | if (allocated(this%col_idx)) deallocate (this%col_idx) |
| 163 |
1/2✓ Branch 6 → 7 taken 1949 times.
✗ Branch 6 → 8 not taken.
|
1949 | if (allocated(this%values)) deallocate (this%values) |
| 164 | 1949 | end subroutine destroy_sparsemat | |
| 165 | |||
| 166 | end submodule s_sparsemat | ||
| 167 |