3131#include " arrow/tensor.h"
3232#include " arrow/testing/gtest_util.h"
3333#include " arrow/type.h"
34+ #include " arrow/util/float16.h"
3435
3536namespace arrow {
3637
@@ -505,8 +506,18 @@ TYPED_TEST_P(TestFloatTensor, Equals) {
505506
506507 std::vector<int64_t > shape = {4 , 4 };
507508
508- std::vector<c_data_type> c_values = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
509+ constexpr int c_vals_as_int_arr[] = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
509510 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 };
511+ std::vector<c_data_type> c_values;
512+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
513+ for (int i : c_vals_as_int_arr) {
514+ c_values.push_back (util::Float16::FromFloat (static_cast <float >(i)).bits ());
515+ }
516+ } else {
517+ for (int i : c_vals_as_int_arr) {
518+ c_values.push_back (static_cast <c_data_type>(i));
519+ }
520+ }
510521 std::vector<int64_t > c_strides = {unit_size * shape[1 ], unit_size};
511522 Tensor tc1 (TypeTraits<DataType>::type_singleton (), Buffer::Wrap (c_values), shape,
512523 c_strides);
@@ -515,8 +526,18 @@ TYPED_TEST_P(TestFloatTensor, Equals) {
515526 Tensor tc2 (TypeTraits<DataType>::type_singleton (), Buffer::Wrap (c_values_2), shape,
516527 c_strides);
517528
518- std::vector<c_data_type> f_values = {1 , 5 , 9 , 13 , 2 , 6 , 10 , 14 ,
529+ constexpr int f_vals_as_int_arr[] = {1 , 5 , 9 , 13 , 2 , 6 , 10 , 14 ,
519530 3 , 7 , 11 , 15 , 4 , 8 , 12 , 16 };
531+ std::vector<c_data_type> f_values;
532+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
533+ for (int i : f_vals_as_int_arr) {
534+ f_values.push_back (util::Float16::FromFloat (static_cast <float >(i)).bits ());
535+ }
536+ } else {
537+ for (int i : f_vals_as_int_arr) {
538+ f_values.push_back (static_cast <c_data_type>(i));
539+ }
540+ }
520541 Tensor tc3 (TypeTraits<DataType>::type_singleton (), Buffer::Wrap (f_values), shape,
521542 c_strides);
522543
@@ -531,9 +552,19 @@ TYPED_TEST_P(TestFloatTensor, Equals) {
531552 Tensor tf3 (TypeTraits<DataType>::type_singleton (), Buffer::Wrap (c_values), shape,
532553 f_strides);
533554
534- std::vector<c_data_type> nc_values = {1 , 0 , 5 , 0 , 9 , 0 , 13 , 0 , 2 , 0 , 6 ,
555+ constexpr int nc_vals_as_int_arr[] = {1 , 0 , 5 , 0 , 9 , 0 , 13 , 0 , 2 , 0 , 6 ,
535556 0 , 10 , 0 , 14 , 0 , 3 , 0 , 7 , 0 , 11 , 0 ,
536557 15 , 0 , 4 , 0 , 8 , 0 , 12 , 0 , 16 , 0 };
558+ std::vector<c_data_type> nc_values;
559+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
560+ for (int i : nc_vals_as_int_arr) {
561+ nc_values.push_back (util::Float16::FromFloat (static_cast <float >(i)).bits ());
562+ }
563+ } else {
564+ for (int i : nc_vals_as_int_arr) {
565+ nc_values.push_back (static_cast <c_data_type>(i));
566+ }
567+ }
537568 std::vector<int64_t > nc_strides = {unit_size * 2 , unit_size * 2 * shape[0 ]};
538569 Tensor tnc (TypeTraits<DataType>::type_singleton (), Buffer::Wrap (nc_values), shape,
539570 nc_strides);
@@ -569,29 +600,54 @@ TYPED_TEST_P(TestFloatTensor, Equals) {
569600 EXPECT_FALSE (tf3.Equals (tnc));
570601
571602 // signed zeros
572- c_values[0 ] = -0.0 ;
573- c_values_2[0 ] = 0.0 ;
603+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
604+ c_values[0 ] = 0x8000 ; // -0.0
605+ c_values_2[0 ] = 0x0000 ; // +0.0
606+ } else {
607+ c_values[0 ] = -0.0 ;
608+ c_values_2[0 ] = 0.0 ;
609+ }
574610 EXPECT_TRUE (tc1.Equals (tc2));
575611 EXPECT_FALSE (tc1.Equals (tc2, EqualOptions ().signed_zeros_equal (false )));
576612
577613 // tensors with NaNs
578- const c_data_type nan_value = static_cast <c_data_type>(NAN );
614+ c_data_type nan_value;
615+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
616+ nan_value = 0x7e00 ; // NaN
617+ } else {
618+ nan_value = static_cast <c_data_type>(NAN );
619+ }
620+
579621 c_values[0 ] = nan_value;
580- EXPECT_TRUE (std::isnan (tc1.Value <DataType>({0 , 0 })));
622+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
623+ EXPECT_TRUE (util::Float16::FromBits (tc1.Value <DataType>({0 , 0 })).is_nan ());
624+ } else {
625+ EXPECT_TRUE (std::isnan (tc1.Value <DataType>({0 , 0 })));
626+ }
581627 EXPECT_FALSE (tc1.Equals (tc1)); // same object
582628 EXPECT_TRUE (tc1.Equals (tc1, EqualOptions ().nans_equal (true ))); // same object
583- EXPECT_FALSE (std::isnan (tc2.Value <DataType>({0 , 0 })));
629+
630+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
631+ EXPECT_FALSE (util::Float16::FromBits (tc2.Value <DataType>({0 , 0 })).is_nan ());
632+ } else {
633+ EXPECT_FALSE (std::isnan (tc2.Value <DataType>({0 , 0 })));
634+ }
584635 EXPECT_FALSE (tc1.Equals (tc2)); // different memory
585636 EXPECT_FALSE (tc1.Equals (tc2, EqualOptions ().nans_equal (true ))); // different memory
586637
587638 c_values_2[0 ] = nan_value;
588- EXPECT_TRUE (std::isnan (tc2.Value <DataType>({0 , 0 })));
639+ if constexpr (std::is_same_v<DataType, HalfFloatType>) {
640+ EXPECT_TRUE (util::Float16::FromBits (tc2.Value <DataType>({0 , 0 })).is_nan ());
641+ } else {
642+ EXPECT_TRUE (std::isnan (tc2.Value <DataType>({0 , 0 })));
643+ }
589644 EXPECT_FALSE (tc1.Equals (tc2)); // different memory
590645 EXPECT_TRUE (tc1.Equals (tc2, EqualOptions ().nans_equal (true ))); // different memory
591646}
592647
593648REGISTER_TYPED_TEST_SUITE_P (TestFloatTensor, Equals);
594649
650+ INSTANTIATE_TYPED_TEST_SUITE_P (Float16, TestFloatTensor, HalfFloatType);
595651INSTANTIATE_TYPED_TEST_SUITE_P (Float32, TestFloatTensor, FloatType);
596652INSTANTIATE_TYPED_TEST_SUITE_P (Float64, TestFloatTensor, DoubleType);
597653
0 commit comments