This is an automated email from the ASF dual-hosted git repository.
tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/master by this push:
new 33bbaa52f feat: add comparison/sort support for Float16 (#3915)
33bbaa52f is described below
commit 33bbaa52f7f3dc421d09cb5e50682d05127d2cb1
Author: Igor Izvekov <[email protected]>
AuthorDate: Fri Mar 24 13:23:04 2023 +0300
feat: add comparison/sort support for Float16 (#3915)
* feat: add comparison/sort support for Float16
* fix: tests with the feature "dyn_cmp_dict"
---
arrow-array/src/array/primitive_array.rs | 1 +
arrow-ord/Cargo.toml | 1 +
arrow-ord/src/comparison.rs | 211 +++++++++++++++++++++++++++++++
arrow-ord/src/ord.rs | 11 ++
arrow-ord/src/sort.rs | 160 +++++++++++++++++++++++
5 files changed, 384 insertions(+)
diff --git a/arrow-array/src/array/primitive_array.rs
b/arrow-array/src/array/primitive_array.rs
index 6faecb1f0..bc62677c7 100644
--- a/arrow-array/src/array/primitive_array.rs
+++ b/arrow-array/src/array/primitive_array.rs
@@ -996,6 +996,7 @@ def_numeric_from_vec!(UInt8Type);
def_numeric_from_vec!(UInt16Type);
def_numeric_from_vec!(UInt32Type);
def_numeric_from_vec!(UInt64Type);
+def_numeric_from_vec!(Float16Type);
def_numeric_from_vec!(Float32Type);
def_numeric_from_vec!(Float64Type);
def_numeric_from_vec!(Decimal128Type);
diff --git a/arrow-ord/Cargo.toml b/arrow-ord/Cargo.toml
index bc6feb4f2..161fce960 100644
--- a/arrow-ord/Cargo.toml
+++ b/arrow-ord/Cargo.toml
@@ -44,6 +44,7 @@ arrow-data = { version = "35.0.0", path = "../arrow-data" }
arrow-schema = { version = "35.0.0", path = "../arrow-schema" }
arrow-select = { version = "35.0.0", path = "../arrow-select" }
num = { version = "0.4", default-features = false, features = ["std"] }
+half = { version = "2.1", default-features = false, features = ["num-traits"] }
[dev-dependencies]
rand = { version = "0.8", default-features = false, features = ["std",
"std_rng"] }
diff --git a/arrow-ord/src/comparison.rs b/arrow-ord/src/comparison.rs
index 0f9414378..aa2f1416d 100644
--- a/arrow-ord/src/comparison.rs
+++ b/arrow-ord/src/comparison.rs
@@ -31,6 +31,7 @@ use arrow_data::bit_mask::combine_option_bitmap;
use arrow_data::ArrayData;
use arrow_schema::{ArrowError, DataType, IntervalUnit, TimeUnit};
use arrow_select::take::take;
+use half::f16;
/// Helper function to perform boolean lambda function on values from two
array accessors, this
/// version does not attempt to use SIMD.
@@ -497,6 +498,11 @@ macro_rules! dyn_compare_scalar {
let left = as_primitive_array::<UInt64Type>($LEFT);
$OP::<UInt64Type>(left, right)
}
+ DataType::Float16 => {
+ let right = try_to_type!($RIGHT, to_f32)?;
+ let left = as_primitive_array::<Float16Type>($LEFT);
+ $OP::<Float16Type>(left, f16::from_f32(right))
+ }
DataType::Float32 => {
let right = try_to_type!($RIGHT, to_f32)?;
let left = as_primitive_array::<Float32Type>($LEFT);
@@ -1524,6 +1530,9 @@ macro_rules! typed_cmp_dict_non_dict {
(DataType::UInt64, DataType::UInt64) => {
typed_dict_non_dict_cmp!($LEFT, $RIGHT,
left_key_type.as_ref(), UInt64Type, $OP_BOOL, $OP)
}
+ (DataType::Float16, DataType::Float16) => {
+ typed_dict_non_dict_cmp!($LEFT, $RIGHT,
left_key_type.as_ref(), Float16Type, $OP_BOOL, $OP_FLOAT)
+ }
(DataType::Float32, DataType::Float32) => {
typed_dict_non_dict_cmp!($LEFT, $RIGHT,
left_key_type.as_ref(), Float32Type, $OP_BOOL, $OP_FLOAT)
}
@@ -1621,6 +1630,9 @@ macro_rules! typed_compares {
(DataType::UInt64, DataType::UInt64) => {
cmp_primitive_array::<UInt64Type, _>($LEFT, $RIGHT, $OP)
}
+ (DataType::Float16, DataType::Float16) => {
+ cmp_primitive_array::<Float16Type, _>($LEFT, $RIGHT, $OP_FLOAT)
+ }
(DataType::Float32, DataType::Float32) => {
cmp_primitive_array::<Float32Type, _>($LEFT, $RIGHT, $OP_FLOAT)
}
@@ -1772,6 +1784,9 @@ macro_rules! typed_dict_cmp {
(DataType::UInt64, DataType::UInt64) => {
cmp_dict::<$KT, UInt64Type, _>($LEFT, $RIGHT, $OP)
}
+ (DataType::Float16, DataType::Float16) => {
+ cmp_dict::<$KT, Float16Type, _>($LEFT, $RIGHT, $OP_FLOAT)
+ }
(DataType::Float32, DataType::Float32) => {
cmp_dict::<$KT, Float32Type, _>($LEFT, $RIGHT, $OP_FLOAT)
}
@@ -4988,6 +5003,30 @@ mod tests {
#[test]
fn test_eq_dyn_neq_dyn_float_nan() {
+ let array1: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(10.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let array2: Float16Array = vec![f16::NAN, f16::NAN,
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(10.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(false), Some(true), Some(true), Some(true)],
+ );
+ assert_eq!(eq_dyn(&array1, &array2).unwrap(), expected);
+
+ #[cfg(not(feature = "simd"))]
+ assert_eq!(eq(&array1, &array2).unwrap(), expected);
+
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(true), Some(false), Some(false),
Some(false)],
+ );
+ assert_eq!(neq_dyn(&array1, &array2).unwrap(), expected);
+
+ #[cfg(not(feature = "simd"))]
+ assert_eq!(neq(&array1, &array2).unwrap(), expected);
+
let array1: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 10.0]
.into_iter()
.map(Some)
@@ -5040,6 +5079,31 @@ mod tests {
#[test]
fn test_lt_dyn_lt_eq_dyn_float_nan() {
+ let array1: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(11.0), f16::NAN]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let array2: Float16Array = vec![f16::NAN, f16::NAN,
f16::from_f32(8.0), f16::from_f32(9.0), f16::from_f32(10.0), f16::from_f32(1.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(true), Some(false), Some(true),
Some(false), Some(false)],
+ );
+ assert_eq!(lt_dyn(&array1, &array2).unwrap(), expected);
+
+ #[cfg(not(feature = "simd"))]
+ assert_eq!(lt(&array1, &array2).unwrap(), expected);
+
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(true), Some(true), Some(true), Some(false),
Some(false)],
+ );
+ assert_eq!(lt_eq_dyn(&array1, &array2).unwrap(), expected);
+
+ #[cfg(not(feature = "simd"))]
+ assert_eq!(lt_eq(&array1, &array2).unwrap(), expected);
+
let array1: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 11.0,
f32::NAN]
.into_iter()
.map(Some)
@@ -5093,6 +5157,31 @@ mod tests {
#[test]
fn test_gt_dyn_gt_eq_dyn_float_nan() {
+ let array1: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(11.0), f16::NAN]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let array2: Float16Array = vec![f16::NAN, f16::NAN,
f16::from_f32(8.0), f16::from_f32(9.0), f16::from_f32(10.0), f16::from_f32(1.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(false), Some(false), Some(false),
Some(true), Some(true)],
+ );
+ assert_eq!(gt_dyn(&array1, &array2).unwrap(), expected);
+
+ #[cfg(not(feature = "simd"))]
+ assert_eq!(gt(&array1, &array2).unwrap(), expected);
+
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(false), Some(true), Some(false), Some(true),
Some(true)],
+ );
+ assert_eq!(gt_eq_dyn(&array1, &array2).unwrap(), expected);
+
+ #[cfg(not(feature = "simd"))]
+ assert_eq!(gt_eq(&array1, &array2).unwrap(), expected);
+
let array1: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 11.0,
f32::NAN]
.into_iter()
.map(Some)
@@ -5146,6 +5235,30 @@ mod tests {
#[test]
fn test_eq_dyn_scalar_neq_dyn_scalar_float_nan() {
+ let array: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(10.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+ #[cfg(feature = "simd")]
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(false), Some(false), Some(false),
Some(false)],
+ );
+ #[cfg(not(feature = "simd"))]
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(false), Some(false), Some(false),
Some(false)],
+ );
+ assert_eq!(eq_dyn_scalar(&array, f32::NAN).unwrap(), expected);
+
+ #[cfg(feature = "simd")]
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(true), Some(true), Some(true), Some(true)],
+ );
+ #[cfg(not(feature = "simd"))]
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(true), Some(true), Some(true), Some(true)],
+ );
+ assert_eq!(neq_dyn_scalar(&array, f32::NAN).unwrap(), expected);
+
let array: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 10.0]
.into_iter()
.map(Some)
@@ -5197,6 +5310,30 @@ mod tests {
#[test]
fn test_lt_dyn_scalar_lt_eq_dyn_scalar_float_nan() {
+ let array: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(10.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+ #[cfg(feature = "simd")]
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(false), Some(false), Some(false),
Some(false)],
+ );
+ #[cfg(not(feature = "simd"))]
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(true), Some(true), Some(true), Some(true)],
+ );
+ assert_eq!(lt_dyn_scalar(&array, f16::NAN).unwrap(), expected);
+
+ #[cfg(feature = "simd")]
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(false), Some(false), Some(false),
Some(false)],
+ );
+ #[cfg(not(feature = "simd"))]
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(true), Some(true), Some(true), Some(true)],
+ );
+ assert_eq!(lt_eq_dyn_scalar(&array, f16::NAN).unwrap(), expected);
+
let array: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 10.0]
.into_iter()
.map(Some)
@@ -5248,6 +5385,25 @@ mod tests {
#[test]
fn test_gt_dyn_scalar_gt_eq_dyn_scalar_float_nan() {
+ let array: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(10.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(false), Some(false), Some(false),
Some(false)],
+ );
+ assert_eq!(gt_dyn_scalar(&array, f16::NAN).unwrap(), expected);
+
+ #[cfg(feature = "simd")]
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(false), Some(false), Some(false),
Some(false)],
+ );
+ #[cfg(not(feature = "simd"))]
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(false), Some(false), Some(false),
Some(false)],
+ );
+ assert_eq!(gt_eq_dyn_scalar(&array, f16::NAN).unwrap(), expected);
+
let array: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 10.0]
.into_iter()
.map(Some)
@@ -5502,6 +5658,25 @@ mod tests {
#[test]
#[cfg(feature = "dyn_cmp_dict")]
fn test_eq_dyn_neq_dyn_dict_non_dict_float_nan() {
+ let array1: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(10.0)]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let values =
+ Float16Array::from(vec![f16::NAN, f16::from_f32(8.0),
f16::from_f32(10.0)]);
+ let keys = Int8Array::from_iter_values([0_i8, 0, 1, 1, 2]);
+ let array2 = DictionaryArray::try_new(&keys, &values).unwrap();
+
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(false), Some(true), Some(true), Some(true)],
+ );
+ assert_eq!(eq_dyn(&array1, &array2).unwrap(), expected);
+
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(true), Some(false), Some(false),
Some(false)],
+ );
+ assert_eq!(neq_dyn(&array1, &array2).unwrap(), expected);
+
let array1: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 10.0]
.into_iter()
.map(Some)
@@ -5542,6 +5717,24 @@ mod tests {
#[test]
#[cfg(feature = "dyn_cmp_dict")]
fn test_lt_dyn_lt_eq_dyn_dict_non_dict_float_nan() {
+ let array1: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(11.0), f16::NAN]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let values = Float16Array::from(vec![f16::NAN, f16::from_f32(8.0),
f16::from_f32(9.0), f16::from_f32(10.0), f16::from_f32(1.0)]);
+ let keys = Int8Array::from_iter_values([0_i8, 0, 1, 2, 3, 4]);
+ let array2 = DictionaryArray::try_new(&keys, &values).unwrap();
+
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(true), Some(false), Some(true),
Some(false), Some(false)],
+ );
+ assert_eq!(lt_dyn(&array1, &array2).unwrap(), expected);
+
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(true), Some(true), Some(true), Some(false),
Some(false)],
+ );
+ assert_eq!(lt_eq_dyn(&array1, &array2).unwrap(), expected);
+
let array1: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 11.0,
f32::NAN]
.into_iter()
.map(Some)
@@ -5582,6 +5775,24 @@ mod tests {
#[test]
#[cfg(feature = "dyn_cmp_dict")]
fn test_gt_dyn_gt_eq_dyn_dict_non_dict_float_nan() {
+ let array1: Float16Array = vec![f16::NAN, f16::from_f32(7.0),
f16::from_f32(8.0), f16::from_f32(8.0), f16::from_f32(11.0), f16::NAN]
+ .into_iter()
+ .map(Some)
+ .collect();
+ let values = Float16Array::from(vec![f16::NAN, f16::from_f32(8.0),
f16::from_f32(9.0), f16::from_f32(10.0), f16::from_f32(1.0)]);
+ let keys = Int8Array::from_iter_values([0_i8, 0, 1, 2, 3, 4]);
+ let array2 = DictionaryArray::try_new(&keys, &values).unwrap();
+
+ let expected = BooleanArray::from(
+ vec![Some(false), Some(false), Some(false), Some(false),
Some(true), Some(true)],
+ );
+ assert_eq!(gt_dyn(&array1, &array2).unwrap(), expected);
+
+ let expected = BooleanArray::from(
+ vec![Some(true), Some(false), Some(true), Some(false), Some(true),
Some(true)],
+ );
+ assert_eq!(gt_eq_dyn(&array1, &array2).unwrap(), expected);
+
let array1: Float32Array = vec![f32::NAN, 7.0, 8.0, 8.0, 11.0,
f32::NAN]
.into_iter()
.map(Some)
diff --git a/arrow-ord/src/ord.rs b/arrow-ord/src/ord.rs
index dc352c5b7..66058907f 100644
--- a/arrow-ord/src/ord.rs
+++ b/arrow-ord/src/ord.rs
@@ -173,6 +173,7 @@ pub fn build_compare(
(Int16, Int16) => compare_primitives::<Int16Type>(left, right),
(Int32, Int32) => compare_primitives::<Int32Type>(left, right),
(Int64, Int64) => compare_primitives::<Int64Type>(left, right),
+ (Float16, Float16) => compare_primitives::<Float16Type>(left, right),
(Float32, Float32) => compare_primitives::<Float32Type>(left, right),
(Float64, Float64) => compare_primitives::<Float64Type>(left, right),
(Decimal128(_, _), Decimal128(_, _)) => {
@@ -286,6 +287,7 @@ pub mod tests {
use super::*;
use arrow_array::{FixedSizeBinaryArray, Float64Array, Int32Array};
use arrow_buffer::i256;
+ use half::f16;
use std::cmp::Ordering;
#[test]
@@ -329,6 +331,15 @@ pub mod tests {
assert_eq!(Ordering::Less, (cmp)(0, 0));
}
+ #[test]
+ fn test_f16() {
+ let array = Float16Array::from(vec![f16::from_f32(1.0),
f16::from_f32(2.0)]);
+
+ let cmp = build_compare(&array, &array).unwrap();
+
+ assert_eq!(Ordering::Less, (cmp)(0, 1));
+ }
+
#[test]
fn test_f64() {
let array = Float64Array::from(vec![1.0, 2.0]);
diff --git a/arrow-ord/src/sort.rs b/arrow-ord/src/sort.rs
index c6fedb960..9b17651f9 100644
--- a/arrow-ord/src/sort.rs
+++ b/arrow-ord/src/sort.rs
@@ -183,6 +183,14 @@ pub fn sort_to_indices(
DataType::UInt64 => {
sort_primitive::<UInt64Type, _>(values, v, n, cmp, &options, limit)
}
+ DataType::Float16 => sort_primitive::<Float16Type, _>(
+ values,
+ v,
+ n,
+ |x, y| x.total_cmp(&y),
+ &options,
+ limit,
+ ),
DataType::Float32 => sort_primitive::<Float32Type, _>(
values,
v,
@@ -283,6 +291,9 @@ pub fn sort_to_indices(
DataType::UInt64 => {
sort_list::<i32, UInt64Type>(values, v, n, &options, limit)
}
+ DataType::Float16 => {
+ sort_list::<i32, Float16Type>(values, v, n, &options, limit)
+ }
DataType::Float32 => {
sort_list::<i32, Float32Type>(values, v, n, &options, limit)
}
@@ -310,6 +321,9 @@ pub fn sort_to_indices(
DataType::UInt64 => {
sort_list::<i64, UInt64Type>(values, v, n, &options, limit)
}
+ DataType::Float16 => {
+ sort_list::<i64, Float16Type>(values, v, n, &options, limit)
+ }
DataType::Float32 => {
sort_list::<i64, Float32Type>(values, v, n, &options, limit)
}
@@ -1266,6 +1280,7 @@ mod tests {
use super::*;
use arrow_array::builder::PrimitiveRunBuilder;
use arrow_buffer::i256;
+ use half::f16;
use rand::rngs::StdRng;
use rand::{Rng, RngCore, SeedableRng};
use std::convert::TryFrom;
@@ -1702,6 +1717,19 @@ mod tests {
None,
vec![0, 5, 3, 1, 4, 2],
);
+ test_sort_to_indices_primitive_arrays::<Float16Type>(
+ vec![
+ None,
+ Some(f16::from_f32(-0.05)),
+ Some(f16::from_f32(2.225)),
+ Some(f16::from_f32(-1.01)),
+ Some(f16::from_f32(-0.05)),
+ None,
+ ],
+ None,
+ None,
+ vec![0, 5, 3, 1, 4, 2],
+ );
test_sort_to_indices_primitive_arrays::<Float32Type>(
vec![
None,
@@ -1770,6 +1798,23 @@ mod tests {
vec![2, 1, 4, 3, 5, 0],
);
+ test_sort_to_indices_primitive_arrays::<Float16Type>(
+ vec![
+ None,
+ Some(f16::from_f32(0.005)),
+ Some(f16::from_f32(20.22)),
+ Some(f16::from_f32(-10.3)),
+ Some(f16::from_f32(0.005)),
+ None,
+ ],
+ Some(SortOptions {
+ descending: true,
+ nulls_first: false,
+ }),
+ None,
+ vec![2, 1, 4, 3, 5, 0],
+ );
+
test_sort_to_indices_primitive_arrays::<Float32Type>(
vec![
None,
@@ -1838,6 +1883,23 @@ mod tests {
vec![5, 0, 2, 1, 4, 3],
);
+ test_sort_to_indices_primitive_arrays::<Float16Type>(
+ vec![
+ None,
+ Some(f16::from_f32(0.1)),
+ Some(f16::from_f32(0.2)),
+ Some(f16::from_f32(-1.3)),
+ Some(f16::from_f32(0.01)),
+ None,
+ ],
+ Some(SortOptions {
+ descending: true,
+ nulls_first: true,
+ }),
+ None,
+ vec![5, 0, 2, 1, 4, 3],
+ );
+
test_sort_to_indices_primitive_arrays::<Float32Type>(
vec![None, Some(0.1), Some(0.2), Some(-1.3), Some(0.01), None],
Some(SortOptions {
@@ -2650,6 +2712,30 @@ mod tests {
vec![None, None, Some(2)],
);
+ test_sort_primitive_arrays::<Float16Type>(
+ vec![
+ None,
+ Some(f16::from_f32(0.0)),
+ Some(f16::from_f32(2.0)),
+ Some(f16::from_f32(-1.0)),
+ Some(f16::from_f32(0.0)),
+ None,
+ ],
+ Some(SortOptions {
+ descending: true,
+ nulls_first: true,
+ }),
+ None,
+ vec![
+ None,
+ None,
+ Some(f16::from_f32(2.0)),
+ Some(f16::from_f32(0.0)),
+ Some(f16::from_f32(0.0)),
+ Some(f16::from_f32(-1.0)),
+ ],
+ );
+
test_sort_primitive_arrays::<Float32Type>(
vec![None, Some(0.0), Some(2.0), Some(-1.0), Some(0.0), None],
Some(SortOptions {
@@ -2715,6 +2801,29 @@ mod tests {
None,
vec![None, None, Some(-1), Some(0), Some(0), Some(2)],
);
+ test_sort_primitive_arrays::<Float16Type>(
+ vec![
+ None,
+ Some(f16::from_f32(0.0)),
+ Some(f16::from_f32(2.0)),
+ Some(f16::from_f32(-1.0)),
+ Some(f16::from_f32(0.0)),
+ None,
+ ],
+ Some(SortOptions {
+ descending: false,
+ nulls_first: true,
+ }),
+ None,
+ vec![
+ None,
+ None,
+ Some(f16::from_f32(-1.0)),
+ Some(f16::from_f32(0.0)),
+ Some(f16::from_f32(0.0)),
+ Some(f16::from_f32(2.0)),
+ ],
+ );
test_sort_primitive_arrays::<Float32Type>(
vec![None, Some(0.0), Some(2.0), Some(-1.0), Some(0.0), None],
Some(SortOptions {
@@ -3391,6 +3500,57 @@ mod tests {
Some(1),
);
+ test_sort_list_arrays::<Float16Type>(
+ vec![
+ Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(0.0))]),
+ Some(vec![
+ Some(f16::from_f32(4.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(2.0)),
+ Some(f16::from_f32(1.0)),
+ ]),
+ Some(vec![
+ Some(f16::from_f32(2.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(4.0)),
+ ]),
+ Some(vec![
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(3.0)),
+ ]),
+ Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(1.0))]),
+ ],
+ Some(SortOptions {
+ descending: false,
+ nulls_first: false,
+ }),
+ None,
+ vec![
+ Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(0.0))]),
+ Some(vec![Some(f16::from_f32(1.0)), Some(f16::from_f32(1.0))]),
+ Some(vec![
+ Some(f16::from_f32(2.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(4.0)),
+ ]),
+ Some(vec![
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(3.0)),
+ ]),
+ Some(vec![
+ Some(f16::from_f32(4.0)),
+ Some(f16::from_f32(3.0)),
+ Some(f16::from_f32(2.0)),
+ Some(f16::from_f32(1.0)),
+ ]),
+ ],
+ None,
+ );
+
test_sort_list_arrays::<Float32Type>(
vec![
Some(vec![Some(1.0), Some(0.0)]),