From 7694704ccfc406cf4069d7008c39c2bedf1b56a4 Mon Sep 17 00:00:00 2001 From: Jake Moss Date: Fri, 18 Aug 2023 11:48:01 +1000 Subject: [PATCH] Add implicit noexcept from Cython<3.0.0 With the release of Cython 3.0.0 there are a few changes of note to use. Particularly the performance impact of the removal of the implicit noexcept. Now all cdefs allow exceptions by default meaning every cdef must require the gil at the end of the function regardless of whether it was nogil or not. Adding the noexcept clause reverts to the old behaviour. There is a compiler directive to result this old behaviour but better be be explicit when the solution is one regex away: `^(cp?def(?:.|\n).*?)(nogil|):$` https://cython.readthedocs.io/en/latest/src/userguide/migrating_to_cy30.html#exception-values-and-noexcept --- aequilibrae/distribution/ipf_core.pyx | 10 ++++----- aequilibrae/paths/basic_path_finding.pyx | 18 ++++++++-------- aequilibrae/paths/bpr.pyx | 6 +++--- aequilibrae/paths/bpr2.pyx | 4 ++-- aequilibrae/paths/conical.pyx | 4 ++-- aequilibrae/paths/graph_building.pyx | 4 ++-- aequilibrae/paths/inrets.pyx | 4 ++-- aequilibrae/paths/parallel_numpy.pyx | 26 ++++++++++++------------ aequilibrae/paths/path_file_saving.pyx | 2 +- aequilibrae/paths/pq_4ary_heap.pyx | 22 ++++++++++---------- 10 files changed, 50 insertions(+), 50 deletions(-) diff --git a/aequilibrae/distribution/ipf_core.pyx b/aequilibrae/distribution/ipf_core.pyx index 7414081a2..9ee9b8e13 100644 --- a/aequilibrae/distribution/ipf_core.pyx +++ b/aequilibrae/distribution/ipf_core.pyx @@ -56,7 +56,7 @@ cdef _fratar(double[:, :] flows, double[:] attr_factor, int max_iter, double toler, - int cpus): + int cpus) noexcept: cdef double err = 1.0 cdef int iter = 0 @@ -99,7 +99,7 @@ cdef _fratar(double[:, :] flows, cpdef void _total_attra(double[:, :] flows, double[:] prod_tgt, double[:] attr_tot, - int cpus): + int cpus) noexcept: cdef long long i, j, jk cdef double *local_buf @@ -133,7 +133,7 @@ cpdef void _total_attra(double[:, :] flows, cpdef void _total_prods(double[:, :] flows, double[:] prod_tgt, double[:] prod_tot, - int cpus)nogil: + int cpus) noexcept nogil: cdef long long i, j cdef long long I = flows.shape[0] @@ -154,7 +154,7 @@ cpdef void _total_prods(double[:, :] flows, cpdef double _factors(double[:] target, double[:] total, double[:] factor, - int cpus): + int cpus) noexcept: cdef long long i, I = target.shape[0] cdef double err = 1.0 @@ -174,7 +174,7 @@ cpdef double _factors(double[:] target, @cython.embedsignature(True) @cython.boundscheck(False) cpdef double _calc_err(double[:] p_factor, - double[:] a_factor): + double[:] a_factor) noexcept: cdef long long i, I = p_factor.shape[0] cdef long long j, J = a_factor.shape[0] diff --git a/aequilibrae/paths/basic_path_finding.pyx b/aequilibrae/paths/basic_path_finding.pyx index af6c88156..0809adc58 100644 --- a/aequilibrae/paths/basic_path_finding.pyx +++ b/aequilibrae/paths/basic_path_finding.pyx @@ -25,7 +25,7 @@ cpdef void network_loading(long classes, long long [:] no_path, long long [:] reached_first, double [:, :] node_load, - long found) nogil: + long found) noexcept nogil: cdef long long i, j, predecessor, connector, node cdef long long zones = demand.shape[0] @@ -70,7 +70,7 @@ cpdef void network_loading(long classes, @cython.embedsignature(True) @cython.boundscheck(False) cdef void _copy_skims(double[:,:] skim_matrix, #Skim matrix_procedures computed from one origin to all nodes - double[:,:] final_skim_matrix) nogil: #Skim matrix_procedures computed for one origin to all other centroids only + double[:,:] final_skim_matrix) noexcept nogil: #Skim matrix_procedures computed for one origin to all other centroids only cdef long i, j cdef long N = final_skim_matrix.shape[0] @@ -81,7 +81,7 @@ cdef void _copy_skims(double[:,:] skim_matrix, #Skim matrix_procedures computed final_skim_matrix[i,j]=skim_matrix[i,j] -cdef return_an_int_view(input): +cdef int[:] return_an_int_view(input) noexcept nogil: cdef int [:] critical_links_view = input return critical_links_view @@ -97,7 +97,7 @@ cdef void sl_network_loading( double [:, :, :] sl_od_matrix, double [:, :, :] sl_link_loading, unsigned char [:] has_flow_mask, - long classes) nogil: + long classes) noexcept nogil: # VARIABLES: # selected_links: 2d memoryview. Each row corresponds to a set of selected links specified by the user # demand: The input demand matrix for a given origin. The first index corresponds to destination, @@ -169,7 +169,7 @@ cpdef void put_path_file_on_disk(unsigned int orig, long long [:] connectors, long long [:] all_nodes, unsigned int [:] origins_to_write, - unsigned int [:] nodes_to_write) nogil: + unsigned int [:] nodes_to_write) noexcept nogil: cdef long long i cdef long long k = pred.shape[0] @@ -188,7 +188,7 @@ cdef void blocking_centroid_flows(int action, long long centroids, long long [:] fs, long long [:] temp_b_nodes, - long long [:] real_b_nodes) nogil: + long long [:] real_b_nodes) noexcept nogil: cdef long long i if action == 1: # We are unblocking @@ -213,7 +213,7 @@ cdef void skim_single_path(long origin, long long [:] conn, double[:, :] graph_costs, long long [:] reached_first, - long found) nogil: + long found) noexcept nogil: cdef long long i, node, predecessor, connector, j # sets all skims to infinity @@ -250,7 +250,7 @@ cpdef void skim_multiple_fields(long origin, double[:, :] graph_costs, long long [:] reached_first, long found, - double [:,:] final_skims) nogil: + double [:,:] final_skims) noexcept nogil: cdef long long i, node, predecessor, connector, j # sets all skims to infinity @@ -295,7 +295,7 @@ cpdef int path_finding(long origin, long long [:] pred, long long [:] ids, long long [:] connectors, - long long [:] reached_first) nogil: + long long [:] reached_first) noexcept nogil: cdef unsigned int N = graph_costs.shape[0] cdef unsigned int M = pred.shape[0] diff --git a/aequilibrae/paths/bpr.pyx b/aequilibrae/paths/bpr.pyx index b8a3d63c9..2f44cc436 100644 --- a/aequilibrae/paths/bpr.pyx +++ b/aequilibrae/paths/bpr.pyx @@ -34,7 +34,7 @@ cpdef void bpr_cython(double[:] congested_time, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = congested_time.shape[0] @@ -53,7 +53,7 @@ cpdef void dbpr_cython(double[:] deltaresult, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = deltaresult.shape[0] @@ -61,4 +61,4 @@ cpdef void dbpr_cython(double[:] deltaresult, if link_flows[i] > 0: deltaresult[i] = fftime[i] * (alpha[i] * beta[i] * (pow(link_flows[i] / capacity[i], beta[i]-1)))/ capacity[i] else: - deltaresult[i] = fftime[i] \ No newline at end of file + deltaresult[i] = fftime[i] diff --git a/aequilibrae/paths/bpr2.pyx b/aequilibrae/paths/bpr2.pyx index 160a5edda..91a400de7 100644 --- a/aequilibrae/paths/bpr2.pyx +++ b/aequilibrae/paths/bpr2.pyx @@ -34,7 +34,7 @@ cpdef void bpr2_cython(double[:] congested_time, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = congested_time.shape[0] @@ -58,7 +58,7 @@ cpdef void dbpr2_cython(double[:] deltaresult, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = deltaresult.shape[0] diff --git a/aequilibrae/paths/conical.pyx b/aequilibrae/paths/conical.pyx index e6eaca3ca..7a4f7f098 100644 --- a/aequilibrae/paths/conical.pyx +++ b/aequilibrae/paths/conical.pyx @@ -34,7 +34,7 @@ cpdef void conical_cython(double[:] congested_time, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = congested_time.shape[0] @@ -57,7 +57,7 @@ cpdef void dconical_cython(double[:] deltaresult, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = deltaresult.shape[0] diff --git a/aequilibrae/paths/graph_building.pyx b/aequilibrae/paths/graph_building.pyx index 4322d2396..685e9cb5a 100644 --- a/aequilibrae/paths/graph_building.pyx +++ b/aequilibrae/paths/graph_building.pyx @@ -19,7 +19,7 @@ cdef long long _build_compressed_graph(long long[:] link_idx, long long[:] all_links, long long[:] compressed_dir, long long[:] compressed_a_node, - long long[:] compressed_b_node) nogil: + long long[:] compressed_b_node) noexcept nogil: cdef: long long slink = 0 long long pre_link, n, first_node, lnk, lidx, a_node, b_node @@ -93,7 +93,7 @@ cdef long long _build_compressed_graph(long long[:] link_idx, @cython.wraparound(False) @cython.embedsignature(True) @cython.boundscheck(False) -cdef void _back_fill(long long[:] links_index, long long max_node): +cdef void _back_fill(long long[:] links_index, long long max_node) noexcept: cdef Py_ssize_t i for i in range(max_node + 1, 0, -1): diff --git a/aequilibrae/paths/inrets.pyx b/aequilibrae/paths/inrets.pyx index 152abae90..c5f2ac01c 100644 --- a/aequilibrae/paths/inrets.pyx +++ b/aequilibrae/paths/inrets.pyx @@ -34,7 +34,7 @@ cpdef void inrets_cython(double[:] congested_time, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = congested_time.shape[0] @@ -60,7 +60,7 @@ cpdef void dinrets_cython(double[:] deltaresult, double [:] fftime, double[:] alpha, double [:] beta, - int cores): + int cores) noexcept: cdef long long i cdef long long l = deltaresult.shape[0] diff --git a/aequilibrae/paths/parallel_numpy.pyx b/aequilibrae/paths/parallel_numpy.pyx index 29239b2f0..d112663b6 100644 --- a/aequilibrae/paths/parallel_numpy.pyx +++ b/aequilibrae/paths/parallel_numpy.pyx @@ -13,7 +13,7 @@ def sum_axis1(totals, multiples, cores): @cython.boundscheck(False) cpdef void sum_axis1_cython(double[:] totals, double[:, :] multiples, - int cores): + int cores) noexcept: cdef long long i, j cdef long long l = totals.shape[0] cdef long long k = multiples.shape[1] @@ -41,7 +41,7 @@ def sum_a_times_b_minus_c(array1, array2, array3, cores): cpdef double sum_a_times_b_minus_c_cython(double[:] array1, double[:] array2, double[:] array3, - int cores): + int cores) noexcept: cdef long long i cdef double row_result cdef double result = 0.0 @@ -72,7 +72,7 @@ cpdef void linear_combination_cython_1d(double stepsize, double[:] results, double[:] array1, double[:] array2, - int cores): + int cores) noexcept: cdef long long i cdef long long l = results.shape[0] @@ -99,7 +99,7 @@ cpdef void linear_combination_cython(double stepsize, double[:, :] results, double[:, :] array1, double[:, :] array2, - int cores): + int cores) noexcept: cdef long long i, j cdef long long l = results.shape[0] cdef long long k = results.shape[1] @@ -129,7 +129,7 @@ cpdef void linear_combination_skims_cython(double stepsize, double[:, :,:] results, double[:, :, :] array1, double[:, :, :] array2, - int cores): + int cores) noexcept: cdef long long i, j, k cdef long long a = results.shape[0] cdef long long b = results.shape[1] @@ -163,7 +163,7 @@ cpdef void triple_linear_combination_cython(double [:] stepsizes, double[:, :] array1, double[:, :] array2, double[:, :] array3, - int cores): + int cores) noexcept: cdef long long i, j cdef long long l = results.shape[0] cdef long long k = results.shape[1] @@ -193,7 +193,7 @@ cpdef void triple_linear_combination_cython_skims(double [:] stepsizes, double[:, :, :] array1, double[:, :, :] array2, double[:, :, :] array3, - int cores): + int cores) noexcept: cdef long long i, j, k cdef long long a = results.shape[0] cdef long long b = results.shape[1] @@ -220,7 +220,7 @@ def copy_one_dimension(target, source, cores): @cython.boundscheck(False) cpdef void copy_one_dimension_cython(double[:] target, double[:] source, - int cores): + int cores) noexcept: cdef long long i cdef long long l = target.shape[0] @@ -243,7 +243,7 @@ def copy_two_dimensions(target, source, cores): @cython.boundscheck(False) cpdef void copy_two_dimensions_cython(double[:, :] target, double[:, :] source, - int cores): + int cores) noexcept: cdef long long i, j cdef long long l = target.shape[0] cdef long long k = target.shape[1] @@ -269,7 +269,7 @@ def copy_three_dimensions(target, source, cores): @cython.boundscheck(False) cpdef void copy_three_dimensions_cython(double[:, :, :] target, double[:, :, :] source, - int cores): + int cores) noexcept: cdef long long i, j, k cdef long long a = target.shape[0] cdef long long b = target.shape[1] @@ -298,7 +298,7 @@ def assign_link_loads(actual_links, compressed_links, crosswalk, cores): cpdef void assign_link_loads_cython(double[:, :] actual, double[:, :] compressed, long long[:] crosswalk, - int cores): + int cores) noexcept: cdef long long i, j, k cdef long long links = actual.shape[0] cdef long long n = actual.shape[1] @@ -322,7 +322,7 @@ def aggregate_link_costs(actual_costs, compressed_costs, crosswalk): @cython.boundscheck(False) cpdef void aggregate_link_costs_cython(double[:] actual, double[:] compressed, - long long[:] crosswalk): + long long[:] crosswalk) noexcept: cdef long long i, j, k cdef long long links = actual.shape[0] cdef long long c_l = compressed.shape[0] @@ -333,4 +333,4 @@ cpdef void aggregate_link_costs_cython(double[:] actual, for i in range(links): k = crosswalk[i] if k < c_l: - compressed[k] += actual[i] \ No newline at end of file + compressed[k] += actual[i] diff --git a/aequilibrae/paths/path_file_saving.pyx b/aequilibrae/paths/path_file_saving.pyx index 16d234c9a..16ec7b36b 100644 --- a/aequilibrae/paths/path_file_saving.pyx +++ b/aequilibrae/paths/path_file_saving.pyx @@ -26,7 +26,7 @@ cpdef void save_path_file(long origin_index, long long [:] conn, string path_file, string index_file, - bool write_feather): + bool write_feather) noexcept: cdef long long class_, node, predecessor, connector, ctr cdef vector[long long] path_data diff --git a/aequilibrae/paths/pq_4ary_heap.pyx b/aequilibrae/paths/pq_4ary_heap.pyx index e744c9d8c..68bd275b9 100644 --- a/aequilibrae/paths/pq_4ary_heap.pyx +++ b/aequilibrae/paths/pq_4ary_heap.pyx @@ -55,7 +55,7 @@ cdef struct PriorityQueue: Element* Elements # array storing the elements DTYPE_t* keys -cdef void init_heap(PriorityQueue* pqueue, size_t length) nogil: +cdef void init_heap(PriorityQueue* pqueue, size_t length) noexcept nogil: """Initialize the binary heap. input @@ -75,7 +75,7 @@ cdef void init_heap(PriorityQueue* pqueue, size_t length) nogil: _initialize_element(pqueue, i) -cdef void _initialize_element(PriorityQueue* pqueue, size_t element_idx) nogil: +cdef void _initialize_element(PriorityQueue* pqueue, size_t element_idx) noexcept nogil: """Initialize a single element. input @@ -88,7 +88,7 @@ cdef void _initialize_element(PriorityQueue* pqueue, size_t element_idx) nogil: pqueue.Elements[element_idx].node_idx = pqueue.length -cdef void free_heap(PriorityQueue* pqueue) nogil: +cdef void free_heap(PriorityQueue* pqueue) noexcept nogil: """Free the binary heap. input @@ -99,7 +99,7 @@ cdef void free_heap(PriorityQueue* pqueue) nogil: free(pqueue.Elements) -cdef void insert(PriorityQueue* pqueue, size_t element_idx, DTYPE_t key) nogil: +cdef void insert(PriorityQueue* pqueue, size_t element_idx, DTYPE_t key) noexcept nogil: """Insert an element into the heap and reorder the heap. input @@ -122,7 +122,7 @@ cdef void insert(PriorityQueue* pqueue, size_t element_idx, DTYPE_t key) nogil: _decrease_key_from_node_index(pqueue, node_idx, key) -cdef void decrease_key(PriorityQueue* pqueue, size_t element_idx, DTYPE_t key_new) nogil: +cdef void decrease_key(PriorityQueue* pqueue, size_t element_idx, DTYPE_t key_new) noexcept nogil: """Decrease the key of a element in the heap, given its element index. input @@ -141,7 +141,7 @@ cdef void decrease_key(PriorityQueue* pqueue, size_t element_idx, DTYPE_t key_ne key_new) -cdef DTYPE_t peek(PriorityQueue* pqueue) nogil: +cdef DTYPE_t peek(PriorityQueue* pqueue) noexcept nogil: """Find heap min key. input @@ -160,7 +160,7 @@ cdef DTYPE_t peek(PriorityQueue* pqueue) nogil: return pqueue.Elements[pqueue.A[0]].key -cdef bint is_empty(PriorityQueue* pqueue) nogil: +cdef bint is_empty(PriorityQueue* pqueue) noexcept nogil: """Check whether the heap is empty. input @@ -175,7 +175,7 @@ cdef bint is_empty(PriorityQueue* pqueue) nogil: return isempty -cdef size_t extract_min(PriorityQueue* pqueue) nogil: +cdef size_t extract_min(PriorityQueue* pqueue) noexcept nogil: """Extract element with min keay from the heap, and return its element index. @@ -209,7 +209,7 @@ cdef size_t extract_min(PriorityQueue* pqueue) nogil: return element_idx -cdef void _exchange_nodes(PriorityQueue* pqueue, size_t node_i, size_t node_j) nogil: +cdef void _exchange_nodes(PriorityQueue* pqueue, size_t node_i, size_t node_j) noexcept nogil: """Exchange two nodes in the heap. input @@ -231,7 +231,7 @@ cdef void _exchange_nodes(PriorityQueue* pqueue, size_t node_i, size_t node_j) n pqueue.Elements[element_i].node_idx = node_j -cdef void _min_heapify(PriorityQueue* pqueue, size_t node_idx) nogil: +cdef void _min_heapify(PriorityQueue* pqueue, size_t node_idx) noexcept nogil: """Re-order sub-tree under a given node (given its node index) until it satisfies the heap property. @@ -304,7 +304,7 @@ cdef void _min_heapify(PriorityQueue* pqueue, size_t node_idx) nogil: break -cdef void _decrease_key_from_node_index(PriorityQueue* pqueue, size_t node_idx, DTYPE_t key_new) nogil: +cdef void _decrease_key_from_node_index(PriorityQueue* pqueue, size_t node_idx, DTYPE_t key_new) noexcept nogil: """Decrease the key of an element in the heap, given its tree index. input