diff --git a/lightfm/_lightfm_fast.pyx.template b/lightfm/_lightfm_fast.pyx.template index 5a3b6805..0072e040 100644 --- a/lightfm/_lightfm_fast.pyx.template +++ b/lightfm/_lightfm_fast.pyx.template @@ -1139,51 +1139,129 @@ def fit_bpr(CSRMatrix item_features, user_alpha) -def predict_lightfm(CSRMatrix item_features, - CSRMatrix user_features, - int[::1] user_ids, - int[::1] item_ids, - double[::1] predictions, - FastLightFM lightfm, - int num_threads): +cdef precompute_unique(CSRMatrix item_features, + CSRMatrix user_features, + int[::1] unique_users, + int[::1] unique_items, + flt *user_reprs, + flt *it_reprs, + FastLightFM lightfm, + int num_threads): """ - Generate predictions. + Precomputes the representations for all the users in unique_users and + all the items in unique_items """ - - cdef int i, no_examples - cdef flt *user_repr + cdef int i, j cdef flt *it_repr + cdef flt *user_repr + cdef int no_features + cdef int no_users - no_examples = predictions.shape[0] - + no_features = unique_items.shape[0] + no_users = unique_users.shape[0] {nogil_block} - user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) - - for i in {range_block}(no_examples): - + # users representations + for i in {range_block}(no_users): compute_representation(user_features, lightfm.user_features, lightfm.user_biases, lightfm, - user_ids[i], + unique_users[i], lightfm.user_scale, user_repr) + for j in {range_block}(lightfm.no_components + 1): + user_reprs[i * (lightfm.no_components + 1) + j] = user_repr[j] + + # items representations + for i in {range_block}(no_features): compute_representation(item_features, lightfm.item_features, lightfm.item_biases, lightfm, - item_ids[i], + unique_items[i], lightfm.item_scale, it_repr) + for j in {range_block}(lightfm.no_components + 1): + it_reprs[i * (lightfm.no_components + 1) + j] = it_repr[j] + + +def predict_lightfm(CSRMatrix item_features, + CSRMatrix user_features, + int[::1] user_ids, + int[::1] item_ids, + double[::1] predictions, + FastLightFM lightfm, + int num_threads, + bint precompute): + """ + Generate predictions. + """ + cdef int i, j, no_examples + cdef flt *user_repr + cdef flt *it_repr + cdef flt *user_reprs + cdef flt *it_reprs + cdef int[::1] unique_users + cdef int[::1] unique_items + cdef long[::1] inverse_users + cdef long[::1] inverse_items + cdef int no_features + cdef int no_users + + no_examples = predictions.shape[0] + + if precompute: + unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + no_features = unique_items.shape[0] + no_users = unique_users.shape[0] + + user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) + it_reprs = malloc(sizeof(flt) * no_features *(lightfm.no_components + 1)) + precompute_unique(item_features, + user_features, + unique_users, + unique_items, + user_reprs, + it_reprs, + lightfm, + num_threads) + + {nogil_block} + user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + for i in {range_block}(no_examples): + if precompute: + for j in {range_block}(lightfm.no_components + 1): + user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] + it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + else: + compute_representation(user_features, + lightfm.user_features, + lightfm.user_biases, + lightfm, + user_ids[i], + lightfm.user_scale, + user_repr) + compute_representation(item_features, + lightfm.item_features, + lightfm.item_biases, + lightfm, + item_ids[i], + lightfm.item_scale, + it_repr) predictions[i] = compute_prediction_from_repr(user_repr, - it_repr, - lightfm.no_components) + it_repr, + lightfm.no_components) free(user_repr) free(it_repr) + if precompute: + free(user_reprs) + free(it_reprs) def predict_ranks(CSRMatrix item_features, @@ -1341,3 +1419,4 @@ def __test_in_positives(int row, int col, CSRMatrix mat): return True else: return False + diff --git a/lightfm/_lightfm_fast_no_openmp.c b/lightfm/_lightfm_fast_no_openmp.c index c2d3266a..3cc4fcb1 100644 --- a/lightfm/_lightfm_fast_no_openmp.c +++ b/lightfm/_lightfm_fast_no_openmp.c @@ -1,4 +1,4 @@ -/* Generated by Cython 0.23.5 */ +/* Generated by Cython 0.23.4 */ /* BEGIN: Cython Metadata { @@ -15,7 +15,7 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) #error Cython requires Python 2.6+ or Python 3.2+. #else -#define CYTHON_ABI "0_23_5" +#define CYTHON_ABI "0_23_4" #include #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) @@ -1111,6 +1111,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); +static PyObject *__pyx_memview_get_int(const char *itemp); +static int __pyx_memview_set_int(const char *itemp, PyObject *obj); + static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs, char order, int ndim); @@ -1132,6 +1135,8 @@ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_int(PyObject *); +static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_long(PyObject *); + static int __Pyx_check_binary_version(void); static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); @@ -1181,6 +1186,7 @@ static CYTHON_INLINE double __pyx_f_7lightfm_23_lightfm_fast_no_openmp_update_fe static CYTHON_INLINE void __pyx_f_7lightfm_23_lightfm_fast_no_openmp_update(double, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *, int, int, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *, double, double); /*proto*/ static void __pyx_f_7lightfm_23_lightfm_fast_no_openmp_warp_update(double, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *, int, int, int, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *, double, double); /*proto*/ static void __pyx_f_7lightfm_23_lightfm_fast_no_openmp_regularize(struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *, double, double); /*proto*/ +static PyObject *__pyx_f_7lightfm_23_lightfm_fast_no_openmp_precompute_unique(struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *, __Pyx_memviewslice, __Pyx_memviewslice, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *, int); /*proto*/ static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/ static void *__pyx_align_pointer(void *, size_t); /*proto*/ static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/ @@ -1217,6 +1223,7 @@ static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_7lightfm_23_lightfm_fast_no_open static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, IS_UNSIGNED(int) ? 'U' : 'I', IS_UNSIGNED(int), 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_unsigned_int = { "unsigned int", NULL, sizeof(unsigned int), { 0 }, 0, IS_UNSIGNED(unsigned int) ? 'U' : 'I', IS_UNSIGNED(unsigned int), 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_long = { "long", NULL, sizeof(long), { 0 }, 0, IS_UNSIGNED(long) ? 'U' : 'I', IS_UNSIGNED(long), 0 }; #define __Pyx_MODULE_NAME "lightfm._lightfm_fast_no_openmp" int __pyx_module_is_main_lightfm___lightfm_fast_no_openmp = 0; @@ -1280,6 +1287,7 @@ static char __pyx_k_indptr[] = "indptr"; static char __pyx_k_name_2[] = "__name__"; static char __pyx_k_struct[] = "struct"; static char __pyx_k_uint32[] = "uint32"; +static char __pyx_k_unique[] = "unique"; static char __pyx_k_unpack[] = "unpack"; static char __pyx_k_weight[] = "weight"; static char __pyx_k_epsilon[] = "epsilon"; @@ -1297,8 +1305,10 @@ static char __pyx_k_Ellipsis[] = "Ellipsis"; static char __pyx_k_MAX_LOSS[] = "MAX_LOSS"; static char __pyx_k_adadelta[] = "adadelta"; static char __pyx_k_fit_warp[] = "fit_warp"; +static char __pyx_k_it_reprs[] = "it_reprs"; static char __pyx_k_item_ids[] = "item_ids"; static char __pyx_k_itemsize[] = "itemsize"; +static char __pyx_k_no_users[] = "no_users"; static char __pyx_k_row_stop[] = "row_stop"; static char __pyx_k_user_ids[] = "user_ids"; static char __pyx_k_TypeError[] = "TypeError"; @@ -1311,15 +1321,18 @@ static char __pyx_k_IndexError[] = "IndexError"; static char __pyx_k_ValueError[] = "ValueError"; static char __pyx_k_csr_matrix[] = "csr_matrix"; static char __pyx_k_item_alpha[] = "item_alpha"; +static char __pyx_k_precompute[] = "precompute"; static char __pyx_k_prediction[] = "prediction"; static char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; static char __pyx_k_user_alpha[] = "user_alpha"; +static char __pyx_k_user_reprs[] = "user_reprs"; static char __pyx_k_MemoryError[] = "MemoryError"; static char __pyx_k_POS_SAMPLES[] = "POS_SAMPLES"; static char __pyx_k_item_biases[] = "item_biases"; static char __pyx_k_max_sampled[] = "max_sampled"; static char __pyx_k_neg_it_repr[] = "neg_it_repr"; static char __pyx_k_no_examples[] = "no_examples"; +static char __pyx_k_no_features[] = "no_features"; static char __pyx_k_num_threads[] = "num_threads"; static char __pyx_k_pos_it_repr[] = "pos_it_repr"; static char __pyx_k_predictions[] = "predictions"; @@ -1329,6 +1342,10 @@ static char __pyx_k_fit_warp_kos[] = "fit_warp_kos"; static char __pyx_k_interactions[] = "interactions"; static char __pyx_k_no_positives[] = "no_positives"; static char __pyx_k_random_state[] = "random_state"; +static char __pyx_k_unique_items[] = "unique_items"; +static char __pyx_k_unique_users[] = "unique_users"; +static char __pyx_k_inverse_items[] = "inverse_items"; +static char __pyx_k_inverse_users[] = "inverse_users"; static char __pyx_k_item_features[] = "item_features"; static char __pyx_k_learning_rate[] = "learning_rate"; static char __pyx_k_no_components[] = "no_components"; @@ -1339,6 +1356,7 @@ static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer"; static char __pyx_k_random_states[] = "random_states"; static char __pyx_k_sample_weight[] = "sample_weight"; static char __pyx_k_user_features[] = "user_features"; +static char __pyx_k_return_inverse[] = "return_inverse"; static char __pyx_k_user_pids_stop[] = "user_pids_stop"; static char __pyx_k_allocate_buffer[] = "allocate_buffer"; static char __pyx_k_dtype_is_object[] = "dtype_is_object"; @@ -1380,7 +1398,7 @@ static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.ar static char __pyx_k_sampled_positive_prediction[] = "sampled_positive_prediction"; static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data."; static char __pyx_k_strided_and_direct_or_indirect[] = ""; -static char __pyx_k_home_maciej_Code_lightfm_lightf[] = "/home/maciej/Code/lightfm/lightfm/_lightfm_fast_no_openmp.pyx"; +static char __pyx_k_home_paolo_raisDataScience_reco[] = "/home/paolo/raisDataScience/recommender_system/FM/modified_lightfm/lightfm/_lightfm_fast_no_openmp.pyx"; static char __pyx_k_lightfm__lightfm_fast_no_openmp[] = "lightfm._lightfm_fast_no_openmp"; static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced"; static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides"; @@ -1443,7 +1461,7 @@ static PyObject *__pyx_n_s_fortran; static PyObject *__pyx_n_u_fortran; static PyObject *__pyx_n_s_gamma; static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi; -static PyObject *__pyx_kp_s_home_maciej_Code_lightfm_lightf; +static PyObject *__pyx_kp_s_home_paolo_raisDataScience_reco; static PyObject *__pyx_n_s_i; static PyObject *__pyx_n_s_id; static PyObject *__pyx_n_s_iinfo; @@ -1452,7 +1470,10 @@ static PyObject *__pyx_n_s_indices; static PyObject *__pyx_n_s_indptr; static PyObject *__pyx_n_s_int32; static PyObject *__pyx_n_s_interactions; +static PyObject *__pyx_n_s_inverse_items; +static PyObject *__pyx_n_s_inverse_users; static PyObject *__pyx_n_s_it_repr; +static PyObject *__pyx_n_s_it_reprs; static PyObject *__pyx_n_s_item_alpha; static PyObject *__pyx_n_s_item_bias_gradients; static PyObject *__pyx_n_s_item_bias_momentum; @@ -1485,7 +1506,9 @@ static PyObject *__pyx_n_s_negative_item_id; static PyObject *__pyx_n_s_negative_prediction; static PyObject *__pyx_n_s_no_components; static PyObject *__pyx_n_s_no_examples; +static PyObject *__pyx_n_s_no_features; static PyObject *__pyx_n_s_no_positives; +static PyObject *__pyx_n_s_no_users; static PyObject *__pyx_n_s_np; static PyObject *__pyx_n_s_num_negatives; static PyObject *__pyx_n_s_num_positives; @@ -1498,6 +1521,7 @@ static PyObject *__pyx_n_s_pos_it_repr; static PyObject *__pyx_n_s_pos_pairs; static PyObject *__pyx_n_s_positive_item_id; static PyObject *__pyx_n_s_positive_prediction; +static PyObject *__pyx_n_s_precompute; static PyObject *__pyx_n_s_predict_lightfm; static PyObject *__pyx_n_s_predict_ranks; static PyObject *__pyx_n_s_prediction; @@ -1512,6 +1536,7 @@ static PyObject *__pyx_n_s_range; static PyObject *__pyx_n_s_rank; static PyObject *__pyx_n_s_rank_data; static PyObject *__pyx_n_s_ranks; +static PyObject *__pyx_n_s_return_inverse; static PyObject *__pyx_n_s_rho; static PyObject *__pyx_n_s_row; static PyObject *__pyx_n_s_row_start; @@ -1537,6 +1562,9 @@ static PyObject *__pyx_n_s_train_interactions; static PyObject *__pyx_n_s_uint32; static PyObject *__pyx_kp_s_unable_to_allocate_array_data; static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str; +static PyObject *__pyx_n_s_unique; +static PyObject *__pyx_n_s_unique_items; +static PyObject *__pyx_n_s_unique_users; static PyObject *__pyx_n_s_unpack; static PyObject *__pyx_n_s_user_alpha; static PyObject *__pyx_n_s_user_bias_gradients; @@ -1550,6 +1578,7 @@ static PyObject *__pyx_n_s_user_ids; static PyObject *__pyx_n_s_user_pids_start; static PyObject *__pyx_n_s_user_pids_stop; static PyObject *__pyx_n_s_user_repr; +static PyObject *__pyx_n_s_user_reprs; static PyObject *__pyx_n_s_weight; static PyObject *__pyx_n_s_y; static PyObject *__pyx_n_s_y_row; @@ -1559,7 +1588,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_fit_logistic(CYTHON static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_2fit_warp(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_interactions, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_Y, __Pyx_memviewslice __pyx_v_sample_weight, __Pyx_memviewslice __pyx_v_shuffle_indices, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED double __pyx_v_learning_rate, double __pyx_v_item_alpha, double __pyx_v_user_alpha, int __pyx_v_num_threads, PyObject *__pyx_v_random_state); /* proto */ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_4fit_warp_kos(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_data, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_shuffle_indices, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED double __pyx_v_learning_rate, double __pyx_v_item_alpha, double __pyx_v_user_alpha, int __pyx_v_k, int __pyx_v_n, int __pyx_v_num_threads, PyObject *__pyx_v_random_state); /* proto */ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_6fit_bpr(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_interactions, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_Y, __Pyx_memviewslice __pyx_v_sample_weight, __Pyx_memviewslice __pyx_v_shuffle_indices, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED double __pyx_v_learning_rate, double __pyx_v_item_alpha, double __pyx_v_user_alpha, int __pyx_v_num_threads, PyObject *__pyx_v_random_state); /* proto */ -static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED int __pyx_v_num_threads); /* proto */ +static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads, int __pyx_v_precompute); /* proto */ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_test_interactions, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_train_interactions, __Pyx_memviewslice __pyx_v_ranks, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED int __pyx_v_num_threads); /* proto */ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_from_rank(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_ranks, __Pyx_memviewslice __pyx_v_num_train_positives, __Pyx_memviewslice __pyx_v_rank_data, __Pyx_memviewslice __pyx_v_auc, CYTHON_UNUSED int __pyx_v_num_threads); /* proto */ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_14__test_in_positives(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_row, int __pyx_v_col, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_mat); /* proto */ @@ -7321,6 +7350,217 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_6fit_bpr(CYTHON_UNU } /* "lightfm/_lightfm_fast_no_openmp.pyx":1142 + * + * + * cdef precompute_unique(CSRMatrix item_features, # <<<<<<<<<<<<<< + * CSRMatrix user_features, + * int[::1] unique_users, + */ + +static PyObject *__pyx_f_7lightfm_23_lightfm_fast_no_openmp_precompute_unique(struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_unique_users, __Pyx_memviewslice __pyx_v_unique_items, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_user_reprs, __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_it_reprs, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED int __pyx_v_num_threads) { + int __pyx_v_i; + int __pyx_v_j; + __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_it_repr; + __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_user_repr; + int __pyx_v_no_features; + int __pyx_v_no_users; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + Py_ssize_t __pyx_t_3; + long __pyx_t_4; + int __pyx_t_5; + Py_ssize_t __pyx_t_6; + __Pyx_RefNannySetupContext("precompute_unique", 0); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1160 + * cdef int no_users + * + * no_features = unique_items.shape[0] # <<<<<<<<<<<<<< + * no_users = unique_users.shape[0] + * with nogil: + */ + __pyx_v_no_features = (__pyx_v_unique_items.shape[0]); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1161 + * + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] # <<<<<<<<<<<<<< + * with nogil: + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + */ + __pyx_v_no_users = (__pyx_v_unique_users.shape[0]); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1162 + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] + * with nogil: # <<<<<<<<<<<<<< + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + */ + { + #ifdef WITH_THREAD + PyThreadState *_save; + Py_UNBLOCK_THREADS + #endif + /*try:*/ { + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1163 + * no_users = unique_users.shape[0] + * with nogil: + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * # users representations + */ + __pyx_v_user_repr = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1164 + * with nogil: + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * # users representations + * for i in range(no_users): + */ + __pyx_v_it_repr = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1166 + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * # users representations + * for i in range(no_users): # <<<<<<<<<<<<<< + * compute_representation(user_features, + * lightfm.user_features, + */ + __pyx_t_1 = __pyx_v_no_users; + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { + __pyx_v_i = __pyx_t_2; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1171 + * lightfm.user_biases, + * lightfm, + * unique_users[i], # <<<<<<<<<<<<<< + * lightfm.user_scale, + * user_repr) + */ + __pyx_t_3 = __pyx_v_i; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1167 + * # users representations + * for i in range(no_users): + * compute_representation(user_features, # <<<<<<<<<<<<<< + * lightfm.user_features, + * lightfm.user_biases, + */ + __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_unique_users.data) + __pyx_t_3)) ))), __pyx_v_lightfm->user_scale, __pyx_v_user_repr); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1174 + * lightfm.user_scale, + * user_repr) + * for j in range(lightfm.no_components + 1): # <<<<<<<<<<<<<< + * user_reprs[i * (lightfm.no_components + 1) + j] = user_repr[j] + * + */ + __pyx_t_4 = (__pyx_v_lightfm->no_components + 1); + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_j = __pyx_t_5; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1175 + * user_repr) + * for j in range(lightfm.no_components + 1): + * user_reprs[i * (lightfm.no_components + 1) + j] = user_repr[j] # <<<<<<<<<<<<<< + * + * # items representations + */ + (__pyx_v_user_reprs[((__pyx_v_i * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]) = (__pyx_v_user_repr[__pyx_v_j]); + } + } + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1178 + * + * # items representations + * for i in range(no_features): # <<<<<<<<<<<<<< + * compute_representation(item_features, + * lightfm.item_features, + */ + __pyx_t_1 = __pyx_v_no_features; + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { + __pyx_v_i = __pyx_t_2; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1183 + * lightfm.item_biases, + * lightfm, + * unique_items[i], # <<<<<<<<<<<<<< + * lightfm.item_scale, + * it_repr) + */ + __pyx_t_6 = __pyx_v_i; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1179 + * # items representations + * for i in range(no_features): + * compute_representation(item_features, # <<<<<<<<<<<<<< + * lightfm.item_features, + * lightfm.item_biases, + */ + __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_unique_items.data) + __pyx_t_6)) ))), __pyx_v_lightfm->item_scale, __pyx_v_it_repr); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1186 + * lightfm.item_scale, + * it_repr) + * for j in range(lightfm.no_components + 1): # <<<<<<<<<<<<<< + * it_reprs[i * (lightfm.no_components + 1) + j] = it_repr[j] + * + */ + __pyx_t_4 = (__pyx_v_lightfm->no_components + 1); + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_j = __pyx_t_5; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1187 + * it_repr) + * for j in range(lightfm.no_components + 1): + * it_reprs[i * (lightfm.no_components + 1) + j] = it_repr[j] # <<<<<<<<<<<<<< + * + * + */ + (__pyx_v_it_reprs[((__pyx_v_i * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]) = (__pyx_v_it_repr[__pyx_v_j]); + } + } + } + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1162 + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] + * with nogil: # <<<<<<<<<<<<<< + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + */ + /*finally:*/ { + /*normal exit:*/{ + #ifdef WITH_THREAD + Py_BLOCK_THREADS + #endif + goto __pyx_L5; + } + __pyx_L5:; + } + } + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1142 + * + * + * cdef precompute_unique(CSRMatrix item_features, # <<<<<<<<<<<<<< + * CSRMatrix user_features, + * int[::1] unique_users, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "lightfm/_lightfm_fast_no_openmp.pyx":1190 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -7339,7 +7579,8 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_9predict_lightfm(Py __Pyx_memviewslice __pyx_v_item_ids = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_memviewslice __pyx_v_predictions = { 0, 0, { 0 }, { 0 }, { 0 } }; struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm = 0; - CYTHON_UNUSED int __pyx_v_num_threads; + int __pyx_v_num_threads; + int __pyx_v_precompute; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; @@ -7347,12 +7588,13 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_9predict_lightfm(Py __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("predict_lightfm (wrapper)", 0); { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_item_features,&__pyx_n_s_user_features,&__pyx_n_s_user_ids,&__pyx_n_s_item_ids,&__pyx_n_s_predictions,&__pyx_n_s_lightfm,&__pyx_n_s_num_threads,0}; - PyObject* values[7] = {0,0,0,0,0,0,0}; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_item_features,&__pyx_n_s_user_features,&__pyx_n_s_user_ids,&__pyx_n_s_item_ids,&__pyx_n_s_predictions,&__pyx_n_s_lightfm,&__pyx_n_s_num_threads,&__pyx_n_s_precompute,0}; + PyObject* values[8] = {0,0,0,0,0,0,0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); @@ -7371,38 +7613,43 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_9predict_lightfm(Py case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_user_features)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_user_ids)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_item_ids)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 4: if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_predictions)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 5: if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_lightfm)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 6: if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_threads)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 7: + if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_precompute)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_lightfm") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_lightfm") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } - } else if (PyTuple_GET_SIZE(__pyx_args) != 7) { + } else if (PyTuple_GET_SIZE(__pyx_args) != 8) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); @@ -7412,27 +7659,29 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_9predict_lightfm(Py values[4] = PyTuple_GET_ITEM(__pyx_args, 4); values[5] = PyTuple_GET_ITEM(__pyx_args, 5); values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); } __pyx_v_item_features = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)values[0]); __pyx_v_user_features = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)values[1]); - __pyx_v_user_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[2]); if (unlikely(!__pyx_v_user_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1144; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_item_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[3]); if (unlikely(!__pyx_v_item_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_predictions = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[4]); if (unlikely(!__pyx_v_predictions.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_user_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[2]); if (unlikely(!__pyx_v_user_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_item_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[3]); if (unlikely(!__pyx_v_item_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_predictions = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[4]); if (unlikely(!__pyx_v_predictions.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1194; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_v_lightfm = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *)values[5]); - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_precompute = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_precompute == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1197; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("lightfm._lightfm_fast_no_openmp.predict_lightfm", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1147; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_r = __pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(__pyx_self, __pyx_v_item_features, __pyx_v_user_features, __pyx_v_user_ids, __pyx_v_item_ids, __pyx_v_predictions, __pyx_v_lightfm, __pyx_v_num_threads); + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1195; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_r = __pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(__pyx_self, __pyx_v_item_features, __pyx_v_user_features, __pyx_v_user_ids, __pyx_v_item_ids, __pyx_v_predictions, __pyx_v_lightfm, __pyx_v_num_threads, __pyx_v_precompute); /* function exit code */ goto __pyx_L0; @@ -7443,35 +7692,305 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_9predict_lightfm(Py return __pyx_r; } -static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED int __pyx_v_num_threads) { +static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads, int __pyx_v_precompute) { int __pyx_v_i; + int __pyx_v_j; int __pyx_v_no_examples; __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_user_repr; __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_it_repr; + __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_user_reprs; + __pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *__pyx_v_it_reprs; + __Pyx_memviewslice __pyx_v_unique_users = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_unique_items = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_inverse_users = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_inverse_items = { 0, 0, { 0 }, { 0 }, { 0 } }; + int __pyx_v_no_features; + int __pyx_v_no_users; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; - int __pyx_t_2; - Py_ssize_t __pyx_t_3; - Py_ssize_t __pyx_t_4; - Py_ssize_t __pyx_t_5; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + __Pyx_memviewslice __pyx_t_7 = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } }; + int __pyx_t_9; + int __pyx_t_10; + long __pyx_t_11; + int __pyx_t_12; + Py_ssize_t __pyx_t_13; + Py_ssize_t __pyx_t_14; + Py_ssize_t __pyx_t_15; + Py_ssize_t __pyx_t_16; + Py_ssize_t __pyx_t_17; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; __Pyx_RefNannySetupContext("predict_lightfm", 0); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1157 - * cdef flt *it_repr + /* "lightfm/_lightfm_fast_no_openmp.pyx":1213 + * cdef int no_users * * no_examples = predictions.shape[0] # <<<<<<<<<<<<<< * - * with nogil: + * if precompute: */ __pyx_v_no_examples = (__pyx_v_predictions.shape[0]); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1159 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1215 * no_examples = predictions.shape[0] * - * with nogil: # <<<<<<<<<<<<<< + * if precompute: # <<<<<<<<<<<<<< + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + */ + __pyx_t_1 = (__pyx_v_precompute != 0); + if (__pyx_t_1) { + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1216 + * + * if precompute: + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) # <<<<<<<<<<<<<< + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + * no_features = unique_items.shape[0] + */ + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_unique); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_user_ids, 1, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); + __pyx_t_2 = 0; + __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return_inverse, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) { + PyObject* sequence = __pyx_t_5; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_4 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = Py_TYPE(__pyx_t_3)->tp_iternext; + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L5_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dc_int(__pyx_t_2); + if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_long(__pyx_t_4); + if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1216; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_unique_users = __pyx_t_7; + __pyx_t_7.memview = NULL; + __pyx_t_7.data = NULL; + __pyx_v_inverse_users = __pyx_t_8; + __pyx_t_8.memview = NULL; + __pyx_t_8.data = NULL; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1217 + * if precompute: + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) # <<<<<<<<<<<<<< + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] + */ + __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_unique); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_v_item_ids, 1, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return_inverse, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_5 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; + index = 0; __pyx_t_5 = __pyx_t_6(__pyx_t_4); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + index = 1; __pyx_t_2 = __pyx_t_6(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_4), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L7_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dc_int(__pyx_t_5); + if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_long(__pyx_t_2); + if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_unique_items = __pyx_t_7; + __pyx_t_7.memview = NULL; + __pyx_t_7.data = NULL; + __pyx_v_inverse_items = __pyx_t_8; + __pyx_t_8.memview = NULL; + __pyx_t_8.data = NULL; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1218 + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + * no_features = unique_items.shape[0] # <<<<<<<<<<<<<< + * no_users = unique_users.shape[0] + * + */ + __pyx_v_no_features = (__pyx_v_unique_items.shape[0]); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1219 + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] # <<<<<<<<<<<<<< + * + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) + */ + __pyx_v_no_users = (__pyx_v_unique_users.shape[0]); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1221 + * no_users = unique_users.shape[0] + * + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * it_reprs = malloc(sizeof(flt) * no_features *(lightfm.no_components + 1)) + * precompute_unique(item_features, + */ + __pyx_v_user_reprs = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc((((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * __pyx_v_no_users) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1222 + * + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) + * it_reprs = malloc(sizeof(flt) * no_features *(lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * precompute_unique(item_features, + * user_features, + */ + __pyx_v_it_reprs = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc((((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * __pyx_v_no_features) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1223 + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) + * it_reprs = malloc(sizeof(flt) * no_features *(lightfm.no_components + 1)) + * precompute_unique(item_features, # <<<<<<<<<<<<<< + * user_features, + * unique_users, + */ + __pyx_t_3 = __pyx_f_7lightfm_23_lightfm_fast_no_openmp_precompute_unique(__pyx_v_item_features, __pyx_v_user_features, __pyx_v_unique_users, __pyx_v_unique_items, __pyx_v_user_reprs, __pyx_v_it_reprs, __pyx_v_lightfm, __pyx_v_num_threads); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1223; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1215 + * no_examples = predictions.shape[0] * + * if precompute: # <<<<<<<<<<<<<< + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + */ + } + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1232 + * num_threads) + * + * with nogil: # <<<<<<<<<<<<<< * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) */ { #ifdef WITH_THREAD @@ -7480,120 +7999,220 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(CY #endif /*try:*/ { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1161 - * with nogil: + /* "lightfm/_lightfm_fast_no_openmp.pyx":1233 * + * with nogil: * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) - * + * for i in range(no_examples): */ __pyx_v_user_repr = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1162 - * + /* "lightfm/_lightfm_fast_no_openmp.pyx":1234 + * with nogil: * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< - * * for i in range(no_examples): + * if precompute: */ __pyx_v_it_repr = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1164 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1235 + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) - * * for i in range(no_examples): # <<<<<<<<<<<<<< - * - * compute_representation(user_features, + * if precompute: + * for j in range(lightfm.no_components + 1): */ - __pyx_t_1 = __pyx_v_no_examples; - for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { - __pyx_v_i = __pyx_t_2; + __pyx_t_9 = __pyx_v_no_examples; + for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { + __pyx_v_i = __pyx_t_10; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1170 - * lightfm.user_biases, - * lightfm, - * user_ids[i], # <<<<<<<<<<<<<< - * lightfm.user_scale, - * user_repr) + /* "lightfm/_lightfm_fast_no_openmp.pyx":1236 + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * for i in range(no_examples): + * if precompute: # <<<<<<<<<<<<<< + * for j in range(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] */ - __pyx_t_3 = __pyx_v_i; + __pyx_t_1 = (__pyx_v_precompute != 0); + if (__pyx_t_1) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1166 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1237 * for i in range(no_examples): - * - * compute_representation(user_features, # <<<<<<<<<<<<<< - * lightfm.user_features, - * lightfm.user_biases, + * if precompute: + * for j in range(lightfm.no_components + 1): # <<<<<<<<<<<<<< + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + */ + __pyx_t_11 = (__pyx_v_lightfm->no_components + 1); + for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) { + __pyx_v_j = __pyx_t_12; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1238 + * if precompute: + * for j in range(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] # <<<<<<<<<<<<<< + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + * else: */ - __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_user_ids.data) + __pyx_t_3)) ))), __pyx_v_lightfm->user_scale, __pyx_v_user_repr); + __pyx_t_13 = __pyx_v_i; + (__pyx_v_user_repr[__pyx_v_j]) = (__pyx_v_user_reprs[(((*((long *) ( /* dim=0 */ ((char *) (((long *) __pyx_v_inverse_users.data) + __pyx_t_13)) ))) * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1177 - * lightfm.item_biases, - * lightfm, - * item_ids[i], # <<<<<<<<<<<<<< - * lightfm.item_scale, - * it_repr) + /* "lightfm/_lightfm_fast_no_openmp.pyx":1239 + * for j in range(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] # <<<<<<<<<<<<<< + * else: + * compute_representation(user_features, */ - __pyx_t_4 = __pyx_v_i; + __pyx_t_14 = __pyx_v_i; + (__pyx_v_it_repr[__pyx_v_j]) = (__pyx_v_it_reprs[(((*((long *) ( /* dim=0 */ ((char *) (((long *) __pyx_v_inverse_items.data) + __pyx_t_14)) ))) * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]); + } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1173 - * lightfm.user_scale, - * user_repr) - * compute_representation(item_features, # <<<<<<<<<<<<<< - * lightfm.item_features, - * lightfm.item_biases, + /* "lightfm/_lightfm_fast_no_openmp.pyx":1236 + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * for i in range(no_examples): + * if precompute: # <<<<<<<<<<<<<< + * for j in range(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] */ - __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_item_ids.data) + __pyx_t_4)) ))), __pyx_v_lightfm->item_scale, __pyx_v_it_repr); + goto __pyx_L13; + } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1181 - * it_repr) + /* "lightfm/_lightfm_fast_no_openmp.pyx":1241 + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + * else: + * compute_representation(user_features, # <<<<<<<<<<<<<< + * lightfm.user_features, + * lightfm.user_biases, + */ + /*else*/ { + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1245 + * lightfm.user_biases, + * lightfm, + * user_ids[i], # <<<<<<<<<<<<<< + * lightfm.user_scale, + * user_repr) + */ + __pyx_t_15 = __pyx_v_i; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1241 + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + * else: + * compute_representation(user_features, # <<<<<<<<<<<<<< + * lightfm.user_features, + * lightfm.user_biases, + */ + __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_user_ids.data) + __pyx_t_15)) ))), __pyx_v_lightfm->user_scale, __pyx_v_user_repr); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1252 + * lightfm.item_biases, + * lightfm, + * item_ids[i], # <<<<<<<<<<<<<< + * lightfm.item_scale, + * it_repr) + */ + __pyx_t_16 = __pyx_v_i; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1248 + * lightfm.user_scale, + * user_repr) + * compute_representation(item_features, # <<<<<<<<<<<<<< + * lightfm.item_features, + * lightfm.item_biases, + */ + __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_item_ids.data) + __pyx_t_16)) ))), __pyx_v_lightfm->item_scale, __pyx_v_it_repr); + } + __pyx_L13:; + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1256 + * it_repr) * * predictions[i] = compute_prediction_from_repr(user_repr, # <<<<<<<<<<<<<< - * it_repr, - * lightfm.no_components) + * it_repr, + * lightfm.no_components) */ - __pyx_t_5 = __pyx_v_i; - *((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_predictions.data) + __pyx_t_5)) )) = __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); + __pyx_t_17 = __pyx_v_i; + *((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_predictions.data) + __pyx_t_17)) )) = __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1185 - * lightfm.no_components) + /* "lightfm/_lightfm_fast_no_openmp.pyx":1260 + * lightfm.no_components) * * free(user_repr) # <<<<<<<<<<<<<< * free(it_repr) - * + * if precompute: */ free(__pyx_v_user_repr); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1186 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1261 * * free(user_repr) * free(it_repr) # <<<<<<<<<<<<<< - * - * + * if precompute: + * free(user_reprs) */ free(__pyx_v_it_repr); } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1159 - * no_examples = predictions.shape[0] + /* "lightfm/_lightfm_fast_no_openmp.pyx":1232 + * num_threads) * * with nogil: # <<<<<<<<<<<<<< - * * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD Py_BLOCK_THREADS #endif - goto __pyx_L5; + goto __pyx_L10; } - __pyx_L5:; + __pyx_L10:; } } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1142 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1262 + * free(user_repr) + * free(it_repr) + * if precompute: # <<<<<<<<<<<<<< + * free(user_reprs) + * free(it_reprs) + */ + __pyx_t_1 = (__pyx_v_precompute != 0); + if (__pyx_t_1) { + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1263 + * free(it_repr) + * if precompute: + * free(user_reprs) # <<<<<<<<<<<<<< + * free(it_reprs) + * + */ + free(__pyx_v_user_reprs); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1264 + * if precompute: + * free(user_reprs) + * free(it_reprs) # <<<<<<<<<<<<<< + * + * + */ + free(__pyx_v_it_reprs); + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1262 + * free(user_repr) + * free(it_repr) + * if precompute: # <<<<<<<<<<<<<< + * free(user_reprs) + * free(it_reprs) + */ + } + + /* "lightfm/_lightfm_fast_no_openmp.pyx":1190 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -7603,6 +8222,21 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(CY /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1); + __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1); + __Pyx_AddTraceback("lightfm._lightfm_fast_no_openmp.predict_lightfm", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __PYX_XDEC_MEMVIEW(&__pyx_v_unique_users, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_unique_items, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_inverse_users, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_inverse_items, 1); __PYX_XDEC_MEMVIEW(&__pyx_v_user_ids, 1); __PYX_XDEC_MEMVIEW(&__pyx_v_item_ids, 1); __PYX_XDEC_MEMVIEW(&__pyx_v_predictions, 1); @@ -7611,7 +8245,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_8predict_lightfm(CY return __pyx_r; } -/* "lightfm/_lightfm_fast_no_openmp.pyx":1189 +/* "lightfm/_lightfm_fast_no_openmp.pyx":1267 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -7662,36 +8296,36 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_11predict_ranks(PyO case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_user_features)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_test_interactions)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_train_interactions)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 4: if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ranks)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 5: if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_lightfm)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 6: if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_threads)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_ranks") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_ranks") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 7) { goto __pyx_L5_argtuple_error; @@ -7708,23 +8342,23 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_11predict_ranks(PyO __pyx_v_user_features = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)values[1]); __pyx_v_test_interactions = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)values[2]); __pyx_v_train_interactions = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)values[3]); - __pyx_v_ranks = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt(values[4]); if (unlikely(!__pyx_v_ranks.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_ranks = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt(values[4]); if (unlikely(!__pyx_v_ranks.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1271; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_v_lightfm = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_FastLightFM *)values[5]); - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1195; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1273; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("lightfm._lightfm_fast_no_openmp.predict_ranks", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_test_interactions), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "test_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1191; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_train_interactions), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "train_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1194; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1268; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_test_interactions), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "test_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1269; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_train_interactions), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "train_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1272; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(__pyx_self, __pyx_v_item_features, __pyx_v_user_features, __pyx_v_test_interactions, __pyx_v_train_interactions, __pyx_v_ranks, __pyx_v_lightfm, __pyx_v_num_threads); /* function exit code */ @@ -7762,7 +8396,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT Py_ssize_t __pyx_t_10; __Pyx_RefNannySetupContext("predict_ranks", 0); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1205 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1283 * cdef flt prediction, rank * * predictions_size = 0 # <<<<<<<<<<<<<< @@ -7771,7 +8405,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_predictions_size = 0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1209 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1287 * # Figure out the max size of the predictions * # buffer. * for user_id in range(test_interactions.rows): # <<<<<<<<<<<<<< @@ -7782,7 +8416,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { __pyx_v_user_id = __pyx_t_2; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1210 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1288 * # buffer. * for user_id in range(test_interactions.rows): * predictions_size = int_max(predictions_size, # <<<<<<<<<<<<<< @@ -7792,7 +8426,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT __pyx_v_predictions_size = __pyx_f_7lightfm_23_lightfm_fast_no_openmp_int_max(__pyx_v_predictions_size, (((struct __pyx_vtabstruct_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_end(__pyx_v_test_interactions, __pyx_v_user_id) - ((struct __pyx_vtabstruct_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_start(__pyx_v_test_interactions, __pyx_v_user_id))); } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1214 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1292 * - test_interactions.get_row_start(user_id)) * * with nogil: # <<<<<<<<<<<<<< @@ -7806,7 +8440,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT #endif /*try:*/ { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1216 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1294 * with nogil: * * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< @@ -7815,7 +8449,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_user_repr = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1217 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1295 * * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< @@ -7824,7 +8458,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_it_repr = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1218 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1296 * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * item_ids = malloc(sizeof(int) * predictions_size) # <<<<<<<<<<<<<< @@ -7833,7 +8467,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_item_ids = ((int *)malloc(((sizeof(int)) * __pyx_v_predictions_size))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1219 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1297 * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * item_ids = malloc(sizeof(int) * predictions_size) * predictions = malloc(sizeof(flt) * predictions_size) # <<<<<<<<<<<<<< @@ -7842,7 +8476,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_predictions = ((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)) * __pyx_v_predictions_size))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1221 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1299 * predictions = malloc(sizeof(flt) * predictions_size) * * for user_id in range(test_interactions.rows): # <<<<<<<<<<<<<< @@ -7853,7 +8487,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { __pyx_v_user_id = __pyx_t_2; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1223 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1301 * for user_id in range(test_interactions.rows): * * row_start = test_interactions.get_row_start(user_id) # <<<<<<<<<<<<<< @@ -7862,7 +8496,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_row_start = ((struct __pyx_vtabstruct_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_start(__pyx_v_test_interactions, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1224 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1302 * * row_start = test_interactions.get_row_start(user_id) * row_stop = test_interactions.get_row_end(user_id) # <<<<<<<<<<<<<< @@ -7871,7 +8505,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_row_stop = ((struct __pyx_vtabstruct_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_end(__pyx_v_test_interactions, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1226 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1304 * row_stop = test_interactions.get_row_end(user_id) * * if row_stop == row_start: # <<<<<<<<<<<<<< @@ -7881,7 +8515,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT __pyx_t_3 = ((__pyx_v_row_stop == __pyx_v_row_start) != 0); if (__pyx_t_3) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1228 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1306 * if row_stop == row_start: * # No test interactions for this user * continue # <<<<<<<<<<<<<< @@ -7890,7 +8524,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ goto __pyx_L8_continue; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1226 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1304 * row_stop = test_interactions.get_row_end(user_id) * * if row_stop == row_start: # <<<<<<<<<<<<<< @@ -7899,7 +8533,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1230 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1308 * continue * * compute_representation(user_features, # <<<<<<<<<<<<<< @@ -7908,7 +8542,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, __pyx_v_user_id, __pyx_v_lightfm->user_scale, __pyx_v_user_repr); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1240 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1318 * # Compute predictions for the items whose * # ranks we want to know * for i in range(row_stop - row_start): # <<<<<<<<<<<<<< @@ -7919,7 +8553,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { __pyx_v_i = __pyx_t_5; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1242 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1320 * for i in range(row_stop - row_start): * * item_id = test_interactions.indices[row_start + i] # <<<<<<<<<<<<<< @@ -7929,7 +8563,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT __pyx_t_6 = (__pyx_v_row_start + __pyx_v_i); __pyx_v_item_id = (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_test_interactions->indices.data) + __pyx_t_6)) ))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1244 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1322 * item_id = test_interactions.indices[row_start + i] * * compute_representation(item_features, # <<<<<<<<<<<<<< @@ -7938,7 +8572,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, __pyx_v_item_id, __pyx_v_lightfm->item_scale, __pyx_v_it_repr); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1252 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1330 * it_repr) * * item_ids[i] = item_id # <<<<<<<<<<<<<< @@ -7947,7 +8581,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ (__pyx_v_item_ids[__pyx_v_i]) = __pyx_v_item_id; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1253 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1331 * * item_ids[i] = item_id * predictions[i] = compute_prediction_from_repr(user_repr, # <<<<<<<<<<<<<< @@ -7957,7 +8591,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT (__pyx_v_predictions[__pyx_v_i]) = __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1258 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1336 * * # Now we can zip through all the other items and compute ranks * for item_id in range(test_interactions.cols): # <<<<<<<<<<<<<< @@ -7968,7 +8602,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { __pyx_v_item_id = __pyx_t_5; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1260 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1338 * for item_id in range(test_interactions.cols): * * if in_positives(item_id, user_id, train_interactions): # <<<<<<<<<<<<<< @@ -7978,7 +8612,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT __pyx_t_3 = (__pyx_f_7lightfm_23_lightfm_fast_no_openmp_in_positives(__pyx_v_item_id, __pyx_v_user_id, __pyx_v_train_interactions) != 0); if (__pyx_t_3) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1261 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1339 * * if in_positives(item_id, user_id, train_interactions): * continue # <<<<<<<<<<<<<< @@ -7987,7 +8621,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ goto __pyx_L13_continue; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1260 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1338 * for item_id in range(test_interactions.cols): * * if in_positives(item_id, user_id, train_interactions): # <<<<<<<<<<<<<< @@ -7996,7 +8630,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1263 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1341 * continue * * compute_representation(item_features, # <<<<<<<<<<<<<< @@ -8005,7 +8639,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, __pyx_v_item_id, __pyx_v_lightfm->item_scale, __pyx_v_it_repr); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1270 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1348 * lightfm.item_scale, * it_repr) * prediction = compute_prediction_from_repr(user_repr, # <<<<<<<<<<<<<< @@ -8014,7 +8648,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ __pyx_v_prediction = __pyx_f_7lightfm_23_lightfm_fast_no_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1274 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1352 * lightfm.no_components) * * for i in range(row_stop - row_start): # <<<<<<<<<<<<<< @@ -8025,7 +8659,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) { __pyx_v_i = __pyx_t_8; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1275 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1353 * * for i in range(row_stop - row_start): * if item_id != item_ids[i] and prediction > predictions[i]: # <<<<<<<<<<<<<< @@ -8043,7 +8677,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT __pyx_L19_bool_binop_done:; if (__pyx_t_3) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1276 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1354 * for i in range(row_stop - row_start): * if item_id != item_ids[i] and prediction > predictions[i]: * ranks[row_start + i] += 1.0 # <<<<<<<<<<<<<< @@ -8053,7 +8687,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT __pyx_t_10 = (__pyx_v_row_start + __pyx_v_i); *((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) __pyx_v_ranks.data) + __pyx_t_10)) )) += 1.0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1275 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1353 * * for i in range(row_stop - row_start): * if item_id != item_ids[i] and prediction > predictions[i]: # <<<<<<<<<<<<<< @@ -8067,7 +8701,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT __pyx_L8_continue:; } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1278 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1356 * ranks[row_start + i] += 1.0 * * free(user_repr) # <<<<<<<<<<<<<< @@ -8076,7 +8710,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ free(__pyx_v_user_repr); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1279 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1357 * * free(user_repr) * free(it_repr) # <<<<<<<<<<<<<< @@ -8085,7 +8719,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT */ free(__pyx_v_it_repr); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1280 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1358 * free(user_repr) * free(it_repr) * free(predictions) # <<<<<<<<<<<<<< @@ -8095,7 +8729,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT free(__pyx_v_predictions); } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1214 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1292 * - test_interactions.get_row_start(user_id)) * * with nogil: # <<<<<<<<<<<<<< @@ -8113,7 +8747,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT } } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1189 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1267 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -8129,7 +8763,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_10predict_ranks(CYT return __pyx_r; } -/* "lightfm/_lightfm_fast_no_openmp.pyx":1283 +/* "lightfm/_lightfm_fast_no_openmp.pyx":1361 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< @@ -8175,26 +8809,26 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_13calculate_auc_fro case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_train_positives)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_rank_data)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_auc)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 4: if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_threads)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate_auc_from_rank") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate_auc_from_rank") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { goto __pyx_L5_argtuple_error; @@ -8206,20 +8840,20 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_13calculate_auc_fro values[4] = PyTuple_GET_ITEM(__pyx_args, 4); } __pyx_v_ranks = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)values[0]); - __pyx_v_num_train_positives = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[1]); if (unlikely(!__pyx_v_num_train_positives.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_rank_data = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt(values[2]); if (unlikely(!__pyx_v_rank_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1285; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_auc = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt(values[3]); if (unlikely(!__pyx_v_auc.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_num_train_positives = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[1]); if (unlikely(!__pyx_v_num_train_positives.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1362; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_rank_data = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt(values[2]); if (unlikely(!__pyx_v_rank_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1363; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_auc = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt(values[3]); if (unlikely(!__pyx_v_auc.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1365; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("lightfm._lightfm_fast_no_openmp.calculate_auc_from_rank", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ranks), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "ranks", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ranks), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "ranks", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_from_rank(__pyx_self, __pyx_v_ranks, __pyx_v_num_train_positives, __pyx_v_rank_data, __pyx_v_auc, __pyx_v_num_threads); /* function exit code */ @@ -8255,7 +8889,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro Py_ssize_t __pyx_t_12; __Pyx_RefNannySetupContext("calculate_auc_from_rank", 0); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1292 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1370 * cdef flt rank * * with nogil: # <<<<<<<<<<<<<< @@ -8269,7 +8903,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro #endif /*try:*/ { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1293 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1371 * * with nogil: * for user_id in range(ranks.rows): # <<<<<<<<<<<<<< @@ -8280,7 +8914,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { __pyx_v_user_id = __pyx_t_2; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1295 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1373 * for user_id in range(ranks.rows): * * row_start = ranks.get_row_start(user_id) # <<<<<<<<<<<<<< @@ -8289,7 +8923,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ __pyx_v_row_start = ((struct __pyx_vtabstruct_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)__pyx_v_ranks->__pyx_vtab)->get_row_start(__pyx_v_ranks, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1296 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1374 * * row_start = ranks.get_row_start(user_id) * row_stop = ranks.get_row_end(user_id) # <<<<<<<<<<<<<< @@ -8298,7 +8932,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ __pyx_v_row_stop = ((struct __pyx_vtabstruct_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)__pyx_v_ranks->__pyx_vtab)->get_row_end(__pyx_v_ranks, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1298 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1376 * row_stop = ranks.get_row_end(user_id) * * num_positives = row_stop - row_start # <<<<<<<<<<<<<< @@ -8307,7 +8941,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ __pyx_v_num_positives = (__pyx_v_row_stop - __pyx_v_row_start); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1299 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1377 * * num_positives = row_stop - row_start * num_negatives = ranks.cols - ((row_stop - row_start) + num_train_positives[user_id]) # <<<<<<<<<<<<<< @@ -8317,7 +8951,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro __pyx_t_3 = __pyx_v_user_id; __pyx_v_num_negatives = (__pyx_v_ranks->cols - ((__pyx_v_row_stop - __pyx_v_row_start) + (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_num_train_positives.data) + __pyx_t_3)) ))))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1303 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1381 * # If there is only one class present, * # return 0.5. * if num_positives == 0 or num_negatives == ranks.cols: # <<<<<<<<<<<<<< @@ -8335,7 +8969,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro __pyx_L9_bool_binop_done:; if (__pyx_t_4) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1304 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1382 * # return 0.5. * if num_positives == 0 or num_negatives == ranks.cols: * auc[user_id] = 0.5 # <<<<<<<<<<<<<< @@ -8345,7 +8979,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro __pyx_t_6 = __pyx_v_user_id; *((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) __pyx_v_auc.data) + __pyx_t_6)) )) = 0.5; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1305 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1383 * if num_positives == 0 or num_negatives == ranks.cols: * auc[user_id] = 0.5 * continue # <<<<<<<<<<<<<< @@ -8354,7 +8988,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ goto __pyx_L6_continue; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1303 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1381 * # If there is only one class present, * # return 0.5. * if num_positives == 0 or num_negatives == ranks.cols: # <<<<<<<<<<<<<< @@ -8363,7 +8997,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1309 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1387 * # Sort the positives according to * # increasing rank. * qsort(&rank_data[row_start], # <<<<<<<<<<<<<< @@ -8372,7 +9006,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ __pyx_t_7 = __pyx_v_row_start; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1312 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1390 * num_positives, * sizeof(flt), * flt_compare) # <<<<<<<<<<<<<< @@ -8381,7 +9015,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ qsort((&(*((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) __pyx_v_rank_data.data) + __pyx_t_7)) )))), __pyx_v_num_positives, (sizeof(__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt)), __pyx_f_7lightfm_23_lightfm_fast_no_openmp_flt_compare); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1314 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1392 * flt_compare) * * for i in range(num_positives): # <<<<<<<<<<<<<< @@ -8392,7 +9026,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1316 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1394 * for i in range(num_positives): * * rank = ranks.data[row_start + i] # <<<<<<<<<<<<<< @@ -8402,7 +9036,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro __pyx_t_10 = (__pyx_v_row_start + __pyx_v_i); __pyx_v_rank = (*((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) __pyx_v_ranks->data.data) + __pyx_t_10)) ))); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1322 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1400 * # by i. Ignore ties but ensure that * # the resulting rank is nonnegative. * rank = rank - i # <<<<<<<<<<<<<< @@ -8411,7 +9045,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ __pyx_v_rank = (__pyx_v_rank - __pyx_v_i); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1324 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1402 * rank = rank - i * * if rank < 0: # <<<<<<<<<<<<<< @@ -8421,7 +9055,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro __pyx_t_4 = ((__pyx_v_rank < 0.0) != 0); if (__pyx_t_4) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1325 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1403 * * if rank < 0: * rank = 0 # <<<<<<<<<<<<<< @@ -8430,7 +9064,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ __pyx_v_rank = 0.0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1324 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1402 * rank = rank - i * * if rank < 0: # <<<<<<<<<<<<<< @@ -8439,7 +9073,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro */ } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1331 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1409 * # of rank inversion. * # print(row_start, row_stop, ranks.data[row_stop + i], 1.0 - rank, num_negatives) * auc[user_id] += 1.0 - rank / num_negatives # <<<<<<<<<<<<<< @@ -8450,7 +9084,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro *((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) __pyx_v_auc.data) + __pyx_t_11)) )) += (1.0 - (__pyx_v_rank / __pyx_v_num_negatives)); } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1333 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1411 * auc[user_id] += 1.0 - rank / num_negatives * * if num_positives != 0: # <<<<<<<<<<<<<< @@ -8460,7 +9094,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro __pyx_t_4 = ((__pyx_v_num_positives != 0) != 0); if (__pyx_t_4) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1334 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1412 * * if num_positives != 0: * auc[user_id] /= num_positives # <<<<<<<<<<<<<< @@ -8470,7 +9104,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro __pyx_t_12 = __pyx_v_user_id; *((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_23_lightfm_fast_no_openmp_flt *) __pyx_v_auc.data) + __pyx_t_12)) )) /= __pyx_v_num_positives; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1333 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1411 * auc[user_id] += 1.0 - rank / num_negatives * * if num_positives != 0: # <<<<<<<<<<<<<< @@ -8482,7 +9116,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro } } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1292 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1370 * cdef flt rank * * with nogil: # <<<<<<<<<<<<<< @@ -8500,7 +9134,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro } } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1283 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1361 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< @@ -8518,7 +9152,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_12calculate_auc_fro return __pyx_r; } -/* "lightfm/_lightfm_fast_no_openmp.pyx":1338 +/* "lightfm/_lightfm_fast_no_openmp.pyx":1416 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< @@ -8560,16 +9194,16 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_15__test_in_positiv case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_col)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mat)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__test_in_positives") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__test_in_positives") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { goto __pyx_L5_argtuple_error; @@ -8578,19 +9212,19 @@ static PyObject *__pyx_pw_7lightfm_23_lightfm_fast_no_openmp_15__test_in_positiv values[1] = PyTuple_GET_ITEM(__pyx_args, 1); values[2] = PyTuple_GET_ITEM(__pyx_args, 2); } - __pyx_v_row = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_row == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_col = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_col == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_row = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_row == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_col = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_col == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_v_mat = ((struct __pyx_obj_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix *)values[2]); } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("lightfm._lightfm_fast_no_openmp.__test_in_positives", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mat), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "mat", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mat), __pyx_ptype_7lightfm_23_lightfm_fast_no_openmp_CSRMatrix, 1, "mat", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7lightfm_23_lightfm_fast_no_openmp_14__test_in_positives(__pyx_self, __pyx_v_row, __pyx_v_col, __pyx_v_mat); /* function exit code */ @@ -8608,7 +9242,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_14__test_in_positiv int __pyx_t_1; __Pyx_RefNannySetupContext("__test_in_positives", 0); - /* "lightfm/_lightfm_fast_no_openmp.pyx":1340 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1418 * def __test_in_positives(int row, int col, CSRMatrix mat): * * if in_positives(col, row, mat): # <<<<<<<<<<<<<< @@ -8618,7 +9252,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_14__test_in_positiv __pyx_t_1 = (__pyx_f_7lightfm_23_lightfm_fast_no_openmp_in_positives(__pyx_v_col, __pyx_v_row, __pyx_v_mat) != 0); if (__pyx_t_1) { - /* "lightfm/_lightfm_fast_no_openmp.pyx":1341 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1419 * * if in_positives(col, row, mat): * return True # <<<<<<<<<<<<<< @@ -8630,7 +9264,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_14__test_in_positiv __pyx_r = Py_True; goto __pyx_L0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1340 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1418 * def __test_in_positives(int row, int col, CSRMatrix mat): * * if in_positives(col, row, mat): # <<<<<<<<<<<<<< @@ -8639,10 +9273,11 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_14__test_in_positiv */ } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1343 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1421 * return True * else: * return False # <<<<<<<<<<<<<< + * */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -8651,7 +9286,7 @@ static PyObject *__pyx_pf_7lightfm_23_lightfm_fast_no_openmp_14__test_in_positiv goto __pyx_L0; } - /* "lightfm/_lightfm_fast_no_openmp.pyx":1338 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1416 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< @@ -21136,7 +21771,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1}, {&__pyx_n_s_gamma, __pyx_k_gamma, sizeof(__pyx_k_gamma), 0, 0, 1, 1}, {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0}, - {&__pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_k_home_maciej_Code_lightfm_lightf, sizeof(__pyx_k_home_maciej_Code_lightfm_lightf), 0, 0, 1, 0}, + {&__pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_k_home_paolo_raisDataScience_reco, sizeof(__pyx_k_home_paolo_raisDataScience_reco), 0, 0, 1, 0}, {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1}, {&__pyx_n_s_iinfo, __pyx_k_iinfo, sizeof(__pyx_k_iinfo), 0, 0, 1, 1}, @@ -21145,7 +21780,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_indptr, __pyx_k_indptr, sizeof(__pyx_k_indptr), 0, 0, 1, 1}, {&__pyx_n_s_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 0, 1, 1}, {&__pyx_n_s_interactions, __pyx_k_interactions, sizeof(__pyx_k_interactions), 0, 0, 1, 1}, + {&__pyx_n_s_inverse_items, __pyx_k_inverse_items, sizeof(__pyx_k_inverse_items), 0, 0, 1, 1}, + {&__pyx_n_s_inverse_users, __pyx_k_inverse_users, sizeof(__pyx_k_inverse_users), 0, 0, 1, 1}, {&__pyx_n_s_it_repr, __pyx_k_it_repr, sizeof(__pyx_k_it_repr), 0, 0, 1, 1}, + {&__pyx_n_s_it_reprs, __pyx_k_it_reprs, sizeof(__pyx_k_it_reprs), 0, 0, 1, 1}, {&__pyx_n_s_item_alpha, __pyx_k_item_alpha, sizeof(__pyx_k_item_alpha), 0, 0, 1, 1}, {&__pyx_n_s_item_bias_gradients, __pyx_k_item_bias_gradients, sizeof(__pyx_k_item_bias_gradients), 0, 0, 1, 1}, {&__pyx_n_s_item_bias_momentum, __pyx_k_item_bias_momentum, sizeof(__pyx_k_item_bias_momentum), 0, 0, 1, 1}, @@ -21178,7 +21816,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_negative_prediction, __pyx_k_negative_prediction, sizeof(__pyx_k_negative_prediction), 0, 0, 1, 1}, {&__pyx_n_s_no_components, __pyx_k_no_components, sizeof(__pyx_k_no_components), 0, 0, 1, 1}, {&__pyx_n_s_no_examples, __pyx_k_no_examples, sizeof(__pyx_k_no_examples), 0, 0, 1, 1}, + {&__pyx_n_s_no_features, __pyx_k_no_features, sizeof(__pyx_k_no_features), 0, 0, 1, 1}, {&__pyx_n_s_no_positives, __pyx_k_no_positives, sizeof(__pyx_k_no_positives), 0, 0, 1, 1}, + {&__pyx_n_s_no_users, __pyx_k_no_users, sizeof(__pyx_k_no_users), 0, 0, 1, 1}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, {&__pyx_n_s_num_negatives, __pyx_k_num_negatives, sizeof(__pyx_k_num_negatives), 0, 0, 1, 1}, {&__pyx_n_s_num_positives, __pyx_k_num_positives, sizeof(__pyx_k_num_positives), 0, 0, 1, 1}, @@ -21191,6 +21831,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_pos_pairs, __pyx_k_pos_pairs, sizeof(__pyx_k_pos_pairs), 0, 0, 1, 1}, {&__pyx_n_s_positive_item_id, __pyx_k_positive_item_id, sizeof(__pyx_k_positive_item_id), 0, 0, 1, 1}, {&__pyx_n_s_positive_prediction, __pyx_k_positive_prediction, sizeof(__pyx_k_positive_prediction), 0, 0, 1, 1}, + {&__pyx_n_s_precompute, __pyx_k_precompute, sizeof(__pyx_k_precompute), 0, 0, 1, 1}, {&__pyx_n_s_predict_lightfm, __pyx_k_predict_lightfm, sizeof(__pyx_k_predict_lightfm), 0, 0, 1, 1}, {&__pyx_n_s_predict_ranks, __pyx_k_predict_ranks, sizeof(__pyx_k_predict_ranks), 0, 0, 1, 1}, {&__pyx_n_s_prediction, __pyx_k_prediction, sizeof(__pyx_k_prediction), 0, 0, 1, 1}, @@ -21205,6 +21846,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_rank, __pyx_k_rank, sizeof(__pyx_k_rank), 0, 0, 1, 1}, {&__pyx_n_s_rank_data, __pyx_k_rank_data, sizeof(__pyx_k_rank_data), 0, 0, 1, 1}, {&__pyx_n_s_ranks, __pyx_k_ranks, sizeof(__pyx_k_ranks), 0, 0, 1, 1}, + {&__pyx_n_s_return_inverse, __pyx_k_return_inverse, sizeof(__pyx_k_return_inverse), 0, 0, 1, 1}, {&__pyx_n_s_rho, __pyx_k_rho, sizeof(__pyx_k_rho), 0, 0, 1, 1}, {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1}, {&__pyx_n_s_row_start, __pyx_k_row_start, sizeof(__pyx_k_row_start), 0, 0, 1, 1}, @@ -21230,6 +21872,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1}, {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0}, {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0}, + {&__pyx_n_s_unique, __pyx_k_unique, sizeof(__pyx_k_unique), 0, 0, 1, 1}, + {&__pyx_n_s_unique_items, __pyx_k_unique_items, sizeof(__pyx_k_unique_items), 0, 0, 1, 1}, + {&__pyx_n_s_unique_users, __pyx_k_unique_users, sizeof(__pyx_k_unique_users), 0, 0, 1, 1}, {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1}, {&__pyx_n_s_user_alpha, __pyx_k_user_alpha, sizeof(__pyx_k_user_alpha), 0, 0, 1, 1}, {&__pyx_n_s_user_bias_gradients, __pyx_k_user_bias_gradients, sizeof(__pyx_k_user_bias_gradients), 0, 0, 1, 1}, @@ -21243,6 +21888,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_user_pids_start, __pyx_k_user_pids_start, sizeof(__pyx_k_user_pids_start), 0, 0, 1, 1}, {&__pyx_n_s_user_pids_stop, __pyx_k_user_pids_stop, sizeof(__pyx_k_user_pids_stop), 0, 0, 1, 1}, {&__pyx_n_s_user_repr, __pyx_k_user_repr, sizeof(__pyx_k_user_repr), 0, 0, 1, 1}, + {&__pyx_n_s_user_reprs, __pyx_k_user_reprs, sizeof(__pyx_k_user_reprs), 0, 0, 1, 1}, {&__pyx_n_s_weight, __pyx_k_weight, sizeof(__pyx_k_weight), 0, 0, 1, 1}, {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1}, {&__pyx_n_s_y_row, __pyx_k_y_row, sizeof(__pyx_k_y_row), 0, 0, 1, 1}, @@ -21422,7 +22068,7 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__14 = PyTuple_Pack(24, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_Y, __pyx_n_s_sample_weight, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_item_id, __pyx_n_s_row, __pyx_n_s_prediction, __pyx_n_s_loss, __pyx_n_s_y, __pyx_n_s_y_row, __pyx_n_s_weight, __pyx_n_s_user_repr, __pyx_n_s_it_repr); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 671; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__14); __Pyx_GIVEREF(__pyx_tuple__14); - __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(12, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_logistic, 671, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 671; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(12, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_logistic, 671, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 671; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "lightfm/_lightfm_fast_no_openmp.pyx":756 * @@ -21434,7 +22080,7 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__16 = PyTuple_Pack(31, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_interactions, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_Y, __pyx_n_s_sample_weight, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_num_threads, __pyx_n_s_random_state, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_positive_item_id, __pyx_n_s_gamma, __pyx_n_s_negative_item_id, __pyx_n_s_sampled, __pyx_n_s_row, __pyx_n_s_positive_prediction, __pyx_n_s_negative_prediction, __pyx_n_s_loss, __pyx_n_s_MAX_LOSS, __pyx_n_s_weight, __pyx_n_s_user_repr, __pyx_n_s_pos_it_repr, __pyx_n_s_neg_it_repr, __pyx_n_s_random_states); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__16); __Pyx_GIVEREF(__pyx_tuple__16); - __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(14, 0, 31, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_warp, 756, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(14, 0, 31, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_warp, 756, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "lightfm/_lightfm_fast_no_openmp.pyx":882 * @@ -21446,7 +22092,7 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__18 = PyTuple_Pack(37, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_data, __pyx_n_s_user_ids, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_k, __pyx_n_s_n, __pyx_n_s_num_threads, __pyx_n_s_random_state, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_positive_item_id, __pyx_n_s_gamma, __pyx_n_s_negative_item_id, __pyx_n_s_sampled, __pyx_n_s_row, __pyx_n_s_sampled_positive_item_id, __pyx_n_s_user_pids_start, __pyx_n_s_user_pids_stop, __pyx_n_s_no_positives, __pyx_n_s_POS_SAMPLES, __pyx_n_s_positive_prediction, __pyx_n_s_negative_prediction, __pyx_n_s_loss, __pyx_n_s_MAX_LOSS, __pyx_n_s_sampled_positive_prediction, __pyx_n_s_user_repr, __pyx_n_s_pos_it_repr, __pyx_n_s_neg_it_repr, __pyx_n_s_pos_pairs, __pyx_n_s_random_states); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__18); __Pyx_GIVEREF(__pyx_tuple__18); - __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(13, 0, 37, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_warp_kos, 882, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(13, 0, 37, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_warp_kos, 882, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "lightfm/_lightfm_fast_no_openmp.pyx":1036 * @@ -21458,55 +22104,55 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__20 = PyTuple_Pack(28, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_interactions, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_Y, __pyx_n_s_sample_weight, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_num_threads, __pyx_n_s_random_state, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_positive_item_id, __pyx_n_s_negative_item_id, __pyx_n_s_sampled, __pyx_n_s_row, __pyx_n_s_positive_prediction, __pyx_n_s_negative_prediction, __pyx_n_s_weight, __pyx_n_s_random_states, __pyx_n_s_user_repr, __pyx_n_s_pos_it_repr, __pyx_n_s_neg_it_repr); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1036; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__20); __Pyx_GIVEREF(__pyx_tuple__20); - __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(14, 0, 28, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_bpr, 1036, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1036; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(14, 0, 28, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_bpr, 1036, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1036; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_no_openmp.pyx":1142 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1190 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * int[::1] user_ids, */ - __pyx_tuple__22 = PyTuple_Pack(11, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_predictions, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_repr, __pyx_n_s_it_repr); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__22 = PyTuple_Pack(21, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_predictions, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_precompute, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_no_examples, __pyx_n_s_user_repr, __pyx_n_s_it_repr, __pyx_n_s_user_reprs, __pyx_n_s_it_reprs, __pyx_n_s_unique_users, __pyx_n_s_unique_items, __pyx_n_s_inverse_users, __pyx_n_s_inverse_items, __pyx_n_s_no_features, __pyx_n_s_no_users); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__22); __Pyx_GIVEREF(__pyx_tuple__22); - __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(7, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_predict_lightfm, 1142, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(8, 0, 21, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_predict_lightfm, 1190, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_no_openmp.pyx":1189 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1267 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * CSRMatrix test_interactions, */ - __pyx_tuple__24 = PyTuple_Pack(20, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_test_interactions, __pyx_n_s_train_interactions, __pyx_n_s_ranks, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_item_id, __pyx_n_s_predictions_size, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_user_repr, __pyx_n_s_it_repr, __pyx_n_s_predictions, __pyx_n_s_prediction, __pyx_n_s_rank, __pyx_n_s_item_ids); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__24 = PyTuple_Pack(20, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_test_interactions, __pyx_n_s_train_interactions, __pyx_n_s_ranks, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_item_id, __pyx_n_s_predictions_size, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_user_repr, __pyx_n_s_it_repr, __pyx_n_s_predictions, __pyx_n_s_prediction, __pyx_n_s_rank, __pyx_n_s_item_ids); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__24); __Pyx_GIVEREF(__pyx_tuple__24); - __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(7, 0, 20, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_predict_ranks, 1189, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(7, 0, 20, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_predict_ranks, 1267, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_no_openmp.pyx":1283 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1361 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< * int[::1] num_train_positives, * flt[::1] rank_data, */ - __pyx_tuple__26 = PyTuple_Pack(13, __pyx_n_s_ranks, __pyx_n_s_num_train_positives, __pyx_n_s_rank_data, __pyx_n_s_auc, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_num_negatives, __pyx_n_s_num_positives, __pyx_n_s_rank); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__26 = PyTuple_Pack(13, __pyx_n_s_ranks, __pyx_n_s_num_train_positives, __pyx_n_s_rank_data, __pyx_n_s_auc, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_num_negatives, __pyx_n_s_num_positives, __pyx_n_s_rank); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__26); __Pyx_GIVEREF(__pyx_tuple__26); - __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_calculate_auc_from_rank, 1283, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_calculate_auc_from_rank, 1361, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_no_openmp.pyx":1338 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1416 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< * * if in_positives(col, row, mat): */ - __pyx_tuple__28 = PyTuple_Pack(3, __pyx_n_s_row, __pyx_n_s_col, __pyx_n_s_mat); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__28 = PyTuple_Pack(3, __pyx_n_s_row, __pyx_n_s_col, __pyx_n_s_mat); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__28); __Pyx_GIVEREF(__pyx_tuple__28); - __pyx_codeobj__29 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_test_in_positives, 1338, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__29 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_test_in_positives, 1416, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "View.MemoryView":278 * return self.name @@ -21777,52 +22423,52 @@ PyMODINIT_FUNC PyInit__lightfm_fast_no_openmp(void) if (PyDict_SetItem(__pyx_d, __pyx_n_s_fit_bpr, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1036; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1142 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1190 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * int[::1] user_ids, */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_9predict_lightfm, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_9predict_lightfm, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_lightfm, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_lightfm, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1189 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1267 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * CSRMatrix test_interactions, */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_11predict_ranks, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_11predict_ranks, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_ranks, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1189; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_ranks, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1283 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1361 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< * int[::1] num_train_positives, * flt[::1] rank_data, */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_13calculate_auc_from_rank, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_13calculate_auc_from_rank, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_auc_from_rank, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_auc_from_rank, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_no_openmp.pyx":1338 + /* "lightfm/_lightfm_fast_no_openmp.pyx":1416 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< * * if in_positives(col, row, mat): */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_15__test_in_positives, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_23_lightfm_fast_no_openmp_15__test_in_positives, NULL, __pyx_n_s_lightfm__lightfm_fast_no_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_in_positives, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_in_positives, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1416; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "lightfm/_lightfm_fast_no_openmp.pyx":1 @@ -24328,7 +24974,7 @@ static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) case -2: if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { @@ -24544,6 +25190,17 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { } } +static PyObject *__pyx_memview_get_int(const char *itemp) { + return (PyObject *) __Pyx_PyInt_From_int(*(int *) itemp); +} +static int __pyx_memview_set_int(const char *itemp, PyObject *obj) { + int value = __Pyx_PyInt_As_int(obj); + if ((value == (int)-1) && PyErr_Occurred()) + return 0; + *(int *) itemp = value; + return 1; +} + static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs, char order, int ndim) @@ -24754,7 +25411,7 @@ static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) { const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (char) 0; - case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, (sdigit) (-(sdigit)digits[0])) + case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(char, digit, +digits[0]) case -2: if (8 * sizeof(char) - 1 > 1 * PyLong_SHIFT) { @@ -24938,7 +25595,7 @@ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) case -2: if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { @@ -25069,6 +25726,28 @@ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_uns return result; } +static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_long(PyObject *obj) { + __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_BufFmt_StackElem stack[1]; + int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) }; + int retcode; + if (obj == Py_None) { + result.memview = (struct __pyx_memoryview_obj *) Py_None; + return result; + } + retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG, + (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1, + &__Pyx_TypeInfo_long, stack, + &result, obj); + if (unlikely(retcode == -1)) + goto __pyx_fail; + return result; +__pyx_fail: + result.memview = NULL; + result.data = NULL; + return result; +} + static int __Pyx_check_binary_version(void) { char ctversion[4], rtversion[4]; PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); diff --git a/lightfm/_lightfm_fast_openmp.c b/lightfm/_lightfm_fast_openmp.c index 66e2d58f..2c291244 100644 --- a/lightfm/_lightfm_fast_openmp.c +++ b/lightfm/_lightfm_fast_openmp.c @@ -1,9 +1,9 @@ -/* Generated by Cython 0.23.5 */ +/* Generated by Cython 0.23.4 */ /* BEGIN: Cython Metadata { "distutils": { - "depends": [], + "depends": [], "extra_link_args": [ "-fopenmp" ] @@ -18,7 +18,7 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) #error Cython requires Python 2.6+ or Python 3.2+. #else -#define CYTHON_ABI "0_23_5" +#define CYTHON_ABI "0_23_4" #include #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) @@ -1115,6 +1115,9 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); +static PyObject *__pyx_memview_get_int(const char *itemp); +static int __pyx_memview_set_int(const char *itemp, PyObject *obj); + static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs, char order, int ndim); @@ -1136,6 +1139,8 @@ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_int(PyObject *); +static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_long(PyObject *); + static int __Pyx_check_binary_version(void); static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); @@ -1187,6 +1192,7 @@ static CYTHON_INLINE double __pyx_f_7lightfm_20_lightfm_fast_openmp_update_featu static CYTHON_INLINE void __pyx_f_7lightfm_20_lightfm_fast_openmp_update(double, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *, int, int, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *, double, double); /*proto*/ static void __pyx_f_7lightfm_20_lightfm_fast_openmp_warp_update(double, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *, int, int, int, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *, double, double); /*proto*/ static void __pyx_f_7lightfm_20_lightfm_fast_openmp_regularize(struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *, double, double); /*proto*/ +static PyObject *__pyx_f_7lightfm_20_lightfm_fast_openmp_precompute_unique(struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *, __Pyx_memviewslice, __Pyx_memviewslice, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *, int); /*proto*/ static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/ static void *__pyx_align_pointer(void *, size_t); /*proto*/ static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/ @@ -1223,6 +1229,7 @@ static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_7lightfm_20_lightfm_fast_openmp_ static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, IS_UNSIGNED(int) ? 'U' : 'I', IS_UNSIGNED(int), 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_unsigned_int = { "unsigned int", NULL, sizeof(unsigned int), { 0 }, 0, IS_UNSIGNED(unsigned int) ? 'U' : 'I', IS_UNSIGNED(unsigned int), 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_long = { "long", NULL, sizeof(long), { 0 }, 0, IS_UNSIGNED(long) ? 'U' : 'I', IS_UNSIGNED(long), 0 }; #define __Pyx_MODULE_NAME "lightfm._lightfm_fast_openmp" int __pyx_module_is_main_lightfm___lightfm_fast_openmp = 0; @@ -1286,6 +1293,7 @@ static char __pyx_k_indptr[] = "indptr"; static char __pyx_k_name_2[] = "__name__"; static char __pyx_k_struct[] = "struct"; static char __pyx_k_uint32[] = "uint32"; +static char __pyx_k_unique[] = "unique"; static char __pyx_k_unpack[] = "unpack"; static char __pyx_k_weight[] = "weight"; static char __pyx_k_epsilon[] = "epsilon"; @@ -1303,8 +1311,10 @@ static char __pyx_k_Ellipsis[] = "Ellipsis"; static char __pyx_k_MAX_LOSS[] = "MAX_LOSS"; static char __pyx_k_adadelta[] = "adadelta"; static char __pyx_k_fit_warp[] = "fit_warp"; +static char __pyx_k_it_reprs[] = "it_reprs"; static char __pyx_k_item_ids[] = "item_ids"; static char __pyx_k_itemsize[] = "itemsize"; +static char __pyx_k_no_users[] = "no_users"; static char __pyx_k_row_stop[] = "row_stop"; static char __pyx_k_user_ids[] = "user_ids"; static char __pyx_k_TypeError[] = "TypeError"; @@ -1317,15 +1327,18 @@ static char __pyx_k_IndexError[] = "IndexError"; static char __pyx_k_ValueError[] = "ValueError"; static char __pyx_k_csr_matrix[] = "csr_matrix"; static char __pyx_k_item_alpha[] = "item_alpha"; +static char __pyx_k_precompute[] = "precompute"; static char __pyx_k_prediction[] = "prediction"; static char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; static char __pyx_k_user_alpha[] = "user_alpha"; +static char __pyx_k_user_reprs[] = "user_reprs"; static char __pyx_k_MemoryError[] = "MemoryError"; static char __pyx_k_POS_SAMPLES[] = "POS_SAMPLES"; static char __pyx_k_item_biases[] = "item_biases"; static char __pyx_k_max_sampled[] = "max_sampled"; static char __pyx_k_neg_it_repr[] = "neg_it_repr"; static char __pyx_k_no_examples[] = "no_examples"; +static char __pyx_k_no_features[] = "no_features"; static char __pyx_k_num_threads[] = "num_threads"; static char __pyx_k_pos_it_repr[] = "pos_it_repr"; static char __pyx_k_predictions[] = "predictions"; @@ -1335,6 +1348,10 @@ static char __pyx_k_fit_warp_kos[] = "fit_warp_kos"; static char __pyx_k_interactions[] = "interactions"; static char __pyx_k_no_positives[] = "no_positives"; static char __pyx_k_random_state[] = "random_state"; +static char __pyx_k_unique_items[] = "unique_items"; +static char __pyx_k_unique_users[] = "unique_users"; +static char __pyx_k_inverse_items[] = "inverse_items"; +static char __pyx_k_inverse_users[] = "inverse_users"; static char __pyx_k_item_features[] = "item_features"; static char __pyx_k_learning_rate[] = "learning_rate"; static char __pyx_k_no_components[] = "no_components"; @@ -1345,6 +1362,7 @@ static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer"; static char __pyx_k_random_states[] = "random_states"; static char __pyx_k_sample_weight[] = "sample_weight"; static char __pyx_k_user_features[] = "user_features"; +static char __pyx_k_return_inverse[] = "return_inverse"; static char __pyx_k_user_pids_stop[] = "user_pids_stop"; static char __pyx_k_allocate_buffer[] = "allocate_buffer"; static char __pyx_k_dtype_is_object[] = "dtype_is_object"; @@ -1387,7 +1405,7 @@ static char __pyx_k_sampled_positive_prediction[] = "sampled_positive_prediction static char __pyx_k_lightfm__lightfm_fast_openmp[] = "lightfm._lightfm_fast_openmp"; static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data."; static char __pyx_k_strided_and_direct_or_indirect[] = ""; -static char __pyx_k_home_maciej_Code_lightfm_lightf[] = "/home/maciej/Code/lightfm/lightfm/_lightfm_fast_openmp.pyx"; +static char __pyx_k_home_paolo_raisDataScience_reco[] = "/home/paolo/raisDataScience/recommender_system/FM/modified_lightfm/lightfm/_lightfm_fast_openmp.pyx"; static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced"; static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides"; static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory."; @@ -1449,7 +1467,7 @@ static PyObject *__pyx_n_s_fortran; static PyObject *__pyx_n_u_fortran; static PyObject *__pyx_n_s_gamma; static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi; -static PyObject *__pyx_kp_s_home_maciej_Code_lightfm_lightf; +static PyObject *__pyx_kp_s_home_paolo_raisDataScience_reco; static PyObject *__pyx_n_s_i; static PyObject *__pyx_n_s_id; static PyObject *__pyx_n_s_iinfo; @@ -1458,7 +1476,10 @@ static PyObject *__pyx_n_s_indices; static PyObject *__pyx_n_s_indptr; static PyObject *__pyx_n_s_int32; static PyObject *__pyx_n_s_interactions; +static PyObject *__pyx_n_s_inverse_items; +static PyObject *__pyx_n_s_inverse_users; static PyObject *__pyx_n_s_it_repr; +static PyObject *__pyx_n_s_it_reprs; static PyObject *__pyx_n_s_item_alpha; static PyObject *__pyx_n_s_item_bias_gradients; static PyObject *__pyx_n_s_item_bias_momentum; @@ -1491,7 +1512,9 @@ static PyObject *__pyx_n_s_negative_item_id; static PyObject *__pyx_n_s_negative_prediction; static PyObject *__pyx_n_s_no_components; static PyObject *__pyx_n_s_no_examples; +static PyObject *__pyx_n_s_no_features; static PyObject *__pyx_n_s_no_positives; +static PyObject *__pyx_n_s_no_users; static PyObject *__pyx_n_s_np; static PyObject *__pyx_n_s_num_negatives; static PyObject *__pyx_n_s_num_positives; @@ -1504,6 +1527,7 @@ static PyObject *__pyx_n_s_pos_it_repr; static PyObject *__pyx_n_s_pos_pairs; static PyObject *__pyx_n_s_positive_item_id; static PyObject *__pyx_n_s_positive_prediction; +static PyObject *__pyx_n_s_precompute; static PyObject *__pyx_n_s_predict_lightfm; static PyObject *__pyx_n_s_predict_ranks; static PyObject *__pyx_n_s_prediction; @@ -1518,6 +1542,7 @@ static PyObject *__pyx_n_s_range; static PyObject *__pyx_n_s_rank; static PyObject *__pyx_n_s_rank_data; static PyObject *__pyx_n_s_ranks; +static PyObject *__pyx_n_s_return_inverse; static PyObject *__pyx_n_s_rho; static PyObject *__pyx_n_s_row; static PyObject *__pyx_n_s_row_start; @@ -1543,6 +1568,9 @@ static PyObject *__pyx_n_s_train_interactions; static PyObject *__pyx_n_s_uint32; static PyObject *__pyx_kp_s_unable_to_allocate_array_data; static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str; +static PyObject *__pyx_n_s_unique; +static PyObject *__pyx_n_s_unique_items; +static PyObject *__pyx_n_s_unique_users; static PyObject *__pyx_n_s_unpack; static PyObject *__pyx_n_s_user_alpha; static PyObject *__pyx_n_s_user_bias_gradients; @@ -1556,6 +1584,7 @@ static PyObject *__pyx_n_s_user_ids; static PyObject *__pyx_n_s_user_pids_start; static PyObject *__pyx_n_s_user_pids_stop; static PyObject *__pyx_n_s_user_repr; +static PyObject *__pyx_n_s_user_reprs; static PyObject *__pyx_n_s_weight; static PyObject *__pyx_n_s_y; static PyObject *__pyx_n_s_y_row; @@ -1565,7 +1594,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_fit_logistic(CYTHON_UN static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_2fit_warp(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_interactions, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_Y, __Pyx_memviewslice __pyx_v_sample_weight, __Pyx_memviewslice __pyx_v_shuffle_indices, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED double __pyx_v_learning_rate, double __pyx_v_item_alpha, double __pyx_v_user_alpha, int __pyx_v_num_threads, PyObject *__pyx_v_random_state); /* proto */ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_4fit_warp_kos(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_data, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_shuffle_indices, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED double __pyx_v_learning_rate, double __pyx_v_item_alpha, double __pyx_v_user_alpha, int __pyx_v_k, int __pyx_v_n, int __pyx_v_num_threads, PyObject *__pyx_v_random_state); /* proto */ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_6fit_bpr(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_interactions, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_Y, __Pyx_memviewslice __pyx_v_sample_weight, __Pyx_memviewslice __pyx_v_shuffle_indices, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, CYTHON_UNUSED double __pyx_v_learning_rate, double __pyx_v_item_alpha, double __pyx_v_user_alpha, int __pyx_v_num_threads, PyObject *__pyx_v_random_state); /* proto */ -static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads); /* proto */ +static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads, int __pyx_v_precompute); /* proto */ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_test_interactions, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_train_interactions, __Pyx_memviewslice __pyx_v_ranks, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads); /* proto */ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_rank(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_ranks, __Pyx_memviewslice __pyx_v_num_train_positives, __Pyx_memviewslice __pyx_v_rank_data, __Pyx_memviewslice __pyx_v_auc, int __pyx_v_num_threads); /* proto */ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_14__test_in_positives(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_row, int __pyx_v_col, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_mat); /* proto */ @@ -4684,7 +4713,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_fit_logistic(CYTHON_UN #define unlikely(x) (x) #endif #ifdef _OPENMP - #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_it_repr) private(__pyx_t_3, __pyx_t_1, __pyx_t_6, __pyx_t_8, __pyx_t_2, __pyx_t_7, __pyx_t_5, __pyx_t_4, __pyx_t_9) num_threads(__pyx_v_num_threads) + #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_it_repr) private(__pyx_t_3, __pyx_t_4, __pyx_t_2, __pyx_t_5, __pyx_t_1, __pyx_t_7, __pyx_t_9, __pyx_t_6, __pyx_t_8) num_threads(__pyx_v_num_threads) #endif /* _OPENMP */ { /* Initialize private variables to invalid values */ @@ -4719,11 +4748,11 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_fit_logistic(CYTHON_UN __pyx_t_1 = __pyx_v_no_examples; if (1 == 0) abort(); { - __pyx_t_3 = (__pyx_t_1 - 0 + 1 - 1/abs(1)) / 1; + __pyx_t_3 = (__pyx_t_1 - 0) / 1; if (__pyx_t_3 > 0) { #ifdef _OPENMP - #pragma omp for lastprivate(__pyx_v_row) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_prediction) lastprivate(__pyx_v_y) lastprivate(__pyx_v_weight) lastprivate(__pyx_v_y_row) lastprivate(__pyx_v_item_id) lastprivate(__pyx_v_loss) lastprivate(__pyx_v_user_id) + #pragma omp for lastprivate(__pyx_v_row) lastprivate(__pyx_v_prediction) lastprivate(__pyx_v_loss) lastprivate(__pyx_v_item_id) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_y_row) lastprivate(__pyx_v_weight) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_y) #endif /* _OPENMP */ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){ { @@ -4731,12 +4760,12 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_fit_logistic(CYTHON_UN /* Initialize private variables to invalid values */ __pyx_v_row = ((int)0xbad0bad0); __pyx_v_prediction = ((double)__PYX_NAN()); - __pyx_v_y = ((int)0xbad0bad0); - __pyx_v_weight = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); - __pyx_v_y_row = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); - __pyx_v_item_id = ((int)0xbad0bad0); __pyx_v_loss = ((double)__PYX_NAN()); + __pyx_v_item_id = ((int)0xbad0bad0); __pyx_v_user_id = ((int)0xbad0bad0); + __pyx_v_y_row = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); + __pyx_v_weight = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); + __pyx_v_y = ((int)0xbad0bad0); /* "lightfm/_lightfm_fast_openmp.pyx":706 * for i in prange(no_examples): @@ -5368,13 +5397,13 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_2fit_warp(CYTHON_UNUSE #define unlikely(x) (x) #endif #ifdef _OPENMP - #pragma omp parallel private(__pyx_v_pos_it_repr, __pyx_v_user_repr, __pyx_v_neg_it_repr) private(__pyx_t_10, __pyx_t_15, __pyx_t_16, __pyx_t_9, __pyx_t_14, __pyx_t_18, __pyx_t_13, __pyx_t_11, __pyx_t_12, __pyx_t_17) num_threads(__pyx_v_num_threads) + #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_neg_it_repr, __pyx_v_pos_it_repr) private(__pyx_t_13, __pyx_t_17, __pyx_t_11, __pyx_t_18, __pyx_t_9, __pyx_t_10, __pyx_t_12, __pyx_t_14, __pyx_t_16, __pyx_t_15) num_threads(__pyx_v_num_threads) #endif /* _OPENMP */ { /* Initialize private variables to invalid values */ - __pyx_v_pos_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_neg_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); + __pyx_v_pos_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); /* "lightfm/_lightfm_fast_openmp.pyx":796 * with nogil, parallel(num_threads=num_threads): @@ -5413,24 +5442,24 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_2fit_warp(CYTHON_UNUSE __pyx_t_9 = __pyx_v_no_examples; if (1 == 0) abort(); { - __pyx_t_11 = (__pyx_t_9 - 0 + 1 - 1/abs(1)) / 1; + __pyx_t_11 = (__pyx_t_9 - 0) / 1; if (__pyx_t_11 > 0) { #ifdef _OPENMP - #pragma omp for lastprivate(__pyx_v_positive_item_id) lastprivate(__pyx_v_weight) lastprivate(__pyx_v_row) lastprivate(__pyx_v_sampled) lastprivate(__pyx_v_loss) lastprivate(__pyx_v_user_id) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_negative_prediction) lastprivate(__pyx_v_negative_item_id) lastprivate(__pyx_v_positive_prediction) + #pragma omp for lastprivate(__pyx_v_row) lastprivate(__pyx_v_positive_item_id) lastprivate(__pyx_v_negative_item_id) lastprivate(__pyx_v_weight) lastprivate(__pyx_v_sampled) lastprivate(__pyx_v_negative_prediction) lastprivate(__pyx_v_loss) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_positive_prediction) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) #endif /* _OPENMP */ for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_11; __pyx_t_10++){ { __pyx_v_i = 0 + 1 * __pyx_t_10; /* Initialize private variables to invalid values */ + __pyx_v_row = ((int)0xbad0bad0); __pyx_v_positive_item_id = ((int)0xbad0bad0); + __pyx_v_negative_item_id = ((int)0xbad0bad0); __pyx_v_weight = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); - __pyx_v_row = ((int)0xbad0bad0); __pyx_v_sampled = ((int)0xbad0bad0); + __pyx_v_negative_prediction = ((double)__PYX_NAN()); __pyx_v_loss = ((double)__PYX_NAN()); __pyx_v_user_id = ((int)0xbad0bad0); - __pyx_v_negative_prediction = ((double)__PYX_NAN()); - __pyx_v_negative_item_id = ((int)0xbad0bad0); __pyx_v_positive_prediction = ((double)__PYX_NAN()); /* "lightfm/_lightfm_fast_openmp.pyx":801 @@ -6219,14 +6248,14 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_4fit_warp_kos(CYTHON_U #define unlikely(x) (x) #endif #ifdef _OPENMP - #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_neg_it_repr, __pyx_v_pos_it_repr, __pyx_v_pos_pairs) private(__pyx_t_18, __pyx_t_10, __pyx_t_16, __pyx_t_19, __pyx_t_9, __pyx_t_14, __pyx_t_15, __pyx_t_13, __pyx_t_11, __pyx_t_12, __pyx_t_17, __pyx_t_20) num_threads(__pyx_v_num_threads) + #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_neg_it_repr, __pyx_v_pos_pairs, __pyx_v_pos_it_repr) private(__pyx_t_14, __pyx_t_13, __pyx_t_15, __pyx_t_19, __pyx_t_17, __pyx_t_11, __pyx_t_20, __pyx_t_18, __pyx_t_9, __pyx_t_10, __pyx_t_12, __pyx_t_16) num_threads(__pyx_v_num_threads) #endif /* _OPENMP */ { /* Initialize private variables to invalid values */ __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_neg_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); - __pyx_v_pos_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_pos_pairs = ((struct __pyx_t_7lightfm_20_lightfm_fast_openmp_Pair *)1); + __pyx_v_pos_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); /* "lightfm/_lightfm_fast_openmp.pyx":922 * with nogil, parallel(num_threads=num_threads): @@ -6274,30 +6303,30 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_4fit_warp_kos(CYTHON_U __pyx_t_9 = __pyx_v_no_examples; if (1 == 0) abort(); { - __pyx_t_11 = (__pyx_t_9 - 0 + 1 - 1/abs(1)) / 1; + __pyx_t_11 = (__pyx_t_9 - 0) / 1; if (__pyx_t_11 > 0) { #ifdef _OPENMP - #pragma omp for lastprivate(__pyx_v_user_pids_stop) lastprivate(__pyx_v_negative_prediction) lastprivate(__pyx_v_no_positives) lastprivate(__pyx_v_j) lastprivate(__pyx_v_row) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_positive_prediction) lastprivate(__pyx_v_sampled) lastprivate(__pyx_v_sampled_positive_item_id) lastprivate(__pyx_v_positive_item_id) lastprivate(__pyx_v_user_pids_start) lastprivate(__pyx_v_sampled_positive_prediction) lastprivate(__pyx_v_loss) lastprivate(__pyx_v_negative_item_id) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) + #pragma omp for lastprivate(__pyx_v_sampled) lastprivate(__pyx_v_positive_item_id) lastprivate(__pyx_v_j) lastprivate(__pyx_v_negative_prediction) lastprivate(__pyx_v_sampled_positive_item_id) lastprivate(__pyx_v_sampled_positive_prediction) lastprivate(__pyx_v_row) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_negative_item_id) lastprivate(__pyx_v_user_pids_start) lastprivate(__pyx_v_positive_prediction) lastprivate(__pyx_v_no_positives) lastprivate(__pyx_v_loss) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_user_pids_stop) #endif /* _OPENMP */ for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_11; __pyx_t_10++){ { __pyx_v_i = 0 + 1 * __pyx_t_10; /* Initialize private variables to invalid values */ - __pyx_v_user_pids_stop = ((int)0xbad0bad0); - __pyx_v_negative_prediction = ((double)__PYX_NAN()); - __pyx_v_no_positives = ((int)0xbad0bad0); + __pyx_v_sampled = ((int)0xbad0bad0); + __pyx_v_positive_item_id = ((int)0xbad0bad0); __pyx_v_j = ((int)0xbad0bad0); + __pyx_v_negative_prediction = ((double)__PYX_NAN()); + __pyx_v_sampled_positive_item_id = ((int)0xbad0bad0); + __pyx_v_sampled_positive_prediction = ((double)__PYX_NAN()); __pyx_v_row = ((int)0xbad0bad0); __pyx_v_user_id = ((int)0xbad0bad0); - __pyx_v_positive_prediction = ((double)__PYX_NAN()); - __pyx_v_sampled = ((int)0xbad0bad0); - __pyx_v_sampled_positive_item_id = ((int)0xbad0bad0); - __pyx_v_positive_item_id = ((int)0xbad0bad0); + __pyx_v_negative_item_id = ((int)0xbad0bad0); __pyx_v_user_pids_start = ((int)0xbad0bad0); - __pyx_v_sampled_positive_prediction = ((double)__PYX_NAN()); + __pyx_v_positive_prediction = ((double)__PYX_NAN()); + __pyx_v_no_positives = ((int)0xbad0bad0); __pyx_v_loss = ((double)__PYX_NAN()); - __pyx_v_negative_item_id = ((int)0xbad0bad0); + __pyx_v_user_pids_stop = ((int)0xbad0bad0); /* "lightfm/_lightfm_fast_openmp.pyx":928 * @@ -7173,12 +7202,12 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_6fit_bpr(CYTHON_UNUSED #define unlikely(x) (x) #endif #ifdef _OPENMP - #pragma omp parallel private(__pyx_v_pos_it_repr, __pyx_v_user_repr, __pyx_v_neg_it_repr) private(__pyx_t_16, __pyx_t_18, __pyx_t_10, __pyx_t_15, __pyx_t_9, __pyx_t_14, __pyx_t_13, __pyx_t_11, __pyx_t_12, __pyx_t_17) num_threads(__pyx_v_num_threads) + #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_pos_it_repr, __pyx_v_neg_it_repr) private(__pyx_t_14, __pyx_t_13, __pyx_t_17, __pyx_t_11, __pyx_t_18, __pyx_t_16, __pyx_t_9, __pyx_t_10, __pyx_t_12, __pyx_t_15) num_threads(__pyx_v_num_threads) #endif /* _OPENMP */ { /* Initialize private variables to invalid values */ - __pyx_v_pos_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); + __pyx_v_pos_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_neg_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); /* "lightfm/_lightfm_fast_openmp.pyx":1074 @@ -7218,23 +7247,23 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_6fit_bpr(CYTHON_UNUSED __pyx_t_9 = __pyx_v_no_examples; if (1 == 0) abort(); { - __pyx_t_11 = (__pyx_t_9 - 0 + 1 - 1/abs(1)) / 1; + __pyx_t_11 = (__pyx_t_9 - 0) / 1; if (__pyx_t_11 > 0) { #ifdef _OPENMP - #pragma omp for lastprivate(__pyx_v_positive_prediction) lastprivate(__pyx_v_weight) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_row) lastprivate(__pyx_v_positive_item_id) lastprivate(__pyx_v_negative_item_id) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_negative_prediction) + #pragma omp for lastprivate(__pyx_v_row) lastprivate(__pyx_v_positive_prediction) lastprivate(__pyx_v_positive_item_id) lastprivate(__pyx_v_negative_prediction) lastprivate(__pyx_v_weight) lastprivate(__pyx_v_user_id) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_negative_item_id) #endif /* _OPENMP */ for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_11; __pyx_t_10++){ { __pyx_v_i = 0 + 1 * __pyx_t_10; /* Initialize private variables to invalid values */ - __pyx_v_positive_prediction = ((double)__PYX_NAN()); - __pyx_v_weight = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); __pyx_v_row = ((int)0xbad0bad0); + __pyx_v_positive_prediction = ((double)__PYX_NAN()); __pyx_v_positive_item_id = ((int)0xbad0bad0); - __pyx_v_negative_item_id = ((int)0xbad0bad0); - __pyx_v_user_id = ((int)0xbad0bad0); __pyx_v_negative_prediction = ((double)__PYX_NAN()); + __pyx_v_weight = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); + __pyx_v_user_id = ((int)0xbad0bad0); + __pyx_v_negative_item_id = ((int)0xbad0bad0); /* "lightfm/_lightfm_fast_openmp.pyx":1079 * @@ -7522,6 +7551,303 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_6fit_bpr(CYTHON_UNUSED } /* "lightfm/_lightfm_fast_openmp.pyx":1145 + * + * + * cdef precompute_unique(CSRMatrix item_features, # <<<<<<<<<<<<<< + * CSRMatrix user_features, + * int[::1] unique_users, + */ + +static PyObject *__pyx_f_7lightfm_20_lightfm_fast_openmp_precompute_unique(struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_unique_users, __Pyx_memviewslice __pyx_v_unique_items, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_user_reprs, __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_it_reprs, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads) { + int __pyx_v_i; + int __pyx_v_j; + __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_it_repr; + __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_user_repr; + CYTHON_UNUSED int __pyx_v_no_features; + CYTHON_UNUSED int __pyx_v_no_users; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + Py_ssize_t __pyx_t_4; + long __pyx_t_5; + long __pyx_t_6; + long __pyx_t_7; + Py_ssize_t __pyx_t_8; + __Pyx_RefNannySetupContext("precompute_unique", 0); + + /* "lightfm/_lightfm_fast_openmp.pyx":1163 + * cdef int no_users + * + * no_features = unique_items.shape[0] # <<<<<<<<<<<<<< + * no_users = unique_users.shape[0] + * with nogil, parallel(num_threads=num_threads): + */ + __pyx_v_no_features = (__pyx_v_unique_items.shape[0]); + + /* "lightfm/_lightfm_fast_openmp.pyx":1164 + * + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] # <<<<<<<<<<<<<< + * with nogil, parallel(num_threads=num_threads): + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + */ + __pyx_v_no_users = (__pyx_v_unique_users.shape[0]); + + /* "lightfm/_lightfm_fast_openmp.pyx":1165 + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] + * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + */ + { + #ifdef WITH_THREAD + PyThreadState *_save; + Py_UNBLOCK_THREADS + #endif + /*try:*/ { + { + #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))) + #undef likely + #undef unlikely + #define likely(x) (x) + #define unlikely(x) (x) + #endif + #ifdef _OPENMP + #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_it_repr) private(__pyx_t_3, __pyx_t_7, __pyx_t_4, __pyx_t_5, __pyx_t_2, __pyx_t_6, __pyx_t_1, __pyx_t_8) num_threads(__pyx_v_num_threads) + #endif /* _OPENMP */ + { + /* Initialize private variables to invalid values */ + __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); + __pyx_v_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); + + /* "lightfm/_lightfm_fast_openmp.pyx":1166 + * no_users = unique_users.shape[0] + * with nogil, parallel(num_threads=num_threads): + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * # users representations + */ + __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_openmp.pyx":1167 + * with nogil, parallel(num_threads=num_threads): + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * # users representations + * for i in prange(no_users): + */ + __pyx_v_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_openmp.pyx":1169 + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * # users representations + * for i in prange(no_users): # <<<<<<<<<<<<<< + * compute_representation(user_features, + * lightfm.user_features, + */ + __pyx_t_1 = __pyx_v_no_users; + if (1 == 0) abort(); + { + __pyx_t_3 = (__pyx_t_1 - 0) / 1; + if (__pyx_t_3 > 0) + { + #ifdef _OPENMP + #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) + #endif /* _OPENMP */ + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){ + { + __pyx_v_i = 0 + 1 * __pyx_t_2; + /* Initialize private variables to invalid values */ + __pyx_v_j = ((int)0xbad0bad0); + + /* "lightfm/_lightfm_fast_openmp.pyx":1174 + * lightfm.user_biases, + * lightfm, + * unique_users[i], # <<<<<<<<<<<<<< + * lightfm.user_scale, + * user_repr) + */ + __pyx_t_4 = __pyx_v_i; + + /* "lightfm/_lightfm_fast_openmp.pyx":1170 + * # users representations + * for i in prange(no_users): + * compute_representation(user_features, # <<<<<<<<<<<<<< + * lightfm.user_features, + * lightfm.user_biases, + */ + __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_unique_users.data) + __pyx_t_4)) ))), __pyx_v_lightfm->user_scale, __pyx_v_user_repr); + + /* "lightfm/_lightfm_fast_openmp.pyx":1177 + * lightfm.user_scale, + * user_repr) + * for j in prange(lightfm.no_components + 1): # <<<<<<<<<<<<<< + * user_reprs[i * (lightfm.no_components + 1) + j] = user_repr[j] + * + */ + __pyx_t_5 = (__pyx_v_lightfm->no_components + 1); + if (1 == 0) abort(); + { + __pyx_t_7 = (__pyx_t_5 - 0) / 1; + if (__pyx_t_7 > 0) + { + #if 0 + #pragma omp parallel + #endif /* _OPENMP */ + { + #if 0 + #pragma omp for firstprivate(__pyx_v_j) lastprivate(__pyx_v_j) + #endif /* _OPENMP */ + for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_7; __pyx_t_6++){ + { + __pyx_v_j = 0 + 1 * __pyx_t_6; + + /* "lightfm/_lightfm_fast_openmp.pyx":1178 + * user_repr) + * for j in prange(lightfm.no_components + 1): + * user_reprs[i * (lightfm.no_components + 1) + j] = user_repr[j] # <<<<<<<<<<<<<< + * + * # items representations + */ + (__pyx_v_user_reprs[((__pyx_v_i * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]) = (__pyx_v_user_repr[__pyx_v_j]); + } + } + } + } + } + } + } + } + } + + /* "lightfm/_lightfm_fast_openmp.pyx":1181 + * + * # items representations + * for i in prange(no_features): # <<<<<<<<<<<<<< + * compute_representation(item_features, + * lightfm.item_features, + */ + __pyx_t_3 = __pyx_v_no_features; + if (1 == 0) abort(); + { + __pyx_t_1 = (__pyx_t_3 - 0) / 1; + if (__pyx_t_1 > 0) + { + #ifdef _OPENMP + #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) lastprivate(__pyx_v_j) + #endif /* _OPENMP */ + for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2++){ + { + __pyx_v_i = 0 + 1 * __pyx_t_2; + /* Initialize private variables to invalid values */ + __pyx_v_j = ((int)0xbad0bad0); + + /* "lightfm/_lightfm_fast_openmp.pyx":1186 + * lightfm.item_biases, + * lightfm, + * unique_items[i], # <<<<<<<<<<<<<< + * lightfm.item_scale, + * it_repr) + */ + __pyx_t_8 = __pyx_v_i; + + /* "lightfm/_lightfm_fast_openmp.pyx":1182 + * # items representations + * for i in prange(no_features): + * compute_representation(item_features, # <<<<<<<<<<<<<< + * lightfm.item_features, + * lightfm.item_biases, + */ + __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_unique_items.data) + __pyx_t_8)) ))), __pyx_v_lightfm->item_scale, __pyx_v_it_repr); + + /* "lightfm/_lightfm_fast_openmp.pyx":1189 + * lightfm.item_scale, + * it_repr) + * for j in prange(lightfm.no_components + 1): # <<<<<<<<<<<<<< + * it_reprs[i * (lightfm.no_components + 1) + j] = it_repr[j] + * + */ + __pyx_t_7 = (__pyx_v_lightfm->no_components + 1); + if (1 == 0) abort(); + { + __pyx_t_5 = (__pyx_t_7 - 0) / 1; + if (__pyx_t_5 > 0) + { + #if 0 + #pragma omp parallel + #endif /* _OPENMP */ + { + #if 0 + #pragma omp for firstprivate(__pyx_v_j) lastprivate(__pyx_v_j) + #endif /* _OPENMP */ + for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6++){ + { + __pyx_v_j = 0 + 1 * __pyx_t_6; + + /* "lightfm/_lightfm_fast_openmp.pyx":1190 + * it_repr) + * for j in prange(lightfm.no_components + 1): + * it_reprs[i * (lightfm.no_components + 1) + j] = it_repr[j] # <<<<<<<<<<<<<< + * + * + */ + (__pyx_v_it_reprs[((__pyx_v_i * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]) = (__pyx_v_it_repr[__pyx_v_j]); + } + } + } + } + } + } + } + } + } + } + } + #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))) + #undef likely + #undef unlikely + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) + #endif + } + + /* "lightfm/_lightfm_fast_openmp.pyx":1165 + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] + * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + */ + /*finally:*/ { + /*normal exit:*/{ + #ifdef WITH_THREAD + Py_BLOCK_THREADS + #endif + goto __pyx_L5; + } + __pyx_L5:; + } + } + + /* "lightfm/_lightfm_fast_openmp.pyx":1145 + * + * + * cdef precompute_unique(CSRMatrix item_features, # <<<<<<<<<<<<<< + * CSRMatrix user_features, + * int[::1] unique_users, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "lightfm/_lightfm_fast_openmp.pyx":1193 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -7541,6 +7867,7 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_9predict_lightfm(PyObj __Pyx_memviewslice __pyx_v_predictions = { 0, 0, { 0 }, { 0 }, { 0 } }; struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm = 0; int __pyx_v_num_threads; + int __pyx_v_precompute; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; @@ -7548,12 +7875,13 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_9predict_lightfm(PyObj __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("predict_lightfm (wrapper)", 0); { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_item_features,&__pyx_n_s_user_features,&__pyx_n_s_user_ids,&__pyx_n_s_item_ids,&__pyx_n_s_predictions,&__pyx_n_s_lightfm,&__pyx_n_s_num_threads,0}; - PyObject* values[7] = {0,0,0,0,0,0,0}; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_item_features,&__pyx_n_s_user_features,&__pyx_n_s_user_ids,&__pyx_n_s_item_ids,&__pyx_n_s_predictions,&__pyx_n_s_lightfm,&__pyx_n_s_num_threads,&__pyx_n_s_precompute,0}; + PyObject* values[8] = {0,0,0,0,0,0,0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); @@ -7572,108 +7900,386 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_9predict_lightfm(PyObj case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_user_features)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_user_ids)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_item_ids)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 4: if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_predictions)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 5: if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_lightfm)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 6: if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_threads)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + case 7: + if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_precompute)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_lightfm") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_lightfm") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 8) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + } + __pyx_v_item_features = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[0]); + __pyx_v_user_features = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[1]); + __pyx_v_user_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[2]); if (unlikely(!__pyx_v_user_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1195; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_item_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[3]); if (unlikely(!__pyx_v_item_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_predictions = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[4]); if (unlikely(!__pyx_v_predictions.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1197; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_lightfm = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *)values[5]); + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1199; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_precompute = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_precompute == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_L3_error:; + __Pyx_AddTraceback("lightfm._lightfm_fast_openmp.predict_lightfm", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1194; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_r = __pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(__pyx_self, __pyx_v_item_features, __pyx_v_user_features, __pyx_v_user_ids, __pyx_v_item_ids, __pyx_v_predictions, __pyx_v_lightfm, __pyx_v_num_threads, __pyx_v_precompute); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads, int __pyx_v_precompute) { + int __pyx_v_i; + int __pyx_v_j; + CYTHON_UNUSED int __pyx_v_no_examples; + __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_user_repr; + __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_it_repr; + __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_user_reprs; + __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_it_reprs; + __Pyx_memviewslice __pyx_v_unique_users = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_unique_items = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_inverse_users = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_v_inverse_items = { 0, 0, { 0 }, { 0 }, { 0 } }; + int __pyx_v_no_features; + int __pyx_v_no_users; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *(*__pyx_t_6)(PyObject *); + __Pyx_memviewslice __pyx_t_7 = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } }; + int __pyx_t_9; + int __pyx_t_10; + int __pyx_t_11; + long __pyx_t_12; + long __pyx_t_13; + long __pyx_t_14; + Py_ssize_t __pyx_t_15; + Py_ssize_t __pyx_t_16; + Py_ssize_t __pyx_t_17; + Py_ssize_t __pyx_t_18; + Py_ssize_t __pyx_t_19; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("predict_lightfm", 0); + + /* "lightfm/_lightfm_fast_openmp.pyx":1216 + * cdef int no_users + * + * no_examples = predictions.shape[0] # <<<<<<<<<<<<<< + * + * if precompute: + */ + __pyx_v_no_examples = (__pyx_v_predictions.shape[0]); + + /* "lightfm/_lightfm_fast_openmp.pyx":1218 + * no_examples = predictions.shape[0] + * + * if precompute: # <<<<<<<<<<<<<< + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + */ + __pyx_t_1 = (__pyx_v_precompute != 0); + if (__pyx_t_1) { + + /* "lightfm/_lightfm_fast_openmp.pyx":1219 + * + * if precompute: + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) # <<<<<<<<<<<<<< + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + * no_features = unique_items.shape[0] + */ + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_unique); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_user_ids, 1, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); + __pyx_t_2 = 0; + __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return_inverse, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_5))) || (PyList_CheckExact(__pyx_t_5))) { + PyObject* sequence = __pyx_t_5; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_2 = PyList_GET_ITEM(sequence, 0); + __pyx_t_4 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + #endif + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_6 = Py_TYPE(__pyx_t_3)->tp_iternext; + index = 0; __pyx_t_2 = __pyx_t_6(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L4_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L5_unpacking_done; + __pyx_L4_unpacking_failed:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L5_unpacking_done:; + } + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dc_int(__pyx_t_2); + if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_long(__pyx_t_4); + if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_unique_users = __pyx_t_7; + __pyx_t_7.memview = NULL; + __pyx_t_7.data = NULL; + __pyx_v_inverse_users = __pyx_t_8; + __pyx_t_8.memview = NULL; + __pyx_t_8.data = NULL; + + /* "lightfm/_lightfm_fast_openmp.pyx":1220 + * if precompute: + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) # <<<<<<<<<<<<<< + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] + */ + __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_unique); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_v_item_ids, 1, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return_inverse, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + #if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + } + #if CYTHON_COMPILING_IN_CPYTHON + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_5 = PyList_GET_ITEM(sequence, 0); + __pyx_t_2 = PyList_GET_ITEM(sequence, 1); } - } else if (PyTuple_GET_SIZE(__pyx_args) != 7) { - goto __pyx_L5_argtuple_error; + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_2); + #else + __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_2); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + Py_ssize_t index = -1; + __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; + index = 0; __pyx_t_5 = __pyx_t_6(__pyx_t_4); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + index = 1; __pyx_t_2 = __pyx_t_6(__pyx_t_4); if (unlikely(!__pyx_t_2)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_4), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_6 = NULL; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_L7_unpacking_done:; } - __pyx_v_item_features = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[0]); - __pyx_v_user_features = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[1]); - __pyx_v_user_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[2]); if (unlikely(!__pyx_v_user_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1147; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_item_ids = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[3]); if (unlikely(!__pyx_v_item_ids.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_predictions = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[4]); if (unlikely(!__pyx_v_predictions.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1149; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_lightfm = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *)values[5]); - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("predict_lightfm", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_L3_error:; - __Pyx_AddTraceback("lightfm._lightfm_fast_openmp.predict_lightfm", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1150; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_r = __pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(__pyx_self, __pyx_v_item_features, __pyx_v_user_features, __pyx_v_user_ids, __pyx_v_item_ids, __pyx_v_predictions, __pyx_v_lightfm, __pyx_v_num_threads); + __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dc_int(__pyx_t_5); + if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_long(__pyx_t_2); + if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_unique_items = __pyx_t_7; + __pyx_t_7.memview = NULL; + __pyx_t_7.data = NULL; + __pyx_v_inverse_items = __pyx_t_8; + __pyx_t_8.memview = NULL; + __pyx_t_8.data = NULL; - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} + /* "lightfm/_lightfm_fast_openmp.pyx":1221 + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + * no_features = unique_items.shape[0] # <<<<<<<<<<<<<< + * no_users = unique_users.shape[0] + * + */ + __pyx_v_no_features = (__pyx_v_unique_items.shape[0]); -static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHON_UNUSED PyObject *__pyx_self, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_item_features, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *__pyx_v_user_features, __Pyx_memviewslice __pyx_v_user_ids, __Pyx_memviewslice __pyx_v_item_ids, __Pyx_memviewslice __pyx_v_predictions, struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *__pyx_v_lightfm, int __pyx_v_num_threads) { - int __pyx_v_i; - CYTHON_UNUSED int __pyx_v_no_examples; - __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_user_repr; - __pyx_t_7lightfm_20_lightfm_fast_openmp_flt *__pyx_v_it_repr; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - int __pyx_t_3; - Py_ssize_t __pyx_t_4; - Py_ssize_t __pyx_t_5; - Py_ssize_t __pyx_t_6; - __Pyx_RefNannySetupContext("predict_lightfm", 0); + /* "lightfm/_lightfm_fast_openmp.pyx":1222 + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + * no_features = unique_items.shape[0] + * no_users = unique_users.shape[0] # <<<<<<<<<<<<<< + * + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) + */ + __pyx_v_no_users = (__pyx_v_unique_users.shape[0]); - /* "lightfm/_lightfm_fast_openmp.pyx":1160 - * cdef flt *it_repr + /* "lightfm/_lightfm_fast_openmp.pyx":1224 + * no_users = unique_users.shape[0] * - * no_examples = predictions.shape[0] # <<<<<<<<<<<<<< + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * it_reprs = malloc(sizeof(flt) * no_features *(lightfm.no_components + 1)) + * precompute_unique(item_features, + */ + __pyx_v_user_reprs = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc((((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * __pyx_v_no_users) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_openmp.pyx":1225 * - * with nogil, parallel(num_threads=num_threads): + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) + * it_reprs = malloc(sizeof(flt) * no_features *(lightfm.no_components + 1)) # <<<<<<<<<<<<<< + * precompute_unique(item_features, + * user_features, */ - __pyx_v_no_examples = (__pyx_v_predictions.shape[0]); + __pyx_v_it_reprs = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc((((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * __pyx_v_no_features) * (__pyx_v_lightfm->no_components + 1)))); + + /* "lightfm/_lightfm_fast_openmp.pyx":1226 + * user_reprs = malloc(sizeof(flt) * no_users * (lightfm.no_components + 1)) + * it_reprs = malloc(sizeof(flt) * no_features *(lightfm.no_components + 1)) + * precompute_unique(item_features, # <<<<<<<<<<<<<< + * user_features, + * unique_users, + */ + __pyx_t_3 = __pyx_f_7lightfm_20_lightfm_fast_openmp_precompute_unique(__pyx_v_item_features, __pyx_v_user_features, __pyx_v_unique_users, __pyx_v_unique_items, __pyx_v_user_reprs, __pyx_v_it_reprs, __pyx_v_lightfm, __pyx_v_num_threads); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1226; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "lightfm/_lightfm_fast_openmp.pyx":1162 + /* "lightfm/_lightfm_fast_openmp.pyx":1218 * no_examples = predictions.shape[0] * - * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< + * if precompute: # <<<<<<<<<<<<<< + * unique_users, inverse_users = np.unique(user_ids, return_inverse=True) + * unique_items, inverse_items = np.unique(item_ids, return_inverse=True) + */ + } + + /* "lightfm/_lightfm_fast_openmp.pyx":1235 + * num_threads) * + * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) */ { #ifdef WITH_THREAD @@ -7689,116 +8295,198 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHO #define unlikely(x) (x) #endif #ifdef _OPENMP - #pragma omp parallel private(__pyx_v_it_repr, __pyx_v_user_repr) private(__pyx_t_3, __pyx_t_1, __pyx_t_6, __pyx_t_2, __pyx_t_5, __pyx_t_4) num_threads(__pyx_v_num_threads) + #pragma omp parallel private(__pyx_v_it_repr, __pyx_v_user_repr) private(__pyx_t_17, __pyx_t_11, __pyx_t_13, __pyx_t_18, __pyx_t_12, __pyx_t_14, __pyx_t_9, __pyx_t_10, __pyx_t_1, __pyx_t_19) num_threads(__pyx_v_num_threads) #endif /* _OPENMP */ { /* Initialize private variables to invalid values */ __pyx_v_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); - /* "lightfm/_lightfm_fast_openmp.pyx":1164 - * with nogil, parallel(num_threads=num_threads): + /* "lightfm/_lightfm_fast_openmp.pyx":1236 * + * with nogil, parallel(num_threads=num_threads): * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) - * + * for i in prange(no_examples): */ __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_openmp.pyx":1165 - * + /* "lightfm/_lightfm_fast_openmp.pyx":1237 + * with nogil, parallel(num_threads=num_threads): * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< - * * for i in prange(no_examples): + * if precompute: */ __pyx_v_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_openmp.pyx":1167 + /* "lightfm/_lightfm_fast_openmp.pyx":1238 + * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) - * * for i in prange(no_examples): # <<<<<<<<<<<<<< - * - * compute_representation(user_features, + * if precompute: + * for j in prange(lightfm.no_components + 1): */ - __pyx_t_1 = __pyx_v_no_examples; + __pyx_t_9 = __pyx_v_no_examples; if (1 == 0) abort(); { - __pyx_t_3 = (__pyx_t_1 - 0 + 1 - 1/abs(1)) / 1; - if (__pyx_t_3 > 0) + __pyx_t_11 = (__pyx_t_9 - 0) / 1; + if (__pyx_t_11 > 0) { #ifdef _OPENMP - #pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) + #pragma omp for lastprivate(__pyx_v_j) firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) #endif /* _OPENMP */ - for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){ + for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_11; __pyx_t_10++){ { - __pyx_v_i = 0 + 1 * __pyx_t_2; + __pyx_v_i = 0 + 1 * __pyx_t_10; + /* Initialize private variables to invalid values */ + __pyx_v_j = ((int)0xbad0bad0); - /* "lightfm/_lightfm_fast_openmp.pyx":1173 - * lightfm.user_biases, - * lightfm, - * user_ids[i], # <<<<<<<<<<<<<< - * lightfm.user_scale, - * user_repr) + /* "lightfm/_lightfm_fast_openmp.pyx":1239 + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * for i in prange(no_examples): + * if precompute: # <<<<<<<<<<<<<< + * for j in prange(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] */ - __pyx_t_4 = __pyx_v_i; + __pyx_t_1 = (__pyx_v_precompute != 0); + if (__pyx_t_1) { - /* "lightfm/_lightfm_fast_openmp.pyx":1169 + /* "lightfm/_lightfm_fast_openmp.pyx":1240 * for i in prange(no_examples): - * - * compute_representation(user_features, # <<<<<<<<<<<<<< - * lightfm.user_features, - * lightfm.user_biases, + * if precompute: + * for j in prange(lightfm.no_components + 1): # <<<<<<<<<<<<<< + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + */ + __pyx_t_12 = (__pyx_v_lightfm->no_components + 1); + if (1 == 0) abort(); + { + __pyx_t_14 = (__pyx_t_12 - 0) / 1; + if (__pyx_t_14 > 0) + { + #if 0 + #pragma omp parallel private(__pyx_t_16, __pyx_t_15) + #endif /* _OPENMP */ + { + #if 0 + #pragma omp for firstprivate(__pyx_v_j) lastprivate(__pyx_v_j) + #endif /* _OPENMP */ + for (__pyx_t_13 = 0; __pyx_t_13 < __pyx_t_14; __pyx_t_13++){ + { + __pyx_v_j = 0 + 1 * __pyx_t_13; + + /* "lightfm/_lightfm_fast_openmp.pyx":1241 + * if precompute: + * for j in prange(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] # <<<<<<<<<<<<<< + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + * else: */ - __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_user_ids.data) + __pyx_t_4)) ))), __pyx_v_lightfm->user_scale, __pyx_v_user_repr); + __pyx_t_15 = __pyx_v_i; + (__pyx_v_user_repr[__pyx_v_j]) = (__pyx_v_user_reprs[(((*((long *) ( /* dim=0 */ ((char *) (((long *) __pyx_v_inverse_users.data) + __pyx_t_15)) ))) * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]); - /* "lightfm/_lightfm_fast_openmp.pyx":1180 - * lightfm.item_biases, - * lightfm, - * item_ids[i], # <<<<<<<<<<<<<< - * lightfm.item_scale, - * it_repr) + /* "lightfm/_lightfm_fast_openmp.pyx":1242 + * for j in prange(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] # <<<<<<<<<<<<<< + * else: + * compute_representation(user_features, + */ + __pyx_t_16 = __pyx_v_i; + (__pyx_v_it_repr[__pyx_v_j]) = (__pyx_v_it_reprs[(((*((long *) ( /* dim=0 */ ((char *) (((long *) __pyx_v_inverse_items.data) + __pyx_t_16)) ))) * (__pyx_v_lightfm->no_components + 1)) + __pyx_v_j)]); + } + } + } + } + } + + /* "lightfm/_lightfm_fast_openmp.pyx":1239 + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * for i in prange(no_examples): + * if precompute: # <<<<<<<<<<<<<< + * for j in prange(lightfm.no_components + 1): + * user_repr[j] = user_reprs[inverse_users[i] * (lightfm.no_components + 1) + j] */ - __pyx_t_5 = __pyx_v_i; + goto __pyx_L19; + } - /* "lightfm/_lightfm_fast_openmp.pyx":1176 - * lightfm.user_scale, - * user_repr) - * compute_representation(item_features, # <<<<<<<<<<<<<< - * lightfm.item_features, - * lightfm.item_biases, + /* "lightfm/_lightfm_fast_openmp.pyx":1244 + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + * else: + * compute_representation(user_features, # <<<<<<<<<<<<<< + * lightfm.user_features, + * lightfm.user_biases, + */ + /*else*/ { + + /* "lightfm/_lightfm_fast_openmp.pyx":1248 + * lightfm.user_biases, + * lightfm, + * user_ids[i], # <<<<<<<<<<<<<< + * lightfm.user_scale, + * user_repr) */ - __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_item_ids.data) + __pyx_t_5)) ))), __pyx_v_lightfm->item_scale, __pyx_v_it_repr); + __pyx_t_17 = __pyx_v_i; - /* "lightfm/_lightfm_fast_openmp.pyx":1184 - * it_repr) + /* "lightfm/_lightfm_fast_openmp.pyx":1244 + * it_repr[j] = it_reprs[inverse_items[i] * (lightfm.no_components + 1) + j] + * else: + * compute_representation(user_features, # <<<<<<<<<<<<<< + * lightfm.user_features, + * lightfm.user_biases, + */ + __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_user_ids.data) + __pyx_t_17)) ))), __pyx_v_lightfm->user_scale, __pyx_v_user_repr); + + /* "lightfm/_lightfm_fast_openmp.pyx":1255 + * lightfm.item_biases, + * lightfm, + * item_ids[i], # <<<<<<<<<<<<<< + * lightfm.item_scale, + * it_repr) + */ + __pyx_t_18 = __pyx_v_i; + + /* "lightfm/_lightfm_fast_openmp.pyx":1251 + * lightfm.user_scale, + * user_repr) + * compute_representation(item_features, # <<<<<<<<<<<<<< + * lightfm.item_features, + * lightfm.item_biases, + */ + __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_item_ids.data) + __pyx_t_18)) ))), __pyx_v_lightfm->item_scale, __pyx_v_it_repr); + } + __pyx_L19:; + + /* "lightfm/_lightfm_fast_openmp.pyx":1259 + * it_repr) * * predictions[i] = compute_prediction_from_repr(user_repr, # <<<<<<<<<<<<<< - * it_repr, - * lightfm.no_components) + * it_repr, + * lightfm.no_components) */ - __pyx_t_6 = __pyx_v_i; - *((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_predictions.data) + __pyx_t_6)) )) = __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); + __pyx_t_19 = __pyx_v_i; + *((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_predictions.data) + __pyx_t_19)) )) = __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); } } } } - /* "lightfm/_lightfm_fast_openmp.pyx":1188 - * lightfm.no_components) + /* "lightfm/_lightfm_fast_openmp.pyx":1263 + * lightfm.no_components) * * free(user_repr) # <<<<<<<<<<<<<< * free(it_repr) - * + * if precompute: */ free(__pyx_v_user_repr); - /* "lightfm/_lightfm_fast_openmp.pyx":1189 + /* "lightfm/_lightfm_fast_openmp.pyx":1264 * * free(user_repr) * free(it_repr) # <<<<<<<<<<<<<< - * - * + * if precompute: + * free(user_reprs) */ free(__pyx_v_it_repr); } @@ -7811,25 +8499,62 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHO #endif } - /* "lightfm/_lightfm_fast_openmp.pyx":1162 - * no_examples = predictions.shape[0] + /* "lightfm/_lightfm_fast_openmp.pyx":1235 + * num_threads) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< - * * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) + * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD Py_BLOCK_THREADS #endif - goto __pyx_L5; + goto __pyx_L10; } - __pyx_L5:; + __pyx_L10:; } } - /* "lightfm/_lightfm_fast_openmp.pyx":1145 + /* "lightfm/_lightfm_fast_openmp.pyx":1265 + * free(user_repr) + * free(it_repr) + * if precompute: # <<<<<<<<<<<<<< + * free(user_reprs) + * free(it_reprs) + */ + __pyx_t_1 = (__pyx_v_precompute != 0); + if (__pyx_t_1) { + + /* "lightfm/_lightfm_fast_openmp.pyx":1266 + * free(it_repr) + * if precompute: + * free(user_reprs) # <<<<<<<<<<<<<< + * free(it_reprs) + * + */ + free(__pyx_v_user_reprs); + + /* "lightfm/_lightfm_fast_openmp.pyx":1267 + * if precompute: + * free(user_reprs) + * free(it_reprs) # <<<<<<<<<<<<<< + * + * + */ + free(__pyx_v_it_reprs); + + /* "lightfm/_lightfm_fast_openmp.pyx":1265 + * free(user_repr) + * free(it_repr) + * if precompute: # <<<<<<<<<<<<<< + * free(user_reprs) + * free(it_reprs) + */ + } + + /* "lightfm/_lightfm_fast_openmp.pyx":1193 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -7839,6 +8564,21 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHO /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1); + __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1); + __Pyx_AddTraceback("lightfm._lightfm_fast_openmp.predict_lightfm", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __PYX_XDEC_MEMVIEW(&__pyx_v_unique_users, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_unique_items, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_inverse_users, 1); + __PYX_XDEC_MEMVIEW(&__pyx_v_inverse_items, 1); __PYX_XDEC_MEMVIEW(&__pyx_v_user_ids, 1); __PYX_XDEC_MEMVIEW(&__pyx_v_item_ids, 1); __PYX_XDEC_MEMVIEW(&__pyx_v_predictions, 1); @@ -7847,7 +8587,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_8predict_lightfm(CYTHO return __pyx_r; } -/* "lightfm/_lightfm_fast_openmp.pyx":1192 +/* "lightfm/_lightfm_fast_openmp.pyx":1270 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -7898,36 +8638,36 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_11predict_ranks(PyObje case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_user_features)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_test_interactions)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_train_interactions)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 4: if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ranks)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 5: if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_lightfm)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 6: if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_threads)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_ranks") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "predict_ranks") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 7) { goto __pyx_L5_argtuple_error; @@ -7944,23 +8684,23 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_11predict_ranks(PyObje __pyx_v_user_features = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[1]); __pyx_v_test_interactions = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[2]); __pyx_v_train_interactions = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[3]); - __pyx_v_ranks = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_20_lightfm_fast_openmp_flt(values[4]); if (unlikely(!__pyx_v_ranks.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_ranks = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_20_lightfm_fast_openmp_flt(values[4]); if (unlikely(!__pyx_v_ranks.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1274; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_v_lightfm = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_FastLightFM *)values[5]); - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1276; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("predict_ranks", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("lightfm._lightfm_fast_openmp.predict_ranks", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_test_interactions), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "test_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1194; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_train_interactions), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "train_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1195; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1197; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_item_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "item_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_features), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "user_features", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1271; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_test_interactions), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "test_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1272; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_train_interactions), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "train_interactions", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1273; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_lightfm), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_FastLightFM, 1, "lightfm", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1275; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(__pyx_self, __pyx_v_item_features, __pyx_v_user_features, __pyx_v_test_interactions, __pyx_v_train_interactions, __pyx_v_ranks, __pyx_v_lightfm, __pyx_v_num_threads); /* function exit code */ @@ -7999,7 +8739,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON Py_ssize_t __pyx_t_11; __Pyx_RefNannySetupContext("predict_ranks", 0); - /* "lightfm/_lightfm_fast_openmp.pyx":1208 + /* "lightfm/_lightfm_fast_openmp.pyx":1286 * cdef flt prediction, rank * * predictions_size = 0 # <<<<<<<<<<<<<< @@ -8008,7 +8748,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_predictions_size = 0; - /* "lightfm/_lightfm_fast_openmp.pyx":1212 + /* "lightfm/_lightfm_fast_openmp.pyx":1290 * # Figure out the max size of the predictions * # buffer. * for user_id in range(test_interactions.rows): # <<<<<<<<<<<<<< @@ -8019,7 +8759,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { __pyx_v_user_id = __pyx_t_2; - /* "lightfm/_lightfm_fast_openmp.pyx":1213 + /* "lightfm/_lightfm_fast_openmp.pyx":1291 * # buffer. * for user_id in range(test_interactions.rows): * predictions_size = int_max(predictions_size, # <<<<<<<<<<<<<< @@ -8029,7 +8769,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON __pyx_v_predictions_size = __pyx_f_7lightfm_20_lightfm_fast_openmp_int_max(__pyx_v_predictions_size, (((struct __pyx_vtabstruct_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_end(__pyx_v_test_interactions, __pyx_v_user_id) - ((struct __pyx_vtabstruct_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_start(__pyx_v_test_interactions, __pyx_v_user_id))); } - /* "lightfm/_lightfm_fast_openmp.pyx":1217 + /* "lightfm/_lightfm_fast_openmp.pyx":1295 * - test_interactions.get_row_start(user_id)) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -8050,16 +8790,16 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON #define unlikely(x) (x) #endif #ifdef _OPENMP - #pragma omp parallel private(__pyx_v_it_repr, __pyx_v_predictions, __pyx_v_item_ids, __pyx_v_user_repr) private(__pyx_t_5, __pyx_t_3, __pyx_t_1, __pyx_t_11, __pyx_t_6, __pyx_t_9, __pyx_t_2, __pyx_t_8, __pyx_t_7, __pyx_t_4, __pyx_t_10) num_threads(__pyx_v_num_threads) + #pragma omp parallel private(__pyx_v_user_repr, __pyx_v_predictions, __pyx_v_item_ids, __pyx_v_it_repr) private(__pyx_t_3, __pyx_t_5, __pyx_t_2, __pyx_t_1, __pyx_t_7, __pyx_t_9, __pyx_t_11, __pyx_t_8, __pyx_t_4, __pyx_t_10, __pyx_t_6) num_threads(__pyx_v_num_threads) #endif /* _OPENMP */ { /* Initialize private variables to invalid values */ - __pyx_v_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); + __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_predictions = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); __pyx_v_item_ids = ((int *)1); - __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); + __pyx_v_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)1); - /* "lightfm/_lightfm_fast_openmp.pyx":1219 + /* "lightfm/_lightfm_fast_openmp.pyx":1297 * with nogil, parallel(num_threads=num_threads): * * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< @@ -8068,7 +8808,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_user_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_openmp.pyx":1220 + /* "lightfm/_lightfm_fast_openmp.pyx":1298 * * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) # <<<<<<<<<<<<<< @@ -8077,7 +8817,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_it_repr = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * (__pyx_v_lightfm->no_components + 1)))); - /* "lightfm/_lightfm_fast_openmp.pyx":1221 + /* "lightfm/_lightfm_fast_openmp.pyx":1299 * user_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * item_ids = malloc(sizeof(int) * predictions_size) # <<<<<<<<<<<<<< @@ -8086,7 +8826,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_item_ids = ((int *)malloc(((sizeof(int)) * __pyx_v_predictions_size))); - /* "lightfm/_lightfm_fast_openmp.pyx":1222 + /* "lightfm/_lightfm_fast_openmp.pyx":1300 * it_repr = malloc(sizeof(flt) * (lightfm.no_components + 1)) * item_ids = malloc(sizeof(int) * predictions_size) * predictions = malloc(sizeof(flt) * predictions_size) # <<<<<<<<<<<<<< @@ -8095,7 +8835,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_predictions = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *)malloc(((sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)) * __pyx_v_predictions_size))); - /* "lightfm/_lightfm_fast_openmp.pyx":1224 + /* "lightfm/_lightfm_fast_openmp.pyx":1302 * predictions = malloc(sizeof(flt) * predictions_size) * * for user_id in prange(test_interactions.rows): # <<<<<<<<<<<<<< @@ -8105,23 +8845,23 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON __pyx_t_1 = __pyx_v_test_interactions->rows; if (1 == 0) abort(); { - __pyx_t_3 = (__pyx_t_1 - 0 + 1 - 1/abs(1)) / 1; + __pyx_t_3 = (__pyx_t_1 - 0) / 1; if (__pyx_t_3 > 0) { #ifdef _OPENMP - #pragma omp for lastprivate(__pyx_v_i) lastprivate(__pyx_v_row_stop) lastprivate(__pyx_v_prediction) lastprivate(__pyx_v_item_id) lastprivate(__pyx_v_row_start) firstprivate(__pyx_v_user_id) lastprivate(__pyx_v_user_id) + #pragma omp for lastprivate(__pyx_v_item_id) lastprivate(__pyx_v_row_start) firstprivate(__pyx_v_user_id) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_prediction) lastprivate(__pyx_v_row_stop) lastprivate(__pyx_v_i) #endif /* _OPENMP */ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){ { __pyx_v_user_id = 0 + 1 * __pyx_t_2; /* Initialize private variables to invalid values */ - __pyx_v_i = ((int)0xbad0bad0); - __pyx_v_row_stop = ((int)0xbad0bad0); - __pyx_v_prediction = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); __pyx_v_item_id = ((int)0xbad0bad0); __pyx_v_row_start = ((int)0xbad0bad0); + __pyx_v_prediction = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); + __pyx_v_row_stop = ((int)0xbad0bad0); + __pyx_v_i = ((int)0xbad0bad0); - /* "lightfm/_lightfm_fast_openmp.pyx":1226 + /* "lightfm/_lightfm_fast_openmp.pyx":1304 * for user_id in prange(test_interactions.rows): * * row_start = test_interactions.get_row_start(user_id) # <<<<<<<<<<<<<< @@ -8130,7 +8870,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_row_start = ((struct __pyx_vtabstruct_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_start(__pyx_v_test_interactions, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_openmp.pyx":1227 + /* "lightfm/_lightfm_fast_openmp.pyx":1305 * * row_start = test_interactions.get_row_start(user_id) * row_stop = test_interactions.get_row_end(user_id) # <<<<<<<<<<<<<< @@ -8139,7 +8879,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_row_stop = ((struct __pyx_vtabstruct_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)__pyx_v_test_interactions->__pyx_vtab)->get_row_end(__pyx_v_test_interactions, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_openmp.pyx":1229 + /* "lightfm/_lightfm_fast_openmp.pyx":1307 * row_stop = test_interactions.get_row_end(user_id) * * if row_stop == row_start: # <<<<<<<<<<<<<< @@ -8149,7 +8889,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON __pyx_t_4 = ((__pyx_v_row_stop == __pyx_v_row_start) != 0); if (__pyx_t_4) { - /* "lightfm/_lightfm_fast_openmp.pyx":1231 + /* "lightfm/_lightfm_fast_openmp.pyx":1309 * if row_stop == row_start: * # No test interactions for this user * continue # <<<<<<<<<<<<<< @@ -8158,7 +8898,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ goto __pyx_L12_continue; - /* "lightfm/_lightfm_fast_openmp.pyx":1229 + /* "lightfm/_lightfm_fast_openmp.pyx":1307 * row_stop = test_interactions.get_row_end(user_id) * * if row_stop == row_start: # <<<<<<<<<<<<<< @@ -8167,7 +8907,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ } - /* "lightfm/_lightfm_fast_openmp.pyx":1233 + /* "lightfm/_lightfm_fast_openmp.pyx":1311 * continue * * compute_representation(user_features, # <<<<<<<<<<<<<< @@ -8176,7 +8916,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_user_features, __pyx_v_lightfm->user_features, __pyx_v_lightfm->user_biases, __pyx_v_lightfm, __pyx_v_user_id, __pyx_v_lightfm->user_scale, __pyx_v_user_repr); - /* "lightfm/_lightfm_fast_openmp.pyx":1243 + /* "lightfm/_lightfm_fast_openmp.pyx":1321 * # Compute predictions for the items whose * # ranks we want to know * for i in range(row_stop - row_start): # <<<<<<<<<<<<<< @@ -8187,7 +8927,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { __pyx_v_i = __pyx_t_6; - /* "lightfm/_lightfm_fast_openmp.pyx":1245 + /* "lightfm/_lightfm_fast_openmp.pyx":1323 * for i in range(row_stop - row_start): * * item_id = test_interactions.indices[row_start + i] # <<<<<<<<<<<<<< @@ -8197,7 +8937,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON __pyx_t_7 = (__pyx_v_row_start + __pyx_v_i); __pyx_v_item_id = (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_test_interactions->indices.data) + __pyx_t_7)) ))); - /* "lightfm/_lightfm_fast_openmp.pyx":1247 + /* "lightfm/_lightfm_fast_openmp.pyx":1325 * item_id = test_interactions.indices[row_start + i] * * compute_representation(item_features, # <<<<<<<<<<<<<< @@ -8206,7 +8946,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, __pyx_v_item_id, __pyx_v_lightfm->item_scale, __pyx_v_it_repr); - /* "lightfm/_lightfm_fast_openmp.pyx":1255 + /* "lightfm/_lightfm_fast_openmp.pyx":1333 * it_repr) * * item_ids[i] = item_id # <<<<<<<<<<<<<< @@ -8215,7 +8955,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ (__pyx_v_item_ids[__pyx_v_i]) = __pyx_v_item_id; - /* "lightfm/_lightfm_fast_openmp.pyx":1256 + /* "lightfm/_lightfm_fast_openmp.pyx":1334 * * item_ids[i] = item_id * predictions[i] = compute_prediction_from_repr(user_repr, # <<<<<<<<<<<<<< @@ -8225,7 +8965,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON (__pyx_v_predictions[__pyx_v_i]) = __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); } - /* "lightfm/_lightfm_fast_openmp.pyx":1261 + /* "lightfm/_lightfm_fast_openmp.pyx":1339 * * # Now we can zip through all the other items and compute ranks * for item_id in range(test_interactions.cols): # <<<<<<<<<<<<<< @@ -8236,7 +8976,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { __pyx_v_item_id = __pyx_t_6; - /* "lightfm/_lightfm_fast_openmp.pyx":1263 + /* "lightfm/_lightfm_fast_openmp.pyx":1341 * for item_id in range(test_interactions.cols): * * if in_positives(item_id, user_id, train_interactions): # <<<<<<<<<<<<<< @@ -8246,7 +8986,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON __pyx_t_4 = (__pyx_f_7lightfm_20_lightfm_fast_openmp_in_positives(__pyx_v_item_id, __pyx_v_user_id, __pyx_v_train_interactions) != 0); if (__pyx_t_4) { - /* "lightfm/_lightfm_fast_openmp.pyx":1264 + /* "lightfm/_lightfm_fast_openmp.pyx":1342 * * if in_positives(item_id, user_id, train_interactions): * continue # <<<<<<<<<<<<<< @@ -8255,7 +8995,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ goto __pyx_L19_continue; - /* "lightfm/_lightfm_fast_openmp.pyx":1263 + /* "lightfm/_lightfm_fast_openmp.pyx":1341 * for item_id in range(test_interactions.cols): * * if in_positives(item_id, user_id, train_interactions): # <<<<<<<<<<<<<< @@ -8264,7 +9004,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ } - /* "lightfm/_lightfm_fast_openmp.pyx":1266 + /* "lightfm/_lightfm_fast_openmp.pyx":1344 * continue * * compute_representation(item_features, # <<<<<<<<<<<<<< @@ -8273,7 +9013,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_representation(__pyx_v_item_features, __pyx_v_lightfm->item_features, __pyx_v_lightfm->item_biases, __pyx_v_lightfm, __pyx_v_item_id, __pyx_v_lightfm->item_scale, __pyx_v_it_repr); - /* "lightfm/_lightfm_fast_openmp.pyx":1273 + /* "lightfm/_lightfm_fast_openmp.pyx":1351 * lightfm.item_scale, * it_repr) * prediction = compute_prediction_from_repr(user_repr, # <<<<<<<<<<<<<< @@ -8282,7 +9022,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ __pyx_v_prediction = __pyx_f_7lightfm_20_lightfm_fast_openmp_compute_prediction_from_repr(__pyx_v_user_repr, __pyx_v_it_repr, __pyx_v_lightfm->no_components); - /* "lightfm/_lightfm_fast_openmp.pyx":1277 + /* "lightfm/_lightfm_fast_openmp.pyx":1355 * lightfm.no_components) * * for i in range(row_stop - row_start): # <<<<<<<<<<<<<< @@ -8293,7 +9033,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "lightfm/_lightfm_fast_openmp.pyx":1278 + /* "lightfm/_lightfm_fast_openmp.pyx":1356 * * for i in range(row_stop - row_start): * if item_id != item_ids[i] and prediction > predictions[i]: # <<<<<<<<<<<<<< @@ -8311,7 +9051,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON __pyx_L25_bool_binop_done:; if (__pyx_t_4) { - /* "lightfm/_lightfm_fast_openmp.pyx":1279 + /* "lightfm/_lightfm_fast_openmp.pyx":1357 * for i in range(row_stop - row_start): * if item_id != item_ids[i] and prediction > predictions[i]: * ranks[row_start + i] += 1.0 # <<<<<<<<<<<<<< @@ -8321,7 +9061,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON __pyx_t_11 = (__pyx_v_row_start + __pyx_v_i); *((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) __pyx_v_ranks.data) + __pyx_t_11)) )) += 1.0; - /* "lightfm/_lightfm_fast_openmp.pyx":1278 + /* "lightfm/_lightfm_fast_openmp.pyx":1356 * * for i in range(row_stop - row_start): * if item_id != item_ids[i] and prediction > predictions[i]: # <<<<<<<<<<<<<< @@ -8341,7 +9081,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON } } - /* "lightfm/_lightfm_fast_openmp.pyx":1281 + /* "lightfm/_lightfm_fast_openmp.pyx":1359 * ranks[row_start + i] += 1.0 * * free(user_repr) # <<<<<<<<<<<<<< @@ -8350,7 +9090,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ free(__pyx_v_user_repr); - /* "lightfm/_lightfm_fast_openmp.pyx":1282 + /* "lightfm/_lightfm_fast_openmp.pyx":1360 * * free(user_repr) * free(it_repr) # <<<<<<<<<<<<<< @@ -8359,7 +9099,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON */ free(__pyx_v_it_repr); - /* "lightfm/_lightfm_fast_openmp.pyx":1283 + /* "lightfm/_lightfm_fast_openmp.pyx":1361 * free(user_repr) * free(it_repr) * free(predictions) # <<<<<<<<<<<<<< @@ -8377,7 +9117,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON #endif } - /* "lightfm/_lightfm_fast_openmp.pyx":1217 + /* "lightfm/_lightfm_fast_openmp.pyx":1295 * - test_interactions.get_row_start(user_id)) * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -8395,7 +9135,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON } } - /* "lightfm/_lightfm_fast_openmp.pyx":1192 + /* "lightfm/_lightfm_fast_openmp.pyx":1270 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< @@ -8411,7 +9151,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_10predict_ranks(CYTHON return __pyx_r; } -/* "lightfm/_lightfm_fast_openmp.pyx":1286 +/* "lightfm/_lightfm_fast_openmp.pyx":1364 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< @@ -8457,26 +9197,26 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_13calculate_auc_from_r case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_train_positives)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_rank_data)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_auc)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 4: if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_num_threads)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate_auc_from_rank") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate_auc_from_rank") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { goto __pyx_L5_argtuple_error; @@ -8488,20 +9228,20 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_13calculate_auc_from_r values[4] = PyTuple_GET_ITEM(__pyx_args, 4); } __pyx_v_ranks = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[0]); - __pyx_v_num_train_positives = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[1]); if (unlikely(!__pyx_v_num_train_positives.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1287; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_rank_data = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_20_lightfm_fast_openmp_flt(values[2]); if (unlikely(!__pyx_v_rank_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1288; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_auc = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_20_lightfm_fast_openmp_flt(values[3]); if (unlikely(!__pyx_v_auc.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1289; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_num_threads = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1290; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_num_train_positives = __Pyx_PyObject_to_MemoryviewSlice_dc_int(values[1]); if (unlikely(!__pyx_v_num_train_positives.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1365; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_rank_data = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_20_lightfm_fast_openmp_flt(values[2]); if (unlikely(!__pyx_v_rank_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1366; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_auc = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_7lightfm_20_lightfm_fast_openmp_flt(values[3]); if (unlikely(!__pyx_v_auc.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1367; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_num_threads = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_num_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1368; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("calculate_auc_from_rank", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("lightfm._lightfm_fast_openmp.calculate_auc_from_rank", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ranks), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "ranks", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ranks), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "ranks", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_rank(__pyx_self, __pyx_v_ranks, __pyx_v_num_train_positives, __pyx_v_rank_data, __pyx_v_auc, __pyx_v_num_threads); /* function exit code */ @@ -8538,7 +9278,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r Py_ssize_t __pyx_t_13; __Pyx_RefNannySetupContext("calculate_auc_from_rank", 0); - /* "lightfm/_lightfm_fast_openmp.pyx":1295 + /* "lightfm/_lightfm_fast_openmp.pyx":1373 * cdef flt rank * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -8559,11 +9299,11 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r #define unlikely(x) (x) #endif #ifdef _OPENMP - #pragma omp parallel private(__pyx_t_3, __pyx_t_1, __pyx_t_10, __pyx_t_11, __pyx_t_8, __pyx_t_9, __pyx_t_2, __pyx_t_5, __pyx_t_7, __pyx_t_4, __pyx_t_13, __pyx_t_6, __pyx_t_12) num_threads(__pyx_v_num_threads) + #pragma omp parallel private(__pyx_t_3, __pyx_t_4, __pyx_t_13, __pyx_t_6, __pyx_t_2, __pyx_t_1, __pyx_t_7, __pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_t_12, __pyx_t_5, __pyx_t_8) num_threads(__pyx_v_num_threads) #endif /* _OPENMP */ { - /* "lightfm/_lightfm_fast_openmp.pyx":1296 + /* "lightfm/_lightfm_fast_openmp.pyx":1374 * * with nogil, parallel(num_threads=num_threads): * for user_id in prange(ranks.rows): # <<<<<<<<<<<<<< @@ -8573,24 +9313,24 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_t_1 = __pyx_v_ranks->rows; if (1 == 0) abort(); { - __pyx_t_3 = (__pyx_t_1 - 0 + 1 - 1/abs(1)) / 1; + __pyx_t_3 = (__pyx_t_1 - 0) / 1; if (__pyx_t_3 > 0) { #ifdef _OPENMP - #pragma omp for lastprivate(__pyx_v_row_stop) firstprivate(__pyx_v_user_id) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_i) lastprivate(__pyx_v_num_negatives) lastprivate(__pyx_v_rank) lastprivate(__pyx_v_row_start) lastprivate(__pyx_v_num_positives) + #pragma omp for lastprivate(__pyx_v_num_positives) lastprivate(__pyx_v_row_stop) lastprivate(__pyx_v_i) lastprivate(__pyx_v_row_start) firstprivate(__pyx_v_user_id) lastprivate(__pyx_v_user_id) lastprivate(__pyx_v_num_negatives) lastprivate(__pyx_v_rank) #endif /* _OPENMP */ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){ { __pyx_v_user_id = 0 + 1 * __pyx_t_2; /* Initialize private variables to invalid values */ + __pyx_v_num_positives = ((int)0xbad0bad0); __pyx_v_row_stop = ((int)0xbad0bad0); __pyx_v_i = ((int)0xbad0bad0); + __pyx_v_row_start = ((int)0xbad0bad0); __pyx_v_num_negatives = ((int)0xbad0bad0); __pyx_v_rank = ((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)__PYX_NAN()); - __pyx_v_row_start = ((int)0xbad0bad0); - __pyx_v_num_positives = ((int)0xbad0bad0); - /* "lightfm/_lightfm_fast_openmp.pyx":1298 + /* "lightfm/_lightfm_fast_openmp.pyx":1376 * for user_id in prange(ranks.rows): * * row_start = ranks.get_row_start(user_id) # <<<<<<<<<<<<<< @@ -8599,7 +9339,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ __pyx_v_row_start = ((struct __pyx_vtabstruct_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)__pyx_v_ranks->__pyx_vtab)->get_row_start(__pyx_v_ranks, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_openmp.pyx":1299 + /* "lightfm/_lightfm_fast_openmp.pyx":1377 * * row_start = ranks.get_row_start(user_id) * row_stop = ranks.get_row_end(user_id) # <<<<<<<<<<<<<< @@ -8608,7 +9348,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ __pyx_v_row_stop = ((struct __pyx_vtabstruct_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)__pyx_v_ranks->__pyx_vtab)->get_row_end(__pyx_v_ranks, __pyx_v_user_id); - /* "lightfm/_lightfm_fast_openmp.pyx":1301 + /* "lightfm/_lightfm_fast_openmp.pyx":1379 * row_stop = ranks.get_row_end(user_id) * * num_positives = row_stop - row_start # <<<<<<<<<<<<<< @@ -8617,7 +9357,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ __pyx_v_num_positives = (__pyx_v_row_stop - __pyx_v_row_start); - /* "lightfm/_lightfm_fast_openmp.pyx":1302 + /* "lightfm/_lightfm_fast_openmp.pyx":1380 * * num_positives = row_stop - row_start * num_negatives = ranks.cols - ((row_stop - row_start) + num_train_positives[user_id]) # <<<<<<<<<<<<<< @@ -8627,7 +9367,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_t_4 = __pyx_v_user_id; __pyx_v_num_negatives = (__pyx_v_ranks->cols - ((__pyx_v_row_stop - __pyx_v_row_start) + (*((int *) ( /* dim=0 */ ((char *) (((int *) __pyx_v_num_train_positives.data) + __pyx_t_4)) ))))); - /* "lightfm/_lightfm_fast_openmp.pyx":1306 + /* "lightfm/_lightfm_fast_openmp.pyx":1384 * # If there is only one class present, * # return 0.5. * if num_positives == 0 or num_negatives == ranks.cols: # <<<<<<<<<<<<<< @@ -8645,7 +9385,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_L15_bool_binop_done:; if (__pyx_t_5) { - /* "lightfm/_lightfm_fast_openmp.pyx":1307 + /* "lightfm/_lightfm_fast_openmp.pyx":1385 * # return 0.5. * if num_positives == 0 or num_negatives == ranks.cols: * auc[user_id] = 0.5 # <<<<<<<<<<<<<< @@ -8655,7 +9395,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_t_7 = __pyx_v_user_id; *((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) __pyx_v_auc.data) + __pyx_t_7)) )) = 0.5; - /* "lightfm/_lightfm_fast_openmp.pyx":1308 + /* "lightfm/_lightfm_fast_openmp.pyx":1386 * if num_positives == 0 or num_negatives == ranks.cols: * auc[user_id] = 0.5 * continue # <<<<<<<<<<<<<< @@ -8664,7 +9404,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ goto __pyx_L10_continue; - /* "lightfm/_lightfm_fast_openmp.pyx":1306 + /* "lightfm/_lightfm_fast_openmp.pyx":1384 * # If there is only one class present, * # return 0.5. * if num_positives == 0 or num_negatives == ranks.cols: # <<<<<<<<<<<<<< @@ -8673,7 +9413,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ } - /* "lightfm/_lightfm_fast_openmp.pyx":1312 + /* "lightfm/_lightfm_fast_openmp.pyx":1390 * # Sort the positives according to * # increasing rank. * qsort(&rank_data[row_start], # <<<<<<<<<<<<<< @@ -8682,7 +9422,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ __pyx_t_8 = __pyx_v_row_start; - /* "lightfm/_lightfm_fast_openmp.pyx":1315 + /* "lightfm/_lightfm_fast_openmp.pyx":1393 * num_positives, * sizeof(flt), * flt_compare) # <<<<<<<<<<<<<< @@ -8691,7 +9431,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ qsort((&(*((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) __pyx_v_rank_data.data) + __pyx_t_8)) )))), __pyx_v_num_positives, (sizeof(__pyx_t_7lightfm_20_lightfm_fast_openmp_flt)), __pyx_f_7lightfm_20_lightfm_fast_openmp_flt_compare); - /* "lightfm/_lightfm_fast_openmp.pyx":1317 + /* "lightfm/_lightfm_fast_openmp.pyx":1395 * flt_compare) * * for i in range(num_positives): # <<<<<<<<<<<<<< @@ -8702,7 +9442,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { __pyx_v_i = __pyx_t_10; - /* "lightfm/_lightfm_fast_openmp.pyx":1319 + /* "lightfm/_lightfm_fast_openmp.pyx":1397 * for i in range(num_positives): * * rank = ranks.data[row_start + i] # <<<<<<<<<<<<<< @@ -8712,7 +9452,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_t_11 = (__pyx_v_row_start + __pyx_v_i); __pyx_v_rank = (*((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) __pyx_v_ranks->data.data) + __pyx_t_11)) ))); - /* "lightfm/_lightfm_fast_openmp.pyx":1325 + /* "lightfm/_lightfm_fast_openmp.pyx":1403 * # by i. Ignore ties but ensure that * # the resulting rank is nonnegative. * rank = rank - i # <<<<<<<<<<<<<< @@ -8721,7 +9461,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ __pyx_v_rank = (__pyx_v_rank - __pyx_v_i); - /* "lightfm/_lightfm_fast_openmp.pyx":1327 + /* "lightfm/_lightfm_fast_openmp.pyx":1405 * rank = rank - i * * if rank < 0: # <<<<<<<<<<<<<< @@ -8731,7 +9471,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_t_5 = ((__pyx_v_rank < 0.0) != 0); if (__pyx_t_5) { - /* "lightfm/_lightfm_fast_openmp.pyx":1328 + /* "lightfm/_lightfm_fast_openmp.pyx":1406 * * if rank < 0: * rank = 0 # <<<<<<<<<<<<<< @@ -8740,7 +9480,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ __pyx_v_rank = 0.0; - /* "lightfm/_lightfm_fast_openmp.pyx":1327 + /* "lightfm/_lightfm_fast_openmp.pyx":1405 * rank = rank - i * * if rank < 0: # <<<<<<<<<<<<<< @@ -8749,7 +9489,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r */ } - /* "lightfm/_lightfm_fast_openmp.pyx":1334 + /* "lightfm/_lightfm_fast_openmp.pyx":1412 * # of rank inversion. * # print(row_start, row_stop, ranks.data[row_stop + i], 1.0 - rank, num_negatives) * auc[user_id] += 1.0 - rank / num_negatives # <<<<<<<<<<<<<< @@ -8760,7 +9500,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r *((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) __pyx_v_auc.data) + __pyx_t_12)) )) += (1.0 - (__pyx_v_rank / __pyx_v_num_negatives)); } - /* "lightfm/_lightfm_fast_openmp.pyx":1336 + /* "lightfm/_lightfm_fast_openmp.pyx":1414 * auc[user_id] += 1.0 - rank / num_negatives * * if num_positives != 0: # <<<<<<<<<<<<<< @@ -8770,7 +9510,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_t_5 = ((__pyx_v_num_positives != 0) != 0); if (__pyx_t_5) { - /* "lightfm/_lightfm_fast_openmp.pyx":1337 + /* "lightfm/_lightfm_fast_openmp.pyx":1415 * * if num_positives != 0: * auc[user_id] /= num_positives # <<<<<<<<<<<<<< @@ -8780,7 +9520,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r __pyx_t_13 = __pyx_v_user_id; *((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) ( /* dim=0 */ ((char *) (((__pyx_t_7lightfm_20_lightfm_fast_openmp_flt *) __pyx_v_auc.data) + __pyx_t_13)) )) /= __pyx_v_num_positives; - /* "lightfm/_lightfm_fast_openmp.pyx":1336 + /* "lightfm/_lightfm_fast_openmp.pyx":1414 * auc[user_id] += 1.0 - rank / num_negatives * * if num_positives != 0: # <<<<<<<<<<<<<< @@ -8806,7 +9546,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r #endif } - /* "lightfm/_lightfm_fast_openmp.pyx":1295 + /* "lightfm/_lightfm_fast_openmp.pyx":1373 * cdef flt rank * * with nogil, parallel(num_threads=num_threads): # <<<<<<<<<<<<<< @@ -8824,7 +9564,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r } } - /* "lightfm/_lightfm_fast_openmp.pyx":1286 + /* "lightfm/_lightfm_fast_openmp.pyx":1364 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< @@ -8842,7 +9582,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_12calculate_auc_from_r return __pyx_r; } -/* "lightfm/_lightfm_fast_openmp.pyx":1341 +/* "lightfm/_lightfm_fast_openmp.pyx":1419 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< @@ -8884,16 +9624,16 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_15__test_in_positives( case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_col)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mat)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__test_in_positives") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__test_in_positives") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;} } } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { goto __pyx_L5_argtuple_error; @@ -8902,19 +9642,19 @@ static PyObject *__pyx_pw_7lightfm_20_lightfm_fast_openmp_15__test_in_positives( values[1] = PyTuple_GET_ITEM(__pyx_args, 1); values[2] = PyTuple_GET_ITEM(__pyx_args, 2); } - __pyx_v_row = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_row == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_v_col = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_col == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_row = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_row == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __pyx_v_col = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_col == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_v_mat = ((struct __pyx_obj_7lightfm_20_lightfm_fast_openmp_CSRMatrix *)values[2]); } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L3_error;} + __Pyx_RaiseArgtupleInvalid("__test_in_positives", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L3_error;} __pyx_L3_error:; __Pyx_AddTraceback("lightfm._lightfm_fast_openmp.__test_in_positives", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mat), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "mat", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mat), __pyx_ptype_7lightfm_20_lightfm_fast_openmp_CSRMatrix, 1, "mat", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __pyx_r = __pyx_pf_7lightfm_20_lightfm_fast_openmp_14__test_in_positives(__pyx_self, __pyx_v_row, __pyx_v_col, __pyx_v_mat); /* function exit code */ @@ -8932,7 +9672,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_14__test_in_positives( int __pyx_t_1; __Pyx_RefNannySetupContext("__test_in_positives", 0); - /* "lightfm/_lightfm_fast_openmp.pyx":1343 + /* "lightfm/_lightfm_fast_openmp.pyx":1421 * def __test_in_positives(int row, int col, CSRMatrix mat): * * if in_positives(col, row, mat): # <<<<<<<<<<<<<< @@ -8942,7 +9682,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_14__test_in_positives( __pyx_t_1 = (__pyx_f_7lightfm_20_lightfm_fast_openmp_in_positives(__pyx_v_col, __pyx_v_row, __pyx_v_mat) != 0); if (__pyx_t_1) { - /* "lightfm/_lightfm_fast_openmp.pyx":1344 + /* "lightfm/_lightfm_fast_openmp.pyx":1422 * * if in_positives(col, row, mat): * return True # <<<<<<<<<<<<<< @@ -8954,7 +9694,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_14__test_in_positives( __pyx_r = Py_True; goto __pyx_L0; - /* "lightfm/_lightfm_fast_openmp.pyx":1343 + /* "lightfm/_lightfm_fast_openmp.pyx":1421 * def __test_in_positives(int row, int col, CSRMatrix mat): * * if in_positives(col, row, mat): # <<<<<<<<<<<<<< @@ -8963,10 +9703,11 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_14__test_in_positives( */ } - /* "lightfm/_lightfm_fast_openmp.pyx":1346 + /* "lightfm/_lightfm_fast_openmp.pyx":1424 * return True * else: * return False # <<<<<<<<<<<<<< + * */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -8975,7 +9716,7 @@ static PyObject *__pyx_pf_7lightfm_20_lightfm_fast_openmp_14__test_in_positives( goto __pyx_L0; } - /* "lightfm/_lightfm_fast_openmp.pyx":1341 + /* "lightfm/_lightfm_fast_openmp.pyx":1419 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< @@ -21460,7 +22201,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1}, {&__pyx_n_s_gamma, __pyx_k_gamma, sizeof(__pyx_k_gamma), 0, 0, 1, 1}, {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0}, - {&__pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_k_home_maciej_Code_lightfm_lightf, sizeof(__pyx_k_home_maciej_Code_lightfm_lightf), 0, 0, 1, 0}, + {&__pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_k_home_paolo_raisDataScience_reco, sizeof(__pyx_k_home_paolo_raisDataScience_reco), 0, 0, 1, 0}, {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1}, {&__pyx_n_s_iinfo, __pyx_k_iinfo, sizeof(__pyx_k_iinfo), 0, 0, 1, 1}, @@ -21469,7 +22210,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_indptr, __pyx_k_indptr, sizeof(__pyx_k_indptr), 0, 0, 1, 1}, {&__pyx_n_s_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 0, 1, 1}, {&__pyx_n_s_interactions, __pyx_k_interactions, sizeof(__pyx_k_interactions), 0, 0, 1, 1}, + {&__pyx_n_s_inverse_items, __pyx_k_inverse_items, sizeof(__pyx_k_inverse_items), 0, 0, 1, 1}, + {&__pyx_n_s_inverse_users, __pyx_k_inverse_users, sizeof(__pyx_k_inverse_users), 0, 0, 1, 1}, {&__pyx_n_s_it_repr, __pyx_k_it_repr, sizeof(__pyx_k_it_repr), 0, 0, 1, 1}, + {&__pyx_n_s_it_reprs, __pyx_k_it_reprs, sizeof(__pyx_k_it_reprs), 0, 0, 1, 1}, {&__pyx_n_s_item_alpha, __pyx_k_item_alpha, sizeof(__pyx_k_item_alpha), 0, 0, 1, 1}, {&__pyx_n_s_item_bias_gradients, __pyx_k_item_bias_gradients, sizeof(__pyx_k_item_bias_gradients), 0, 0, 1, 1}, {&__pyx_n_s_item_bias_momentum, __pyx_k_item_bias_momentum, sizeof(__pyx_k_item_bias_momentum), 0, 0, 1, 1}, @@ -21502,7 +22246,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_negative_prediction, __pyx_k_negative_prediction, sizeof(__pyx_k_negative_prediction), 0, 0, 1, 1}, {&__pyx_n_s_no_components, __pyx_k_no_components, sizeof(__pyx_k_no_components), 0, 0, 1, 1}, {&__pyx_n_s_no_examples, __pyx_k_no_examples, sizeof(__pyx_k_no_examples), 0, 0, 1, 1}, + {&__pyx_n_s_no_features, __pyx_k_no_features, sizeof(__pyx_k_no_features), 0, 0, 1, 1}, {&__pyx_n_s_no_positives, __pyx_k_no_positives, sizeof(__pyx_k_no_positives), 0, 0, 1, 1}, + {&__pyx_n_s_no_users, __pyx_k_no_users, sizeof(__pyx_k_no_users), 0, 0, 1, 1}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, {&__pyx_n_s_num_negatives, __pyx_k_num_negatives, sizeof(__pyx_k_num_negatives), 0, 0, 1, 1}, {&__pyx_n_s_num_positives, __pyx_k_num_positives, sizeof(__pyx_k_num_positives), 0, 0, 1, 1}, @@ -21515,6 +22261,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_pos_pairs, __pyx_k_pos_pairs, sizeof(__pyx_k_pos_pairs), 0, 0, 1, 1}, {&__pyx_n_s_positive_item_id, __pyx_k_positive_item_id, sizeof(__pyx_k_positive_item_id), 0, 0, 1, 1}, {&__pyx_n_s_positive_prediction, __pyx_k_positive_prediction, sizeof(__pyx_k_positive_prediction), 0, 0, 1, 1}, + {&__pyx_n_s_precompute, __pyx_k_precompute, sizeof(__pyx_k_precompute), 0, 0, 1, 1}, {&__pyx_n_s_predict_lightfm, __pyx_k_predict_lightfm, sizeof(__pyx_k_predict_lightfm), 0, 0, 1, 1}, {&__pyx_n_s_predict_ranks, __pyx_k_predict_ranks, sizeof(__pyx_k_predict_ranks), 0, 0, 1, 1}, {&__pyx_n_s_prediction, __pyx_k_prediction, sizeof(__pyx_k_prediction), 0, 0, 1, 1}, @@ -21529,6 +22276,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_rank, __pyx_k_rank, sizeof(__pyx_k_rank), 0, 0, 1, 1}, {&__pyx_n_s_rank_data, __pyx_k_rank_data, sizeof(__pyx_k_rank_data), 0, 0, 1, 1}, {&__pyx_n_s_ranks, __pyx_k_ranks, sizeof(__pyx_k_ranks), 0, 0, 1, 1}, + {&__pyx_n_s_return_inverse, __pyx_k_return_inverse, sizeof(__pyx_k_return_inverse), 0, 0, 1, 1}, {&__pyx_n_s_rho, __pyx_k_rho, sizeof(__pyx_k_rho), 0, 0, 1, 1}, {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1}, {&__pyx_n_s_row_start, __pyx_k_row_start, sizeof(__pyx_k_row_start), 0, 0, 1, 1}, @@ -21554,6 +22302,9 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1}, {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0}, {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0}, + {&__pyx_n_s_unique, __pyx_k_unique, sizeof(__pyx_k_unique), 0, 0, 1, 1}, + {&__pyx_n_s_unique_items, __pyx_k_unique_items, sizeof(__pyx_k_unique_items), 0, 0, 1, 1}, + {&__pyx_n_s_unique_users, __pyx_k_unique_users, sizeof(__pyx_k_unique_users), 0, 0, 1, 1}, {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1}, {&__pyx_n_s_user_alpha, __pyx_k_user_alpha, sizeof(__pyx_k_user_alpha), 0, 0, 1, 1}, {&__pyx_n_s_user_bias_gradients, __pyx_k_user_bias_gradients, sizeof(__pyx_k_user_bias_gradients), 0, 0, 1, 1}, @@ -21567,6 +22318,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_user_pids_start, __pyx_k_user_pids_start, sizeof(__pyx_k_user_pids_start), 0, 0, 1, 1}, {&__pyx_n_s_user_pids_stop, __pyx_k_user_pids_stop, sizeof(__pyx_k_user_pids_stop), 0, 0, 1, 1}, {&__pyx_n_s_user_repr, __pyx_k_user_repr, sizeof(__pyx_k_user_repr), 0, 0, 1, 1}, + {&__pyx_n_s_user_reprs, __pyx_k_user_reprs, sizeof(__pyx_k_user_reprs), 0, 0, 1, 1}, {&__pyx_n_s_weight, __pyx_k_weight, sizeof(__pyx_k_weight), 0, 0, 1, 1}, {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1}, {&__pyx_n_s_y_row, __pyx_k_y_row, sizeof(__pyx_k_y_row), 0, 0, 1, 1}, @@ -21746,7 +22498,7 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__14 = PyTuple_Pack(24, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_Y, __pyx_n_s_sample_weight, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_item_id, __pyx_n_s_row, __pyx_n_s_prediction, __pyx_n_s_loss, __pyx_n_s_y, __pyx_n_s_y_row, __pyx_n_s_weight, __pyx_n_s_user_repr, __pyx_n_s_it_repr); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 674; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__14); __Pyx_GIVEREF(__pyx_tuple__14); - __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(12, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_logistic, 674, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 674; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(12, 0, 24, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_logistic, 674, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 674; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "lightfm/_lightfm_fast_openmp.pyx":759 * @@ -21758,7 +22510,7 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__16 = PyTuple_Pack(31, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_interactions, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_Y, __pyx_n_s_sample_weight, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_num_threads, __pyx_n_s_random_state, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_positive_item_id, __pyx_n_s_gamma, __pyx_n_s_negative_item_id, __pyx_n_s_sampled, __pyx_n_s_row, __pyx_n_s_positive_prediction, __pyx_n_s_negative_prediction, __pyx_n_s_loss, __pyx_n_s_MAX_LOSS, __pyx_n_s_weight, __pyx_n_s_user_repr, __pyx_n_s_pos_it_repr, __pyx_n_s_neg_it_repr, __pyx_n_s_random_states); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__16); __Pyx_GIVEREF(__pyx_tuple__16); - __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(14, 0, 31, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_warp, 759, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(14, 0, 31, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_warp, 759, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "lightfm/_lightfm_fast_openmp.pyx":885 * @@ -21770,7 +22522,7 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__18 = PyTuple_Pack(37, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_data, __pyx_n_s_user_ids, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_k, __pyx_n_s_n, __pyx_n_s_num_threads, __pyx_n_s_random_state, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_positive_item_id, __pyx_n_s_gamma, __pyx_n_s_negative_item_id, __pyx_n_s_sampled, __pyx_n_s_row, __pyx_n_s_sampled_positive_item_id, __pyx_n_s_user_pids_start, __pyx_n_s_user_pids_stop, __pyx_n_s_no_positives, __pyx_n_s_POS_SAMPLES, __pyx_n_s_positive_prediction, __pyx_n_s_negative_prediction, __pyx_n_s_loss, __pyx_n_s_MAX_LOSS, __pyx_n_s_sampled_positive_prediction, __pyx_n_s_user_repr, __pyx_n_s_pos_it_repr, __pyx_n_s_neg_it_repr, __pyx_n_s_pos_pairs, __pyx_n_s_random_states); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__18); __Pyx_GIVEREF(__pyx_tuple__18); - __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(13, 0, 37, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_warp_kos, 885, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(13, 0, 37, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_warp_kos, 885, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "lightfm/_lightfm_fast_openmp.pyx":1039 * @@ -21782,55 +22534,55 @@ static int __Pyx_InitCachedConstants(void) { __pyx_tuple__20 = PyTuple_Pack(28, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_interactions, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_Y, __pyx_n_s_sample_weight, __pyx_n_s_shuffle_indices, __pyx_n_s_lightfm, __pyx_n_s_learning_rate, __pyx_n_s_item_alpha, __pyx_n_s_user_alpha, __pyx_n_s_num_threads, __pyx_n_s_random_state, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_id, __pyx_n_s_positive_item_id, __pyx_n_s_negative_item_id, __pyx_n_s_sampled, __pyx_n_s_row, __pyx_n_s_positive_prediction, __pyx_n_s_negative_prediction, __pyx_n_s_weight, __pyx_n_s_random_states, __pyx_n_s_user_repr, __pyx_n_s_pos_it_repr, __pyx_n_s_neg_it_repr); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__20); __Pyx_GIVEREF(__pyx_tuple__20); - __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(14, 0, 28, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_fit_bpr, 1039, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(14, 0, 28, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_fit_bpr, 1039, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_openmp.pyx":1145 + /* "lightfm/_lightfm_fast_openmp.pyx":1193 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * int[::1] user_ids, */ - __pyx_tuple__22 = PyTuple_Pack(11, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_predictions, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_no_examples, __pyx_n_s_user_repr, __pyx_n_s_it_repr); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__22 = PyTuple_Pack(21, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_user_ids, __pyx_n_s_item_ids, __pyx_n_s_predictions, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_precompute, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_no_examples, __pyx_n_s_user_repr, __pyx_n_s_it_repr, __pyx_n_s_user_reprs, __pyx_n_s_it_reprs, __pyx_n_s_unique_users, __pyx_n_s_unique_items, __pyx_n_s_inverse_users, __pyx_n_s_inverse_items, __pyx_n_s_no_features, __pyx_n_s_no_users); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__22); __Pyx_GIVEREF(__pyx_tuple__22); - __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(7, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_predict_lightfm, 1145, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(8, 0, 21, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_predict_lightfm, 1193, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_openmp.pyx":1192 + /* "lightfm/_lightfm_fast_openmp.pyx":1270 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * CSRMatrix test_interactions, */ - __pyx_tuple__24 = PyTuple_Pack(20, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_test_interactions, __pyx_n_s_train_interactions, __pyx_n_s_ranks, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_item_id, __pyx_n_s_predictions_size, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_user_repr, __pyx_n_s_it_repr, __pyx_n_s_predictions, __pyx_n_s_prediction, __pyx_n_s_rank, __pyx_n_s_item_ids); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__24 = PyTuple_Pack(20, __pyx_n_s_item_features, __pyx_n_s_user_features, __pyx_n_s_test_interactions, __pyx_n_s_train_interactions, __pyx_n_s_ranks, __pyx_n_s_lightfm, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_item_id, __pyx_n_s_predictions_size, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_user_repr, __pyx_n_s_it_repr, __pyx_n_s_predictions, __pyx_n_s_prediction, __pyx_n_s_rank, __pyx_n_s_item_ids); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__24); __Pyx_GIVEREF(__pyx_tuple__24); - __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(7, 0, 20, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_predict_ranks, 1192, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__25 = (PyObject*)__Pyx_PyCode_New(7, 0, 20, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__24, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_predict_ranks, 1270, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_openmp.pyx":1286 + /* "lightfm/_lightfm_fast_openmp.pyx":1364 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< * int[::1] num_train_positives, * flt[::1] rank_data, */ - __pyx_tuple__26 = PyTuple_Pack(13, __pyx_n_s_ranks, __pyx_n_s_num_train_positives, __pyx_n_s_rank_data, __pyx_n_s_auc, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_num_negatives, __pyx_n_s_num_positives, __pyx_n_s_rank); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__26 = PyTuple_Pack(13, __pyx_n_s_ranks, __pyx_n_s_num_train_positives, __pyx_n_s_rank_data, __pyx_n_s_auc, __pyx_n_s_num_threads, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_user_id, __pyx_n_s_row_start, __pyx_n_s_row_stop, __pyx_n_s_num_negatives, __pyx_n_s_num_positives, __pyx_n_s_rank); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__26); __Pyx_GIVEREF(__pyx_tuple__26); - __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_calculate_auc_from_rank, 1286, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__27 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__26, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_calculate_auc_from_rank, 1364, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /* "lightfm/_lightfm_fast_openmp.pyx":1341 + /* "lightfm/_lightfm_fast_openmp.pyx":1419 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< * * if in_positives(col, row, mat): */ - __pyx_tuple__28 = PyTuple_Pack(3, __pyx_n_s_row, __pyx_n_s_col, __pyx_n_s_mat); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_tuple__28 = PyTuple_Pack(3, __pyx_n_s_row, __pyx_n_s_col, __pyx_n_s_mat); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_tuple__28); __Pyx_GIVEREF(__pyx_tuple__28); - __pyx_codeobj__29 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_maciej_Code_lightfm_lightf, __pyx_n_s_test_in_positives, 1341, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_codeobj__29 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__28, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_paolo_raisDataScience_reco, __pyx_n_s_test_in_positives, 1419, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;} /* "View.MemoryView":278 * return self.name @@ -22108,52 +22860,52 @@ PyMODINIT_FUNC PyInit__lightfm_fast_openmp(void) if (PyDict_SetItem(__pyx_d, __pyx_n_s_fit_bpr, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_openmp.pyx":1145 + /* "lightfm/_lightfm_fast_openmp.pyx":1193 * * * def predict_lightfm(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * int[::1] user_ids, */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_9predict_lightfm, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_9predict_lightfm, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_lightfm, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_lightfm, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_openmp.pyx":1192 + /* "lightfm/_lightfm_fast_openmp.pyx":1270 * * * def predict_ranks(CSRMatrix item_features, # <<<<<<<<<<<<<< * CSRMatrix user_features, * CSRMatrix test_interactions, */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_11predict_ranks, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_11predict_ranks, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_ranks, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_predict_ranks, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_openmp.pyx":1286 + /* "lightfm/_lightfm_fast_openmp.pyx":1364 * * * def calculate_auc_from_rank(CSRMatrix ranks, # <<<<<<<<<<<<<< * int[::1] num_train_positives, * flt[::1] rank_data, */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_13calculate_auc_from_rank, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_13calculate_auc_from_rank, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_auc_from_rank, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1286; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_calculate_auc_from_rank, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "lightfm/_lightfm_fast_openmp.pyx":1341 + /* "lightfm/_lightfm_fast_openmp.pyx":1419 * * # Expose test functions * def __test_in_positives(int row, int col, CSRMatrix mat): # <<<<<<<<<<<<<< * * if in_positives(col, row, mat): */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_15__test_in_positives, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7lightfm_20_lightfm_fast_openmp_15__test_in_positives, NULL, __pyx_n_s_lightfm__lightfm_fast_openmp); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_in_positives, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;} + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test_in_positives, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1419; __pyx_clineno = __LINE__; goto __pyx_L1_error;} __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "lightfm/_lightfm_fast_openmp.pyx":1 @@ -24659,7 +25411,7 @@ static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) case -2: if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { @@ -24875,6 +25627,17 @@ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { } } +static PyObject *__pyx_memview_get_int(const char *itemp) { + return (PyObject *) __Pyx_PyInt_From_int(*(int *) itemp); +} +static int __pyx_memview_set_int(const char *itemp, PyObject *obj) { + int value = __Pyx_PyInt_As_int(obj); + if ((value == (int)-1) && PyErr_Occurred()) + return 0; + *(int *) itemp = value; + return 1; +} + static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs, char order, int ndim) @@ -25085,7 +25848,7 @@ static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) { const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (char) 0; - case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, (sdigit) (-(sdigit)digits[0])) + case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(char, digit, +digits[0]) case -2: if (8 * sizeof(char) - 1 > 1 * PyLong_SHIFT) { @@ -25269,7 +26032,7 @@ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) case -2: if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { @@ -25400,6 +26163,28 @@ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_uns return result; } +static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_long(PyObject *obj) { + __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; + __Pyx_BufFmt_StackElem stack[1]; + int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) }; + int retcode; + if (obj == Py_None) { + result.memview = (struct __pyx_memoryview_obj *) Py_None; + return result; + } + retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG, + (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1, + &__Pyx_TypeInfo_long, stack, + &result, obj); + if (unlikely(retcode == -1)) + goto __pyx_fail; + return result; +__pyx_fail: + result.memview = NULL; + result.data = NULL; + return result; +} + static int __Pyx_check_binary_version(void) { char ctversion[4], rtversion[4]; PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); diff --git a/lightfm/lightfm.py b/lightfm/lightfm.py index d537c77a..28220cc3 100644 --- a/lightfm/lightfm.py +++ b/lightfm/lightfm.py @@ -6,7 +6,8 @@ from ._lightfm_fast import (CSRMatrix, FastLightFM, fit_bpr, fit_logistic, fit_warp, - fit_warp_kos, predict_lightfm, predict_ranks) + fit_warp_kos, predict_lightfm, + predict_ranks) __all__ = ['LightFM'] @@ -538,7 +539,9 @@ def _run_epoch(self, item_features, user_features, interactions, self.user_alpha, num_threads) - def predict(self, user_ids, item_ids, item_features=None, user_features=None, num_threads=1): + def predict(self, user_ids, item_ids, item_features=None, + user_features=None, num_threads=1, + precompute_representations=True): """ Compute the recommendation score for user-item pairs. @@ -558,6 +561,9 @@ def predict(self, user_ids, item_ids, item_features=None, user_features=None, nu num_threads: int, optional Number of parallel computation threads to use. Should not be higher than the number of physical cores. + precompute_representations: boolean + if True, the representations are pre-computed for all items + and all users, instead of being computed once for each pair. Returns ------- @@ -598,7 +604,8 @@ def predict(self, user_ids, item_ids, item_features=None, user_features=None, nu item_ids, predictions, lightfm_data, - num_threads) + num_threads, + precompute_representations) return predictions @@ -679,3 +686,81 @@ def predict_rank(self, test_interactions, train_interactions=None, num_threads) return ranks + + def predict_score(self, test_interactions, train_interactions=None, + item_features=None, user_features=None, num_threads=1, + precompute_representations=True): + """ + Score prediction accepting a test and train matrix as input. + Modelled upon predict_rank. + + Arguments + --------- + test_interactions: np.float32 csr_matrix of shape [n_users, n_items] + Non-zero entries denote the user-item pairs whose score will be computed. + train_interactions: np.float32 csr_matrix of shape [n_users, n_items], optional + Non-zero entries denote the user-item pairs which will be excluded from + score computation. Use to exclude training set interactions from being scored + for evaluation. + item_ids: np.int32 array of shape [n_pairs,] + an array containing the item ids for the user-item pairs for which + a prediction is to be computed. + user_features: np.float32 csr_matrix of shape [n_users, n_user_features], optional + Each row contains that user's weights over features. + item_features: np.float32 csr_matrix of shape [n_items, n_item_features], optional + Each row contains that item's weights over features. + num_threads: int, optional + Number of parallel computation threads to use. Should + not be higher than the number of physical cores. + + Returns + ------- + + np.float32 csr_matrix of shape [n_users, n_items] + the [i, j]-th entry of the matrix will contain the evaluation score of the j-th item + in the sorted recommendations list for the i-th user. The degree + of sparsity of this matrix will be equal to that of the input interactions + matrix. + """ + + n_users, n_items = test_interactions.shape + + (user_features, + item_features) = self._construct_feature_matrices(n_users, + n_items, + user_features, + item_features) + + if not item_features.shape[1] == self.item_embeddings.shape[0]: + raise ValueError('Incorrect number of features in item_features') + + if not user_features.shape[1] == self.user_embeddings.shape[0]: + raise ValueError('Incorrect number of features in user_features') + + test_interactions = test_interactions.tocoo() + test_interactions = self._to_cython_dtype(test_interactions) + + if train_interactions is None: + train_interactions = sp.coo_matrix((n_users, n_items), + dtype=CYTHON_DTYPE) + else: + train_interactions = train_interactions.tocoo() + train_interactions = self._to_cython_dtype(train_interactions) + + test_set = (set(zip(test_interactions.row, test_interactions.col)) - + set(zip(train_interactions.row, train_interactions.col))) + if len(test_set) > 0: + user_ids, item_ids = zip(*test_set) + user_ids = np.array(user_ids, dtype=np.int32) + item_ids = np.array(item_ids, dtype=np.int32) + + scores = self.predict( + user_ids, item_ids, item_features, user_features, + num_threads, + precompute_representations=precompute_representations) + scores = sp.coo_matrix((scores, (user_ids, item_ids)), + shape=(n_users, n_items)) + + return scores.tocsr() + else: + return sp.csr_matrix((n_users, n_items), dtype=np.float32) diff --git a/tests/test_api.py b/tests/test_api.py index c5ef63d7..0a489078 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -58,7 +58,7 @@ def test_matrix_types(): item_features=item_features) -def test_predict(): +def test_predict(num_threads=2): no_users, no_items = (10, 100) @@ -75,6 +75,20 @@ def test_predict(): scores_int = model.predict(uid, np.arange(no_items)) assert np.allclose(scores_arr, scores_int) + scores_parallel = model.predict(np.repeat(uid, no_items), + np.arange(no_items), + num_threads=num_threads) + assert np.allclose(scores_parallel, scores_arr) + scores_no_prec = model.predict(np.repeat(uid, no_items), + np.arange(no_items), + num_threads=num_threads, + precompute_representations=False) + assert np.allclose(scores_parallel, scores_no_prec) + scores_no_prec_serial = model.predict(np.repeat(uid, no_items), + np.arange(no_items), + num_threads=1, + precompute_representations=False) + assert np.allclose(scores_parallel, scores_no_prec_serial) def test_input_dtypes(): @@ -278,3 +292,75 @@ def test_predict_ranks(): # Wrong input dimensions with pytest.raises(ValueError): model.predict_rank(sp.csr_matrix((5, 5)), num_threads=2) + + +def test_predict_scores(num_threads=2): + + no_users, no_items = (10, 100) + + train = sp.coo_matrix((no_users, + no_items), + dtype=np.float32) + train = sp.rand(no_users, no_items, format='csr') + + model = LightFM() + model.fit_partial(train) + + # Compute scores and check if results equal to model.predict + predict_input = sp.csr_matrix(np.ones((no_users, no_items))) + scores = model.predict_score(predict_input, + num_threads=num_threads).todense() + for uid in range(no_users): + scores_arr = model.predict(np.repeat(uid, no_items), + np.arange(no_items)) + score_slice = np.array(scores)[uid, :] + assert np.array_equal(score_slice, scores_arr) + + # check if precompute and parallelization work correctly + scores_serial = model.predict_score(predict_input, + num_threads=1).todense() + scores_no_prec = model.predict_score(predict_input, + num_threads=num_threads, + precompute_representations=False + ).todense() + scores_ser_no_prec = model.predict_score(predict_input, + num_threads=1, + precompute_representations=False + ).todense() + assert np.array_equal(scores, scores_serial) + assert np.array_equal(scores, scores_no_prec) + assert np.array_equal(scores, scores_ser_no_prec) + + # Compute ranks and compares with ranks computed from scores + ranks = model.predict_rank(predict_input, + num_threads=num_threads).todense() + + def rank_scores(s): + # ranks from scores as in http://stackoverflow.com/a/14672797/5251962 + u, v = np.unique(s, return_inverse=True) + return len(s) - 1 - (np.cumsum(np.bincount(v)) - 1)[v] + + check_ranks = np.apply_along_axis(rank_scores, 1, scores) + assert np.array_equal(ranks, check_ranks) + + # Train set exclusions. All scores should be zero + # if train interactions is dense. + scores = model.predict_score(predict_input, + train_interactions=predict_input).todense() + assert np.all(scores == 0) + + # Make sure invariants hold when there are ties + model.user_embeddings = np.zeros_like(model.user_embeddings) + model.item_embeddings = np.zeros_like(model.item_embeddings) + model.user_biases = np.zeros_like(model.user_biases) + model.item_biases = np.zeros_like(model.item_biases) + + scores = model.predict_score(predict_input, + num_threads=num_threads).todense() + + assert np.all(scores.min(axis=1) == 0) + assert np.all(scores.max(axis=1) == 0) + + # Wrong input dimensions + with pytest.raises(ValueError): + model.predict_score(sp.csr_matrix((5, 5)), num_threads=num_threads)