From a5764880c64a5d48f217bce79f6628e5f2d0322f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 28 Jun 2024 15:29:07 -0600 Subject: [PATCH 01/70] use cython.floating --- landlab/ca/cfuncs.pyx | 76 +++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index 26a5d32b69..aa8bf7c70d 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -21,8 +21,8 @@ cdef double _NEVER = 1.0e50 cdef int _CORE = NodeStatus.CORE -DTYPE = np.double -ctypedef np.double_t DTYPE_t +# DTYPE = np.double +# ctypedef np.double_t DTYPE_t DTYPE_INT = int ctypedef np.int_t DTYPE_INT_t @@ -196,12 +196,12 @@ cpdef update_link_states_and_transitions( np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, event_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, - DTYPE_t current_time, + double current_time, np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, xn_prop_update_fn, ): @@ -267,13 +267,13 @@ cpdef update_link_states_and_transitions_new( np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, priority_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, - np.ndarray[DTYPE_t, ndim=1] trn_rate, + cython.floating [:] trn_rate, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, - DTYPE_t current_time, + double current_time, ): """ Following an "external" change to the node state grid, updates link @@ -353,10 +353,10 @@ cpdef update_node_states( @cython.wraparound(False) cpdef get_next_event( DTYPE_INT_t link, DTYPE_INT_t current_state, - DTYPE_t current_time, + double current_time, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, xn_prop_update_fn, ): @@ -429,10 +429,10 @@ cpdef get_next_event( @cython.wraparound(False) cpdef get_next_event_new( DTYPE_INT_t link, DTYPE_INT_t current_state, - DTYPE_t current_time, + double current_time, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, - np.ndarray[DTYPE_t, ndim=1] trn_rate, + cython.floating [:] trn_rate, ): """Get the next event for a link. @@ -493,8 +493,8 @@ cpdef push_transitions_to_event_queue( np.ndarray[DTYPE_INT_t, ndim=1] n_trn, np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, - np.ndarray[DTYPE_t, ndim=1] trn_rate, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] trn_rate, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, PriorityQueue priority_queue, ): @@ -523,7 +523,7 @@ cpdef push_transitions_to_event_queue( @cython.wraparound(False) cdef void update_link_state( DTYPE_INT_t link, DTYPE_INT_t new_link_state, - DTYPE_t current_time, + double current_time, np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, @@ -533,9 +533,9 @@ cdef void update_link_state( DTYPE_INT_t num_node_states_sq, np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, event_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, np.ndarray[object, ndim=2] xn_prop_update_fn, ): @@ -589,7 +589,7 @@ cdef void update_link_state( @cython.wraparound(False) cdef void update_link_state_new( DTYPE_INT_t link, DTYPE_INT_t new_link_state, - DTYPE_t current_time, + double current_time, np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, @@ -600,10 +600,10 @@ cdef void update_link_state_new( np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, PriorityQueue priority_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, - np.ndarray[DTYPE_t, ndim=1] trn_rate, + cython.floating [:] trn_rate, ): """ Implements a link transition by updating the current state of the link @@ -655,7 +655,7 @@ cdef void update_link_state_new( @cython.wraparound(False) cdef void do_transition( Event event, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, @@ -666,7 +666,7 @@ cdef void do_transition( object prop_data, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, DTYPE_INT_t num_node_states, @@ -867,9 +867,9 @@ cdef void do_transition( # @cython.wraparound(False) cpdef void do_transition_new( DTYPE_INT_t event_link, - DTYPE_t event_time, + double event_time, PriorityQueue priority_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, @@ -883,7 +883,7 @@ cpdef void do_transition_new( np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, - np.ndarray[DTYPE_t, ndim=1] trn_rate, + cython.floating [:] trn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, np.ndarray[DTYPE_INT8_t, ndim=1] trn_propswap, @@ -1117,7 +1117,7 @@ cpdef double run_cts_new( double run_to, double current_time, PriorityQueue priority_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, @@ -1131,7 +1131,7 @@ cpdef double run_cts_new( np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, - np.ndarray[DTYPE_t, ndim=1] trn_rate, + cython.floating [:] trn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, np.ndarray[DTYPE_INT8_t, ndim=1] trn_propswap, @@ -1222,7 +1222,7 @@ cpdef double run_cts( char plot_each_transition, object plotter, object event_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, @@ -1233,7 +1233,7 @@ cpdef double run_cts( object prop_data, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, DTYPE_INT_t num_node_states, @@ -1314,10 +1314,10 @@ cpdef double run_cts( cpdef get_next_event_lean( DTYPE_INT_t link, DTYPE_INT_t current_state, - DTYPE_t current_time, + double current_time, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, ): """Get the next event for a link. @@ -1384,7 +1384,7 @@ cpdef get_next_event_lean( cdef void update_link_state_lean( DTYPE_INT_t link, DTYPE_INT_t new_link_state, - DTYPE_t current_time, + double current_time, np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, @@ -1394,9 +1394,9 @@ cdef void update_link_state_lean( DTYPE_INT_t num_node_states_sq, np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, event_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, ): """ Implements a link transition by updating the current state of the link @@ -1441,7 +1441,7 @@ cdef void update_link_state_lean( @cython.wraparound(False) cdef void do_transition_lean( Event event, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, @@ -1450,7 +1450,7 @@ cdef void do_transition_lean( np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, DTYPE_INT_t num_node_states, @@ -1617,7 +1617,7 @@ cpdef double run_cts_lean( double run_to, double current_time, object event_queue, - np.ndarray[DTYPE_t, ndim=1] next_update, + cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, @@ -1626,7 +1626,7 @@ cpdef double run_cts_lean( np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, - np.ndarray[DTYPE_t, ndim=2] xn_rate, + cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, DTYPE_INT_t num_node_states, From 06b82cfc465da9f5eea75b92f3b9b6be826a2b59 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 28 Jun 2024 15:42:51 -0600 Subject: [PATCH 02/70] use int8_t, uint8_t from stdint --- landlab/ca/cfuncs.pyx | 98 ++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index aa8bf7c70d..1392613678 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -3,10 +3,12 @@ Created on Thu Jun 30 12:40:39 2016 @author: gtucker """ +cimport cython +from libc.stdint cimport int8_t +from libc.stdint cimport uint8_t import numpy as np -cimport cython cimport numpy as np import sys # for debug @@ -27,11 +29,11 @@ cdef int _CORE = NodeStatus.CORE DTYPE_INT = int ctypedef np.int_t DTYPE_INT_t -DTYPE_INT8 = np.int8 -ctypedef np.int8_t DTYPE_INT8_t +# DTYPE_INT8 = np.int8 +# ctypedef np.int8_t DTYPE_INT8_t -DTYPE_UINT8 = np.uint8 -ctypedef np.uint8_t DTYPE_UINT8_t +# DTYPE_UINT8 = np.uint8 +# ctypedef np.uint8_t DTYPE_UINT8_t cdef char _DEBUG = 0 @@ -137,7 +139,7 @@ cdef int current_link_state( np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + int8_t [:] link_orientation, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, ): @@ -191,8 +193,8 @@ cpdef update_link_states_and_transitions( np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] link_orientation, + int8_t [:] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, event_queue, @@ -202,7 +204,7 @@ cpdef update_link_states_and_transitions( DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, double current_time, - np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, + int8_t [:, :] xn_propswap, xn_prop_update_fn, ): """ @@ -262,8 +264,8 @@ cpdef update_link_states_and_transitions_new( np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] link_orientation, + int8_t [:] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, priority_queue, @@ -329,7 +331,7 @@ cpdef update_link_states_and_transitions_new( @cython.cdivision(True) cpdef update_node_states( np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_UINT8_t, ndim=1] status_at_node, + uint8_t [:] status_at_node, DTYPE_INT_t tail_node, DTYPE_INT_t head_node, DTYPE_INT_t new_link_state, @@ -357,7 +359,7 @@ cpdef get_next_event( np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, cython.floating [:, :] xn_rate, - np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, + int8_t [:, :] xn_propswap, xn_prop_update_fn, ): """Get the next event for a link. @@ -524,11 +526,11 @@ cpdef push_transitions_to_event_queue( cdef void update_link_state( DTYPE_INT_t link, DTYPE_INT_t new_link_state, double current_time, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + int8_t [:] link_orientation, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, np.ndarray[DTYPE_INT_t, ndim=1] link_state, @@ -536,7 +538,7 @@ cdef void update_link_state( cython.floating [:] next_update, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, cython.floating [:, :] xn_rate, - np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, + int8_t [:, :] xn_propswap, np.ndarray[object, ndim=2] xn_prop_update_fn, ): """ @@ -590,11 +592,11 @@ cdef void update_link_state( cdef void update_link_state_new( DTYPE_INT_t link, DTYPE_INT_t new_link_state, double current_time, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + int8_t [:] link_orientation, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, np.ndarray[DTYPE_INT_t, ndim=1] link_state, @@ -660,21 +662,21 @@ cdef void do_transition( np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_UINT8_t, ndim=1] status_at_node, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + uint8_t [:] status_at_node, + int8_t [:] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] propid, object prop_data, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, - np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, + int8_t [:, :] active_link_dirs_at_node, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, DTYPE_INT_t prop_reset_value, - np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, + int8_t [:, :] xn_propswap, xn_prop_update_fn, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] bnd_lnk, event_queue, this_cts_model, plot_each_transition=False, @@ -875,18 +877,18 @@ cpdef void do_transition_new( np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, np.ndarray[DTYPE_INT_t, ndim=1] trn_to, - np.ndarray[DTYPE_UINT8_t, ndim=1] status_at_node, + uint8_t [:] status_at_node, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + int8_t [:] bnd_lnk, + int8_t [:] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, cython.floating [:] trn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, - np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, - np.ndarray[DTYPE_INT8_t, ndim=1] trn_propswap, + int8_t [:, :] active_link_dirs_at_node, + int8_t [:] trn_propswap, np.ndarray[DTYPE_INT_t, ndim=1] propid, object prop_data, DTYPE_INT_t prop_reset_value, @@ -1123,18 +1125,18 @@ cpdef double run_cts_new( np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, np.ndarray[DTYPE_INT_t, ndim=1] trn_to, - np.ndarray[DTYPE_UINT8_t, ndim=1] status_at_node, + uint8_t [:] status_at_node, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + int8_t [:] bnd_lnk, + int8_t [:] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] link_state, np.ndarray[DTYPE_INT_t, ndim=1] n_trn, np.ndarray[DTYPE_INT_t, ndim=2] trn_id, cython.floating [:] trn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, - np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, - np.ndarray[DTYPE_INT8_t, ndim=1] trn_propswap, + int8_t [:, :] active_link_dirs_at_node, + int8_t [:] trn_propswap, np.ndarray[DTYPE_INT_t, ndim=1] propid, object prop_data, DTYPE_INT_t prop_reset_value, @@ -1227,21 +1229,21 @@ cpdef double run_cts( np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_UINT8_t, ndim=1] status_at_node, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + uint8_t [:] status_at_node, + int8_t [:] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] propid, object prop_data, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, - np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, + int8_t [:, :] active_link_dirs_at_node, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, DTYPE_INT_t prop_reset_value, - np.ndarray[DTYPE_INT8_t, ndim=2] xn_propswap, + int8_t [:, :] xn_propswap, xn_prop_update_fn, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] bnd_lnk, this_cts_model, ): """Run the model forward for a specified period of time. @@ -1385,11 +1387,11 @@ cdef void update_link_state_lean( DTYPE_INT_t link, DTYPE_INT_t new_link_state, double current_time, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] bnd_lnk, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + int8_t [:] link_orientation, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, np.ndarray[DTYPE_INT_t, ndim=1] link_state, @@ -1446,16 +1448,16 @@ cdef void do_transition_lean( np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_UINT8_t, ndim=1] status_at_node, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + uint8_t [:] status_at_node, + int8_t [:] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, - np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, + int8_t [:, :] active_link_dirs_at_node, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] bnd_lnk, object event_queue, ): """Transition state. @@ -1622,16 +1624,16 @@ cpdef double run_cts_lean( np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, np.ndarray[DTYPE_INT_t, ndim=1] node_state, np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_UINT8_t, ndim=1] status_at_node, - np.ndarray[DTYPE_INT8_t, ndim=1] link_orientation, + uint8_t [:] status_at_node, + int8_t [:] link_orientation, np.ndarray[DTYPE_INT_t, ndim=1] n_xn, np.ndarray[DTYPE_INT_t, ndim=2] xn_to, cython.floating [:, :] xn_rate, np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, - np.ndarray[DTYPE_INT8_t, ndim=2] active_link_dirs_at_node, + int8_t [:, :] active_link_dirs_at_node, DTYPE_INT_t num_node_states, DTYPE_INT_t num_node_states_sq, - np.ndarray[DTYPE_INT8_t, ndim=1] bnd_lnk, + int8_t [:] bnd_lnk, ): """Run the model forward for a specified period of time. This "lean" version omits parameters related to property exchange and callback fn. From eb9eede451eecd6d42f25c48f63d587d86455188 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 28 Jun 2024 15:54:20 -0600 Subject: [PATCH 03/70] replace np.int_t with cython.integral --- landlab/ca/cfuncs.pyx | 290 +++++++++++++++++++++--------------------- 1 file changed, 147 insertions(+), 143 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index 1392613678..535e13f9a1 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -26,8 +26,8 @@ cdef int _CORE = NodeStatus.CORE # DTYPE = np.double # ctypedef np.double_t DTYPE_t -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t +# DTYPE_INT = int +# ctypedef np.int_t DTYPE_INT_t # DTYPE_INT8 = np.int8 # ctypedef np.int8_t DTYPE_INT8_t @@ -135,13 +135,13 @@ cdef class Event: @cython.boundscheck(True) @cython.wraparound(False) cdef int current_link_state( - DTYPE_INT_t link_id, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, + link_id, + cython.integral [:] node_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, int8_t [:] link_orientation, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, + num_node_states, + num_node_states_sq, ): """Get the current state of a link. @@ -189,20 +189,20 @@ cdef int current_link_state( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions( - np.ndarray[DTYPE_INT_t, ndim=1] active_links, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, + cython.integral [:] active_links, + cython.integral [:] node_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, int8_t [:] link_orientation, int8_t [:] bnd_lnk, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, + cython.integral [:] link_state, + cython.integral [:] n_xn, event_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, + num_node_states, + num_node_states_sq, double current_time, int8_t [:, :] xn_propswap, xn_prop_update_fn, @@ -260,21 +260,21 @@ cpdef update_link_states_and_transitions( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions_new( - np.ndarray[DTYPE_INT_t, ndim=1] active_links, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, + cython.integral [:] active_links, + cython.integral [:] node_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, int8_t [:] link_orientation, int8_t [:] bnd_lnk, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=1] n_trn, + cython.integral [:] link_state, + cython.integral [:] n_trn, priority_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, - np.ndarray[DTYPE_INT_t, ndim=2] trn_id, + cython.integral [:] next_trn_id, + cython.integral [:, :] trn_id, cython.floating [:] trn_rate, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, + num_node_states, + num_node_states_sq, double current_time, ): """ @@ -330,12 +330,12 @@ cpdef update_link_states_and_transitions_new( @cython.wraparound(False) @cython.cdivision(True) cpdef update_node_states( - np.ndarray[DTYPE_INT_t, ndim=1] node_state, + cython.integral [:] node_state, uint8_t [:] status_at_node, - DTYPE_INT_t tail_node, - DTYPE_INT_t head_node, - DTYPE_INT_t new_link_state, - DTYPE_INT_t num_states, + tail_node, + head_node, + new_link_state, + num_states, ): """Update the states of 2 nodes that underwent a transition.""" if _DEBUG: @@ -354,10 +354,11 @@ cpdef update_node_states( @cython.boundscheck(True) @cython.wraparound(False) cpdef get_next_event( - DTYPE_INT_t link, DTYPE_INT_t current_state, + link, + long current_state, double current_time, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:] n_xn, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, xn_prop_update_fn, @@ -430,10 +431,11 @@ cpdef get_next_event( @cython.boundscheck(True) @cython.wraparound(False) cpdef get_next_event_new( - DTYPE_INT_t link, DTYPE_INT_t current_state, + link, + long current_state, double current_time, - np.ndarray[DTYPE_INT_t, ndim=1] n_trn, - np.ndarray[DTYPE_INT_t, ndim=2] trn_id, + cython.integral [:] n_trn, + cython.integral [:, :] trn_id, cython.floating [:] trn_rate, ): """Get the next event for a link. @@ -491,13 +493,13 @@ cpdef get_next_event_new( cpdef push_transitions_to_event_queue( int number_of_active_links, - np.ndarray[DTYPE_INT_t, ndim=1] active_links, - np.ndarray[DTYPE_INT_t, ndim=1] n_trn, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=2] trn_id, + cython.integral [:] active_links, + cython.integral [:] n_trn, + cython.integral [:] link_state, + cython.integral [:, :] trn_id, cython.floating [:] trn_rate, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, + cython.integral [:] next_trn_id, PriorityQueue priority_queue, ): """ @@ -524,19 +526,20 @@ cpdef push_transitions_to_event_queue( @cython.boundscheck(True) @cython.wraparound(False) cdef void update_link_state( - DTYPE_INT_t link, DTYPE_INT_t new_link_state, + link, + long new_link_state, double current_time, int8_t [:] bnd_lnk, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, int8_t [:] link_orientation, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, event_queue, + num_node_states, + num_node_states_sq, + cython.integral [:] link_state, + cython.integral [:] n_xn, event_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, np.ndarray[object, ndim=2] xn_prop_update_fn, @@ -590,21 +593,22 @@ cdef void update_link_state( @cython.boundscheck(True) @cython.wraparound(False) cdef void update_link_state_new( - DTYPE_INT_t link, DTYPE_INT_t new_link_state, + link, + long new_link_state, double current_time, int8_t [:] bnd_lnk, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, int8_t [:] link_orientation, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=1] n_trn, + num_node_states, + num_node_states_sq, + cython.integral [:] link_state, + cython.integral [:] n_trn, PriorityQueue priority_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, - np.ndarray[DTYPE_INT_t, ndim=2] trn_id, + cython.integral [:] next_trn_id, + cython.integral [:, :] trn_id, cython.floating [:] trn_rate, ): """ @@ -658,22 +662,22 @@ cdef void update_link_state_new( cdef void do_transition( Event event, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - np.ndarray[DTYPE_INT_t, ndim=1] propid, + cython.integral [:] propid, object prop_data, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:] n_xn, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, - np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, + cython.integral [:, :] links_at_node, int8_t [:, :] active_link_dirs_at_node, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, - DTYPE_INT_t prop_reset_value, + num_node_states, + num_node_states_sq, + prop_reset_value, int8_t [:, :] xn_propswap, xn_prop_update_fn, int8_t [:] bnd_lnk, @@ -868,30 +872,30 @@ cdef void do_transition( # @cython.boundscheck(False) # @cython.wraparound(False) cpdef void do_transition_new( - DTYPE_INT_t event_link, + event_link, double event_time, PriorityQueue priority_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, - np.ndarray[DTYPE_INT_t, ndim=1] trn_to, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] next_trn_id, + cython.integral [:] trn_to, uint8_t [:] status_at_node, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, + num_node_states, + num_node_states_sq, int8_t [:] bnd_lnk, int8_t [:] link_orientation, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=1] n_trn, - np.ndarray[DTYPE_INT_t, ndim=2] trn_id, + cython.integral [:] link_state, + cython.integral [:] n_trn, + cython.integral [:, :] trn_id, cython.floating [:] trn_rate, - np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, + cython.integral [:, :] links_at_node, int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, - np.ndarray[DTYPE_INT_t, ndim=1] propid, + cython.integral [:] propid, object prop_data, - DTYPE_INT_t prop_reset_value, + prop_reset_value, object trn_prop_update_fn, object this_cts_model, plot_each_transition=False, @@ -1120,26 +1124,26 @@ cpdef double run_cts_new( double current_time, PriorityQueue priority_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] next_trn_id, - np.ndarray[DTYPE_INT_t, ndim=1] trn_to, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] next_trn_id, + cython.integral [:] trn_to, uint8_t [:] status_at_node, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, + num_node_states, + num_node_states_sq, int8_t [:] bnd_lnk, int8_t [:] link_orientation, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=1] n_trn, - np.ndarray[DTYPE_INT_t, ndim=2] trn_id, + cython.integral [:] link_state, + cython.integral [:] n_trn, + cython.integral [:, :] trn_id, cython.floating [:] trn_rate, - np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, + cython.integral [:, :] links_at_node, int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, - np.ndarray[DTYPE_INT_t, ndim=1] propid, + cython.integral [:] propid, object prop_data, - DTYPE_INT_t prop_reset_value, + prop_reset_value, trn_prop_update_fn, this_cts_model, char plot_each_transition, @@ -1225,22 +1229,22 @@ cpdef double run_cts( object plotter, object event_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - np.ndarray[DTYPE_INT_t, ndim=1] propid, + cython.integral [:] propid, object prop_data, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:] n_xn, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, - np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, + cython.integral [:, :] links_at_node, int8_t [:, :] active_link_dirs_at_node, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, - DTYPE_INT_t prop_reset_value, + num_node_states, + num_node_states_sq, + prop_reset_value, int8_t [:, :] xn_propswap, xn_prop_update_fn, int8_t [:] bnd_lnk, @@ -1314,11 +1318,11 @@ cpdef double run_cts( @cython.boundscheck(False) @cython.wraparound(False) cpdef get_next_event_lean( - DTYPE_INT_t link, - DTYPE_INT_t current_state, + link, + current_state, double current_time, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:] n_xn, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, ): """Get the next event for a link. @@ -1384,20 +1388,20 @@ cpdef get_next_event_lean( @cython.boundscheck(False) @cython.wraparound(False) cdef void update_link_state_lean( - DTYPE_INT_t link, - DTYPE_INT_t new_link_state, + link, + new_link_state, double current_time, int8_t [:] bnd_lnk, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, int8_t [:] link_orientation, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, event_queue, + num_node_states, + num_node_states_sq, + cython.integral [:] link_state, + cython.integral [:] n_xn, event_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, ): """ @@ -1444,19 +1448,19 @@ cdef void update_link_state_lean( cdef void do_transition_lean( Event event, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:] n_xn, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, - np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, + cython.integral [:, :] links_at_node, int8_t [:, :] active_link_dirs_at_node, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, + num_node_states, + num_node_states_sq, int8_t [:] bnd_lnk, object event_queue, ): @@ -1620,19 +1624,19 @@ cpdef double run_cts_lean( double current_time, object event_queue, cython.floating [:] next_update, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_tail, - np.ndarray[DTYPE_INT_t, ndim=1] node_at_link_head, - np.ndarray[DTYPE_INT_t, ndim=1] node_state, - np.ndarray[DTYPE_INT_t, ndim=1] link_state, + cython.integral [:] node_at_link_tail, + cython.integral [:] node_at_link_head, + cython.integral [:] node_state, + cython.integral [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - np.ndarray[DTYPE_INT_t, ndim=1] n_xn, - np.ndarray[DTYPE_INT_t, ndim=2] xn_to, + cython.integral [:] n_xn, + cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, - np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, + cython.integral [:, :] links_at_node, int8_t [:, :] active_link_dirs_at_node, - DTYPE_INT_t num_node_states, - DTYPE_INT_t num_node_states_sq, + num_node_states, + num_node_states_sq, int8_t [:] bnd_lnk, ): """Run the model forward for a specified period of time. This "lean" From 3ce4e88217b0e276ea0a984293ca991863f4a9ca Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 12:04:59 -0600 Subject: [PATCH 04/70] remove unused landlab/graph/cfuncs.pyx --- landlab/grid/cfuncs.pyx | 106 ---------------------------------------- setup.py | 1 - 2 files changed, 107 deletions(-) delete mode 100644 landlab/grid/cfuncs.pyx diff --git a/landlab/grid/cfuncs.pyx b/landlab/grid/cfuncs.pyx deleted file mode 100644 index dbc850daae..0000000000 --- a/landlab/grid/cfuncs.pyx +++ /dev/null @@ -1,106 +0,0 @@ -import numpy as np - -cimport cython -cimport numpy as np - -DTYPE = int -ctypedef np.int_t DTYPE_INT_t -DTYPE_INTP = np.intp -ctypedef np.intp_t DTYPE_INTP_t -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - - -@cython.boundscheck(False) -def find_rows_containing_ID(np.ndarray[DTYPE_INT_t, ndim=2] input_array, - np.ndarray[DTYPE_INT_t, ndim=2] out): - """ - Record the row in which ID appears in in_array, indexed by ID. - - Parameters - ---------- - input_array : 2d array of ints - The input array. The function will report in which rows it finds - each ID. - out : 2d array of ints, num_IDs x num_rows_in_input_array - The output array. The number of rows sets the number of IDs to search - for in input_array. - """ - cdef int nrows = out.shape[0] - cdef int i - cdef np.ndarray[DTYPE_INT_t, ndim=2] contains_ID = np.empty_like( - input_array) - - for i in range(nrows): - contains_ID = np.equal(input_array, i).astype(int) - out[i, :] = contains_ID.sum(axis=1) - - -@cython.boundscheck(False) -def create_patches_at_element( - np.ndarray[DTYPE_INT_t, ndim=2] elements_at_patch, - int number_of_elements, np.ndarray[DTYPE_INT_t, ndim=2] out): - """ - """ - cdef int i - cdef np.ndarray[DTYPE_INT_t, ndim=2] element_with_value = np.empty_like( - (elements_at_patch), dtype=int) - cdef np.ndarray[DTYPE_INTP_t, ndim=1] patches_with_element - cdef int num_elements_here - - for i in range(number_of_elements): - np.equal(elements_at_patch, i, out=element_with_value) - patches_with_element = np.argwhere(element_with_value)[:, 0] - num_elements_here = patches_with_element.shape[0] - out[i, :num_elements_here] = patches_with_element - - -@cython.boundscheck(False) -def create_links_at_patch(np.ndarray[DTYPE_INT_t, ndim=2] nodes_at_patch, - np.ndarray[DTYPE_INT_t, ndim=2] links_at_node, - int number_of_patches, - np.ndarray[DTYPE_INT_t, ndim=2] out): - - cdef int i - cdef np.ndarray[DTYPE_INT_t, ndim=1] nodes_on_patch = np.empty( - nodes_at_patch.shape[1], dtype=int) - cdef np.ndarray[DTYPE_INT_t, ndim=2] links_at_patch_nodes = np.empty( - (nodes_at_patch.shape[1], links_at_node.shape[1]), dtype=int) - cdef np.ndarray[DTYPE_INT_t, ndim=1] vals - cdef np.ndarray[DTYPE_INTP_t, ndim=1] counts - cdef np.ndarray[DTYPE_INT_t, ndim=1] duplicated_vals - - for i in range(number_of_patches): - nodes_on_patch = nodes_at_patch[i, :] - links_at_patch_nodes = links_at_node[nodes_on_patch, :] - vals, counts = np.unique(links_at_patch_nodes, - return_counts=True) - duplicated_vals = vals[counts == 2] - # if len==4, contains a -1; strip it - out[i, :] = duplicated_vals[-3:] # out of order, so far - - -@cython.boundscheck(False) -def _argsort_points_by_x_then_y(np.ndarray[DTYPE_INT_t, ndim=1] pts, - np.ndarray[DTYPE_INT_t, ndim=1] out): - - cdef np.ndarray[DTYPE_INT_t, ndim=1] a - cdef np.ndarray[DTYPE_INT_t, ndim=1] b - - a = pts[:, 0].argsort(kind="mergesort") - b = pts[a, 1].argsort(kind="mergesort") - out[:] = a[b] - - -@cython.boundscheck(False) -def _anticlockwise_argsort_points(np.ndarray[DTYPE_INT_t, ndim=2] pts, - np.ndarray[DTYPE_INT_t, ndim=1] out): - - cdef np.ndarray[DTYPE_FLOAT_t, ndim=1] midpt = pts.mean(axis=0) - cdef np.ndarray[DTYPE_FLOAT_t, ndim=1] theta = np.empty( - pts.shape[0], dtype=float) - cdef double twopi = 2.*np.pi - - theta[:] = np.arctan2(pts[:, 1] - midpt[1], pts[:, 0] - midpt[0]) - theta[:] = theta % twopi - out[:] = np.argsort(theta) diff --git a/setup.py b/setup.py index e68d88f0d2..6a92609484 100644 --- a/setup.py +++ b/setup.py @@ -46,7 +46,6 @@ "landlab/graph/structured_quad/ext/at_patch.pyx", "landlab/graph/voronoi/ext/delaunay.pyx", "landlab/graph/voronoi/ext/voronoi.pyx", - "landlab/grid/cfuncs.pyx", "landlab/grid/ext/raster_divergence.pyx", "landlab/grid/ext/raster_gradient.pyx", "landlab/layers/ext/eventlayers.pyx", From c6f52f50389d8e9ba371dc012ed2b568eb54b01c Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 12:30:04 -0600 Subject: [PATCH 05/70] replace np.int_t with np.int64_t or fused types --- landlab/ca/cfuncs.pyx | 167 +++++++++--------- .../components/bedrock_landslider/cfuncs.pyx | 35 ++-- .../components/depression_finder/cfuncs.pyx | 29 ++- .../components/drainage_density/cfuncs.pyx | 33 ++-- .../components/erosion_deposition/cfuncs.pyx | 30 ++-- landlab/components/flow_accum/cfuncs.pyx | 67 +++---- landlab/components/flow_director/cfuncs.pyx | 28 ++- .../single_flow/priority_routing/breach.pxd | 80 ++++----- .../single_flow/priority_routing/breach.pyx | 144 +++++++-------- .../overland_flow/_neighbors_at_link.pyx | 10 +- .../priority_flood_flow_router/cfuncs.pyx | 43 ++--- landlab/components/space/ext/calc_qs.pyx | 30 ++-- .../space/ext/calc_sequential_ero_depo.pyx | 66 +++---- landlab/components/stream_power/cfuncs.pyx | 98 +++++----- .../components/threshold_eroder/cfuncs.pyx | 24 +-- landlab/graph/sort/ext/argsort.pyx | 18 +- landlab/graph/sort/ext/remap_element.pyx | 3 +- landlab/utils/_matrix.pyx | 43 ++--- landlab/utils/ext/jaggedarray.pyx | 3 - .../priority_routing/test_breach_c.pxd | 6 +- .../priority_routing/test_breach_c.pyx | 126 ++++++------- 21 files changed, 486 insertions(+), 597 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index 535e13f9a1..50e9ed808c 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -135,13 +135,13 @@ cdef class Event: @cython.boundscheck(True) @cython.wraparound(False) cdef int current_link_state( - link_id, - cython.integral [:] node_state, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - int8_t [:] link_orientation, - num_node_states, - num_node_states_sq, + const long link_id, + const cython.integral [:] node_state, + const cython.integral [:] node_at_link_tail, + const cython.integral [:] node_at_link_head, + const int8_t [:] link_orientation, + const long num_node_states, + const long num_node_states_sq, ): """Get the current state of a link. @@ -173,7 +173,8 @@ cdef int current_link_state( int New link state code """ - cdef int tail_node_state, head_node_state + cdef long tail_node_state + cdef long head_node_state cdef char orientation # Find out the states of the two nodes, and the orientation @@ -189,11 +190,11 @@ cdef int current_link_state( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions( - cython.integral [:] active_links, - cython.integral [:] node_state, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - int8_t [:] link_orientation, + const cython.integral [:] active_links, + const cython.integral [:] node_state, + const cython.integral [:] node_at_link_tail, + const cython.integral [:] node_at_link_head, + const int8_t [:] link_orientation, int8_t [:] bnd_lnk, cython.integral [:] link_state, cython.integral [:] n_xn, @@ -201,11 +202,11 @@ cpdef update_link_states_and_transitions( cython.floating [:] next_update, cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, - num_node_states, - num_node_states_sq, + long num_node_states, + long num_node_states_sq, double current_time, int8_t [:, :] xn_propswap, - xn_prop_update_fn, + np.ndarray[object, ndim=2] xn_prop_update_fn, ): """ Following an "external" change to the node state grid, updates link @@ -260,21 +261,21 @@ cpdef update_link_states_and_transitions( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions_new( - cython.integral [:] active_links, - cython.integral [:] node_state, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - int8_t [:] link_orientation, + const cython.integral [:] active_links, + const cython.integral [:] node_state, + const cython.integral [:] node_at_link_tail, + const cython.integral [:] node_at_link_head, + const int8_t [:] link_orientation, int8_t [:] bnd_lnk, cython.integral [:] link_state, cython.integral [:] n_trn, - priority_queue, + PriorityQueue priority_queue, cython.floating [:] next_update, cython.integral [:] next_trn_id, cython.integral [:, :] trn_id, cython.floating [:] trn_rate, - num_node_states, - num_node_states_sq, + long num_node_states, + long num_node_states_sq, double current_time, ): """ @@ -331,9 +332,9 @@ cpdef update_link_states_and_transitions_new( @cython.cdivision(True) cpdef update_node_states( cython.integral [:] node_state, - uint8_t [:] status_at_node, - tail_node, - head_node, + const uint8_t [:] status_at_node, + long tail_node, + long head_node, new_link_state, num_states, ): @@ -354,7 +355,7 @@ cpdef update_node_states( @cython.boundscheck(True) @cython.wraparound(False) cpdef get_next_event( - link, + long link, long current_state, double current_time, cython.integral [:] n_xn, @@ -492,8 +493,8 @@ cpdef get_next_event_new( cpdef push_transitions_to_event_queue( - int number_of_active_links, - cython.integral [:] active_links, + long number_of_active_links, + const cython.integral [:] active_links, cython.integral [:] n_trn, cython.integral [:] link_state, cython.integral [:, :] trn_id, @@ -526,18 +527,19 @@ cpdef push_transitions_to_event_queue( @cython.boundscheck(True) @cython.wraparound(False) cdef void update_link_state( - link, + long link, long new_link_state, double current_time, int8_t [:] bnd_lnk, - cython.integral [:] node_state, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - int8_t [:] link_orientation, - num_node_states, - num_node_states_sq, + const cython.integral [:] node_state, + const cython.integral [:] node_at_link_tail, + const cython.integral [:] node_at_link_head, + const int8_t [:] link_orientation, + long num_node_states, + long num_node_states_sq, cython.integral [:] link_state, - cython.integral [:] n_xn, event_queue, + cython.integral [:] n_xn, + event_queue, cython.floating [:] next_update, cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -593,16 +595,16 @@ cdef void update_link_state( @cython.boundscheck(True) @cython.wraparound(False) cdef void update_link_state_new( - link, + long link, long new_link_state, double current_time, int8_t [:] bnd_lnk, - cython.integral [:] node_state, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - int8_t [:] link_orientation, - num_node_states, - num_node_states_sq, + const cython.integral [:] node_state, + const cython.integral [:] node_at_link_tail, + const cython.integral [:] node_at_link_head, + const int8_t [:] link_orientation, + long num_node_states, + long num_node_states_sq, cython.integral [:] link_state, cython.integral [:] n_trn, PriorityQueue priority_queue, @@ -674,12 +676,13 @@ cdef void do_transition( cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, cython.integral [:, :] links_at_node, - int8_t [:, :] active_link_dirs_at_node, - num_node_states, - num_node_states_sq, + const int8_t [:, :] active_link_dirs_at_node, + long num_node_states, + long num_node_states_sq, prop_reset_value, int8_t [:, :] xn_propswap, - xn_prop_update_fn, + # xn_prop_update_fn, + np.ndarray[object, ndim=2] xn_prop_update_fn, int8_t [:] bnd_lnk, event_queue, this_cts_model, @@ -872,26 +875,26 @@ cdef void do_transition( # @cython.boundscheck(False) # @cython.wraparound(False) cpdef void do_transition_new( - event_link, + long event_link, double event_time, PriorityQueue priority_queue, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, + const cython.integral [:] node_at_link_tail, + const cython.integral [:] node_at_link_head, cython.integral [:] node_state, cython.integral [:] next_trn_id, cython.integral [:] trn_to, uint8_t [:] status_at_node, - num_node_states, - num_node_states_sq, + long num_node_states, + long num_node_states_sq, int8_t [:] bnd_lnk, - int8_t [:] link_orientation, + const int8_t [:] link_orientation, cython.integral [:] link_state, cython.integral [:] n_trn, cython.integral [:, :] trn_id, cython.floating [:] trn_rate, - cython.integral [:, :] links_at_node, - int8_t [:, :] active_link_dirs_at_node, + const cython.integral [:, :] links_at_node, + const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, cython.integral [:] propid, object prop_data, @@ -1124,22 +1127,22 @@ cpdef double run_cts_new( double current_time, PriorityQueue priority_queue, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, + const cython.integral [:] node_at_link_tail, + const cython.integral [:] node_at_link_head, cython.integral [:] node_state, cython.integral [:] next_trn_id, cython.integral [:] trn_to, uint8_t [:] status_at_node, - num_node_states, - num_node_states_sq, + long num_node_states, + long num_node_states_sq, int8_t [:] bnd_lnk, - int8_t [:] link_orientation, + const int8_t [:] link_orientation, cython.integral [:] link_state, cython.integral [:] n_trn, cython.integral [:, :] trn_id, cython.floating [:] trn_rate, - cython.integral [:, :] links_at_node, - int8_t [:, :] active_link_dirs_at_node, + const cython.integral [:, :] links_at_node, + const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, cython.integral [:] propid, object prop_data, @@ -1241,12 +1244,13 @@ cpdef double run_cts( cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, cython.integral [:, :] links_at_node, - int8_t [:, :] active_link_dirs_at_node, - num_node_states, - num_node_states_sq, + const int8_t [:, :] active_link_dirs_at_node, + long num_node_states, + long num_node_states_sq, prop_reset_value, int8_t [:, :] xn_propswap, - xn_prop_update_fn, + # xn_prop_update_fn, + np.ndarray[object, ndim=2] xn_prop_update_fn, int8_t [:] bnd_lnk, this_cts_model, ): @@ -1318,8 +1322,8 @@ cpdef double run_cts( @cython.boundscheck(False) @cython.wraparound(False) cpdef get_next_event_lean( - link, - current_state, + long link, + long current_state, double current_time, cython.integral [:] n_xn, cython.integral [:, :] xn_to, @@ -1388,18 +1392,19 @@ cpdef get_next_event_lean( @cython.boundscheck(False) @cython.wraparound(False) cdef void update_link_state_lean( - link, - new_link_state, + long link, + long new_link_state, double current_time, int8_t [:] bnd_lnk, cython.integral [:] node_state, cython.integral [:] node_at_link_tail, cython.integral [:] node_at_link_head, int8_t [:] link_orientation, - num_node_states, - num_node_states_sq, + long num_node_states, + long num_node_states_sq, cython.integral [:] link_state, - cython.integral [:] n_xn, event_queue, + cython.integral [:] n_xn, + event_queue, cython.floating [:] next_update, cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -1458,9 +1463,9 @@ cdef void do_transition_lean( cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, cython.integral [:, :] links_at_node, - int8_t [:, :] active_link_dirs_at_node, - num_node_states, - num_node_states_sq, + const int8_t [:, :] active_link_dirs_at_node, + long num_node_states, + long num_node_states_sq, int8_t [:] bnd_lnk, object event_queue, ): @@ -1634,9 +1639,9 @@ cpdef double run_cts_lean( cython.integral [:, :] xn_to, cython.floating [:, :] xn_rate, cython.integral [:, :] links_at_node, - int8_t [:, :] active_link_dirs_at_node, - num_node_states, - num_node_states_sq, + const int8_t [:, :] active_link_dirs_at_node, + long num_node_states, + long num_node_states_sq, int8_t [:] bnd_lnk, ): """Run the model forward for a specified period of time. This "lean" diff --git a/landlab/components/bedrock_landslider/cfuncs.pyx b/landlab/components/bedrock_landslider/cfuncs.pyx index 226ebc9623..f4141254c2 100755 --- a/landlab/components/bedrock_landslider/cfuncs.pyx +++ b/landlab/components/bedrock_landslider/cfuncs.pyx @@ -1,30 +1,21 @@ cimport cython -cimport numpy as np - -import numpy as np - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - -DTYPE_FLOAT = np.float64 -ctypedef np.float64_t DTYPE_FLOAT_t @cython.boundscheck(False) cpdef _landslide_runout( - DTYPE_FLOAT_t dx, - DTYPE_FLOAT_t phi, - DTYPE_FLOAT_t min_deposition_slope, - np.ndarray[DTYPE_INT_t, ndim=1] stack_rev_sel, - np.ndarray[DTYPE_INT_t, ndim=2] receivers, - np.ndarray[DTYPE_FLOAT_t, ndim=2] fract, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Qs_in, - np.ndarray[DTYPE_FLOAT_t, ndim=1] L_Hill, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Qs_out, - np.ndarray[DTYPE_FLOAT_t, ndim=1] dH_Hill, - np.ndarray[DTYPE_FLOAT_t, ndim=1] H_i_temp, - np.ndarray[DTYPE_FLOAT_t, ndim=1] max_D, - np.ndarray[DTYPE_FLOAT_t, ndim=1] length_adjacent_cells, + double dx, + double phi, + double min_deposition_slope, + cython.integral [:] stack_rev_sel, + cython.integral [:, :] receivers, + cython.floating [:, :] fract, + cython.floating [:] Qs_in, + cython.floating [:] L_Hill, + cython.floating [:] Qs_out, + cython.floating [:] dH_Hill, + cython.floating [:] H_i_temp, + cython.floating [:] max_D, + cython.floating [:] length_adjacent_cells, ): """ Calculate landslide runout using a non-local deposition algorithm, see: diff --git a/landlab/components/depression_finder/cfuncs.pyx b/landlab/components/depression_finder/cfuncs.pyx index 6932887882..7856cedda8 100644 --- a/landlab/components/depression_finder/cfuncs.pyx +++ b/landlab/components/depression_finder/cfuncs.pyx @@ -1,25 +1,16 @@ -import numpy as np - cimport cython -cimport numpy as np from landlab.core.messages import warning_message -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - @cython.boundscheck(False) cpdef find_lowest_node_on_lake_perimeter_c( - np.ndarray[DTYPE_INT_t, ndim=2] node_nbrs, - np.ndarray[DTYPE_INT_t, ndim=1] flood_status, - np.ndarray[DTYPE_FLOAT_t, ndim=1] elev, - np.ndarray[DTYPE_INT_t, ndim=1] nodes_this_depression, - DTYPE_INT_t pit_count, - DTYPE_FLOAT_t BIG_ELEV, + const cython.integral [:, :] node_nbrs, + cython.integral [:] flood_status, + cython.floating [:] elev, + cython.integral [:] nodes_this_depression, + long pit_count, + double BIG_ELEV, ): """Locate the lowest node on the margin of the "lake". @@ -84,7 +75,7 @@ cpdef find_lowest_node_on_lake_perimeter_c( """ # Start with the first node on the list, and an arbitrarily large elev cdef int lowest_node = nodes_this_depression[0] - cdef DTYPE_FLOAT_t lowest_elev = BIG_ELEV + cdef double lowest_elev = BIG_ELEV # set up a worst-case scanario array for the pits, and a counter to pull # the good entries later: @@ -125,9 +116,9 @@ cpdef find_lowest_node_on_lake_perimeter_c( print("Node ID: ", i) print("Node Elevation: ", elev[i]) print("Node Flood Status: ", flood_status[i]) - print("Node Neigbors: ", node_nbrs[i]) - print("Neighbor Elevations: ", elev[node_nbrs[i]]) - print("Neigbor Flood Status: ", flood_status[node_nbrs[i]]) + # print("Node Neigbors: ", node_nbrs[i]) + # print("Neighbor Elevations: ", elev[node_nbrs[i]]) + # print("Neigbor Flood Status: ", flood_status[node_nbrs[i]]) warning_message( """If you see no data values in any of the elevation terms this may because you have disconnected open nodes (which diff --git a/landlab/components/drainage_density/cfuncs.pyx b/landlab/components/drainage_density/cfuncs.pyx index db420578a4..12553ede9d 100644 --- a/landlab/components/drainage_density/cfuncs.pyx +++ b/landlab/components/drainage_density/cfuncs.pyx @@ -1,22 +1,17 @@ -import numpy as np - cimport cython -cimport numpy as np - -DTYPE = int -ctypedef np.int_t DTYPE_INT_t -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t +from libc.stdint cimport uint8_t @cython.boundscheck(False) -def _calc_dists_to_channel(np.ndarray[np.uint8_t, ndim=1] ch_network, - np.ndarray[DTYPE_INT_t, ndim=1] flow_receivers, - np.ndarray[DTYPE_INT_t, ndim=1] upstream_order, - np.ndarray[DTYPE_FLOAT_t, ndim=1] link_lengths, - np.ndarray[DTYPE_INT_t, ndim=1] stack_links, - np.ndarray[DTYPE_FLOAT_t, ndim=1] dist_to_ch, - DTYPE_INT_t num_nodes): +def _calc_dists_to_channel( + uint8_t [:] ch_network, + cython.integral [:] flow_receivers, + cython.integral [:] upstream_order, + const cython.floating [:] link_lengths, + cython.integral [:] stack_links, + cython.floating [:] dist_to_ch, + long num_nodes, +): """Calculate distance to nearest channel. Calculate the distances to the closest channel node for all nodes in the @@ -37,10 +32,10 @@ def _calc_dists_to_channel(np.ndarray[np.uint8_t, ndim=1] ch_network, num_nodes : int The number of nodes. """ - cdef DTYPE_INT_t node - cdef DTYPE_INT_t node_iter - cdef DTYPE_INT_t flag - cdef DTYPE_FLOAT_t distance + cdef long node + cdef long node_iter + cdef long flag + cdef double distance for i in range(num_nodes): node = upstream_order[i] diff --git a/landlab/components/erosion_deposition/cfuncs.pyx b/landlab/components/erosion_deposition/cfuncs.pyx index e1728c4a30..ed106b4e8d 100644 --- a/landlab/components/erosion_deposition/cfuncs.pyx +++ b/landlab/components/erosion_deposition/cfuncs.pyx @@ -1,27 +1,21 @@ -import numpy as np - -cimport numpy as np +cimport cython cdef extern from "math.h": double exp(double x) nogil -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - -def calculate_qs_in(np.ndarray[DTYPE_INT_t, ndim=1] stack_flip_ud, - np.ndarray[DTYPE_INT_t, ndim=1] flow_receivers, - np.ndarray[DTYPE_FLOAT_t, ndim=1] cell_area_at_node, - np.ndarray[DTYPE_FLOAT_t, ndim=1] q, - np.ndarray[DTYPE_FLOAT_t, ndim=1] qs, - np.ndarray[DTYPE_FLOAT_t, ndim=1] qs_in, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Es, - DTYPE_FLOAT_t v_s, - DTYPE_FLOAT_t F_f): +def calculate_qs_in( + cython.integral [:] stack_flip_ud, + cython.integral [:] flow_receivers, + const cython.floating [:] cell_area_at_node, + cython.floating [:] q, + cython.floating [:] qs, + cython.floating [:] qs_in, + cython.floating [:] Es, + double v_s, + double F_f, +): """Calculate and qs and qs_in.""" # define internal variables diff --git a/landlab/components/flow_accum/cfuncs.pyx b/landlab/components/flow_accum/cfuncs.pyx index c91b1a285b..dd3ec2cee8 100644 --- a/landlab/components/flow_accum/cfuncs.pyx +++ b/landlab/components/flow_accum/cfuncs.pyx @@ -1,22 +1,13 @@ -import numpy as np - cimport cython -cimport numpy as np - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t @cython.boundscheck(False) cpdef _add_to_stack( - DTYPE_INT_t l, - DTYPE_INT_t j, - np.ndarray[DTYPE_INT_t, ndim=1] s, - np.ndarray[DTYPE_INT_t, ndim=1] delta, - np.ndarray[DTYPE_INT_t, ndim=1] donors, + long l, + long j, + cython.integral [:] s, + cython.integral [:] delta, + cython.integral [:] donors, ): """ Adds node l to the stack and increments the current index (j). @@ -38,13 +29,13 @@ cpdef _add_to_stack( @cython.boundscheck(False) cpdef _accumulate_to_n( - DTYPE_INT_t size, - DTYPE_INT_t q, - np.ndarray[DTYPE_INT_t, ndim=1] s, - np.ndarray[DTYPE_INT_t, ndim=2] r, - np.ndarray[DTYPE_FLOAT_t, ndim=2] p, - np.ndarray[DTYPE_FLOAT_t, ndim=1] drainage_area, - np.ndarray[DTYPE_FLOAT_t, ndim=1] discharge, + long size, + long q, + cython.integral [:] s, + cython.integral [:, :] r, + cython.floating [:, :] p, + cython.floating [:] drainage_area, + cython.floating [:] discharge, ): """ Accumulates drainage area and discharge, permitting transmission losses. @@ -70,11 +61,11 @@ cpdef _accumulate_to_n( @cython.boundscheck(False) cpdef _accumulate_bw( - DTYPE_INT_t size, - np.ndarray[DTYPE_INT_t, ndim=1] s, - np.ndarray[DTYPE_INT_t, ndim=1] r, - np.ndarray[DTYPE_FLOAT_t, ndim=1] drainage_area, - np.ndarray[DTYPE_FLOAT_t, ndim=1] discharge, + long size, + cython.integral [:] s, + cython.integral [:] r, + cython.floating [:] drainage_area, + cython.floating [:] discharge, ): """ Accumulates drainage area and discharge, permitting transmission losses. @@ -97,11 +88,11 @@ cpdef _accumulate_bw( @cython.boundscheck(False) cpdef _make_donors( - DTYPE_INT_t size, - np.ndarray[DTYPE_INT_t, ndim=1] w, - np.ndarray[DTYPE_INT_t, ndim=1] D, - np.ndarray[DTYPE_INT_t, ndim=1] delta, - np.ndarray[DTYPE_INT_t, ndim=1] r, + long size, + cython.integral [:] w, + cython.integral [:] D, + cython.integral [:] delta, + cython.integral [:] r, ): """Determines number of donors""" cdef int ri, i @@ -113,13 +104,13 @@ cpdef _make_donors( @cython.boundscheck(False) cpdef _make_donors_to_n( - DTYPE_INT_t size, - DTYPE_INT_t q, - np.ndarray[DTYPE_INT_t, ndim=1] w, - np.ndarray[DTYPE_INT_t, ndim=1] D, - np.ndarray[DTYPE_INT_t, ndim=1] delta, - np.ndarray[DTYPE_INT_t, ndim=2] r, - np.ndarray[DTYPE_FLOAT_t, ndim=2] p, + long size, + long q, + cython.integral [:] w, + cython.integral [:] D, + cython.integral [:] delta, + cython.integral [:, :] r, + cython.floating [:, :] p, ): """Determines number of donors for route to n""" cdef int ri, i, v, ind diff --git a/landlab/components/flow_director/cfuncs.pyx b/landlab/components/flow_director/cfuncs.pyx index 93e4915995..a7d85c9fb5 100644 --- a/landlab/components/flow_director/cfuncs.pyx +++ b/landlab/components/flow_director/cfuncs.pyx @@ -1,25 +1,17 @@ -import numpy as np - cimport cython -cimport numpy as np - -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - -DTYPE_INT = int -# ctypedef np.longlong_t DTYPE_INT_t -ctypedef np.int_t DTYPE_INT_t @cython.boundscheck(False) -def adjust_flow_receivers(np.ndarray[DTYPE_INT_t, ndim=1] src_nodes, - np.ndarray[DTYPE_INT_t, ndim=1] dst_nodes, - np.ndarray[DTYPE_FLOAT_t, ndim=1] z, - np.ndarray[DTYPE_FLOAT_t, ndim=1] link_slope, - np.ndarray[DTYPE_INT_t, ndim=1] active_links, - np.ndarray[DTYPE_INT_t, ndim=1] receiver, - np.ndarray[DTYPE_INT_t, ndim=1] receiver_link, - np.ndarray[DTYPE_FLOAT_t, ndim=1] steepest_slope): +def adjust_flow_receivers( + const cython.integral [:] src_nodes, + const cython.integral [:] dst_nodes, + const cython.floating [:] z, + const cython.floating [:] link_slope, + const cython.integral [:] active_links, + cython.integral [:] receiver, + cython.integral [:] receiver_link, + cython.floating [:] steepest_slope, +): """Adjust flow receivers based on link slopes and steepest gradients. Parameters diff --git a/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pxd b/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pxd index bdc8d44156..2224080590 100644 --- a/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pxd +++ b/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pxd @@ -10,83 +10,83 @@ from libcpp.pair cimport pair cdef extern from "_priority_queue.hpp" nogil: cdef cppclass _priority_queue: _priority_queue(...) except + - void push(pair[cnp.int_t, cnp.float_t]) - pair[cnp.int_t, cnp.float_t] top() except + + void push(pair[cnp.int64_t, cnp.float_t]) + pair[cnp.int64_t, cnp.float_t] top() except + void pop() bool empty() - cnp.int_t size() + cnp.int64_t size() cdef bool _compare_second(pair[int, double] a, pair[int, double] b) nogil cdef void _init_flow_direction_queues( - const cnp.int_t [:] base_level_nodes, - const cnp.int_t [:] closed_nodes, + const cnp.int64_t [:] base_level_nodes, + const cnp.int64_t [:] closed_nodes, cnp.float_t [:] z, _priority_queue& to_do, - cnp.int_t [:] receivers, - cnp.int_t [:] outlet_nodes, - cnp.int_t [:] done, cnp.int_t* done_n_ptr + cnp.int64_t [:] receivers, + cnp.int64_t [:] outlet_nodes, + cnp.int64_t [:] done, cnp.int64_t* done_n_ptr ) nogil cdef void _set_flooded_and_outlet( - cnp.int_t donor_id, + cnp.int64_t donor_id, cnp.float_t [:] z, - cnp.int_t [:] receivers, - cnp.int_t [:] outlet_nodes, - cnp.int_t [:] depression_outlet_nodes, - cnp.int_t [:] flooded_nodes, + cnp.int64_t [:] receivers, + cnp.int64_t [:] outlet_nodes, + cnp.int64_t [:] depression_outlet_nodes, + cnp.int64_t [:] flooded_nodes, cnp.float_t [:] depression_depths, cnp.float_t [:] depression_free_elevations, - cnp.int_t flooded_status, - cnp.int_t bad_index, + cnp.int64_t flooded_status, + cnp.int64_t bad_index, cnp.float_t min_elevation_relative_diff ) nogil cdef void _set_receiver( - cnp.int_t donor_id, - cnp.int_t receiver_id, - cnp.int_t [:] receivers, - cnp.int_t [:] done, - cnp.int_t* done_n_ptr, + cnp.int64_t donor_id, + cnp.int64_t receiver_id, + cnp.int64_t [:] receivers, + cnp.int64_t [:] done, + cnp.int64_t* done_n_ptr, ) nogil cdef void _set_donor_properties( - cnp.int_t donor_id, - cnp.int_t receiver_id, - cnp.int_t [:] sorted_pseudo_tails, - const cnp.int_t [:, :] head_start_end_indexes, - const cnp.int_t [:] sorted_dupli_links, + cnp.int64_t donor_id, + cnp.int64_t receiver_id, + cnp.int64_t [:] sorted_pseudo_tails, + const cnp.int64_t [:, :] head_start_end_indexes, + const cnp.int64_t [:] sorted_dupli_links, cnp.float_t [:] sorted_dupli_gradients, cnp.float_t [:] z, cnp.float_t [:] steepest_slopes, - cnp.int_t [:] links_to_receivers, + cnp.int64_t [:] links_to_receivers, ) nogil cdef void _direct_flow_c( - cnp.int_t nodes_n, - const cnp.int_t[:] base_level_nodes, - const cnp.int_t[:] closed_nodes, - cnp.int_t[:] sorted_pseudo_tails, + cnp.int64_t nodes_n, + const cnp.int64_t[:] base_level_nodes, + const cnp.int64_t[:] closed_nodes, + cnp.int64_t[:] sorted_pseudo_tails, cnp.float_t[:] sorted_dupli_gradients, - const cnp.int_t[:] sorted_dupli_links, - const cnp.int_t[:, :] head_start_end_indexes, - cnp.int_t [:] outlet_nodes, - cnp.int_t [:] depression_outlet_nodes, - cnp.int_t[:] flooded_nodes, + const cnp.int64_t[:] sorted_dupli_links, + const cnp.int64_t[:, :] head_start_end_indexes, + cnp.int64_t [:] outlet_nodes, + cnp.int64_t [:] depression_outlet_nodes, + cnp.int64_t[:] flooded_nodes, cnp.float_t[:] depression_depths, cnp.float_t [:] depression_free_elevations, - cnp.int_t[:] links_to_receivers, - cnp.int_t[:] receivers, + cnp.int64_t[:] links_to_receivers, + cnp.int64_t[:] receivers, cnp.float_t[:] steepest_slopes, cnp.float_t[:] z, - cnp.int_t flooded_status, - cnp.int_t bad_index, - cnp.int_t neighbors_max_number, + cnp.int64_t flooded_status, + cnp.int64_t bad_index, + cnp.int64_t neighbors_max_number, cnp.float_t min_elevation_relative_diff, ) diff --git a/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pyx b/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pyx index 3bf993a944..892693410a 100644 --- a/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pyx +++ b/landlab/components/flow_router/ext/single_flow/priority_routing/breach.pyx @@ -18,11 +18,11 @@ from libcpp.pair cimport pair cdef extern from "_priority_queue.hpp" nogil: cdef cppclass _priority_queue: _priority_queue(...) except + - void push(pair[cnp.int_t, cnp.float_t]) - pair[cnp.int_t, cnp.float_t] top() except + + void push(pair[cnp.int64_t, cnp.float_t]) + pair[cnp.int64_t, cnp.float_t] top() except + void pop() bool empty() - cnp.int_t size() + cnp.int64_t size() cdef bool _compare_second(pair[int, double] a, pair[int, double] b) nogil: @@ -31,14 +31,14 @@ cdef bool _compare_second(pair[int, double] a, pair[int, double] b) nogil: @cython.boundscheck(False) # turn off bounds-checking for entire function cdef void _init_flow_direction_queues( - const cnp.int_t [:] base_level_nodes, - const cnp.int_t [:] closed_nodes, + const cnp.int64_t [:] base_level_nodes, + const cnp.int64_t [:] closed_nodes, cnp.float_t [:] z, _priority_queue& to_do, - cnp.int_t [:] receivers, - cnp.int_t [:] outlet_nodes, - cnp.int_t [:] done, - cnp.int_t* done_n_ptr, + cnp.int64_t [:] receivers, + cnp.int64_t [:] outlet_nodes, + cnp.int64_t [:] done, + cnp.int64_t* done_n_ptr, ) nogil: """ Add the base-level nodes to the queue and update receivers for base-level and @@ -72,13 +72,13 @@ cdef void _init_flow_direction_queues( """ cdef: - cnp.int_t node_id, i, n = len(base_level_nodes), m = len(closed_nodes) - pair[cnp.int_t, cnp.float_t] node_pair + cnp.int64_t node_id, i, n = len(base_level_nodes), m = len(closed_nodes) + pair[cnp.int64_t, cnp.float_t] node_pair for i in range(n): # NB: for node_i in open_boundary raises a compiling error with nogil. node_id = base_level_nodes[i] - node_pair = pair[cnp.int_t, cnp.float_t](node_id, z[node_id]) + node_pair = pair[cnp.int64_t, cnp.float_t](node_id, z[node_id]) to_do.push(node_pair) receivers[node_id] = node_id outlet_nodes[node_id] = node_id @@ -101,16 +101,16 @@ cdef void _init_flow_direction_queues( @cython.boundscheck(False) cdef void _set_flooded_and_outlet( - cnp.int_t donor_id, + cnp.int64_t donor_id, cnp.float_t [:] z, - cnp.int_t [:] receivers, - cnp.int_t [:] outlet_nodes, - cnp.int_t [:] depression_outlet_nodes, - cnp.int_t [:] flooded_nodes, + cnp.int64_t [:] receivers, + cnp.int64_t [:] outlet_nodes, + cnp.int64_t [:] depression_outlet_nodes, + cnp.int64_t [:] flooded_nodes, cnp.float_t [:] depression_depths, cnp.float_t [:] depression_free_elevations, - cnp.int_t flooded_status, - cnp.int_t bad_index, + cnp.int64_t flooded_status, + cnp.int64_t bad_index, cnp.float_t min_elevation_relative_diff, ) nogil: """ Updates the base-level outlet nodes (outlet_nodes), the depression outlet @@ -148,13 +148,13 @@ cdef void _set_flooded_and_outlet( surface. """ cdef: - cnp.int_t receiver_id = receivers[donor_id] - cnp.int_t receiver_depression_outlet = ( + cnp.int64_t receiver_id = receivers[donor_id] + cnp.int64_t receiver_depression_outlet = ( receiver_id if ( depression_outlet_nodes[receiver_id] == bad_index ) else depression_outlet_nodes[receiver_id] ) - cnp.int_t receiver_outlet = ( + cnp.int64_t receiver_outlet = ( receiver_id if ( outlet_nodes[receiver_id] == bad_index ) else outlet_nodes[receiver_id] @@ -171,11 +171,11 @@ cdef void _set_flooded_and_outlet( @cython.boundscheck(False) cdef void _set_receiver( - cnp.int_t donor_id, - cnp.int_t receiver_id, - cnp.int_t [:] receivers, - cnp.int_t [:] done, - cnp.int_t* done_n_ptr, + cnp.int64_t donor_id, + cnp.int64_t receiver_id, + cnp.int64_t [:] receivers, + cnp.int64_t [:] done, + cnp.int64_t* done_n_ptr, ) nogil: """ Updates the receiver (receivers) and the process statuses (done) of the donor node donor_id. @@ -198,15 +198,15 @@ cdef void _set_receiver( @cython.boundscheck(False) cdef void _set_donor_properties( - cnp.int_t donor_id, - cnp.int_t receiver_id, - cnp.int_t [:] sorted_pseudo_tails, - const cnp.int_t [:, :] head_start_end_indexes, - const cnp.int_t [:] sorted_dupli_links, + cnp.int64_t donor_id, + cnp.int64_t receiver_id, + cnp.int64_t [:] sorted_pseudo_tails, + const cnp.int64_t [:, :] head_start_end_indexes, + const cnp.int64_t [:] sorted_dupli_links, cnp.float_t [:] sorted_dupli_gradients, cnp.float_t [:] z, cnp.float_t [:] steepest_slopes, - cnp.int_t [:] links_to_receivers, + cnp.int64_t [:] links_to_receivers, ) nogil: """ Updates the steepest_slopes and the links_to_receivers of a donor in function of the slopes with its neighbors and the head-tail links of the grid. Steepest @@ -242,11 +242,11 @@ cdef void _set_donor_properties( # range of indexes where donor_id is founded in sorted_pseudo_heads cdef: - cnp.int_t idx1 = head_start_end_indexes[0, donor_id] - cnp.int_t idx2 = head_start_end_indexes[1, donor_id] + 1 + cnp.int64_t idx1 = head_start_end_indexes[0, donor_id] + cnp.int64_t idx2 = head_start_end_indexes[1, donor_id] + 1 - cnp.int_t [:] s = sorted_pseudo_tails[idx1:idx2] - cnp.int_t n = len(s), c = -1, i + cnp.int64_t [:] s = sorted_pseudo_tails[idx1:idx2] + cnp.int64_t n = len(s), c = -1, i # loop to bypass the impossibility to use # sorted_pseudo_tails[idx1:idx2] == receiver_id with memoryviews @@ -267,25 +267,25 @@ cdef void _set_donor_properties( @cython.boundscheck(False) cdef void _direct_flow_c( - cnp.int_t nodes_n, - const cnp.int_t[:] base_level_nodes, - const cnp.int_t[:] closed_nodes, - cnp.int_t[:] sorted_pseudo_tails, + cnp.int64_t nodes_n, + const cnp.int64_t[:] base_level_nodes, + const cnp.int64_t[:] closed_nodes, + cnp.int64_t[:] sorted_pseudo_tails, cnp.float_t[:] sorted_dupli_gradients, - const cnp.int_t[:] sorted_dupli_links, - const cnp.int_t[:, :] head_start_end_indexes, - cnp.int_t [:] outlet_nodes, - cnp.int_t [:] depression_outlet_nodes, - cnp.int_t[:] flooded_nodes, + const cnp.int64_t[:] sorted_dupli_links, + const cnp.int64_t[:, :] head_start_end_indexes, + cnp.int64_t [:] outlet_nodes, + cnp.int64_t [:] depression_outlet_nodes, + cnp.int64_t[:] flooded_nodes, cnp.float_t[:] depression_depths, cnp.float_t[:] depression_free_elevations, - cnp.int_t[:] links_to_receivers, - cnp.int_t[:] receivers, + cnp.int64_t[:] links_to_receivers, + cnp.int64_t[:] receivers, cnp.float_t[:] steepest_slopes, cnp.float_t[:] z, - cnp.int_t flooded_status, - cnp.int_t bad_index, - cnp.int_t neighbors_max_number, + cnp.int64_t flooded_status, + cnp.int64_t bad_index, + cnp.int64_t neighbors_max_number, cnp.float_t min_elevation_relative_diff, ): """ @@ -347,13 +347,13 @@ cdef void _direct_flow_c( surface. """ cdef: - cnp.int_t [:] done - # cnp.int_t [:] tmp_neighbors - # cnp.int_t [:] neighbors_to_do + cnp.int64_t [:] done + # cnp.int64_t [:] tmp_neighbors + # cnp.int64_t [:] neighbors_to_do _priority_queue to_do = _priority_queue(_compare_second) - cnp.int_t receiver_id, donor_id, i, j, done_n - # cnp.int_t [:] neighbors - pair[cnp.int_t, cnp.float_t] node_pair + cnp.int64_t receiver_id, donor_id, i, j, done_n + # cnp.int64_t [:] neighbors + pair[cnp.int64_t, cnp.float_t] node_pair done = np.full(nodes_n, 0, dtype=int) # tmp_neighbors = np.full(neighbors_max_number, 0, dtype=int) @@ -410,30 +410,30 @@ cdef void _direct_flow_c( steepest_slopes, links_to_receivers, ) - node_pair = pair[cnp.int_t, cnp.float_t](donor_id, z[donor_id]) + node_pair = pair[cnp.int64_t, cnp.float_t](donor_id, z[donor_id]) to_do.push(node_pair) def _direct_flow( - cnp.int_t nodes_n, - const cnp.int_t[:] base_level_nodes, - const cnp.int_t[:] closed_nodes, - cnp.int_t[:] sorted_pseudo_tails, + cnp.int64_t nodes_n, + const cnp.int64_t[:] base_level_nodes, + const cnp.int64_t[:] closed_nodes, + cnp.int64_t[:] sorted_pseudo_tails, cnp.float_t[:] sorted_dupli_gradients, - const cnp.int_t[:] sorted_dupli_links, - const cnp.int_t[:, :] head_start_end_indexes, - cnp.int_t [:] outlet_nodes, - cnp.int_t [:] depression_outlet_nodes, - cnp.int_t[:] flooded_nodes, + const cnp.int64_t[:] sorted_dupli_links, + const cnp.int64_t[:, :] head_start_end_indexes, + cnp.int64_t [:] outlet_nodes, + cnp.int64_t [:] depression_outlet_nodes, + cnp.int64_t[:] flooded_nodes, cnp.float_t[:] depression_depths, cnp.float_t[:] depression_free_elevations, - cnp.int_t[:] links_to_receivers, - cnp.int_t[:] receivers, + cnp.int64_t[:] links_to_receivers, + cnp.int64_t[:] receivers, cnp.float_t[:] steepest_slopes, cnp.float_t[:] z, - cnp.int_t flooded_status, - cnp.int_t bad_index, - cnp.int_t neighbors_max_number, + cnp.int64_t flooded_status, + cnp.int64_t bad_index, + cnp.int64_t neighbors_max_number, cnp.float_t min_elevation_relative_diff, ): """ diff --git a/landlab/components/overland_flow/_neighbors_at_link.pyx b/landlab/components/overland_flow/_neighbors_at_link.pyx index 396abbf430..26c1c2141f 100644 --- a/landlab/components/overland_flow/_neighbors_at_link.pyx +++ b/landlab/components/overland_flow/_neighbors_at_link.pyx @@ -1,17 +1,11 @@ -import numpy as np - cimport cython -cimport numpy as np - -DTYPE = int -ctypedef np.int_t DTYPE_t @cython.boundscheck(False) def neighbors_at_link( - np.ndarray[DTYPE_t, ndim=1] links, + const cython.integral [:] links, shape, - np.ndarray[DTYPE_t, ndim=2] out, + cython.integral [:, :] out, ): cdef int stride cdef int n_links diff --git a/landlab/components/priority_flood_flow_router/cfuncs.pyx b/landlab/components/priority_flood_flow_router/cfuncs.pyx index d9f09313e1..1b32f920bb 100644 --- a/landlab/components/priority_flood_flow_router/cfuncs.pyx +++ b/landlab/components/priority_flood_flow_router/cfuncs.pyx @@ -1,29 +1,24 @@ +cimport cython import numpy as np cimport numpy as np -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - cpdef _D8_flowDir( - np.ndarray[DTYPE_INT_t, ndim=1] receivers, - np.ndarray[DTYPE_FLOAT_t, ndim=1] distance_receiver, - np.ndarray[DTYPE_FLOAT_t, ndim=1] steepest_slope, - np.ndarray[DTYPE_FLOAT_t, ndim=1] el_dep_free, - np.ndarray[DTYPE_FLOAT_t, ndim=1] el_ori, - np.ndarray[DTYPE_FLOAT_t, ndim=1] dist, - np.ndarray[DTYPE_INT_t, ndim=1] ngb, - np.ndarray[DTYPE_INT_t, ndim=1] activeCores, - np.ndarray[DTYPE_INT_t, ndim=1] activeCells, - np.ndarray[DTYPE_FLOAT_t, ndim=1] el_d, - DTYPE_INT_t c, - DTYPE_FLOAT_t dx, - np.ndarray[DTYPE_INT_t, ndim=2] adj_link , - np.ndarray[DTYPE_INT_t, ndim=1] rec_link, + cython.integral [:] receivers, + cython.floating [:] distance_receiver, + cython.floating [:] steepest_slope, + cython.floating [:] el_dep_free, + cython.floating [:] el_ori, + cython.floating [:] dist, + cython.integral [:] ngb, + cython.integral [:] activeCores, + cython.integral [:] activeCells, + cython.floating [:] el_d, + long c, + double dx, + cython.integral [:, :] adj_link, + cython.integral [:] rec_link, ): """ Calcualte D8 flow dirs @@ -87,10 +82,10 @@ cpdef _D8_flowDir( steepest_slope[i] = 0 cpdef _D8_FlowAcc( - np.ndarray[DTYPE_FLOAT_t, ndim=1] a, - np.ndarray[DTYPE_FLOAT_t, ndim=1] q, - np.ndarray[DTYPE_INT_t, ndim=1] stack_flip, - np.ndarray[DTYPE_INT_t, ndim=1] receivers, + cython.floating [:] a, + cython.floating [:] q, + cython.integral [:] stack_flip, + cython.integral [:] receivers, ): """ Accumulates drainage area and discharge, permitting transmission losses. diff --git a/landlab/components/space/ext/calc_qs.pyx b/landlab/components/space/ext/calc_qs.pyx index 8c14a44a08..6c71ab4a8d 100644 --- a/landlab/components/space/ext/calc_qs.pyx +++ b/landlab/components/space/ext/calc_qs.pyx @@ -1,29 +1,21 @@ -import numpy as np - -cimport numpy as np +cimport cython cdef extern from "math.h": double exp(double x) nogil -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - def calculate_qs_in( - np.ndarray[DTYPE_INT_t, ndim=1] stack_flip_ud, - np.ndarray[DTYPE_INT_t, ndim=1] flow_receivers, - np.ndarray[DTYPE_FLOAT_t, ndim=1] cell_area_at_node, - np.ndarray[DTYPE_FLOAT_t, ndim=1] q, - np.ndarray[DTYPE_FLOAT_t, ndim=1] qs, - np.ndarray[DTYPE_FLOAT_t, ndim=1] qs_in, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Es, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Er, - DTYPE_FLOAT_t v_s, - DTYPE_FLOAT_t F_f, + cython.integral [:] stack_flip_ud, + cython.integral [:] flow_receivers, + const cython.floating [:] cell_area_at_node, + cython.floating [:] q, + cython.floating [:] qs, + cython.floating [:] qs_in, + cython.floating [:] Es, + cython.floating [:] Er, + double v_s, + double F_f, ): """Calculate and qs and qs_in.""" # define internal variables diff --git a/landlab/components/space/ext/calc_sequential_ero_depo.pyx b/landlab/components/space/ext/calc_sequential_ero_depo.pyx index 75e1d76573..85a24f2d9c 100644 --- a/landlab/components/space/ext/calc_sequential_ero_depo.pyx +++ b/landlab/components/space/ext/calc_sequential_ero_depo.pyx @@ -1,46 +1,31 @@ -import numpy as np - -cimport numpy as np - - -cdef extern from "math.h": - double exp(double x) nogil - +cimport cython from libc.math cimport exp +from libc.math cimport isinf from libc.math cimport log -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - -DTYPE_UINT8 = np.uint8 -ctypedef np.uint8_t DTYPE_UINT8_t - def _sequential_ero_depo( - np.ndarray[DTYPE_INT_t, ndim=1] stack_flip_ud_sel, - np.ndarray[DTYPE_INT_t, ndim=1] flow_receivers, - np.ndarray[DTYPE_FLOAT_t, ndim=1] cell_area, - np.ndarray[DTYPE_FLOAT_t, ndim=1] q, - np.ndarray[DTYPE_FLOAT_t, ndim=1] qs, - np.ndarray[DTYPE_FLOAT_t, ndim=1] qs_in, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Es, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Er, - np.ndarray[DTYPE_FLOAT_t, ndim=1] Q_to_the_m, - np.ndarray[DTYPE_FLOAT_t, ndim=1] slope, - np.ndarray[DTYPE_FLOAT_t, ndim=1] H, - np.ndarray[DTYPE_FLOAT_t, ndim=1] br, - np.ndarray[DTYPE_FLOAT_t, ndim=1] sed_erosion_term, - np.ndarray[DTYPE_FLOAT_t, ndim=1] bed_erosion_term, - np.ndarray[DTYPE_FLOAT_t, ndim=1] K_sed, - DTYPE_FLOAT_t v, - DTYPE_FLOAT_t phi, - DTYPE_FLOAT_t F_f, - DTYPE_FLOAT_t H_star, - DTYPE_FLOAT_t dt, - DTYPE_FLOAT_t thickness_lim, + cython.integral [:] stack_flip_ud_sel, + cython.integral [:] flow_receivers, + const cython.floating [:] cell_area, + cython.floating [:] q, + cython.floating [:] qs, + cython.floating [:] qs_in, + cython.floating [:] Es, + cython.floating [:] Er, + cython.floating [:] Q_to_the_m, + cython.floating [:] slope, + cython.floating [:] H, + cython.floating [:] br, + cython.floating [:] sed_erosion_term, + cython.floating [:] bed_erosion_term, + cython.floating [:] K_sed, + double v, + double phi, + double F_f, + double H_star, + double dt, + double thickness_lim, ): """Calculate and qs and qs_in.""" @@ -75,7 +60,7 @@ def _sequential_ero_depo( ) # No blowup else: - H_loc = H_star * np.log( + H_loc = H_star * log( (1 / ((depo_rate / (1 - phi)) / (sed_erosion_loc / (1 - phi)) - 1)) * ( exp( @@ -94,7 +79,8 @@ def _sequential_ero_depo( ) ) # In case soil depth evolves to infinity, fall back to no entrainment - if H_loc == np.inf: + # if H_loc == np.inf: + if isinf(H_loc): H_loc = ( H[node_id] + (depo_rate / (1 - phi) - sed_erosion_loc/ (1 - phi)) * dt diff --git a/landlab/components/stream_power/cfuncs.pyx b/landlab/components/stream_power/cfuncs.pyx index a2399688b5..d929cad78d 100644 --- a/landlab/components/stream_power/cfuncs.pyx +++ b/landlab/components/stream_power/cfuncs.pyx @@ -1,6 +1,6 @@ -import numpy as np - -cimport numpy as np +cimport cython +from libc.math cimport exp +from libc.math cimport powf from scipy.optimize import newton @@ -8,28 +8,14 @@ from scipy.optimize import newton # method for using the brentq method in cython. from scipy.optimize._zeros import _brentq as brentq -# from libc.math cimport fabs - - -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - - -cdef extern from "math.h": - double fabs(double x) nogil - double pow(double x, double y) nogil - def brent_method_erode_variable_threshold( - np.ndarray[DTYPE_INT_t, ndim=1] src_nodes, - np.ndarray[DTYPE_INT_t, ndim=1] dst_nodes, - np.ndarray[DTYPE_FLOAT_t, ndim=1] threshsxdt, - np.ndarray[DTYPE_FLOAT_t, ndim=1] alpha, - DTYPE_FLOAT_t n, - np.ndarray[DTYPE_FLOAT_t, ndim=1] z, + const cython.integral [:] src_nodes, + const cython.integral [:] dst_nodes, + const cython.floating [:] threshsxdt, + const cython.floating [:] alpha, + const double n, + cython.floating [:] z, ): """Erode node elevations using Brent's method for stability. @@ -98,7 +84,7 @@ def brent_method_erode_variable_threshold( # using z_diff_old, calculate the alpha paramter of Braun and # Willet by calculating alpha times z - alpha_param = alpha[src_id] * pow(z_diff_old, n-1.0) + alpha_param = alpha[src_id] * powf(z_diff_old, n-1.0) # Calculate the beta parameter that accounts for the possible # presence of a threshold. @@ -156,12 +142,12 @@ def brent_method_erode_variable_threshold( def brent_method_erode_fixed_threshold( - np.ndarray[DTYPE_INT_t, ndim=1] src_nodes, - np.ndarray[DTYPE_INT_t, ndim=1] dst_nodes, - DTYPE_FLOAT_t threshsxdt, - np.ndarray[DTYPE_FLOAT_t, ndim=1] alpha, - DTYPE_FLOAT_t n, - np.ndarray[DTYPE_FLOAT_t, ndim=1] z, + const cython.integral [:] src_nodes, + const cython.integral [:] dst_nodes, + const double threshsxdt, + const cython.floating [:] alpha, + const double n, + cython.floating [:] z, ): """Erode node elevations. @@ -231,7 +217,7 @@ def brent_method_erode_fixed_threshold( # using z_diff_old, calculate the alpha paramter of Braun and # Willet by calculating alpha times z - alpha_param = alpha[src_id] * pow(z_diff_old, n-1.0) + alpha_param = alpha[src_id] * powf(z_diff_old, n-1.0) # Calculate the beta parameter that accounts for the possible # presence of a threshold. @@ -288,10 +274,10 @@ def brent_method_erode_fixed_threshold( def erode_fn( - DTYPE_FLOAT_t x, - DTYPE_FLOAT_t alpha, - DTYPE_FLOAT_t beta, - DTYPE_FLOAT_t n, + const double x, + const double alpha, + const double beta, + const double n, ): """Evaluates the solution to the water-depth equation. @@ -375,18 +361,18 @@ def erode_fn( """ cdef double f - f = x - 1.0 + (alpha * pow(x, n)) - beta + f = x - 1.0 + (alpha * powf(x, n)) - beta return f def smooth_stream_power_eroder_solver( - np.ndarray[DTYPE_INT_t, ndim=1] src_nodes, - np.ndarray[DTYPE_INT_t, ndim=1] dst_nodes, - np.ndarray[DTYPE_FLOAT_t, ndim=1] z, - np.ndarray[DTYPE_FLOAT_t, ndim=1] alpha, - np.ndarray[DTYPE_FLOAT_t, ndim=1] gamma, - np.ndarray[DTYPE_FLOAT_t, ndim=1] delta, + const cython.integral [:] src_nodes, + const cython.integral [:] dst_nodes, + cython.floating [:] z, + const cython.floating [:] alpha, + const cython.floating [:] gamma, + const cython.floating [:] delta, ): """Erode node elevations using Newtons Method for smoothed Stream Power. " @@ -444,12 +430,12 @@ def smooth_stream_power_eroder_solver( def new_elev( - DTYPE_FLOAT_t x, - DTYPE_FLOAT_t a, - DTYPE_FLOAT_t b, - DTYPE_FLOAT_t c, - DTYPE_FLOAT_t d, - DTYPE_FLOAT_t e, + const double x, + const double a, + const double b, + const double c, + const double d, + const double e, ): """Equation for elevation of a node at timestep t+1. @@ -470,18 +456,18 @@ def new_elev( """ cdef double f - f = x * (1.0 + a) + c * np.exp(-d * (x - b)) - e + f = x * (1.0 + a) + c * exp(-d * (x - b)) - e return f def new_elev_prime( - DTYPE_FLOAT_t x, - DTYPE_FLOAT_t a, - DTYPE_FLOAT_t b, - DTYPE_FLOAT_t c, - DTYPE_FLOAT_t d, - DTYPE_FLOAT_t e, + const double x, + const double a, + const double b, + const double c, + const double d, + const double e, ): """Equation for elevation of a node at timestep t+1. @@ -502,6 +488,6 @@ def new_elev_prime( """ cdef double f - f = (1.0 + a) - c * d * np.exp(-d * (x - b)) + f = (1.0 + a) - c * d * exp(-d * (x - b)) return f diff --git a/landlab/components/threshold_eroder/cfuncs.pyx b/landlab/components/threshold_eroder/cfuncs.pyx index 54fecd5069..1a8d564cda 100644 --- a/landlab/components/threshold_eroder/cfuncs.pyx +++ b/landlab/components/threshold_eroder/cfuncs.pyx @@ -1,21 +1,13 @@ -import numpy as np - -cimport numpy as np - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t - -DTYPE_FLOAT = np.float64 -ctypedef np.float64_t DTYPE_FLOAT_t +cimport cython cpdef _thresholder( - np.ndarray[DTYPE_INT_t, ndim=1] stack, - np.ndarray[DTYPE_INT_t, ndim=1] link_to_rcvr, - np.ndarray[DTYPE_INT_t, ndim=1] receivers, - np.ndarray[DTYPE_FLOAT_t, ndim=1] linkLengths, - np.ndarray[DTYPE_FLOAT_t, ndim=1] el, - DTYPE_FLOAT_t slope_thres, + const cython.integral [:] stack, + const cython.integral [:] link_to_rcvr, + const cython.integral [:] receivers, + const cython.floating [:] linkLengths, + cython.floating [:] el, + const double slope_thres, ): """ Calcualte D8 flow dirs @@ -29,6 +21,6 @@ cpdef _thresholder( for node in stack: dist_to_rcvr = linkLengths[link_to_rcvr[node]] - el[node] = np.minimum( + el[node] = min( el[node], el[receivers[node]] + slope_thres * dist_to_rcvr ) diff --git a/landlab/graph/sort/ext/argsort.pyx b/landlab/graph/sort/ext/argsort.pyx index eb0459b9f9..1fe3251644 100644 --- a/landlab/graph/sort/ext/argsort.pyx +++ b/landlab/graph/sort/ext/argsort.pyx @@ -1,25 +1,19 @@ -import numpy as np - cimport cython -cimport numpy as np - -from cython.parallel import prange - from cython cimport view from libc.stdlib cimport free from libc.stdlib cimport malloc -ctypedef np.int_t INT_t -ctypedef np.float_t FLOAT_t +from cython.parallel import prange + cdef struct Sorter: - INT_t index - FLOAT_t value + long index + double value cdef struct IntSorter: - INT_t index - INT_t value + long index + long value cdef extern from "stdlib.h": diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index d271288c05..b25930f53c 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -14,8 +14,7 @@ cdef extern from "math.h": from .spoke_sort import sort_spokes_at_wheel -DTYPE = int -ctypedef np.int_t DTYPE_t +ctypedef np.int64_t DTYPE_t ctypedef np.uint8_t uint8 ctypedef fused id_t: diff --git a/landlab/utils/_matrix.pyx b/landlab/utils/_matrix.pyx index 9b8238f546..6860cc82df 100644 --- a/landlab/utils/_matrix.pyx +++ b/landlab/utils/_matrix.pyx @@ -1,25 +1,20 @@ -import numpy as np - cimport cython -cimport numpy as np - -DTYPE_INT = int -ctypedef np.int_t DTYPE_INT_t -DTYPE_FLOAT = np.double -ctypedef np.double_t DTYPE_FLOAT_t +ctypedef fused id_t: + cython.integral + long long @cython.boundscheck(False) @cython.wraparound(False) def get_matrix_diagonal_elements_with_coef( - np.ndarray[DTYPE_INT_t, ndim=2] core_nodes_at_c2c_link, - np.ndarray[DTYPE_INT_t, ndim=2] core_nodes_at_c2fv_link, - np.ndarray[DTYPE_INT_t, ndim=2] core_nodes_at_fv2c_link, - np.ndarray[DTYPE_FLOAT_t, ndim=1] coef_at_c2c_link, - np.ndarray[DTYPE_FLOAT_t, ndim=1] coef_at_c2fv_link, - np.ndarray[DTYPE_FLOAT_t, ndim=1] coef_at_fv2c_link, - np.ndarray[DTYPE_FLOAT_t, ndim=1] data, + const id_t [:, :] core_nodes_at_c2c_link, + const id_t [:, :] core_nodes_at_c2fv_link, + const id_t [:, :] core_nodes_at_fv2c_link, + const cython.floating [:] coef_at_c2c_link, + const cython.floating [:] coef_at_c2fv_link, + const cython.floating [:] coef_at_fv2c_link, + cython.floating [:] data, ): cdef int tail, head cdef int link @@ -48,10 +43,10 @@ def get_matrix_diagonal_elements_with_coef( @cython.boundscheck(False) @cython.wraparound(False) def get_matrix_diagonal_elements( - np.ndarray[DTYPE_INT_t, ndim=2] core_nodes_at_c2c_link, - np.ndarray[DTYPE_INT_t, ndim=2] core_nodes_at_c2fv_link, - np.ndarray[DTYPE_INT_t, ndim=2] core_nodes_at_fv2c_link, - np.ndarray[DTYPE_FLOAT_t, ndim=1] data, + const id_t [:, :] core_nodes_at_c2c_link, + const id_t [:, :] core_nodes_at_c2fv_link, + const id_t [:, :] core_nodes_at_fv2c_link, + cython.floating [:] data, ): cdef int tail, head cdef int link @@ -78,11 +73,11 @@ def get_matrix_diagonal_elements( @cython.boundscheck(False) @cython.wraparound(False) def fill_right_hand_side( - np.ndarray[DTYPE_INT_t, ndim=2] nodes_at_c2fv_link, - np.ndarray[DTYPE_INT_t, ndim=2] nodes_at_fv2c_link, - np.ndarray[DTYPE_INT_t, ndim=1] core_node_at_node, - np.ndarray[DTYPE_FLOAT_t, ndim=1] value_at_node, - np.ndarray[DTYPE_FLOAT_t, ndim=1] out, + const id_t [:, :] nodes_at_c2fv_link, + const id_t [:, :] nodes_at_fv2c_link, + const id_t [:] core_node_at_node, + const cython.floating [:] value_at_node, + cython.floating [:] out, ): cdef int tail, head diff --git a/landlab/utils/ext/jaggedarray.pyx b/landlab/utils/ext/jaggedarray.pyx index 6f64e3d004..ab0b419a4a 100644 --- a/landlab/utils/ext/jaggedarray.pyx +++ b/landlab/utils/ext/jaggedarray.pyx @@ -4,9 +4,6 @@ cimport cython cimport numpy as np from libc.string cimport memcpy -ctypedef np.int_t INT_t -ctypedef np.float_t FLOAT_t - cdef void _pad_jaggedarray( void * data, diff --git a/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pxd b/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pxd index 96261b72c3..71762b2a8a 100644 --- a/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pxd +++ b/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pxd @@ -10,8 +10,8 @@ from libcpp.pair cimport pair cdef extern from "_priority_queue.hpp" nogil: cdef cppclass _priority_queue: _priority_queue(...) except + - void push(pair[cnp.int_t, cnp.float_t]) - pair[cnp.int_t, cnp.float_t] top() except + + void push(pair[cnp.int64_t, cnp.float_t]) + pair[cnp.int64_t, cnp.float_t] top() except + void pop() bool empty() - cnp.int_t size() + cnp.int64_t size() diff --git a/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pyx b/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pyx index be00bced35..fa56c8c9c9 100644 --- a/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pyx +++ b/tests/components/flow_router/ext/single_flow/priority_routing/test_breach_c.pyx @@ -26,18 +26,18 @@ import landlab.components.flow_router.ext.single_flow.priority_routing.breach as cdef extern from "_priority_queue.hpp" nogil: cdef cppclass _priority_queue: _priority_queue(...) except + - void push(pair[cnp.int_t, cnp.float_t]) - pair[cnp.int_t, cnp.float_t] top() except + + void push(pair[cnp.int64_t, cnp.float_t]) + pair[cnp.int64_t, cnp.float_t] top() except + void pop() bool empty() - cnp.int_t size() + cnp.int64_t size() def test_priority_queue(): cdef: - pair[cnp.int_t, cnp.float_t] a = pair[cnp.int_t, cnp.float_t](0, 1045.3) - pair[cnp.int_t, cnp.float_t] b = pair[cnp.int_t, cnp.float_t](1, 536.3) - pair[cnp.int_t, cnp.float_t] c = pair[cnp.int_t, cnp.float_t](2, 2034.12) + pair[cnp.int64_t, cnp.float_t] a = pair[cnp.int64_t, cnp.float_t](0, 1045.3) + pair[cnp.int64_t, cnp.float_t] b = pair[cnp.int64_t, cnp.float_t](1, 536.3) + pair[cnp.int64_t, cnp.float_t] c = pair[cnp.int64_t, cnp.float_t](2, 2034.12) _priority_queue to_do = _priority_queue(breach_c._compare_second) assert to_do.empty() is True @@ -53,15 +53,15 @@ def test_priority_queue(): def test_init_flow_direction_queues(): # on a grid of 7 nodes cdef: - cnp.int_t nodes_n = 7 - cnp.int_t [:] base_level_nodes = np.array([0, 2]) - cnp.int_t [:] closed_nodes = np.array([5]) + cnp.int64_t nodes_n = 7 + cnp.int64_t [:] base_level_nodes = np.array([0, 2]) + cnp.int64_t [:] closed_nodes = np.array([5]) cnp.float_t [:] z = np.array([4.5, 3.2, 6.7, 13.2, 5.6, 100.3, 45.32]) _priority_queue to_do = _priority_queue(breach_c._compare_second) - cnp.int_t [:] receivers = -1 * np.ones(nodes_n, dtype=int) - cnp.int_t [:] outlet_nodes = -1 * np.ones(nodes_n, dtype=int) - cnp.int_t [:] done = np.zeros(nodes_n, dtype=int) - cnp.int_t done_n = 0 + cnp.int64_t [:] receivers = -1 * np.ones(nodes_n, dtype=int) + cnp.int64_t [:] outlet_nodes = -1 * np.ones(nodes_n, dtype=int) + cnp.int64_t [:] done = np.zeros(nodes_n, dtype=int) + cnp.int64_t done_n = 0 breach_c._init_flow_direction_queues( base_level_nodes, closed_nodes, z, to_do, receivers, outlet_nodes, done, &done_n ) @@ -77,13 +77,13 @@ def test_init_flow_direction_queues(): def test_set_flooded_and_outlet(): # on a grid of 5 nodes cdef: - cnp.int_t donor_id = 2, bad_index = -1, flooded_status = 3 + cnp.int64_t donor_id = 2, bad_index = -1, flooded_status = 3 cnp.float_t min_elevation_relative_diff = 1e-2 cnp.float_t [:] z = np.array([0.1, 67.1, 42.1, 70.3, 34.5]) - cnp.int_t [:] receivers = np.array([0, 0, 1, -1, -1]) - cnp.int_t [:] outlet_nodes = np.array([0, 0, -1, -1, -1]) - cnp.int_t [:] depression_outlet_nodes = np.array([-1, -1, -1, -1, -1]) - cnp.int_t [:] flooded_nodes = np.zeros(5, dtype=int) + cnp.int64_t [:] receivers = np.array([0, 0, 1, -1, -1]) + cnp.int64_t [:] outlet_nodes = np.array([0, 0, -1, -1, -1]) + cnp.int64_t [:] depression_outlet_nodes = np.array([-1, -1, -1, -1, -1]) + cnp.int64_t [:] flooded_nodes = np.zeros(5, dtype=int) cnp.float_t [:] depression_depths = np.zeros(5, dtype=float) cnp.float_t [:] depression_free_elevations = ( np.array([0.1, 67.1, 42.1, 70.3, 34.5]) @@ -149,9 +149,9 @@ def test_set_flooded_and_outlet(): def test_set_receiver(): # on a grid of 6 nodes cdef: - cnp.int_t donor_id = 3, receiver_id = 4, done_n = 1 - cnp.int_t [:] receivers = np.array([0, -1, -1, -1, -1, -1]) - cnp.int_t [:] done = np.array([1, 0, 0, 0, 0, 0]) + cnp.int64_t donor_id = 3, receiver_id = 4, done_n = 1 + cnp.int64_t [:] receivers = np.array([0, -1, -1, -1, -1, -1]) + cnp.int64_t [:] done = np.array([1, 0, 0, 0, 0, 0]) breach_c._set_receiver(donor_id, receiver_id, receivers, done, &done_n) assert donor_id == 3 assert receiver_id == 4 @@ -163,26 +163,26 @@ def test_set_receiver(): def test_set_donor_properties(): # on a grid of 9 nodes cdef: - cnp.int_t donor_id = 5, receiver_id = 7 - cnp.int_t [:] _sorted_pseudo_heads = np.array( + cnp.int64_t donor_id = 5, receiver_id = 7 + cnp.int64_t [:] _sorted_pseudo_heads = np.array( [ 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8 ] ) - cnp.int_t [:] sorted_pseudo_tails = np.array( + cnp.int64_t [:] sorted_pseudo_tails = np.array( [ 3, 1, 0, 4, 2, 1, 5, 0, 6, 4, 7, 3, 1, 5, 4, 2, 8, 7, 3, 8, 4, 6, 5, 7 ] ) - cnp.int_t [:, :] head_start_end_indexes = np.array( + cnp.int64_t [:, :] head_start_end_indexes = np.array( [ [0, 2, 5, 7, 10, 14, 17, 19, 22], [1, 4, 6, 9, 13, 16, 18, 21, 23] ] ) - cnp.int_t [:] sorted_dupli_links = np.array( + cnp.int64_t [:] sorted_dupli_links = np.array( [ 2, 0, 0, 3, 1, 1, 4, 2, 7, 5, 8, 5, 3, 6, 6, 4, 9, @@ -206,7 +206,7 @@ def test_set_donor_properties(): ] ) cnp.float_t [:] steepest_slopes = np.zeros(9, dtype=float) - cnp.int_t [:] links_to_receivers = -1 * np.ones(9, dtype=int) + cnp.int64_t [:] links_to_receivers = -1 * np.ones(9, dtype=int) breach_c._set_donor_properties( donor_id, @@ -292,16 +292,16 @@ def test_set_donor_properties(): def test_direct_flow_c(): # Grid of 25 nodes cdef: - cnp.int_t nodes_n = 25, flooded_status = 3, bad_index = -1 + cnp.int64_t nodes_n = 25, flooded_status = 3, bad_index = -1 cnp.float_t min_elevation_relative_diff = 1e-2 - cnp.int_t neighbors_max_number = 50 - cnp.int_t[:] base_level_nodes = np.array( + cnp.int64_t neighbors_max_number = 50 + cnp.int64_t[:] base_level_nodes = np.array( [0, 1, 2, 4, 5, 9, 10, 14, 15, 19, 20, 21, 22, 23, 24] ) - cnp.int_t[:] base_level_nodes_0 = np.copy(base_level_nodes) - cnp.int_t[:] closed_nodes = np.array([3]) - cnp.int_t[:] closed_nodes_0 = np.copy(closed_nodes) - cnp.int_t[:] _sorted_pseudo_heads = np.array( + cnp.int64_t[:] base_level_nodes_0 = np.copy(base_level_nodes) + cnp.int64_t[:] closed_nodes = np.array([3]) + cnp.int64_t[:] closed_nodes_0 = np.copy(closed_nodes) + cnp.int64_t[:] _sorted_pseudo_heads = np.array( [ 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, @@ -311,7 +311,7 @@ def test_direct_flow_c(): 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24 ] ) # unused, for info - cnp.int_t[:] sorted_pseudo_tails = np.array( + cnp.int64_t[:] sorted_pseudo_tails = np.array( [ 5, 1, 6, 2, 0, 3, 7, 1, 8, 2, 4, 9, 3, 6, 10, 0, 7, @@ -321,7 +321,7 @@ def test_direct_flow_c(): 15, 20, 22, 16, 17, 23, 21, 24, 18, 22, 19, 23 ] ) - cnp.int_t[:] sorted_pseudo_tails_0 = np.copy(sorted_pseudo_tails) + cnp.int64_t[:] sorted_pseudo_tails_0 = np.copy(sorted_pseudo_tails) cnp.float_t[:] sorted_dupli_gradients = np.array( [ 0.1955672, @@ -344,7 +344,7 @@ def test_direct_flow_c(): ] ) cnp.float_t[:] sorted_dupli_gradients_0 = np.copy(sorted_dupli_gradients) - cnp.int_t[:] sorted_dupli_links = np.array( + cnp.int64_t[:] sorted_dupli_links = np.array( [ 4, 0, 5, 1, 0, 2, 6, 1, 7, 2, 3, 8, 3, 9, 13, 4, 10, @@ -354,8 +354,8 @@ def test_direct_flow_c(): 31, 36, 37, 32, 33, 38, 37, 39, 34, 38, 35, 39 ] ) - cnp.int_t[:] sorted_dupli_links_0 = np.copy(sorted_dupli_links) - cnp.int_t[:, :] head_start_end_indexes = np.array( + cnp.int64_t[:] sorted_dupli_links_0 = np.copy(sorted_dupli_links) + cnp.int64_t[:, :] head_start_end_indexes = np.array( [ [ 0, 2, 5, @@ -368,13 +368,13 @@ def test_direct_flow_c(): ] ] ) - cnp.int_t[:, :] head_start_end_indexes_0 = np.copy(head_start_end_indexes) + cnp.int64_t[:, :] head_start_end_indexes_0 = np.copy(head_start_end_indexes) cnp.float_t[:] depression_depths = np.zeros(25, dtype=float) - cnp.int_t[:] outlet_nodes = -1 * np.ones(25, dtype=int) - cnp.int_t[:] depression_outlet_nodes = -1 * np.ones(25, dtype=int) - cnp.int_t[:] flooded_nodes = np.zeros(25, dtype=int) - cnp.int_t[:] links_to_receivers = -1 * np.ones(25, dtype=int) - cnp.int_t[:] receivers = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] outlet_nodes = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] depression_outlet_nodes = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] flooded_nodes = np.zeros(25, dtype=int) + cnp.int64_t[:] links_to_receivers = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] receivers = -1 * np.ones(25, dtype=int) cnp.float_t[:] steepest_slopes = np.zeros(25, dtype=float) cnp.float_t[:] z = np.array( [ @@ -496,16 +496,16 @@ def test_direct_flow_c(): def test_direct_flow(): # Grid of 25 nodes cdef: - cnp.int_t nodes_n = 25, flooded_status = 3, bad_index = -1 - cnp.int_t neighbors_max_number = 50 + cnp.int64_t nodes_n = 25, flooded_status = 3, bad_index = -1 + cnp.int64_t neighbors_max_number = 50 cnp.float_t min_elevation_relative_diff = 1e-2 - cnp.int_t[:] base_level_nodes = np.array( + cnp.int64_t[:] base_level_nodes = np.array( [0, 1, 2, 4, 5, 9, 10, 14, 15, 19, 20, 21, 22, 23, 24] ) - cnp.int_t[:] base_level_nodes_0 = np.copy(base_level_nodes) - cnp.int_t[:] closed_nodes = np.array([3]) - cnp.int_t[:] closed_nodes_0 = np.copy(closed_nodes) - cnp.int_t[:] _sorted_pseudo_heads = np.array( + cnp.int64_t[:] base_level_nodes_0 = np.copy(base_level_nodes) + cnp.int64_t[:] closed_nodes = np.array([3]) + cnp.int64_t[:] closed_nodes_0 = np.copy(closed_nodes) + cnp.int64_t[:] _sorted_pseudo_heads = np.array( [ 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, @@ -515,7 +515,7 @@ def test_direct_flow(): 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24 ] ) # unused, for info - cnp.int_t[:] sorted_pseudo_tails = np.array( + cnp.int64_t[:] sorted_pseudo_tails = np.array( [ 5, 1, 6, 2, 0, 3, 7, 1, 8, 2, 4, 9, 3, 6, 10, 0, 7, @@ -525,7 +525,7 @@ def test_direct_flow(): 15, 20, 22, 16, 17, 23, 21, 24, 18, 22, 19, 23 ] ) - cnp.int_t[:] sorted_pseudo_tails_0 = np.copy(sorted_pseudo_tails) + cnp.int64_t[:] sorted_pseudo_tails_0 = np.copy(sorted_pseudo_tails) cnp.float_t[:] sorted_dupli_gradients = np.array( [ 0.1955672, @@ -548,7 +548,7 @@ def test_direct_flow(): ] ) cnp.float_t[:] sorted_dupli_gradients_0 = np.copy(sorted_dupli_gradients) - cnp.int_t[:] sorted_dupli_links = np.array( + cnp.int64_t[:] sorted_dupli_links = np.array( [ 4, 0, 5, 1, 0, 2, 6, 1, 7, 2, 3, 8, 3, 9, 13, 4, 10, @@ -558,8 +558,8 @@ def test_direct_flow(): 31, 36, 37, 32, 33, 38, 37, 39, 34, 38, 35, 39 ] ) - cnp.int_t[:] sorted_dupli_links_0 = np.copy(sorted_dupli_links) - cnp.int_t[:, :] head_start_end_indexes = np.array( + cnp.int64_t[:] sorted_dupli_links_0 = np.copy(sorted_dupli_links) + cnp.int64_t[:, :] head_start_end_indexes = np.array( [ [ 0, 2, 5, @@ -572,13 +572,13 @@ def test_direct_flow(): ] ] ) - cnp.int_t[:, :] head_start_end_indexes_0 = np.copy(head_start_end_indexes) + cnp.int64_t[:, :] head_start_end_indexes_0 = np.copy(head_start_end_indexes) cnp.float_t[:] depression_depths = np.zeros(25, dtype=float) - cnp.int_t[:] outlet_nodes = -1 * np.ones(25, dtype=int) - cnp.int_t[:] depression_outlet_nodes = -1 * np.ones(25, dtype=int) - cnp.int_t[:] flooded_nodes = np.zeros(25, dtype=int) - cnp.int_t[:] links_to_receivers = -1 * np.ones(25, dtype=int) - cnp.int_t[:] receivers = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] outlet_nodes = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] depression_outlet_nodes = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] flooded_nodes = np.zeros(25, dtype=int) + cnp.int64_t[:] links_to_receivers = -1 * np.ones(25, dtype=int) + cnp.int64_t[:] receivers = -1 * np.ones(25, dtype=int) cnp.float_t[:] steepest_slopes = np.zeros(25, dtype=float) cnp.float_t[:] z = np.array( [ From b7e813aaee3d64f2e0a544f4655fc0daebecb4ca Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 12:32:01 -0600 Subject: [PATCH 06/70] remove asfarray, use asarray instead --- landlab/graph/framed_voronoi/framed_voronoi.py | 8 +++++--- landlab/graph/sort/sort.py | 4 +++- landlab/grid/hex.py | 2 +- landlab/grid/raster.py | 6 +++--- landlab/layers/eventlayers.py | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/landlab/graph/framed_voronoi/framed_voronoi.py b/landlab/graph/framed_voronoi/framed_voronoi.py index a496a783d0..a75aa87517 100644 --- a/landlab/graph/framed_voronoi/framed_voronoi.py +++ b/landlab/graph/framed_voronoi/framed_voronoi.py @@ -355,14 +355,16 @@ def __init__( self._seed = seed try: - xy_spacing = np.asfarray(np.broadcast_to(xy_spacing, 2)) + xy_spacing = np.asarray(np.broadcast_to(xy_spacing, 2), dtype=float) except TypeError as exc: raise TypeError("spacing must be a float or a tuple of floats") from exc else: self._xy_spacing = xy_spacing[0], xy_spacing[1] try: - xy_of_lower_left = np.asfarray(np.broadcast_to(xy_of_lower_left, 2)) + xy_of_lower_left = np.asarray( + np.broadcast_to(xy_of_lower_left, 2), dtype=float + ) except TypeError as exc: raise TypeError( "xy of lower left must be a float or a tuple of floats" @@ -379,7 +381,7 @@ def __init__( layout = layouts["_".join([orientation, node_layout])] try: - xy_min_spacing = np.asfarray(np.broadcast_to(xy_min_spacing, 2)) + xy_min_spacing = np.asarray(np.broadcast_to(xy_min_spacing, 2), dtype=float) except TypeError as exc: raise TypeError( "minimal spacing must be a float or a tuple of floats" diff --git a/landlab/graph/sort/sort.py b/landlab/graph/sort/sort.py index 8cb9088c33..ef5a529795 100644 --- a/landlab/graph/sort/sort.py +++ b/landlab/graph/sort/sort.py @@ -492,7 +492,9 @@ def sort_links(nodes_at_link, nodes, midpoint_of_link=None): """ from ..quantity.ext.of_link import calc_midpoint_of_link - y_of_node, x_of_node = np.asfarray(nodes[0]), np.asfarray(nodes[1]) + y_of_node, x_of_node = np.asarray(nodes[0], dtype=float), np.asarray( + nodes[1], dtype=float + ) if midpoint_of_link is None: midpoint_of_link = np.empty((len(nodes_at_link), 2), dtype=float) diff --git a/landlab/grid/hex.py b/landlab/grid/hex.py index 83405d9b51..3b1b190c4b 100644 --- a/landlab/grid/hex.py +++ b/landlab/grid/hex.py @@ -102,7 +102,7 @@ def __init__( >>> hmg.number_of_nodes 7 """ - self._xy_of_lower_left = tuple(numpy.asfarray(xy_of_lower_left)) + self._xy_of_lower_left = tuple(numpy.asarray(xy_of_lower_left, dtype=float)) DualHexGraph.__init__( self, diff --git a/landlab/grid/raster.py b/landlab/grid/raster.py index d880c4d839..0eb4a4e466 100644 --- a/landlab/grid/raster.py +++ b/landlab/grid/raster.py @@ -195,8 +195,8 @@ def __init__( or set it up such that one can create a zero-node grid. """ shape = tuple(shape) - xy_spacing = np.asfarray(np.broadcast_to(xy_spacing, 2)) - self._xy_of_lower_left = tuple(np.asfarray(xy_of_lower_left)) + xy_spacing = np.asarray(np.broadcast_to(xy_spacing, 2), dtype=float) + self._xy_of_lower_left = tuple(np.asarray(xy_of_lower_left, dtype=float)) if shape[0] <= 0 or shape[1] <= 0: raise ValueError("number of rows and columns must be positive") @@ -363,7 +363,7 @@ def xy_of_lower_left(self, xy_of_lower_left): with self.thawed(): self.x_of_node[:] -= dx self.y_of_node[:] -= dy - self._xy_of_lower_left = tuple(np.asfarray(xy_of_lower_left)) + self._xy_of_lower_left = tuple(np.asarray(xy_of_lower_left, dtype=float)) @property def cell_grid_shape(self): diff --git a/landlab/layers/eventlayers.py b/landlab/layers/eventlayers.py index 0b2e70d40c..698b9893c1 100644 --- a/landlab/layers/eventlayers.py +++ b/landlab/layers/eventlayers.py @@ -97,7 +97,7 @@ def _deposit_or_erode(layers, n_layers, dz): except (AttributeError, ValueError): dz = np.broadcast_to(dz, (layers.shape[1],)) finally: - dz = np.asfarray(dz) + dz = np.asarray(dz, dtype=float) deposit_or_erode(layers, n_layers, dz) From e72c3e13b2c7c75d0674bf294e92e95b7895574d Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 12:32:39 -0600 Subject: [PATCH 07/70] remove np.NaN, use np.nan instead --- landlab/utils/window_statistic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/landlab/utils/window_statistic.py b/landlab/utils/window_statistic.py index b2a9617905..de17633f0f 100644 --- a/landlab/utils/window_statistic.py +++ b/landlab/utils/window_statistic.py @@ -215,7 +215,7 @@ def calculate_window_statistic( closed_nodes = grid.status_at_node == grid.BC_NODE_IS_CLOSED nodes_in_loop = nodes_in_loop[~closed_nodes] nodes_to_include[closed_nodes] = False - output[closed_nodes] = np.NaN + output[closed_nodes] = np.nan # Calculate "dist to point" then local value at nodes within window. for node in nodes_in_loop: From 6d002f575ef6ea392e585894cd69e869fa435e32 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 12:33:11 -0600 Subject: [PATCH 08/70] update doctest for numpy array to list --- tests/ca/grain_hill.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/ca/grain_hill.py b/tests/ca/grain_hill.py index 52167918d1..bf82617426 100644 --- a/tests/ca/grain_hill.py +++ b/tests/ca/grain_hill.py @@ -442,14 +442,14 @@ def get_profile_and_soil_thickness(self, grid, data): >>> ns[[8, 13, 11, 16, 14]] = 7 >>> gh = GrainHill((3, 7), show_plots=False) # grid size arbitrary here >>> (elev, thickness) = gh.get_profile_and_soil_thickness(hg, ns) - >>> list(elev) - [0.0, 2.5, 3.0, 2.5, 0.0] - >>> list(thickness) - [0.0, 2.0, 2.0, 1.0, 0.0] + >>> elev + array([0. , 2.5, 3. , 2.5, 0. ]) + >>> thickness + array([0., 2., 2., 1., 0.]) """ nc = grid.number_of_node_columns - elev = zeros(nc) - soil = zeros(nc) + elev = zeros(nc, dtype=float) + soil = zeros(nc, dtype=float) for col in range(nc): base_id = (col // 2) + (col % 2) * ((nc + 1) // 2) node_ids = arange(base_id, grid.number_of_nodes, nc) From 772ff18618ade6fd0f489db5ffae393e43c821b6 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 12:35:42 -0600 Subject: [PATCH 09/70] remove uses of itemset for numpy arrays --- landlab/grid/decorators.py | 5 ----- tests/grid/test_raster_grid/test_status_at_node.py | 10 ---------- 2 files changed, 15 deletions(-) diff --git a/landlab/grid/decorators.py b/landlab/grid/decorators.py index 3c4bf9a5e6..22e8ac7f12 100644 --- a/landlab/grid/decorators.py +++ b/landlab/grid/decorators.py @@ -75,11 +75,6 @@ def __array_finalize__(self, obj): if obj is None: return - def itemset(self, ind, value): - """Set value of array, then call reset function.""" - np.ndarray.itemset(self, ind, value) - getattr(self.grid, reset)() - def __setitem__(self, ind, value): """Set value of array, then call reset function.""" np.ndarray.__setitem__(self, ind, value) diff --git a/tests/grid/test_raster_grid/test_status_at_node.py b/tests/grid/test_raster_grid/test_status_at_node.py index 999c12f42a..dae59f938a 100644 --- a/tests/grid/test_raster_grid/test_status_at_node.py +++ b/tests/grid/test_raster_grid/test_status_at_node.py @@ -54,16 +54,6 @@ def test_set_status_with_array_bool(): ) -def test_set_with_itemset(): - grid = RasterModelGrid((4, 5)) - grid.status_at_node.itemset(7, 2) - - assert_array_equal( - grid.status_at_node, - [FV, FV, FV, FV, FV, FV, 0, 2, 0, FV, FV, 0, 0, 0, FV, FV, FV, FV, FV, FV], - ) - - def test_set_status_with_array(): """Test that active links are reset after changing the node status.""" grid = RasterModelGrid((4, 5)) From 34e01d82b7e554dbad5daed709d2f1ba94087ab0 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 12:37:13 -0600 Subject: [PATCH 10/70] allow numpy 2 --- pyproject.toml | 4 ++-- requirements.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1ab7c3aa60..19851e70a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["cython~=3.0.0b3", "numpy<2", "setuptools", "wheel"] +requires = ["cython~=3.0.0b3", "numpy", "setuptools", "wheel"] build-backend = "setuptools.build_meta" [project] @@ -40,7 +40,7 @@ dependencies = [ "importlib-resources; python_version < '3.12'", "matplotlib", "netcdf4", - "numpy >=1.20,<2", + "numpy >=1.20", "pyyaml", "pyshp != 2.3.0", "rich-click", diff --git a/requirements.in b/requirements.in index c9a5d40f50..79cf3de277 100644 --- a/requirements.in +++ b/requirements.in @@ -2,7 +2,7 @@ bmipy importlib-resources; python_version < '3.12' matplotlib netcdf4 -numpy >=1.20,<2 +numpy >=1.20 pandas pyshp != 2.3.0 pyyaml From c4990678fb6c8c8f276b4a626229da09f85ee62f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 13:38:34 -0600 Subject: [PATCH 11/70] convert link orientation to an int before multiply --- landlab/ca/boundaries/hex_lattice_tectonicizer.py | 2 +- landlab/ca/celllab_cts.py | 2 +- landlab/ca/cfuncs.pyx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/landlab/ca/boundaries/hex_lattice_tectonicizer.py b/landlab/ca/boundaries/hex_lattice_tectonicizer.py index 7d48358eb5..c35be5569d 100644 --- a/landlab/ca/boundaries/hex_lattice_tectonicizer.py +++ b/landlab/ca/boundaries/hex_lattice_tectonicizer.py @@ -1015,7 +1015,7 @@ def shift_link_and_transition_data_upward(self, ca, current_time): tns = self.node_state[self.grid.node_at_link_head[lk]] orientation = ca.link_orientation[lk] new_link_state = ( - orientation * ca.num_node_states_sq + fns * ca.num_node_states + tns + int(orientation) * ca.num_node_states_sq + fns * ca.num_node_states + tns ) # Schedule a new transition, if applicable diff --git a/landlab/ca/celllab_cts.py b/landlab/ca/celllab_cts.py index 17c7f69704..0239377908 100644 --- a/landlab/ca/celllab_cts.py +++ b/landlab/ca/celllab_cts.py @@ -681,7 +681,7 @@ def update_link_state_new(self, link, new_link_state, current_time): tns = self.node_state[self.grid.node_at_link_head[link]] orientation = self.link_orientation[link] new_link_state = int( - orientation * self.num_node_states_sq + fns * self.num_node_states + tns + int(orientation) * self.num_node_states_sq + fns * self.num_node_states + tns ) self.link_state[link] = new_link_state diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index 50e9ed808c..d902eae24c 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -432,7 +432,7 @@ cpdef get_next_event( @cython.boundscheck(True) @cython.wraparound(False) cpdef get_next_event_new( - link, + long link, long current_state, double current_time, cython.integral [:] n_trn, From da4c20d13396d78f5bee61abd1d9aeecc853e48d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 3 Jul 2024 19:57:15 +0000 Subject: [PATCH 12/70] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- landlab/ca/boundaries/hex_lattice_tectonicizer.py | 4 +++- landlab/ca/celllab_cts.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/landlab/ca/boundaries/hex_lattice_tectonicizer.py b/landlab/ca/boundaries/hex_lattice_tectonicizer.py index c35be5569d..bfe3212368 100644 --- a/landlab/ca/boundaries/hex_lattice_tectonicizer.py +++ b/landlab/ca/boundaries/hex_lattice_tectonicizer.py @@ -1015,7 +1015,9 @@ def shift_link_and_transition_data_upward(self, ca, current_time): tns = self.node_state[self.grid.node_at_link_head[lk]] orientation = ca.link_orientation[lk] new_link_state = ( - int(orientation) * ca.num_node_states_sq + fns * ca.num_node_states + tns + int(orientation) * ca.num_node_states_sq + + fns * ca.num_node_states + + tns ) # Schedule a new transition, if applicable diff --git a/landlab/ca/celllab_cts.py b/landlab/ca/celllab_cts.py index 0239377908..b7bded600b 100644 --- a/landlab/ca/celllab_cts.py +++ b/landlab/ca/celllab_cts.py @@ -681,7 +681,9 @@ def update_link_state_new(self, link, new_link_state, current_time): tns = self.node_state[self.grid.node_at_link_head[link]] orientation = self.link_orientation[link] new_link_state = int( - int(orientation) * self.num_node_states_sq + fns * self.num_node_states + tns + int(orientation) * self.num_node_states_sq + + fns * self.num_node_states + + tns ) self.link_state[link] = new_link_state From 5f56bee7f40c69942b2f4dd6d9c626d4bcda4aef Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 14:10:40 -0600 Subject: [PATCH 13/70] cancel currently running workflows --- .github/workflows/docs.yml | 4 ++++ .github/workflows/test-notebooks.yml | 4 ++++ .github/workflows/test.yml | 12 +++--------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0ccedf2942..b1f0a24b3c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,6 +2,10 @@ name: Documentation on: [push, pull_request] +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + jobs: build: name: Build documentation diff --git a/.github/workflows/test-notebooks.yml b/.github/workflows/test-notebooks.yml index ad7fda0a1e..21f7a53a59 100644 --- a/.github/workflows/test-notebooks.yml +++ b/.github/workflows/test-notebooks.yml @@ -2,6 +2,10 @@ name: Notebooks on: [push, pull_request] +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + jobs: build-and-test: name: Check notebooks diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cb1051422f..6e5e6aea86 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,15 +2,9 @@ name: Test on: [push, pull_request] -# on: -# push: -# paths: -# - "landlab/**" -# - "tests/**" -# pull_request: -# paths: -# - "landlab/**" -# - "tests/**" +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true jobs: build-and-test: From 26ba72a7933ca6eea02761f7c41e1087c01ecca4 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 14:12:23 -0600 Subject: [PATCH 14/70] add news fragment --- news/1956.misc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 news/1956.misc diff --git a/news/1956.misc b/news/1956.misc new file mode 100644 index 0000000000..263521f7f4 --- /dev/null +++ b/news/1956.misc @@ -0,0 +1,2 @@ + +Updated *Landlab* to be compatible with *numpy* v2. From eaeec8ed5689cb54c4c925ad0f9477b29ca43597 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 14:35:37 -0600 Subject: [PATCH 15/70] set read-only arrays to be const arrays --- .../space/ext/calc_sequential_ero_depo.pyx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/landlab/components/space/ext/calc_sequential_ero_depo.pyx b/landlab/components/space/ext/calc_sequential_ero_depo.pyx index 85a24f2d9c..4cae0886e7 100644 --- a/landlab/components/space/ext/calc_sequential_ero_depo.pyx +++ b/landlab/components/space/ext/calc_sequential_ero_depo.pyx @@ -5,21 +5,21 @@ from libc.math cimport log def _sequential_ero_depo( - cython.integral [:] stack_flip_ud_sel, - cython.integral [:] flow_receivers, + const cython.integral [:] stack_flip_ud_sel, + const cython.integral [:] flow_receivers, const cython.floating [:] cell_area, - cython.floating [:] q, + const cython.floating [:] q, cython.floating [:] qs, cython.floating [:] qs_in, - cython.floating [:] Es, - cython.floating [:] Er, - cython.floating [:] Q_to_the_m, - cython.floating [:] slope, + const cython.floating [:] Es, + const cython.floating [:] Er, + const cython.floating [:] Q_to_the_m, + const cython.floating [:] slope, cython.floating [:] H, cython.floating [:] br, - cython.floating [:] sed_erosion_term, - cython.floating [:] bed_erosion_term, - cython.floating [:] K_sed, + const cython.floating [:] sed_erosion_term, + const cython.floating [:] bed_erosion_term, + const cython.floating [:] K_sed, double v, double phi, double F_f, From 1570447c34abab695ab99bdc40dbabb659376510 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 15:07:04 -0600 Subject: [PATCH 16/70] pin numpy 2.0.0 --- noxfile.py | 4 ++-- requirements/required.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index 55a0e564b4..06b32ef7a8 100644 --- a/noxfile.py +++ b/noxfile.py @@ -37,7 +37,7 @@ def test(session: nox.Session) -> None: PATH["requirements"] / "testing.txt", ) - session.conda_install("richdem", "numpy<2", channel=["nodefaults", "conda-forge"]) + session.conda_install("richdem", channel=["nodefaults", "conda-forge"]) session.install("-e", ".", "--no-deps") check_package_versions(session, files=["required.txt", "testing.txt"]) @@ -87,7 +87,7 @@ def test_notebooks(session: nox.Session) -> None: "-r", PATH["requirements"] / "notebooks.txt", ) - session.conda_install("richdem", "numpy<2", channel=["nodefaults", "conda-forge"]) + session.conda_install("richdem", channel=["nodefaults", "conda-forge"]) session.install("git+https://github.com/mcflugen/nbmake.git@mcflugen/add-markers") session.install("-e", ".", "--no-deps") diff --git a/requirements/required.txt b/requirements/required.txt index d370fbbaf5..abb9703612 100644 --- a/requirements/required.txt +++ b/requirements/required.txt @@ -2,7 +2,7 @@ bmipy==2.0.1 importlib-resources==6.4.0; python_version < '3.12' matplotlib==3.8.0 netcdf4==1.6.5 -numpy==1.26.1 +numpy==2.0.0 pandas==2.1.2 pyshp==2.3.1 pyyaml==6.0.1 From 930970affd4a5d7d73c7ca6ff1e38b7be9aa15f7 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 15:29:02 -0600 Subject: [PATCH 17/70] update matplotlib lib to 3.9.0 --- requirements/required.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/required.txt b/requirements/required.txt index abb9703612..689a1ce4f7 100644 --- a/requirements/required.txt +++ b/requirements/required.txt @@ -1,6 +1,6 @@ bmipy==2.0.1 importlib-resources==6.4.0; python_version < '3.12' -matplotlib==3.8.0 +matplotlib==3.9.0 netcdf4==1.6.5 numpy==2.0.0 pandas==2.1.2 From 17118111e8cafbdd6171a77b511da610423b44dd Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 15:38:16 -0600 Subject: [PATCH 18/70] bump pandas to 2.2.2 --- requirements/required.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/required.txt b/requirements/required.txt index 689a1ce4f7..7d09ff3247 100644 --- a/requirements/required.txt +++ b/requirements/required.txt @@ -3,7 +3,7 @@ importlib-resources==6.4.0; python_version < '3.12' matplotlib==3.9.0 netcdf4==1.6.5 numpy==2.0.0 -pandas==2.1.2 +pandas==2.2.2 pyshp==2.3.1 pyyaml==6.0.1 rich-click==1.7.0 From 76fe8d92386307aa1c96d40207cebd5fe64cf113 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 15:40:06 -0600 Subject: [PATCH 19/70] bump scipy to 1.14.0, xarray to 2024.6.0 --- requirements/required.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/required.txt b/requirements/required.txt index 7d09ff3247..6bbb405c2b 100644 --- a/requirements/required.txt +++ b/requirements/required.txt @@ -7,6 +7,6 @@ pandas==2.2.2 pyshp==2.3.1 pyyaml==6.0.1 rich-click==1.7.0 -scipy==1.11.3 +scipy==1.14.0 statsmodels==0.14.0 -xarray==2023.10.1 +xarray==2024.6.0 From d912dfba93b8ab24188802735e9ab9e1d356012a Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 16:02:05 -0600 Subject: [PATCH 20/70] bump dask to 2024.6.2 --- requirements/notebooks.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/notebooks.txt b/requirements/notebooks.txt index 77261f8567..c1486f5b79 100644 --- a/requirements/notebooks.txt +++ b/requirements/notebooks.txt @@ -1,5 +1,5 @@ bmi-topography==0.8.2 -dask[array]==2023.10.1 +dask[array]==2024.6.2 holoviews==1.18.0 jupyter==1.0.0 mesa==2.1.2 From f71a34a21774083a3f691d5335dbf5e90dc8f345 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 16:02:40 -0600 Subject: [PATCH 21/70] bump netcdf to 1.7.1.post1 --- requirements/required.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/required.txt b/requirements/required.txt index 6bbb405c2b..1259c0c358 100644 --- a/requirements/required.txt +++ b/requirements/required.txt @@ -1,7 +1,7 @@ bmipy==2.0.1 importlib-resources==6.4.0; python_version < '3.12' matplotlib==3.9.0 -netcdf4==1.6.5 +netcdf4==1.7.1.post1 numpy==2.0.0 pandas==2.2.2 pyshp==2.3.1 From bf5c97990f56fc6d3dd20d41b06e19e686276072 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 23:41:09 -0600 Subject: [PATCH 22/70] use int64_t for jaggedarray offset --- landlab/utils/ext/jaggedarray.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/landlab/utils/ext/jaggedarray.pyx b/landlab/utils/ext/jaggedarray.pyx index ab0b419a4a..226e1fde09 100644 --- a/landlab/utils/ext/jaggedarray.pyx +++ b/landlab/utils/ext/jaggedarray.pyx @@ -2,12 +2,13 @@ import numpy as np cimport cython cimport numpy as np +from libc.stdint cimport int64_t from libc.string cimport memcpy cdef void _pad_jaggedarray( void * data, - long * offset, + int64_t * offset, size_t n_rows, size_t size, void * buff, @@ -28,7 +29,7 @@ cdef void _pad_jaggedarray( @cython.wraparound(False) def unravel( np.ndarray data, - np.ndarray[long, ndim=1, mode="c"] offset, + np.ndarray[int64_t, ndim=1, mode="c"] offset, np.ndarray out, ): _pad_jaggedarray( From efcfe47bc5fd68d006d124778b1979ee4bdae831 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 3 Jul 2024 23:44:46 -0600 Subject: [PATCH 23/70] set numpy print option to v1.25 --- landlab/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/landlab/__init__.py b/landlab/__init__.py index 91bb5874d5..3e52da0039 100644 --- a/landlab/__init__.py +++ b/landlab/__init__.py @@ -9,6 +9,8 @@ :URL: https://landlab.readthedocs.io/en/release/ :License: MIT """ +import numpy as np + from landlab._registry import registry from landlab._version import __version__ from landlab.core.errors import MissingKeyError @@ -33,6 +35,8 @@ from landlab.plot.imshowhs import imshowhs_grid from landlab.plot.imshowhs import imshowhs_grid_at_node +np.set_printoptions(legacy="1.25") + cite_as = registry.format_citations __all__ = [ From 6b2695425245fe904d0329b25289cb7df585d4b7 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 4 Jul 2024 09:04:02 -0600 Subject: [PATCH 24/70] replace np.alltrue with np.all --- landlab/components/lake_fill/lake_fill_barnes.py | 2 +- landlab/components/plant_competition_ca/plant_competition_ca.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/landlab/components/lake_fill/lake_fill_barnes.py b/landlab/components/lake_fill/lake_fill_barnes.py index 07bdca4af1..3e4b10b184 100644 --- a/landlab/components/lake_fill/lake_fill_barnes.py +++ b/landlab/components/lake_fill/lake_fill_barnes.py @@ -1091,7 +1091,7 @@ def _redirect_flowdirs(self, surface, lake_dict, openq): >>> lake_dict = {8: deque([7]), 16: deque([15, 9, 14, 22])} >>> fd.run_one_step() # fill the director fields >>> fa.run_one_step() # get a drainage_area - >>> np.alltrue(mg.at_node["flow__sink_flag"][[7, 15, 22]]) # sinks + >>> np.all(mg.at_node["flow__sink_flag"][[7, 15, 22]]) # sinks True >>> nodes_in_lakes = np.array([7, 8, 9, 14, 15, 16, 22]) >>> nodes_not_in_lakes = np.setdiff1d(mg.nodes.flat, nodes_in_lakes) diff --git a/landlab/components/plant_competition_ca/plant_competition_ca.py b/landlab/components/plant_competition_ca/plant_competition_ca.py index c7d3220553..b2725a1ac7 100644 --- a/landlab/components/plant_competition_ca/plant_competition_ca.py +++ b/landlab/components/plant_competition_ca/plant_competition_ca.py @@ -62,7 +62,7 @@ class VegCA(Component): >>> import numpy as np >>> A = np.copy(grid["cell"]["plant__age"]) >>> ca_veg.update() - >>> np.alltrue(grid["cell"]["plant__age"] == A) + >>> np.all(grid["cell"]["plant__age"] == A) False References From 04b1b57aa592cfbfa3e57af5f17b5047359b498c Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 4 Jul 2024 11:33:46 -0600 Subject: [PATCH 25/70] import netcdf_file from scipy.io --- landlab/io/netcdf/dump.py | 4 ++-- landlab/io/netcdf/write.py | 8 ++++---- tests/io/netcdf/test_write_netcdf.py | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/landlab/io/netcdf/dump.py b/landlab/io/netcdf/dump.py index ae1bd94308..44f670e7de 100644 --- a/landlab/io/netcdf/dump.py +++ b/landlab/io/netcdf/dump.py @@ -67,8 +67,8 @@ def to_netcdf( Read the file back in and check its contents. - >>> from scipy.io import netcdf - >>> fp = netcdf.netcdf_file("test.nc", "r") + >>> from scipy.io import netcdf_file + >>> fp = netcdf_file("test.nc", "r") >>> "at_node:uplift_rate" in fp.variables True >>> "at_node:topographic__elevation" in fp.variables diff --git a/landlab/io/netcdf/write.py b/landlab/io/netcdf/write.py index 5664b0cd78..df497f2235 100644 --- a/landlab/io/netcdf/write.py +++ b/landlab/io/netcdf/write.py @@ -620,8 +620,8 @@ def write_netcdf( Read the file back in and check its contents. - >>> from scipy.io import netcdf - >>> fp = netcdf.netcdf_file("test.nc", "r") + >>> from scipy.io import netcdf_file + >>> fp = netcdf_file("test.nc", "r") >>> "uplift_rate" in fp.variables True >>> "topographic__elevation" in fp.variables @@ -797,8 +797,8 @@ def write_raster_netcdf( Read the file back in and check its contents. - >>> from scipy.io import netcdf - >>> fp = netcdf.netcdf_file("test.nc", "r") + >>> from scipy.io import netcdf_file + >>> fp = netcdf_file("test.nc", "r") >>> "uplift_rate" in fp.variables True >>> "topographic__elevation" in fp.variables diff --git a/tests/io/netcdf/test_write_netcdf.py b/tests/io/netcdf/test_write_netcdf.py index 14d2a97f39..ae34a4a421 100644 --- a/tests/io/netcdf/test_write_netcdf.py +++ b/tests/io/netcdf/test_write_netcdf.py @@ -57,7 +57,7 @@ def test_netcdf_write_uint8_field_netcdf4(tmpdir): def test_netcdf_write_as_netcdf3_64bit(tmpdir): """Test write_netcdf with output format 64-bit netcdf3.""" - from scipy.io import netcdf + from scipy.io import netcdf_file field = RasterModelGrid((4, 3)) field.add_field("topographic__elevation", np.arange(12.0), at="node") @@ -66,7 +66,7 @@ def test_netcdf_write_as_netcdf3_64bit(tmpdir): with tmpdir.as_cwd(): write_netcdf("test.nc", field, format="NETCDF3_64BIT") - f = netcdf.netcdf_file("test.nc", "r") + f = netcdf_file("test.nc", "r") for name in ["topographic__elevation", "uplift_rate"]: assert name in f.variables @@ -88,7 +88,7 @@ def test_netcdf_write_as_netcdf3_classic(tmpdir): with tmpdir.as_cwd(): write_netcdf("test.nc", field, format="NETCDF3_CLASSIC") - f = netcdf.netcdf_file("test.nc", "r") + f = netcdf_file("test.nc", "r") for name in ["topographic__elevation", "uplift_rate"]: assert name in f.variables From 3917029cf8bf61aa15e716696c903d9752c02818 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 10:38:56 -0600 Subject: [PATCH 26/70] use np.tile instead of repmat --- .../priority_flood_flow_router/priority_flood_flow_router.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py index 1e4968c62e..02be8d4e63 100644 --- a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py +++ b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py @@ -17,7 +17,6 @@ from functools import partial import numpy as np -import numpy.matlib as npm from landlab import Component from landlab import FieldError @@ -662,8 +661,8 @@ def calc_flow_dir_acc(self, hill_flow=False, update_depressions=True): props_Pf = props_Pf.astype(np.float64) # should be float64 # Now, make sure sum is 1 in 64 bits props_Pf[props_Pf == -1] = 0 - proportion_matrix = npm.repmat( - np.reshape(props_Pf.sum(axis=1), [props_Pf.shape[0], 1]), 1, 8 + proportion_matrix = np.tile( + np.reshape(props_Pf.sum(axis=1), [props_Pf.shape[0], 1]), (1, 8) ) rc64_temp = np.where( proportion_matrix == 0, props_Pf, props_Pf / proportion_matrix From 51ddc5a6e0822b63ae15324289b142d2e0fbabf3 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 10:43:44 -0600 Subject: [PATCH 27/70] use np.isin instead of deprecated np.in1d --- landlab/components/depression_finder/lake_mapper.py | 5 +++-- landlab/components/diffusion/diffusion.py | 2 +- .../overland_flow/generate_overland_flow_deAlmeida.py | 2 +- landlab/components/sink_fill/fill_sinks.py | 2 +- landlab/graph/voronoi/voronoi_to_graph.py | 2 +- landlab/grid/raster.py | 2 +- landlab/utils/structured_grid.py | 2 +- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/landlab/components/depression_finder/lake_mapper.py b/landlab/components/depression_finder/lake_mapper.py index 115c87ff3f..f1e69aebce 100644 --- a/landlab/components/depression_finder/lake_mapper.py +++ b/landlab/components/depression_finder/lake_mapper.py @@ -1154,7 +1154,8 @@ def _route_flow(self): if np.min(new_link) == np.max(new_link) and np.min(new_link) == -1: self._links[outlet_node] = -1 else: - self._links[outlet_node] = new_link + assert len(new_link) == 1 + self._links[outlet_node] = new_link[0] # make a check assert ( @@ -1213,7 +1214,7 @@ def _handle_outlet_node(self, outlet_node, nodes_in_lake): outlet_neighbors = self._grid.active_adjacent_nodes_at_node[ outlet_node ].copy() - inlake = np.in1d(outlet_neighbors.flat, nodes_in_lake) + inlake = np.isin(outlet_neighbors.flat, nodes_in_lake) assert inlake.size > 0 outlet_neighbors[inlake] = -1 unique_outs, unique_indxs = np.unique(outlet_neighbors, return_index=True) diff --git a/landlab/components/diffusion/diffusion.py b/landlab/components/diffusion/diffusion.py index 88f1495442..f1c764dad6 100644 --- a/landlab/components/diffusion/diffusion.py +++ b/landlab/components/diffusion/diffusion.py @@ -353,7 +353,7 @@ def updated_boundary_conditions(self): )[0] heads = self._grid.node_at_link_head[self._grid.fixed_links] tails = self._grid.node_at_link_tail[self._grid.fixed_links] - head_is_fixed = np.in1d(heads, fixed_grad_nodes) + head_is_fixed = np.isin(heads, fixed_grad_nodes) self._fixed_grad_nodes = np.where(head_is_fixed, heads, tails) self._fixed_grad_anchors = np.where(head_is_fixed, tails, heads) vals = self._grid.at_node[self._values_to_diffuse] diff --git a/landlab/components/overland_flow/generate_overland_flow_deAlmeida.py b/landlab/components/overland_flow/generate_overland_flow_deAlmeida.py index 0ec0baef68..18507c7d45 100644 --- a/landlab/components/overland_flow/generate_overland_flow_deAlmeida.py +++ b/landlab/components/overland_flow/generate_overland_flow_deAlmeida.py @@ -919,4 +919,4 @@ def find_active_neighbors_for_fixed_links(grid): array([20, 21, 22, 23, 24, 14, 17, 27, 30, 20, 21, 22, 23, 24]) """ neighbors = links.neighbors_at_link(grid.shape, grid.fixed_links).flat - return neighbors[np.in1d(neighbors, grid.active_links)] + return neighbors[np.isin(neighbors, grid.active_links)] diff --git a/landlab/components/sink_fill/fill_sinks.py b/landlab/components/sink_fill/fill_sinks.py index c45670a45a..e797257762 100644 --- a/landlab/components/sink_fill/fill_sinks.py +++ b/landlab/components/sink_fill/fill_sinks.py @@ -238,7 +238,7 @@ def run_one_step(self): ) assert elev_increment > 0.0 all_ordering = self._grid.at_node["flow__upstream_node_order"] - upstream_order_bool = np.in1d( + upstream_order_bool = np.isin( all_ordering, lake_nodes, assume_unique=True ) lake_upstream_order = all_ordering[upstream_order_bool] diff --git a/landlab/graph/voronoi/voronoi_to_graph.py b/landlab/graph/voronoi/voronoi_to_graph.py index 59db9ad98b..4228759367 100644 --- a/landlab/graph/voronoi/voronoi_to_graph.py +++ b/landlab/graph/voronoi/voronoi_to_graph.py @@ -354,7 +354,7 @@ def drop_element(self, ids, at="node"): for name in self.ids_with_prefix(at): var = self._mesh[name] array = var.values.reshape((-1,)) - array[np.in1d(array, dropped_ids)] = -1 + array[np.isin(array, dropped_ids)] = -1 for id_ in dropped_ids[::-1]: array[array > id_] -= 1 diff --git a/landlab/grid/raster.py b/landlab/grid/raster.py index 0eb4a4e466..0bc117c25b 100644 --- a/landlab/grid/raster.py +++ b/landlab/grid/raster.py @@ -1104,7 +1104,7 @@ def set_looped_boundaries(self, top_bottom_are_looped, sides_are_looped): existing_links = np.array([]) else: unrepeated_node_entries = np.logical_not( - np.in1d( + np.isin( self.looped_node_properties["boundary_node_IDs"], these_linked_nodes ) ) diff --git a/landlab/utils/structured_grid.py b/landlab/utils/structured_grid.py index 8bb78b257b..0eeabe3832 100644 --- a/landlab/utils/structured_grid.py +++ b/landlab/utils/structured_grid.py @@ -1523,7 +1523,7 @@ def _set_open_boundary_neighbors(neighbors, open_boundary_nodes, value): def _find_open_boundary_neighbors(neighbors, open_boundary_nodes): """Array of booleans that indicate if a neighbor is an open boundary.""" open_boundary_neighbors = neighbors[:, open_boundary_nodes] - is_open_boundary_neighbor = np.in1d(open_boundary_neighbors, open_boundary_nodes) + is_open_boundary_neighbor = np.isin(open_boundary_neighbors, open_boundary_nodes) is_open_boundary_neighbor.shape = (neighbors.shape[0], len(open_boundary_nodes)) return is_open_boundary_neighbor From 08345ae9382cedeea56bb256e75fa39a7077fd5f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 10:44:16 -0600 Subject: [PATCH 28/70] import netcdf_file --- tests/io/netcdf/test_write_netcdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/io/netcdf/test_write_netcdf.py b/tests/io/netcdf/test_write_netcdf.py index ae34a4a421..124653427a 100644 --- a/tests/io/netcdf/test_write_netcdf.py +++ b/tests/io/netcdf/test_write_netcdf.py @@ -79,7 +79,7 @@ def test_netcdf_write_as_netcdf3_64bit(tmpdir): def test_netcdf_write_as_netcdf3_classic(tmpdir): """Test write_netcdf with output format classic netcdf3.""" - from scipy.io import netcdf + from scipy.io import netcdf_file field = RasterModelGrid((4, 3)) field.add_field("topographic__elevation", np.arange(12.0), at="node") From 3fa09b71bdfab238c3380e44ddc4e9032ba9a6e4 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 10:45:35 -0600 Subject: [PATCH 29/70] imoprt lablel from scipy.ndimage --- landlab/components/species_evolution/zone_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/landlab/components/species_evolution/zone_controller.py b/landlab/components/species_evolution/zone_controller.py index 95d5ff8c27..717813812b 100644 --- a/landlab/components/species_evolution/zone_controller.py +++ b/landlab/components/species_evolution/zone_controller.py @@ -1,7 +1,7 @@ #!/usr/bin/env python """ZoneController of SpeciesEvolver.""" import numpy as np -from scipy.ndimage.measurements import label +from scipy.ndimage import label from .record import Record from .zone import Zone From 7a3a767448901ec1aa3e89e520f86d62cbfd36ae Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 10:50:24 -0600 Subject: [PATCH 30/70] remove unnecessary call to np.where fixes deprecation warning --- landlab/layers/materiallayers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/landlab/layers/materiallayers.py b/landlab/layers/materiallayers.py index 8a445bd10a..4df42a0924 100644 --- a/landlab/layers/materiallayers.py +++ b/landlab/layers/materiallayers.py @@ -282,8 +282,9 @@ def is_compatible(self, dz, **kwds): bool ``True`` if the new layer is compatible, otherwise ``False``. """ - where_deposition = np.where(dz > 0.0)[0] - if len(where_deposition) > 0: + where_deposition = dz > 0.0 + + if np.any(where_deposition): for name in kwds: try: is_compatible = self[name][self.surface_index] == kwds[name] From fb9915c028a46eff3d23a8ea7ec2c323c88e50a1 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 10:54:35 -0600 Subject: [PATCH 31/70] extract array element when assigning scalar fixes deprecation warning --- landlab/components/profiler/profiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/landlab/components/profiler/profiler.py b/landlab/components/profiler/profiler.py index 82dfbb000a..b7481ff471 100644 --- a/landlab/components/profiler/profiler.py +++ b/landlab/components/profiler/profiler.py @@ -216,7 +216,7 @@ def _create_profile_structure(self): pt = self._project_point_onto_line(sample_xy, start_xy, end_xy) d = grid.calc_distances_of_nodes_to_point(pt, node_subset=start_node) - sample_distances[i_sample] = d + sample_distances[i_sample] = d[0] # Store the segment data. From 00541a82890e3ce2718b70341b8911e23073f8a7 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 11:54:37 -0600 Subject: [PATCH 32/70] fix doctest for new np.ptp behavior with masked arrays --- landlab/utils/jaggedarray_ma.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/landlab/utils/jaggedarray_ma.py b/landlab/utils/jaggedarray_ma.py index 8c546f58d9..52d3078c72 100644 --- a/landlab/utils/jaggedarray_ma.py +++ b/landlab/utils/jaggedarray_ma.py @@ -39,7 +39,19 @@ array([ 6., 8., 9., 17., 22., 22., 11., 19., 16.]) >>> values_at_node.foreach_row(np.min) array([0., 0., 1., 2., 2., 3., 4., 4., 5.]) ->>> values_at_node.foreach_row(np.ptp) +>>> values_at_node.foreach_row(np.max) +array([ 6., 7., 8., 9., 10., 11., 7., 10., 11.]) + +Note: `np.ptp` doesn't work on masked arrays but since `max` and `min` seem +to, you can create a new `ptp` that returns the expected values. + +>>> ptp = lambda x, axis=None : np.max(x, axis=axis) - np.min(x, axis=axis) +>>> values_at_node.foreach_row(ptp) +array([6., 7., 7., 7., 8., 8., 3., 6., 6.]) + +Or access the underlying masked array directly, + +>>> values_at_node.masked_array.ptp(axis=1).data array([6., 7., 7., 7., 8., 8., 3., 6., 6.]) """ From a1e20eeb95470722883d20073246ddd807a58b61 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 5 Jul 2024 18:03:50 +0000 Subject: [PATCH 33/70] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- landlab/utils/jaggedarray_ma.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/landlab/utils/jaggedarray_ma.py b/landlab/utils/jaggedarray_ma.py index 52d3078c72..dcef4a643a 100644 --- a/landlab/utils/jaggedarray_ma.py +++ b/landlab/utils/jaggedarray_ma.py @@ -45,7 +45,7 @@ Note: `np.ptp` doesn't work on masked arrays but since `max` and `min` seem to, you can create a new `ptp` that returns the expected values. ->>> ptp = lambda x, axis=None : np.max(x, axis=axis) - np.min(x, axis=axis) +>>> ptp = lambda x, axis=None: np.max(x, axis=axis) - np.min(x, axis=axis) >>> values_at_node.foreach_row(ptp) array([6., 7., 7., 7., 8., 8., 3., 6., 6.]) From f19e1a84034a58cad23c7785153b9aa3051a974b Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 16:27:08 -0600 Subject: [PATCH 34/70] adjust doctest for small changes in floating point result --- landlab/components/stream_power/fastscape_stream_power.py | 8 ++++---- landlab/components/stream_power/stream_power.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/landlab/components/stream_power/fastscape_stream_power.py b/landlab/components/stream_power/fastscape_stream_power.py index 8654428ce5..dfd9a62e6e 100644 --- a/landlab/components/stream_power/fastscape_stream_power.py +++ b/landlab/components/stream_power/fastscape_stream_power.py @@ -96,8 +96,8 @@ class FastscapeEroder(Component): >>> fr.run_one_step() >>> sp.run_one_step(dt=10.0) >>> z.reshape(grid.shape)[1, :] - array([ 0. , 1. , 4. , 8.52493781, - 13.29039716, 18.44367965, 36. ]) + array([ 0. , 1. , 4. , 8.52493772, 13.29039699, + 18.44367949, 36. ]) >>> grid = RasterModelGrid((3, 7), xy_spacing=1.0) >>> z = np.array(grid.node_x**2.0) @@ -123,8 +123,8 @@ class FastscapeEroder(Component): >>> fr.run_one_step() >>> sp.run_one_step(1.0) >>> z.reshape(grid.shape)[1, :] - array([ 0. , 0.0647484 , 0.58634455, 2.67253503, - 8.49212152, 20.92606987, 36. ]) + array([ 0. , 0.06474841, 0.58634459, 2.6725351 , 8.4921219 , + 20.92606983, 36. ]) References ---------- diff --git a/landlab/components/stream_power/stream_power.py b/landlab/components/stream_power/stream_power.py index e994e8d6ab..e83fd19251 100644 --- a/landlab/components/stream_power/stream_power.py +++ b/landlab/components/stream_power/stream_power.py @@ -75,8 +75,8 @@ class StreamPowerEroder(Component): >>> fr2.run_one_step() >>> sp2.run_one_step(dt=10.0) >>> z.reshape((3, 7))[1, :] - array([ 0. , 1. , 4. , 8.52493781, - 13.29039716, 18.44367965, 36. ]) + array([ 0. , 1. , 4. , 8.52493772, 13.29039699, + 18.44367949, 36. ]) >>> mg3 = RasterModelGrid((5, 5), xy_spacing=2.0) >>> z = mg.node_x / 100.0 From 57f77baee68abfd5534d316b85583954a0ea5fd9 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 16:27:57 -0600 Subject: [PATCH 35/70] adjust unit test for new numpy type promotion rules --- tests/grid/test_create_network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/grid/test_create_network.py b/tests/grid/test_create_network.py index 460f65a4e6..a777fc7891 100644 --- a/tests/grid/test_create_network.py +++ b/tests/grid/test_create_network.py @@ -34,7 +34,7 @@ drainage_area=hynp.arrays( dtype=hynp.floating_dtypes(), shape=hynp.array_shapes(), - elements=floats(min_value=0, width=16), + elements=floats(min_value=0, max_value=1000, width=16), ) ) def test_calc_spacing_always_positive(drainage_area): @@ -45,7 +45,7 @@ def test_calc_spacing_always_positive(drainage_area): drainage_area=hynp.arrays( dtype=hynp.floating_dtypes(), shape=hynp.array_shapes(), - elements=floats(min_value=0, width=16), + elements=floats(min_value=0, width=16, allow_infinity=False), ) ) def test_calc_spacing_unit_keywords(drainage_area): From f4fb4c50b69a9fc090c450e65aa4e744454d4623 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 16:28:38 -0600 Subject: [PATCH 36/70] adjust doctest for new DataArray string representation --- landlab/grid/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/landlab/grid/base.py b/landlab/grid/base.py index af7c3d7915..50e65c5aec 100644 --- a/landlab/grid/base.py +++ b/landlab/grid/base.py @@ -500,8 +500,8 @@ def as_dataarray(self, name, at=None, time=None): >>> _ = grid.add_full("elevation", 3.0, at="node") >>> grid.as_dataarray("at_node:elevation") - - array([3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.]) + Size: 96B + array([3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.]) Dimensions without coordinates: node >>> all( From 171d721b5fa452cd42b4c547821e073e45546104 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Fri, 5 Jul 2024 16:29:13 -0600 Subject: [PATCH 37/70] check for tracked/untracked fields before checking sizes --- landlab/layers/materiallayers.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/landlab/layers/materiallayers.py b/landlab/layers/materiallayers.py index 4df42a0924..06c9bda64d 100644 --- a/landlab/layers/materiallayers.py +++ b/landlab/layers/materiallayers.py @@ -285,13 +285,15 @@ def is_compatible(self, dz, **kwds): where_deposition = dz > 0.0 if np.any(where_deposition): + if not_tracked := set(kwds) - set(self): + raise ValueError( + "Error adding layer." + f" {', '.join(sorted(repr(t) for t in not_tracked))}" + " is not being tracked. Currently tracking:" + f" {', '.join(sorted(repr(t) for t in set(self)))}" + ) for name in kwds: - try: - is_compatible = self[name][self.surface_index] == kwds[name] - except KeyError as exc: - raise ValueError( - f"{name!r} is not being tracked. Error in adding." - ) from exc + is_compatible = self[name][self.surface_index] == kwds[name] if not np.all(is_compatible[where_deposition]): return False From dde61882a5227db25b735bfaf3ba8b82bbc25b94 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sat, 6 Jul 2024 09:53:31 -0600 Subject: [PATCH 38/70] try to ensure common types; some windows debugging --- .../flow_director/flow_direction_DN.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/landlab/components/flow_director/flow_direction_DN.py b/landlab/components/flow_director/flow_direction_DN.py index ba23abeedc..878d9ea33a 100644 --- a/landlab/components/flow_director/flow_direction_DN.py +++ b/landlab/components/flow_director/flow_direction_DN.py @@ -91,8 +91,8 @@ def flow_directions( # Setup num_nodes = len(elev) steepest_slope = np.zeros(num_nodes) - receiver = np.arange(num_nodes) - receiver_link = BAD_INDEX_VALUE + np.zeros(num_nodes, dtype=int) + receiver = np.arange(num_nodes, dtype=active_links.dtype) + receiver_link = np.full(num_nodes, BAD_INDEX_VALUE, dtype=active_links.dtype) # For each link, find the higher of the two nodes. The higher is the # potential donor, and the lower is the potential receiver. If the slope @@ -104,6 +104,19 @@ def flow_directions( # THIS REMAINS A PROBLEM AS OF DEJH'S EFFORTS, MID MARCH 14. # overridden as part of fastscape_stream_power + types = { + tail_node.dtype, + head_node.dtype, + active_links.dtype, + receiver.dtype, + receiver_link.dtype, + } + if len(types) > 1: + print(f"incompatible types: {', '.join(types)}") + types = {elev.dtype, link_slope.dtype, steepest_slope.dtype} + if len(types) > 1: + print(f"incompatible types: {', '.join(types)}") + adjust_flow_receivers( tail_node, head_node, From 7eda566b1f05c66c103872bf8974adb9b4a2f0d9 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sat, 6 Jul 2024 10:20:04 -0600 Subject: [PATCH 39/70] use id_t for adjust_flow_receivers --- landlab/components/flow_director/cfuncs.pyx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/landlab/components/flow_director/cfuncs.pyx b/landlab/components/flow_director/cfuncs.pyx index a7d85c9fb5..621c4129a8 100644 --- a/landlab/components/flow_director/cfuncs.pyx +++ b/landlab/components/flow_director/cfuncs.pyx @@ -1,15 +1,20 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + + @cython.boundscheck(False) def adjust_flow_receivers( - const cython.integral [:] src_nodes, - const cython.integral [:] dst_nodes, + const id_t [:] src_nodes, + const id_t [:] dst_nodes, const cython.floating [:] z, const cython.floating [:] link_slope, - const cython.integral [:] active_links, - cython.integral [:] receiver, - cython.integral [:] receiver_link, + const id_t [:] active_links, + id_t [:] receiver, + id_t [:] receiver_link, cython.floating [:] steepest_slope, ): """Adjust flow receivers based on link slopes and steepest gradients. From 6d393cc12d3f675e4dc0743ec937b199857bd114 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 6 Jul 2024 16:22:12 +0000 Subject: [PATCH 40/70] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- landlab/components/flow_director/cfuncs.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/landlab/components/flow_director/cfuncs.pyx b/landlab/components/flow_director/cfuncs.pyx index 621c4129a8..776be880ac 100644 --- a/landlab/components/flow_director/cfuncs.pyx +++ b/landlab/components/flow_director/cfuncs.pyx @@ -1,6 +1,5 @@ cimport cython - ctypedef fused id_t: cython.integral long long From 671bb66f71b283c87e16f819e0e11e0417ebeebd Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sat, 6 Jul 2024 11:09:41 -0600 Subject: [PATCH 41/70] use id_t for flow accumulation cython --- landlab/components/flow_accum/cfuncs.pyx | 34 +++++++++++-------- .../components/flow_accum/flow_accum_bw.py | 4 +-- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/landlab/components/flow_accum/cfuncs.pyx b/landlab/components/flow_accum/cfuncs.pyx index dd3ec2cee8..466f2b128a 100644 --- a/landlab/components/flow_accum/cfuncs.pyx +++ b/landlab/components/flow_accum/cfuncs.pyx @@ -1,13 +1,17 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) cpdef _add_to_stack( long l, long j, - cython.integral [:] s, - cython.integral [:] delta, - cython.integral [:] donors, + id_t [:] s, + id_t [:] delta, + id_t [:] donors, ): """ Adds node l to the stack and increments the current index (j). @@ -31,8 +35,8 @@ cpdef _add_to_stack( cpdef _accumulate_to_n( long size, long q, - cython.integral [:] s, - cython.integral [:, :] r, + id_t [:] s, + id_t [:, :] r, cython.floating [:, :] p, cython.floating [:] drainage_area, cython.floating [:] discharge, @@ -62,8 +66,8 @@ cpdef _accumulate_to_n( @cython.boundscheck(False) cpdef _accumulate_bw( long size, - cython.integral [:] s, - cython.integral [:] r, + id_t [:] s, + id_t [:] r, cython.floating [:] drainage_area, cython.floating [:] discharge, ): @@ -89,10 +93,10 @@ cpdef _accumulate_bw( @cython.boundscheck(False) cpdef _make_donors( long size, - cython.integral [:] w, - cython.integral [:] D, - cython.integral [:] delta, - cython.integral [:] r, + id_t [:] w, + id_t [:] D, + id_t [:] delta, + id_t [:] r, ): """Determines number of donors""" cdef int ri, i @@ -106,10 +110,10 @@ cpdef _make_donors( cpdef _make_donors_to_n( long size, long q, - cython.integral [:] w, - cython.integral [:] D, - cython.integral [:] delta, - cython.integral [:, :] r, + id_t [:] w, + id_t [:] D, + id_t [:] delta, + id_t [:, :] r, cython.floating [:, :] p, ): """Determines number of donors for route to n""" diff --git a/landlab/components/flow_accum/flow_accum_bw.py b/landlab/components/flow_accum/flow_accum_bw.py index 7e8e3de54a..3bd0285bdc 100644 --- a/landlab/components/flow_accum/flow_accum_bw.py +++ b/landlab/components/flow_accum/flow_accum_bw.py @@ -163,8 +163,8 @@ def _make_array_of_donors(r, delta): array([0, 2, 1, 4, 5, 7, 6, 3, 8, 9]) """ np = len(r) - w = numpy.zeros(np, dtype=int) - D = numpy.zeros(np, dtype=int) + w = numpy.zeros(np, dtype=r.dtype) + D = numpy.zeros(np, dtype=r.dtype) _make_donors(np, w, D, delta, r) From 46e8a83c8999a3e4393d47f0ee061a955679ade5 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 13 Aug 2024 15:45:01 -0400 Subject: [PATCH 42/70] use id_t for calculate_qs_in --- landlab/components/space/ext/calc_qs.pyx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/landlab/components/space/ext/calc_qs.pyx b/landlab/components/space/ext/calc_qs.pyx index 6c71ab4a8d..595d8f8eda 100644 --- a/landlab/components/space/ext/calc_qs.pyx +++ b/landlab/components/space/ext/calc_qs.pyx @@ -1,13 +1,18 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + + cdef extern from "math.h": double exp(double x) nogil def calculate_qs_in( - cython.integral [:] stack_flip_ud, - cython.integral [:] flow_receivers, + const id_t [:] stack_flip_ud, + const id_t [:] flow_receivers, const cython.floating [:] cell_area_at_node, cython.floating [:] q, cython.floating [:] qs, From cb952e98c9c209f2ec3529b4ca355ed4f17063cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 19:47:31 +0000 Subject: [PATCH 43/70] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- landlab/components/space/ext/calc_qs.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/landlab/components/space/ext/calc_qs.pyx b/landlab/components/space/ext/calc_qs.pyx index 595d8f8eda..fb8a56a3de 100644 --- a/landlab/components/space/ext/calc_qs.pyx +++ b/landlab/components/space/ext/calc_qs.pyx @@ -1,6 +1,5 @@ cimport cython - ctypedef fused id_t: cython.integral long long From f2695f94db3c1904a808fd76f2018414abe40ed5 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 13 Aug 2024 17:19:35 -0400 Subject: [PATCH 44/70] print some type information for debugging --- landlab/components/space/space.py | 37 +++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/landlab/components/space/space.py b/landlab/components/space/space.py index bbc51f2e37..58e9c29224 100644 --- a/landlab/components/space/space.py +++ b/landlab/components/space/space.py @@ -460,18 +460,31 @@ def _calc_qs_in_and_depo_rate(self): # iterate top to bottom through the stack, calculate qs # cythonized version of calculating qs_in - calculate_qs_in( - np.flipud(self._stack), - self._flow_receivers, - self._cell_area_at_node, - self._q, - self._qs, - self.sediment_influx, - self._Es, - self._Er, - self._v_s, - self._F_f, - ) + try: + calculate_qs_in( + np.flipud(self._stack), + self._flow_receivers, + self._cell_area_at_node, + self._q, + self._qs, + self.sediment_influx, + self._Es, + self._Er, + self._v_s, + self._F_f, + ) + except TypeError as error: + print(np.flipud(self._stack).dtype) + print(self._flow_receivers.dtype) + print(self._cell_area_at_node.dtype) + print(self._q.dtype) + print(self._qs.dtype) + print(self.sediment_influx.dtype) + print(self._Es.dtype) + print(self._Er.dtype) + print(type(self._v_s)) + print(type(self._F_f)) + raise error self._depo_rate[self._q > 0] = self._qs[self._q > 0] * ( self._v_s / self._q[self._q > 0] From c7ec57da92102c5a93625932c476ce793a769c87 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 13 Aug 2024 18:19:27 -0400 Subject: [PATCH 45/70] more type debugging --- .../space/space_large_scale_eroder.py | 74 +++++++++++++------ 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/landlab/components/space/space_large_scale_eroder.py b/landlab/components/space/space_large_scale_eroder.py index ccf34d260a..bbe10bc43e 100644 --- a/landlab/components/space/space_large_scale_eroder.py +++ b/landlab/components/space/space_large_scale_eroder.py @@ -547,29 +547,57 @@ def run_one_step_basic(self, dt=10): K_sed_vector = np.broadcast_to(self._K_sed, self._q.shape) - vol_SSY_riv = _sequential_ero_depo( - stack_flip_ud_sel, - r, - area, - self._q, - self._qs, - self.sediment_influx, - self._Es, - self._Er, - self._Q_to_the_m, - slope, - H, - br, - self._sed_erosion_term, - self._br_erosion_term, - K_sed_vector, - self._v_s, - self._phi, - self._F_f, - self._H_star, - dt, - self._thickness_lim, - ) + try: + vol_SSY_riv = _sequential_ero_depo( + stack_flip_ud_sel, + r, + area, + self._q, + self._qs, + self.sediment_influx, + self._Es, + self._Er, + self._Q_to_the_m, + slope, + H, + br, + self._sed_erosion_term, + self._br_erosion_term, + K_sed_vector, + self._v_s, + self._phi, + self._F_f, + self._H_star, + dt, + self._thickness_lim, + ) + except TypeError: + raise RuntimeError( + ( + stack_flip_ud_sel.dtype, + r.dtype, + area.dtype, + self._q.dtype, + self._qs.dtype, + self.sediment_influx.dtype, + self._Es.dtype, + self._Er.dtype, + self._Q_to_the_m.dtype, + slope.dtype, + H.dtype, + br.dtype, + self._sed_erosion_term.dtype, + self._br_erosion_term.dtype, + K_sed_vector.dtype, + self._v_s.dtype, + self._phi.dtype, + self._F_f.dtype, + type(self._H_star), + type(dt), + type(self._thickness_lim), + ) + ) from None + V_leaving_riv = np.sum(self.sediment_influx[self.grid.boundary_nodes]) * dt # Update topography From 6b4021fbc8dd8c906180b6a10728e3914a3d4891 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 22:21:28 +0000 Subject: [PATCH 46/70] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- landlab/components/space/space_large_scale_eroder.py | 1 - 1 file changed, 1 deletion(-) diff --git a/landlab/components/space/space_large_scale_eroder.py b/landlab/components/space/space_large_scale_eroder.py index bbe10bc43e..ad6f77717a 100644 --- a/landlab/components/space/space_large_scale_eroder.py +++ b/landlab/components/space/space_large_scale_eroder.py @@ -598,7 +598,6 @@ def run_one_step_basic(self, dt=10): ) ) from None - V_leaving_riv = np.sum(self.sediment_influx[self.grid.boundary_nodes]) * dt # Update topography cores = self._grid.core_nodes From 43e4f4810f7e0c44899dd921eddbff41438fbc00 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 13 Aug 2024 19:01:24 -0400 Subject: [PATCH 47/70] more debugging of dtypes --- .../priority_flood_flow_router/cfuncs.pyx | 18 ++++--- .../priority_flood_flow_router.py | 53 +++++++++++++------ .../space/ext/calc_sequential_ero_depo.pyx | 8 ++- .../space/space_large_scale_eroder.py | 4 +- 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/landlab/components/priority_flood_flow_router/cfuncs.pyx b/landlab/components/priority_flood_flow_router/cfuncs.pyx index 1b32f920bb..20340c97c6 100644 --- a/landlab/components/priority_flood_flow_router/cfuncs.pyx +++ b/landlab/components/priority_flood_flow_router/cfuncs.pyx @@ -3,22 +3,26 @@ import numpy as np cimport numpy as np +ctypedef fused id_t: + cython.integral + long long + cpdef _D8_flowDir( - cython.integral [:] receivers, + id_t [:] receivers, cython.floating [:] distance_receiver, cython.floating [:] steepest_slope, cython.floating [:] el_dep_free, cython.floating [:] el_ori, cython.floating [:] dist, - cython.integral [:] ngb, - cython.integral [:] activeCores, - cython.integral [:] activeCells, - cython.floating [:] el_d, + id_t [:] ngb, + id_t [:] activeCores, + id_t [:] activeCells, + id_t [:] el_d, long c, double dx, - cython.integral [:, :] adj_link, - cython.integral [:] rec_link, + id_t [:, :] adj_link, + id_t [:] rec_link, ): """ Calcualte D8 flow dirs diff --git a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py index 02be8d4e63..c8c733927f 100644 --- a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py +++ b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py @@ -737,22 +737,43 @@ def _FlowAcc_D8(self, hill_flow=False): adj_link = np.array(self._grid.d8s_at_node, dtype=int) recvr_link = np.zeros((receivers.shape), dtype=int) - 1 - _D8_flowDir( - receivers, - distance_receiver, - steepest_slope, - np.array(el_dep_free), - el_ori, - dist, - ngb, - activeCores, - activeCells, - el_d, - c, - dx, - adj_link, - recvr_link, - ) + try: + _D8_flowDir( + receivers, + distance_receiver, + steepest_slope, + np.array(el_dep_free), + el_ori, + dist, + ngb, + activeCores, + activeCells, + el_d, + c, + dx, + adj_link, + recvr_link, + ) + raise TypeError() + except TypeError: + raise RuntimeError( + ( + receivers.dtype, + distance_receiver.dtype, + steepest_slope.dtype, + np.array(el_dep_free.dtype).dtype, + el_ori.dtype, + dist.dtype, + ngb.dtype, + activeCores.dtype, + activeCells.dtype, + el_d.dtype, + type(c), + type(dx), + adj_link.dtype, + recvr_link.dtype, + ) + ) from None # Calcualte flow acc do_FA = False diff --git a/landlab/components/space/ext/calc_sequential_ero_depo.pyx b/landlab/components/space/ext/calc_sequential_ero_depo.pyx index 4cae0886e7..a7567330ee 100644 --- a/landlab/components/space/ext/calc_sequential_ero_depo.pyx +++ b/landlab/components/space/ext/calc_sequential_ero_depo.pyx @@ -3,10 +3,14 @@ from libc.math cimport exp from libc.math cimport isinf from libc.math cimport log +ctypedef fused id_t: + cython.integral + long long + def _sequential_ero_depo( - const cython.integral [:] stack_flip_ud_sel, - const cython.integral [:] flow_receivers, + const id_t [:] stack_flip_ud_sel, + const id_t [:] flow_receivers, const cython.floating [:] cell_area, const cython.floating [:] q, cython.floating [:] qs, diff --git a/landlab/components/space/space_large_scale_eroder.py b/landlab/components/space/space_large_scale_eroder.py index ad6f77717a..6c8dfa53a1 100644 --- a/landlab/components/space/space_large_scale_eroder.py +++ b/landlab/components/space/space_large_scale_eroder.py @@ -261,7 +261,7 @@ def __init__( sp_crit_br=0.0, discharge_field="surface_water__discharge", erode_flooded_nodes=False, - thickness_lim=100, + thickness_lim=100.0, ): """Initialize the SpaceLargeScaleEroder model. @@ -340,7 +340,7 @@ def __init__( ) # specific inits - self._thickness_lim = thickness_lim + self._thickness_lim = float(thickness_lim) self._H_star = H_star self._sed_erosion_term = np.zeros(grid.number_of_nodes) From 731f5366fad12cb8ff624da1e65801e8d312dc42 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 13 Aug 2024 19:22:13 -0400 Subject: [PATCH 48/70] fix typos --- landlab/components/priority_flood_flow_router/cfuncs.pyx | 2 +- .../priority_flood_flow_router/priority_flood_flow_router.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/landlab/components/priority_flood_flow_router/cfuncs.pyx b/landlab/components/priority_flood_flow_router/cfuncs.pyx index 20340c97c6..b1d3ba2e7a 100644 --- a/landlab/components/priority_flood_flow_router/cfuncs.pyx +++ b/landlab/components/priority_flood_flow_router/cfuncs.pyx @@ -18,7 +18,7 @@ cpdef _D8_flowDir( id_t [:] ngb, id_t [:] activeCores, id_t [:] activeCells, - id_t [:] el_d, + cython.floating [:] el_d, long c, double dx, id_t [:, :] adj_link, diff --git a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py index c8c733927f..0bfcf6230f 100644 --- a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py +++ b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py @@ -754,7 +754,6 @@ def _FlowAcc_D8(self, hill_flow=False): adj_link, recvr_link, ) - raise TypeError() except TypeError: raise RuntimeError( ( From 7e9f6d97b076d42fdd51fa9c1311fdc284274c2c Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 14 Aug 2024 09:30:46 -0600 Subject: [PATCH 49/70] use id_t for int arrays --- landlab/components/depression_finder/cfuncs.pyx | 10 +++++++--- .../components/priority_flood_flow_router/cfuncs.pyx | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/landlab/components/depression_finder/cfuncs.pyx b/landlab/components/depression_finder/cfuncs.pyx index 7856cedda8..157d9e821d 100644 --- a/landlab/components/depression_finder/cfuncs.pyx +++ b/landlab/components/depression_finder/cfuncs.pyx @@ -2,13 +2,17 @@ cimport cython from landlab.core.messages import warning_message +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) cpdef find_lowest_node_on_lake_perimeter_c( - const cython.integral [:, :] node_nbrs, - cython.integral [:] flood_status, + const id_t [:, :] node_nbrs, + id_t [:] flood_status, cython.floating [:] elev, - cython.integral [:] nodes_this_depression, + id_t [:] nodes_this_depression, long pit_count, double BIG_ELEV, ): diff --git a/landlab/components/priority_flood_flow_router/cfuncs.pyx b/landlab/components/priority_flood_flow_router/cfuncs.pyx index b1d3ba2e7a..e8386a6d90 100644 --- a/landlab/components/priority_flood_flow_router/cfuncs.pyx +++ b/landlab/components/priority_flood_flow_router/cfuncs.pyx @@ -88,8 +88,8 @@ cpdef _D8_flowDir( cpdef _D8_FlowAcc( cython.floating [:] a, cython.floating [:] q, - cython.integral [:] stack_flip, - cython.integral [:] receivers, + id_t [:] stack_flip, + id_t [:] receivers, ): """ Accumulates drainage area and discharge, permitting transmission losses. From e892435673c11c933a9b60fa6b83032b0f8a2bfa Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 14 Aug 2024 09:31:25 -0600 Subject: [PATCH 50/70] more debugging of types --- .../depression_finder/lake_mapper.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/landlab/components/depression_finder/lake_mapper.py b/landlab/components/depression_finder/lake_mapper.py index f1e69aebce..0daf13724d 100644 --- a/landlab/components/depression_finder/lake_mapper.py +++ b/landlab/components/depression_finder/lake_mapper.py @@ -765,14 +765,28 @@ def find_depression_from_pit(self, pit_node, reroute_flow=True): pit_count = 1 while not found_outlet: - lowest_node_on_perimeter, pit_count = find_lowest_node_on_lake_perimeter_c( - self._node_nbrs, - self.flood_status, - self._elev, - nodes_this_depression, - pit_count, - self._BIG_ELEV, - ) + try: + lowest_node_on_perimeter, pit_count = ( + find_lowest_node_on_lake_perimeter_c( + self._node_nbrs, + self.flood_status, + self._elev, + nodes_this_depression, + pit_count, + self._BIG_ELEV, + ) + ) + except TypeError: + raise RuntimeError( + ( + self._node_nbrs.dtype, + self.flood_status.dtype, + self._elev.dtype, + nodes_this_depression.dtype, + type(pit_count), + type(self._BIG_ELEV), + ) + ) from None # note this can return the supplied node, if - somehow - the # surrounding nodes are all self._grid.BAD_INDEX # I BELIEVE THE IS_VALID_OUTLET FN SHOULD ASSIGN FLOW DIR From 6998fff148510dc47e2ee4a10436a1c16566be03 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 14 Aug 2024 10:08:23 -0600 Subject: [PATCH 51/70] add long long to integral data types --- landlab/components/stream_power/cfuncs.pyx | 16 ++++++++++------ landlab/components/threshold_eroder/cfuncs.pyx | 10 +++++++--- landlab/graph/object/ext/at_patch.pyx | 1 + landlab/graph/quantity/ext/of_element.pyx | 2 +- landlab/grid/ext/raster_divergence.pyx | 1 + landlab/grid/ext/raster_gradient.pyx | 1 + 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/landlab/components/stream_power/cfuncs.pyx b/landlab/components/stream_power/cfuncs.pyx index d929cad78d..34c3f9f414 100644 --- a/landlab/components/stream_power/cfuncs.pyx +++ b/landlab/components/stream_power/cfuncs.pyx @@ -8,10 +8,14 @@ from scipy.optimize import newton # method for using the brentq method in cython. from scipy.optimize._zeros import _brentq as brentq +ctypedef fused id_t: + cython.integral + long long + def brent_method_erode_variable_threshold( - const cython.integral [:] src_nodes, - const cython.integral [:] dst_nodes, + const id_t [:] src_nodes, + const id_t [:] dst_nodes, const cython.floating [:] threshsxdt, const cython.floating [:] alpha, const double n, @@ -142,8 +146,8 @@ def brent_method_erode_variable_threshold( def brent_method_erode_fixed_threshold( - const cython.integral [:] src_nodes, - const cython.integral [:] dst_nodes, + const id_t [:] src_nodes, + const id_t [:] dst_nodes, const double threshsxdt, const cython.floating [:] alpha, const double n, @@ -367,8 +371,8 @@ def erode_fn( def smooth_stream_power_eroder_solver( - const cython.integral [:] src_nodes, - const cython.integral [:] dst_nodes, + const id_t [:] src_nodes, + const id_t [:] dst_nodes, cython.floating [:] z, const cython.floating [:] alpha, const cython.floating [:] gamma, diff --git a/landlab/components/threshold_eroder/cfuncs.pyx b/landlab/components/threshold_eroder/cfuncs.pyx index 1a8d564cda..7282899c4a 100644 --- a/landlab/components/threshold_eroder/cfuncs.pyx +++ b/landlab/components/threshold_eroder/cfuncs.pyx @@ -1,10 +1,14 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + cpdef _thresholder( - const cython.integral [:] stack, - const cython.integral [:] link_to_rcvr, - const cython.integral [:] receivers, + const id_t [:] stack, + const id_t [:] link_to_rcvr, + const id_t [:] receivers, const cython.floating [:] linkLengths, cython.floating [:] el, const double slope_thres, diff --git a/landlab/graph/object/ext/at_patch.pyx b/landlab/graph/object/ext/at_patch.pyx index 8df23f27b8..becbc5c989 100644 --- a/landlab/graph/object/ext/at_patch.pyx +++ b/landlab/graph/object/ext/at_patch.pyx @@ -5,6 +5,7 @@ from libc.stdint cimport int8_t ctypedef fused float_or_int: cython.floating cython.integral + long long int8_t ctypedef fused id_t: diff --git a/landlab/graph/quantity/ext/of_element.pyx b/landlab/graph/quantity/ext/of_element.pyx index 672bafa1df..2c34eb03cf 100644 --- a/landlab/graph/quantity/ext/of_element.pyx +++ b/landlab/graph/quantity/ext/of_element.pyx @@ -166,7 +166,7 @@ cpdef max_of_children_at_parent( @cython.wraparound(False) cpdef count_of_children_at_parent( const id_t [:, :] children_at_parent, - cython.integral [:] out, + id_t [:] out, ): """Count the number of children for each parent. diff --git a/landlab/grid/ext/raster_divergence.pyx b/landlab/grid/ext/raster_divergence.pyx index 2e0596d369..c7fa71a644 100644 --- a/landlab/grid/ext/raster_divergence.pyx +++ b/landlab/grid/ext/raster_divergence.pyx @@ -3,6 +3,7 @@ from cython.parallel cimport prange ctypedef fused float_or_int: cython.integral + long long cython.floating diff --git a/landlab/grid/ext/raster_gradient.pyx b/landlab/grid/ext/raster_gradient.pyx index 4b157a3eb7..4d2816c10a 100644 --- a/landlab/grid/ext/raster_gradient.pyx +++ b/landlab/grid/ext/raster_gradient.pyx @@ -3,6 +3,7 @@ from cython.parallel cimport prange ctypedef fused float_or_int: cython.integral + long long cython.floating From 1b5a87ce1dda7ce9ebcfc9c476917a2f8603f2fc Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 14 Aug 2024 10:47:01 -0600 Subject: [PATCH 52/70] use id_t for calculate_qs_in; more debugging --- .../components/erosion_deposition/cfuncs.pyx | 8 +++- .../erosion_deposition/erosion_deposition.py | 37 +++++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/landlab/components/erosion_deposition/cfuncs.pyx b/landlab/components/erosion_deposition/cfuncs.pyx index ed106b4e8d..e9ba7dc429 100644 --- a/landlab/components/erosion_deposition/cfuncs.pyx +++ b/landlab/components/erosion_deposition/cfuncs.pyx @@ -1,13 +1,17 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + cdef extern from "math.h": double exp(double x) nogil def calculate_qs_in( - cython.integral [:] stack_flip_ud, - cython.integral [:] flow_receivers, + id_t [:] stack_flip_ud, + id_t [:] flow_receivers, const cython.floating [:] cell_area_at_node, cython.floating [:] q, cython.floating [:] qs, diff --git a/landlab/components/erosion_deposition/erosion_deposition.py b/landlab/components/erosion_deposition/erosion_deposition.py index 3127755cbf..a6f2047802 100644 --- a/landlab/components/erosion_deposition/erosion_deposition.py +++ b/landlab/components/erosion_deposition/erosion_deposition.py @@ -386,17 +386,32 @@ def _calc_qs_in_and_depo_rate(self): # iterate top to bottom through the stack, calculate qs # cythonized version of calculating qs_in - calculate_qs_in( - np.flipud(self._stack), - self._flow_receivers, - self._cell_area_at_node, - self._q, - self._qs, - self.sediment_influx, - self._erosion_term, - self._v_s, - self._F_f, - ) + try: + calculate_qs_in( + np.flipud(self._stack), + self._flow_receivers, + self._cell_area_at_node, + self._q, + self._qs, + self.sediment_influx, + self._erosion_term, + self._v_s, + self._F_f, + ) + except TypeError: + raise RuntimeError( + ( + np.flipud(self._stack).dtype, + self._flow_receivers.dtype, + self._cell_area_at_node.dtype, + self._q.dtype, + self._qs.dtype, + self.sediment_influx.dtype, + self._erosion_term.dtype, + type(self._v_s), + type(self._F_f), + ) + ) from None self._depo_rate[self._q > 0] = self._qs[self._q > 0] * ( self._v_s / self._q[self._q > 0] From 88b1efa0bebadaa9a67f9cdc63ebc9f0b45a76d4 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 14 Aug 2024 11:40:19 -0600 Subject: [PATCH 53/70] use id_t in all cython files --- landlab/ca/cfuncs.pyx | 202 +++++++++--------- .../components/bedrock_landslider/cfuncs.pyx | 8 +- .../components/drainage_density/cfuncs.pyx | 10 +- .../overland_flow/_neighbors_at_link.pyx | 8 +- landlab/graph/matrix/ext/matrix.pyx | 8 +- 5 files changed, 128 insertions(+), 108 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index d902eae24c..7949632898 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -18,6 +18,10 @@ from _heapq import heappush from landlab.grid.nodestatus import NodeStatus +ctypedef fused id_t: + cython.integral + long long + cdef double _NEVER = 1.0e50 @@ -136,9 +140,9 @@ cdef class Event: @cython.wraparound(False) cdef int current_link_state( const long link_id, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, const long num_node_states, const long num_node_states_sq, @@ -190,17 +194,17 @@ cdef int current_link_state( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions( - const cython.integral [:] active_links, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] active_links, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, int8_t [:] bnd_lnk, - cython.integral [:] link_state, - cython.integral [:] n_xn, + id_t [:] link_state, + id_t [:] n_xn, event_queue, cython.floating [:] next_update, - cython.integral [:, :] xn_to, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, long num_node_states, long num_node_states_sq, @@ -261,18 +265,18 @@ cpdef update_link_states_and_transitions( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions_new( - const cython.integral [:] active_links, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] active_links, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, int8_t [:] bnd_lnk, - cython.integral [:] link_state, - cython.integral [:] n_trn, + id_t [:] link_state, + id_t [:] n_trn, PriorityQueue priority_queue, cython.floating [:] next_update, - cython.integral [:] next_trn_id, - cython.integral [:, :] trn_id, + id_t [:] next_trn_id, + id_t [:, :] trn_id, cython.floating [:] trn_rate, long num_node_states, long num_node_states_sq, @@ -331,7 +335,7 @@ cpdef update_link_states_and_transitions_new( @cython.wraparound(False) @cython.cdivision(True) cpdef update_node_states( - cython.integral [:] node_state, + id_t [:] node_state, const uint8_t [:] status_at_node, long tail_node, long head_node, @@ -358,8 +362,8 @@ cpdef get_next_event( long link, long current_state, double current_time, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, xn_prop_update_fn, @@ -435,8 +439,8 @@ cpdef get_next_event_new( long link, long current_state, double current_time, - cython.integral [:] n_trn, - cython.integral [:, :] trn_id, + id_t [:] n_trn, + id_t [:, :] trn_id, cython.floating [:] trn_rate, ): """Get the next event for a link. @@ -494,13 +498,13 @@ cpdef get_next_event_new( cpdef push_transitions_to_event_queue( long number_of_active_links, - const cython.integral [:] active_links, - cython.integral [:] n_trn, - cython.integral [:] link_state, - cython.integral [:, :] trn_id, + const id_t [:] active_links, + id_t [:] n_trn, + id_t [:] link_state, + id_t [:, :] trn_id, cython.floating [:] trn_rate, cython.floating [:] next_update, - cython.integral [:] next_trn_id, + id_t [:] next_trn_id, PriorityQueue priority_queue, ): """ @@ -531,17 +535,17 @@ cdef void update_link_state( long new_link_state, double current_time, int8_t [:] bnd_lnk, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, long num_node_states, long num_node_states_sq, - cython.integral [:] link_state, - cython.integral [:] n_xn, + id_t [:] link_state, + id_t [:] n_xn, event_queue, cython.floating [:] next_update, - cython.integral [:, :] xn_to, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, np.ndarray[object, ndim=2] xn_prop_update_fn, @@ -599,18 +603,18 @@ cdef void update_link_state_new( long new_link_state, double current_time, int8_t [:] bnd_lnk, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, long num_node_states, long num_node_states_sq, - cython.integral [:] link_state, - cython.integral [:] n_trn, + id_t [:] link_state, + id_t [:] n_trn, PriorityQueue priority_queue, cython.floating [:] next_update, - cython.integral [:] next_trn_id, - cython.integral [:, :] trn_id, + id_t [:] next_trn_id, + id_t [:, :] trn_id, cython.floating [:] trn_rate, ): """ @@ -664,18 +668,18 @@ cdef void update_link_state_new( cdef void do_transition( Event event, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] propid, + id_t [:] propid, object prop_data, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, @@ -879,24 +883,24 @@ cpdef void do_transition_new( double event_time, PriorityQueue priority_queue, cython.floating [:] next_update, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] next_trn_id, - cython.integral [:] trn_to, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] next_trn_id, + id_t [:] trn_to, uint8_t [:] status_at_node, long num_node_states, long num_node_states_sq, int8_t [:] bnd_lnk, const int8_t [:] link_orientation, - cython.integral [:] link_state, - cython.integral [:] n_trn, - cython.integral [:, :] trn_id, + id_t [:] link_state, + id_t [:] n_trn, + id_t [:, :] trn_id, cython.floating [:] trn_rate, - const cython.integral [:, :] links_at_node, + const id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, - cython.integral [:] propid, + id_t [:] propid, object prop_data, prop_reset_value, object trn_prop_update_fn, @@ -1127,24 +1131,24 @@ cpdef double run_cts_new( double current_time, PriorityQueue priority_queue, cython.floating [:] next_update, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] next_trn_id, - cython.integral [:] trn_to, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] next_trn_id, + id_t [:] trn_to, uint8_t [:] status_at_node, long num_node_states, long num_node_states_sq, int8_t [:] bnd_lnk, const int8_t [:] link_orientation, - cython.integral [:] link_state, - cython.integral [:] n_trn, - cython.integral [:, :] trn_id, + id_t [:] link_state, + id_t [:] n_trn, + id_t [:, :] trn_id, cython.floating [:] trn_rate, - const cython.integral [:, :] links_at_node, + const id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, - cython.integral [:] propid, + id_t [:] propid, object prop_data, prop_reset_value, trn_prop_update_fn, @@ -1232,18 +1236,18 @@ cpdef double run_cts( object plotter, object event_queue, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] propid, + id_t [:] propid, object prop_data, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, @@ -1325,8 +1329,8 @@ cpdef get_next_event_lean( long link, long current_state, double current_time, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, ): """Get the next event for a link. @@ -1396,17 +1400,17 @@ cdef void update_link_state_lean( long new_link_state, double current_time, int8_t [:] bnd_lnk, - cython.integral [:] node_state, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, + id_t [:] node_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, int8_t [:] link_orientation, long num_node_states, long num_node_states_sq, - cython.integral [:] link_state, - cython.integral [:] n_xn, + id_t [:] link_state, + id_t [:] n_xn, event_queue, cython.floating [:] next_update, - cython.integral [:, :] xn_to, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, ): """ @@ -1453,16 +1457,16 @@ cdef void update_link_state_lean( cdef void do_transition_lean( Event event, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, @@ -1629,16 +1633,16 @@ cpdef double run_cts_lean( double current_time, object event_queue, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, diff --git a/landlab/components/bedrock_landslider/cfuncs.pyx b/landlab/components/bedrock_landslider/cfuncs.pyx index f4141254c2..d0c5e740df 100755 --- a/landlab/components/bedrock_landslider/cfuncs.pyx +++ b/landlab/components/bedrock_landslider/cfuncs.pyx @@ -1,13 +1,17 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) cpdef _landslide_runout( double dx, double phi, double min_deposition_slope, - cython.integral [:] stack_rev_sel, - cython.integral [:, :] receivers, + id_t [:] stack_rev_sel, + id_t [:, :] receivers, cython.floating [:, :] fract, cython.floating [:] Qs_in, cython.floating [:] L_Hill, diff --git a/landlab/components/drainage_density/cfuncs.pyx b/landlab/components/drainage_density/cfuncs.pyx index 12553ede9d..1581b82063 100644 --- a/landlab/components/drainage_density/cfuncs.pyx +++ b/landlab/components/drainage_density/cfuncs.pyx @@ -1,14 +1,18 @@ cimport cython from libc.stdint cimport uint8_t +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) def _calc_dists_to_channel( uint8_t [:] ch_network, - cython.integral [:] flow_receivers, - cython.integral [:] upstream_order, + id_t [:] flow_receivers, + id_t [:] upstream_order, const cython.floating [:] link_lengths, - cython.integral [:] stack_links, + id_t [:] stack_links, cython.floating [:] dist_to_ch, long num_nodes, ): diff --git a/landlab/components/overland_flow/_neighbors_at_link.pyx b/landlab/components/overland_flow/_neighbors_at_link.pyx index 26c1c2141f..b78cb0f588 100644 --- a/landlab/components/overland_flow/_neighbors_at_link.pyx +++ b/landlab/components/overland_flow/_neighbors_at_link.pyx @@ -1,11 +1,15 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) def neighbors_at_link( - const cython.integral [:] links, + const id_t [:] links, shape, - cython.integral [:, :] out, + id_t [:, :] out, ): cdef int stride cdef int n_links diff --git a/landlab/graph/matrix/ext/matrix.pyx b/landlab/graph/matrix/ext/matrix.pyx index b07c851176..9421302210 100644 --- a/landlab/graph/matrix/ext/matrix.pyx +++ b/landlab/graph/matrix/ext/matrix.pyx @@ -5,6 +5,10 @@ from libc.stdlib cimport malloc from libc.string cimport memcpy from libc.string cimport memmove +ctypedef fused id_t: + cython.integral + long long + cdef void roll( void * values, @@ -39,8 +43,8 @@ cdef void roll( @cython.boundscheck(False) @cython.wraparound(False) def roll_id_matrix_rows( - cython.integral [:, :] matrix, - cython.integral [:] shift, + id_t [:, :] matrix, + id_t [:] shift, ): cdef int n_rows = matrix.shape[0] cdef int n_cols = matrix.shape[1] From cfaac8c600df7de4eae384f5f1997047a7a1cd31 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 14 Aug 2024 11:40:19 -0600 Subject: [PATCH 54/70] use id_t in all cython files --- landlab/ca/cfuncs.pyx | 202 +++++++++--------- .../components/bedrock_landslider/cfuncs.pyx | 8 +- .../components/drainage_density/cfuncs.pyx | 10 +- .../overland_flow/_neighbors_at_link.pyx | 8 +- landlab/graph/matrix/ext/matrix.pyx | 8 +- 5 files changed, 128 insertions(+), 108 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index d902eae24c..7949632898 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -18,6 +18,10 @@ from _heapq import heappush from landlab.grid.nodestatus import NodeStatus +ctypedef fused id_t: + cython.integral + long long + cdef double _NEVER = 1.0e50 @@ -136,9 +140,9 @@ cdef class Event: @cython.wraparound(False) cdef int current_link_state( const long link_id, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, const long num_node_states, const long num_node_states_sq, @@ -190,17 +194,17 @@ cdef int current_link_state( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions( - const cython.integral [:] active_links, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] active_links, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, int8_t [:] bnd_lnk, - cython.integral [:] link_state, - cython.integral [:] n_xn, + id_t [:] link_state, + id_t [:] n_xn, event_queue, cython.floating [:] next_update, - cython.integral [:, :] xn_to, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, long num_node_states, long num_node_states_sq, @@ -261,18 +265,18 @@ cpdef update_link_states_and_transitions( @cython.boundscheck(True) @cython.wraparound(False) cpdef update_link_states_and_transitions_new( - const cython.integral [:] active_links, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] active_links, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, int8_t [:] bnd_lnk, - cython.integral [:] link_state, - cython.integral [:] n_trn, + id_t [:] link_state, + id_t [:] n_trn, PriorityQueue priority_queue, cython.floating [:] next_update, - cython.integral [:] next_trn_id, - cython.integral [:, :] trn_id, + id_t [:] next_trn_id, + id_t [:, :] trn_id, cython.floating [:] trn_rate, long num_node_states, long num_node_states_sq, @@ -331,7 +335,7 @@ cpdef update_link_states_and_transitions_new( @cython.wraparound(False) @cython.cdivision(True) cpdef update_node_states( - cython.integral [:] node_state, + id_t [:] node_state, const uint8_t [:] status_at_node, long tail_node, long head_node, @@ -358,8 +362,8 @@ cpdef get_next_event( long link, long current_state, double current_time, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, xn_prop_update_fn, @@ -435,8 +439,8 @@ cpdef get_next_event_new( long link, long current_state, double current_time, - cython.integral [:] n_trn, - cython.integral [:, :] trn_id, + id_t [:] n_trn, + id_t [:, :] trn_id, cython.floating [:] trn_rate, ): """Get the next event for a link. @@ -494,13 +498,13 @@ cpdef get_next_event_new( cpdef push_transitions_to_event_queue( long number_of_active_links, - const cython.integral [:] active_links, - cython.integral [:] n_trn, - cython.integral [:] link_state, - cython.integral [:, :] trn_id, + const id_t [:] active_links, + id_t [:] n_trn, + id_t [:] link_state, + id_t [:, :] trn_id, cython.floating [:] trn_rate, cython.floating [:] next_update, - cython.integral [:] next_trn_id, + id_t [:] next_trn_id, PriorityQueue priority_queue, ): """ @@ -531,17 +535,17 @@ cdef void update_link_state( long new_link_state, double current_time, int8_t [:] bnd_lnk, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, long num_node_states, long num_node_states_sq, - cython.integral [:] link_state, - cython.integral [:] n_xn, + id_t [:] link_state, + id_t [:] n_xn, event_queue, cython.floating [:] next_update, - cython.integral [:, :] xn_to, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, np.ndarray[object, ndim=2] xn_prop_update_fn, @@ -599,18 +603,18 @@ cdef void update_link_state_new( long new_link_state, double current_time, int8_t [:] bnd_lnk, - const cython.integral [:] node_state, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, + const id_t [:] node_state, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, const int8_t [:] link_orientation, long num_node_states, long num_node_states_sq, - cython.integral [:] link_state, - cython.integral [:] n_trn, + id_t [:] link_state, + id_t [:] n_trn, PriorityQueue priority_queue, cython.floating [:] next_update, - cython.integral [:] next_trn_id, - cython.integral [:, :] trn_id, + id_t [:] next_trn_id, + id_t [:, :] trn_id, cython.floating [:] trn_rate, ): """ @@ -664,18 +668,18 @@ cdef void update_link_state_new( cdef void do_transition( Event event, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] propid, + id_t [:] propid, object prop_data, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, @@ -879,24 +883,24 @@ cpdef void do_transition_new( double event_time, PriorityQueue priority_queue, cython.floating [:] next_update, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] next_trn_id, - cython.integral [:] trn_to, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] next_trn_id, + id_t [:] trn_to, uint8_t [:] status_at_node, long num_node_states, long num_node_states_sq, int8_t [:] bnd_lnk, const int8_t [:] link_orientation, - cython.integral [:] link_state, - cython.integral [:] n_trn, - cython.integral [:, :] trn_id, + id_t [:] link_state, + id_t [:] n_trn, + id_t [:, :] trn_id, cython.floating [:] trn_rate, - const cython.integral [:, :] links_at_node, + const id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, - cython.integral [:] propid, + id_t [:] propid, object prop_data, prop_reset_value, object trn_prop_update_fn, @@ -1127,24 +1131,24 @@ cpdef double run_cts_new( double current_time, PriorityQueue priority_queue, cython.floating [:] next_update, - const cython.integral [:] node_at_link_tail, - const cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] next_trn_id, - cython.integral [:] trn_to, + const id_t [:] node_at_link_tail, + const id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] next_trn_id, + id_t [:] trn_to, uint8_t [:] status_at_node, long num_node_states, long num_node_states_sq, int8_t [:] bnd_lnk, const int8_t [:] link_orientation, - cython.integral [:] link_state, - cython.integral [:] n_trn, - cython.integral [:, :] trn_id, + id_t [:] link_state, + id_t [:] n_trn, + id_t [:, :] trn_id, cython.floating [:] trn_rate, - const cython.integral [:, :] links_at_node, + const id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, - cython.integral [:] propid, + id_t [:] propid, object prop_data, prop_reset_value, trn_prop_update_fn, @@ -1232,18 +1236,18 @@ cpdef double run_cts( object plotter, object event_queue, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] propid, + id_t [:] propid, object prop_data, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, @@ -1325,8 +1329,8 @@ cpdef get_next_event_lean( long link, long current_state, double current_time, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, ): """Get the next event for a link. @@ -1396,17 +1400,17 @@ cdef void update_link_state_lean( long new_link_state, double current_time, int8_t [:] bnd_lnk, - cython.integral [:] node_state, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, + id_t [:] node_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, int8_t [:] link_orientation, long num_node_states, long num_node_states_sq, - cython.integral [:] link_state, - cython.integral [:] n_xn, + id_t [:] link_state, + id_t [:] n_xn, event_queue, cython.floating [:] next_update, - cython.integral [:, :] xn_to, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, ): """ @@ -1453,16 +1457,16 @@ cdef void update_link_state_lean( cdef void do_transition_lean( Event event, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, @@ -1629,16 +1633,16 @@ cpdef double run_cts_lean( double current_time, object event_queue, cython.floating [:] next_update, - cython.integral [:] node_at_link_tail, - cython.integral [:] node_at_link_head, - cython.integral [:] node_state, - cython.integral [:] link_state, + id_t [:] node_at_link_tail, + id_t [:] node_at_link_head, + id_t [:] node_state, + id_t [:] link_state, uint8_t [:] status_at_node, int8_t [:] link_orientation, - cython.integral [:] n_xn, - cython.integral [:, :] xn_to, + id_t [:] n_xn, + id_t [:, :] xn_to, cython.floating [:, :] xn_rate, - cython.integral [:, :] links_at_node, + id_t [:, :] links_at_node, const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, diff --git a/landlab/components/bedrock_landslider/cfuncs.pyx b/landlab/components/bedrock_landslider/cfuncs.pyx index f4141254c2..d0c5e740df 100755 --- a/landlab/components/bedrock_landslider/cfuncs.pyx +++ b/landlab/components/bedrock_landslider/cfuncs.pyx @@ -1,13 +1,17 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) cpdef _landslide_runout( double dx, double phi, double min_deposition_slope, - cython.integral [:] stack_rev_sel, - cython.integral [:, :] receivers, + id_t [:] stack_rev_sel, + id_t [:, :] receivers, cython.floating [:, :] fract, cython.floating [:] Qs_in, cython.floating [:] L_Hill, diff --git a/landlab/components/drainage_density/cfuncs.pyx b/landlab/components/drainage_density/cfuncs.pyx index 12553ede9d..1581b82063 100644 --- a/landlab/components/drainage_density/cfuncs.pyx +++ b/landlab/components/drainage_density/cfuncs.pyx @@ -1,14 +1,18 @@ cimport cython from libc.stdint cimport uint8_t +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) def _calc_dists_to_channel( uint8_t [:] ch_network, - cython.integral [:] flow_receivers, - cython.integral [:] upstream_order, + id_t [:] flow_receivers, + id_t [:] upstream_order, const cython.floating [:] link_lengths, - cython.integral [:] stack_links, + id_t [:] stack_links, cython.floating [:] dist_to_ch, long num_nodes, ): diff --git a/landlab/components/overland_flow/_neighbors_at_link.pyx b/landlab/components/overland_flow/_neighbors_at_link.pyx index 26c1c2141f..b78cb0f588 100644 --- a/landlab/components/overland_flow/_neighbors_at_link.pyx +++ b/landlab/components/overland_flow/_neighbors_at_link.pyx @@ -1,11 +1,15 @@ cimport cython +ctypedef fused id_t: + cython.integral + long long + @cython.boundscheck(False) def neighbors_at_link( - const cython.integral [:] links, + const id_t [:] links, shape, - cython.integral [:, :] out, + id_t [:, :] out, ): cdef int stride cdef int n_links diff --git a/landlab/graph/matrix/ext/matrix.pyx b/landlab/graph/matrix/ext/matrix.pyx index b07c851176..9421302210 100644 --- a/landlab/graph/matrix/ext/matrix.pyx +++ b/landlab/graph/matrix/ext/matrix.pyx @@ -5,6 +5,10 @@ from libc.stdlib cimport malloc from libc.string cimport memcpy from libc.string cimport memmove +ctypedef fused id_t: + cython.integral + long long + cdef void roll( void * values, @@ -39,8 +43,8 @@ cdef void roll( @cython.boundscheck(False) @cython.wraparound(False) def roll_id_matrix_rows( - cython.integral [:, :] matrix, - cython.integral [:] shift, + id_t [:, :] matrix, + id_t [:] shift, ): cdef int n_rows = matrix.shape[0] cdef int n_cols = matrix.shape[1] From 47dae1b2659901e81512fcacd3f69eab3964db42 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 14 Aug 2024 18:13:10 -0600 Subject: [PATCH 55/70] clean up more cython typed memory views --- landlab/graph/quantity/ext/of_element.pyx | 6 +- landlab/graph/sort/ext/remap_element.pyx | 150 +++++++++++++++------- landlab/graph/sort/intpair.py | 2 +- 3 files changed, 110 insertions(+), 48 deletions(-) diff --git a/landlab/graph/quantity/ext/of_element.pyx b/landlab/graph/quantity/ext/of_element.pyx index 2c34eb03cf..8f0621bf36 100644 --- a/landlab/graph/quantity/ext/of_element.pyx +++ b/landlab/graph/quantity/ext/of_element.pyx @@ -5,6 +5,10 @@ ctypedef fused id_t: cython.integral long long +ctypedef fused integral_out_t: + cython.integral + long long + @cython.boundscheck(False) @cython.wraparound(False) @@ -166,7 +170,7 @@ cpdef max_of_children_at_parent( @cython.wraparound(False) cpdef count_of_children_at_parent( const id_t [:, :] children_at_parent, - id_t [:] out, + integral_out_t [:] out, ): """Count the number of children for each parent. diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index b25930f53c..85d8592767 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -21,6 +21,10 @@ ctypedef fused id_t: cython.integral long long +ctypedef fused integral_out_t: + cython.integral + long long + @cython.boundscheck(False) @cython.wraparound(False) @@ -91,7 +95,7 @@ def remap_graph_element( @cython.wraparound(False) def remap_graph_element_ignore( id_t [:] elements, - id_t [:] old_to_new, + const id_t [:] old_to_new, int bad_val, ): """Remap elements in an array in place, ignoring bad values. @@ -150,9 +154,9 @@ def reorder_patches( @cython.boundscheck(False) @cython.wraparound(False) def calc_center_of_patch( - id_t [:] links_at_patch, - id_t [:] offset_to_patch, - cython.floating [:, :] xy_at_link, + const id_t [:] links_at_patch, + const id_t [:] offset_to_patch, + const cython.floating [:, :] xy_at_link, cython.floating [:, :] xy_at_patch, ): cdef int patch @@ -209,7 +213,7 @@ cdef void reverse_order(id_t * array, long size) noexcept nogil: @cython.wraparound(False) def reverse_element_order( id_t [:, :] links_at_patch, - id_t [:] patches, + const id_t [:] patches, ): cdef long n_patches = patches.shape[0] cdef long max_links = links_at_patch.shape[1] @@ -228,11 +232,12 @@ def reverse_element_order( cdef void _offset_to_sorted_blocks( - DTYPE_t *array, + const id_t [:] array, # id_t *array, long len, long stride, - DTYPE_t *offset, + integral_out_t [:] offset, + # long long [:] offset, # id_t *offset, long n_values, ) noexcept: @@ -263,19 +268,23 @@ cdef void _offset_to_sorted_blocks( @cython.boundscheck(False) @cython.wraparound(False) def offset_to_sorted_block( - # id_t [:, :] sorted_ids, - # id_t [:] offset_to_block, - np.ndarray[DTYPE_t, ndim=2, mode="c"] sorted_ids not None, - np.ndarray[DTYPE_t, ndim=1, mode="c"] offset_to_block not None, + id_t [:, :] sorted_ids, + integral_out_t [:] offset_to_block, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] sorted_ids not None, + # np.ndarray[DTYPE_t, ndim=1, mode="c"] offset_to_block not None, ): cdef long n_ids = sorted_ids.shape[0] cdef long n_blocks = offset_to_block.shape[0] + # cdef id_t [:] sorted_ids_flat = sorted_ids + # cdef id_t [:] sorted_ids_flat = sorted_ids.reshape((-1,)) + cdef id_t *ptr = &sorted_ids[0, 0] + cdef id_t [:] sorted_ids_flat= ptr _offset_to_sorted_blocks( - &sorted_ids[0, 0], + sorted_ids_flat, n_ids, sorted_ids.shape[1], - &offset_to_block[0], + offset_to_block, n_blocks, ) @@ -283,44 +292,62 @@ def offset_to_sorted_block( @cython.boundscheck(False) @cython.wraparound(False) def pair_isin( - np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, - np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, - # np.ndarray[uint8, ndim=1, mode="c"] out not None, - np.ndarray[uint8, ndim=1, mode="c", cast=True] out not None, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, + # # np.ndarray[uint8, ndim=1, mode="c"] out not None, + # np.ndarray[uint8, ndim=1, mode="c", cast=True] out not None, + + const id_t [:, :] src_pairs, + const id_t [:, :] pairs, + uint8 [:] out, ): - cdef long n + # cdef long n cdef long pair cdef long n_pairs = pairs.shape[0] cdef long n_values = src_pairs.shape[0] - cdef DTYPE_t *data = malloc(n_values * sizeof(DTYPE_t)) + # cdef long *data = malloc(n_values * sizeof(long)) + cdef long [:] data = np.full(n_values, 1, dtype=long) + # cdef const id_t [:] src_pairs_flat = src_pairs.reshape((-1,)) + cdef const id_t *ptr = &src_pairs[0, 0] + cdef const id_t [:] src_pairs_flat = ptr cdef SparseMatrixInt mat - for n in range(n_values): - data[n] = 1 + # for n in range(n_values): + # data[n] = 1 try: - mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], data, n_values, 0) + # mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], data, n_values, 0) + mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, 0) for pair in range(n_pairs): out[pair] = sparse_matrix_get_or_transpose( mat, pairs[pair, 0], pairs[pair, 1] ) finally: - free(data) + pass + # free(data) @cython.boundscheck(False) @cython.wraparound(False) def map_pairs_to_values( - np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, - np.ndarray[DTYPE_t, ndim=1, mode="c"] data not None, - np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, - np.ndarray[DTYPE_t, ndim=1, mode="c"] out not None, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, + # np.ndarray[DTYPE_t, ndim=1, mode="c"] data not None, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, + # np.ndarray[DTYPE_t, ndim=1, mode="c"] out not None, + const id_t [:, :] src_pairs, + const integral_out_t [:] data, + const id_t [:, :] pairs, + integral_out_t [:] out, ): cdef long pair cdef long n_pairs = out.shape[0] cdef long n_values = data.shape[0] + # cdef const id_t [:] src_pairs_flat = src_pairs.reshape((-1,)) + cdef const id_t *ptr = &src_pairs[0, 0] + cdef const id_t [:] src_pairs_flat = ptr cdef SparseMatrixInt mat - mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], &data[0], n_values, -1) + # mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], &data[0], n_values, -1) + mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) for pair in range(n_pairs): out[pair] = sparse_matrix_get_or_transpose(mat, pairs[pair, 0], pairs[pair, 1]) @@ -329,24 +356,38 @@ def map_pairs_to_values( @cython.boundscheck(False) @cython.wraparound(False) def map_rolling_pairs_to_values( - np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, - np.ndarray[DTYPE_t, ndim=1, mode="c"] data not None, - np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, - np.ndarray[DTYPE_t, ndim=1, mode="c"] size_of_row not None, - np.ndarray[DTYPE_t, ndim=2, mode="c"] out not None, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, + # np.ndarray[DTYPE_t, ndim=1, mode="c"] data not None, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, + # np.ndarray[DTYPE_t, ndim=1, mode="c"] size_of_row not None, + # np.ndarray[DTYPE_t, ndim=2, mode="c"] out not None, + const id_t [:, :] src_pairs, + const integral_out_t [:] data, + const id_t [:, :] pairs, + const id_t [:] size_of_row, + integral_out_t [:, :] out, ): cdef long n_values = data.shape[0] cdef long n_pairs = pairs.shape[0] cdef long pair + # cdef const id_t [:] src_pairs_flat = src_pairs.ravel() + cdef const id_t *ptr = &src_pairs[0, 0] + cdef const id_t [:] src_pairs_flat = ptr cdef SparseMatrixInt mat - mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], &data[0], n_values, -1) + # mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], &data[0], n_values, -1) + mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) for pair in range(n_pairs): - _map_rolling_pairs(mat, &pairs[pair, 0], &out[pair, 0], size_of_row[pair]) + _map_rolling_pairs(mat, pairs[pair, :], out[pair, :], size_of_row[pair]) -cdef _map_rolling_pairs(SparseMatrixInt mat, DTYPE_t *pairs, DTYPE_t *out, long size): +cdef _map_rolling_pairs( + SparseMatrixInt mat, + const id_t [:] pairs, + integral_out_t [:] out, + long size, +): cdef long n if size > 0: @@ -358,10 +399,10 @@ cdef _map_rolling_pairs(SparseMatrixInt mat, DTYPE_t *pairs, DTYPE_t *out, long cdef struct SparseMatrixInt: - DTYPE_t *values + long long *values long n_values - DTYPE_t *offset_to_row - DTYPE_t *col + long long *offset_to_row + long long *col long col_start long col_stride long n_rows @@ -370,8 +411,12 @@ cdef struct SparseMatrixInt: cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( - DTYPE_t *rows_and_cols, - DTYPE_t *values, + # DTYPE_t *rows_and_cols, + # DTYPE_t *values, + # long n_values, + # long no_val, + const id_t [:] rows_and_cols, + const integral_out_t [:] values, long n_values, long no_val, ): @@ -381,7 +426,12 @@ cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( cdef long max_col = 0 cdef long i cdef SparseMatrixInt mat - cdef DTYPE_t *offset + # cdef long long *offset + cdef long long [:] _col + cdef long long [:] _values + # cdef long long * offset = malloc((n_rows + 1) * sizeof(long long)) + # cdef long long [:] offset_view = offset + cdef long long [:] offset for i in range(0, n_values * 2, 2): if rows_and_cols[i] > max_row: @@ -391,14 +441,20 @@ cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( n_rows = max_row + 1 n_cols = max_col + 1 - offset = malloc((n_rows + 1) * sizeof(DTYPE_t)) + offset = np.empty(n_rows + 1, dtype=long) + _col = np.array(rows_and_cols, dtype=long) + _values = np.array(values, dtype=long) + # offset = malloc((n_rows + 1) * sizeof(long long)) + # col = malloc((2 * n_values) * sizeof(long long)) + # values = malloc(n_values * sizeof(long long)) _offset_to_sorted_blocks(rows_and_cols, n_values, 2, offset, n_rows + 1) - mat.values = values + mat.values = &_values[0] mat.n_values = n_values - mat.offset_to_row = offset - mat.col = rows_and_cols + mat.offset_to_row = &offset[0] + # mat.col = rows_and_cols + mat.col = &_col[0] mat.col_start = 1 mat.col_stride = 2 mat.n_rows = n_rows @@ -410,6 +466,8 @@ cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( cdef sparse_matrix_free(SparseMatrixInt mat): free(mat.offset_to_row) + free(mat.col) + free(mat.values) cdef long sparse_matrix_get_or_transpose(SparseMatrixInt mat, long row, long col): diff --git a/landlab/graph/sort/intpair.py b/landlab/graph/sort/intpair.py index adedb69d29..7b4634c9df 100644 --- a/landlab/graph/sort/intpair.py +++ b/landlab/graph/sort/intpair.py @@ -81,7 +81,7 @@ def map_pairs_to_values(mapping, pairs, out=None, sorter=None, sorted=False): pairs = np.asarray(pairs) if out is None: - out = np.empty(len(pairs), dtype=int) + out = np.empty(len(pairs), dtype=values.dtype) if not sorted and sorter is None: sorter = np.argsort(keys[:, 0]) From 92ea24b2fd53f65161dde99bfbbaf2aa59035642 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 15 Aug 2024 12:48:22 -0600 Subject: [PATCH 56/70] use newer numpy api --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 6a92609484..98459ffbdb 100644 --- a/setup.py +++ b/setup.py @@ -61,6 +61,7 @@ [path], extra_compile_args=compile_args, extra_link_args=compile_args, + define_macros=[("NPY_NO_DEPRECATED_API", "1")], ) for path in cython_files ], From 5e4a2801972b53b2fbb12444c9e04aaefbbac465 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 15 Aug 2024 12:53:48 -0600 Subject: [PATCH 57/70] use c pointers --- landlab/graph/sort/ext/remap_element.pyx | 49 +++++++++++++++--------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index 85d8592767..9569a0f17b 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -96,7 +96,7 @@ def remap_graph_element( def remap_graph_element_ignore( id_t [:] elements, const id_t [:] old_to_new, - int bad_val, + long bad_val, ): """Remap elements in an array in place, ignoring bad values. @@ -109,10 +109,10 @@ def remap_graph_element_ignore( bad_val : int Ignore values in the input array when remapping. """ - cdef int n_elements = elements.shape[0] - cdef int i + cdef long n_elements = elements.shape[0] + cdef long i - for i in range(n_elements): + for i in prange(n_elements, nogil=True, schedule="static"): if elements[i] != bad_val: elements[i] = old_to_new[elements[i]] @@ -306,7 +306,7 @@ def pair_isin( cdef long n_pairs = pairs.shape[0] cdef long n_values = src_pairs.shape[0] # cdef long *data = malloc(n_values * sizeof(long)) - cdef long [:] data = np.full(n_values, 1, dtype=long) + cdef long [:] data = np.full(n_values, 1, dtype=int) # cdef const id_t [:] src_pairs_flat = src_pairs.reshape((-1,)) cdef const id_t *ptr = &src_pairs[0, 0] cdef const id_t [:] src_pairs_flat = ptr @@ -427,11 +427,14 @@ cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( cdef long i cdef SparseMatrixInt mat # cdef long long *offset - cdef long long [:] _col - cdef long long [:] _values + # cdef long long [:] _col + # cdef long long [:] _values + cdef long long * _col + cdef long long * _values # cdef long long * offset = malloc((n_rows + 1) * sizeof(long long)) # cdef long long [:] offset_view = offset - cdef long long [:] offset + cdef long long * offset + cdef long long [:] mv for i in range(0, n_values * 2, 2): if rows_and_cols[i] > max_row: @@ -441,20 +444,30 @@ cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( n_rows = max_row + 1 n_cols = max_col + 1 - offset = np.empty(n_rows + 1, dtype=long) - _col = np.array(rows_and_cols, dtype=long) - _values = np.array(values, dtype=long) - # offset = malloc((n_rows + 1) * sizeof(long long)) - # col = malloc((2 * n_values) * sizeof(long long)) - # values = malloc(n_values * sizeof(long long)) + # offset = np.empty(n_rows + 1, dtype=long) + # _col = np.array(rows_and_cols, dtype=long) + # _values = np.array(values, dtype=long) + offset = malloc((n_rows + 1) * sizeof(long long)) + + mv = offset + + _col = malloc((2 * n_values) * sizeof(long long)) + _values = malloc(n_values * sizeof(long long)) + for i in range(2 * n_values): + _col[i] = rows_and_cols[i] + for i in range(n_values): + _values[i] = values[i] - _offset_to_sorted_blocks(rows_and_cols, n_values, 2, offset, n_rows + 1) + _offset_to_sorted_blocks(rows_and_cols, n_values, 2, mv, n_rows + 1) - mat.values = &_values[0] + # mat.values = &_values[0] + mat.values = _values mat.n_values = n_values - mat.offset_to_row = &offset[0] + # mat.offset_to_row = &offset[0] + mat.offset_to_row = offset # mat.col = rows_and_cols - mat.col = &_col[0] + # mat.col = &_col[0] + mat.col = _col mat.col_start = 1 mat.col_stride = 2 mat.n_rows = n_rows From 3997166cf64c8adea9f5f5528e2eaaefca4513d7 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 15 Aug 2024 14:16:42 -0600 Subject: [PATCH 58/70] use malloc instead of numpy --- landlab/graph/sort/ext/remap_element.pyx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index 9569a0f17b..944b9359de 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -306,14 +306,19 @@ def pair_isin( cdef long n_pairs = pairs.shape[0] cdef long n_values = src_pairs.shape[0] # cdef long *data = malloc(n_values * sizeof(long)) - cdef long [:] data = np.full(n_values, 1, dtype=int) + cdef long *data_p + cdef long [:] data + # cdef int64_t [:] data = np.full(n_values, 1, dtype="int64") # cdef const id_t [:] src_pairs_flat = src_pairs.reshape((-1,)) cdef const id_t *ptr = &src_pairs[0, 0] cdef const id_t [:] src_pairs_flat = ptr cdef SparseMatrixInt mat - # for n in range(n_values): - # data[n] = 1 + data_p = malloc(n_values * sizeof(long)) + data = data_p + + for n in range(n_values): + data[n] = 1 try: # mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], data, n_values, 0) mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, 0) @@ -322,8 +327,7 @@ def pair_isin( mat, pairs[pair, 0], pairs[pair, 1] ) finally: - pass - # free(data) + free(data_p) @cython.boundscheck(False) From 2c49caf467e2858d4da6b4b4d8dc1ac02e117896 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 15 Aug 2024 15:41:31 -0600 Subject: [PATCH 59/70] clean up; remove debugging statements --- landlab/ca/cfuncs.pyx | 22 +--- .../depression_finder/lake_mapper.py | 31 ++--- .../erosion_deposition/erosion_deposition.py | 37 ++---- .../flow_director/flow_direction_DN.py | 14 --- .../priority_flood_flow_router.py | 52 +++------ .../space/ext/calc_sequential_ero_depo.pyx | 1 - landlab/components/space/space.py | 37 ++---- .../space/space_large_scale_eroder.py | 73 ++++-------- landlab/graph/sort/ext/remap_element.pyx | 106 +++++------------- landlab/graph/sort/sort.py | 5 +- 10 files changed, 104 insertions(+), 274 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index 7949632898..7baec0f67e 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -11,8 +11,6 @@ import numpy as np cimport numpy as np -import sys # for debug - from _heapq import heappop from _heapq import heappush @@ -24,21 +22,7 @@ ctypedef fused id_t: cdef double _NEVER = 1.0e50 - cdef int _CORE = NodeStatus.CORE - -# DTYPE = np.double -# ctypedef np.double_t DTYPE_t - -# DTYPE_INT = int -# ctypedef np.int_t DTYPE_INT_t - -# DTYPE_INT8 = np.int8 -# ctypedef np.int8_t DTYPE_INT8_t - -# DTYPE_UINT8 = np.uint8 -# ctypedef np.uint8_t DTYPE_UINT8_t - cdef char _DEBUG = 0 @@ -876,8 +860,8 @@ cdef void do_transition( event.prop_update_fn(this_cts_model, tail_node, head_node, event.time) -# @cython.boundscheck(False) -# @cython.wraparound(False) +@cython.boundscheck(False) +@cython.wraparound(False) cpdef void do_transition_new( long event_link, double event_time, @@ -1170,7 +1154,6 @@ cpdef double run_cts_new( Needed if caller wants to plot after every transition (see celllab_cts.py for other parameters) """ - import sys cdef double ev_time cdef int _ev_idx cdef int ev_link @@ -1253,7 +1236,6 @@ cpdef double run_cts( long num_node_states_sq, prop_reset_value, int8_t [:, :] xn_propswap, - # xn_prop_update_fn, np.ndarray[object, ndim=2] xn_prop_update_fn, int8_t [:] bnd_lnk, this_cts_model, diff --git a/landlab/components/depression_finder/lake_mapper.py b/landlab/components/depression_finder/lake_mapper.py index 0daf13724d..1e07653617 100644 --- a/landlab/components/depression_finder/lake_mapper.py +++ b/landlab/components/depression_finder/lake_mapper.py @@ -765,28 +765,17 @@ def find_depression_from_pit(self, pit_node, reroute_flow=True): pit_count = 1 while not found_outlet: - try: - lowest_node_on_perimeter, pit_count = ( - find_lowest_node_on_lake_perimeter_c( - self._node_nbrs, - self.flood_status, - self._elev, - nodes_this_depression, - pit_count, - self._BIG_ELEV, - ) + lowest_node_on_perimeter, pit_count = ( + find_lowest_node_on_lake_perimeter_c( + self._node_nbrs, + self.flood_status, + self._elev, + nodes_this_depression, + pit_count, + self._BIG_ELEV, ) - except TypeError: - raise RuntimeError( - ( - self._node_nbrs.dtype, - self.flood_status.dtype, - self._elev.dtype, - nodes_this_depression.dtype, - type(pit_count), - type(self._BIG_ELEV), - ) - ) from None + ) + # note this can return the supplied node, if - somehow - the # surrounding nodes are all self._grid.BAD_INDEX # I BELIEVE THE IS_VALID_OUTLET FN SHOULD ASSIGN FLOW DIR diff --git a/landlab/components/erosion_deposition/erosion_deposition.py b/landlab/components/erosion_deposition/erosion_deposition.py index a6f2047802..3127755cbf 100644 --- a/landlab/components/erosion_deposition/erosion_deposition.py +++ b/landlab/components/erosion_deposition/erosion_deposition.py @@ -386,32 +386,17 @@ def _calc_qs_in_and_depo_rate(self): # iterate top to bottom through the stack, calculate qs # cythonized version of calculating qs_in - try: - calculate_qs_in( - np.flipud(self._stack), - self._flow_receivers, - self._cell_area_at_node, - self._q, - self._qs, - self.sediment_influx, - self._erosion_term, - self._v_s, - self._F_f, - ) - except TypeError: - raise RuntimeError( - ( - np.flipud(self._stack).dtype, - self._flow_receivers.dtype, - self._cell_area_at_node.dtype, - self._q.dtype, - self._qs.dtype, - self.sediment_influx.dtype, - self._erosion_term.dtype, - type(self._v_s), - type(self._F_f), - ) - ) from None + calculate_qs_in( + np.flipud(self._stack), + self._flow_receivers, + self._cell_area_at_node, + self._q, + self._qs, + self.sediment_influx, + self._erosion_term, + self._v_s, + self._F_f, + ) self._depo_rate[self._q > 0] = self._qs[self._q > 0] * ( self._v_s / self._q[self._q > 0] diff --git a/landlab/components/flow_director/flow_direction_DN.py b/landlab/components/flow_director/flow_direction_DN.py index 878d9ea33a..cdb70a7480 100644 --- a/landlab/components/flow_director/flow_direction_DN.py +++ b/landlab/components/flow_director/flow_direction_DN.py @@ -103,20 +103,6 @@ def flow_directions( # NOTE: MAKE SURE WE ARE ONLY LOOKING AT ACTIVE LINKS # THIS REMAINS A PROBLEM AS OF DEJH'S EFFORTS, MID MARCH 14. # overridden as part of fastscape_stream_power - - types = { - tail_node.dtype, - head_node.dtype, - active_links.dtype, - receiver.dtype, - receiver_link.dtype, - } - if len(types) > 1: - print(f"incompatible types: {', '.join(types)}") - types = {elev.dtype, link_slope.dtype, steepest_slope.dtype} - if len(types) > 1: - print(f"incompatible types: {', '.join(types)}") - adjust_flow_receivers( tail_node, head_node, diff --git a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py index 0bfcf6230f..02be8d4e63 100644 --- a/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py +++ b/landlab/components/priority_flood_flow_router/priority_flood_flow_router.py @@ -737,42 +737,22 @@ def _FlowAcc_D8(self, hill_flow=False): adj_link = np.array(self._grid.d8s_at_node, dtype=int) recvr_link = np.zeros((receivers.shape), dtype=int) - 1 - try: - _D8_flowDir( - receivers, - distance_receiver, - steepest_slope, - np.array(el_dep_free), - el_ori, - dist, - ngb, - activeCores, - activeCells, - el_d, - c, - dx, - adj_link, - recvr_link, - ) - except TypeError: - raise RuntimeError( - ( - receivers.dtype, - distance_receiver.dtype, - steepest_slope.dtype, - np.array(el_dep_free.dtype).dtype, - el_ori.dtype, - dist.dtype, - ngb.dtype, - activeCores.dtype, - activeCells.dtype, - el_d.dtype, - type(c), - type(dx), - adj_link.dtype, - recvr_link.dtype, - ) - ) from None + _D8_flowDir( + receivers, + distance_receiver, + steepest_slope, + np.array(el_dep_free), + el_ori, + dist, + ngb, + activeCores, + activeCells, + el_d, + c, + dx, + adj_link, + recvr_link, + ) # Calcualte flow acc do_FA = False diff --git a/landlab/components/space/ext/calc_sequential_ero_depo.pyx b/landlab/components/space/ext/calc_sequential_ero_depo.pyx index a7567330ee..d1a9d91da7 100644 --- a/landlab/components/space/ext/calc_sequential_ero_depo.pyx +++ b/landlab/components/space/ext/calc_sequential_ero_depo.pyx @@ -83,7 +83,6 @@ def _sequential_ero_depo( ) ) # In case soil depth evolves to infinity, fall back to no entrainment - # if H_loc == np.inf: if isinf(H_loc): H_loc = ( H[node_id] diff --git a/landlab/components/space/space.py b/landlab/components/space/space.py index 58e9c29224..bbc51f2e37 100644 --- a/landlab/components/space/space.py +++ b/landlab/components/space/space.py @@ -460,31 +460,18 @@ def _calc_qs_in_and_depo_rate(self): # iterate top to bottom through the stack, calculate qs # cythonized version of calculating qs_in - try: - calculate_qs_in( - np.flipud(self._stack), - self._flow_receivers, - self._cell_area_at_node, - self._q, - self._qs, - self.sediment_influx, - self._Es, - self._Er, - self._v_s, - self._F_f, - ) - except TypeError as error: - print(np.flipud(self._stack).dtype) - print(self._flow_receivers.dtype) - print(self._cell_area_at_node.dtype) - print(self._q.dtype) - print(self._qs.dtype) - print(self.sediment_influx.dtype) - print(self._Es.dtype) - print(self._Er.dtype) - print(type(self._v_s)) - print(type(self._F_f)) - raise error + calculate_qs_in( + np.flipud(self._stack), + self._flow_receivers, + self._cell_area_at_node, + self._q, + self._qs, + self.sediment_influx, + self._Es, + self._Er, + self._v_s, + self._F_f, + ) self._depo_rate[self._q > 0] = self._qs[self._q > 0] * ( self._v_s / self._q[self._q > 0] diff --git a/landlab/components/space/space_large_scale_eroder.py b/landlab/components/space/space_large_scale_eroder.py index 6c8dfa53a1..07f9a75242 100644 --- a/landlab/components/space/space_large_scale_eroder.py +++ b/landlab/components/space/space_large_scale_eroder.py @@ -547,56 +547,29 @@ def run_one_step_basic(self, dt=10): K_sed_vector = np.broadcast_to(self._K_sed, self._q.shape) - try: - vol_SSY_riv = _sequential_ero_depo( - stack_flip_ud_sel, - r, - area, - self._q, - self._qs, - self.sediment_influx, - self._Es, - self._Er, - self._Q_to_the_m, - slope, - H, - br, - self._sed_erosion_term, - self._br_erosion_term, - K_sed_vector, - self._v_s, - self._phi, - self._F_f, - self._H_star, - dt, - self._thickness_lim, - ) - except TypeError: - raise RuntimeError( - ( - stack_flip_ud_sel.dtype, - r.dtype, - area.dtype, - self._q.dtype, - self._qs.dtype, - self.sediment_influx.dtype, - self._Es.dtype, - self._Er.dtype, - self._Q_to_the_m.dtype, - slope.dtype, - H.dtype, - br.dtype, - self._sed_erosion_term.dtype, - self._br_erosion_term.dtype, - K_sed_vector.dtype, - self._v_s.dtype, - self._phi.dtype, - self._F_f.dtype, - type(self._H_star), - type(dt), - type(self._thickness_lim), - ) - ) from None + vol_SSY_riv = _sequential_ero_depo( + stack_flip_ud_sel, + r, + area, + self._q, + self._qs, + self.sediment_influx, + self._Es, + self._Er, + self._Q_to_the_m, + slope, + H, + br, + self._sed_erosion_term, + self._br_erosion_term, + K_sed_vector, + self._v_s, + self._phi, + self._F_f, + self._H_star, + dt, + self._thickness_lim, + ) V_leaving_riv = np.sum(self.sediment_influx[self.grid.boundary_nodes]) * dt # Update topography diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index 944b9359de..a4de11ed1f 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -6,7 +6,8 @@ from cython.parallel import prange cimport numpy as np from libc.stdlib cimport free from libc.stdlib cimport malloc - +from libc.stdint cimport int64_t +from libc.stdint cimport uint8_t cdef extern from "math.h": double atan2(double y, double x) nogil @@ -14,8 +15,6 @@ cdef extern from "math.h": from .spoke_sort import sort_spokes_at_wheel -ctypedef np.int64_t DTYPE_t -ctypedef np.uint8_t uint8 ctypedef fused id_t: cython.integral @@ -87,7 +86,7 @@ def remap_graph_element( cdef int n_elements = elements.shape[0] cdef int i - for i in range(n_elements): + for i in prange(n_elements, nogil=True, schedule="static"): elements[i] = old_to_new[elements[i]] @@ -233,12 +232,9 @@ def reverse_element_order( cdef void _offset_to_sorted_blocks( const id_t [:] array, - # id_t *array, long len, long stride, integral_out_t [:] offset, - # long long [:] offset, - # id_t *offset, long n_values, ) noexcept: cdef long i @@ -270,15 +266,11 @@ cdef void _offset_to_sorted_blocks( def offset_to_sorted_block( id_t [:, :] sorted_ids, integral_out_t [:] offset_to_block, - # np.ndarray[DTYPE_t, ndim=2, mode="c"] sorted_ids not None, - # np.ndarray[DTYPE_t, ndim=1, mode="c"] offset_to_block not None, ): cdef long n_ids = sorted_ids.shape[0] cdef long n_blocks = offset_to_block.shape[0] - # cdef id_t [:] sorted_ids_flat = sorted_ids - # cdef id_t [:] sorted_ids_flat = sorted_ids.reshape((-1,)) cdef id_t *ptr = &sorted_ids[0, 0] - cdef id_t [:] sorted_ids_flat= ptr + cdef id_t [:] sorted_ids_flat = ptr _offset_to_sorted_blocks( sorted_ids_flat, @@ -292,51 +284,35 @@ def offset_to_sorted_block( @cython.boundscheck(False) @cython.wraparound(False) def pair_isin( - # np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, - # np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, - # # np.ndarray[uint8, ndim=1, mode="c"] out not None, - # np.ndarray[uint8, ndim=1, mode="c", cast=True] out not None, - const id_t [:, :] src_pairs, const id_t [:, :] pairs, - uint8 [:] out, + uint8_t [:] out, ): - # cdef long n cdef long pair cdef long n_pairs = pairs.shape[0] cdef long n_values = src_pairs.shape[0] - # cdef long *data = malloc(n_values * sizeof(long)) - cdef long *data_p - cdef long [:] data - # cdef int64_t [:] data = np.full(n_values, 1, dtype="int64") - # cdef const id_t [:] src_pairs_flat = src_pairs.reshape((-1,)) + cdef long * data_ptr = malloc(n_values * sizeof(long)) + cdef long [:] data_array = data_ptr cdef const id_t *ptr = &src_pairs[0, 0] cdef const id_t [:] src_pairs_flat = ptr cdef SparseMatrixInt mat - data_p = malloc(n_values * sizeof(long)) - data = data_p - for n in range(n_values): - data[n] = 1 + data_array[n] = 1 + try: - # mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], data, n_values, 0) - mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, 0) + mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data_array, n_values, 0) for pair in range(n_pairs): out[pair] = sparse_matrix_get_or_transpose( mat, pairs[pair, 0], pairs[pair, 1] ) finally: - free(data_p) + free(data_ptr) @cython.boundscheck(False) @cython.wraparound(False) def map_pairs_to_values( - # np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, - # np.ndarray[DTYPE_t, ndim=1, mode="c"] data not None, - # np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, - # np.ndarray[DTYPE_t, ndim=1, mode="c"] out not None, const id_t [:, :] src_pairs, const integral_out_t [:] data, const id_t [:, :] pairs, @@ -345,12 +321,10 @@ def map_pairs_to_values( cdef long pair cdef long n_pairs = out.shape[0] cdef long n_values = data.shape[0] - # cdef const id_t [:] src_pairs_flat = src_pairs.reshape((-1,)) cdef const id_t *ptr = &src_pairs[0, 0] cdef const id_t [:] src_pairs_flat = ptr cdef SparseMatrixInt mat - # mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], &data[0], n_values, -1) mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) for pair in range(n_pairs): @@ -360,11 +334,6 @@ def map_pairs_to_values( @cython.boundscheck(False) @cython.wraparound(False) def map_rolling_pairs_to_values( - # np.ndarray[DTYPE_t, ndim=2, mode="c"] src_pairs not None, - # np.ndarray[DTYPE_t, ndim=1, mode="c"] data not None, - # np.ndarray[DTYPE_t, ndim=2, mode="c"] pairs not None, - # np.ndarray[DTYPE_t, ndim=1, mode="c"] size_of_row not None, - # np.ndarray[DTYPE_t, ndim=2, mode="c"] out not None, const id_t [:, :] src_pairs, const integral_out_t [:] data, const id_t [:, :] pairs, @@ -374,12 +343,10 @@ def map_rolling_pairs_to_values( cdef long n_values = data.shape[0] cdef long n_pairs = pairs.shape[0] cdef long pair - # cdef const id_t [:] src_pairs_flat = src_pairs.ravel() cdef const id_t *ptr = &src_pairs[0, 0] cdef const id_t [:] src_pairs_flat = ptr cdef SparseMatrixInt mat - # mat = sparse_matrix_alloc_with_tuple(&src_pairs[0, 0], &data[0], n_values, -1) mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) for pair in range(n_pairs): @@ -403,10 +370,10 @@ cdef _map_rolling_pairs( cdef struct SparseMatrixInt: - long long *values + long *values long n_values - long long *offset_to_row - long long *col + long *offset_to_row + long *col long col_start long col_stride long n_rows @@ -415,10 +382,6 @@ cdef struct SparseMatrixInt: cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( - # DTYPE_t *rows_and_cols, - # DTYPE_t *values, - # long n_values, - # long no_val, const id_t [:] rows_and_cols, const integral_out_t [:] values, long n_values, @@ -430,15 +393,10 @@ cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( cdef long max_col = 0 cdef long i cdef SparseMatrixInt mat - # cdef long long *offset - # cdef long long [:] _col - # cdef long long [:] _values - cdef long long * _col - cdef long long * _values - # cdef long long * offset = malloc((n_rows + 1) * sizeof(long long)) - # cdef long long [:] offset_view = offset - cdef long long * offset - cdef long long [:] mv + cdef long * col_ptr + cdef long * values_ptr + cdef long * offset_ptr + cdef long [:] offset_array for i in range(0, n_values * 2, 2): if rows_and_cols[i] > max_row: @@ -448,30 +406,22 @@ cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( n_rows = max_row + 1 n_cols = max_col + 1 - # offset = np.empty(n_rows + 1, dtype=long) - # _col = np.array(rows_and_cols, dtype=long) - # _values = np.array(values, dtype=long) - offset = malloc((n_rows + 1) * sizeof(long long)) - - mv = offset + offset_ptr = malloc((n_rows + 1) * sizeof(long)) + offset_array = offset_ptr - _col = malloc((2 * n_values) * sizeof(long long)) - _values = malloc(n_values * sizeof(long long)) + col_ptr = malloc((2 * n_values) * sizeof(long)) + values_ptr = malloc(n_values * sizeof(long)) for i in range(2 * n_values): - _col[i] = rows_and_cols[i] + col_ptr[i] = rows_and_cols[i] for i in range(n_values): - _values[i] = values[i] + values_ptr[i] = values[i] - _offset_to_sorted_blocks(rows_and_cols, n_values, 2, mv, n_rows + 1) + _offset_to_sorted_blocks(rows_and_cols, n_values, 2, offset_array, n_rows + 1) - # mat.values = &_values[0] - mat.values = _values + mat.values = values_ptr mat.n_values = n_values - # mat.offset_to_row = &offset[0] - mat.offset_to_row = offset - # mat.col = rows_and_cols - # mat.col = &_col[0] - mat.col = _col + mat.offset_to_row = offset_ptr + mat.col = col_ptr mat.col_start = 1 mat.col_stride = 2 mat.n_rows = n_rows diff --git a/landlab/graph/sort/sort.py b/landlab/graph/sort/sort.py index ef5a529795..4c92a6d8fe 100644 --- a/landlab/graph/sort/sort.py +++ b/landlab/graph/sort/sort.py @@ -492,9 +492,8 @@ def sort_links(nodes_at_link, nodes, midpoint_of_link=None): """ from ..quantity.ext.of_link import calc_midpoint_of_link - y_of_node, x_of_node = np.asarray(nodes[0], dtype=float), np.asarray( - nodes[1], dtype=float - ) + y_of_node = np.asarray(nodes[0], dtype=float) + x_of_node = np.asarray(nodes[1], dtype=float) if midpoint_of_link is None: midpoint_of_link = np.empty((len(nodes_at_link), 2), dtype=float) From 15fb8e36d6875573055f11afd8574dc22102038f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 21:43:57 +0000 Subject: [PATCH 60/70] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../components/depression_finder/lake_mapper.py | 16 +++++++--------- landlab/graph/sort/ext/remap_element.pyx | 6 +++--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/landlab/components/depression_finder/lake_mapper.py b/landlab/components/depression_finder/lake_mapper.py index 1e07653617..56ca1c4c82 100644 --- a/landlab/components/depression_finder/lake_mapper.py +++ b/landlab/components/depression_finder/lake_mapper.py @@ -765,15 +765,13 @@ def find_depression_from_pit(self, pit_node, reroute_flow=True): pit_count = 1 while not found_outlet: - lowest_node_on_perimeter, pit_count = ( - find_lowest_node_on_lake_perimeter_c( - self._node_nbrs, - self.flood_status, - self._elev, - nodes_this_depression, - pit_count, - self._BIG_ELEV, - ) + lowest_node_on_perimeter, pit_count = find_lowest_node_on_lake_perimeter_c( + self._node_nbrs, + self.flood_status, + self._elev, + nodes_this_depression, + pit_count, + self._BIG_ELEV, ) # note this can return the supplied node, if - somehow - the diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index a4de11ed1f..23071b2fec 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -4,10 +4,11 @@ import numpy as np from cython.parallel import prange cimport numpy as np -from libc.stdlib cimport free -from libc.stdlib cimport malloc from libc.stdint cimport int64_t from libc.stdint cimport uint8_t +from libc.stdlib cimport free +from libc.stdlib cimport malloc + cdef extern from "math.h": double atan2(double y, double x) nogil @@ -15,7 +16,6 @@ cdef extern from "math.h": from .spoke_sort import sort_spokes_at_wheel - ctypedef fused id_t: cython.integral long long From 539766c93bf3f09bbdab5db32bf95dab91f53e24 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Thu, 15 Aug 2024 15:55:03 -0600 Subject: [PATCH 61/70] remove unused import --- landlab/graph/sort/ext/remap_element.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index 23071b2fec..efcf8a14ba 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -4,7 +4,6 @@ import numpy as np from cython.parallel import prange cimport numpy as np -from libc.stdint cimport int64_t from libc.stdint cimport uint8_t from libc.stdlib cimport free from libc.stdlib cimport malloc From e3639f5ca623b92ba0c74af34a9c372197108e82 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 26 Aug 2024 13:50:58 -0600 Subject: [PATCH 62/70] set default prop_data to int --- landlab/ca/celllab_cts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/landlab/ca/celllab_cts.py b/landlab/ca/celllab_cts.py index b7bded600b..d3b1171654 100644 --- a/landlab/ca/celllab_cts.py +++ b/landlab/ca/celllab_cts.py @@ -471,8 +471,8 @@ def __init__( # are tracked. self.propid = np.arange(self.grid.number_of_nodes) if prop_data is None: - self.prop_data = np.zeros(self.grid.number_of_nodes) - self.prop_reset_value = 0.0 + self.prop_data = np.zeros(self.grid.number_of_nodes, dtype=int) + self.prop_reset_value = 0 else: self.prop_data = prop_data self.prop_reset_value = prop_reset_value From 52552fbab979c6d52c60ed338605f9879f8d9d9f Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 26 Aug 2024 13:51:29 -0600 Subject: [PATCH 63/70] add additional types to celllab_cts cython functions --- landlab/ca/cfuncs.pyx | 49 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index 7baec0f67e..d8348aa0a5 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -186,7 +186,7 @@ cpdef update_link_states_and_transitions( int8_t [:] bnd_lnk, id_t [:] link_state, id_t [:] n_xn, - event_queue, + Event [:] event_queue, cython.floating [:] next_update, id_t [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -194,7 +194,7 @@ cpdef update_link_states_and_transitions( long num_node_states_sq, double current_time, int8_t [:, :] xn_propswap, - np.ndarray[object, ndim=2] xn_prop_update_fn, + object [:, :] xn_prop_update_fn, ): """ Following an "external" change to the node state grid, updates link @@ -350,7 +350,7 @@ cpdef get_next_event( id_t [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, - xn_prop_update_fn, + object [:, :] xn_prop_update_fn, ): """Get the next event for a link. @@ -527,12 +527,12 @@ cdef void update_link_state( long num_node_states_sq, id_t [:] link_state, id_t [:] n_xn, - event_queue, + Event [:] event_queue, cython.floating [:] next_update, id_t [:, :] xn_to, cython.floating [:, :] xn_rate, int8_t [:, :] xn_propswap, - np.ndarray[object, ndim=2] xn_prop_update_fn, + object [:, :] xn_prop_update_fn, ): """ Implements a link transition by updating the current state of the link @@ -659,7 +659,7 @@ cdef void do_transition( uint8_t [:] status_at_node, int8_t [:] link_orientation, id_t [:] propid, - object prop_data, + cython.integral [:] prop_data, id_t [:] n_xn, id_t [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -667,12 +667,11 @@ cdef void do_transition( const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, - prop_reset_value, + long prop_reset_value, int8_t [:, :] xn_propswap, - # xn_prop_update_fn, - np.ndarray[object, ndim=2] xn_prop_update_fn, + object [:, :] xn_prop_update_fn, int8_t [:] bnd_lnk, - event_queue, + Event [:] event_queue, this_cts_model, plot_each_transition=False, plotter=None, @@ -885,9 +884,9 @@ cpdef void do_transition_new( const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, id_t [:] propid, - object prop_data, - prop_reset_value, - object trn_prop_update_fn, + cython.integral [:] prop_data, + long prop_reset_value, + object [:] trn_prop_update_fn, object this_cts_model, plot_each_transition=False, plotter=None, @@ -1133,9 +1132,9 @@ cpdef double run_cts_new( const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, id_t [:] propid, - object prop_data, - prop_reset_value, - trn_prop_update_fn, + cython.integral [:] prop_data, + long prop_reset_value, + object [:] trn_prop_update_fn, this_cts_model, char plot_each_transition, object plotter, @@ -1217,7 +1216,7 @@ cpdef double run_cts( double current_time, char plot_each_transition, object plotter, - object event_queue, + Event [:] event_queue, cython.floating [:] next_update, id_t [:] node_at_link_tail, id_t [:] node_at_link_head, @@ -1226,7 +1225,7 @@ cpdef double run_cts( uint8_t [:] status_at_node, int8_t [:] link_orientation, id_t [:] propid, - object prop_data, + cython.integral [:] prop_data, id_t [:] n_xn, id_t [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -1234,9 +1233,9 @@ cpdef double run_cts( const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, - prop_reset_value, + long prop_reset_value, int8_t [:, :] xn_propswap, - np.ndarray[object, ndim=2] xn_prop_update_fn, + object [:, :] xn_prop_update_fn, int8_t [:] bnd_lnk, this_cts_model, ): @@ -1257,7 +1256,7 @@ cpdef double run_cts( cdef Event ev # Continue until we've run out of either time or events - while current_time < run_to and event_queue: + while current_time < run_to and len(event_queue) > 0: # Is there an event scheduled to occur within this run? if event_queue[0].time <= run_to: @@ -1390,7 +1389,7 @@ cdef void update_link_state_lean( long num_node_states_sq, id_t [:] link_state, id_t [:] n_xn, - event_queue, + Event [:] event_queue, cython.floating [:] next_update, id_t [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -1453,7 +1452,7 @@ cdef void do_transition_lean( long num_node_states, long num_node_states_sq, int8_t [:] bnd_lnk, - object event_queue, + Event [:] event_queue, ): """Transition state. @@ -1613,7 +1612,7 @@ cdef void do_transition_lean( cpdef double run_cts_lean( double run_to, double current_time, - object event_queue, + Event [:] event_queue, cython.floating [:] next_update, id_t [:] node_at_link_tail, id_t [:] node_at_link_head, @@ -1642,7 +1641,7 @@ cpdef double run_cts_lean( cdef Event ev # Continue until we've run out of either time or events - while current_time < run_to and event_queue: + while current_time < run_to and len(event_queue) > 0: # Is there an event scheduled to occur within this run? if event_queue[0].time <= run_to: From 45934d95dd84daf906db1317c0e47b4b29521317 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Mon, 26 Aug 2024 15:50:03 -0600 Subject: [PATCH 64/70] allow prop_data to be either float or int --- landlab/ca/cfuncs.pyx | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index d8348aa0a5..c3ebca99d4 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -21,6 +21,12 @@ ctypedef fused id_t: long long +ctypedef fused int_or_float_t: + cython.floating + cython.integral + long long + + cdef double _NEVER = 1.0e50 cdef int _CORE = NodeStatus.CORE cdef char _DEBUG = 0 @@ -659,7 +665,7 @@ cdef void do_transition( uint8_t [:] status_at_node, int8_t [:] link_orientation, id_t [:] propid, - cython.integral [:] prop_data, + int_or_float_t [:] prop_data, id_t [:] n_xn, id_t [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -667,7 +673,7 @@ cdef void do_transition( const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, - long prop_reset_value, + int_or_float_t prop_reset_value, int8_t [:, :] xn_propswap, object [:, :] xn_prop_update_fn, int8_t [:] bnd_lnk, @@ -884,8 +890,8 @@ cpdef void do_transition_new( const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, id_t [:] propid, - cython.integral [:] prop_data, - long prop_reset_value, + int_or_float_t [:] prop_data, + int_or_float_t prop_reset_value, object [:] trn_prop_update_fn, object this_cts_model, plot_each_transition=False, @@ -1132,8 +1138,8 @@ cpdef double run_cts_new( const int8_t [:, :] active_link_dirs_at_node, int8_t [:] trn_propswap, id_t [:] propid, - cython.integral [:] prop_data, - long prop_reset_value, + int_or_float_t [:] prop_data, + int_or_float_t prop_reset_value, object [:] trn_prop_update_fn, this_cts_model, char plot_each_transition, @@ -1225,7 +1231,7 @@ cpdef double run_cts( uint8_t [:] status_at_node, int8_t [:] link_orientation, id_t [:] propid, - cython.integral [:] prop_data, + int_or_float_t [:] prop_data, id_t [:] n_xn, id_t [:, :] xn_to, cython.floating [:, :] xn_rate, @@ -1233,7 +1239,7 @@ cpdef double run_cts( const int8_t [:, :] active_link_dirs_at_node, long num_node_states, long num_node_states_sq, - long prop_reset_value, + int_or_float_t prop_reset_value, int8_t [:, :] xn_propswap, object [:, :] xn_prop_update_fn, int8_t [:] bnd_lnk, From ab880587e4a8a15e72410dba82becddda4e5dcaa Mon Sep 17 00:00:00 2001 From: mcflugen Date: Tue, 27 Aug 2024 13:21:24 -0600 Subject: [PATCH 65/70] add link to cython fused types [skip ci] --- landlab/ca/cfuncs.pyx | 1 + landlab/components/bedrock_landslider/cfuncs.pyx | 1 + landlab/components/depression_finder/cfuncs.pyx | 1 + landlab/components/drainage_density/cfuncs.pyx | 1 + landlab/components/erosion_deposition/cfuncs.pyx | 1 + landlab/components/flexure/_ext/flexure2d.pyx | 1 + landlab/components/flow_accum/cfuncs.pyx | 1 + landlab/components/flow_director/cfuncs.pyx | 1 + landlab/components/overland_flow/_neighbors_at_link.pyx | 1 + landlab/components/priority_flood_flow_router/cfuncs.pyx | 1 + landlab/components/space/ext/calc_qs.pyx | 1 + landlab/components/space/ext/calc_sequential_ero_depo.pyx | 1 + landlab/components/stream_power/cfuncs.pyx | 1 + landlab/components/threshold_eroder/cfuncs.pyx | 1 + landlab/graph/hex/ext/hex.pyx | 1 + landlab/graph/hex/ext/perimeternodes.pyx | 1 + landlab/graph/matrix/ext/at_patch.pyx | 1 + landlab/graph/matrix/ext/matrix.pyx | 1 + landlab/graph/object/ext/at_node.pyx | 1 + landlab/graph/object/ext/at_patch.pyx | 1 + landlab/graph/quantity/ext/of_element.pyx | 1 + landlab/graph/quantity/ext/of_link.pyx | 1 + landlab/graph/quantity/ext/of_patch.pyx | 1 + landlab/graph/sort/ext/argsort.pxd | 1 + landlab/graph/sort/ext/remap_element.pyx | 1 + landlab/graph/sort/ext/spoke_sort.pyx | 1 + landlab/graph/structured_quad/ext/at_cell.pyx | 1 + landlab/graph/structured_quad/ext/at_face.pyx | 1 + landlab/graph/structured_quad/ext/at_link.pyx | 1 + landlab/graph/structured_quad/ext/at_node.pyx | 1 + landlab/graph/structured_quad/ext/at_patch.pyx | 1 + landlab/graph/voronoi/ext/delaunay.pyx | 1 + landlab/graph/voronoi/ext/voronoi.pyx | 1 + landlab/grid/ext/raster_divergence.pyx | 1 + landlab/grid/ext/raster_gradient.pyx | 1 + landlab/layers/ext/eventlayers.pyx | 1 + landlab/utils/_matrix.pyx | 1 + 37 files changed, 37 insertions(+) diff --git a/landlab/ca/cfuncs.pyx b/landlab/ca/cfuncs.pyx index c3ebca99d4..321aec4651 100644 --- a/landlab/ca/cfuncs.pyx +++ b/landlab/ca/cfuncs.pyx @@ -16,6 +16,7 @@ from _heapq import heappush from landlab.grid.nodestatus import NodeStatus +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/bedrock_landslider/cfuncs.pyx b/landlab/components/bedrock_landslider/cfuncs.pyx index d0c5e740df..af89c2070b 100755 --- a/landlab/components/bedrock_landslider/cfuncs.pyx +++ b/landlab/components/bedrock_landslider/cfuncs.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/depression_finder/cfuncs.pyx b/landlab/components/depression_finder/cfuncs.pyx index 157d9e821d..aca328b526 100644 --- a/landlab/components/depression_finder/cfuncs.pyx +++ b/landlab/components/depression_finder/cfuncs.pyx @@ -2,6 +2,7 @@ cimport cython from landlab.core.messages import warning_message +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/drainage_density/cfuncs.pyx b/landlab/components/drainage_density/cfuncs.pyx index 1581b82063..59e41ae672 100644 --- a/landlab/components/drainage_density/cfuncs.pyx +++ b/landlab/components/drainage_density/cfuncs.pyx @@ -1,6 +1,7 @@ cimport cython from libc.stdint cimport uint8_t +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/erosion_deposition/cfuncs.pyx b/landlab/components/erosion_deposition/cfuncs.pyx index e9ba7dc429..d151b22c96 100644 --- a/landlab/components/erosion_deposition/cfuncs.pyx +++ b/landlab/components/erosion_deposition/cfuncs.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/flexure/_ext/flexure2d.pyx b/landlab/components/flexure/_ext/flexure2d.pyx index 852d244bcc..826444b213 100644 --- a/landlab/components/flexure/_ext/flexure2d.pyx +++ b/landlab/components/flexure/_ext/flexure2d.pyx @@ -3,6 +3,7 @@ from cython.parallel cimport prange from libc.math cimport M_PI from libc.stdlib cimport labs +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused index_t: cython.integral long long diff --git a/landlab/components/flow_accum/cfuncs.pyx b/landlab/components/flow_accum/cfuncs.pyx index 466f2b128a..0c0ae3c94e 100644 --- a/landlab/components/flow_accum/cfuncs.pyx +++ b/landlab/components/flow_accum/cfuncs.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/flow_director/cfuncs.pyx b/landlab/components/flow_director/cfuncs.pyx index 776be880ac..314592156b 100644 --- a/landlab/components/flow_director/cfuncs.pyx +++ b/landlab/components/flow_director/cfuncs.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/overland_flow/_neighbors_at_link.pyx b/landlab/components/overland_flow/_neighbors_at_link.pyx index b78cb0f588..dabcbc518e 100644 --- a/landlab/components/overland_flow/_neighbors_at_link.pyx +++ b/landlab/components/overland_flow/_neighbors_at_link.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/priority_flood_flow_router/cfuncs.pyx b/landlab/components/priority_flood_flow_router/cfuncs.pyx index e8386a6d90..2ab9a36eaf 100644 --- a/landlab/components/priority_flood_flow_router/cfuncs.pyx +++ b/landlab/components/priority_flood_flow_router/cfuncs.pyx @@ -3,6 +3,7 @@ import numpy as np cimport numpy as np +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/space/ext/calc_qs.pyx b/landlab/components/space/ext/calc_qs.pyx index fb8a56a3de..8729a46e7b 100644 --- a/landlab/components/space/ext/calc_qs.pyx +++ b/landlab/components/space/ext/calc_qs.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/space/ext/calc_sequential_ero_depo.pyx b/landlab/components/space/ext/calc_sequential_ero_depo.pyx index d1a9d91da7..f201ddeabd 100644 --- a/landlab/components/space/ext/calc_sequential_ero_depo.pyx +++ b/landlab/components/space/ext/calc_sequential_ero_depo.pyx @@ -3,6 +3,7 @@ from libc.math cimport exp from libc.math cimport isinf from libc.math cimport log +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/stream_power/cfuncs.pyx b/landlab/components/stream_power/cfuncs.pyx index 34c3f9f414..cec7df4678 100644 --- a/landlab/components/stream_power/cfuncs.pyx +++ b/landlab/components/stream_power/cfuncs.pyx @@ -8,6 +8,7 @@ from scipy.optimize import newton # method for using the brentq method in cython. from scipy.optimize._zeros import _brentq as brentq +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/components/threshold_eroder/cfuncs.pyx b/landlab/components/threshold_eroder/cfuncs.pyx index 7282899c4a..4fbb2b369e 100644 --- a/landlab/components/threshold_eroder/cfuncs.pyx +++ b/landlab/components/threshold_eroder/cfuncs.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/hex/ext/hex.pyx b/landlab/graph/hex/ext/hex.pyx index c2dfcea397..0fd30334b6 100644 --- a/landlab/graph/hex/ext/hex.pyx +++ b/landlab/graph/hex/ext/hex.pyx @@ -5,6 +5,7 @@ from cython.parallel import prange from libc.stdlib cimport free from libc.stdlib cimport malloc +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/hex/ext/perimeternodes.pyx b/landlab/graph/hex/ext/perimeternodes.pyx index a5f79c1a6e..69ddc30fc5 100644 --- a/landlab/graph/hex/ext/perimeternodes.pyx +++ b/landlab/graph/hex/ext/perimeternodes.pyx @@ -2,6 +2,7 @@ cimport cython from libc.stdlib cimport free from libc.stdlib cimport malloc +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/matrix/ext/at_patch.pyx b/landlab/graph/matrix/ext/at_patch.pyx index 01f7dcfa66..03dfacb470 100644 --- a/landlab/graph/matrix/ext/at_patch.pyx +++ b/landlab/graph/matrix/ext/at_patch.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/matrix/ext/matrix.pyx b/landlab/graph/matrix/ext/matrix.pyx index 9421302210..b9d5c34506 100644 --- a/landlab/graph/matrix/ext/matrix.pyx +++ b/landlab/graph/matrix/ext/matrix.pyx @@ -5,6 +5,7 @@ from libc.stdlib cimport malloc from libc.string cimport memcpy from libc.string cimport memmove +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/object/ext/at_node.pyx b/landlab/graph/object/ext/at_node.pyx index 7e0ee5ed2d..657eb2c293 100644 --- a/landlab/graph/object/ext/at_node.pyx +++ b/landlab/graph/object/ext/at_node.pyx @@ -7,6 +7,7 @@ from libc.stdlib cimport free from libc.stdlib cimport malloc import numpy as np +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused float_or_int: cython.floating cython.integral diff --git a/landlab/graph/object/ext/at_patch.pyx b/landlab/graph/object/ext/at_patch.pyx index becbc5c989..2ca1acc1d5 100644 --- a/landlab/graph/object/ext/at_patch.pyx +++ b/landlab/graph/object/ext/at_patch.pyx @@ -2,6 +2,7 @@ cimport cython from cython.parallel cimport prange from libc.stdint cimport int8_t +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused float_or_int: cython.floating cython.integral diff --git a/landlab/graph/quantity/ext/of_element.pyx b/landlab/graph/quantity/ext/of_element.pyx index 8f0621bf36..4f0a74e134 100644 --- a/landlab/graph/quantity/ext/of_element.pyx +++ b/landlab/graph/quantity/ext/of_element.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel import prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/quantity/ext/of_link.pyx b/landlab/graph/quantity/ext/of_link.pyx index ed56be3bf6..af79a19c17 100644 --- a/landlab/graph/quantity/ext/of_link.pyx +++ b/landlab/graph/quantity/ext/of_link.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/quantity/ext/of_patch.pyx b/landlab/graph/quantity/ext/of_patch.pyx index 93ee6da50c..7b31eb248d 100644 --- a/landlab/graph/quantity/ext/of_patch.pyx +++ b/landlab/graph/quantity/ext/of_patch.pyx @@ -3,6 +3,7 @@ from cython.parallel cimport prange from libc.stdlib cimport free from libc.stdlib cimport malloc +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/sort/ext/argsort.pxd b/landlab/graph/sort/ext/argsort.pxd index 31063b2e45..bddf67893a 100644 --- a/landlab/graph/sort/ext/argsort.pxd +++ b/landlab/graph/sort/ext/argsort.pxd @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index efcf8a14ba..ea32b65abf 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -15,6 +15,7 @@ cdef extern from "math.h": from .spoke_sort import sort_spokes_at_wheel +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/sort/ext/spoke_sort.pyx b/landlab/graph/sort/ext/spoke_sort.pyx index 4d59bc7a72..f4223c153e 100644 --- a/landlab/graph/sort/ext/spoke_sort.pyx +++ b/landlab/graph/sort/ext/spoke_sort.pyx @@ -9,6 +9,7 @@ from libc.stdlib cimport malloc from .argsort cimport argsort_flt +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/structured_quad/ext/at_cell.pyx b/landlab/graph/structured_quad/ext/at_cell.pyx index 053aa5a6a7..5af447fb30 100644 --- a/landlab/graph/structured_quad/ext/at_cell.pyx +++ b/landlab/graph/structured_quad/ext/at_cell.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/structured_quad/ext/at_face.pyx b/landlab/graph/structured_quad/ext/at_face.pyx index bdbf884046..8e193aab29 100644 --- a/landlab/graph/structured_quad/ext/at_face.pyx +++ b/landlab/graph/structured_quad/ext/at_face.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/structured_quad/ext/at_link.pyx b/landlab/graph/structured_quad/ext/at_link.pyx index cc6564b393..6d21c9f462 100644 --- a/landlab/graph/structured_quad/ext/at_link.pyx +++ b/landlab/graph/structured_quad/ext/at_link.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/structured_quad/ext/at_node.pyx b/landlab/graph/structured_quad/ext/at_node.pyx index 8b7642f6fd..7d2516a54f 100644 --- a/landlab/graph/structured_quad/ext/at_node.pyx +++ b/landlab/graph/structured_quad/ext/at_node.pyx @@ -2,6 +2,7 @@ cimport cython from cython.parallel cimport prange from libc.stdint cimport int8_t +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/structured_quad/ext/at_patch.pyx b/landlab/graph/structured_quad/ext/at_patch.pyx index 4a5c1942f3..1dbb7ef6f6 100644 --- a/landlab/graph/structured_quad/ext/at_patch.pyx +++ b/landlab/graph/structured_quad/ext/at_patch.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/voronoi/ext/delaunay.pyx b/landlab/graph/voronoi/ext/delaunay.pyx index e26b17d810..fa2f728c26 100644 --- a/landlab/graph/voronoi/ext/delaunay.pyx +++ b/landlab/graph/voronoi/ext/delaunay.pyx @@ -2,6 +2,7 @@ cimport cython from libc.stdlib cimport free from libc.stdlib cimport malloc +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/graph/voronoi/ext/voronoi.pyx b/landlab/graph/voronoi/ext/voronoi.pyx index f9e36ea73c..bd735cc719 100644 --- a/landlab/graph/voronoi/ext/voronoi.pyx +++ b/landlab/graph/voronoi/ext/voronoi.pyx @@ -4,6 +4,7 @@ from cython.parallel import prange from libc.stdint cimport uint8_t +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/grid/ext/raster_divergence.pyx b/landlab/grid/ext/raster_divergence.pyx index c7fa71a644..3b85173b0b 100644 --- a/landlab/grid/ext/raster_divergence.pyx +++ b/landlab/grid/ext/raster_divergence.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused float_or_int: cython.integral long long diff --git a/landlab/grid/ext/raster_gradient.pyx b/landlab/grid/ext/raster_gradient.pyx index 4d2816c10a..2fd776f07e 100644 --- a/landlab/grid/ext/raster_gradient.pyx +++ b/landlab/grid/ext/raster_gradient.pyx @@ -1,6 +1,7 @@ cimport cython from cython.parallel cimport prange +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused float_or_int: cython.integral long long diff --git a/landlab/layers/ext/eventlayers.pyx b/landlab/layers/ext/eventlayers.pyx index 4324d29ba5..9802c46467 100644 --- a/landlab/layers/ext/eventlayers.pyx +++ b/landlab/layers/ext/eventlayers.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long diff --git a/landlab/utils/_matrix.pyx b/landlab/utils/_matrix.pyx index 6860cc82df..378cda3f4d 100644 --- a/landlab/utils/_matrix.pyx +++ b/landlab/utils/_matrix.pyx @@ -1,5 +1,6 @@ cimport cython +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html ctypedef fused id_t: cython.integral long long From abce01ae19f33f0590b37faeaaa38cba11c0f4eb Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sat, 31 Aug 2024 11:03:21 -0600 Subject: [PATCH 66/70] reorganize intpair, sparse matrix cython code --- landlab/graph/sort/ext/_deprecated_sparse.pyx | 255 ++++++++++++++++++ landlab/graph/sort/ext/intpair.pyx | 175 ++++++++++++ landlab/graph/sort/ext/remap_element.pyx | 243 ----------------- setup.py | 2 + tests/graph/sort/test_intpair.py | 37 ++- 5 files changed, 468 insertions(+), 244 deletions(-) create mode 100644 landlab/graph/sort/ext/_deprecated_sparse.pyx create mode 100644 landlab/graph/sort/ext/intpair.pyx diff --git a/landlab/graph/sort/ext/_deprecated_sparse.pyx b/landlab/graph/sort/ext/_deprecated_sparse.pyx new file mode 100644 index 0000000000..0d35d965ec --- /dev/null +++ b/landlab/graph/sort/ext/_deprecated_sparse.pyx @@ -0,0 +1,255 @@ +cimport cython +from libc.stdint cimport uint8_t +from libc.stdlib cimport free +from libc.stdlib cimport malloc + +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html +ctypedef fused id_t: + cython.integral + long long + +ctypedef fused integral_out_t: + cython.integral + long long + + +cdef struct SparseMatrixInt: + long *values + long n_values + long *offset_to_row + long *col + long col_start + long col_stride + long n_rows + long n_cols + long no_val + + +cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( + const id_t [:] rows_and_cols, + const integral_out_t [:] values, + long n_values, + long no_val, +): + cdef long n_rows + cdef long n_cols + cdef long max_row = 0 + cdef long max_col = 0 + cdef long i + cdef SparseMatrixInt mat + cdef long * col_ptr + cdef long * values_ptr + cdef long * offset_ptr + cdef long [:] offset_array + + for i in range(0, n_values * 2, 2): + if rows_and_cols[i] > max_row: + max_row = rows_and_cols[i] + if rows_and_cols[i + 1] > max_col: + max_col = rows_and_cols[i + 1] + n_rows = max_row + 1 + n_cols = max_col + 1 + + offset_ptr = malloc((n_rows + 1) * sizeof(long)) + offset_array = offset_ptr + + col_ptr = malloc((2 * n_values) * sizeof(long)) + values_ptr = malloc(n_values * sizeof(long)) + for i in range(2 * n_values): + col_ptr[i] = rows_and_cols[i] + for i in range(n_values): + values_ptr[i] = values[i] + + _offset_to_sorted_blocks(rows_and_cols, n_values, 2, offset_array, n_rows + 1) + + mat.values = values_ptr + mat.n_values = n_values + mat.offset_to_row = offset_ptr + mat.col = col_ptr + mat.col_start = 1 + mat.col_stride = 2 + mat.n_rows = n_rows + mat.n_cols = n_cols + mat.no_val = no_val + + return mat + + +cdef sparse_matrix_free(SparseMatrixInt mat): + free(mat.offset_to_row) + free(mat.col) + free(mat.values) + + +cdef long sparse_matrix_get_or_transpose(SparseMatrixInt mat, long row, long col): + cdef long val + val = sparse_matrix_get(mat, row, col) + if val == mat.no_val: + val = sparse_matrix_get(mat, col, row) + return val + + +cdef long sparse_matrix_get(SparseMatrixInt mat, long row, long col): + cdef long start + cdef long stop + cdef long n + cdef long i + + if row < 0: + return mat.no_val + elif row >= mat.n_rows: + return mat.no_val + elif col < 0: + return mat.no_val + elif col >= mat.n_cols: + return mat.no_val + + start = mat.offset_to_row[row] + stop = mat.offset_to_row[row + 1] + + i = mat.col_start + start * mat.col_stride + for n in range(start, stop): + if mat.col[i] == col: + return mat.values[n] + i += mat.col_stride + + return mat.no_val + + +cdef void _offset_to_sorted_blocks( + const id_t [:] array, + long len, + long stride, + integral_out_t [:] offset, + long n_values, +) noexcept: + cdef long i + cdef long value + cdef long first_non_negative + + first_non_negative = len * stride + for i in range(0, len * stride, stride): + if array[i] >= 0: + first_non_negative = i + break + + offset[0] = first_non_negative + for value in range(1, n_values): + offset[value] = offset[value - 1] + for i in range(offset[value], len * stride, stride): + if array[i] >= value: + offset[value] = i + break + else: + offset[value] = len * stride + + for value in range(n_values): + offset[value] = offset[value] // stride + + +@cython.boundscheck(False) +@cython.wraparound(False) +def offset_to_sorted_block( + id_t [:, :] sorted_ids, + integral_out_t [:] offset_to_block, +): + cdef long n_ids = sorted_ids.shape[0] + cdef long n_blocks = offset_to_block.shape[0] + cdef id_t *ptr = &sorted_ids[0, 0] + cdef id_t [:] sorted_ids_flat = ptr + + _offset_to_sorted_blocks( + sorted_ids_flat, + n_ids, + sorted_ids.shape[1], + offset_to_block, + n_blocks, + ) + + +@cython.boundscheck(False) +@cython.wraparound(False) +def pair_isin( + const id_t [:, :] src_pairs, + const id_t [:, :] pairs, + uint8_t [:] out, +): + cdef long pair + cdef long n_pairs = pairs.shape[0] + cdef long n_values = src_pairs.shape[0] + cdef long * data_ptr = malloc(n_values * sizeof(long)) + cdef long [:] data_array = data_ptr + cdef const id_t *ptr = &src_pairs[0, 0] + cdef const id_t [:] src_pairs_flat = ptr + cdef SparseMatrixInt mat + + for n in range(n_values): + data_array[n] = 1 + + try: + mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data_array, n_values, 0) + for pair in range(n_pairs): + out[pair] = sparse_matrix_get_or_transpose( + mat, pairs[pair, 0], pairs[pair, 1] + ) + finally: + free(data_ptr) + + +@cython.boundscheck(False) +@cython.wraparound(False) +def map_pairs_to_values( + const id_t [:, :] src_pairs, + const integral_out_t [:] data, + const id_t [:, :] pairs, + integral_out_t [:] out, +): + cdef long pair + cdef long n_pairs = out.shape[0] + cdef long n_values = data.shape[0] + cdef const id_t *ptr = &src_pairs[0, 0] + cdef const id_t [:] src_pairs_flat = ptr + cdef SparseMatrixInt mat + + mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) + + for pair in range(n_pairs): + out[pair] = sparse_matrix_get_or_transpose(mat, pairs[pair, 0], pairs[pair, 1]) + + +@cython.boundscheck(False) +@cython.wraparound(False) +def map_rolling_pairs_to_values( + const id_t [:, :] src_pairs, + const integral_out_t [:] data, + const id_t [:, :] pairs, + const id_t [:] size_of_row, + integral_out_t [:, :] out, +): + cdef long n_values = data.shape[0] + cdef long n_pairs = pairs.shape[0] + cdef long pair + cdef const id_t *ptr = &src_pairs[0, 0] + cdef const id_t [:] src_pairs_flat = ptr + cdef SparseMatrixInt mat + + mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) + + for pair in range(n_pairs): + _map_rolling_pairs(mat, pairs[pair, :], out[pair, :], size_of_row[pair]) + + +cdef _map_rolling_pairs( + SparseMatrixInt mat, + const id_t [:] pairs, + integral_out_t [:] out, + long size, +): + cdef long n + + if size > 0: + for n in range(size - 1): + out[n] = sparse_matrix_get_or_transpose(mat, pairs[n], pairs[n + 1]) + + n = size - 1 + out[n] = sparse_matrix_get_or_transpose(mat, pairs[n], pairs[0]) diff --git a/landlab/graph/sort/ext/intpair.pyx b/landlab/graph/sort/ext/intpair.pyx new file mode 100644 index 0000000000..4d256a9133 --- /dev/null +++ b/landlab/graph/sort/ext/intpair.pyx @@ -0,0 +1,175 @@ +cimport cython + +from cython.parallel import prange + +# https://cython.readthedocs.io/en/stable/src/userguide/fusedtypes.html +ctypedef fused id_t: + cython.integral + long long + + +ctypedef fused integral_out_t: + cython.integral + long long + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef void fill_offsets_to_sorted_blocks( + const id_t [:] array, + integral_out_t [:] offsets, +) noexcept nogil: + cdef long n_values = len(array) + cdef long n_offsets = len(offsets) + cdef long first_non_negative + cdef long i + cdef long j + + for i in range(0, n_values): + if array[i] >= 0: + first_non_negative = i + break + else: + first_non_negative = n_values + + offsets[0] = first_non_negative + for i in range(1, n_offsets): + offsets[i] = offsets[i - 1] + for j in range(offsets[i], n_values): + if array[j] >= i: + offsets[i] = j + break + else: + offsets[i] = n_values + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef void find_pairs( + const id_t [:, :] array, + const integral_out_t [:] offsets, + const id_t [:, :] pairs, + id_t [:] where, +) noexcept nogil: + cdef long n_pairs = len(pairs) + cdef long pair + cdef long first + cdef long second + cdef long ind + + for pair in prange(n_pairs, nogil=True, schedule="static"): + first = pairs[pair, 0] + second = pairs[pair, 1] + + ind = find_pair(array, offsets, first, second) + if ind == -1: + ind = find_pair(array, offsets, second, first) + + where[pair] = ind + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef void find_rolling_pairs( + const id_t [:, :] array, + const integral_out_t [:] offsets, + const id_t [:] pairs, + id_t [:] where, + const int wraparound, +) noexcept nogil: + cdef long n_pairs = len(pairs) + cdef long first + cdef long second + cdef long i + cdef long ind + + for i in range(n_pairs - 1): + first = pairs[i] + second = pairs[i + 1] + + ind = find_pair(array, offsets, first, second) + if ind == -1: + ind = find_pair(array, offsets, second, first) + + where[i] = ind + + if wraparound: + first = pairs[n_pairs - 1] + second = pairs[0] + + ind = find_pair(array, offsets, first, second) + if ind == -1: + ind = find_pair(array, offsets, second, first) + + where[n_pairs - 1] = ind + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef void find_rolling_pairs_2d( + const id_t [:, :] array, + const integral_out_t [:] offsets, + const id_t [:, :] pairs, + id_t [:, :] where, + const int wraparound, +) noexcept nogil: + cdef long n_rows = len(pairs) + cdef long n_cols = pairs.shape[1] + cdef long length_of_row + cdef long row + + for row in prange(n_rows, nogil=True, schedule="static"): + length_of_row = find_first(pairs[row, :], -1) + if length_of_row == -1: + length_of_row = n_cols + + if length_of_row > 1: + find_rolling_pairs( + array, + offsets, + pairs[row, :length_of_row], + where[row, :length_of_row], + wraparound, + ) + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef long find_pair( + const id_t [:, :] pairs, + const integral_out_t [:] offsets, + const long a, + const long b, +) noexcept nogil: + cdef long n_offsets = len(offsets) + cdef long start + cdef long stop + cdef long ind + + if a + 1 >= n_offsets: + return -1 + + start = offsets[a] + stop = offsets[a + 1] + + ind = find_first(pairs[start:stop, 1], b) + if ind >= 0: + ind += start + + return ind + + +@cython.boundscheck(False) +@cython.wraparound(False) +cpdef long find_first( + const id_t [:] array, + const id_t value, +) noexcept nogil: + cdef long n_values = len(array) + cdef long i + + for i in range(n_values): + if array[i] == value: + return i + else: + return -1 diff --git a/landlab/graph/sort/ext/remap_element.pyx b/landlab/graph/sort/ext/remap_element.pyx index ea32b65abf..0eb8b7255c 100644 --- a/landlab/graph/sort/ext/remap_element.pyx +++ b/landlab/graph/sort/ext/remap_element.pyx @@ -4,7 +4,6 @@ import numpy as np from cython.parallel import prange cimport numpy as np -from libc.stdint cimport uint8_t from libc.stdlib cimport free from libc.stdlib cimport malloc @@ -228,245 +227,3 @@ def reverse_element_order( break n = n + 1 reverse_order(&links_at_patch[patch, 1], n - 1) - - -cdef void _offset_to_sorted_blocks( - const id_t [:] array, - long len, - long stride, - integral_out_t [:] offset, - long n_values, -) noexcept: - cdef long i - cdef long value - cdef long first_non_negative - - first_non_negative = len * stride - for i in range(0, len * stride, stride): - if array[i] >= 0: - first_non_negative = i - break - - offset[0] = first_non_negative - for value in range(1, n_values): - offset[value] = offset[value - 1] - for i in range(offset[value], len * stride, stride): - if array[i] >= value: - offset[value] = i - break - else: - offset[value] = len * stride - - for value in range(n_values): - offset[value] = offset[value] // stride - - -@cython.boundscheck(False) -@cython.wraparound(False) -def offset_to_sorted_block( - id_t [:, :] sorted_ids, - integral_out_t [:] offset_to_block, -): - cdef long n_ids = sorted_ids.shape[0] - cdef long n_blocks = offset_to_block.shape[0] - cdef id_t *ptr = &sorted_ids[0, 0] - cdef id_t [:] sorted_ids_flat = ptr - - _offset_to_sorted_blocks( - sorted_ids_flat, - n_ids, - sorted_ids.shape[1], - offset_to_block, - n_blocks, - ) - - -@cython.boundscheck(False) -@cython.wraparound(False) -def pair_isin( - const id_t [:, :] src_pairs, - const id_t [:, :] pairs, - uint8_t [:] out, -): - cdef long pair - cdef long n_pairs = pairs.shape[0] - cdef long n_values = src_pairs.shape[0] - cdef long * data_ptr = malloc(n_values * sizeof(long)) - cdef long [:] data_array = data_ptr - cdef const id_t *ptr = &src_pairs[0, 0] - cdef const id_t [:] src_pairs_flat = ptr - cdef SparseMatrixInt mat - - for n in range(n_values): - data_array[n] = 1 - - try: - mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data_array, n_values, 0) - for pair in range(n_pairs): - out[pair] = sparse_matrix_get_or_transpose( - mat, pairs[pair, 0], pairs[pair, 1] - ) - finally: - free(data_ptr) - - -@cython.boundscheck(False) -@cython.wraparound(False) -def map_pairs_to_values( - const id_t [:, :] src_pairs, - const integral_out_t [:] data, - const id_t [:, :] pairs, - integral_out_t [:] out, -): - cdef long pair - cdef long n_pairs = out.shape[0] - cdef long n_values = data.shape[0] - cdef const id_t *ptr = &src_pairs[0, 0] - cdef const id_t [:] src_pairs_flat = ptr - cdef SparseMatrixInt mat - - mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) - - for pair in range(n_pairs): - out[pair] = sparse_matrix_get_or_transpose(mat, pairs[pair, 0], pairs[pair, 1]) - - -@cython.boundscheck(False) -@cython.wraparound(False) -def map_rolling_pairs_to_values( - const id_t [:, :] src_pairs, - const integral_out_t [:] data, - const id_t [:, :] pairs, - const id_t [:] size_of_row, - integral_out_t [:, :] out, -): - cdef long n_values = data.shape[0] - cdef long n_pairs = pairs.shape[0] - cdef long pair - cdef const id_t *ptr = &src_pairs[0, 0] - cdef const id_t [:] src_pairs_flat = ptr - cdef SparseMatrixInt mat - - mat = sparse_matrix_alloc_with_tuple(src_pairs_flat, data, n_values, -1) - - for pair in range(n_pairs): - _map_rolling_pairs(mat, pairs[pair, :], out[pair, :], size_of_row[pair]) - - -cdef _map_rolling_pairs( - SparseMatrixInt mat, - const id_t [:] pairs, - integral_out_t [:] out, - long size, -): - cdef long n - - if size > 0: - for n in range(size - 1): - out[n] = sparse_matrix_get_or_transpose(mat, pairs[n], pairs[n + 1]) - - n = size - 1 - out[n] = sparse_matrix_get_or_transpose(mat, pairs[n], pairs[0]) - - -cdef struct SparseMatrixInt: - long *values - long n_values - long *offset_to_row - long *col - long col_start - long col_stride - long n_rows - long n_cols - long no_val - - -cdef SparseMatrixInt sparse_matrix_alloc_with_tuple( - const id_t [:] rows_and_cols, - const integral_out_t [:] values, - long n_values, - long no_val, -): - cdef long n_rows - cdef long n_cols - cdef long max_row = 0 - cdef long max_col = 0 - cdef long i - cdef SparseMatrixInt mat - cdef long * col_ptr - cdef long * values_ptr - cdef long * offset_ptr - cdef long [:] offset_array - - for i in range(0, n_values * 2, 2): - if rows_and_cols[i] > max_row: - max_row = rows_and_cols[i] - if rows_and_cols[i + 1] > max_col: - max_col = rows_and_cols[i + 1] - n_rows = max_row + 1 - n_cols = max_col + 1 - - offset_ptr = malloc((n_rows + 1) * sizeof(long)) - offset_array = offset_ptr - - col_ptr = malloc((2 * n_values) * sizeof(long)) - values_ptr = malloc(n_values * sizeof(long)) - for i in range(2 * n_values): - col_ptr[i] = rows_and_cols[i] - for i in range(n_values): - values_ptr[i] = values[i] - - _offset_to_sorted_blocks(rows_and_cols, n_values, 2, offset_array, n_rows + 1) - - mat.values = values_ptr - mat.n_values = n_values - mat.offset_to_row = offset_ptr - mat.col = col_ptr - mat.col_start = 1 - mat.col_stride = 2 - mat.n_rows = n_rows - mat.n_cols = n_cols - mat.no_val = no_val - - return mat - - -cdef sparse_matrix_free(SparseMatrixInt mat): - free(mat.offset_to_row) - free(mat.col) - free(mat.values) - - -cdef long sparse_matrix_get_or_transpose(SparseMatrixInt mat, long row, long col): - cdef long val - val = sparse_matrix_get(mat, row, col) - if val == mat.no_val: - val = sparse_matrix_get(mat, col, row) - return val - - -cdef long sparse_matrix_get(SparseMatrixInt mat, long row, long col): - cdef long start - cdef long stop - cdef long n - cdef long i - - if row < 0: - return mat.no_val - elif row >= mat.n_rows: - return mat.no_val - elif col < 0: - return mat.no_val - elif col >= mat.n_cols: - return mat.no_val - - start = mat.offset_to_row[row] - stop = mat.offset_to_row[row + 1] - - i = mat.col_start + start * mat.col_stride - for n in range(start, stop): - if mat.col[i] == col: - return mat.values[n] - i += mat.col_stride - - return mat.no_val diff --git a/setup.py b/setup.py index 98459ffbdb..2d61c4fe5a 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,9 @@ "landlab/graph/quantity/ext/of_element.pyx", "landlab/graph/quantity/ext/of_link.pyx", "landlab/graph/quantity/ext/of_patch.pyx", + "landlab/graph/sort/ext/_deprecated_sparse.pyx", "landlab/graph/sort/ext/argsort.pyx", + "landlab/graph/sort/ext/intpair.pyx", "landlab/graph/sort/ext/remap_element.pyx", "landlab/graph/sort/ext/spoke_sort.pyx", "landlab/graph/structured_quad/ext/at_cell.pyx", diff --git a/tests/graph/sort/test_intpair.py b/tests/graph/sort/test_intpair.py index 7c27db3368..66916d9d2f 100644 --- a/tests/graph/sort/test_intpair.py +++ b/tests/graph/sort/test_intpair.py @@ -1,12 +1,47 @@ import numpy as np from numpy.testing import assert_array_equal -from landlab.graph.sort.ext.remap_element import offset_to_sorted_block +from landlab.graph.sort.ext._deprecated_sparse import offset_to_sorted_block +from landlab.graph.sort.ext.intpair import fill_offsets_to_sorted_blocks from landlab.graph.sort.intpair import map_pairs_to_values from landlab.graph.sort.intpair import map_rolling_pairs_to_values from landlab.graph.sort.intpair import pair_isin +def test_fill_offsets(): + + array = [0, 2, 6, 7] + offsets = np.full(10, -2) + + fill_offsets_to_sorted_blocks(np.asarray(array), offsets) + + assert_array_equal(offsets, [0, 1, 1, 2, 2, 2, 2, 3, 4, 4]) + + array = [0, 2, 2, 2, 6, 7, 7] + offsets = np.full(10, -2) + fill_offsets_to_sorted_blocks(np.asarray(array), offsets) + + assert_array_equal(offsets, [0, 1, 1, 4, 4, 4, 4, 5, 7, 7]) + + actual = [] + for i in range(len(offsets) - 1): + actual += [i] * (offsets[i + 1] - offsets[i]) + + assert actual == array + + array = [0, 2, 6, 7] + offsets = np.full(5, -2) + fill_offsets_to_sorted_blocks(np.asarray(array), offsets) + + assert_array_equal(offsets, [0, 1, 1, 2, 2]) + + actual = [] + for i in range(len(offsets) - 1): + actual += [i] * (offsets[i + 1] - offsets[i]) + + assert actual == [0, 2] + + def test_pair_isin_one_pair(): src = np.asarray( [[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0]], dtype=int From 0d6f06525eb6f6d805f620e3de44c5a08dc87d97 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Sat, 31 Aug 2024 11:04:12 -0600 Subject: [PATCH 67/70] add class interface for intpair mappings --- landlab/graph/sort/intpair.py | 265 +++++++++++++++++++++++++++++++++- 1 file changed, 261 insertions(+), 4 deletions(-) diff --git a/landlab/graph/sort/intpair.py b/landlab/graph/sort/intpair.py index 7b4634c9df..c73018d5ae 100644 --- a/landlab/graph/sort/intpair.py +++ b/landlab/graph/sort/intpair.py @@ -1,13 +1,157 @@ +from collections.abc import Collection +from collections.abc import Iterable +from collections.abc import Mapping + import numpy as np +from numpy.typing import ArrayLike + +from landlab.graph.sort.ext.intpair import fill_offsets_to_sorted_blocks +from landlab.graph.sort.ext.intpair import find_pair +from landlab.graph.sort.ext.intpair import find_pairs +from landlab.graph.sort.ext.intpair import find_rolling_pairs_2d -from .ext.remap_element import map_pairs_to_values as _map_pairs_to_values -from .ext.remap_element import ( +from .ext._deprecated_sparse import map_pairs_to_values as _map_pairs_to_values +from .ext._deprecated_sparse import ( map_rolling_pairs_to_values as _map_rolling_pairs_to_values, ) -from .ext.remap_element import pair_isin as _pair_isin +from .ext._deprecated_sparse import pair_isin as _pair_isin + + +class IntPairs(Collection): + def __init__( + self, + pairs: ArrayLike, + sorter: ArrayLike | None = None, + sorted: bool = False, + ): + pairs = np.atleast_2d(pairs) + + if sorter is None and not sorted: + sorter = np.argsort(pairs[:, 0]) + + if sorter is not None: + pairs = pairs[sorter] + + self._data = pairs + self._offsets = np.empty(pairs.max() + 2, dtype=int) + + fill_offsets_to_sorted_blocks(self._data[:, 0], self._offsets) + + def __contains__(self, pair) -> bool: + pairs = np.atleast_2d(pair) + result = np.asarray([-1], dtype=int) + + find_pairs(self._data, self._offsets, pairs, result) + + return result[0] >= 0 + + def __len__(self) -> int: + return len(self._data) + + def __iter__(self) -> tuple[int, int]: + for pair in self._data: + yield tuple(pair) + + def _find_pairs(self, pairs, out=None, wraparound=False): + pairs = np.atleast_2d(pairs) + + if wraparound: + shape = (pairs.shape[0], pairs.shape[1]) + else: + shape = (pairs.shape[0], pairs.shape[1] - 1) + result = np.full(shape, -1, dtype=int) + + # find_pairs(self._data, self._offsets, pairs, result) + + find_rolling_pairs_2d(self._data, self._offsets, pairs, result, int(wraparound)) + + return result + + def contains_keys(self, pairs, wraparound=False): + return self._find_pairs(pairs, wraparound=wraparound) >= 0 + + +class IntPairMapping(Mapping, IntPairs): + def __init__( + self, + pairs: ArrayLike, + values: ArrayLike, + sorter: ArrayLike | None = None, + sorted: bool = False, + ) -> None: + pairs = np.atleast_2d(pairs) + + if sorter is None and not sorted: + sorter = np.argsort(pairs[:, 0]) + + if sorter is not None: + pairs = pairs[sorter] + values = values[sorter] + + self._values = values + self._data = pairs + self._offsets = np.empty(pairs.max() + 2, dtype=int) + + fill_offsets_to_sorted_blocks(self._data[:, 0], self._offsets) + + def __getitem__(self, key: Iterable[int]): + ind = find_pair(self._data, self._offsets, key[0], key[1]) + if ind == -1: + ind = find_pair(self._data, self._offsets, key[1], key[0]) + if ind == -1: + raise KeyError(key) + else: + return self._values[ind] + + def get_items(self, keys, out=None, wraparound=False): + keys = np.atleast_2d(keys) + + if wraparound: + shape = (keys.shape[0], keys.shape[1]) + else: + shape = (keys.shape[0], keys.shape[1] - 1) + + if out is None: + out = np.empty(shape, dtype=self._values.dtype) + + result = np.full(shape, -1, dtype=int) + + find_rolling_pairs_2d( + self._data, + self._offsets, + keys, + result, + int(wraparound), + ) + + out[:] = self._values[result] + out[result == -1] = -1 + + return out def pair_isin(src, pairs, out=None, sorter=None, sorted=False): + if not sorted and sorter is None: + sorter = np.argsort(src[:, 0]) + if sorter is not None: + src = src[sorter] + + offsets = np.empty(pairs.max() + 2, dtype=int) + fill_offsets_to_sorted_blocks(src[:, 0], offsets) + + result = np.empty(len(pairs), dtype=int) + + find_pairs(src, offsets, pairs, result) + + if out is None: + out = result >= 0 + else: + out[:] = result >= 0 + + return out + + +def __pair_isin(src, pairs, out=None, sorter=None, sorted=False): """Check if integer-pairs are contained in source set. Parameters @@ -15,7 +159,7 @@ def pair_isin(src, pairs, out=None, sorter=None, sorted=False): src : ndarray of int, size *(N, 2)* Integer pairs that form the source set. pairs : ndarray of int, size *(M, 2)* - Integer pairs to check if the are contained in the source set. + Integer pairs to check if they are contained in the source set. out : ndarray of bool, size *(M,)*, optional Buffer to place the result. If not provided, a new array will be allocated. sorter : ndarray of int, size *(N,)*, optional @@ -80,6 +224,65 @@ def map_pairs_to_values(mapping, pairs, out=None, sorter=None, sorted=False): keys, values = np.asarray(mapping[0]), np.asarray(mapping[1]) pairs = np.asarray(pairs) + if out is None: + out = np.empty(len(pairs), dtype=values.dtype) + + if not sorted and sorter is None: + sorter = np.argsort(keys[:, 0]) + + if sorter is not None: + keys = keys[sorter] + values = values[sorter] + + offsets = np.empty(pairs.max() + 2, dtype=int) + fill_offsets_to_sorted_blocks(keys[:, 0], offsets) + + result = np.empty(len(pairs), dtype=int) + + find_pairs(keys, offsets, pairs, result) + + out[:] = values[result] + out[result == -1] = -1 + + return out + + +def __map_pairs_to_values(mapping, pairs, out=None, sorter=None, sorted=False): + """Return the values for integer pairs from a mapping. + + Parameters + ---------- + mapping : tuple of ndarray of int + Integer pair to value mapping as *(pairs, values)* where *pairs* is + *ndarray* of shape *(M, 2)* and *values* an array of length *M*. + pairs : ndarray of int of shape *(N, 2)* + Integer pairs to get the values of. + out : ndarray of bool, size *(N,)*, optional + Buffer to place the result. If not provided, a new array will be allocated. + sorter : ndarray of int, size *(M,)*, optional + Array of indices that sorts the *src*, as would be returned by *argsort*. + If not provided, *src* is assumed to already be sorted. + sorted : bool, optional + Indicate if the mapping key pairs are already sorted. + + Returns + ------- + ndarray of int + Array of values of the given integer pairs. + + Examples + -------- + >>> from landlab.graph.sort.intpair import map_pairs_to_values + + >>> keys = [[0, 1], [1, 1], [2, 1], [3, 1], [4, 1]] + >>> values = [0, 10, 20, 30, 40] + >>> pairs = [[1, 1], [3, 1]] + >>> map_pairs_to_values((keys, values), pairs) + array([10, 30]) + """ + keys, values = np.asarray(mapping[0]), np.asarray(mapping[1]) + pairs = np.asarray(pairs) + if out is None: out = np.empty(len(pairs), dtype=values.dtype) @@ -97,6 +300,60 @@ def map_pairs_to_values(mapping, pairs, out=None, sorter=None, sorted=False): def map_rolling_pairs_to_values( + mapping, + pairs, + out=None, + sorter=None, + sorted=False, + size_of_row=None, + wraparound=True, +): + keys, values = np.asarray(mapping[0]), np.asarray(mapping[1]) + pairs = np.asarray(pairs) + + if out is None: + out = np.empty_like(pairs, dtype=int) + + if size_of_row is None: + size_of_row = np.full(len(pairs), pairs.shape[1], dtype=int) + else: + size_of_row = np.asarray(size_of_row) + out[:] = -1 + + if not sorted and sorter is None: + sorter = np.argsort(keys[:, 0]) + if sorter is not None: + keys = keys[sorter] + values = values[sorter] + + offsets = np.empty(pairs.max() + 2, dtype=int) + fill_offsets_to_sorted_blocks(keys[:, 0], offsets) + + result = np.full(pairs.shape, -1, dtype=int) + + find_rolling_pairs_2d( + keys, + offsets, + pairs, + result, + bool(wraparound), + ) + + out[:] = values[result] + out[result == -1] = -1 + + # _map_rolling_pairs_to_values( + # np.ascontiguousarray(keys), + # np.ascontiguousarray(values), + # np.ascontiguousarray(pairs), + # np.ascontiguousarray(size_of_row), + # out, + # ) + + return out + + +def __map_rolling_pairs_to_values( mapping, pairs, out=None, sorter=None, sorted=False, size_of_row=None ): """Return the values for integer pairs given as a 2D matrix of rolling From ccaab9cea9e4546350e65d7618ecf546b5c68cad Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 4 Sep 2024 11:27:52 -0600 Subject: [PATCH 68/70] add more unit tests for IntPairCollection, IntPairMapping --- landlab/graph/sort/intpair.py | 114 +++++++++++++++++-- landlab/graph/voronoi/voronoi_to_graph.py | 22 ++-- tests/graph/sort/test_intpair.py | 131 ++++++++++++++++++++++ 3 files changed, 247 insertions(+), 20 deletions(-) diff --git a/landlab/graph/sort/intpair.py b/landlab/graph/sort/intpair.py index c73018d5ae..ca9205e212 100644 --- a/landlab/graph/sort/intpair.py +++ b/landlab/graph/sort/intpair.py @@ -1,6 +1,7 @@ from collections.abc import Collection from collections.abc import Iterable from collections.abc import Mapping +from pprint import pformat import numpy as np from numpy.typing import ArrayLike @@ -17,7 +18,39 @@ from .ext._deprecated_sparse import pair_isin as _pair_isin -class IntPairs(Collection): +class IntPairCollection(Collection): + """Collection of pairs of int, that ignores ordering of pairs. + + + Examples + -------- + >>> from landlab.graph.sort.intpair import IntPairCollection + >>> pairs = IntPairCollection([(0, 1), (2, 3), (1, 2), (4, 5)]) + >>> (0, 1) in pairs + True + >>> (1, 0) in pairs + True + >>> (2, 4) in pairs + False + + >>> pairs.contains_pairs([(1, 0), (5, 4), (4, 5), (3, 200)]) + array([ True, True, True, False]) + + >>> pairs.contains_pairs([(1, 0, 2), (5, 4, -1), (-1, 4, 5), (3, 2, 1)]) + array([[ True, False], + [ True, False], + [False, False], + [ True, True]]) + + >>> pairs.contains_pairs( + ... [(1, 0, 2), (5, 4, -1), (-1, 4, 5), (3, 2, 1)], wraparound=True + ... ) + array([[ True, False, True], + [ True, True, False], + [False, False, False], + [ True, True, False]]) + """ + def __init__( self, pairs: ArrayLike, @@ -37,6 +70,13 @@ def __init__( fill_offsets_to_sorted_blocks(self._data[:, 0], self._offsets) + self._assert_is_sorted(self._data) + + @staticmethod + def _assert_is_sorted(data): + if np.any(np.diff(data[:, 0]) < 0): + raise ValueError("array is not sorted") + def __contains__(self, pair) -> bool: pairs = np.atleast_2d(pair) result = np.asarray([-1], dtype=int) @@ -59,19 +99,59 @@ def _find_pairs(self, pairs, out=None, wraparound=False): shape = (pairs.shape[0], pairs.shape[1]) else: shape = (pairs.shape[0], pairs.shape[1] - 1) - result = np.full(shape, -1, dtype=int) - - # find_pairs(self._data, self._offsets, pairs, result) + result = np.full(shape, -2, dtype=int) find_rolling_pairs_2d(self._data, self._offsets, pairs, result, int(wraparound)) return result - def contains_keys(self, pairs, wraparound=False): - return self._find_pairs(pairs, wraparound=wraparound) >= 0 + def contains_pairs(self, pairs, wraparound=False): + return np.squeeze(self._find_pairs(pairs, wraparound=wraparound) >= 0) + def __repr__(self) -> str: + if len(self._data) > 6: + s = ( + f"[{' '.join([repr(tuple(p)) + ',' for p in self._data[:3]])}" + " ... " + f"{', '.join([repr(tuple(p)) for p in self._data[-3:]])}]" + ) + else: + s = f"{pformat([tuple(pair) for pair in self._data], compact=True)}" + return f"IntPairCollection({s})" + + +class IntPairMapping(Mapping, IntPairCollection): + """Mapping of pairs of int, that ignores ordering of pairs. + + + Examples + -------- + >>> from landlab.graph.sort.intpair import IntPairMapping + >>> pairs = IntPairMapping([(0, 1), (2, 3), (1, 2), (4, 5)], values=[1, 2, 3, 4]) + >>> pairs[(1, 0)] + 1 + >>> pairs[(0, 1)] + 1 + >>> pairs[(2, 4)] + Traceback (most recent call last): + KeyError: (2, 4) + + >>> pairs.get_items([(1, 0), (5, 4), (4, 5), (3, 200)]) + array([ 1, 4, 4, -1]) + + >>> pairs.get_items([(1, 0, 2), (5, 4, -1), (-1, 4, 5), (3, 2, 1)]) + array([[ 1, -1], + [ 4, -1], + [-1, -1], + [ 2, 3]]) + + >>> pairs.get_items([(1, 0, 2), (5, 4, -1), (-1, 4, 5), (3, 2, 1)], wraparound=True) + array([[ 1, -1, 3], + [ 4, 4, -1], + [-1, -1, -1], + [ 2, 3, -1]]) + """ -class IntPairMapping(Mapping, IntPairs): def __init__( self, pairs: ArrayLike, @@ -80,6 +160,7 @@ def __init__( sorted: bool = False, ) -> None: pairs = np.atleast_2d(pairs) + values = np.asarray(values) if sorter is None and not sorted: sorter = np.argsort(pairs[:, 0]) @@ -127,7 +208,24 @@ def get_items(self, keys, out=None, wraparound=False): out[:] = self._values[result] out[result == -1] = -1 - return out + return np.squeeze(out) + + def __repr__(self) -> str: + if len(self._data) > 6: + s = ( + f"[{' '.join([repr(tuple(p)) + ',' for p in self._data[:3]])}" + " ... " + f"{', '.join([repr(tuple(p)) for p in self._data[-3:]])}]" + ) + v = ( + f"[{' '.join([repr(v) + ',' for v in self._values[:3]])}" + " ... " + f"{', '.join([repr(v) for v in self._values[-3:]])}]" + ) + else: + s = f"{pformat([tuple(pair) for pair in self._data], compact=True)}" + v = f"{pformat(list(self._values), compact=True)}" + return f"IntPairCollection({s}, values={v})" def pair_isin(src, pairs, out=None, sorter=None, sorted=False): diff --git a/landlab/graph/voronoi/voronoi_to_graph.py b/landlab/graph/voronoi/voronoi_to_graph.py index 4228759367..12fba32bb6 100644 --- a/landlab/graph/voronoi/voronoi_to_graph.py +++ b/landlab/graph/voronoi/voronoi_to_graph.py @@ -5,10 +5,11 @@ from scipy.spatial import Delaunay from scipy.spatial import Voronoi -from ...core.utils import as_id_array -from ...utils import jaggedarray -from ..sort.intpair import pair_isin -from ..sort.sort import reverse_one_to_one +from landlab.core.utils import as_id_array +from landlab.graph.sort.intpair import IntPairCollection +from landlab.graph.sort.intpair import IntPairMapping +from landlab.graph.sort.sort import reverse_one_to_one +from landlab.utils import jaggedarray class VoronoiDelaunay: @@ -235,14 +236,10 @@ def __init__(self, xy_of_node, perimeter_links=None): @staticmethod def _links_at_patch(nodes_at_link, nodes_at_patch, n_links_at_patch=None): - from ..sort.intpair import map_rolling_pairs_to_values + """Construct links_at_path from nodes_at_link/nodes_at_path.""" + pairs = IntPairMapping(nodes_at_link, values=np.arange(len(nodes_at_link))) - return map_rolling_pairs_to_values( - (nodes_at_link, np.arange(len(nodes_at_link))), - nodes_at_patch, - size_of_row=n_links_at_patch, - # (nodes_at_link[link_at_nodes], link_at_nodes), nodes_at_patch, sorted=True - ) + return pairs.get_items(nodes_at_patch, wraparound=True) def is_perimeter_face(self): return np.any(self.corners_at_face == -1, axis=1) @@ -263,7 +260,8 @@ def is_perimeter_cell(self): def is_perimeter_link(self): if self._perimeter_links is not None: - is_perimeter_link = pair_isin(self._perimeter_links, self.nodes_at_link) + pairs = IntPairCollection(self._perimeter_links) + is_perimeter_link = pairs.contains_pairs(self.nodes_at_link) else: is_perimeter_link = self.is_perimeter_face() return is_perimeter_link diff --git a/tests/graph/sort/test_intpair.py b/tests/graph/sort/test_intpair.py index 66916d9d2f..cad3c04f56 100644 --- a/tests/graph/sort/test_intpair.py +++ b/tests/graph/sort/test_intpair.py @@ -1,8 +1,11 @@ import numpy as np from numpy.testing import assert_array_equal +from landlab import RasterModelGrid from landlab.graph.sort.ext._deprecated_sparse import offset_to_sorted_block from landlab.graph.sort.ext.intpair import fill_offsets_to_sorted_blocks +from landlab.graph.sort.intpair import IntPairCollection +from landlab.graph.sort.intpair import IntPairMapping from landlab.graph.sort.intpair import map_pairs_to_values from landlab.graph.sort.intpair import map_rolling_pairs_to_values from landlab.graph.sort.intpair import pair_isin @@ -42,6 +45,134 @@ def test_fill_offsets(): assert actual == [0, 2] +def test_collection_contains(): + pairs = IntPairCollection( + [[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0]] + ) + assert (4, 8) not in pairs + assert (3, 0) in pairs + assert (0, 3) in pairs + + assert pairs.contains_pairs([(4, 8)]) == (False,) + assert pairs.contains_pairs((4, 8)) == (False,) + assert_array_equal( + pairs.contains_pairs([(4, 8), (7, 8), (0, 1)]), (False, True, True) + ) + + pairs = IntPairCollection([[0, 1], [1, 1], [2, 1], [3, 1], [4, 1]]) + assert_array_equal( + pairs.contains_pairs([[1, 1], [3, 1], [1, 2], [5, 1]]), + (True, True, True, False), + ) + + +def test_collection_with_sorter(): + src = np.asarray([[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0]]) + pairs = IntPairCollection(src, sorter=np.argsort(src[:, 0])) + + assert_array_equal( + pairs.contains_pairs( + [ + *([5, 2], [5, 4], [5, 8], [1, 2], [1, 4]), + *([1, 0], [1, 3], [2, 4], [0, 6], [0, 3]), + *([7, 3], [7, 4], [7, 6], [7, 8], [3, 6]), + *([3, 4], [4, 8]), + ] + ), + [ + *(True, False, True, True, False), + *(True, False, False, False, True), + *(False, False, True, True, True), + *(False, False), + ], + ) + + +def test_mapping(): + pairs = IntPairMapping( + [[0, 1], [1, 1], [2, 1], [3, 1], [4, 1]], values=[0, 10, 20, 30, 40] + ) + + assert_array_equal(pairs.get_items([(1, 1), (3, 1)]), (10, 30)) + + +def test_mapping_with_sorter_keyword(): + pairs = IntPairMapping( + [[0, 1], [1, 1], [3, 1], [2, 1], [4, 1]], + values=[0, 10, 30, 20, 40], + sorter=[0, 1, 3, 2, 4], + ) + + assert_array_equal(pairs.get_items([(1, 1), (3, 1)]), (10, 30)) + + +def test_mapping_pairs_at_end(): + pairs = IntPairMapping( + [[0, 1], [1, 1], [2, 1], [3, 1], [4, 1]], values=[0, 10, 20, 30, 40] + ) + assert_array_equal( + pairs.get_items([[1, 1], [3, 1], [4, 1], [1, 4], [4, 2]]), [10, 30, 40, 40, -1] + ) + + +def test_mapping_pairs_transposed(): + pairs = IntPairMapping( + [[0, 1], [1, 1], [2, 1], [3, 1], [4, 1]], values=[0, 10, 20, 30, 40] + ) + + assert_array_equal(pairs.get_items([(1, 0), (1, 3)]), [0, 30]) + + +def test_mapping_pairs_all_missing(): + pairs = IntPairMapping( + [[0, 1], [1, 1], [2, 1], [3, 1], [4, 1]], values=[0, 10, 20, 30, 40] + ) + assert_array_equal(pairs.get_items([(5, 1), (1, 42)]), (-1, -1)) + + +def test_mapping_pairs_big_data(): + grid = RasterModelGrid((2**10, 2**10)) + + n_pairs = len(grid.nodes_at_link) + + pairs = IntPairMapping(grid.nodes_at_link, values=np.arange(n_pairs) * 10) + + ids = np.random.randint(n_pairs, size=n_pairs // 10) + + assert_array_equal(pairs.get_items(grid.nodes_at_link[ids]), ids * 10) + + +def test_mapping_rolling_pairs(): + pairs = IntPairMapping( + [[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]], values=[0, 10, 20, 30, 40] + ) + + assert_array_equal( + pairs.get_items([[0, 1, 2, 3], [0, 2, 3, 4]], wraparound=True), + [[0, 10, 20, -1], [-1, 20, 30, 40]], + ) + + assert_array_equal( + pairs.get_items([[0, 1, 2, 3], [0, 2, 3, 4]], wraparound=False), + [[0, 10, 20], [-1, 20, 30]], + ) + + +def test_mapping_rolling_pairs_with_jagged_rows(): + pairs = IntPairMapping( + [[0, 1], [1, 2], [2, 3], [2, 0], [3, 4], [4, 0]], values=[0, 10, 20, 30, 40, 50] + ) + + assert_array_equal( + pairs.get_items([[0, 1, 2, -1], [0, 2, -1, -1]], wraparound=True), + [[0, 10, 30, -1], [30, 30, -1, -1]], + ) + assert_array_equal( + pairs.get_items([[0, 1, 2, -1], [0, 2, -1, -1]], wraparound=False), + [[0, 10, -1], [30, -1, -1]], + ) + + def test_pair_isin_one_pair(): src = np.asarray( [[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0]], dtype=int From 6c838951c0a22ffccc69df1ca03c47c7696a6367 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 4 Sep 2024 13:20:46 -0600 Subject: [PATCH 69/70] refactor map_pairs_to_values to use IntPairMapping --- landlab/graph/sort/intpair.py | 38 ++++++++++++++--------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/landlab/graph/sort/intpair.py b/landlab/graph/sort/intpair.py index ca9205e212..97cf461270 100644 --- a/landlab/graph/sort/intpair.py +++ b/landlab/graph/sort/intpair.py @@ -193,7 +193,9 @@ def get_items(self, keys, out=None, wraparound=False): shape = (keys.shape[0], keys.shape[1] - 1) if out is None: - out = np.empty(shape, dtype=self._values.dtype) + _out = np.empty(shape, dtype=self._values.dtype) + else: + _out = out.reshape(shape) result = np.full(shape, -1, dtype=int) @@ -205,10 +207,13 @@ def get_items(self, keys, out=None, wraparound=False): int(wraparound), ) - out[:] = self._values[result] - out[result == -1] = -1 + _out[:] = self._values[result] + _out[result == -1] = -1 - return np.squeeze(out) + if out is None: + return np.squeeze(_out) + else: + return out def __repr__(self) -> str: if len(self._data) > 6: @@ -319,30 +324,17 @@ def map_pairs_to_values(mapping, pairs, out=None, sorter=None, sorted=False): >>> map_pairs_to_values((keys, values), pairs) array([10, 30]) """ - keys, values = np.asarray(mapping[0]), np.asarray(mapping[1]) - pairs = np.asarray(pairs) + keys, values = mapping - if out is None: - out = np.empty(len(pairs), dtype=values.dtype) + if sorted and sorter is not None: + sorter = None if not sorted and sorter is None: + keys = np.atleast_2d(keys) sorter = np.argsort(keys[:, 0]) - if sorter is not None: - keys = keys[sorter] - values = values[sorter] - - offsets = np.empty(pairs.max() + 2, dtype=int) - fill_offsets_to_sorted_blocks(keys[:, 0], offsets) - - result = np.empty(len(pairs), dtype=int) - - find_pairs(keys, offsets, pairs, result) - - out[:] = values[result] - out[result == -1] = -1 - - return out + mapping = IntPairMapping(keys, values=values, sorter=sorter) + return mapping.get_items(pairs, out=out) def __map_pairs_to_values(mapping, pairs, out=None, sorter=None, sorted=False): From 762a7417a6905f8f5398c2688b67251832fac511 Mon Sep 17 00:00:00 2001 From: mcflugen Date: Wed, 4 Sep 2024 13:56:58 -0600 Subject: [PATCH 70/70] update output data types for int pair functions --- landlab/graph/sort/ext/intpair.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/landlab/graph/sort/ext/intpair.pyx b/landlab/graph/sort/ext/intpair.pyx index 4d256a9133..e0f29f6fbe 100644 --- a/landlab/graph/sort/ext/intpair.pyx +++ b/landlab/graph/sort/ext/intpair.pyx @@ -74,7 +74,7 @@ cpdef void find_rolling_pairs( const id_t [:, :] array, const integral_out_t [:] offsets, const id_t [:] pairs, - id_t [:] where, + integral_out_t [:] where, const int wraparound, ) noexcept nogil: cdef long n_pairs = len(pairs) @@ -110,7 +110,7 @@ cpdef void find_rolling_pairs_2d( const id_t [:, :] array, const integral_out_t [:] offsets, const id_t [:, :] pairs, - id_t [:, :] where, + integral_out_t [:, :] where, const int wraparound, ) noexcept nogil: cdef long n_rows = len(pairs)