Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(type_crs_adjacency_element), | intent(inout) | :: | self | |||
type(holder_elements), | intent(in) | :: | elements(:) |
subroutine initialize_crs_adjacency(self, elements) class(type_crs_adjacency_element), intent(inout) :: self type(holder_elements), intent(in) :: elements(:) integer(int32) :: num_elements integer(int32) :: i, j integer(int32) :: pair_count, capacity integer(int32), allocatable :: coo_row(:), coo_col(:), temp_row(:), temp_col(:) num_elements = size(elements) self%num_row = num_elements if (num_elements <= 1) return ! --- Step 1 & 2: 隣接ペアを全探索で探し、一時的なCOO形式で格納 --- pair_count = 0 capacity = num_elements * 5 call allocate_array(coo_row, length=capacity) call allocate_array(coo_col, length=capacity) do i = 1, num_elements do j = i + 1, num_elements if (are_elements_adjacent(elements(i)%e, elements(j)%e)) then if ((pair_count + 2) > capacity) then capacity = capacity * 2 call allocate_array(temp_row, length=capacity) call allocate_array(temp_col, length=capacity) temp_row(1:pair_count) = coo_row(1:pair_count) temp_col(1:pair_count) = coo_col(1:pair_count) call deallocate_array(coo_row) call deallocate_array(coo_col) call move_alloc(temp_row, coo_row) call move_alloc(temp_col, coo_col) end if pair_count = pair_count + 1 coo_row(pair_count) = i coo_col(pair_count) = j pair_count = pair_count + 1 coo_row(pair_count) = j coo_col(pair_count) = i end if end do end do self%nnz = pair_count ! --- Step 3: COO形式からCRS形式へ変換 --- call allocate_array(self%ptr, length=self%num_row + 1_int32) call allocate_array(self%ind, length=self%nnz) self%ptr = 0 ! Pass 1: 各行の非ゼロ要素数(次数)をカウント do i = 1, self%nnz self%ptr(coo_row(i) + 1) = self%ptr(coo_row(i) + 1) + 1 end do ! Pass 2: 累積和を計算して、ptr配列を完成させる self%ptr(1) = 1 do i = 2, self%num_row + 1 self%ptr(i) = self%ptr(i) + self%ptr(i - 1) end do ! Pass 3: ind配列を構築する call allocate_array(temp_row, length=self%num_row) temp_row(:) = self%ptr(1:self%num_row) do i = 1, self%nnz j = temp_row(coo_row(i)) self%ind(j) = coo_col(i) temp_row(coo_row(i)) = j + 1 end do call deallocate_array(temp_row) call deallocate_array(coo_row) call deallocate_array(coo_col) end subroutine initialize_crs_adjacency