subroutine build_csr_from_edges(self, edge_i_in, edge_j_in, edge_count_in)
class(type_node_adjacency), intent(inout) :: self
integer(int32), intent(in) :: edge_i_in(:), edge_j_in(:), edge_count_in
integer(int64), allocatable :: sort_keys(:)
integer(int32), allocatable :: temp_deg(:), temp_pos(:)
integer(int32) :: unique_count, i, n1, n2, total_adj
if (edge_count_in == 0) then
call allocate_array(self%ptr, self%num_nodes + 1_int32)
call allocate_array(self%ind, 0_int32)
self%ptr = 1
return
end if
call allocate_array(sort_keys, int(edge_count_in, kind=int64))
do i = 1, edge_count_in
sort_keys(i) = int(edge_i_in(i), int64) * (self%num_nodes + 1) &
+ int(edge_j_in(i), int64)
end do
call sort(sort_keys)
unique_count = 1
do i = 2, edge_count_in
if (sort_keys(i) > sort_keys(i - 1)) then
unique_count = unique_count + 1
sort_keys(unique_count) = sort_keys(i)
end if
end do
call allocate_array(temp_deg, self%num_nodes)
temp_deg = 0
do i = 1, unique_count
n1 = int(sort_keys(i) / (self%num_nodes + 1))
n2 = int(mod(sort_keys(i), int(self%num_nodes + 1, int64)))
temp_deg(n1) = temp_deg(n1) + 1
temp_deg(n2) = temp_deg(n2) + 1
end do
call allocate_array(self%ptr, self%num_nodes + 1_int32)
self%ptr(1) = 1
do i = 1, self%num_nodes
self%ptr(i + 1) = self%ptr(i) + temp_deg(i)
end do
total_adj = self%ptr(self%num_nodes + 1) - 1
call allocate_array(self%ind, total_adj)
call allocate_array(temp_pos, self%num_nodes)
temp_pos = self%ptr(1:self%num_nodes)
do i = 1, unique_count
n1 = int(sort_keys(i) / (self%num_nodes + 1))
n2 = int(mod(sort_keys(i), int(self%num_nodes + 1, int64)))
self%ind(temp_pos(n1)) = n2
temp_pos(n1) = temp_pos(n1) + 1
self%ind(temp_pos(n2)) = n1
temp_pos(n2) = temp_pos(n2) + 1
end do
call deallocate_array(sort_keys)
call deallocate_array(temp_deg)
call deallocate_array(temp_pos)
end subroutine build_csr_from_edges