@@ -88,6 +88,7 @@ from libc.stdio cimport fprintf, printf, stderr
88
88
89
89
# It would really be nice if these were modules. The 'include' syntax is long deprecated and adds a lot to compilation times
90
90
include ' basic_path_finding.pyx'
91
+ include ' parallel_numpy.pyx'
91
92
92
93
@ cython.embedsignature (True )
93
94
cdef class RouteChoiceSet:
@@ -136,6 +137,7 @@ cdef class RouteChoiceSet:
136
137
self .a_star = False
137
138
138
139
self .ids_graph_view = graph.compact_graph.id.values
140
+ self .graph_compressed_id_view = graph.graph.__compressed_id__.values
139
141
self .num_nodes = graph.compact_num_nodes
140
142
self .num_links = graph.compact_num_links
141
143
self .zones = graph.num_zones
@@ -820,7 +822,8 @@ cdef class RouteChoiceSet:
820
822
821
823
return prob_vec
822
824
823
- def link_loading (RouteChoiceSet self , matrix , generate_path_files: bool = False ):
825
+ @ cython.embedsignature (True )
826
+ def link_loading (RouteChoiceSet self , matrix , generate_path_files: bool = False , cores: int = 0 ):
824
827
if self .ods == nullptr \
825
828
or self .link_union_set == nullptr \
826
829
or self .prob_set == nullptr:
@@ -829,6 +832,8 @@ cdef class RouteChoiceSet:
829
832
if not isinstance (matrix, AequilibraeMatrix):
830
833
raise ValueError (" `matrix` is not an AequilibraE matrix" )
831
834
835
+ cores = cores if cores > 0 else openmp.omp_get_num_threads()
836
+
832
837
cdef:
833
838
vector[vector[double ] * ] * path_files = < vector[vector[double ] * ] * > nullptr
834
839
vector[double ] * ll
@@ -838,7 +843,8 @@ cdef class RouteChoiceSet:
838
843
deref(self .ods),
839
844
deref(self .results),
840
845
deref(self .link_union_set),
841
- deref(self .prob_set)
846
+ deref(self .prob_set),
847
+ cores,
842
848
)
843
849
tmp = []
844
850
for vec in deref(path_files):
@@ -853,7 +859,17 @@ cdef class RouteChoiceSet:
853
859
)
854
860
else :
855
861
ll = self .apply_link_loading(m)
856
- return deref(ll)
862
+
863
+ actual = np.zeros((self .graph_compressed_id_view.shape[0 ], 1 ), dtype = np.float64)
864
+ assign_link_loads_cython(
865
+ actual,
866
+ # This incantation creates a 2d (ll.size() x 1) memory view object around the underlying vector data without transferring owner ship.
867
+ < double [:ll.size(), :1 ]> & deref(ll)[0 ],
868
+ self .graph_compressed_id_view,
869
+ cores
870
+ )
871
+ del ll
872
+ return actual
857
873
858
874
if len (matrix.view_names) == 1 :
859
875
link_loads = apply_link_loading_func(matrix.matrix_view)
@@ -865,14 +881,23 @@ cdef class RouteChoiceSet:
865
881
866
882
return link_loads
867
883
868
-
884
+ @ cython.boundscheck (False )
885
+ @ cython.wraparound (False )
886
+ @ cython.embedsignature (True )
887
+ @ cython.initializedcheck (False )
869
888
@staticmethod
870
889
cdef vector[vector[double ] * ] * compute_path_files(
871
890
vector[pair[long long , long long ]] & ods,
872
891
vector[RouteSet_t * ] & results,
873
892
vector[vector[long long ] * ] & link_union_set,
874
- vector[vector[double ] * ] & prob_set
893
+ vector[vector[double ] * ] & prob_set,
894
+ unsigned int cores
875
895
) noexcept nogil:
896
+ """
897
+ Computes the path files for the provided vector of RouteSets.
898
+
899
+ Returns vector of vectors of link loads corresponding to each link in it's link_union_set.
900
+ """
876
901
cdef:
877
902
vector[vector[double ] * ] * link_loads = new vector[vector[double ] * ](ods.size()) # FIXME FREE ME
878
903
vector[long long ] * link_union
@@ -886,7 +911,7 @@ cdef class RouteChoiceSet:
886
911
double prob
887
912
long long i
888
913
889
- with parallel(num_threads = 6 ):
914
+ with parallel(num_threads = cores ):
890
915
# The link union needs to be allocated per thread as scratch space, as its of unknown length we can't allocated a matrix of them.
891
916
# Additionally getting them to be reused between batches is complicated, instead we just get a new one each batch
892
917
@@ -932,11 +957,22 @@ cdef class RouteChoiceSet:
932
957
933
958
return link_loads
934
959
960
+ @ cython.boundscheck (False )
961
+ @ cython.wraparound (False )
962
+ @ cython.embedsignature (True )
963
+ @ cython.initializedcheck (False )
935
964
cdef vector[double ] * apply_link_loading_from_path_files(
936
965
RouteChoiceSet self ,
937
966
double [:, :] matrix_view,
938
967
vector[vector[double ] * ] & path_files
939
968
) noexcept nogil:
969
+ """
970
+ Apply link loading from path files.
971
+
972
+ If path files have already been computed then this is a more efficient manner for the link loading.
973
+
974
+ Returns a vector of link loads indexed by compressed link ID.
975
+ """
940
976
cdef:
941
977
vector[double ] * loads
942
978
vector[long long ] * link_union
@@ -959,7 +995,16 @@ cdef class RouteChoiceSet:
959
995
960
996
return link_loads
961
997
998
+ @ cython.boundscheck (False )
999
+ @ cython.wraparound (False )
1000
+ @ cython.embedsignature (True )
1001
+ @ cython.initializedcheck (False )
962
1002
cdef vector[double ] * apply_link_loading(self , double [:, :] matrix_view) noexcept nogil:
1003
+ """
1004
+ Apply link loading.
1005
+
1006
+ Returns a vector of link loads indexed by compressed link ID.
1007
+ """
963
1008
cdef:
964
1009
RouteSet_t * route_set
965
1010
vector[double ] * route_set_prob
@@ -987,8 +1032,6 @@ cdef class RouteChoiceSet:
987
1032
988
1033
return link_loads
989
1034
990
-
991
-
992
1035
@ cython.wraparound (False )
993
1036
@ cython.embedsignature (True )
994
1037
@ cython.boundscheck (False )
0 commit comments