From 746b6480e1f1aa7b4f080fabcb872bc437242f86 Mon Sep 17 00:00:00 2001 From: Philip Sampaio Date: Thu, 31 Mar 2022 20:19:18 -0300 Subject: [PATCH] Add "schedule" annotation to NIF functions (#148) This is needed to classify most of the NIF functions as possible "dirty". For smaller sets, those functions should not take more than 1 millisecond to perform. But for larger datasets, it's probably going to take more time. This follows the recommendations from: https://www.erlang.org/doc/man/erl_nif.html#lengthy_work Also see https://github.com/rusterlium/rustler/issues/402 --- native/explorer/src/dataframe.rs | 66 +++++++------- native/explorer/src/series.rs | 144 +++++++++++++++---------------- 2 files changed, 105 insertions(+), 105 deletions(-) diff --git a/native/explorer/src/dataframe.rs b/native/explorer/src/dataframe.rs index 6b94caf37..f8913f107 100644 --- a/native/explorer/src/dataframe.rs +++ b/native/explorer/src/dataframe.rs @@ -32,7 +32,7 @@ macro_rules! df_read_read { }; } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] #[allow(clippy::too_many_arguments)] pub fn df_read_csv( filename: &str, @@ -96,14 +96,14 @@ fn dtype_from_str(dtype: &str) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_read_parquet(filename: &str) -> Result { let f = File::open(filename)?; let df = ParquetReader::new(f).finish()?; Ok(ExDataFrame::new(df)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_write_parquet(data: ExDataFrame, filename: &str) -> Result<(), ExplorerError> { df_read!(data, df, { let file = File::create(filename).expect("could not create file"); @@ -112,7 +112,7 @@ pub fn df_write_parquet(data: ExDataFrame, filename: &str) -> Result<(), Explore }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_to_csv( data: ExDataFrame, has_headers: bool, @@ -130,7 +130,7 @@ pub fn df_to_csv( }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_to_csv_file( data: ExDataFrame, filename: &str, @@ -147,14 +147,14 @@ pub fn df_to_csv_file( }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_read_ipc(filename: &str) -> Result { let f = File::open(filename)?; let df = IpcReader::new(f).finish()?; Ok(ExDataFrame::new(df)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_write_ipc(data: ExDataFrame, filename: &str) -> Result<(), ExplorerError> { df_read!(data, df, { let mut file = File::create(filename).expect("could not create file"); @@ -163,7 +163,7 @@ pub fn df_write_ipc(data: ExDataFrame, filename: &str) -> Result<(), ExplorerErr }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_read_ndjson( filename: &str, infer_schema_length: Option, @@ -180,7 +180,7 @@ pub fn df_read_ndjson( Ok(ExDataFrame::new(df)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_write_ndjson(data: ExDataFrame, filename: &str) -> Result<(), ExplorerError> { df_read!(data, df, { let file = File::create(filename).expect("could not create file"); @@ -189,12 +189,12 @@ pub fn df_write_ndjson(data: ExDataFrame, filename: &str) -> Result<(), Explorer }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyIo")] pub fn df_as_str(data: ExDataFrame) -> Result { df_read!(data, df, { Ok(format!("{:?}", df)) }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_from_map_rows( rows: Vec>>, ) -> Result { @@ -259,7 +259,7 @@ fn case_insensitive_sort(strings: &mut Vec) { strings.sort_by(|a, b| a.to_lowercase().cmp(&b.to_lowercase())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_from_keyword_rows( rows: Vec)>>, ) -> Result { @@ -315,7 +315,7 @@ pub fn df_fill_none(data: ExDataFrame, strategy: &str) -> Result Result, ExplorerError> { df_read!(data, df, { Ok(to_ex_series_collection(df.get_columns().clone())) @@ -389,14 +389,14 @@ pub fn df_hstack(data: ExDataFrame, cols: Vec) -> Result Result { df_read_read!(data, other, df, df1, { Ok(ExDataFrame::new(df.vstack(&df1.clone())?)) }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_drop_nulls( data: ExDataFrame, subset: Option>, @@ -407,7 +407,7 @@ pub fn df_drop_nulls( }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_drop(data: ExDataFrame, name: &str) -> Result { df_read!(data, df, { let new_df = (&*df).drop(name)?; @@ -415,7 +415,7 @@ pub fn df_drop(data: ExDataFrame, name: &str) -> Result Result, ExplorerError> { df_read!(data, df, { let result = df.select_at_idx(idx).map(|s| ExSeries::new(s.clone())); @@ -423,7 +423,7 @@ pub fn df_select_at_idx(data: ExDataFrame, idx: usize) -> Result Result { df_read!(data, df, { let series = df.column(name).map(|s| ExSeries::new(s.clone()))?; @@ -439,7 +439,7 @@ pub fn df_select(data: ExDataFrame, selection: Vec<&str>) -> Result Result { df_read!(data, df, { let filter_series = &mask.resource.0; @@ -461,7 +461,7 @@ pub fn df_take(data: ExDataFrame, indices: Vec) -> Result) -> Result { df_read!(data, df, { let new_df = df.head(length); @@ -493,7 +493,7 @@ pub fn df_head(data: ExDataFrame, length: Option) -> Result) -> Result { df_read!(data, df, { let new_df = df.tail(length); @@ -501,12 +501,12 @@ pub fn df_tail(data: ExDataFrame, length: Option) -> Result Result { df_read!(data, df, { Ok(ExDataFrame::new(df.clone())) }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_melt( data: ExDataFrame, id_vars: Vec<&str>, @@ -518,7 +518,7 @@ pub fn df_melt( }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_drop_duplicates( data: ExDataFrame, maintain_order: bool, @@ -533,7 +533,7 @@ pub fn df_drop_duplicates( }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_to_dummies(data: ExDataFrame) -> Result { df_read!(data, df, { let new_df = df.to_dummies()?; @@ -541,7 +541,7 @@ pub fn df_to_dummies(data: ExDataFrame) -> Result { }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_with_column(data: ExDataFrame, col: ExSeries) -> Result { df_read!(data, df, { let mut new_df = df.clone(); @@ -557,7 +557,7 @@ pub fn df_new(cols: Vec) -> Result { Ok(ExDataFrame::new(df)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_set_column_names( data: ExDataFrame, names: Vec<&str>, @@ -569,7 +569,7 @@ pub fn df_set_column_names( }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_groups(data: ExDataFrame, groups: Vec<&str>) -> Result { df_read!(data, df, { let groups = df.groupby(groups)?.groups()?; @@ -577,7 +577,7 @@ pub fn df_groups(data: ExDataFrame, groups: Vec<&str>) -> Result, @@ -589,7 +589,7 @@ pub fn df_groupby_agg( }) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn df_pivot_wider( data: ExDataFrame, id_cols: Vec<&str>, diff --git a/native/explorer/src/series.rs b/native/explorer/src/series.rs index 60e2694a5..0d4415915 100644 --- a/native/explorer/src/series.rs +++ b/native/explorer/src/series.rs @@ -117,7 +117,7 @@ pub fn s_slice(data: ExSeries, offset: i64, length: usize) -> Result Result { let mut s = data.resource.0.clone(); let s1 = &other.resource.0; @@ -125,7 +125,7 @@ pub fn s_append(data: ExSeries, other: ExSeries) -> Result Result { let s = &data.resource.0; let s1 = &filter.resource.0; @@ -137,28 +137,28 @@ pub fn s_filter(data: ExSeries, filter: ExSeries) -> Result Result { let s = &data.resource.0; let s1 = &other.resource.0; Ok(ExSeries::new(s + s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_sub(data: ExSeries, other: ExSeries) -> Result { let s = &data.resource.0; let s1 = &other.resource.0; Ok(ExSeries::new(s - s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_mul(data: ExSeries, other: ExSeries) -> Result { let s = &data.resource.0; let s1 = &other.resource.0; Ok(ExSeries::new(s * s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_div(data: ExSeries, other: ExSeries) -> Result { let s = &data.resource.0; let s1 = &other.resource.0; @@ -171,19 +171,19 @@ pub fn s_head(data: ExSeries, length: Option) -> Result) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.tail(length))) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_sort(data: ExSeries, reverse: bool) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.sort(reverse))) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_argsort(data: ExSeries, reverse: bool) -> Result>, ExplorerError> { let s = &data.resource.0; Ok(s.argsort(SortOptions { @@ -194,21 +194,21 @@ pub fn s_argsort(data: ExSeries, reverse: bool) -> Result>, Expl .collect::>>()) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_distinct(data: ExSeries) -> Result { let s = &data.resource.0; let unique = s.take(&s.arg_unique()?)?; Ok(ExSeries::new(unique)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_unordered_distinct(data: ExSeries) -> Result { let s = &data.resource.0; let unique = s.unique()?; Ok(ExSeries::new(unique)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_value_counts(data: ExSeries) -> Result { let s = &data.resource.0; let mut df = s.value_counts()?; @@ -218,7 +218,7 @@ pub fn s_value_counts(data: ExSeries) -> Result { Ok(ExDataFrame::new(df)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_take(data: ExSeries, indices: Vec) -> Result { let s = &data.resource.0; let idx = UInt32Chunked::from_vec("idx", indices); @@ -226,60 +226,60 @@ pub fn s_take(data: ExSeries, indices: Vec) -> Result Result { let s = &data.resource.0; Ok(s.null_count()) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_is_null(data: ExSeries) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.is_null().into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_is_not_null(data: ExSeries) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.is_not_null().into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_is_unique(data: ExSeries) -> Result { let s = &data.resource.0; let ca = s.is_unique()?; Ok(ExSeries::new(ca.into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_arg_true(data: ExSeries) -> Result { let s = &data.resource.0; let ca = s.arg_true()?; Ok(ExSeries::new(ca.into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_is_duplicated(data: ExSeries) -> Result { let s = &data.resource.0; let ca = s.is_duplicated()?; Ok(ExSeries::new(ca.into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_explode(data: ExSeries) -> Result { let s = &data.resource.0; let s1 = s.explode()?; Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_take_every(data: ExSeries, n: usize) -> Result { let s = &data.resource.0; let s1 = s.take_every(n); Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_series_equal( data: ExSeries, other: ExSeries, @@ -295,56 +295,56 @@ pub fn s_series_equal( Ok(result) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_eq(data: ExSeries, rhs: ExSeries) -> Result { let s = &data.resource.0; let s1 = &rhs.resource.0; Ok(ExSeries::new(s.equal(s1).into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_neq(data: ExSeries, rhs: ExSeries) -> Result { let s = &data.resource.0; let s1 = &rhs.resource.0; Ok(ExSeries::new(s.not_equal(s1).into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_gt(data: ExSeries, rhs: ExSeries) -> Result { let s = &data.resource.0; let s1 = &rhs.resource.0; Ok(ExSeries::new(s.gt(s1).into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_gt_eq(data: ExSeries, rhs: ExSeries) -> Result { let s = &data.resource.0; let s1 = &rhs.resource.0; Ok(ExSeries::new(s.gt_eq(s1).into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_lt(data: ExSeries, rhs: ExSeries) -> Result { let s = &data.resource.0; let s1 = &rhs.resource.0; Ok(ExSeries::new(s.lt(s1).into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_lt_eq(data: ExSeries, rhs: ExSeries) -> Result { let s = &data.resource.0; let s1 = &rhs.resource.0; Ok(ExSeries::new(s.lt_eq(s1).into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_not(data: ExSeries) -> Result { let s = &data.resource.0; let bool = s.bool()?; Ok(ExSeries::new((!bool).into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_and(lhs: ExSeries, rhs: ExSeries) -> Result { let s = &lhs.resource.0; let s1 = &rhs.resource.0; @@ -352,7 +352,7 @@ pub fn s_and(lhs: ExSeries, rhs: ExSeries) -> Result { Ok(ExSeries::new(and.into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_or(lhs: ExSeries, rhs: ExSeries) -> Result { let s = &lhs.resource.0; let s1 = &rhs.resource.0; @@ -366,13 +366,13 @@ pub fn s_len(data: ExSeries) -> Result { Ok(s.len()) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_drop_nulls(data: ExSeries) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.drop_nulls())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_fill_none(data: ExSeries, strategy: &str) -> Result { let strat = match strategy { "backward" => FillNullStrategy::Backward, @@ -393,41 +393,41 @@ pub fn s_fill_none(data: ExSeries, strategy: &str) -> Result Result { let s = &data.resource.0; let s = s.i64()?.fill_null_with_values(strategy)?.into_series(); Ok(ExSeries::new(s)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_fill_none_with_float(data: ExSeries, strategy: f64) -> Result { let s = &data.resource.0; let s = s.f64()?.fill_null_with_values(strategy)?.into_series(); Ok(ExSeries::new(s)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_fill_none_with_bin(data: ExSeries, strategy: &str) -> Result { let s = &data.resource.0; let s = s.utf8()?.fill_null_with_values(strategy)?.into_series(); Ok(ExSeries::new(s)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_clone(data: ExSeries) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.clone())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_shift(data: ExSeries, periods: i64) -> Result { let s = &data.resource.0; let s1 = s.shift(periods); Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_zip_with( data: ExSeries, mask: ExSeries, @@ -441,7 +441,7 @@ pub fn s_zip_with( Ok(ExSeries::new(s2)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_str_lengths(data: ExSeries) -> Result { let s = &data.resource.0; let ca = s.utf8()?; @@ -449,7 +449,7 @@ pub fn s_str_lengths(data: ExSeries) -> Result { Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_str_contains(data: ExSeries, pat: &str) -> Result { let s = &data.resource.0; let ca = s.utf8()?; @@ -457,7 +457,7 @@ pub fn s_str_contains(data: ExSeries, pat: &str) -> Result Result { let s = &data.resource.0; let ca = s.utf8()?; @@ -465,7 +465,7 @@ pub fn s_str_replace(data: ExSeries, pat: &str, val: &str) -> Result Result { let s = &data.resource.0; let ca = s.utf8()?; @@ -473,7 +473,7 @@ pub fn s_str_replace_all(data: ExSeries, pat: &str, val: &str) -> Result Result { let s = &data.resource.0; let ca = s.utf8()?; @@ -481,7 +481,7 @@ pub fn s_str_to_uppercase(data: ExSeries) -> Result { Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_str_to_lowercase(data: ExSeries) -> Result { let s = &data.resource.0; let ca = s.utf8()?; @@ -489,7 +489,7 @@ pub fn s_str_to_lowercase(data: ExSeries) -> Result { Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_str_parse_date32(data: ExSeries, fmt: Option<&str>) -> Result { let s = &data.resource.0; if let Ok(ca) = s.utf8() { @@ -502,7 +502,7 @@ pub fn s_str_parse_date32(data: ExSeries, fmt: Option<&str>) -> Result) -> Result { let s = &data.resource.0; if let Ok(ca) = s.utf8() { @@ -515,14 +515,14 @@ pub fn s_str_parse_date64(data: ExSeries, fmt: Option<&str>) -> Result Result { let s = &data.resource.0; let df = s.to_dummies()?; Ok(ExDataFrame::new(df)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_rolling_sum( data: ExSeries, window_size: usize, @@ -546,7 +546,7 @@ pub fn s_rolling_sum( Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_rolling_mean( data: ExSeries, window_size: usize, @@ -570,7 +570,7 @@ pub fn s_rolling_mean( Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_rolling_max( data: ExSeries, window_size: usize, @@ -594,7 +594,7 @@ pub fn s_rolling_max( Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_rolling_min( data: ExSeries, window_size: usize, @@ -618,13 +618,13 @@ pub fn s_rolling_min( Ok(ExSeries::new(s1)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_to_list(env: Env, data: ExSeries) -> Result { let s = ExSeriesRef(data.resource.0.clone()); Ok(s.encode(env)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_sum(env: Env, data: ExSeries) -> Result { let s = &data.resource.0; match s.dtype() { @@ -635,7 +635,7 @@ pub fn s_sum(env: Env, data: ExSeries) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_min(env: Env, data: ExSeries) -> Result { let s = &data.resource.0; match s.dtype() { @@ -649,7 +649,7 @@ pub fn s_min(env: Env, data: ExSeries) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_max(env: Env, data: ExSeries) -> Result { let s = &data.resource.0; match s.dtype() { @@ -663,7 +663,7 @@ pub fn s_max(env: Env, data: ExSeries) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_mean(env: Env, data: ExSeries) -> Result { let s = &data.resource.0; match s.dtype() { @@ -674,7 +674,7 @@ pub fn s_mean(env: Env, data: ExSeries) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_median(env: Env, data: ExSeries) -> Result { let s = &data.resource.0; match s.dtype() { @@ -684,7 +684,7 @@ pub fn s_median(env: Env, data: ExSeries) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_var(env: Env, data: ExSeries) -> Result { let s = &data.resource.0; match s.dtype() { @@ -694,7 +694,7 @@ pub fn s_var(env: Env, data: ExSeries) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_std(env: Env, data: ExSeries) -> Result { let s = &data.resource.0; match s.dtype() { @@ -725,25 +725,25 @@ fn term_from_value<'b>(v: AnyValue, env: Env<'b>) -> Term<'b> { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_cum_sum(data: ExSeries, reverse: bool) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.cumsum(reverse))) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_cum_max(data: ExSeries, reverse: bool) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.cummax(reverse))) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_cum_min(data: ExSeries, reverse: bool) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.cummin(reverse))) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_quantile<'a>( env: Env<'a>, data: ExSeries, @@ -773,31 +773,31 @@ pub fn s_quantile<'a>( } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_peak_max(data: ExSeries) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.peak_max().into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_peak_min(data: ExSeries) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.peak_min().into_series())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_reverse(data: ExSeries) -> Result { let s = &data.resource.0; Ok(ExSeries::new(s.reverse())) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_n_unique(data: ExSeries) -> Result { let s = &data.resource.0; Ok(s.n_unique()?) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_pow(data: ExSeries, exponent: f64) -> Result { let s = &data.resource.0; let s = cast(s, "float")? @@ -807,14 +807,14 @@ pub fn s_pow(data: ExSeries, exponent: f64) -> Result { Ok(ExSeries::new(s)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_int_pow(data: ExSeries, exponent: u32) -> Result { let s = &data.resource.0; let s = s.i64()?.apply(|v| v.pow(exponent)).into_series(); Ok(ExSeries::new(s)) } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_cast(data: ExSeries, to_type: &str) -> Result { let s = &data.resource.0; Ok(ExSeries::new(cast(s, to_type)?)) @@ -832,7 +832,7 @@ pub fn cast(s: &Series, to_type: &str) -> Result { } } -#[rustler::nif] +#[rustler::nif(schedule = "DirtyCpu")] pub fn s_seedable_random_indices( length: usize, n_samples: usize,