1414
1515 implicit none
1616
17+ type searched_and_ordered_t
18+ integer , allocatable , dimension (:) :: s, o
19+ end type
20+
1721contains
1822
1923 module procedure construct_from_components
@@ -30,50 +34,44 @@ pure module function topological_sort(dag) result(order)
3034 call assert(all (dag% vertices(:)% edges_allocated()), " dag_s topological_sort: all(dag%vertices(:)%edges_allocated())" )
3135
3236 block
33- integer , allocatable :: discovered(:), searched(:)
37+ type (searched_and_ordered_t) searched_and_ordered
3438 integer v
3539
36- allocate (discovered( 0 ), order( 0 ), searched( 0 ) )
40+ searched_and_ordered = searched_and_ordered_t(s = [ integer :: ], o = [ integer :: ] )
3741
38- do v = 1 , size (dag% vertices)
39- if (.not. any (v == searched)) then
40- call depth_first_search(v, [integer :: ], searched, order)
41- discovered = [discovered, searched]
42- searched = discovered
43- end if
42+ do concurrent(v = 1 :size (dag% vertices))
43+ if (.not. any (v == searched_and_ordered% s)) &
44+ searched_and_ordered = depth_first_search(v, [integer :: ], searched_and_ordered% o)
4445 end do
46+ order = searched_and_ordered% o
4547 end block
4648
4749 contains
4850
49- pure recursive subroutine depth_first_search(v, d, s, o )
50- integer , intent (in ) :: v, d(:)
51- integer , intent (out ), allocatable :: s(:)
52- integer , intent ( inout ), allocatable :: o(:)
51+ pure recursive function depth_first_search(v, d, o) result(hybrid )
52+ integer , intent (in ) :: v
53+ integer , intent (in ), dimension (:) :: d, o
54+ type (searched_and_ordered_t) hybrid
5355
5456 call assert(.not. any (v == d), " depth_first_search: cycle detected" , intrinsic_array_t([v,d]))
5557
56- block
57- integer , allocatable :: dependencies(:), s_local(:), d_local(:)
58- integer w
59-
60- dependencies = dag% depends_on(v)
58+ hybrid = searched_and_ordered_t(s = [integer :: ], o = o)
6159
62- allocate (s_local(0 ), d_local(0 ))
60+ associate(dependencies = > dag% depends_on(v))
61+ block
62+ integer w
63+ do concurrent(w = 1 :size (dependencies))
64+ associate(w_dependencies = > dependencies(w))
65+ if (.not. any (w_dependencies == hybrid% s)) hybrid = depth_first_search(w_dependencies, [d, v], hybrid% o)
66+ end associate
67+ end do
68+ end block
69+ end associate
6370
64- do w = 1 , size (dependencies)
65- if (.not. any (dependencies(w) == s_local)) then
66- call depth_first_search(dependencies(w), [d, v], s_local, o)
67- d_local = [d_local, s_local]
68- s_local = d_local
69- end if
70- end do
71-
72- if (.not. any (v == o)) o = [v, o]
73- s = [v, s_local]
74- end block
71+ if (.not. any (v == hybrid% o)) hybrid% o = [v, hybrid% o]
72+ hybrid = searched_and_ordered_t(s = [v, hybrid% s], o = hybrid% o)
7573
76- end subroutine
74+ end function
7775
7876 end function topological_sort
7977
0 commit comments