Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion r/src/array_to_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <arrow/table.h>
#include <arrow/util/bitmap_reader.h>
#include <arrow/util/bitmap_writer.h>
#include <arrow/util/float16.h>
#include <arrow/util/int_util.h>

#include <type_traits>
Expand Down Expand Up @@ -224,7 +225,11 @@ class Converter_Double : public Converter {
}
auto p_data = REAL(data) + start;
auto ingest_one = [&](R_xlen_t i) {
p_data[i] = static_cast<value_type>(p_values[i]);
if constexpr (std::is_same_v<Type, HalfFloatType>) {
p_data[i] = arrow::util::Float16::FromBits(p_values[i]).ToDouble();
} else {
p_data[i] = static_cast<value_type>(p_values[i]);
}
return Status::OK();
};
auto null_one = [&](R_xlen_t i) {
Expand Down
5 changes: 3 additions & 2 deletions r/src/r_to_arrow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <arrow/util/bitmap_writer.h>
#include <arrow/util/checked_cast.h>
#include <arrow/util/converter.h>
#include <arrow/util/float16.h>
#include <arrow/util/logging.h>

#include "./r_task_group.h"
Expand Down Expand Up @@ -390,12 +391,12 @@ struct RConvert {
return static_cast<float>(from);
}

// ---- convert to half float: not implemented
// ---- convert to half float
template <typename Type, typename From>
static enable_if_t<std::is_same<Type, const HalfFloatType>::value,
Result<typename Type::c_type>>
Convert(Type*, From from) {
return Status::Invalid("Cannot convert to Half Float");
Comment thread
thisisnic marked this conversation as resolved.
return arrow::util::Float16(static_cast<double>(from)).bits();
}
};

Expand Down
14 changes: 13 additions & 1 deletion r/tests/testthat/test-chunked-array.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

int_types <- c(int8(), int16(), int32(), int64())
uint_types <- c(uint8(), uint16(), uint32(), uint64())
float_types <- c(float32(), float64()) # float16() not really supported in C++ yet
float_types <- c(float16(), float32(), float64())
all_numeric_types <- c(int_types, uint_types, float_types)

expect_chunked_roundtrip <- function(x, type) {
Expand Down Expand Up @@ -549,3 +549,15 @@ test_that("as_chunked_array() works for Array", {
chunked_array(Array$create(1:6, type = float64()))
)
})

test_that("float16 values roundtrip to R correctly", {
# Values exactly representable in half-float, so the roundtrip is exact.
# Regression test for GH-50378 (values were previously decoded as raw uint16 bits)
x <- c(1, 2, 3.5, NA, -0.25, 1024, Inf)
a <- chunked_array(x[1:4], x[5:7], type = float16())
expect_type_equal(a$type, float16())
expect_identical(a$num_chunks, 2L)
expect_as_vector(a, x)
expect_as_vector(a$chunk(1), x[5:7])
expect_as_vector(a$Slice(1), x[-1])
})
13 changes: 12 additions & 1 deletion r/tests/testthat/test-dplyr-funcs-type.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test_that("explicit type conversions with cast()", {

int_types <- c(int8(), int16(), int32(), int64())
uint_types <- c(uint8(), uint16(), uint32(), uint64())
float_types <- c(float32(), float64())
float_types <- c(float16(), float32(), float64())

Comment thread
thisisnic marked this conversation as resolved.
types <- c(
int_types,
Expand Down Expand Up @@ -1064,3 +1064,14 @@ test_that("format() for unsupported types returns the input as string", {
collect()
)
})

test_that("cast to float16 roundtrips values correctly", {
# Values exactly representable in half-float, so the roundtrip is exact.
# Regression test for GH-50378 (values were previously decoded as raw uint16 bits)
df <- tibble::tibble(x = c(1, 2, 3.5, -0.25, 1024, NA))
result <- df |>
arrow_table() |>
mutate(x = cast(x, float16())) |>
collect()
expect_identical(result$x, df$x)
})
Loading