Release 2.2.1.
Release 2.2.1.
Fixed error in int-to-half conversion when converting minium negative value.
Yes, there is indeed a bug in the integer to half conversion when calling it with the type's minimum negative value, since on two's complement platforms (which is virtually everywhere) that doesn't have a positive equivalent inside the type's own domain. I will look into fixing it. Thank you for bringing this up.
Hi, Thank you for making this library, it really helps a lot in my work. But recently, I have found that when I use half_cast() to convert the minimum value of short type (-32768) to half, I get -1, but it should be -32768. This problem also occurs when converting the minimum value of int type. I'm not sure, but it may be related to the overflow in half. hpp: 1082 line, or did I miss something? The following code can reproduce this issue. short x = std::numeric_limits<short>::min(); std::cout <<...
The issue occurs in miopen, where std::isfinite is applied in templated code for double/float/half_float and half8 (miopen defines namespace std { bool isfinite(half8 x){...} } for their half8 type). Regarding the issue with libc++, a quick discussion occurred in https://github.com/llvm/llvm-project/pull/98841, the issue was fixed and now std::isfinite(half_float_variable) will work, but it will implicitly cast to float (or to double, or to long double, or fail with ambiguous call) in the same way...
Hello, Thank you for reporting this issue. However, I don't think your solution would be appropriate for the project (at least from my side, it could be a fine thing to do for ROCm). Rather than adding a specialization into the std namespace, what should actually happen is to call the actual half function from the half_float namespace in the first place wherever it's needed. ADL should actually take care of that, but if the standard library specializations mess that up, I guess one has to actually...
Hi, I noticed a few problems affecting ROCm/half and upstream (v2.2 incl. trunk), so I'll report in both places. Both are related to std::isfinite. First problem is that it does not work with libc++. Here is a breakdown why: 1) Since C++11 std::isfinite is defined for integral types (having specific traits) 2) Used trait is std::is_arithmetic, it uses std::is_floating_point. Both traits have no specialization for half_float::half 3) What happens in gcc/libstdc++/msvc is that std::isfinite(half_value)...
Updated documentation.
Added explicit qualifications to internal exception functions to avoid namespace conflicts.
Reduced type conversion warnings when internal computations use 64 integers.
So it seems that this happens due to built-in C++ conversion rules for ternary operator assignments or otherwise. Usage of the const int expression 0 causes the compiler to down-convert the half argument to float, and then float to int in order to perform the comparison. Afterwards converting the int result back to float and assigning it to the result via using half& operator=(float rhs) I've found that disabling all the operators in the library which specify (float rhs) as their signature helps...
So it seems that this happens due to built-in C++ conversion rules for ternary operator assignments or otherwise. Usage of the const int expression 0 causes the compiler to down-convert the half argument to float, and then float to int in order to perform the comparison. Afterwards converting the int result back to float and assigning it to the result via using half& operator=(float rhs) I've found that disabling all the operators in the library which specify (float rhs) as their signature helps...
So it seems that this happens due to built-in C++ conversion rules for ternary operator assignments or otherwise. Usage of the const int expression 0 causes the compiler to down-convert the half argument to float, and then float to int in order to perform the comparison. Afterwards converting the int result back to float and assigning it to the result via using half& operator=(float rhs) I've found that disabling all the operators in the library which specify (float rhs) as their signature helps...
So it seems that this happens due to built-in C++ conversion rules for ternary operator assignments or otherwise. Usage of the const int expression 0 causes the compiler to down-convert the half argument to float, and then float to int in order to perform the comparison. Afterwards converting the int result back to float and assigning it to the result via using half& operator=(float rhs) I've found that disabling all the operators in the library which specify (float rhs) as their signature helps...
So it seems that this happens due to built-in C++ conversion rules for ternary operator assignments or otherwise. Usage of the const int expression 0 causes the compiler to down-convert the half argument to float, and then float to int in order to perform the comparison. Afterwards converting the int result back to float and assigning it to the result via using half& operator=(float rhs) I've found that disabling all the operators in the library which specify (float rhs) as their signature helps...
So it seems that this happens due to built-in C++ conversion rules for ternary operator assignments or otherwise. Usage of the const int expression 0 causes the compiler to down-convert the half argument to float, and then float to int in order to perform the comparison. Afterwards converting the int result back to float and assigning it to the result via using half& operator=(float rhs) I've found that disabling all the operators in library which specify (float rhs) as their signature helps catch...
Hi Christian, thanks for your reply. I've done some further testing regarding this issue and found some strange and interesting results. This is probably beyond the scope of this forum since it is probably related to C++ behavior in general, rather than the half precision library specifically. Nevertheless, I'd like to share my findings here. #define MAX(a,b) (((a)>(b)) ? (a) : (b)) Example 1: half myvalue = half(49.625f); half result = MAX(0, myvalue); std::cout << std::hex << "0x" << myvalue.data_...
It is true, that the only assignment operator for builtin types is the float version and will perform an implicit conversion to float, as described in the documentation (which also lists some ways to work around any problems with this). However, assignment between halfs works directly by copying the internal bit representation, like you described. There is no explicit assignment operator for half in the class definition because it is default generated by the compiler anyway (same with the copy constructor)....
Hi, I've noticed that the only assignment operator implemented in the library looks like this: half& operator= ( float rhs ) And internally it performs conversion to/from float if the original argument is a half-precision value. This sometimes causes somewhat unexpected behavior. Consider the following example: half_float::half value_a = SomeCalculationResult(); //let's say the result is 49.625 or 0x5234 half_float::half value_b = value_a; //the value stored in value_b is now 49.0, or 0x5220 I suppose...
Hello, I don't really want to hide all the necessary headers behind configuration macros, though. There already are quite a few macros and some things can just be assumed as given. I might consider making the streaming operators optional (as "iostream" can indeed be quite a monster) and I will also try to look into what "algorithm" is even used for. But things like "utility" and "cmath" are just necessary. I'm not going to implement my own swap function in in 2023. ;-)
Hi, I've been using half for my personal project and overall I can say I'm quite happy with it. The only issue I have is that my compile times are affected quite a bit by some of the includes the library pulls in. I've already set HALF_ENABLE_CPP11_HASH=0 and HALF_ENABLE_CPP11_TYPE_TRAITS=0 as the existing options, but a few includes still remain. The heaviest hitters are "algorithm", which I comment out and still compiles, "iostream", which I comment out as well as the stream operators, and "utility",...
Hi, I've been using half for my personal project and overall I can say I'm quite happy with it. The only issue I have is that my compile times are affected quite a bit by some of the includes the library pulls in. I've already set HALF_ENABLE_CPP11_HASH=0 and HALF_ENABLE_CPP11_TYPE_TRAITS=0 as the existing options, but a few includes still remain. The heaviest hitters are <algorithm>, which I comment out and still compiles, <iostream>, which I comment out as well as the stream operators, and <utility>,...
Fixed language in documentation.
Hello, Sorry, yes, I had actually changed it locally already after your first message. I just haven't put up a new release since then, so the changes haven't found their way into the public. I wasn't really planning to make an entirely new release for that, but I'll see if I can update the website at least or find other things that warrant a new version. Regards, Christian Rau Am Do., 10. März 2022 um 12:04 Uhr schrieb Teresa teresachr@users.sourceforge.net: Hello @rauy, I hope you are well. Sorry...
Hello @rauy, I hope you are well. Sorry to bother you. I was wondering if you think you can still change the README.txt. Kindest Regards Thanks a million!
Thank you very much :)
Hello, Yes, I think I can change that. Regards, Christian Rau Am Mo., 13. Dez. 2021 um 16:25 Uhr schrieb Teresa teresachr@users.sourceforge.net: Hello @rauy, we are reviewing our documentation at arm. We have your half implementation as part of our third party libraries in Arm NN. We were wondering, if perhaps, the next time you publish a new version, you could consider changing the sentence: "the user knows what he is doing" for "the user knows what they are doing". I am attaching a README.txt with...
Hello @rauy, we are reviewing our documentation at arm. We have your half implementation as part of our third party libraries in Arm NN. We were wondering, if perhaps, the next time you publish a new version, you could consider changing the sentence: "the user knows what he is doing" for "the user knows what they are doing". I am attaching a README.txt with the change, and some other little changes, in case it helps. Thank you very much! Kindest Regards
Hi, Thank you for your reply. Turns out using clang-12 on linux with -fno-exceptions produce similar error. AFAIK Android NDK is using clang for their compiler. on my machine clang --version says: Ubuntu clang version 12.0.0-3ubuntu1~20.04.3 Thank you for your time. Best Regards,
Hello, That wouldn't be the HALF_ERRHANDLING_FLAGS macro, rather than the HALF_ERRHANDLING_THROW_... macros, as explained in the documentation on http://half.sourceforge.net/. However, all the automatic error handling features already are disabled by default, so this won't help you. Your problem likely is the function fethrowexcept, which also works without automatic error handling and contains throw statements. Unfortunately it seems there really is no other way around it than for you to manually...
Hi, Sorry to bother you again. This time it's Android Studio. Compiling using Android Studio with ndk 22.1.7171670 or 23.1.7779620 will throw error: half.hpp:4576:4: error: cannot use 'throw' with exceptions disabled Setting the flag -DHALF_ERRHANDLING_FLAGS=0 doesn't help. Did I miss anything? Thank you for your time! Best Regards,
Hi, Defining HALF_ENABLE_CPP11_CFENV=0 fix the issue. Thank you so much and keep up the good work! Cheers!
Hello, In this case it seems you need to manually undefine support for the <cfenv> header. This is normally enabled automatically based on the compiler/library version used. But if you say your environment is explicitly unsupporting the standard there, then you can manually deactivate support for these macros by defining the HALF_ENABLE_CPP11_CFENF macro to 0 (either via compiler/preprocessor options or in code before including half.hpp), as described in the documentation on half.sourceforge.net....
Hi, Thank you for this awesome library. It works on desktop but unfortunately emscripten can't compile it. Macros such as FE_INEXACT and FE_INVALID are not defined. According to emscripten release 1.39.15: 05/06/2020: Stop defining FE_INEXACT and other floating point exception macros in libc, since we don't support them. That also prevents musl from including code using pragmas that don't make sense for wasm. Ifdef out other uses of those pragmas as well, as tip of tree LLVM now fails to compile...
Release 2.2.0.
Release 2.2.0.
I didn't see a way to create a ticket, but I encountered a compilation error on one system that defines a function int raise(int) in signal.h: ../deps/half/include/half.hpp:1342:21: error: call of overloaded 'raise(<unnamed enum="">)' is ambiguous raise(FE_INEXACT); ^ ../deps/half/include/half.hpp:625:15: note: candidate: void half_float::detail::raise(int, bool) inline void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond) = true)</unnamed> ...sysroot/usr/include/signal.h:138:12:...
Removed exception handling branch.
Fixed missing include for F16C intrinsics.
Hi, I have warning C4244: 'argument': conversion from 'double' to 'float', possible loss of data ~~~ double a = 1.0; half b = 2.0_h; b = (half)a; ~~~ internally half.hpp not using double->half conversation code for some reason. I wrote here because it is not allowed to create ticket.
Hello, Yes, this is a shortcoming of half not offering conversion constructors for every possible builtin type, but only for float. So when converting a double to a half, it always takes the route over the implicit conversion to float first. This is somewhat intentional, but can cause some unwanted warnings. The only way around that is either using the explicit 'half_cast' or explicitly converting the double to float beforehand. But I'm reconsidering the layout of conversion constructors and assignment...
Hi, I have warning C4244: 'argument': conversion from 'double' to 'float', possible loss of data ~~~ double a = 1.0; half b = 2.0_h; b = (half)a; ~~~ internally half.hpp not using double->half conversation code for some reason. I wrote here because it is allowed to create ticket.
The implicit conversion thing I addressed in the other thread and is kind of a problem. Specializations for std::complex shouldn't be necessary since the standard implementation should work as well. If it doesn't, the root problems for that might rather need to be adressed. However, since specializing standard library templates usually isn't a big deal, I might look into that. As to the mathematical functions, this is somewhat of a problem since the standard library functions aren't templates rather...
That seems to get messy quickly. I will consider broadening type conversions to more types in general in the future, to adress some of the above problems with double initializations maybe, but specifically allowing uint8_t conversion sounds like a bit of an inconsistent mess just to support 0 and 1. I know it's unfortunate when template code just uses these all over the place, it's why I usually use T(1) and T() in such completely type-agnostic code. That's ugly too, but such is the case if you want...
How about adding integer to half conversion? Even though this is actually an error-prone conversion, int-to-float conversion is still done implicitly as part of c++ standard. I'm just trying to make this work better for code templates that may be used with or without half library present. Alternatively, if want to avoid all implicit narrowing conversions, could we at least support implicit uint8_t or int8_t to half conversion? This is a lossless conversion and when I tried that it also didn't work....
How about adding integer to half conversion? Even though this is actually an error-prone conversion, int-to-float conversion is still done implicitly as part of c++ standard. I'm just trying to make this work better for code templates that may be used with or without half library present. Alternatively, if want to avoid all implicit narrowing conversions, could we at least support implicit uint8_t or int8_t to float conversion? This is a lossless conversion and when I tried that it also didn't work....
The problem is that code that implicitly casts from double to float is already problematic and narrowing conversions should be taken care of in templated code like that. So either you are already operating with mixed types even when using builtin types, in which case you might want to care for proper type-safety and narrowing conversions there, too. Or you only work within a single type, which should as well work when switching that type to half. I really don't intend to add implicit conversions...
This relates somewhat to the other discussion topic (https://sourceforge.net/p/half/discussion/general/thread/36919c68c5/#a326). I am running into many issues when trying to convert code that worked before with all the built-in float types to start using the half float type, having to add in explicit conversions all over. In some cases, I have to add custom code when templating to check if type is half so that it will operate in a different way than with the other types, especially when using std::complex<half>....
I think you should consider adding implicit casting from float to half rather than explicit. Even though this is a narrowing conversion, it would be really helpful if the half type behaved the same as built-in float types. Otherwise, I am running into many issues when trying to convert code that worked before with all the built-in float types to start using the half float type, having to add in explicit conversions all over. In some cases, I have to add custom code when templating to check if type...
The problem is I'd have to provide constructors like these for every type then and I'd like to avoid that. But I'm thinking about it, maybe I'll reconsider that. Am Sa., 18. Jan. 2020 um 15:40 Uhr schrieb "Emilio Mª López Riñón" redorav@users.sourceforge.net: Would a simple explicit constructor taking a double not work in this case? No viable conversion from 'double' to 'half' Sent from sourceforge.net because you indicated interest in < https://sourceforge.net/p/half/discussion/general/> To unsubscribe...
Would a simple explicit constructor and assignment operator taking a double not work in this case?
Would a simple explicit constructor taking a double not work in this case?
Hello, Yes, you're right. Explicit construction ('half a(3.4);') works and assignment ('half a; a = 3.4;') works too. But when using initialization with assignment operator ('half a = 3.4;') is should actually first use the 'float' constructor and then the copy constructor, but it seems it can't use the 'float' constructor as long as that is 'explicit'. This surprises me and I have to look if that has changed somehow since C++11 or if that has always been the case. Unfortunately, the 'float' constructor...
Hi Chirstian, Thank you for your reply and suggestion. Sorry to say but it is not working for me. Following is the test code: #include <iostream> #include "half.hpp" using half_float::half; int main() { half b(5); // half a = half(0.0); // works well // half a = 0.0; // not working (expected to work like double) half a = 3.4; // not wokring // half a (3.4); // works well half c = a * b; c += 3.5; if(c > a) std::cout << c << std::endl; } I am using Apache NetBeans 11.1 on macOS and GNU compiler, C++11....
Hi Chirstian, Thank you for your reply and suggestion. Sorry to say but it is not working for me. Following is the test code: #include <iostream> #include "half.hpp" using half_float::half; int main() { half b(5); // half a = half(0.0); // works well // half a = 0.0; // not working (espected to work like double) half a = 3.4; // not wokring // half a (3.4); // works well half c = a * b; c += 3.5; if(c > a) std::cout << c << std::endl; } I am using Apache NetBeans 11.1 on macOS and GNU compiler, C++11....
Hello, This should actually work and I don't quite understand why it doesn't. The half type has implicit constructors and assignment operators taking float arguments. These constructors are implicit and the compiler should thus allow the expression using an implicit conversion from 3.4 to 3.4f and then calling the float constructor. You could try with 3.4f directly and see if that works, but it should actually work with 3.4 already. There seems to be something else wrong, but without more code it's...
Hi, Thank you for developing this library. I am doing some arithmetic tests. Like double or flot, I want to assign vraiable with some value like half a = 3.4; but I am getting error for this as error: no viable conversion from 'double' to 'half' (aka 'half_float::half') Would you plesae suggest me work around to fix this error. Looking forward to hearing from you. Thank you. Regards Deepak
Improved performance of pow function.
Refined rsqrt function.
Improved accuracy of rsqrt function.
Improved and tested rsqrt function.
Added rsqrt function.
Release 2.1.0.
Release 2.1.0.
Separated performance tests into new file.
Improved accuracy of atan2.
Fixed exception handling for integral conversions.
Tested exception handling for 2 argument functions.
Changed handling of unused parameters.
Updated documentation.
Fixed tgamma exceptions.
Integrated branch for exception handling.
Tested exception detection and handling.
Updated documentation for error handling.
Added precondition error handling to mathematical functions.
Added error handling functionality.
Fixed Win64 rounding behaviour in tests.
Floating-point exception handling.
Updated tests.
Release 2.0.0.
Release 2.0.0.
Tested with gcc and clang.
Fixed problems in C++03.
Fixed problems with 64-bit integers in fixed point computations.
Fixed problems with gcc.
Updated documentation for version 2.0.