14
14
15
15
implicit none
16
16
17
+ type searched_and_ordered_t
18
+ integer , allocatable , dimension (:) :: s, o
19
+ end type
20
+
17
21
contains
18
22
19
23
module procedure construct_from_components
@@ -30,50 +34,44 @@ pure module function topological_sort(dag) result(order)
30
34
call assert(all (dag% vertices(:)% edges_allocated()), " dag_s topological_sort: all(dag%vertices(:)%edges_allocated())" )
31
35
32
36
block
33
- integer , allocatable :: discovered(:), searched(:)
37
+ type (searched_and_ordered_t) searched_and_ordered
34
38
integer v
35
39
36
- allocate (discovered( 0 ), order( 0 ), searched( 0 ) )
40
+ searched_and_ordered = searched_and_ordered_t(s = [ integer :: ], o = [ integer :: ] )
37
41
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)
44
45
end do
46
+ order = searched_and_ordered% o
45
47
end block
46
48
47
49
contains
48
50
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
53
55
54
56
call assert(.not. any (v == d), " depth_first_search: cycle detected" , intrinsic_array_t([v,d]))
55
57
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)
61
59
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
63
70
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)
75
73
76
- end subroutine
74
+ end function
77
75
78
76
end function topological_sort
79
77
0 commit comments