This is an automated email from the ASF dual-hosted git repository.
paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git
The following commit(s) were added to refs/heads/main by this push:
new 7b31916c feat: Add float16 support for
`ArrowArrayViewGet{Double,Int,UInt}Unsafe()` (#501)
7b31916c is described below
commit 7b31916c493ae9abc57613e5de11d55de333d7fe
Author: Cocoa <[email protected]>
AuthorDate: Fri May 31 20:45:01 2024 +0100
feat: Add float16 support for `ArrowArrayViewGet{Double,Int,UInt}Unsafe()`
(#501)
Hi this PR adds float16 support for
`ArrowArrayViewGet{Double,Int,UInt}Unsafe()`. Related issue: #500
---------
Co-authored-by: Dewey Dunnington <[email protected]>
---
src/nanoarrow/array_inline.h | 6 ++++
src/nanoarrow/array_test.cc | 66 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/src/nanoarrow/array_inline.h b/src/nanoarrow/array_inline.h
index 2f606edf..7ee3d943 100644
--- a/src/nanoarrow/array_inline.h
+++ b/src/nanoarrow/array_inline.h
@@ -810,6 +810,8 @@ static inline int64_t ArrowArrayViewGetIntUnsafe(const
struct ArrowArrayView* ar
return (int64_t)data_view->data.as_double[i];
case NANOARROW_TYPE_FLOAT:
return (int64_t)data_view->data.as_float[i];
+ case NANOARROW_TYPE_HALF_FLOAT:
+ return (int64_t)ArrowHalfFloatToFloat(data_view->data.as_uint16[i]);
case NANOARROW_TYPE_BOOL:
return ArrowBitGet(data_view->data.as_uint8, i);
default:
@@ -843,6 +845,8 @@ static inline uint64_t ArrowArrayViewGetUIntUnsafe(
return (uint64_t)data_view->data.as_double[i];
case NANOARROW_TYPE_FLOAT:
return (uint64_t)data_view->data.as_float[i];
+ case NANOARROW_TYPE_HALF_FLOAT:
+ return (uint64_t)ArrowHalfFloatToFloat(data_view->data.as_uint16[i]);
case NANOARROW_TYPE_BOOL:
return ArrowBitGet(data_view->data.as_uint8, i);
default:
@@ -875,6 +879,8 @@ static inline double ArrowArrayViewGetDoubleUnsafe(
return data_view->data.as_double[i];
case NANOARROW_TYPE_FLOAT:
return data_view->data.as_float[i];
+ case NANOARROW_TYPE_HALF_FLOAT:
+ return ArrowHalfFloatToFloat(data_view->data.as_uint16[i]);
case NANOARROW_TYPE_BOOL:
return ArrowBitGet(data_view->data.as_uint8, i);
default:
diff --git a/src/nanoarrow/array_test.cc b/src/nanoarrow/array_test.cc
index d0fc510e..35531495 100644
--- a/src/nanoarrow/array_test.cc
+++ b/src/nanoarrow/array_test.cc
@@ -2506,6 +2506,72 @@ TEST(ArrayViewTest, ArrayViewTestGetNumeric) {
TestGetFromNumericArrayView<FloatType>();
}
+TEST(ArrayViewTest, ArrayViewTestGetFloat16) {
+ struct ArrowArray array;
+ struct ArrowSchema schema;
+ struct ArrowArrayView array_view;
+ struct ArrowError error;
+
+ ASSERT_EQ(ArrowArrayInitFromType(&array, NANOARROW_TYPE_HALF_FLOAT),
NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayStartAppending(&array), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayAppendInt(&array, 1), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayAppendNull(&array, 2), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayAppendDouble(&array, 4), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayFinishBuildingDefault(&array, nullptr), NANOARROW_OK);
+
+ ASSERT_EQ(ArrowSchemaInitFromType(&schema, NANOARROW_TYPE_HALF_FLOAT),
NANOARROW_OK);
+ ASSERT_EQ(ArrowArrayViewInitFromSchema(&array_view, &schema, &error),
NANOARROW_OK);
+ ASSERT_EQ(ArrowArrayViewSetArray(&array_view, &array, &error), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayViewValidate(&array_view,
NANOARROW_VALIDATION_LEVEL_FULL, &error),
+ NANOARROW_OK);
+
+ EXPECT_EQ(ArrowArrayViewIsNull(&array_view, 2), 1);
+ EXPECT_EQ(ArrowArrayViewIsNull(&array_view, 3), 0);
+
+ EXPECT_EQ(ArrowArrayViewGetIntUnsafe(&array_view, 3), 4);
+ EXPECT_EQ(ArrowArrayViewGetUIntUnsafe(&array_view, 3), 4);
+ EXPECT_EQ(ArrowArrayViewGetDoubleUnsafe(&array_view, 3), 4.0);
+
+ auto string_view = ArrowArrayViewGetStringUnsafe(&array_view, 0);
+ EXPECT_EQ(string_view.data, nullptr);
+ EXPECT_EQ(string_view.size_bytes, 0);
+ auto buffer_view = ArrowArrayViewGetBytesUnsafe(&array_view, 0);
+ EXPECT_EQ(buffer_view.data.data, nullptr);
+ EXPECT_EQ(buffer_view.size_bytes, 0);
+
+ ArrowArrayViewReset(&array_view);
+ ArrowArrayRelease(&array);
+ ArrowSchemaRelease(&schema);
+
+ // Array without nulls (Arrow does not allocate the validity buffer)
+ ASSERT_EQ(ArrowArrayInitFromType(&array, NANOARROW_TYPE_HALF_FLOAT),
NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayStartAppending(&array), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayAppendInt(&array, 1), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayAppendDouble(&array, 2), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayFinishBuildingDefault(&array, nullptr), NANOARROW_OK);
+
+ ASSERT_EQ(ArrowSchemaInitFromType(&schema, NANOARROW_TYPE_HALF_FLOAT),
NANOARROW_OK);
+ schema.flags &= ~ARROW_FLAG_NULLABLE;
+ ASSERT_EQ(ArrowArrayViewInitFromSchema(&array_view, &schema, &error),
NANOARROW_OK);
+ ASSERT_EQ(ArrowArrayViewSetArray(&array_view, &array, &error), NANOARROW_OK);
+ EXPECT_EQ(ArrowArrayViewValidate(&array_view,
NANOARROW_VALIDATION_LEVEL_FULL, &error),
+ NANOARROW_OK);
+
+ // We're trying to test behavior with no validity buffer, so make sure
that's true
+ ASSERT_EQ(array_view.buffer_views[0].data.data, nullptr);
+
+ EXPECT_EQ(ArrowArrayViewIsNull(&array_view, 0), 0);
+ EXPECT_EQ(ArrowArrayViewIsNull(&array_view, 1), 0);
+
+ EXPECT_EQ(ArrowArrayViewGetIntUnsafe(&array_view, 0), 1);
+ EXPECT_EQ(ArrowArrayViewGetUIntUnsafe(&array_view, 1), 2);
+ EXPECT_EQ(ArrowArrayViewGetDoubleUnsafe(&array_view, 1), 2);
+
+ ArrowArrayViewReset(&array_view);
+ ArrowArrayRelease(&array);
+ ArrowSchemaRelease(&schema);
+}
+
template <typename BuilderClass>
void TestGetFromBinary(BuilderClass& builder) {
struct ArrowArray array;