From 692d028afdc3e1cf909f3d9d020310e83896861d Mon Sep 17 00:00:00 2001 From: Hansung Kim Date: Wed, 14 Aug 2024 20:46:09 -0700 Subject: [PATCH] Add flash attention kernel skeleton --- tests/regression/flash_attention/Makefile | 12 + tests/regression/flash_attention/common.h | 18 + .../flash_attention/flash_attention | Bin 0 -> 2049104 bytes tests/regression/flash_attention/half.hpp | 4018 +++++++++++++++++ tests/regression/flash_attention/kernel.cpp | 158 + tests/regression/flash_attention/main.cpp | 308 ++ 6 files changed, 4514 insertions(+) create mode 100644 tests/regression/flash_attention/Makefile create mode 100644 tests/regression/flash_attention/common.h create mode 100644 tests/regression/flash_attention/flash_attention create mode 100644 tests/regression/flash_attention/half.hpp create mode 100644 tests/regression/flash_attention/kernel.cpp create mode 100644 tests/regression/flash_attention/main.cpp diff --git a/tests/regression/flash_attention/Makefile b/tests/regression/flash_attention/Makefile new file mode 100644 index 00000000..4f49f927 --- /dev/null +++ b/tests/regression/flash_attention/Makefile @@ -0,0 +1,12 @@ +PROJECT = flash_attention + +SRCS = main.cpp common.h + +VX_SRCS = kernel.cpp +VX_INCLUDES = ../sgemm_tcore/sgemm_impl.hpp + +OPTS ?= -n16 + +VX_CFLAGS += -I../sgemm_tcore + +include ../common.mk diff --git a/tests/regression/flash_attention/common.h b/tests/regression/flash_attention/common.h new file mode 100644 index 00000000..5c84f3b7 --- /dev/null +++ b/tests/regression/flash_attention/common.h @@ -0,0 +1,18 @@ +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include + +#define KERNEL_ARG_DEV_MEM_ADDR 0x9fff0000 +#define DEV_SMEM_START_ADDR 0xff000000 + +typedef struct { + uint32_t dim_m; + uint32_t dim_n; + uint32_t dim_k; + uint64_t addr_a; + uint64_t addr_b; + uint64_t addr_c; +} kernel_arg_t; + +#endif diff --git a/tests/regression/flash_attention/flash_attention b/tests/regression/flash_attention/flash_attention new file mode 100644 index 0000000000000000000000000000000000000000..993f22bf2e6fdc13c2f5a5f3f9d69d5e29d6758b GIT binary patch literal 2049104 zcmeFa2Y6&xc{hI7827R^7)+P3fwhfowbg2=)~f6ZYb9A_3k0r5qmeYbqZ#cK6$glc zKukB?bVC}D<^Tax0-JX;1W5V|&|K|(;*=IHH`MsyV z=bZQSbC=hOE0=cn^gsH6?|#NJ=l<=&eP8!U=5HmRP6m z)OkX-MVo^ImksnQ&fF&qrgux6GrhZq@*!_KfgDiG_;Uz*OB0kiVZLway2?k8dB{wj zk7(OTnGKn8`Esqr>$YgQR4vuZMK``Q)a~$a7XIRRc6K_Rotv4O+#APTefI|MZ03*b znTYp~PsXE%reU$;vYzhVo{PzvyvA{HZ7nV|oAvTSt66Gv^>%j;cJF>TtR9kDS8LVg z)>EKRz?s)q7vqoX4KWCgys22iaRswRyLujg5UDjtuC%Ii{wJn}uZqWJMp5Ibcttc$ z#qH|757_r&zg&Qakf7o5{X2_9t@+hDWKI_FV`-0gJAv)=Hbj(pocKYE_HPa;+MZ zZlJJt_HRqU`m9lA z(JU>-RVetzTA^5q7fVa!YMDx!YYZinNf_qTz#-Itjo@$`~5ZA`E8c|P`)iR2@yc8E9x@Ku}t5t|_fv0zMnLt421;?7i6y{7aVk@ioa$>C?x0?zZLx2VJf|g24b7>hm-nPu#jtqO;1eySfJ^s7z%-Kw1kGUz#I%lH&G12k| z?-ej=rdOY{>a|>LVbljjO@63-qSB2-O_uc*6iAo}nq3OAqR80)@dm4$V zoXtQNf|l&@=$*%HjyOaJ7_Lwfq*rrPTUN1XG$Va$B2(%%WkG_+W*CyWb!TRL7*%U> zcAV-Cg)5%ZMwNw37E;*7wMwf&f1S#|l$xL-3tyX2-7UoM-Da1~OJ4tsZT3eEn zb$1YejM1e|qJ(Kc<><-L%li68ST~E;+1XJVPxA5#_k~h^I(OWMmOL{`<%rtV*VDbL zm-<3U4(i6p_}CaH7o)^{WzUpJVRdl;OAXX#>KdZ7WF{8seMUpW$nU0 z(ntd_PEh%ZYgI|SK$EUEB}I>Eo-TmVYM(bSPIPs;T*w3CT)4daMB(y$R_hyenw-F- zj0XDsc^FS5QK_!Q(qX0CXma^u)Ie=kgi5t!rL-9@RcZxZl0t(eTgen@?x8*7@qy8q zS+xDG9;|41jgku6Hp(n;R1O<+R6jm1&3!InT-MjLQ7Yf`oUaQ~j(1$9D$dtlQRz=*^R-?7KAv#){@+>U? zc{VNJa!$V3YAs170vPdRnVpzM!qJ{GWtHe`Z?5V^)z@nV*_2aq5vS`+d&Wm%OfJym zDDX_{AfY+}afS)BD3f)w?8GjK^>S}1<6&*?G+;;An2GlEqp?$Ii8NxSp8k<&FXuJXEYR>;GI^BdNVQTXdjpy7MozqGGsY&n z)1)TZgr0C`xBA)yr#EqM10Sh`?EN?Cl}xNn*9-A>Ie? zzP$hP?gvwnWmrW5L6d*WOOXv zC!L2B9QA{?H%$f?&fGs+bYu_Nw3e!&*B+cc1`4j9a*^6|kDZP*d;1>_OA!vQ_s0jZ zGOnxRaaWsla#Gvkherasa_Oo8cYTGjKuOT;m~@+Bq0rzx8SJm{utnUU^b$Rn_3T+) zg*9^E7vXNIt5PM^x74`4K4PY82Jk1vM{Q12F2X^fdL3xb&XEyvAo-JRg6WazY>%L? zzlV2pM50M;Me9g971YPxi}Q*S(Yq4DC}#(vkxXX;s%$LOSgB#(!WASXNn_RVWhNoY zkJMBiiZq+$uAbeyclGp8E!DvQEkL5v{P%)7IJ#puKsX*%jJsEX^3!|Z-+{|xPo zr{?FT=ds`h7bI-yVM&mgpxq3TeX7smnV}J0W9g+XT#7nvg|-M#QshFE3u_Rk!d%X4 zMWQ|^auS=XBxt4YMEu3^QEZ-2>7^Bwx)W9Am-DuYl&!P4pOitO47%Vwx6UO4M{nJU zWGtCVx=DH|Sec|!sUDU}Jwns(`ZgI%yx+0uA1NmEjQNt$>sC)Ib!WGidUBM3&S zyy}-WVrAKef6@U$RvA!+x$&dlB$H0e*;VVt)F`0uvqq9zPp7?gDK=5BB7|H|K8l`c zWQ2sBwLhIB_U<3T%my9p_#}3B56w*u?Z*@+Q(Qc8 z$YRNcg|nl3K6iHV4dZ|1!dGe^jRCTB`ibK>8nxPdc?5WQ%xeuxHE;u8dFC9BpPOvnCji|*K zd$WtWib97c(h*Q{vVa;tCRdcsv>(R+muQM?r*IdawMg|S4Hu-2>9$Xr zHCo_k+XVgLTLaU!MQjHaDwSFh%T2W^Eghgc@>iplTj;E+%@W)eYinC^2@^eai;R*m zL>Z#&AaEAOlcPdGJ0ru6x&8qlc*G#q>_1gQsM)S6uED5 zM!p06{?H34UoOQo>{`U~k#5-aQDu-$IZL!V5g=Wc%9U>&R`jdSm>g_3! zBwJBmsKrzp-985mEmLpQli8N&4qviT(EeT)%n(L4URuL$1*TF|VOi8P@hTJ*|mj+c$;91OOH=Vs>V#D_>t z%7SYoMjfaVq8NH;KI8XUIjZ6&EtpsYgspiP* zOwxxURV2zyQ7?~sMTjz8zlgeCJ=t>Cum zO71n;v-`09N;NgBx>%^BOppQrFuUrP+pFtz_RY1^N`f) zzFsP6sb5qzIORzXLd%ZSXeDQAK*1XH<5njq%4SUq>zXBuupY-U-w|9%T*kR zB`HISTFOv$x#N{iUr?$gYF)y`^6k(eEJb&dDwOI;RVL^BJlz(j#Z0*G7qjY)W~iNK9=&bs;;Ex#l{VwqP7U;*wnR zcGmRJ+%T4=4`44GE6>^NPg9-iR7r`Z4VNl}ZS0APsq{_qA%?>G^btS9q|HBQ-)u%*l)>_p7z zw3{R*!!54qS=G%u2rRGPkCvKI+xeR8FYBxi~pEhCv0h>pUd z+)huGP_@pf5=ynFUxzXLo~OAZaiu%SckPqLHL{px+;hQBfvUEKy1c zou6=P7U>B-Yv*+(swC3dOJgdkP@<`lnx8g-I2qsKjA7OcWC-GPEa;O+aH3YY-?8yf z#-&3*CNWBtCg{{S+Tcfx%Nh+TE(thUvB~=NWd34GE+_ce(W~R(*}1NrSsT|dZGFNf z3iSX|Y{`h%4c={9-Ec{n<>e}9onN%Bf>jhA50Us(?!;4w5uZsRp9aaY zK}|+4Jvf_dbhehnEXs(6L&>&n)>~*h)Jcw<;qm7tEu3|iGp(57xr;d12&FQhu=vy> zH4eY`=o_HkQEHQOif+PAsVEqcAeTqJ4P|`|X)iyL-GQY$XI&*}3kjX)9y^yN89zGb z`l!bi`SV!R>)6xMr;QoXI;>gIh?B#AyuK{Hsc2{yH#t(va|skou6ANun|98-@;1qS zdfz)fi@5Ob!s1#hx^T5nT)`|Qy0Ec@)3U44CC$|?+}6O-_iA)`+>O7U=n;>IhN7W~ zxoBu@tx}dnh(CXXDQ!HGwhn!jn8qj7#QKfQ(9Vb}IklRY#9gAf ziHnxT?m#s>GKo8w((o|WB z@P96z+Vi-P@tKI$aHFZ|XnJNp{q@jKZ!|qSHxbXz4(%O{aj;=>d~)w>!W)ezr*Hyz z|Mb)hwj*Zere;PRyXhftC+NKG)WrDkcw(hnz!FBXAH09)aZ@vfMFW5+>CH%>sTo;K z%p!V!bt`fq+&VCEF4vA=1B3F=!$v%)-#0phn@h6*GtqoR`i?r}#6SsAo_HjH5)}tj zQPn|O%H#kAC=Rrwm6wG;?UI;Mu42k;5vJOcDT#s1nHy?zi4B=E8?NQj32+<&i4UML#GS2#(6iKSc^(>b1_)L97*WC8w1mnJ#jFThyt>K1cX_E}t9-vjz2n}9V zj1x~-^p4`u&2lq}$3}k`h`?>Tj+*~>~elGd6+8nmxS>S0>ajp!v8F=Ty;mMuYJ@exebK{dJ zKrN_v4^A!7*$Et6nuHcHd{X+e(?i3!Ejh6_D-!jU*+SZLLs(wPq@8y{wW59aH1WA> zTda22oJ!)eWF);unhUN4S+My^5f4w#Q!7B)9id?6LoLEbPVrIFFh8((K}p|mzSWr%WfEs{g6As%K)e84-i!-d&Ekr6kOgX zd*-pCcwl^Xe9t)UW#^sHRw{P(Mh}fU4TDpxT7~DL^ONIO(~uGKvuP7c;%t029@@JX z$0fa@_CkUaZmV?bf;Oe*>A-iJ;3kIVac|7gJRH*S==g+{4e_jOk_#}lJOh;ltbMs4 z!OI7kt5a0g$cl|*WMXWXd;LTkbJ9om42|rc^(r;0Dh|C*4&$`A6~pN8zVV41b9@BD z^i&N>uyV`ZrU7@-M~3Exa*i=9pS&v1ot?IA0s+ig=@SnFWSfAgIaK*6RQ@5{VhPyJ z&f7XOO0F@_K4@J}9Yk+4f@W?lrbqKRpPreTb9yfk2Mw~UXX0U<)mHG)xkGb%W^I!g zJvcQ_x)3KpZ8*uiY(*Oz+LP00#LKxG zp2RH87W~-gO!A?v~&Ex_gX3qcqsgayR@N({^hbJ)5 zu_>JiNDglz9wo=qDwb7`B!op2i!@$$aG%=M@0#=X{BZ1Ok zrVSe7Uq~ZgXD4ut8_RFGfSDaoW8!{{CQl}tVl$JgLBcGe=#K_eCT$w?!!ZKW*P$ol|Hrlp2F}1g++ZGBlbCR3d8*pb`?caliOmz3Q3L@Kl zi_l~T?5UZJBO3+kP=Ln9i920Btqq@jI{l&PPXvQ=A{Hf6%Ki3{iguySJ-;sw0s zSm@V=u-rRid$-xEXXbJV0xuW9+z3~uTsdHN#qUYjGL~6a$T{>ufITxhGlNNCK3=u3 z0}z=k@QQ{v;1Yf)g1M<&M(1YcrgGyggfNe5k~+*A;l^!CcW&m;7+(L$rS|atPz8}W z0;URk@bCr(kC^RX$7yDMl7=Xl5l&-S)wbT*!??pfH5|~JY%`5_2yCL@gH~emN{W17 z^@kUeg5G9F^4&ann#KBYC>ks_Ulo`)u@~r~17m@5q2OQ_4(~8k_x#X_0%RG55)oFq zuM%tCL=vJBT%wT;n=8Oa+un+rb$; zmt?gi&)sdpf)jd-7xIH7X4=BQs%>EIE!?2neEfkTjze=%X6C{S%sMd<&QCj;8S&hTf!dZ-Bp?-lyq$`SIWuOz8iyX_J_8nusBEii;nBr(fN_7;8OH7b|f>0df3Nh z%;HT^ED<;(B$`xA#duIPb0)0W(b22o;dy70;PA0w;kl2U1yUM5Ig6mOobR}np*xN^ zxxC3?6#eA*88_94A=UJuJzh1KJ0vgIWDz7B zs$m(IwrY8|1E<<&==P9rHB7s?JeD*~P`7xE>%g9`-6q9d6K5+h-6`h5U(kxzDuXsy zCXzw@UE9halrFghBK9|!lH~BXJm{Y430Cvl+Bs{ANnr5e?&+oiF*~~K90!weF5XC$ zH*c_^kA>{Xai{jN54OZo1NL^^2G4f6eQ=4J_vo<^=|__s7vz&|)+)b8NfFSQAzA1$ z?x756huY_k4evv@AL6-v0foy+z&T0ZEv7@1$EmTAA!j+B+`}fGgf1C&+CK47Qn^qj z#*Cx%Os5~)1kFBu7DikcF^syKTNKNrJ1JvEu1g{Aw05mC2f4^h*t%Yrt5;OA=qsI> z9EF9K9Wj-njQ1 zr$Z5$??ZTSXJ&+iPQ0l-sIM{Zg92zNQ9kz5>Mk!Rj8Kt9=%J@bAtong2;!u*3wQ7I z;qDYp;E)}<@d-NIllVw^83#vba2IF_Ig9mh9uI1wc>nA$?|;)9MS{eDH^>Uhr3k7U ze>J%w8O2lRV)kQ0ZF-89J+W7=CxZkh2oFY2&Or#Mi>lX9&t?zcA)UkpEsqRCfV@C6 z>ptrpB|}AeCoPKSs~fm^9M6;*c$qPUvqvV5fVYe%nM!q^J72{iT;(64tp8 zixEiK&;FSa`y&B5nl$$-xk4GisLco{6il14cV8x-h3456i$aaWG7U z4H=|9nBl-FT5&4I3wdl7waVl%;kmBd9F5KLTQh0usM+(QcO<~QuFGWMhAq&I;rU2<+I5nTb>ciU ztxU?fNS-W=^5eMD)?}1O=W{W#$o!)#nHjyB;^E-X&|Guoj#^-LK8tibm1pY7wbOMf z$1;Bi+x42W+KQ02eMS+>#xin8tZZa*hIW8weok4TeDIWawd3 zwiIVseWF@`H;^%rgGz%!;%bpGFf+l)1e}thmB~bt(c}Xw<*LxYJ)DI{6FCl!TNWd{ zB7w8V`i3V1=x2G+QxG>O!8B`7&}zj*|ZVE4g((ahlzqf2ZYfA&Q>_AshAf&$!5weVIUhRx#8^L zm)03#9LsbI4iEt+1*ewcEQ>IG51W-9HSnuQM)j_rqiC8YTzT^GLa(} zbO2lsx+koa3kRF?PzvePP?^)y)N^8-f%6!&{kUgl3L}Tq53Kv+Ui3wn)$SjkHd(D=BlG(SpbEP}4~4_!s?EK*u98id~BSx(UDfuWgkI+_wE zC(*Dwl8<;7nkSwJWnGz^UbpT>hh`=Y^YV!afbRAfv5bS&GZ>>8VfADGh>=P<=C@He zL$4S^u|$gU{ECmb0nj%u&}Oht#iJl85`CEW0Jh6VQr(r!$=puPGYdq-Y zf0(PQNnSYWA-f5nbx6||NE3@G6|sp)EDsG&%+KO*9frwt#KDV@U0~_&7r5ZtwHRWj zB@hZG=P2&QAdh+}ZW&G<+6teO6G-L(sBH9_^UyGSA~6XwS-+7O1jR%1ID_DEaPCBg zC~`*wqY_gU=SOnY+uY>P0I3(w-{rv47_S-}VB&JS%!#d9FWJ{{P!4S~eL_tK1uWR#Myv%JfJTx?O# z;;i2!>R8(K>3~xOcoL0(v4^^e$BaV$#f! z`g@!n;o8JJtoYHV6!^ggb;nDO>_aB2$|kUTrwevFKu&zKuXIYP)+tV7Mej_bBuW6! zCS5Zwq2t{q!`a!5vyYj38r-Iyxlh0yu(=5==`b66)Q5J{RFB;7RM0i|Vium+^j_sT z1Uxj0MJLyRVYu_jdACg;7@}Knc+wEwVa6zljj|X)7lG2RV&Jk5%vpU*jHm(0-7~5I zjw9HxlHiKs@Ofzgl}ffl`baQ^g>u|1EOXra(Tdsi3DU5j{@s?;p5kd| z`Q=Isk4`#s9-ZXo?A%nFWX9DjzI@UXj+^9+=Oi^{I!R1< zPSR4IlcbdABn2OqDwG=~SmBdjSqizZsWt{!ZW>c}o;)+Ilgf7dbJV z$jgm5p!D!Sy;B1Txd{>Mq=6Yu^o*UD89R|Oc3L9W0bfQjqPQ)qCiI!eRMyI$$U%1Qi-oSgv7P`q`d#~~f$4P)N zoY;loMop2ps+p>#kwMDxVo%)pDM-0)DpIDKl9cJB2H$6G#-wE$rDi4w`5coK4^?54 z(3IsS)L}Zsm2sVfW=toc8B-FfACl$dsaXdw3F7BNoq9esR##Xt4mlt`GLpBN2rALQ_#nVv- z>V5Up2VP^MQ5znSDXvf>PC|;~r8Rt9sEKbTt{nCFtEJT<9+M5QS8MC^Nr9a6wKne2 zcyi9$MB1pfvuMX}24ihB*Q%k^pukaIbEzSAAg^Fo+c*z~zTQrj>uplM-ZsDMjj)#z zKSPifUtt07@jJyIgX?0C($pif5elrD{R@kk5W7q7w<>*Y0c3!ZznYvQBWYc-wUrT)@y zIp902n8V>4T^Ke~@NNM5*+W(r9v|wXkYmKGsCcq@S9aW0tQIz1H+VK_%VK^5&1K@d zs|I@FhP787gmVr&`NM^eY4bVx*rOX&v*5)H$QmfA8HBxH%D<;WxKq`;ZOYXlyLmt|58zJFA6LMi$Ug`k@Y!fu+NHN6(Y*!KVj zZob)tmvQ0bLiHKcdwI#MFB|B`T3`14`xU8J0QNml)$u|kM&3y-RG)z|^a3%J06G(e zY+aaWY&~F4UNj4yYAXVI2?h3?n<4`AoZA8-oO56U^l+(cq30jgOMIv*Rh&g)c{Nix zu7+TiS6P)~9r=-Ox{aiWZ|?bN*<35T@`rsn=fDQ&;qq$1t9pdJ5QyRVsNk#i<)tnD zI=LHnrRD_$*uw)J)iFh8ctJDA54+|^4i~z(}AcLgM8-Rea91ULe=z zg1FW=_r2GuM_m7aUbcWe@AQ#syxZ^fgcy0F-)ydz=!248U~5}6Eeo*xIK-K)h|rGk>j^4h`;{`|h8+7Dlh}@ViFLbQ+cu5vv@H|Z58qeLYu+HE2(suX)8p z*!KX2@1w;pFuK`U1Ix=17>(B28ir#Y8z1iVf+FliMhwq|QQ=mDTLqre-^8#1`uLcy zR~x`yl8E8?KrMCi4(PcjO>XRc%}NezfIjxxT{GA2ntr-F9uk3 zym6W72n-2V-E0u{Ld6UZv!W$;G`PsT20e6KX|1|KDXqx2H`WW4R>`dauvo$zjt=>y z>Iu9x%t>?1KNyP@w*Im)Yt3w0L;pVJkW0)xj83KZuhXXSa#bcK`(8< zo_EwetY)N}B#FqEN@(__s#^_(#k(m>6>mtxHuYMIHx{xGR`3nuK*0X4Oy(Sm8#Y2> zg(HMbK0;b#3`E#kLz^#|u$Nrbvb5AN0~ByPF#&p*-Vt`2yeTTYXr{DQf=SHk7S0F11&u=y<+iN-w*KHXo z+iOA&H{>{!Ft?js*;=c)LmtLn%E^HnO1XeDI;g$HLcPAV8MnNoTT3sgiRGFr^_1zh zorKv4x%8H8#bv3nSStFWbu6F(nqf<9XSTIy@2kAp#@Er(7CxCkiyq+!tBch@-ie#f ze04GCH1BeuQD1adb~xi;Hge2jWvSBg)+E_2R#!{M@{tKUmoR4M%SG5B*UP0~*kA`; zH^Z)*LD!XV*kFgk##h&J^$F<)JLo!`l1iJDG{a#xgJDD{BU~0;)na7d}{ST>q1o^ekgqKgXt%J z$bGBYE(Wn_>n9is`w7H@t*nx(%cV7g%O~!VaYV*-^?b^$xP4~E4Z1~jbNac|F_do` zemEhG#pPh|jm2^kd4AdW8uMCv%dUNquZ@`D}^QE

e;)P&ouMBb#@Vw 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%0DLWuop4hME93TDEjC% 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

#os0FR{Lyw?+{)wkEv|GaNOC_&a{W!w`F5Jk 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

J8WdcpHL z8Of`CT#vCo*Gsui&5qHl>FdJJ={#o59HG}CqhpbqxLzUc&r}F_T}yd&t(Uy^i$&IR zz2tob_E*2dVkxSAm4a(E_d!z4uiD>`yr#t>-{5+M#H(*R_38s&4Y9~KxnA<<%zis@V{W z+|27y-tS<4^*bzm;v^>PUw1 z$_)}PC@+_ZAHWNq3z0!w{4>Vs0*V`-$bZ}n7*e4efubzOspdMQu5aZWUa{L`T*2{`|7X$2a zPW+&}M5?&o!Mat$37MDf`4Rlyt6$xjlT0Yu;|}gufmcpG*H^07E-Yfr8d_d34_wM? zH_q#o|9-qib6!JSkI;XW>c!uU?hLVBUcC0;B$Gp1k1$VHsuyc=MsA4pYG2#`{K(HW z#(6`lSJLBo0N$q?KO0(JUiCPR(Xxh^SL*8i^~m1?=?pP1!^6M$do*+Z4S9`cyo^_e z*1upLm{Z{g9~VwwAM3v%uNdRy4AFHOj3?lJ5u@TBT(4^OafVngFJA1`xkhe?dBM6J zS1k4)*J~dh`T5ZLJ=~Y!RQSPp?aMya5c2}PN}rS1j}t6&SnNBvPAdZ&&{yF1&`%^E z7S}`E*ynsKTI~BB%?qwOdP;b)SI(9_EcWe=<^|(>r+u4VW?5Fu_XdF%jK5+VxAB_D z@^w^x&%PTBUeF#pN_e@~yexm!VX-fEbUi}9ns{WJUXxUWWcpz6g6ob#39keG8}Neh zYRjYB^g8gr0WTQeN58v`7w_A0L+tm~hW_K|DV)~{LwkPg@!(a%cv*Er%d7aDyYwl3 z-k!?;er;%Z!F+UkiGQ&<^dX;*HXjuJRrS4Xet$6MrP7Ok$38o{U+t2-vL(C@Vfi{k z%q#tn(5tp%n_klxuiOyxg6A$k8NH3dBwS2 zLp<+Wc%?tD!x=AQ_R#8;e^v16F7f*#IIn+K@M2$C>=SlBVgE$%fa{JmI<%`MKa}|6m)h=?q~FvR+Nk3Lf-1D?`37bMj;3BVS`Th+zLO zSqv0dET&tJz1z7SIVaZ{PJV1cmLjqJH6$L5^R1~NvP*I?wKt+Ly z0y+xt(c4fSL!19(w#w;C>A>ZO_ZkKMA^pJs^M~hhskutLqCiD~iUJh{DhgB-s3=fT zprSxUfr;V-1 zedz)E7)hbekcE;I@QF%3LluHXz-OrZ2J)qRhDsO6m+}FgLlsg!L*~cOjwB)QAJA>6 z!iqkke^cpC^%*KZhI}cXj!j}8h@lE8pPKgspP>pVpU(FMpP>pVpDwA-P=%CF`~#uS zP=&w;LVNgVcTB?KaW`$$XoEjbYz#l%9kQJ5CK`q*)AN6iwS50d_C8%1&S&X-{1kgv z?57A}p=z{I!_(JSyLbqVokco~hnD{O5AJv=%^qsweYCymM3)cy-W`&ic%EcpJ?pK(qq4td}L^{biUrtCBedx zzY~0%OC+Bo7rA`c_tSYk?;f+r<&!^B7g*zjSY*gA8Xsd!@^V?}fqht(_?NQi9pE+2v~@>x#! zG%NV9bWc9#EBLVVQa(wkPl2U-@!@sp9?TitzlSQ6G=NW=JYNh|DCrafd-iTc|KW-D z+}%9;Lr11VKM3JtEZwcgcSL`fk)d6`o7*4eZxrnfLPw_a_Q((D4@Hdm^RLzv`S5nI z+Z$_K`+3=ZAk6;f8rRSBUy=Q@41dbfIiFZo_&J2L-{k46KRh?$`U8YHmd^bL`muiP z{n~2~ANz)DJloedS-PtOXYi0CqTVD%#l!n<+<=-O&JYk<8_$}qx zmK5{&Yc+Xx-HUm)`|xc2u>AhZz?1G@M|lGOYczQ#{|oC!<6sZMj>E#`d95bTKEjj6 zfggmq9#LNqr(sY%uhZn2{SfO(53Hvs|?^Ham*W{V`8`h7;As+~J+mTs-!X4Uhp_9gaQe?~$@7u{^6VKTp6Ldm=Vh8aqY<&c0_fHDkMepNA?X=iAb76U zdB)zxJPSTNtk1LWB~NIWgc^J-0=bUfek&+>Zej_2V$5^(-djYHmaZ(#ag zADN$GUNjE*=!P&(uDKtd=P1wUbE01wr>SQ)hW)dP@TUCIU)1wYzj1QxWidWHK$B3(fgPx$R0H0wR~8RkXfU=PArqo^;4(=aH{zi9Hz z5uP+oc{o1(Jby00>%oBH`%%dIzOG;oJXywAgTEW1+&ly9Q<^(o_&vmdU-~SpcQO5C z@g6Mm6ZzbY`~vj!8_$ECk2Lk9<4+m~d&N+5{Hg1o|Ip;wNyf=EUgRhLNFA=%-u?8< zR0}(^G~0W$4YzlD81DBd&qQ9Yz5DU3-COXSqscS94D+lSUY@7@OgKFAlIIBnMu zJX`h=dL}e^M*jornHo`E&+M>p{4>6vurptiXL>#6X^bq-v->xC^{zV~@`+}9ZzsHH zoVKH$BlPs7`ys2&oBz_}ncNBMN8^;IeWV^wx<9gt=VzKc`v^}Or#xFVdD8uoRXp7X z1U2U8v!k${G){STX!6uOA4N3VQKAa-q;bl#`&7Mlq|0-dCeL2Nlg25}n(2D}smpV? zCeO^ySWg)E52u~WPJbOdt$zC_F#j|Z! ztS60Ap4L&}`sXN3p0&GSo-|H*ny2Zt_u6}~UD|(E{X|@6?XJl)wHH3W7YJ|4v+YiYdu&Fgn~ zzfQ+Okw3&C2Wx@%^?QxHez#-@_@MI)r)lzpd4*I`@Ps(zn^*8mE9M!3>Up{*PtdO> zD(WBNz%#ut96f3O3HI6RPS~>{dqjBo%FWxr{pakpf+xhmPIjF)&%B%`Y9aGQs(Nqw zH!;uC^b&sW`CP`6?*PHyAzO|oTyOQX3Z4)Lp0zi4^K@i>Ntr+3RXpMS#q|Bm>~*b% z$@awH@02aa6W$|~xK8kdION-{;2D+v*+ukG@l>_}5LtJ#iJJR3B5Li_HLdO{p{x1Qk5vut~ZAD4ux_Rf|^^Y-rewRbvC zN#o{RZ=M<1&O5x?dkH`IQ`O$t>uL<0`FS}1q#M1@@5zKW&#=z#?DaKTJfUBT?J3$3 z#EUv8c!t$4En+-%&YRE=&;e6h-mv_GuJJFkGSpCux#xqF2 z6df;k(tfE!!85FW=_E~_&<}M=o)Cw6Pt5byGpv5;WX3Z{zhqAkdeVNWpx{}yUvjU_ zprj&H^-E_ko;v*!wC`>?PKG$-QkC@9vut}0!1F5sd1m+Z?w7J5@l>6U8b!Tpk3a1N zqMxVZ&)P40>lt+Xsp4q|vjghcqtG+HWB__Xr&bcGcrMrE3FEq! zF+xv>Ll#{Mo@K{%@Z*wD#q*qiJPQ-OdDlu`%%0E{K|I{AO_w6Hi((`7Yf~V@d zIi^HI{%70CqMRx{n;1{S7@PCE?tu4RI0p!x5HCy=_ERaT=W`;=og(AhJUi^2a6Bl_ zX2H|aWr75eYfr}_(B}A>V_mmpTImiTftU592lDf4?|2 z2DgiJ4Q^LZ&k%MVT>idH&~}v8taoTP-Ll<79C#&9^RD-x?MPMcUkzCAT~oa4y+^@Q zRqsLdyeOcav8jS5)zdkB0D3}Yl!PihR|!3}&+l=09-{sqJHwl&>in+KQ^oV*fIOoI z3q2{%j(|L&y{F#A_seN}Pvpe?_c5C7Jvjl}vkxiX-rK)WzP$ra=RRzQ^345K*cq$I zvybqsnuhI{xS0E=8PfCfE$al&&uQ|c&(C-G@YH>N-f!JR>Ur_J!QPrYt!r?-rw%Qz zXV2^9pJ#x2_v7hEp8E`tr*YWe@a&U3_toUtdOg;&-G^t*ufoyOd_maRZ-6|L@$!1= z^7LDWV!tSOeqNI&ZAX1RJayZVAJ4qxX=?J!UWMyDdw6+0`+lKU?|wXumxP^(1LT=F zA{?Idyhi(Z=Zk{po|-)4uVP-kK0Il^Pvg)p`RQr?MDW~8lV{uExZX2IV&0TTwq38@ z{rboJO`cX9^X&2A*`c}a%#UY2C(1iPlV|O9 zm}lEj<@N0NrJkOC{@E+_oTSN<_Mf#!m*=V5fBN}n*K?x0F-@Ly98&P%8P+(YSMsbL zAkWrg%Im4i)34t9ek=5xtjRM`jr}uTTb^ewq;YckEx~h&CePX`lg|Ip z^HG)5^FU3W)**O4#F-RPk&H$kY6yH_xcOV|lI)$g@kqvwa{u1I*7~uE`VnIaAIn zLL92hI@4Rvu;%B#7LaF5v93J7gL$qA$g{~1{z>($S~dVZp)yKBRXh5+CQoSJ>EpcH zQC7h-toD9oK%P;{n`iCW-g<_`(+SA4Q^B))AUp%K_p3B{fN9LGK^Y>ke?2>lx1=&nKsjAxMNe%tpJ zJn3`4eF~mspZhK02Y;&SeOw$3IEhSZzkq?_n*m?-g<`Be|}rj zKViJoD|td3>b*z7GpzpeW=;Qu{xXvgdO{p{Iv0BD8CL&!i>7}wig@0=IpFNT%?LRvdJj3cgZ`1To=r7w&6na7&^h|u!ThFli&)YTq6Z*^Ad4eaz zfoDO%Gid**Iv-^;^@R2vZxB2o4m?{f^47C#dxsyFgesnQ1mtOc*_&r{)sE$PXF#4^ z3ZCr);ps6BQJvrK()3U0FY~hAAr4h$UF@xA(Ed|Z@88kX6WVw8LhtsTSMV&`-aYhG z@!SxQXKt}K&-5kUdWOaG?tna-mU#25x^w_M!D&iDm7e!#@`QdUy~w-0XB9ll_Dcck zJ*&wR{4;uzx1P0^?N~kU)#M3!c1oTQhbrq<@C-}O`!soip7zP!dN#EL)03|2Y5lhN zef(9i4@>v=@qR4#GoI{*XwGlH-&9KQGnR@F;;^nKcALn@k?W7ln=$X4&-x=jo(~9~ zmNrjW(c8-to(D@^Aj>c9s?JA`Yu*ErqW8J_~_B5PM>&to!w;TAKDunwT)UN7$bQ9yLGp|Vb)3}O{Djn*b z`j4vK*K5{$FVUICDW9ZIy#r5O|GZa|XXXrC?=((%*81!RsA})3djBTl88J>R?(1H# zF(1g^`ie;Jks-w4`=H?-vK>)BSMh8kJlh(*c>+J+v%Nf_9Z|a~p5J0Tb=nc-PvgK} zHw6FGZAaf`JayLb)e?W8amugPryYTwv|dzt-mIx7^;;UJJpJOJr*3<{MN`k#GqK;& zIOWy3d-?NwP@cDH@{FH_dD1xL8Q-HkPw1EE{@$u_$nA`0#5mn|976YJrE$vBFCJ9S zjHaH>GOQ?m(J$2jrU7C8fEXVajYw*$)_bf8>rCU2 zKZJ>B`F=hq&#WfT9N|ghzz@QVCQo`FO4W`Y(&X9HjP;~(;0IxBTzNfP5980zuzgx? z9^>xs&8F_A^WQp|F~*)OjAg4^_97CbDqza=Q7nzyX?|0rL%r*cKYy&LXXm+CPa1d0 zmHd~gF0Uu_OZ0rCYVYlg=Wyfr;`LEUR_IUrJj|2E5m+MvdQv+o|J?oP zdZ%_&_5M9gJ^Khx8mGKcdzRM|c;3zhJbMXG8mBySA@lr!CeO@8SWgypK~HK&)h|7zsb|~8SWg=7$7_OKJJRLZsmZhU63mmv zDbE&7p7eaA((`Feo&~~_#wpJ(O`f{#=!cp-TQ9|W(m3VWtILy|=Tv$=qscRV8Rkjj zlxLUEdf27GXPk7Qe<=LyrQ@7rq)#T~4U_EJ^@+`#k+B;oOP4#rPihZ|M zYVu6}lB|DUjd@d^iIL^^F=Okbs@#if@HO5f( z8f)1`+lw)#?S-K2%~)!TNZFzZNk-l=iWN^ThCeUcJ8^oz=_&>5IAMS@?Pz|##!~k zlM?KG-b+l?o7 zvfUo!OlZ!C@t>hZ@8a~Yqbbf``(N_g(TL|q4TxN?lK0Yy7S8fT;Ac{E4jLcRVejja zFAs~Z=cIhTdYIL)>ro(x|nbw?<&rQgehecOE?~kt<-p?0a3FnmYo{7Ena?!Gh=8J*TEQlEY z8S1Btb0Tmyy&BFb<3GC%r)c3UT?(8{+Rw;w)bizF(Z%VHryTBQpMw*RXHgGb2ApQw zIrE;o&XMnntjkaTdj4?Ej@QEd^iF_u(8bGvGo$_NF??Cse;WSK#;%sR_V50_joH6< z0T=2_88{73-tZMha)$cp;`GM}Gn}m_YClUS>nPgbc)iHkto`gWem28#o!SqEa=P}L zi>eKc^A;}1ep9xKama8=I_jPR_?gw51BNrzYmbW#${hz&tIS=Ti>YPx9ES)e9*0Oe z#)#t(Prasc#K+ao`{$?i%+DYhV?QtH7$f`n5KdRWw4};-czeg~h{paBwXBCRvi}U> zbhV?URL1qRBjLbyB$uMUU4F~-kDH>-H}NBigPY+JJr)i_w(3)phnI(E$xUc_lHP7JI=7n z9W`?GkoA+jKL0SunJ(I#sFAZw)=w-KSN(j1$c)AkcJa;BE! z`cJlgK1On;&aydCBWD}QiPr&K<=#hfR)7;Vau!KWwthZNa<-jq`-vJkt0X5|?oW`M z$=} zCkn17<8><6b;U_4*P5p$ydl+elDX{818531bhD|-xvO-9rbe2vb^5t-~SE!xUPFI zr&b<5KSTA>a6jcab(v2=v}~*1`59cCEKXv~hj8Nl-No5Na^koV)FfVQHCH=wajqF~u3hVwy1%yDwPcL%aYZfbvC+lp>X+75 z85g{DYVEymRyb!9q@!l}WIZW&%*W;DI_ir|J3@ZcvVAuC<30QjTR+zg)?TkRE+~*8 z|8!ho`#eII>g(r)lkGn<0n>)DoasNeB&zjsX;~?#g=9@*TBq)|(W2Tvxuq_7io;CL@zvdwmDHpLWL}JmAi{`yMS}~SU(4W z6LknmWRk1gUHwvv$}Oo{ynp@|HD0mwC)-cdkx(HE1I{}7&+P-wRbn}_H`<)2Lr@}< zT=moC=MDj9yq^QWi8>N0WTC5mx;S?XIOF{+-emiUIs_#$$yM&I{&Q!QTiRPSwx4gl z+2%wY2^F%?Rqig%T>{P(V>zq9i8=%&GAZygWDQrp)T-9adMm~DOP#maexeT9WMq=7 z++Ccz1)P&(IWxD~oTwwALKeEp-Nm_kz!~pnKX9TBL5WNXI79kR7w7bVGv3d_ZML7N zBcVbTy2{;koncRvN5NYy_WZr6$L2&Gf)bhJDt8y>UIFLIv7CLti8>N0WMRFWxqwr9 z6}5lwm~H!sIs_#$$yGmHe$EIuSBUj9eY?$xIua^mVNgFq(p{YU1f21H_5vsBkWEG= z1)L%6-NiXG;EeaP{SMnt)R9mj3-QsT~p)8@@{b^8W+jH~tYO^@0< zvWe84b~oVJw?_>0@yZIlSkHXb|epju_-0!FWC+c9MA^*sH7ZPO^e|)+B z!QYF1>a{#?zu=E={FHQzZFgxu3y9CXZYBlQ#Wb@iV=Q28brt$MdfG`9qbls-Lm#DEpwz ziCXw-F{kH|C>wt|9e!dyuJ-<;AmjMm;b-${Ck09_(2#)vY_sBLBF+@0Ut{v+JRJvk$K4;Bk1p&v!^W!so(V?dXNM ze3JNf)bUrFAGQ1*iRGB*E)WzJ9bdDtq+nR?vjL@j)^cm~JGKCk^M$yotT)HOcyN15bg z=RJ6hUGm+4tbQMRIllCu+d-3M41{9-OyH&ene0Pt?fSMRKywmA^xB z4gn`>OkIR{8i_Wb>Ql5-F^Q6p#Z zt7t#vd=t;RT<4ods|_&cn|OYQ8ad;%oOiH(4w8Om%{&6KebkaJu{&nJxwt1YkIFZq z<1fr&IWI20XxBsew#;`R<%Gu%^_~|?xl6va?Obc_$H03EeyLVq${qPp%XZi}-f>^X zRX>jjIKP=splap|!0pLA0+No;GuAtwfcQBgUx%N^2Aqr5#<2(oM&w70>&NK@d_UEF z1iTOB^7B_J!{Ozgam$~XyG&&By0k`w1ULM_{2qa26e{?~Q> zeo~Ne{PpBsn3oAP@^zc>W|%HoIPtvzF3yul&i23C{XA;fzC@N2%iYDj&*VVj^xb0W&4R*_$0ENI4_5b^9+(R@wUy0TKFWgoH*Zw zi}Os9vl}>33!g-q6Xv^cah^qT=H9XWL@j(0S$ z1Wwe**|k2$$?o4TAUR8ewx6hxvx)SR-M?Q*a%MlUIZ-2LE6K_3-!CFL2Y?eba+YH_ zUHy{ld~;>Bf#LI%;`T)2{tdOP$3|&K*uS~j(ZxZ=@%>WsKkafyjeNZ^ehMdhymSf4 zSp`ni$T=9p=_+^EbCIj44Gf?66}Kn4^CR0&)UqBMYkrc)b(aPi$CrENW1AB-^5xH1 z!f^#&uPK~Z&t3JiOmg-ECu-zOt;hBASS~Kk%Sg_`zidBIBWIT6WcQnwlblVT*qo@5 zvyJ4$c^X}Q<PcfD<)x7D-N=r_sfE1_BiAZBxm|ln-ev1CdlI@ z_BiB9lCu{$Q6p!DlWj*=lbor~ZBEq4*++7+?dTekvjUu` zk#mUTWUnXxk>qUq!uAt2a;B$5?~mku2VQ4z9e=K&Ho)9BOnzx|qDIa*E&F%Y&ufDW zqyT0SGJ$1k+Z$QoY#|_iLY%=)W}(i;gtG`*Oy%Nb1k(2 zrhei)>Zp-3PS;!R-9d)&^)sjDu$5Y4+u_kqRVsJ{HSF;iJfG*vz#{v8OOKxmU(PW)WRpRyTP2dkeq|SiCXw-acX1B z{Z^8*G_UO^>KdQ6J4#szI~qUoJ3iabM59xf&Jh zc?ae76VO?eKCjZLuTmZUdJ+#(>C;rYzbyFv(*C>{>T`@<-_OfW-}22@=JJ!%D&1e- z&)iRMGV5nmx__)G>1X|2udkAVPxZD5Hs>7^Y)-RYR;7n={zRqw+ZCRs0X?q0dY4{b z((gB%-rahA;mH}!v`P=-4CYrf48w!#zIIlvlvd9MEU04Cyc~TC+VvCl@NF@F%keyp zr*&Qb{Bw|L{P9x9M4J;evSk{4{CO|QnO?}|M2(y|l9Rn2av#ar3!JEtvk=26>sPN@ z$ZAKGYZkKGk!kO5sr0GpOSuE)4cfEB^tF2Z(&xG#kT_kX4{u+&TXg%XT)$AzUKUe% z`R)DSw{*L%nsjMj(%z+hvgb$l2R|&nex{OkxuX_;BzDF4Suf{bNX`myq82`hsY|)z zdDhPdNY1uJY(G&8pTsQ5$=*lkB{`Fe+MK9`PhyeeWbY%)Avt@16SeS3>>)YXaRLvK zocYCUKT!*x#PUYmd#l-T0uPg%iN$SB)WRn*wK2!Zj-S8B@7RcWW4eJ8weU&oOmdv~ z{#Mui{gEK!`2I7ugzYD4;geV-{lw#B7w4lSr?;fdIYJAdiB*!59VhTtlCujqQ3Ixz z+k`83ynp2K^D&aMbt&6V)X3RIa^igi7iS;IIRu=jku$w1=O@0;)W!KY$yrX>exgRs zc9IjHuXJ%fL2|ZCvN=&BXNBZs&pVzZIR}9gHF7p@#+5rhzv=SxDU!3awCyKqi+&Gq{)oE4r?S?5fsd-qTbCPSmiuSn2Z9b-iv6m1Dt+e{W0Y z^0uF-W5HmBde1kX3%(zJT$fqF=0pt`Ui0l-J7Ui_pC>u{ffF@yc3#f)pULCwaT2b6 z{ymbjkhc9qjht-{aDKA;qrZ`yO)J`*sFAbxj>dAnKyvm0Cu-#Ei0MD29kG7CNOE?p zWc!I4Im->^e3|4-uWWOoM$X;_bN++m>;+EL$eGJ>^^-mRtdgAVtJr>`M$Un|8_W3$ z$(dT!=0uI0gJikmJQA+{^Hq|w0-UIkGqnZhXZtZ+KmQuZ**4ks6E$*nR5;GIUvZqT zlbp%bY);h3nI-*X`_I3VoISva8adlYPImwP2FaOkvi(GjoQZq6a!(!0mHV3{XJU1m z6E$)c8|>!*$=MB@sFAaW)vmZoL#_$8ZbTYFI+of@58=Ba<;Bz`-vJk6XbCSzL(0i-+Y(k90E?%$eAHI*>>~+ z$yr|8_7gR74#jZFxO5!v>Kd2+q1pg5E*;0&qDIa*E$1EVdGSAk4CBw=2Vp!gYUD~@ z#q~?<_2iF8&eFPexuZtTJjuz{&yPvYY{uq9jhx*iC+p|GNX`M^M2(zYS7Xb4h~zA; zXZwj7Im->^{FLNuUf**$teiku%-Rl{f4F_t( zP29}+$v%IyJjq$y)-HF{$eAHI+2@Z|AUT`2vpG>CXMyBopFc{IoK@gNjhuZXC;J}8 zkAkO|WI<8~8EFnc3dvM2(zPl9PRJ;J--De&9rnoP~2aKiT(M zenN5oor6j$eAofm%DJX$H||OoavoyPSnVmCpp>UrO!#uUf@KH zoZTcRdtUqn$=SY(?I&vF^v>tXo#p(JsYx~Vk+fP?Jnx8E9ruFstuxu~4hwZPVODx5dd%c|FNzSf4feW<&nmEv4 z&ILxvIf5HFlNU#~Bk_}+M`A_te6w{g+fUSh>7{SsIN5$_0_kVd&uq>i;6~1-hdEAm z9*LDmKg)aDoT!nro%EBPM`C4?vn6M9qDIaN$;r+mu?opK2%M;qGu=Vn-z2Zstx9s1 zX4rnBM$YD2x%$bTA2pGj*?nwI)X3R%8^_6>7q3oo4ge==1TCc+fUTUmFnT@Cwo14Et0eIyEZ3k z|I>_Wc#JffK#@EG0|poqQ>=$Bqux0O3$7ie|^3i zI8h^K56Q{Sdypml%pGd`i5fXOAL7cL9S^o8$>|+tbB@pe+D&q@<-Qfk*#(@a0n_uy z>vgRsa@W1LCOKPwVEc(0Ijg5|*O%D&1hyeLhkz3`at@MyviG^RB{|E7+kT=(&fKY- zpKN>Ij^u1P!sbMcoI@lh+umD9&OzWrjhq9gaelJxeS4C#^h4WE)X156l^#!;6E$+?ALIOFId>&FGe5C8Q6r~!Hs>dM z{=OT@*$No`6;fwvwrSD`k6k;=0uI0<-W#nrXJDxOeFn8j$Yu# z1P*|J8I-ip0R{} zuP81sTAq`_`w^~jLHj5_nQ_#39|W}n$C)hSg4pwp#YjJg;C>Bi1S*i%mvFqd>v(A< zSwG9aw%ZMAD+TR+oVQRm`n|vdhO=DJyrLzadZYLm zcN`-5?nnAr{Eh7=YROOH!0)2_dEsQ+(f3Hs=96qr)WRpRyTRx0%aZ+krqkxcd5?up zVq#i&dvAM2r;DF#JIa%OcAji=q82`hO;3k&%5vdk>*sQH`dKyQKUzPF;3vzuKj~*b zlsjtiNn*$4(dQjYnH3AawaZDqk8%0HPtTi6E%5i7@;!;New=Ro_2~ASte*#vem0$A z|8CUsdn68$e#-iBaRu(oc3iz$HjO zQ@^u0Q6p!Sybi|J&+n6dCW|&_1-Oy3rJt*xZ2!3=>1W#+HYaN29J-*f_4ANX`icG` zXNmNa9Z$Oy>1Pj=J8I+{xRCRcy*_^^>1X~-yWCMDXa93t{ba}erbs^%XW5*nk+bKL z#`<{}>1Q`^qDId2o1C9)x&MIV%$;rfi5fZENltd0)!`(k_j{Xjga*(G$;s}IjvzU^ zfD<)fdabu|^^?6`*G_V_o@4uo8ac~varKjZ{^-Xf=MZqBM$XjR94Gty(UBx)`CQvi z)W}&RIoaorenN7#oM&^QM$W`LoS*D`fIlTU2Z0kcau!HVeE!#U-TP-GXQ^cSi5fY3 zZsXcJJ3qtENzUx~HYaN2tdg8;dq0}w8~{$#$m#uqtDkIp{{_ieyukJoHF9>4oNRml zCCS-*q0NaJIR{Bj_Ppa5lCuh&sFAbheXiVD&R>z7ofp}DqDIcX!D!ClJ@vu1?Qgp7 z%WR`o%X-Vl-j~T-Y;&Tvw-&GDIs@xxf%LN+>AkK>ele@(Wd^kp^|YROMx^25gXDft~wa`plzYROMx zC&|e^k8lFX*?zh0Cu-r7*xz8z6G_h0ESnRx@JVd_Cs*#QpT8kFE5M0b_#_VXG^icz zs@wZ9WP5K}!XB^Kc7^S)@JURr!*Q~Ho<#bY{DaMfTKFWUK5A^apG;_KM!Y8qhm!v2FZ!fA7pNf=8StD!M{%H&*zVy%yo+g z&kMA#W{+>)Tdi2|RtuK-YJ~v+}6T)f>k-t}*p<$n1~SBRMl0*qrUR*&6$!;?<4WzbBW_ zzjqqRnO?}|O7++pIdjuE&bV?o%02ErSH*CyO>z!oY|ggX zwnjg_F3!)`{?nBEMkFWpOUc`#IUCh4WtY7|ymexpI&5vuR14&&DKY z>tc34pT8s8&!M#%!`W&$HyI^o;?DmJXTtQK>yVsy9MT=b*{I`?jNx2&l$^P{qWxq! z+3Skuljm{X-N1z!I;PGqxPFPfFLMFO*#%sv0n_uo*vL!pQU^4`iUC(vR_5F zcX@sjzvt4EgZlZ+^P8^qviI4XsJl-X-SeBQpO=t+4ge=={C(91`?(tFXYqd9Pt+|Z ze!G5NO8VLS7n>6``kDJWx_(MKV(%ZF8f+kbzVs?^qDIc{bve$s{ifu*aZv8@oVefY zf5G-w@{{P=Z;tl4@-kWOnFnny)WRpR@CbK2A9q~WZ07T6BK_?7Qjf1|nxlF9fm`?_ zwoGYkxnD;5S?IO>L@j(0(_Ul!T)j>|g=4gS_Kb4ggUd-j`%HNYCu&KT*iQNx*WTqg zc@5G}nKz>MVO{4t;`T>z*X!hW zUrG9zG<@(x*r|CkEW2EgQmQz&ud>r3pd6B*^Z?D zl<&Kqf4`0__tLX=xucftNbG!(D|hxdWP>{WEIy}sv+z8p@JVF-jJy9X`CU)?iO-p$ zmi#2L&zZ7*P9^=6dMO;E^%IZl*yH3INIyIOX4lVV)1HJIV>Z#4`YHKtI7&Z9+urfI zBI{@ODE&l#<#$VLBmM0B$bQb&)i3=%$TWJke%eJ4WB|nM9&+Ku~k}i?0pR)cfBxky6bE1~~B<3e@<<8#Uyp`na z1y0n$C$ZXKKYK{d_E&5_Q462Mjs-bC+5ORMk~8(H&52t0BxWaaoNT$@PI6X&6SeS3 zEPUSBc60~H+4h?4Cu-r7SXijBe%?iLCSSKXQ462M^cS3;Y`Nb}a`pfxYT=WZOg7ff z3dx!OyX_}x;geV){bct?eF65zbGR^Inp(8#qx5pTy##(VXLDMTpf0 z^mWJ~6J_!0>W{RymZ$DJ1@n6+&3$%RE;09}?I&tkkBzc_XWP+zq@Uh^%{f8?V5fN= z2a;=2INANtUr5d_;6z;mFn+NUXpVN zI8h@7s>`E%zIOFUFs5mfyDhL@nEwn2XuJFCr_NSlrsaj|+>vO@s3|FDvu; z<8sk0?`Y0J6GhAY4%tqj61_diZxQQmlBBxhX24l`*Y-`mDSV>;T}~ONiutz7S>$>b|htr~ptv-Yq!7rbhZ zP|ix%9-*AoAblj~{8#IIQZLRMa7y&9*(2ceyN}@aF0!=#y(V4wBuaZ{=Xt(8_*L=k zz4#Bi-lEp-eDiN#Ona9#^RxB@KlgO_xu?TVKRwJ(olpPHy4)pt*X-%=Q>TlM5^J0{ z*_@}{7S5TS9nP5#(noThs?z=X*}se7G|{`m!D-TkPhyR8%3hYAk4)Pu)X&03dxiR0 z4$?<*KC04v&eChTeo8ECvR9~|Ws@#^5^J2(XIPx?9ylYEvwZN3P|iw_K9ciel^$^J zrTr|KSZ+ucQs}Bh{RX?$T-%s2!`w-1}s`0_Z!kveN z`gyrZ_jyuR>;6{a7P@kKQ62EX)3+8UG)Hg|BOpTr7xyp>V$cM{!!v9W_{`B z^Je|@zDGoIW>sEhf0R~#2HW#_ye;?Z@Pqe}o}tv|m{!L)Q|Chm!H0bpWygpReC*~{U4_SPKkd0LAg&i`yCVg^m&7=t3QT) zkh8Qr$C+Pwyl`gx><*tiUi$<4_jJ?vpneLU#B7l6dGo06`t|#R=d}NasPupz_M7?D z$Jff&-`XG?Y;SSywBh!loL=+x0cYwN z{e6k)AYJXppVa9Rw^Qjsxo1p2Z(??%?E_A~U-CcmzNG7C-lWg3(tOTC|7Pm#s=A%! zx85b-RPAsB|9gvXyGxLN|37s85-Tmc1f2fqho8@{O#ZK`^j4MTw_`s&HC2BvyZtV@ z|AgOFQ0dYy`Rk`m|5;Y)OQ<}M(@*n1?D_i~AB32XI{B%6{E6DnW%#En6@7iFX?^48 z%DdP6^nc%5lXutUwUH?=6SGab2Y$+aMD|BNRq1~D_IK;{BGFrO_rTBo)AasG;&)W~ z@cm}WIf$mh*9vv;4K~Cu-r7SZU_`WXt^tlC#CLpGQC~d=i^i z;rwJdpCma4ffKdxN$l93^OG(2r%2AyINMLu!Y8p~RnAYA^J$VZJD1IgTKFV(@6y=& z#m|tO1Hg$|_#~!xZ!G7tBxiAM+fUTOCo#8LW6Qmtua#>`vjn*Y-^ zPIVKtfrPh=`d{CF$L)#k2Ts(o9vj6^c7OB&>1Sbn+fURipR6aGY&&|9EX$;rMS;dPR;eS+;LYT>Izavojw{Rn?2Ia3SToTzJj=8qB-`yPikNzNYNM2(ysBq!U?50IQVUuAw_+h62l=YeE7-x?(+awF$pgZ+G)b_ejnz;6x3W zUXJ8s+tK?ZC(iea8adhde%WzWgCyq=%u9?KIosFft~0QHen4{KdjrdhLwyBM_Pv2D z=ZB-@L~g+Jn#uPYvYa20oP+QlM%2jJ+u--EeoS(fmbA+mHF6d+T>WIvk3JzevrE~W zsFAa4pXlRHIj)N<_w*$Fd$$a3?8hG`CyVxdgaP12&X)ehaORfNoI8`8?WfzE#gy$Y za`rvTamHP@89YvN?m}|nb(-c$(VWPQnl1N=Dfg{OPAvCo3@2Oeaek%>+Rt4{PV}>L z>BjiUw)g&^K;qj`W*M6cHI{2-w)O$jMN7HI`PqMh&Zm|16X!?o2X5JZEym18Eu3-v zQr?V<*oNe6KhSRPg=KAjYkcO9{2h&H@2w|lKX)TJaenls<)S&`=1UhpVQ5=-lAA4Fr6eu=#= z^BKvRSk>l4jT{w{bLc(0ed2xX?A?02!GdJD=NGfvQ8#cSXL%#e&$#-ToTWJvBxmX% zn=?1r_7^$3$>X}_eeHbF&!X{jBFULp+|JKiEt)g6G3V#N#nI(HaEJDDJjt0{)aLAp z;Vj17=aP05cR#NCPR+Rh$%*&hTAQN%jJqEvoW&2L{Vd$0ITt25y(MiwhhjLZWVshF ziRSFMOLI;jIeVbo%d1EG*+Z5)j!VaO)MxxmlAK-OXUiJVoViW7cEpZfdMW5o;?Lg) zfeSVEOS!u^&bZ?x$#;}E=6)yffIF&&-~GPBX@m?t)I)1oSp01exgRs9`gMNte>X^8;I{eGZ~u`HFC1& zo4F&nb~G-S=Omu9A2?AXXW~Mx+}U&Z*!tX&dNoc zpK-^@lJ8`)9rXbxYROMx=dB!P(=4ujo)=^sUq3sh*nXlGK8b8QiaY+4{M74e)F+-Z zy@Ab%TJn?FPx={m-XZyANX}m1L@oJAEX?N0J#HTI&ThS5%ai-}mPz(;UHeqqU*VHj z*_7LF#+|=chjc!NlbrY-jMRqFoa}os*#2`1vfL}cg<5=+*!&Pz?s3VQ63Y)qb1vXNg{rpQajIRPT;o(%R{gvhr&@@6ZwtP^7vDcyIG&roOn!%)zsJ?j zfpc~JoI%!4yuQ@aZ2K$Qm&jgUisLLjt2qxOIq`aOexqnk_Ih$$ztnM+=G=$mY(2-W zM~RK2Im>TF*H0<;IL@-+oH9)BK4_MctAg<9IV#5VKZcF`E6e#Tw5$y}}d+>i7V$N9Ey7VT%F#{K5r*PI8D zoXy>K{Tzzn9Qd4T?{R*189%>Aa-yH*%^TxqTs!JE$94OYoOoQiHag>8Gob0&Dxcz2&P}k3cNzMw~KPqLT{q*kS>SydY>JK&N_eoA1H=W%wnv)$z z9mm;piT=HZjFNMpL7Z{dms*XVZ6qhY&#<^vw4ZVBiy zpX&N~1j&i#an%@3_B<|*bMO<*dDtj9JHHd{XQMb%=Dhd^qvXtN^Pl1DGUfgwk`v#% z*dN2mzK1bxzuEqoF86kl6W_yD*f!cv_PuOz{ihrc{*XNWY}(G|LM{18>>S|sM{)g< z>X^A00<>_5vqr;gi_@0mm74{8`yqk7wv0+dICup?wG2U*VI;zQ=*}^Y^5msU2-D z)WRn*@mXX1>@@F#XeRx{c_S*oEqoH==8^E{RS72TlrNa*dLPQJ>bhduTcq|r6!=~?Q(F& zz5ku<=hso3%>7MoH@lp(+t}B|gjZslW84M49~SF5j<1vat|j+JUBHQ2@{`z2z6YG0 zH|FagJl*yaHF8!K zh~|{_t9y?hH~c*~g?+}43*I|0_vQiFLHQSgp0ljd{r3*Y{P+^@SLyzo#r`sXKI^VE z%{LI{+n1fTLhjGqP z>Hc>8d42rtwjZsx>m44>nO5l*=gNBhtV)mMd=NMv3g_%n=~ER;?z?&(Z;6$M_4=jH z^?MT}eyGxY9{-&aK7aGgdj9C_Up0@Uzx#&vEpO7%PiaT&eeK(VS`gpfvwPX~6Scy& zK20(2GnJLAt1V#F&+-}zgx1eFDn0P?0OO~L-dcKn@loOwmG1lL*LB~|R^w-RodtsO zML#Ph9sR6vo@{fbPYvhHs&v18roPhUEAdd3KD>SwO#LjMrq>tFE#K7TTT$u5>u1W; z&#Fp~teUm89%H4u>Jgz;rHH;;oNS5RqojxCxn*! zp(;JB+{-)Z^`*QeKB>}&mwQ3l(XJD$au?3LNq3g}RW@h(kHBdvNLHnXmHSUr`f#3- z_;#IMU&{S{@$GuOzVNh~{xhx8Bg_4&1uZ|*e_Sxs&lZ&)TJG2C^~FbtXQ}kz<=#1< z`=#pj3tE0Q4VeD?2AwYaBl`KhC)%7dCx&uvuhPTHy|AxdU-%^6q|%4`JY;-Me{W(a zXV#=UIj^!gE7t(0Dfg;M4=eY@{%G?gZ_&OLuG8yFxxZn2E30&$UwB$fd#|YUuyXg) z{14mD-|1&ej00@i*Y4+0`?(DN48^>^Sk|o`wUAZrP zuP^0(hT*BG^x@^6lYU;Mhn2f*zWS!knSKX2&2e2;rTg_$wtKhP?x8B(->w`lRSz@A zY46(W*Em)BaLzX2ROw-y^`38TF*i5AqMTn2o}|xn z-R0nPoxl6pa_sQ0$C?Qe6UHrdre z-0!HD^E<+sj^<1rpg9W*>)$WB1_pn`an`#(x}V%1^%zdUK`rSLhZc)IFRqvKL6S3n zpk3~$g->GdlF^*9UVbtAJ)vtY75<*kYAXCaq28qM_n9`S^r>ni^4>U!*`>qZ6Ph>a z@*XLPHO{$b*4}sKpKm=f|I8qNdC#uI!uXlNd#`e*>-ShmEC=b|9RJAsb{|#gK4)r% zet(w4!i1TgUzYMdONnKZF7MrxSZ}{{7}+o74z|l3wfKWk`lX8LpK$q@9&=#KfiVZh z92j$8%z-fn#vJ(Ha-dSR&sXKwcfF<43$N&yeO1SH6JNF}PJ}v@9Rzf4txy|64}*f2sS!zV!d_*U(w&1oMSp zVUXgl75q0&HX3}*|Bm_YIF*}hAV}3;@zdrCVAUUHL%{~ejhowFLm|l8WA7&9_sj)8`+bPNUh1Vu!8rbMkghueKV9y_&r#{YefT}heRvbod+U6} zx6~p_2l?!v(t~m_>y=C_=W@XqcYm0QpMTD5x2n>I`=6Swx8uzSUq7qT{q=>vWY*8C zbbnj`ehMaC)=#})ey?MF{66Z!Hpfbx$oRj*+x}SPr~1Hi6|1TAz_%~w@n>@LQYL11 zI98397{>pc<~dQNPgCjsm_0w=%!;~PvpXKE>i#$DzxA@N&!?;OsVco>@|Bq1S?7;F zU#`;q{3TsYBNcF^chUJvx|GY2D&5aN^_Af_vC?{MsL#Fyjr_2dv@?)Hro2l2A_>f8u zeE8h>VB(f<>-=l=-+b>%mG0*+{fwGsDDe5RcXa;f^YWfo@bk~j()<$tJb0Y9luF0X zsvqe5{bzgpdeUR^ud4L0`j6j7UHBM$p05z@vq}&3dHzDU&nkVm&lSVDf1(iXvq}&3 zc>$gO2%lB@aG$fLy<9dy=Rd;d1$F-Y#%GD+l7T_4`Z{^E15w3kH+b@|*eS(ks| zmJ@zRr%z-fn{(p5KEkEpAx*xAP>)<%# z|9mt)h#%k9xPkwce5G29`C;lW)Q@j#yvKh_zF0s0&$sVyyB~u3@!!(Uzb#IzAO9`& z`rG0}Kbqdw^PByzM)YH>|Im)4jWOR=J^XLU7wbp&Te`jcuSWEv_>T7De>I{XJ;sm! z)hK=xmechjf5L9Tv-awGWN_VY<=^k-cd@~hUH^JoX{x?%c7Krm&2|3%X*&I+b9PhL z<!~96k4)^0Al^*7YcYC-WX_GEKNEAOL7FInvs2@rP_c=~m<7mybs`-5; zrq?<;xGpT$!Am>p>!?|k?w5t6ziI9d9iY;K-*=%YZxbsj-M=>>_rv6V(yNa3vuhvi zWz_mu-g%Yo=ih&Ush1`eRJxxxu3uK^e!Y?Hrk2qBDrxL9=D?T(V-ActFy_FR17i-1 zIWXqHm;+-Dj5#po!2hHJKU62^yQu+J8>>Nzv(z|c|Ffh&084$;FgMRn^3UP@v7-L@ zw14jJeIdDmi05spE*$vJ^lzvB_kXhg`$*d(W|0AhEt87^eXiHpM2C8bMDoto;T6YKz$O+zjXCa zSG{TLV_$mes;^dB?`)mwd6UfYC*NN0lr#4_{+fRswBMf(oAc?JvV3X3aMWj&@{2Y#HHJ-PRZA)V@ZD~#8FUHIx&8@%%LbInhzu*t;2pI)0O%O{%xyyd8$o&V_m z`zG!?t7*ZFFHW5%%cuGUu0EeEI`o&RQ#M`oR|nko@=F)q{)JBUys0bczy6ikap@x- zd*JRje|W)e^K8;ul;s;4{vYoC>mz?~%bfSBZ+v{#HP6oMl;xY6{AX|c{`EhY^YJgg zx7!~UJO8qlXJmPc;Tzhg{L_6mzhvV2pB?nG%x`b}ptgJ&{nx;{_sn_g@U3s(=ZmXm z|KSH~?jg&M^ee6U%shUP7k+>5xYMrx^t?^h+v2$$bgJhaZF2hX$J37a;g5f_*MvJN zx8Hl`QJ=~3g4zBZ$9#YCxwoIU!@RTpwb@D=Ebd>13O*blh+DW9$56r@_tke&ofwA1$orSE1l@yUG8C!Pm0`H|FPC=h$6O z`teJ%I%N61rk;H~<*?b;W^UNz_&I+&{<-sa_(YaJYkuEukDq$ZN88=E)utyt(L3?( z2ficA`~8ZoJ`?w!dGC>>7Y;1lx5VmgOP+VJPW8O!{Q>;yv**hP?y>JR3tqb3Rc+%= qzjm!(=v2@9(68L;^M3D=yPmWAMd#jr#uaz1`{o;_)buj>_x}M&@i9LD literal 0 HcmV?d00001 diff --git a/tests/regression/flash_attention/half.hpp b/tests/regression/flash_attention/half.hpp new file mode 100644 index 00000000..debe094f --- /dev/null +++ b/tests/regression/flash_attention/half.hpp @@ -0,0 +1,4018 @@ +// half - IEEE 754-based half-precision floating-point library. +// +// Copyright (c) 2012-2019 Christian Rau +// Copyright (c) 2020 0xBYTESHIFT +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +/// \file +/// Main header file for half-precision functionality. + +#pragma once + +#define HALF_TWOS_COMPLEMENT_INT 1 + +// any error throwing C++ exceptions? +#if defined(HALF_ERRHANDLING_THROW_INVALID) || defined(HALF_ERRHANDLING_THROW_DIVBYZERO) || defined(HALF_ERRHANDLING_THROW_OVERFLOW) || defined(HALF_ERRHANDLING_THROW_UNDERFLOW) || defined(HALF_ERRHANDLING_THROW_INEXACT) +#define HALF_ERRHANDLING_THROWS 1 +#endif + +// any error handling enabled? +#define HALF_ERRHANDLING (HALF_ERRHANDLING_FLAGS||HALF_ERRHANDLING_ERRNO||HALF_ERRHANDLING_FENV||HALF_ERRHANDLING_THROWS) + +#if HALF_ERRHANDLING + #define HALF_UNUSED_NOERR(name) name +#else + #define HALF_UNUSED_NOERR(name) +#endif + +// support constexpr +#if HALF_ERRHANDLING + #define constexpr_NOERR +#else + #define constexpr_NOERR constexpr +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if HALF_ERRHANDLING_ERRNO + #include +#endif +#include +#include + +#ifndef HALF_ENABLE_F16C_INTRINSICS + /// Enable F16C intruction set intrinsics. + /// Defining this to 1 enables the use of [F16C compiler intrinsics](https://en.wikipedia.org/wiki/F16C) for converting between + /// half-precision and single-precision values which may result in improved performance. This will not perform additional checks + /// for support of the F16C instruction set, so an appropriate target platform is required when enabling this feature. + /// + /// Unless predefined it will be enabled automatically when the `__F16C__` symbol is defined, which some compilers do on supporting platforms. + #define HALF_ENABLE_F16C_INTRINSICS __F16C__ +#endif + +#if HALF_ENABLE_F16C_INTRINSICS + #include +#endif + +#ifndef HALF_ERRHANDLING_OVERFLOW_TO_INEXACT +/// Raise INEXACT exception on overflow. +/// Defining this to 1 (default) causes overflow errors to automatically raise inexact exceptions in addition. +/// These will be raised after any possible handling of the underflow exception. +#define HALF_ERRHANDLING_OVERFLOW_TO_INEXACT 1 +#endif + +#ifndef HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT +/// Raise INEXACT exception on underflow. +/// Defining this to 1 (default) causes underflow errors to automatically raise inexact exceptions in addition. +/// These will be raised after any possible handling of the underflow exception. +/// +/// **Note:** This will actually cause underflow (and the accompanying inexact) exceptions to be raised *only* when the result +/// is inexact, while if disabled bare underflow errors will be raised for *any* (possibly exact) subnormal result. +#define HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT 1 +#endif + +/// Default rounding mode. +/// This specifies the rounding mode used for all conversions between [half](\ref half_float::half)s and more precise types +/// (unless using half_cast() and specifying the rounding mode directly) as well as in arithmetic operations and mathematical +/// functions. It can be redefined (before including half.hpp) to one of the standard rounding modes using their respective +/// constants or the equivalent values of +/// [std::float_round_style](https://en.cppreference.com/w/cpp/types/numeric_limits/float_round_style): +/// +/// `std::float_round_style` | value | rounding +/// ---------------------------------|-------|------------------------- +/// `std::round_indeterminate` | -1 | fastest +/// `std::round_toward_zero` | 0 | toward zero +/// `std::round_to_nearest` | 1 | to nearest (default) +/// `std::round_toward_infinity` | 2 | toward positive infinity +/// `std::round_toward_neg_infinity` | 3 | toward negative infinity +/// +/// By default this is set to `1` (`std::round_to_nearest`), which rounds results to the nearest representable value. It can even +/// be set to [std::numeric_limits::round_style](https://en.cppreference.com/w/cpp/types/numeric_limits/round_style) to synchronize +/// the rounding mode with that of the built-in single-precision implementation (which is likely `std::round_to_nearest`, though). +#ifndef HALF_ROUND_STYLE + #define HALF_ROUND_STYLE 1 // = std::round_to_nearest +#endif + +/// Value signaling overflow. +/// In correspondence with `HUGE_VAL[F|L]` from `` this symbol expands to a positive value signaling the overflow of an +/// operation, in particular it just evaluates to positive infinity. +/// +/// **See also:** Documentation for [HUGE_VAL](https://en.cppreference.com/w/cpp/numeric/math/HUGE_VAL) +#define HUGE_VALH std::numeric_limits::infinity() + +/// Fast half-precision fma function. +/// This symbol is defined if the fma() function generally executes as fast as, or faster than, a separate +/// half-precision multiplication followed by an addition, which is always the case. +/// +/// **See also:** Documentation for [FP_FAST_FMA](https://en.cppreference.com/w/cpp/numeric/math/fma) +#define FP_FAST_FMAH 1 + +/// Half rounding mode. +/// In correspondence with `FLT_ROUNDS` from `` this symbol expands to the rounding mode used for +/// half-precision operations. It is an alias for [HALF_ROUND_STYLE](\ref HALF_ROUND_STYLE). +/// +/// **See also:** Documentation for [FLT_ROUNDS](https://en.cppreference.com/w/cpp/types/climits/FLT_ROUNDS) +#define HLF_ROUNDS HALF_ROUND_STYLE + +#ifndef FP_ILOGB0 + #define FP_ILOGB0 INT_MIN +#endif +#ifndef FP_ILOGBNAN + #define FP_ILOGBNAN INT_MAX +#endif +#ifndef FP_SUBNORMAL + #define FP_SUBNORMAL 0 +#endif +#ifndef FP_ZERO + #define FP_ZERO 1 +#endif +#ifndef FP_NAN + #define FP_NAN 2 +#endif +#ifndef FP_INFINITE + #define FP_INFINITE 3 +#endif +#ifndef FP_NORMAL + #define FP_NORMAL 4 +#endif + +#if !defined(FE_ALL_EXCEPT) + #define FE_INVALID 0x10 + #define FE_DIVBYZERO 0x08 + #define FE_OVERFLOW 0x04 + #define FE_UNDERFLOW 0x02 + #define FE_INEXACT 0x01 + #define FE_ALL_EXCEPT (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT) +#endif + + +/// Main namespace for half-precision functionality. +/// This namespace contains all the functionality provided by the library. +namespace half_float { + class half; + + /// Library-defined half-precision literals. + /// Import this namespace to enable half-precision floating-point literals: + /// ~~~~{.cpp} + /// using namespace half_float::literal; + /// half_float::half = 4.2_h; + /// ~~~~ + namespace literal { + half operator "" _h(long double); + } + + /// \internal + /// \brief Implementation details. + namespace detail { + /// Conditional type. + template struct conditional : std::conditional {}; + + /// Helper for tag dispatching. + template struct bool_type : std::integral_constant {}; + using std::true_type; + using std::false_type; + + /// Type traits for floating-point types. + template struct is_float : std::is_floating_point {}; + + /// Type traits for floating-point bits. + template struct bits { using type = unsigned char; }; + template struct bits : bits {}; + template struct bits : bits {}; + template struct bits : bits {}; + + /// Unsigned integer of (at least) 16 bits width. + using uint16 = std::uint_least16_t; + + /// Fastest unsigned integer of (at least) 32 bits width. + using uint32 = std::uint_fast32_t; + + /// Fastest signed integer of (at least) 32 bits width. + using int32 = std::int_fast32_t; + + /// Unsigned integer of (at least) 32 bits width. + template<> struct bits { using type = std::uint_least32_t; }; + + /// Unsigned integer of (at least) 64 bits width. + template<> struct bits { using type = std::uint_least64_t; }; + template using bits_t = typename bits::type; + + #ifdef HALF_ARITHMETIC_TYPE + /// Type to use for arithmetic computations and mathematic functions internally. + typedef HALF_ARITHMETIC_TYPE internal_t; + #endif + + /// Tag type for binary construction. + struct binary_t {}; + + /// Tag for binary construction. + constexpr binary_t binary = binary_t(); + + /// \name Implementation defined classification and arithmetic + /// \{ + + /// Check for infinity. + /// \tparam T argument type (builtin floating-point type) + /// \param arg value to query + /// \retval true if infinity + /// \retval false else + template bool builtin_isinf(T arg) { return std::isinf(arg); } + + /// Check for NaN. + /// \tparam T argument type (builtin floating-point type) + /// \param arg value to query + /// \retval true if not a number + /// \retval false else + template bool builtin_isnan(T arg) { return std::isnan(arg); } + + /// Check sign. + /// \tparam T argument type (builtin floating-point type) + /// \param arg value to query + /// \retval true if signbit set + /// \retval false else + template bool builtin_signbit(T arg) { return std::signbit(arg); } + + /// Platform-independent sign mask. + /// \param arg integer value in two's complement + /// \retval -1 if \a arg negative + /// \retval 0 if \a arg positive + inline uint32 sign_mask(uint32 arg) { + static const int N = std::numeric_limits::digits - 1; + #if HALF_TWOS_COMPLEMENT_INT + return static_cast(arg) >> N; + #else + return -((arg>>N)&1); + #endif + } + + /// Platform-independent arithmetic right shift. + /// \param arg integer value in two's complement + /// \param i shift amount (at most 31) + /// \return \a arg right shifted for \a i bits with possible sign extension + inline uint32 arithmetic_shift(uint32 arg, int i) { + #if HALF_TWOS_COMPLEMENT_INT + return static_cast(arg) >> i; + #else + return static_cast(arg)/(static_cast(1)<>(std::numeric_limits::digits-1))&1); + #endif + } + + /// \} + /// \name Error handling + /// \{ + + /// Internal exception flags. + /// \return reference to global exception flags + inline int& errflags() { thread_local int flags = 0; return flags; } + + /// Raise floating-point exception. + /// \param flags exceptions to raise + /// \param cond condition to raise exceptions for + inline void raise(int HALF_UNUSED_NOERR(flags), bool HALF_UNUSED_NOERR(cond) = true) { + #if HALF_ERRHANDLING + if(!cond) + return; + #if HALF_ERRHANDLING_FLAGS + errflags() |= flags; + #endif + #if HALF_ERRHANDLING_ERRNO + if(flags & FE_INVALID) + errno = EDOM; + else if(flags & (FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW)) + errno = ERANGE; + #endif + #if HALF_ERRHANDLING_FENV + std::feraiseexcept(flags); + #endif + #ifdef HALF_ERRHANDLING_THROW_INVALID + if(flags & FE_INVALID) + throw std::domain_error(HALF_ERRHANDLING_THROW_INVALID); + #endif + #ifdef HALF_ERRHANDLING_THROW_DIVBYZERO + if(flags & FE_DIVBYZERO) + throw std::domain_error(HALF_ERRHANDLING_THROW_DIVBYZERO); + #endif + #ifdef HALF_ERRHANDLING_THROW_OVERFLOW + if(flags & FE_OVERFLOW) + throw std::overflow_error(HALF_ERRHANDLING_THROW_OVERFLOW); + #endif + #ifdef HALF_ERRHANDLING_THROW_UNDERFLOW + if(flags & FE_UNDERFLOW) + throw std::underflow_error(HALF_ERRHANDLING_THROW_UNDERFLOW); + #endif + #ifdef HALF_ERRHANDLING_THROW_INEXACT + if(flags & FE_INEXACT) + throw std::range_error(HALF_ERRHANDLING_THROW_INEXACT); + #endif + #if HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT + if((flags & FE_UNDERFLOW) && !(flags & FE_INEXACT)) + raise(FE_INEXACT); + #endif + #if HALF_ERRHANDLING_OVERFLOW_TO_INEXACT + if((flags & FE_OVERFLOW) && !(flags & FE_INEXACT)) + raise(FE_INEXACT); + #endif + #endif + } + + /// Check and signal for any NaN. + /// \param x first half-precision value to check + /// \param y second half-precision value to check + /// \retval true if either \a x or \a y is NaN + /// \retval false else + /// \exception FE_INVALID if \a x or \a y is NaN + inline constexpr_NOERR bool compsignal(unsigned int x, unsigned int y) { + #if HALF_ERRHANDLING + raise(FE_INVALID, (x&0x7FFF)>0x7C00 || (y&0x7FFF)>0x7C00); + #endif + return (x&0x7FFF) > 0x7C00 || (y&0x7FFF) > 0x7C00; + } + + /// Signal and silence signaling NaN. + /// \param nan half-precision NaN value + /// \return quiet NaN + /// \exception FE_INVALID if \a nan is signaling NaN + inline constexpr_NOERR unsigned int signal(unsigned int nan) { + #if HALF_ERRHANDLING + raise(FE_INVALID, !(nan&0x200)); + #endif + return nan | 0x200; + } + + /// Signal and silence signaling NaNs. + /// \param x first half-precision value to check + /// \param y second half-precision value to check + /// \return quiet NaN + /// \exception FE_INVALID if \a x or \a y is signaling NaN + inline constexpr_NOERR unsigned int signal(unsigned int x, unsigned int y) { + #if HALF_ERRHANDLING + raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200))); + #endif + return ((x&0x7FFF)>0x7C00) ? (x|0x200) : (y|0x200); + } + + /// Signal and silence signaling NaNs. + /// \param x first half-precision value to check + /// \param y second half-precision value to check + /// \param z third half-precision value to check + /// \return quiet NaN + /// \exception FE_INVALID if \a x, \a y or \a z is signaling NaN + inline constexpr_NOERR unsigned int signal(unsigned int x, unsigned int y, unsigned int z) { + #if HALF_ERRHANDLING + raise(FE_INVALID, ((x&0x7FFF)>0x7C00 && !(x&0x200)) || ((y&0x7FFF)>0x7C00 && !(y&0x200)) || ((z&0x7FFF)>0x7C00 && !(z&0x200))); + #endif + return ((x&0x7FFF)>0x7C00) ? (x|0x200) : ((y&0x7FFF)>0x7C00) ? (y|0x200) : (z|0x200); + } + + /// Select value or signaling NaN. + /// \param x preferred half-precision value + /// \param y ignored half-precision value except for signaling NaN + /// \return \a y if signaling NaN, \a x otherwise + /// \exception FE_INVALID if \a y is signaling NaN + inline constexpr_NOERR unsigned int select(unsigned int x, unsigned int HALF_UNUSED_NOERR(y)) { + #if HALF_ERRHANDLING + return (((y&0x7FFF)>0x7C00) && !(y&0x200)) ? signal(y) : x; + #else + return x; + #endif + } + + /// Raise domain error and return NaN. + /// return quiet NaN + /// \exception FE_INVALID + inline constexpr_NOERR unsigned int invalid() { + #if HALF_ERRHANDLING + raise(FE_INVALID); + #endif + return 0x7FFF; + } + + /// Raise pole error and return infinity. + /// \param sign half-precision value with sign bit only + /// \return half-precision infinity with sign of \a sign + /// \exception FE_DIVBYZERO + inline constexpr_NOERR unsigned int pole(unsigned int sign = 0) { + #if HALF_ERRHANDLING + raise(FE_DIVBYZERO); + #endif + return sign | 0x7C00; + } + + /// Check value for underflow. + /// \param arg non-zero half-precision value to check + /// \return \a arg + /// \exception FE_UNDERFLOW if arg is subnormal + inline constexpr_NOERR unsigned int check_underflow(unsigned int arg) { + #if HALF_ERRHANDLING && !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT + raise(FE_UNDERFLOW, !(arg&0x7C00)); + #endif + return arg; + } + + /// \} + /// \name Conversion and rounding + /// \{ + + /// Half-precision overflow. + /// \tparam R rounding mode to use + /// \param sign half-precision value with sign bit only + /// \return rounded overflowing half-precision value + /// \exception FE_OVERFLOW + template constexpr_NOERR unsigned int overflow(unsigned int sign = 0) { + #if HALF_ERRHANDLING + raise(FE_OVERFLOW); + #endif + return (R==std::round_toward_infinity) ? (sign+0x7C00-(sign>>15)) : + (R==std::round_toward_neg_infinity) ? (sign+0x7BFF+(sign>>15)) : + (R==std::round_toward_zero) ? (sign|0x7BFF) : + (sign|0x7C00); + } + + /// Half-precision underflow. + /// \tparam R rounding mode to use + /// \param sign half-precision value with sign bit only + /// \return rounded underflowing half-precision value + /// \exception FE_UNDERFLOW + template constexpr_NOERR unsigned int underflow(unsigned int sign = 0) { + #if HALF_ERRHANDLING + raise(FE_UNDERFLOW); + #endif + return (R==std::round_toward_infinity) ? (sign+1-(sign>>15)) : + (R==std::round_toward_neg_infinity) ? (sign+(sign>>15)) : + sign; + } + + /// Round half-precision number. + /// \tparam R rounding mode to use + /// \tparam I `true` to always raise INEXACT exception, `false` to raise only for rounded results + /// \param value finite half-precision number to round + /// \param g guard bit (most significant discarded bit) + /// \param s sticky bit (or of all but the most significant discarded bits) + /// \return rounded half-precision value + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if value had to be rounded or \a I is `true` + template constexpr_NOERR unsigned int rounded(unsigned int value, int g, int s) { + #if HALF_ERRHANDLING + value += (R==std::round_to_nearest) ? (g&(s|value)) : + (R==std::round_toward_infinity) ? (~(value>>15)&(g|s)) : + (R==std::round_toward_neg_infinity) ? ((value>>15)&(g|s)) : 0; + if((value&0x7C00) == 0x7C00) + raise(FE_OVERFLOW); + else if(value & 0x7C00) + raise(FE_INEXACT, I || (g|s)!=0); + else + raise(FE_UNDERFLOW, !(HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT) || I || (g|s)!=0); + return value; + #else + return (R==std::round_to_nearest) ? (value+(g&(s|value))) : + (R==std::round_toward_infinity) ? (value+(~(value>>15)&(g|s))) : + (R==std::round_toward_neg_infinity) ? (value+((value>>15)&(g|s))) : + value; + #endif + } + + /// Round half-precision number to nearest integer value. + /// \tparam R rounding mode to use + /// \tparam E `true` for round to even, `false` for round away from zero + /// \tparam I `true` to raise INEXACT exception (if inexact), `false` to never raise it + /// \param value half-precision value to round + /// \return half-precision bits for nearest integral value + /// \exception FE_INVALID for signaling NaN + /// \exception FE_INEXACT if value had to be rounded and \a I is `true` + template unsigned int integral(unsigned int value) { + unsigned int abs = value & 0x7FFF; + if(abs < 0x3C00) { + raise(FE_INEXACT, I); + return ((R==std::round_to_nearest) ? (0x3C00&-static_cast(abs>=(0x3800+E))) : + (R==std::round_toward_infinity) ? (0x3C00&-(~(value>>15)&(abs!=0))) : + (R==std::round_toward_neg_infinity) ? (0x3C00&-static_cast(value>0x8000)) : + 0) | (value&0x8000); + } + if(abs >= 0x6400) + return (abs>0x7C00) ? signal(value) : value; + unsigned int exp = 25 - (abs>>10), mask = (1<>exp)&E)) : + (R==std::round_toward_infinity) ? (mask&((value>>15)-1)) : + (R==std::round_toward_neg_infinity) ? (mask&-(value>>15)) : + 0) + value) & ~mask; + } + + /// Convert fixed point to half-precision floating-point. + /// \tparam R rounding mode to use + /// \tparam F number of fractional bits (at least 11) + /// \tparam S `true` for signed, `false` for unsigned + /// \tparam N `true` for additional normalization step, `false` if already normalized to 1.F + /// \tparam I `true` to always raise INEXACT exception, `false` to raise only for rounded results + /// \param m mantissa in Q1.F fixed point format + /// \param exp exponent + /// \param sign half-precision value with sign bit only + /// \param s sticky bit (or of all but the most significant already discarded bits) + /// \return value converted to half-precision + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if value had to be rounded or \a I is `true` + template unsigned int fixed2half(uint32 m, int exp = 14, unsigned int sign = 0, int s = 0) { + if(S) { + uint32 msign = sign_mask(m); + m = (m^msign) - msign; + sign = msign & 0x8000; + } + if(N) + for(; m<(static_cast(1)<(sign+(m>>(F-10-exp)), (m>>(F-11-exp))&1, s|((m&((static_cast(1)<<(F-11-exp))-1))!=0)); + return rounded(sign+(exp<<10)+(m>>(F-10)), (m>>(F-11))&1, s|((m&((static_cast(1)<<(F-11))-1))!=0)); + } + + /// Convert IEEE single-precision to half-precision. + /// Credit for this goes to [Jeroen van der Zijp](ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf). + /// \tparam R rounding mode to use + /// \param value single-precision value to convert + /// \return rounded half-precision value + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if value had to be rounded + template unsigned int float2half_impl(float value, true_type) { + #if HALF_ENABLE_F16C_INTRINSICS + return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value), + (R==std::round_to_nearest) ? _MM_FROUND_TO_NEAREST_INT : + (R==std::round_toward_zero) ? _MM_FROUND_TO_ZERO : + (R==std::round_toward_infinity) ? _MM_FROUND_TO_POS_INF : + (R==std::round_toward_neg_infinity) ? _MM_FROUND_TO_NEG_INF : + _MM_FROUND_CUR_DIRECTION)); + #else + bits_t fbits; + std::memcpy(&fbits, &value, sizeof(float)); + #if 1 + unsigned int sign = (fbits>>16) & 0x8000; + fbits &= 0x7FFFFFFF; + if(fbits >= 0x7F800000) + return sign | 0x7C00 | ((fbits>0x7F800000) ? (0x200|((fbits>>13)&0x3FF)) : 0); + if(fbits >= 0x47800000) + return overflow(sign); + if(fbits >= 0x38800000) + return rounded(sign|(((fbits>>23)-112)<<10)|((fbits>>13)&0x3FF), (fbits>>12)&1, (fbits&0xFFF)!=0); + if(fbits >= 0x33000000) + { + int i = 125 - (fbits>>23); + fbits = (fbits&0x7FFFFF) | 0x800000; + return rounded(sign|(fbits>>(i+1)), (fbits>>i)&1, (fbits&((static_cast(1)<(sign); + return sign; + #else + static const uint16 base_table[512] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, + 0x0200, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, + 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000, 0x5400, 0x5800, 0x5C00, 0x6000, 0x6400, 0x6800, 0x6C00, 0x7000, 0x7400, 0x7800, 0x7BFF, + 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, + 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, + 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, + 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, + 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, + 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, + 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7BFF, 0x7C00, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, + 0x8200, 0x8400, 0x8800, 0x8C00, 0x9000, 0x9400, 0x9800, 0x9C00, 0xA000, 0xA400, 0xA800, 0xAC00, 0xB000, 0xB400, 0xB800, 0xBC00, + 0xC000, 0xC400, 0xC800, 0xCC00, 0xD000, 0xD400, 0xD800, 0xDC00, 0xE000, 0xE400, 0xE800, 0xEC00, 0xF000, 0xF400, 0xF800, 0xFBFF, + 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, + 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, + 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, + 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, + 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, + 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, + 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFBFF, 0xFC00 }; + static const unsigned char shift_table[256] = { + 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13 }; + int sexp = fbits >> 23, exp = sexp & 0xFF, i = shift_table[exp]; + fbits &= 0x7FFFFF; + uint32 m = (fbits|((exp!=0)<<23)) & -static_cast(exp!=0xFF); + return rounded(base_table[sexp]+(fbits>>i), (m>>(i-1))&1, (((static_cast(1)<<(i-1))-1)&m)!=0); + #endif + #endif + } + + /// Convert IEEE double-precision to half-precision. + /// \tparam R rounding mode to use + /// \param value double-precision value to convert + /// \return rounded half-precision value + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if value had to be rounded + template unsigned int float2half_impl(double value, true_type) { + #if HALF_ENABLE_F16C_INTRINSICS + if(R == std::round_indeterminate) + return _mm_cvtsi128_si32(_mm_cvtps_ph(_mm_cvtpd_ps(_mm_set_sd(value)), _MM_FROUND_CUR_DIRECTION)); + #endif + bits_t dbits; + std::memcpy(&dbits, &value, sizeof(double)); + uint32 hi = dbits >> 32, lo = dbits & 0xFFFFFFFF; + unsigned int sign = (hi>>16) & 0x8000; + hi &= 0x7FFFFFFF; + if(hi >= 0x7FF00000) + return sign | 0x7C00 | ((dbits&0xFFFFFFFFFFFFF) ? (0x200|((hi>>10)&0x3FF)) : 0); + if(hi >= 0x40F00000) + return overflow(sign); + if(hi >= 0x3F100000) + return rounded(sign|(((hi>>20)-1008)<<10)|((hi>>10)&0x3FF), (hi>>9)&1, ((hi&0x1FF)|lo)!=0); + if(hi >= 0x3E600000) { + int i = 1018 - (hi>>20); + hi = (hi&0xFFFFF) | 0x100000; + return rounded(sign|(hi>>(i+1)), (hi>>i)&1, ((hi&((static_cast(1)<(sign); + return sign; + } + + /// Convert non-IEEE floating-point to half-precision. + /// \tparam R rounding mode to use + /// \tparam T source type (builtin floating-point type) + /// \param value floating-point value to convert + /// \return rounded half-precision value + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if value had to be rounded + template unsigned int float2half_impl(T value, ...) { + unsigned int hbits = static_cast(builtin_signbit(value)) << 15; + if(value == T()) + return hbits; + if(builtin_isnan(value)) + return hbits | 0x7FFF; + if(builtin_isinf(value)) + return hbits | 0x7C00; + int exp; + std::frexp(value, &exp); + if(exp > 16) + return overflow(hbits); + if(exp < -13) + value = std::ldexp(value, 25); + else { + value = std::ldexp(value, 12-exp); + hbits |= ((exp+13)<<10); + } + T ival, frac = std::modf(value, &ival); + int m = std::abs(static_cast(ival)); + return rounded(hbits+(m>>1), m&1, frac!=T()); + } + + /// Convert floating-point to half-precision. + /// \tparam R rounding mode to use + /// \tparam T source type (builtin floating-point type) + /// \param value floating-point value to convert + /// \return rounded half-precision value + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if value had to be rounded + template unsigned int float2half(T value) { + return float2half_impl(value, bool_type::is_iec559&&sizeof(bits_t)==sizeof(T)>()); + } + template unsigned int float2half(T value) { + return float2half_impl<(std::float_round_style)(HALF_ROUND_STYLE)>(value, bool_type::is_iec559&&sizeof(bits_t)==sizeof(T)>()); + } + + /// Convert integer to half-precision floating-point. + /// \tparam R rounding mode to use + /// \tparam T type to convert (builtin integer type) + /// \param value integral value to convert + /// \return rounded half-precision value + /// \exception FE_OVERFLOW on overflows + /// \exception FE_INEXACT if value had to be rounded + template unsigned int int2half(T value) { + unsigned int bits = static_cast(value<0) << 15; + if(!value) + return bits; + if(bits) + value = -value; + if(value > 0xFFFF) + return overflow(bits); + unsigned int m = static_cast(value), exp = 24; + for(; m<0x400; m<<=1,--exp) ; + for(; m>0x7FF; m>>=1,++exp) ; + bits |= (exp<<10) + m; + return (exp>24) ? rounded(bits, (value>>(exp-25))&1, (((1<<(exp-25))-1)&value)!=0) : bits; + } + + /// Convert half-precision to IEEE single-precision. + /// Credit for this goes to [Jeroen van der Zijp](ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf). + /// \param value half-precision value to convert + /// \return single-precision value + inline float half2float_impl(unsigned int value, float, true_type) { + #if HALF_ENABLE_F16C_INTRINSICS + return _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(value))); + #else + #if 0 + bits_t fbits = static_cast>(value&0x8000) << 16; + int abs = value & 0x7FFF; + if(abs) + { + fbits |= 0x38000000 << static_cast(abs>=0x7C00); + for(; abs<0x400; abs<<=1,fbits-=0x800000) ; + fbits += static_cast>(abs) << 13; + } + #else + static const bits_t mantissa_table[2048] = { + 0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34A00000, 0x34C00000, 0x34E00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000, + 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35A00000, 0x35A80000, 0x35B00000, 0x35B80000, 0x35C00000, 0x35C80000, 0x35D00000, 0x35D80000, 0x35E00000, 0x35E80000, 0x35F00000, 0x35F80000, + 0x36000000, 0x36040000, 0x36080000, 0x360C0000, 0x36100000, 0x36140000, 0x36180000, 0x361C0000, 0x36200000, 0x36240000, 0x36280000, 0x362C0000, 0x36300000, 0x36340000, 0x36380000, 0x363C0000, + 0x36400000, 0x36440000, 0x36480000, 0x364C0000, 0x36500000, 0x36540000, 0x36580000, 0x365C0000, 0x36600000, 0x36640000, 0x36680000, 0x366C0000, 0x36700000, 0x36740000, 0x36780000, 0x367C0000, + 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368A0000, 0x368C0000, 0x368E0000, 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369A0000, 0x369C0000, 0x369E0000, + 0x36A00000, 0x36A20000, 0x36A40000, 0x36A60000, 0x36A80000, 0x36AA0000, 0x36AC0000, 0x36AE0000, 0x36B00000, 0x36B20000, 0x36B40000, 0x36B60000, 0x36B80000, 0x36BA0000, 0x36BC0000, 0x36BE0000, + 0x36C00000, 0x36C20000, 0x36C40000, 0x36C60000, 0x36C80000, 0x36CA0000, 0x36CC0000, 0x36CE0000, 0x36D00000, 0x36D20000, 0x36D40000, 0x36D60000, 0x36D80000, 0x36DA0000, 0x36DC0000, 0x36DE0000, + 0x36E00000, 0x36E20000, 0x36E40000, 0x36E60000, 0x36E80000, 0x36EA0000, 0x36EC0000, 0x36EE0000, 0x36F00000, 0x36F20000, 0x36F40000, 0x36F60000, 0x36F80000, 0x36FA0000, 0x36FC0000, 0x36FE0000, + 0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000, 0x370A0000, 0x370B0000, 0x370C0000, 0x370D0000, 0x370E0000, 0x370F0000, + 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371A0000, 0x371B0000, 0x371C0000, 0x371D0000, 0x371E0000, 0x371F0000, + 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000, 0x37280000, 0x37290000, 0x372A0000, 0x372B0000, 0x372C0000, 0x372D0000, 0x372E0000, 0x372F0000, + 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000, 0x373A0000, 0x373B0000, 0x373C0000, 0x373D0000, 0x373E0000, 0x373F0000, + 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374A0000, 0x374B0000, 0x374C0000, 0x374D0000, 0x374E0000, 0x374F0000, + 0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000, 0x37580000, 0x37590000, 0x375A0000, 0x375B0000, 0x375C0000, 0x375D0000, 0x375E0000, 0x375F0000, + 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000, 0x376A0000, 0x376B0000, 0x376C0000, 0x376D0000, 0x376E0000, 0x376F0000, + 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377A0000, 0x377B0000, 0x377C0000, 0x377D0000, 0x377E0000, 0x377F0000, + 0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000, 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000, + 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378A0000, 0x378A8000, 0x378B0000, 0x378B8000, 0x378C0000, 0x378C8000, 0x378D0000, 0x378D8000, 0x378E0000, 0x378E8000, 0x378F0000, 0x378F8000, + 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000, + 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379A0000, 0x379A8000, 0x379B0000, 0x379B8000, 0x379C0000, 0x379C8000, 0x379D0000, 0x379D8000, 0x379E0000, 0x379E8000, 0x379F0000, 0x379F8000, + 0x37A00000, 0x37A08000, 0x37A10000, 0x37A18000, 0x37A20000, 0x37A28000, 0x37A30000, 0x37A38000, 0x37A40000, 0x37A48000, 0x37A50000, 0x37A58000, 0x37A60000, 0x37A68000, 0x37A70000, 0x37A78000, + 0x37A80000, 0x37A88000, 0x37A90000, 0x37A98000, 0x37AA0000, 0x37AA8000, 0x37AB0000, 0x37AB8000, 0x37AC0000, 0x37AC8000, 0x37AD0000, 0x37AD8000, 0x37AE0000, 0x37AE8000, 0x37AF0000, 0x37AF8000, + 0x37B00000, 0x37B08000, 0x37B10000, 0x37B18000, 0x37B20000, 0x37B28000, 0x37B30000, 0x37B38000, 0x37B40000, 0x37B48000, 0x37B50000, 0x37B58000, 0x37B60000, 0x37B68000, 0x37B70000, 0x37B78000, + 0x37B80000, 0x37B88000, 0x37B90000, 0x37B98000, 0x37BA0000, 0x37BA8000, 0x37BB0000, 0x37BB8000, 0x37BC0000, 0x37BC8000, 0x37BD0000, 0x37BD8000, 0x37BE0000, 0x37BE8000, 0x37BF0000, 0x37BF8000, + 0x37C00000, 0x37C08000, 0x37C10000, 0x37C18000, 0x37C20000, 0x37C28000, 0x37C30000, 0x37C38000, 0x37C40000, 0x37C48000, 0x37C50000, 0x37C58000, 0x37C60000, 0x37C68000, 0x37C70000, 0x37C78000, + 0x37C80000, 0x37C88000, 0x37C90000, 0x37C98000, 0x37CA0000, 0x37CA8000, 0x37CB0000, 0x37CB8000, 0x37CC0000, 0x37CC8000, 0x37CD0000, 0x37CD8000, 0x37CE0000, 0x37CE8000, 0x37CF0000, 0x37CF8000, + 0x37D00000, 0x37D08000, 0x37D10000, 0x37D18000, 0x37D20000, 0x37D28000, 0x37D30000, 0x37D38000, 0x37D40000, 0x37D48000, 0x37D50000, 0x37D58000, 0x37D60000, 0x37D68000, 0x37D70000, 0x37D78000, + 0x37D80000, 0x37D88000, 0x37D90000, 0x37D98000, 0x37DA0000, 0x37DA8000, 0x37DB0000, 0x37DB8000, 0x37DC0000, 0x37DC8000, 0x37DD0000, 0x37DD8000, 0x37DE0000, 0x37DE8000, 0x37DF0000, 0x37DF8000, + 0x37E00000, 0x37E08000, 0x37E10000, 0x37E18000, 0x37E20000, 0x37E28000, 0x37E30000, 0x37E38000, 0x37E40000, 0x37E48000, 0x37E50000, 0x37E58000, 0x37E60000, 0x37E68000, 0x37E70000, 0x37E78000, + 0x37E80000, 0x37E88000, 0x37E90000, 0x37E98000, 0x37EA0000, 0x37EA8000, 0x37EB0000, 0x37EB8000, 0x37EC0000, 0x37EC8000, 0x37ED0000, 0x37ED8000, 0x37EE0000, 0x37EE8000, 0x37EF0000, 0x37EF8000, + 0x37F00000, 0x37F08000, 0x37F10000, 0x37F18000, 0x37F20000, 0x37F28000, 0x37F30000, 0x37F38000, 0x37F40000, 0x37F48000, 0x37F50000, 0x37F58000, 0x37F60000, 0x37F68000, 0x37F70000, 0x37F78000, + 0x37F80000, 0x37F88000, 0x37F90000, 0x37F98000, 0x37FA0000, 0x37FA8000, 0x37FB0000, 0x37FB8000, 0x37FC0000, 0x37FC8000, 0x37FD0000, 0x37FD8000, 0x37FE0000, 0x37FE8000, 0x37FF0000, 0x37FF8000, + 0x38000000, 0x38004000, 0x38008000, 0x3800C000, 0x38010000, 0x38014000, 0x38018000, 0x3801C000, 0x38020000, 0x38024000, 0x38028000, 0x3802C000, 0x38030000, 0x38034000, 0x38038000, 0x3803C000, + 0x38040000, 0x38044000, 0x38048000, 0x3804C000, 0x38050000, 0x38054000, 0x38058000, 0x3805C000, 0x38060000, 0x38064000, 0x38068000, 0x3806C000, 0x38070000, 0x38074000, 0x38078000, 0x3807C000, + 0x38080000, 0x38084000, 0x38088000, 0x3808C000, 0x38090000, 0x38094000, 0x38098000, 0x3809C000, 0x380A0000, 0x380A4000, 0x380A8000, 0x380AC000, 0x380B0000, 0x380B4000, 0x380B8000, 0x380BC000, + 0x380C0000, 0x380C4000, 0x380C8000, 0x380CC000, 0x380D0000, 0x380D4000, 0x380D8000, 0x380DC000, 0x380E0000, 0x380E4000, 0x380E8000, 0x380EC000, 0x380F0000, 0x380F4000, 0x380F8000, 0x380FC000, + 0x38100000, 0x38104000, 0x38108000, 0x3810C000, 0x38110000, 0x38114000, 0x38118000, 0x3811C000, 0x38120000, 0x38124000, 0x38128000, 0x3812C000, 0x38130000, 0x38134000, 0x38138000, 0x3813C000, + 0x38140000, 0x38144000, 0x38148000, 0x3814C000, 0x38150000, 0x38154000, 0x38158000, 0x3815C000, 0x38160000, 0x38164000, 0x38168000, 0x3816C000, 0x38170000, 0x38174000, 0x38178000, 0x3817C000, + 0x38180000, 0x38184000, 0x38188000, 0x3818C000, 0x38190000, 0x38194000, 0x38198000, 0x3819C000, 0x381A0000, 0x381A4000, 0x381A8000, 0x381AC000, 0x381B0000, 0x381B4000, 0x381B8000, 0x381BC000, + 0x381C0000, 0x381C4000, 0x381C8000, 0x381CC000, 0x381D0000, 0x381D4000, 0x381D8000, 0x381DC000, 0x381E0000, 0x381E4000, 0x381E8000, 0x381EC000, 0x381F0000, 0x381F4000, 0x381F8000, 0x381FC000, + 0x38200000, 0x38204000, 0x38208000, 0x3820C000, 0x38210000, 0x38214000, 0x38218000, 0x3821C000, 0x38220000, 0x38224000, 0x38228000, 0x3822C000, 0x38230000, 0x38234000, 0x38238000, 0x3823C000, + 0x38240000, 0x38244000, 0x38248000, 0x3824C000, 0x38250000, 0x38254000, 0x38258000, 0x3825C000, 0x38260000, 0x38264000, 0x38268000, 0x3826C000, 0x38270000, 0x38274000, 0x38278000, 0x3827C000, + 0x38280000, 0x38284000, 0x38288000, 0x3828C000, 0x38290000, 0x38294000, 0x38298000, 0x3829C000, 0x382A0000, 0x382A4000, 0x382A8000, 0x382AC000, 0x382B0000, 0x382B4000, 0x382B8000, 0x382BC000, + 0x382C0000, 0x382C4000, 0x382C8000, 0x382CC000, 0x382D0000, 0x382D4000, 0x382D8000, 0x382DC000, 0x382E0000, 0x382E4000, 0x382E8000, 0x382EC000, 0x382F0000, 0x382F4000, 0x382F8000, 0x382FC000, + 0x38300000, 0x38304000, 0x38308000, 0x3830C000, 0x38310000, 0x38314000, 0x38318000, 0x3831C000, 0x38320000, 0x38324000, 0x38328000, 0x3832C000, 0x38330000, 0x38334000, 0x38338000, 0x3833C000, + 0x38340000, 0x38344000, 0x38348000, 0x3834C000, 0x38350000, 0x38354000, 0x38358000, 0x3835C000, 0x38360000, 0x38364000, 0x38368000, 0x3836C000, 0x38370000, 0x38374000, 0x38378000, 0x3837C000, + 0x38380000, 0x38384000, 0x38388000, 0x3838C000, 0x38390000, 0x38394000, 0x38398000, 0x3839C000, 0x383A0000, 0x383A4000, 0x383A8000, 0x383AC000, 0x383B0000, 0x383B4000, 0x383B8000, 0x383BC000, + 0x383C0000, 0x383C4000, 0x383C8000, 0x383CC000, 0x383D0000, 0x383D4000, 0x383D8000, 0x383DC000, 0x383E0000, 0x383E4000, 0x383E8000, 0x383EC000, 0x383F0000, 0x383F4000, 0x383F8000, 0x383FC000, + 0x38400000, 0x38404000, 0x38408000, 0x3840C000, 0x38410000, 0x38414000, 0x38418000, 0x3841C000, 0x38420000, 0x38424000, 0x38428000, 0x3842C000, 0x38430000, 0x38434000, 0x38438000, 0x3843C000, + 0x38440000, 0x38444000, 0x38448000, 0x3844C000, 0x38450000, 0x38454000, 0x38458000, 0x3845C000, 0x38460000, 0x38464000, 0x38468000, 0x3846C000, 0x38470000, 0x38474000, 0x38478000, 0x3847C000, + 0x38480000, 0x38484000, 0x38488000, 0x3848C000, 0x38490000, 0x38494000, 0x38498000, 0x3849C000, 0x384A0000, 0x384A4000, 0x384A8000, 0x384AC000, 0x384B0000, 0x384B4000, 0x384B8000, 0x384BC000, + 0x384C0000, 0x384C4000, 0x384C8000, 0x384CC000, 0x384D0000, 0x384D4000, 0x384D8000, 0x384DC000, 0x384E0000, 0x384E4000, 0x384E8000, 0x384EC000, 0x384F0000, 0x384F4000, 0x384F8000, 0x384FC000, + 0x38500000, 0x38504000, 0x38508000, 0x3850C000, 0x38510000, 0x38514000, 0x38518000, 0x3851C000, 0x38520000, 0x38524000, 0x38528000, 0x3852C000, 0x38530000, 0x38534000, 0x38538000, 0x3853C000, + 0x38540000, 0x38544000, 0x38548000, 0x3854C000, 0x38550000, 0x38554000, 0x38558000, 0x3855C000, 0x38560000, 0x38564000, 0x38568000, 0x3856C000, 0x38570000, 0x38574000, 0x38578000, 0x3857C000, + 0x38580000, 0x38584000, 0x38588000, 0x3858C000, 0x38590000, 0x38594000, 0x38598000, 0x3859C000, 0x385A0000, 0x385A4000, 0x385A8000, 0x385AC000, 0x385B0000, 0x385B4000, 0x385B8000, 0x385BC000, + 0x385C0000, 0x385C4000, 0x385C8000, 0x385CC000, 0x385D0000, 0x385D4000, 0x385D8000, 0x385DC000, 0x385E0000, 0x385E4000, 0x385E8000, 0x385EC000, 0x385F0000, 0x385F4000, 0x385F8000, 0x385FC000, + 0x38600000, 0x38604000, 0x38608000, 0x3860C000, 0x38610000, 0x38614000, 0x38618000, 0x3861C000, 0x38620000, 0x38624000, 0x38628000, 0x3862C000, 0x38630000, 0x38634000, 0x38638000, 0x3863C000, + 0x38640000, 0x38644000, 0x38648000, 0x3864C000, 0x38650000, 0x38654000, 0x38658000, 0x3865C000, 0x38660000, 0x38664000, 0x38668000, 0x3866C000, 0x38670000, 0x38674000, 0x38678000, 0x3867C000, + 0x38680000, 0x38684000, 0x38688000, 0x3868C000, 0x38690000, 0x38694000, 0x38698000, 0x3869C000, 0x386A0000, 0x386A4000, 0x386A8000, 0x386AC000, 0x386B0000, 0x386B4000, 0x386B8000, 0x386BC000, + 0x386C0000, 0x386C4000, 0x386C8000, 0x386CC000, 0x386D0000, 0x386D4000, 0x386D8000, 0x386DC000, 0x386E0000, 0x386E4000, 0x386E8000, 0x386EC000, 0x386F0000, 0x386F4000, 0x386F8000, 0x386FC000, + 0x38700000, 0x38704000, 0x38708000, 0x3870C000, 0x38710000, 0x38714000, 0x38718000, 0x3871C000, 0x38720000, 0x38724000, 0x38728000, 0x3872C000, 0x38730000, 0x38734000, 0x38738000, 0x3873C000, + 0x38740000, 0x38744000, 0x38748000, 0x3874C000, 0x38750000, 0x38754000, 0x38758000, 0x3875C000, 0x38760000, 0x38764000, 0x38768000, 0x3876C000, 0x38770000, 0x38774000, 0x38778000, 0x3877C000, + 0x38780000, 0x38784000, 0x38788000, 0x3878C000, 0x38790000, 0x38794000, 0x38798000, 0x3879C000, 0x387A0000, 0x387A4000, 0x387A8000, 0x387AC000, 0x387B0000, 0x387B4000, 0x387B8000, 0x387BC000, + 0x387C0000, 0x387C4000, 0x387C8000, 0x387CC000, 0x387D0000, 0x387D4000, 0x387D8000, 0x387DC000, 0x387E0000, 0x387E4000, 0x387E8000, 0x387EC000, 0x387F0000, 0x387F4000, 0x387F8000, 0x387FC000, + 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800A000, 0x3800C000, 0x3800E000, 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801A000, 0x3801C000, 0x3801E000, + 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802A000, 0x3802C000, 0x3802E000, 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803A000, 0x3803C000, 0x3803E000, + 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804A000, 0x3804C000, 0x3804E000, 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805A000, 0x3805C000, 0x3805E000, + 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806A000, 0x3806C000, 0x3806E000, 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807A000, 0x3807C000, 0x3807E000, + 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808A000, 0x3808C000, 0x3808E000, 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809A000, 0x3809C000, 0x3809E000, + 0x380A0000, 0x380A2000, 0x380A4000, 0x380A6000, 0x380A8000, 0x380AA000, 0x380AC000, 0x380AE000, 0x380B0000, 0x380B2000, 0x380B4000, 0x380B6000, 0x380B8000, 0x380BA000, 0x380BC000, 0x380BE000, + 0x380C0000, 0x380C2000, 0x380C4000, 0x380C6000, 0x380C8000, 0x380CA000, 0x380CC000, 0x380CE000, 0x380D0000, 0x380D2000, 0x380D4000, 0x380D6000, 0x380D8000, 0x380DA000, 0x380DC000, 0x380DE000, + 0x380E0000, 0x380E2000, 0x380E4000, 0x380E6000, 0x380E8000, 0x380EA000, 0x380EC000, 0x380EE000, 0x380F0000, 0x380F2000, 0x380F4000, 0x380F6000, 0x380F8000, 0x380FA000, 0x380FC000, 0x380FE000, + 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810A000, 0x3810C000, 0x3810E000, 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811A000, 0x3811C000, 0x3811E000, + 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812A000, 0x3812C000, 0x3812E000, 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813A000, 0x3813C000, 0x3813E000, + 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814A000, 0x3814C000, 0x3814E000, 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815A000, 0x3815C000, 0x3815E000, + 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816A000, 0x3816C000, 0x3816E000, 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817A000, 0x3817C000, 0x3817E000, + 0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818A000, 0x3818C000, 0x3818E000, 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819A000, 0x3819C000, 0x3819E000, + 0x381A0000, 0x381A2000, 0x381A4000, 0x381A6000, 0x381A8000, 0x381AA000, 0x381AC000, 0x381AE000, 0x381B0000, 0x381B2000, 0x381B4000, 0x381B6000, 0x381B8000, 0x381BA000, 0x381BC000, 0x381BE000, + 0x381C0000, 0x381C2000, 0x381C4000, 0x381C6000, 0x381C8000, 0x381CA000, 0x381CC000, 0x381CE000, 0x381D0000, 0x381D2000, 0x381D4000, 0x381D6000, 0x381D8000, 0x381DA000, 0x381DC000, 0x381DE000, + 0x381E0000, 0x381E2000, 0x381E4000, 0x381E6000, 0x381E8000, 0x381EA000, 0x381EC000, 0x381EE000, 0x381F0000, 0x381F2000, 0x381F4000, 0x381F6000, 0x381F8000, 0x381FA000, 0x381FC000, 0x381FE000, + 0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820A000, 0x3820C000, 0x3820E000, 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821A000, 0x3821C000, 0x3821E000, + 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822A000, 0x3822C000, 0x3822E000, 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823A000, 0x3823C000, 0x3823E000, + 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824A000, 0x3824C000, 0x3824E000, 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825A000, 0x3825C000, 0x3825E000, + 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826A000, 0x3826C000, 0x3826E000, 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827A000, 0x3827C000, 0x3827E000, + 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828A000, 0x3828C000, 0x3828E000, 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829A000, 0x3829C000, 0x3829E000, + 0x382A0000, 0x382A2000, 0x382A4000, 0x382A6000, 0x382A8000, 0x382AA000, 0x382AC000, 0x382AE000, 0x382B0000, 0x382B2000, 0x382B4000, 0x382B6000, 0x382B8000, 0x382BA000, 0x382BC000, 0x382BE000, + 0x382C0000, 0x382C2000, 0x382C4000, 0x382C6000, 0x382C8000, 0x382CA000, 0x382CC000, 0x382CE000, 0x382D0000, 0x382D2000, 0x382D4000, 0x382D6000, 0x382D8000, 0x382DA000, 0x382DC000, 0x382DE000, + 0x382E0000, 0x382E2000, 0x382E4000, 0x382E6000, 0x382E8000, 0x382EA000, 0x382EC000, 0x382EE000, 0x382F0000, 0x382F2000, 0x382F4000, 0x382F6000, 0x382F8000, 0x382FA000, 0x382FC000, 0x382FE000, + 0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830A000, 0x3830C000, 0x3830E000, 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831A000, 0x3831C000, 0x3831E000, + 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832A000, 0x3832C000, 0x3832E000, 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833A000, 0x3833C000, 0x3833E000, + 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834A000, 0x3834C000, 0x3834E000, 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835A000, 0x3835C000, 0x3835E000, + 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836A000, 0x3836C000, 0x3836E000, 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837A000, 0x3837C000, 0x3837E000, + 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838A000, 0x3838C000, 0x3838E000, 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839A000, 0x3839C000, 0x3839E000, + 0x383A0000, 0x383A2000, 0x383A4000, 0x383A6000, 0x383A8000, 0x383AA000, 0x383AC000, 0x383AE000, 0x383B0000, 0x383B2000, 0x383B4000, 0x383B6000, 0x383B8000, 0x383BA000, 0x383BC000, 0x383BE000, + 0x383C0000, 0x383C2000, 0x383C4000, 0x383C6000, 0x383C8000, 0x383CA000, 0x383CC000, 0x383CE000, 0x383D0000, 0x383D2000, 0x383D4000, 0x383D6000, 0x383D8000, 0x383DA000, 0x383DC000, 0x383DE000, + 0x383E0000, 0x383E2000, 0x383E4000, 0x383E6000, 0x383E8000, 0x383EA000, 0x383EC000, 0x383EE000, 0x383F0000, 0x383F2000, 0x383F4000, 0x383F6000, 0x383F8000, 0x383FA000, 0x383FC000, 0x383FE000, + 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840A000, 0x3840C000, 0x3840E000, 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841A000, 0x3841C000, 0x3841E000, + 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842A000, 0x3842C000, 0x3842E000, 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843A000, 0x3843C000, 0x3843E000, + 0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844A000, 0x3844C000, 0x3844E000, 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845A000, 0x3845C000, 0x3845E000, + 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846A000, 0x3846C000, 0x3846E000, 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847A000, 0x3847C000, 0x3847E000, + 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848A000, 0x3848C000, 0x3848E000, 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849A000, 0x3849C000, 0x3849E000, + 0x384A0000, 0x384A2000, 0x384A4000, 0x384A6000, 0x384A8000, 0x384AA000, 0x384AC000, 0x384AE000, 0x384B0000, 0x384B2000, 0x384B4000, 0x384B6000, 0x384B8000, 0x384BA000, 0x384BC000, 0x384BE000, + 0x384C0000, 0x384C2000, 0x384C4000, 0x384C6000, 0x384C8000, 0x384CA000, 0x384CC000, 0x384CE000, 0x384D0000, 0x384D2000, 0x384D4000, 0x384D6000, 0x384D8000, 0x384DA000, 0x384DC000, 0x384DE000, + 0x384E0000, 0x384E2000, 0x384E4000, 0x384E6000, 0x384E8000, 0x384EA000, 0x384EC000, 0x384EE000, 0x384F0000, 0x384F2000, 0x384F4000, 0x384F6000, 0x384F8000, 0x384FA000, 0x384FC000, 0x384FE000, + 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850A000, 0x3850C000, 0x3850E000, 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851A000, 0x3851C000, 0x3851E000, + 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852A000, 0x3852C000, 0x3852E000, 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853A000, 0x3853C000, 0x3853E000, + 0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854A000, 0x3854C000, 0x3854E000, 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855A000, 0x3855C000, 0x3855E000, + 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856A000, 0x3856C000, 0x3856E000, 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857A000, 0x3857C000, 0x3857E000, + 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858A000, 0x3858C000, 0x3858E000, 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859A000, 0x3859C000, 0x3859E000, + 0x385A0000, 0x385A2000, 0x385A4000, 0x385A6000, 0x385A8000, 0x385AA000, 0x385AC000, 0x385AE000, 0x385B0000, 0x385B2000, 0x385B4000, 0x385B6000, 0x385B8000, 0x385BA000, 0x385BC000, 0x385BE000, + 0x385C0000, 0x385C2000, 0x385C4000, 0x385C6000, 0x385C8000, 0x385CA000, 0x385CC000, 0x385CE000, 0x385D0000, 0x385D2000, 0x385D4000, 0x385D6000, 0x385D8000, 0x385DA000, 0x385DC000, 0x385DE000, + 0x385E0000, 0x385E2000, 0x385E4000, 0x385E6000, 0x385E8000, 0x385EA000, 0x385EC000, 0x385EE000, 0x385F0000, 0x385F2000, 0x385F4000, 0x385F6000, 0x385F8000, 0x385FA000, 0x385FC000, 0x385FE000, + 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860A000, 0x3860C000, 0x3860E000, 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861A000, 0x3861C000, 0x3861E000, + 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862A000, 0x3862C000, 0x3862E000, 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863A000, 0x3863C000, 0x3863E000, + 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864A000, 0x3864C000, 0x3864E000, 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865A000, 0x3865C000, 0x3865E000, + 0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866A000, 0x3866C000, 0x3866E000, 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867A000, 0x3867C000, 0x3867E000, + 0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868A000, 0x3868C000, 0x3868E000, 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869A000, 0x3869C000, 0x3869E000, + 0x386A0000, 0x386A2000, 0x386A4000, 0x386A6000, 0x386A8000, 0x386AA000, 0x386AC000, 0x386AE000, 0x386B0000, 0x386B2000, 0x386B4000, 0x386B6000, 0x386B8000, 0x386BA000, 0x386BC000, 0x386BE000, + 0x386C0000, 0x386C2000, 0x386C4000, 0x386C6000, 0x386C8000, 0x386CA000, 0x386CC000, 0x386CE000, 0x386D0000, 0x386D2000, 0x386D4000, 0x386D6000, 0x386D8000, 0x386DA000, 0x386DC000, 0x386DE000, + 0x386E0000, 0x386E2000, 0x386E4000, 0x386E6000, 0x386E8000, 0x386EA000, 0x386EC000, 0x386EE000, 0x386F0000, 0x386F2000, 0x386F4000, 0x386F6000, 0x386F8000, 0x386FA000, 0x386FC000, 0x386FE000, + 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870A000, 0x3870C000, 0x3870E000, 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871A000, 0x3871C000, 0x3871E000, + 0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872A000, 0x3872C000, 0x3872E000, 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873A000, 0x3873C000, 0x3873E000, + 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874A000, 0x3874C000, 0x3874E000, 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875A000, 0x3875C000, 0x3875E000, + 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876A000, 0x3876C000, 0x3876E000, 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877A000, 0x3877C000, 0x3877E000, + 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878A000, 0x3878C000, 0x3878E000, 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879A000, 0x3879C000, 0x3879E000, + 0x387A0000, 0x387A2000, 0x387A4000, 0x387A6000, 0x387A8000, 0x387AA000, 0x387AC000, 0x387AE000, 0x387B0000, 0x387B2000, 0x387B4000, 0x387B6000, 0x387B8000, 0x387BA000, 0x387BC000, 0x387BE000, + 0x387C0000, 0x387C2000, 0x387C4000, 0x387C6000, 0x387C8000, 0x387CA000, 0x387CC000, 0x387CE000, 0x387D0000, 0x387D2000, 0x387D4000, 0x387D6000, 0x387D8000, 0x387DA000, 0x387DC000, 0x387DE000, + 0x387E0000, 0x387E2000, 0x387E4000, 0x387E6000, 0x387E8000, 0x387EA000, 0x387EC000, 0x387EE000, 0x387F0000, 0x387F2000, 0x387F4000, 0x387F6000, 0x387F8000, 0x387FA000, 0x387FC000, 0x387FE000 }; + static const bits_t exponent_table[64] = { + 0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000, + 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0A000000, 0x0A800000, 0x0B000000, 0x0B800000, 0x0C000000, 0x0C800000, 0x0D000000, 0x0D800000, 0x0E000000, 0x0E800000, 0x0F000000, 0x47800000, + 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000, + 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8A000000, 0x8A800000, 0x8B000000, 0x8B800000, 0x8C000000, 0x8C800000, 0x8D000000, 0x8D800000, 0x8E000000, 0x8E800000, 0x8F000000, 0xC7800000 }; + static const unsigned short offset_table[64] = { + 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 0, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 }; + bits_t fbits = mantissa_table[offset_table[value>>10]+(value&0x3FF)] + exponent_table[value>>10]; + #endif + float out; + std::memcpy(&out, &fbits, sizeof(float)); + return out; + #endif + } + + /// Convert half-precision to IEEE double-precision. + /// \param value half-precision value to convert + /// \return double-precision value + inline double half2float_impl(unsigned int value, double, true_type) { + #if HALF_ENABLE_F16C_INTRINSICS + return _mm_cvtsd_f64(_mm_cvtps_pd(_mm_cvtph_ps(_mm_cvtsi32_si128(value)))); + #else + uint32 hi = static_cast(value&0x8000) << 16; + unsigned int abs = value & 0x7FFF; + if(abs) { + hi |= 0x3F000000 << static_cast(abs>=0x7C00); + for(; abs<0x400; abs<<=1,hi-=0x100000) ; + hi += static_cast(abs) << 10; + } + bits_t dbits = static_cast>(hi) << 32; + double out; + std::memcpy(&out, &dbits, sizeof(double)); + return out; + #endif + } + + /// Convert half-precision to non-IEEE floating-point. + /// \tparam T type to convert to (builtin integer type) + /// \param value half-precision value to convert + /// \return floating-point value + template T half2float_impl(unsigned int value, T, ...) { + T out; + unsigned int abs = value & 0x7FFF; + if(abs > 0x7C00) + out = (std::numeric_limits::has_signaling_NaN && !(abs&0x200)) ? std::numeric_limits::signaling_NaN() : + std::numeric_limits::has_quiet_NaN ? std::numeric_limits::quiet_NaN() : T(); + else if(abs == 0x7C00) + out = std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max(); + else if(abs > 0x3FF) + out = std::ldexp(static_cast((abs&0x3FF)|0x400), (abs>>10)-25); + else + out = std::ldexp(static_cast(abs), -24); + return (value&0x8000) ? -out : out; + } + + /// Convert half-precision to floating-point. + /// \tparam T type to convert to (builtin integer type) + /// \param value half-precision value to convert + /// \return floating-point value + template T half2float(unsigned int value) { + return half2float_impl(value, T(), bool_type::is_iec559&&sizeof(bits_t)==sizeof(T)>()); + } + + /// Convert half-precision floating-point to integer. + /// \tparam R rounding mode to use + /// \tparam E `true` for round to even, `false` for round away from zero + /// \tparam I `true` to raise INEXACT exception (if inexact), `false` to never raise it + /// \tparam T type to convert to (buitlin integer type with at least 16 bits precision, excluding any implicit sign bits) + /// \param value half-precision value to convert + /// \return rounded integer value + /// \exception FE_INVALID if value is not representable in type \a T + /// \exception FE_INEXACT if value had to be rounded and \a I is `true` + template T half2int(unsigned int value) { + unsigned int abs = value & 0x7FFF; + if(abs >= 0x7C00) { + raise(FE_INVALID); + return (value&0x8000) ? std::numeric_limits::min() : std::numeric_limits::max(); + } + if(abs < 0x3800) { + raise(FE_INEXACT, I); + return (R==std::round_toward_infinity) ? T(~(value>>15)&(abs!=0)) : + (R==std::round_toward_neg_infinity) ? -T(value>0x8000) : + T(); + } + int exp = 25 - (abs>>10); + unsigned int m = (value&0x3FF) | 0x400; + int32 i = static_cast((exp<=0) ? (m<<-exp) : ((m+( + (R==std::round_to_nearest) ? ((1<<(exp-1))-(~(m>>exp)&E)) : + (R==std::round_toward_infinity) ? (((1<>15)-1)) : + (R==std::round_toward_neg_infinity) ? (((1<>15)) : 0))>>exp)); + if((!std::numeric_limits::is_signed && (value&0x8000)) || (std::numeric_limits::digits<16 && + ((value&0x8000) ? (-i::min()) : (i>std::numeric_limits::max())))) + raise(FE_INVALID); + else if(I && exp > 0 && (m&((1<((value&0x8000) ? -i : i); + } + + /// \} + /// \name Mathematics + /// \{ + + /// upper part of 64-bit multiplication. + /// \tparam R rounding mode to use + /// \param x first factor + /// \param y second factor + /// \return upper 32 bit of \a x * \a y + template uint32 mulhi(uint32 x, uint32 y) { + uint32 xy = (x>>16) * (y&0xFFFF), yx = (x&0xFFFF) * (y>>16), c = (xy&0xFFFF) + (yx&0xFFFF) + (((x&0xFFFF)*(y&0xFFFF))>>16); + return (x>>16)*(y>>16) + (xy>>16) + (yx>>16) + (c>>16) + + ((R==std::round_to_nearest) ? ((c>>15)&1) : (R==std::round_toward_infinity) ? ((c&0xFFFF)!=0) : 0); + } + + /// 64-bit multiplication. + /// \param x first factor + /// \param y second factor + /// \return upper 32 bit of \a x * \a y rounded to nearest + inline uint32 multiply64(uint32 x, uint32 y) { + return static_cast((static_cast(x)*static_cast(y)+0x80000000)>>32); + } + + /// 64-bit division. + /// \param x upper 32 bit of dividend + /// \param y divisor + /// \param s variable to store sticky bit for rounding + /// \return (\a x << 32) / \a y + inline uint32 divide64(uint32 x, uint32 y, int &s) { + unsigned long long xx = static_cast(x) << 32; + return s = (xx%y!=0), static_cast(xx/y); + } + + /// Half precision positive modulus. + /// \tparam Q `true` to compute full quotient, `false` else + /// \tparam R `true` to compute signed remainder, `false` for positive remainder + /// \param x first operand as positive finite half-precision value + /// \param y second operand as positive finite half-precision value + /// \param quo adress to store quotient at, `nullptr` if \a Q `false` + /// \return modulus of \a x / \a y + template unsigned int mod(unsigned int x, unsigned int y, int *quo = NULL) { + unsigned int q = 0; + if(x > y) { + int absx = x, absy = y, expx = 0, expy = 0; + for(; absx<0x400; absx<<=1,--expx) ; + for(; absy<0x400; absy<<=1,--expy) ; + expx += absx >> 10; + expy += absy >> 10; + int mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400; + for(int d=expx-expy; d; --d) { + if(!Q && mx == my) + return 0; + if(mx >= my) { + mx -= my; + q += Q; + } + mx <<= 1; + q <<= static_cast(Q); + } + if(!Q && mx == my) + return 0; + if(mx >= my) { + mx -= my; + ++q; + } + if(Q) { + q &= (1<<(std::numeric_limits::digits-1)) - 1; + if(!mx) + return *quo = q, 0; + } + for(; mx<0x400; mx<<=1,--expy) ; + x = (expy>0) ? ((expy<<10)|(mx&0x3FF)) : (mx>>(1-expy)); + } + if(R) { + unsigned int a, b; + if(y < 0x800) { + a = (x<0x400) ? (x<<1) : (x+0x400); + b = y; + } else { + a = x; + b = y - 0x400; + } + if(a > b || (a == b && (q&1))) { + int exp = (y>>10) + (y<=0x3FF), d = exp - (x>>10) - (x<=0x3FF); + int m = (((y&0x3FF)|((y>0x3FF)<<10))<<1) - (((x&0x3FF)|((x>0x3FF)<<10))<<(1-d)); + for(; m<0x800 && exp>1; m<<=1,--exp) ; + x = 0x8000 + ((exp-1)<<10) + (m>>1); + q += Q; + } + } + if(Q) + *quo = q; + return x; + } + + /// Fixed point square root. + /// \tparam F number of fractional bits + /// \param r radicand in Q1.F fixed point format + /// \param exp exponent + /// \return square root as Q1.F/2 + template uint32 sqrt(uint32 &r, int &exp) { + int i = exp & 1; + r <<= i; + exp = (exp-i) / 2; + uint32 m = 0; + for(uint32 bit=static_cast(1)<>=2) { + if(r < m+bit) + m >>= 1; + else { + r -= m + bit; + m = (m>>1) + bit; + } + } + return m; + } + + /// Fixed point binary exponential. + /// This uses the BKM algorithm in E-mode. + /// \param m exponent in [0,1) as Q0.31 + /// \param n number of iterations (at most 32) + /// \return 2 ^ \a m as Q1.31 + inline uint32 exp2(uint32 m, unsigned int n = 32) { + static const uint32 logs[] = { + 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B, + 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153, + 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171, + 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 }; + if(!m) + return 0x80000000; + uint32 mx = 0x80000000, my = 0; + for(unsigned int i=1; i> i; + } + } + return mx; + } + + /// Fixed point binary logarithm. + /// This uses the BKM algorithm in L-mode. + /// \param m mantissa in [1,2) as Q1.30 + /// \param n number of iterations (at most 32) + /// \return log2(\a m) as Q0.31 + inline uint32 log2(uint32 m, unsigned int n = 32) { + static const uint32 logs[] = { + 0x80000000, 0x4AE00D1D, 0x2934F098, 0x15C01A3A, 0x0B31FB7D, 0x05AEB4DD, 0x02DCF2D1, 0x016FE50B, + 0x00B84E23, 0x005C3E10, 0x002E24CA, 0x001713D6, 0x000B8A47, 0x0005C53B, 0x0002E2A3, 0x00017153, + 0x0000B8AA, 0x00005C55, 0x00002E2B, 0x00001715, 0x00000B8B, 0x000005C5, 0x000002E3, 0x00000171, + 0x000000B9, 0x0000005C, 0x0000002E, 0x00000017, 0x0000000C, 0x00000006, 0x00000003, 0x00000001 }; + if(m == 0x40000000) + return 0; + uint32 mx = 0x40000000, my = 0; + for(unsigned int i=1; i>i); + if(mz <= m) { + mx = mz; + my += logs[i]; + } + } + return my; + } + + /// Fixed point sine and cosine. + /// This uses the CORDIC algorithm in rotation mode. + /// \param mz angle in [-pi/2,pi/2] as Q1.30 + /// \param n number of iterations (at most 31) + /// \return sine and cosine of \a mz as Q1.30 + inline std::pair sincos(uint32 mz, unsigned int n = 31) { + static const uint32 angles[] = { + 0x3243F6A9, 0x1DAC6705, 0x0FADBAFD, 0x07F56EA7, 0x03FEAB77, 0x01FFD55C, 0x00FFFAAB, 0x007FFF55, + 0x003FFFEB, 0x001FFFFD, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x00008000, + 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080, + 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; + uint32 mx = 0x26DD3B6A, my = 0; + for(unsigned int i=0; i0x3FF)<<10); + int exp = (abs>>10) + (abs<=0x3FF) - 15; + if(abs < 0x3A48) + return k = 0, m << (exp+20); + unsigned long long y = m * 0xA2F9836E4E442, mask = (1ULL<<(62-exp)) - 1, yi = (y+(mask>>1)) & ~mask, f = y - yi; + uint32 sign = -static_cast(f>>63); + k = static_cast(yi>>(62-exp)); + return (multiply64(static_cast((sign ? -f : f)>>(31-exp)), 0xC90FDAA2)^sign) - sign; + } + + /// Get arguments for atan2 function. + /// \param abs half-precision floating-point value + /// \return \a abs and sqrt(1 - \a abs^2) as Q0.30 + inline std::pair atan2_args(unsigned int abs) { + int exp = -15; + for(; abs<0x400; abs<<=1,--exp) ; + exp += abs >> 10; + uint32 my = ((abs&0x3FF)|0x400) << 5, r = my * my; + int rexp = 2 * exp; + r = 0x40000000 - ((rexp>-31) ? ((r>>-rexp)|((r&((static_cast(1)<<-rexp)-1))!=0)) : 1); + for(rexp=0; r<0x40000000; r<<=1,--rexp) ; + uint32 mx = sqrt<30>(r, rexp); + int d = exp - rexp; + if(d < 0) + return std::make_pair((d<-14) ? ((my>>(-d-14))+((my>>(-d-15))&1)) : (my<<(14+d)), (mx<<14)+(r<<13)/mx); + if(d > 0) + return std::make_pair(my<<14, (d>14) ? ((mx>>(d-14))+((mx>>(d-15))&1)) : ((d==14) ? mx : ((mx<<(14-d))+(r<<(13-d))/mx))); + return std::make_pair(my<<13, (mx<<13)+(r<<12)/mx); + } + + /// Get exponentials for hyperbolic computation + /// \param abs half-precision floating-point value + /// \param exp variable to take unbiased exponent of larger result + /// \param n number of BKM iterations (at most 32) + /// \return exp(abs) and exp(-\a abs) as Q1.31 with same exponent + inline std::pair hyperbolic_args(unsigned int abs, int &exp, unsigned int n = 32) { + uint32 mx = detail::multiply64(static_cast((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29), my; + int e = (abs>>10) + (abs<=0x3FF); + if(e < 14) { + exp = 0; + mx >>= 14 - e; + } else { + exp = mx >> (45-e); + mx = (mx<<(e-14)) & 0x7FFFFFFF; + } + mx = exp2(mx, n); + int d = exp << 1, s; + if(mx > 0x80000000) { + my = divide64(0x80000000, mx, s); + my |= s; + ++d; + } else + my = mx; + return std::make_pair(mx, (d<31) ? ((my>>d)|((my&((static_cast(1)< unsigned int exp2_post(uint32 m, int exp, bool esign, unsigned int sign = 0) { + int s = 0; + if(esign) { + if(m > 0x80000000) { + m = divide64(0x80000000, m, s); + ++exp; + } + if(exp > 25) + return underflow(sign); + else if(exp == 25) + return rounded(sign, 1, (m&0x7FFFFFFF)!=0); + exp = -exp; + } else if(exp > 15) + return overflow(sign); + return fixed2half(m, exp+14, sign, s); + } + + /// Postprocessing for binary logarithm. + /// \tparam R rounding mode to use + /// \tparam L logarithm for base transformation as Q1.31 + /// \param m fractional part of logarithm as Q0.31 + /// \param ilog signed integer part of logarithm + /// \param exp biased exponent of result + /// \param sign sign bit of result + /// \return value base-transformed and converted to half-precision + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if no other exception occurred + template unsigned int log2_post(uint32 m, int ilog, int exp, unsigned int sign = 0) { + uint32 msign = sign_mask(ilog); + m = (((static_cast(ilog)<<27)+(m>>4))^msign) - msign; + if(!m) + return 0; + for(; m<0x80000000; m<<=1,--exp) ; + int i = m >= L, s; + exp += i; + m >>= 1 + i; + sign ^= msign & 0x8000; + if(exp < -11) + return underflow(sign); + m = divide64(m, L, s); + return fixed2half(m, exp, sign, 1); + } + + /// Hypotenuse square root and postprocessing. + /// \tparam R rounding mode to use + /// \param r mantissa as Q2.30 + /// \param exp unbiased exponent + /// \return square root converted to half-precision + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if value had to be rounded + template unsigned int hypot_post(uint32 r, int exp) { + int i = r >> 31; + if((exp+=i) > 46) + return overflow(); + if(exp < -34) + return underflow(); + r = (r>>i) | (r&i); + uint32 m = sqrt<30>(r, exp+=15); + return fixed2half(m, exp-1, 0, r!=0); + } + + /// Division and postprocessing for tangents. + /// \tparam R rounding mode to use + /// \param my dividend as Q1.31 + /// \param mx divisor as Q1.31 + /// \param exp biased exponent of result + /// \param sign sign bit of result + /// \return quotient converted to half-precision + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if no other exception occurred + template unsigned int tangent_post(uint32 my, uint32 mx, int exp, unsigned int sign = 0) { + int i = my >= mx, s; + exp += i; + if(exp > 29) + return overflow(sign); + if(exp < -11) + return underflow(sign); + uint32 m = divide64(my>>(i+1), mx, s); + return fixed2half(m, exp, sign, s); + } + + /// Area function and postprocessing. + /// This computes the value directly in Q2.30 using the representation `asinh|acosh(x) = log(x+sqrt(x^2+|-1))`. + /// \tparam R rounding mode to use + /// \tparam S `true` for asinh, `false` for acosh + /// \param arg half-precision argument + /// \return asinh|acosh(\a arg) converted to half-precision + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if no other exception occurred + template unsigned int area(unsigned int arg) { + int abs = arg & 0x7FFF, expx = (abs>>10) + (abs<=0x3FF) - 15, expy = -15, ilog, i; + uint32 mx = static_cast((abs&0x3FF)|((abs>0x3FF)<<10)) << 20, my, r; + for(; abs<0x400; abs<<=1,--expy) ; + expy += abs >> 10; + r = ((abs&0x3FF)|0x400) << 5; + r *= r; + i = r >> 31; + expy = 2*expy + i; + r >>= i; + if(S) { + if(expy < 0) { + r = 0x40000000 + ((expy>-30) ? ((r>>-expy)|((r&((static_cast(1)<<-expy)-1))!=0)) : 1); + expy = 0; + } else { + r += 0x40000000 >> expy; + i = r >> 31; + r = (r>>i) | (r&i); + expy += i; + } + } else { + r -= 0x40000000 >> expy; + for(; r<0x40000000; r<<=1,--expy) ; + } + my = sqrt<30>(r, expy); + my = (my<<15) + (r<<14)/my; + if(S) { + mx >>= expy - expx; + ilog = expy; + } else { + my >>= expx - expy; + ilog = expx; + } + my += mx; + i = my >> 31; + static const int G = S && (R==std::round_to_nearest); + return log2_post(log2(my>>i, 26+S+G)+(G<<3), ilog+i, 17, arg&(static_cast(S)<<15)); + } + + /// Class for 1.31 unsigned floating-point computation + struct f31 { + /// Constructor. + /// \param mant mantissa as 1.31 + /// \param e exponent + constexpr f31(uint32 mant, int e) : m(mant), exp(e) {} + + /// Constructor. + /// \param abs unsigned half-precision value + f31(unsigned int abs) : exp(-15) { + for(; abs<0x400; abs<<=1,--exp) ; + m = static_cast((abs&0x3FF)|0x400) << 21; + exp += (abs>>10); + } + + /// Addition operator. + /// \param a first operand + /// \param b second operand + /// \return \a a + \a b + friend f31 operator+(f31 a, f31 b) { + if(b.exp > a.exp) + std::swap(a, b); + int d = a.exp - b.exp; + uint32 m = a.m + ((d<32) ? (b.m>>d) : 0); + int i = (m&0xFFFFFFFF) < a.m; + return f31(((m+i)>>i)|0x80000000, a.exp+i); + } + + /// Subtraction operator. + /// \param a first operand + /// \param b second operand + /// \return \a a - \a b + friend f31 operator-(f31 a, f31 b) { + int d = a.exp - b.exp, exp = a.exp; + uint32 m = a.m - ((d<32) ? (b.m>>d) : 0); + if(!m) + return f31(0, -32); + for(; m<0x80000000; m<<=1,--exp) ; + return f31(m, exp); + } + + /// Multiplication operator. + /// \param a first operand + /// \param b second operand + /// \return \a a * \a b + friend f31 operator*(f31 a, f31 b) { + uint32 m = multiply64(a.m, b.m); + int i = m >> 31; + return f31(m<<(1-i), a.exp + b.exp + i); + } + + /// Division operator. + /// \param a first operand + /// \param b second operand + /// \return \a a / \a b + friend f31 operator/(f31 a, f31 b) { + int i = a.m >= b.m, s; + uint32 m = divide64((a.m+i)>>i, b.m, s); + return f31(m, a.exp - b.exp + i - 1); + } + + uint32 m; ///< mantissa as 1.31. + int exp; ///< exponent. + }; + + /// Error function and postprocessing. + /// This computes the value directly in Q1.31 using the approximations given + /// [here](https://en.wikipedia.org/wiki/Error_function#Approximation_with_elementary_functions). + /// \tparam R rounding mode to use + /// \tparam C `true` for comlementary error function, `false` else + /// \param arg half-precision function argument + /// \return approximated value of error function in half-precision + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if no other exception occurred + template unsigned int erf(unsigned int arg) { + unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000; + f31 x(abs), x2 = x * x * f31(0xB8AA3B29, 0), t = f31(0x80000000, 0) / (f31(0x80000000, 0)+f31(0xA7BA054A, -2)*x), t2 = t * t; + f31 e = ((f31(0x87DC2213, 0)*t2+f31(0xB5F0E2AE, 0))*t2+f31(0x82790637, -2)-(f31(0xBA00E2B8, 0)*t2+f31(0x91A98E62, -2))*t) * t / + ((x2.exp<0) ? f31(exp2((x2.exp>-32) ? (x2.m>>-x2.exp) : 0, 30), 0) : f31(exp2((x2.m<>(31-x2.exp))); + return (!C || sign) ? fixed2half(0x80000000-(e.m>>(C-e.exp)), 14+C, sign&(C-1U)) : + (e.exp<-25) ? underflow() : fixed2half(e.m>>1, e.exp+14, 0, e.m&1); + } + + /// Gamma function and postprocessing. + /// This approximates the value of either the gamma function or its logarithm directly in Q1.31. + /// \tparam R rounding mode to use + /// \tparam L `true` for lograithm of gamma function, `false` for gamma function + /// \param arg half-precision floating-point value + /// \return lgamma/tgamma(\a arg) in half-precision + /// \exception FE_OVERFLOW on overflows + /// \exception FE_UNDERFLOW on underflows + /// \exception FE_INEXACT if \a arg is not a positive integer + template unsigned int gamma(unsigned int arg) { +/* static const double p[] ={ 2.50662827563479526904, 225.525584619175212544, -268.295973841304927459, 80.9030806934622512966, -5.00757863970517583837, 0.0114684895434781459556 }; + double t = arg + 4.65, s = p[0]; + for(unsigned int i=0; i<5; ++i) + s += p[i+1] / (arg+i); + return std::log(s) + (arg-0.5)*std::log(t) - t; +*/ static const f31 pi(0xC90FDAA2, 1), lbe(0xB8AA3B29, 0); + unsigned int abs = arg & 0x7FFF, sign = arg & 0x8000; + bool bsign = sign != 0; + f31 z(abs), x = sign ? (z+f31(0x80000000, 0)) : z, t = x + f31(0x94CCCCCD, 2), s = + f31(0xA06C9901, 1) + f31(0xBBE654E2, -7)/(x+f31(0x80000000, 2)) + f31(0xA1CE6098, 6)/(x+f31(0x80000000, 1)) + + f31(0xE1868CB7, 7)/x - f31(0x8625E279, 8)/(x+f31(0x80000000, 0)) - f31(0xA03E158F, 2)/(x+f31(0xC0000000, 1)); + int i = (s.exp>=2) + (s.exp>=4) + (s.exp>=8) + (s.exp>=16); + s = f31((static_cast(s.exp)<<(31-i))+(log2(s.m>>1, 28)>>i), i) / lbe; + if(x.exp != -1 || x.m != 0x80000000) { + i = (t.exp>=2) + (t.exp>=4) + (t.exp>=8); + f31 l = f31((static_cast(t.exp)<<(31-i))+(log2(t.m>>1, 30)>>i), i) / lbe; + s = (x.exp<-1) ? (s-(f31(0x80000000, -1)-x)*l) : (s+(x-f31(0x80000000, -1))*l); + } + s = x.exp ? (s-t) : (t-s); + if(bsign) { + if(z.exp >= 0) { + sign &= (L|((z.m>>(31-z.exp))&1)) - 1; + for(z=f31((z.m<<(1+z.exp))&0xFFFFFFFF, -1); z.m<0x80000000; z.m<<=1,--z.exp) ; + } + if(z.exp == -1) + z = f31(0x80000000, 0) - z; + if(z.exp < -1) { + z = z * pi; + z.m = sincos(z.m>>(1-z.exp), 30).first; + for(z.exp=1; z.m<0x80000000; z.m<<=1,--z.exp) ; + } + else + z = f31(0x80000000, 0); + } if(L) { + if(bsign) { + f31 l(0x92868247, 0); + if(z.exp < 0) { + uint32 m = log2((z.m+1)>>1, 27); + z = f31(-((static_cast(z.exp)<<26)+(m>>5)), 5); + for(; z.m<0x80000000; z.m<<=1,--z.exp) ; + l = l + z / lbe; + } + sign = static_cast(x.exp&&(l.exp(x.exp==0) << 15; + if(s.exp < -24) + return underflow(sign); + if(s.exp > 15) + return overflow(sign); + } + } else { + s = s * lbe; + uint32 m; + if(s.exp < 0) { + m = s.m >> -s.exp; + s.exp = 0; + } else { + m = (s.m<>(31-s.exp)); + } + s.m = exp2(m, 27); + if(!x.exp) + s = f31(0x80000000, 0) / s; + if(bsign) { + if(z.exp < 0) + s = s * z; + s = pi / s; + if(s.exp < -24) + return underflow(sign); + } else if(z.exp > 0 && !(z.m&((1<<(31-z.exp))-1))) + return ((s.exp+14)<<10) + (s.m>>21); + if(s.exp > 15) + return overflow(sign); + } + return fixed2half(s.m, s.exp+14, sign); + } + /// \} + + template struct half_caster; + } + + /// Half-precision floating-point type. + /// This class implements an IEEE-conformant half-precision floating-point type with the usual arithmetic + /// operators and conversions. It is implicitly convertible to single-precision floating-point, which makes artihmetic + /// expressions and functions with mixed-type operands to be of the most precise operand type. + /// + /// According to the C++98/03 definition, the half type is not a POD type. But according to C++11's less strict and + /// extended definitions it is both a standard layout type and a trivially copyable type (even if not a POD type), which + /// means it can be standard-conformantly copied using raw binary copies. But in this context some more words about the + /// actual size of the type. Although the half is representing an IEEE 16-bit type, it does not neccessarily have to be of + /// exactly 16-bits size. But on any reasonable implementation the actual binary representation of this type will most + /// probably not ivolve any additional "magic" or padding beyond the simple binary representation of the underlying 16-bit + /// IEEE number, even if not strictly guaranteed by the standard. But even then it only has an actual size of 16 bits if + /// your C++ implementation supports an unsigned integer type of exactly 16 bits width. But this should be the case on + /// nearly any reasonable platform. + /// + /// So if your C++ implementation is not totally exotic or imposes special alignment requirements, it is a reasonable + /// assumption that the data of a half is just comprised of the 2 bytes of the underlying IEEE representation. + class half { + public: + /// \name Construction and assignment + /// \{ + + /// Default constructor. + /// This initializes the half to 0. Although this does not match the builtin types' default-initialization semantics + /// and may be less efficient than no initialization, it is needed to provide proper value-initialization semantics. + constexpr half() noexcept : data_() {} + + /// Conversion constructor. + /// \param rhs float to convert + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + //explicit half(float rhs) : data_(static_cast(detail::float2half(rhs))) {} + + /// Conversion constructor. + /// \param rhs float to convert + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + template + half(T rhs) : data_(static_cast(detail::float2half(static_cast(rhs)))) {} + + /// Conversion to single-precision. + /// \return single precision value representing expression value + operator float() const { return detail::half2float(data_); } + + /// Assignment operator. + /// \param rhs single-precision value to copy from + /// \return reference to this half + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + half& operator=(const float &rhs) { data_ = static_cast(detail::float2half(rhs)); return *this; } + + template + half& operator=(const T &rhs) { return *this = static_cast(rhs); } + + /// \} + /// \name Arithmetic updates + /// \{ + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to add + /// \return reference to this half + /// \exception FE_... according to operator+(half,half) + half& operator+=(half rhs) { return *this = *this + rhs; } + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to subtract + /// \return reference to this half + /// \exception FE_... according to operator-(half,half) + half& operator-=(half rhs) { return *this = *this - rhs; } + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to multiply with + /// \return reference to this half + /// \exception FE_... according to operator*(half,half) + half& operator*=(half rhs) { return *this = *this * rhs; } + + /// Arithmetic assignment. + /// \tparam T type of concrete half expression + /// \param rhs half expression to divide by + /// \return reference to this half + /// \exception FE_... according to operator/(half,half) + half& operator/=(half rhs) { return *this = *this / rhs; } + + /* + /// Arithmetic assignment. + /// \param rhs single-precision value to add + /// \return reference to this half + /// \exception FE_... according to operator=() + half& operator+=(float rhs) { return *this = *this + rhs; } + + /// Arithmetic assignment. + /// \param rhs single-precision value to subtract + /// \return reference to this half + /// \exception FE_... according to operator=() + half& operator-=(float rhs) { return *this = *this - rhs; } + + /// Arithmetic assignment. + /// \param rhs single-precision value to multiply with + /// \return reference to this half + /// \exception FE_... according to operator=() + half& operator*=(float rhs) { return *this = *this * rhs; } + + /// Arithmetic assignment. + /// \param rhs single-precision value to divide by + /// \return reference to this half + /// \exception FE_... according to operator=() + half& operator/=(float rhs) { return *this = *this / rhs; } + */ + + /// \} + /// \name Increment and decrement + /// \{ + + /// Prefix increment. + /// \return incremented half value + /// \exception FE_... according to operator+(half,half) + half& operator++() { return *this = *this + half(detail::binary, 0x3C00); } + + /// Prefix decrement. + /// \return decremented half value + /// \exception FE_... according to operator-(half,half) + half& operator--() { return *this = *this + half(detail::binary, 0xBC00); } + + /// Postfix increment. + /// \return non-incremented half value + /// \exception FE_... according to operator+(half,half) + half operator++(int) { half out(*this); ++*this; return out; } + + /// Postfix decrement. + /// \return non-decremented half value + /// \exception FE_... according to operator-(half,half) + half operator--(int) { half out(*this); --*this; return out; } + /// \} + detail::uint16 get_data()const{ return data_; } + + private: + /// Rounding mode to use + static const std::float_round_style round_style = (std::float_round_style)(HALF_ROUND_STYLE); + + /// Constructor. + /// \param bits binary representation to set half to + constexpr half(detail::binary_t, unsigned int bits) noexcept : data_(static_cast(bits)) {} + + /// Internal binary representation + detail::uint16 data_; + + friend constexpr_NOERR bool operator==(half, half); + template friend constexpr_NOERR bool operator==(half, T); + template friend constexpr_NOERR bool operator==(T, half); + friend constexpr_NOERR bool operator!=(half, half); + template friend constexpr_NOERR bool operator!=(half, T); + template friend constexpr_NOERR bool operator!=(T, half); + friend constexpr_NOERR bool operator<(half, half); + template friend constexpr_NOERR bool operator<(half, T); + template friend constexpr_NOERR bool operator<(T, half); + friend constexpr_NOERR bool operator>(half, half); + template friend constexpr_NOERR bool operator>(half, T); + template friend constexpr_NOERR bool operator>(T, half); + friend constexpr_NOERR bool operator<=(half, half); + template friend constexpr_NOERR bool operator<=(half, T); + template friend constexpr_NOERR bool operator<=(T, half); + friend constexpr_NOERR bool operator>=(half, half); + template friend constexpr_NOERR bool operator>=(half, T); + template friend constexpr_NOERR bool operator>=(T, half); + friend constexpr half operator+(half); + friend constexpr half operator-(half); + friend half operator+(half, half); + template friend half operator+(half, T); + template friend half operator+(T, half); + friend half operator-(half, half); + template friend half operator-(half, T); + template friend half operator-(T, half); + friend half operator*(half, half); + template friend half operator*(half, T); + template friend half operator*(T, half); + friend half operator/(half, half); + template friend half operator/(half, T); + template friend half operator/(T, half); + template friend std::basic_ostream& operator<<(std::basic_ostream&, half); + template friend std::basic_istream& operator>>(std::basic_istream&, half&); + friend constexpr half fabs(half); + friend half fmod(half, half); + friend half remainder(half, half); + friend half remquo(half, half, int*); + friend half fma(half, half, half); + friend constexpr_NOERR half fmax(half, half); + friend constexpr_NOERR half fmin(half, half); + friend half fdim(half, half); + friend half nanh(const char*); + friend half exp(half); + friend half exp2(half); + friend half expm1(half); + friend half log(half); + friend half log10(half); + friend half log2(half); + friend half log1p(half); + friend half sqrt(half); + friend half cbrt(half); + friend half hypot(half, half); + friend half hypot(half, half, half); + friend half pow(half, half); + friend void sincos(half, half*, half*); + friend half sin(half); + friend half cos(half); + friend half tan(half); + friend half asin(half); + friend half acos(half); + friend half atan(half); + friend half atan2(half, half); + friend half sinh(half); + friend half cosh(half); + friend half tanh(half); + friend half asinh(half); + friend half acosh(half); + friend half atanh(half); + friend half erf(half); + friend half erfc(half); + friend half lgamma(half); + friend half tgamma(half); + friend half ceil(half); + friend half floor(half); + friend half trunc(half); + friend half round(half); + friend long lround(half); + friend half rint(half); + friend long lrint(half); + friend half nearbyint(half); + friend long long llround(half); + friend long long llrint(half); + friend half frexp(half, int*); + friend half scalbln(half, long); + friend half modf(half, half*); + friend int ilogb(half); + friend half logb(half); + friend half nextafter(half, half); + friend half nexttoward(half, long double); + friend constexpr half copysign(half, half); + friend constexpr int fpclassify(half); + friend constexpr bool isfinite(half); + friend constexpr bool isinf(half); + friend constexpr bool isnan(half); + friend constexpr bool isnormal(half); + friend constexpr bool signbit(half); + friend constexpr bool isgreater(half, half); + friend constexpr bool isgreaterequal(half, half); + friend constexpr bool isless(half, half); + friend constexpr bool islessequal(half, half); + friend constexpr bool islessgreater(half, half); + template friend struct detail::half_caster; + friend class std::numeric_limits; + friend struct std::hash; + friend half literal::operator "" _h(long double); + }; + + namespace literal { + /// Half literal. + /// While this returns a properly rounded half-precision value, half literals can unfortunately not be constant + /// expressions due to rather involved conversions. So don't expect this to be a literal literal without involving + /// conversion operations at runtime. It is a convenience feature, not a performance optimization. + /// \param value literal value + /// \return half with of given value (possibly rounded) + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half operator "" _h(long double value) { return half(detail::binary, detail::float2half(value)); } + } + + namespace detail { + /// Helper class for half casts. + /// This class template has to be specialized for all valid cast arguments to define an appropriate static + /// `cast` member function and a corresponding `type` member denoting its return type. + /// \tparam T destination type + /// \tparam U source type + /// \tparam R rounding mode to use + template struct half_caster {}; + template struct half_caster { + static_assert(std::is_arithmetic::value, "half_cast from non-arithmetic type unsupported"); + static half cast(U arg) { return cast_impl(arg, is_float()); }; + private: + static half cast_impl(U arg, true_type) { return half(binary, float2half(arg)); } + static half cast_impl(U arg, false_type) { return half(binary, int2half(arg)); } + }; + template struct half_caster { + static_assert(std::is_arithmetic::value, "half_cast to non-arithmetic type unsupported"); + static T cast(half arg) { return cast_impl(arg, is_float()); } + private: + static T cast_impl(half arg, true_type) { return half2float(arg.data_); } + static T cast_impl(half arg, false_type) { return half2int(arg.data_); } + }; + template struct half_caster { + static half cast(half arg) { return arg; } + }; + } +} + +/// Extensions to the C++ standard library. +namespace std { + /// Numeric limits for half-precision floats. + /// **See also:** Documentation for [std::numeric_limits](https://en.cppreference.com/w/cpp/types/numeric_limits) + template<> class numeric_limits { + public: + /// Is template specialization. + static constexpr bool is_specialized = true; + + /// Supports signed values. + static constexpr bool is_signed = true; + + /// Is not an integer type. + static constexpr bool is_integer = false; + + /// Is not exact. + static constexpr bool is_exact = false; + + /// Doesn't provide modulo arithmetic. + static constexpr bool is_modulo = false; + + /// Has a finite set of values. + static constexpr bool is_bounded = true; + + /// IEEE conformant. + static constexpr bool is_iec559 = true; + + /// Supports infinity. + static constexpr bool has_infinity = true; + + /// Supports quiet NaNs. + static constexpr bool has_quiet_NaN = true; + + /// Supports signaling NaNs. + static constexpr bool has_signaling_NaN = true; + + /// Supports subnormal values. + static constexpr float_denorm_style has_denorm = denorm_present; + + /// Supports no denormalization detection. + static constexpr bool has_denorm_loss = false; + + #if HALF_ERRHANDLING_THROWS + static constexpr bool traps = true; + #else + /// Traps only if [HALF_ERRHANDLING_THROW_...](\ref HALF_ERRHANDLING_THROW_INVALID) is acitvated. + static constexpr bool traps = false; + #endif + + /// Does not support no pre-rounding underflow detection. + static constexpr bool tinyness_before = false; + + /// Rounding mode. + static constexpr float_round_style round_style = half_float::half::round_style; + + /// Significant digits. + static constexpr int digits = 11; + + /// Significant decimal digits. + static constexpr int digits10 = 3; + + /// Required decimal digits to represent all possible values. + static constexpr int max_digits10 = 5; + + /// Number base. + static constexpr int radix = 2; + + /// One more than smallest exponent. + static constexpr int min_exponent = -13; + + /// Smallest normalized representable power of 10. + static constexpr int min_exponent10 = -4; + + /// One more than largest exponent + static constexpr int max_exponent = 16; + + /// Largest finitely representable power of 10. + static constexpr int max_exponent10 = 4; + + /// Smallest positive normal value. + static constexpr half_float::half min() noexcept { return half_float::half(half_float::detail::binary, 0x0400); } + + /// Smallest finite value. + static constexpr half_float::half lowest() noexcept { return half_float::half(half_float::detail::binary, 0xFBFF); } + + /// Largest finite value. + static constexpr half_float::half max() noexcept { return half_float::half(half_float::detail::binary, 0x7BFF); } + + /// Difference between 1 and next representable value. + static constexpr half_float::half epsilon() noexcept { return half_float::half(half_float::detail::binary, 0x1400); } + + /// Maximum rounding error in ULP (units in the last place). + static constexpr half_float::half round_error() noexcept + { return half_float::half(half_float::detail::binary, (round_style==std::round_to_nearest) ? 0x3800 : 0x3C00); } + + /// Positive infinity. + static constexpr half_float::half infinity() noexcept { return half_float::half(half_float::detail::binary, 0x7C00); } + + /// Quiet NaN. + static constexpr half_float::half quiet_NaN() noexcept { return half_float::half(half_float::detail::binary, 0x7FFF); } + + /// Signaling NaN. + static constexpr half_float::half signaling_NaN() noexcept { return half_float::half(half_float::detail::binary, 0x7DFF); } + + /// Smallest positive subnormal value. + static constexpr half_float::half denorm_min() noexcept { return half_float::half(half_float::detail::binary, 0x0001); } + }; + + /// Hash function for half-precision floats. + /// **See also:** Documentation for [std::hash](https://en.cppreference.com/w/cpp/utility/hash) + template<> struct hash { + /// Type of function argument. + typedef half_float::half argument_type; + + /// Function return type. + typedef size_t result_type; + + /// Compute hash function. + /// \param arg half to hash + /// \return hash value + result_type operator()(argument_type arg) const { return hash()(arg.data_&-static_cast(arg.data_!=0x8000)); } + }; +} + +namespace half_float { + /// \anchor compop + /// \name Comparison operators + /// \{ + + /// Comparison for equality. + /// \param x first operand + /// \param y second operand + /// \retval true if operands equal + /// \retval false else + /// \exception FE_INVALID if \a x or \a y is NaN + inline constexpr_NOERR bool operator==(half x, half y) { + return !detail::compsignal(x.data_, y.data_) && (x.data_==y.data_ || !((x.data_|y.data_)&0x7FFF)); + } + template + inline constexpr_NOERR bool operator==(half x, T y) { return x == static_cast(y); } + template + inline constexpr_NOERR bool operator==(T x, half y) { return static_cast(x) == y; } + + /// Comparison for inequality. + /// \param x first operand + /// \param y second operand + /// \retval true if operands not equal + /// \retval false else + /// \exception FE_INVALID if \a x or \a y is NaN + inline constexpr_NOERR bool operator!=(half x, half y) { + return detail::compsignal(x.data_, y.data_) || (x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF)); + } + template + inline constexpr_NOERR bool operator!=(half x, T y) { return x != static_cast(y); } + template + inline constexpr_NOERR bool operator!=(T x, half y) { return static_cast(x) != y; } + + /// Comparison for less than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less than \a y + /// \retval false else + /// \exception FE_INVALID if \a x or \a y is NaN + inline constexpr_NOERR bool operator<(half x, half y) { + return !detail::compsignal(x.data_, y.data_) && + ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)); + } + template + inline constexpr_NOERR bool operator<(half x, T y) { return x < static_cast(y); } + template + inline constexpr_NOERR bool operator<(T x, half y) { return static_cast(x) < y; } + + /// Comparison for greater than. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater than \a y + /// \retval false else + /// \exception FE_INVALID if \a x or \a y is NaN + inline constexpr_NOERR bool operator>(half x, half y) { + return !detail::compsignal(x.data_, y.data_) && + ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)); + } + template + inline constexpr_NOERR bool operator>(half x, T y) { return x > static_cast(y); } + template + inline constexpr_NOERR bool operator>(T x, half y) { return static_cast(x) > y; } + + /// Comparison for less equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less equal \a y + /// \retval false else + /// \exception FE_INVALID if \a x or \a y is NaN + inline constexpr_NOERR bool operator<=(half x, half y) { + return !detail::compsignal(x.data_, y.data_) && + ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)); + } + template + inline constexpr_NOERR bool operator<=(half x, T y) { return x <= static_cast(y); } + template + inline constexpr_NOERR bool operator<=(T x, half y) { return static_cast(x) <= y; } + + /// Comparison for greater equal. + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater equal \a y + /// \retval false else + /// \exception FE_INVALID if \a x or \a y is NaN + inline constexpr_NOERR bool operator>=(half x, half y) { + return !detail::compsignal(x.data_, y.data_) && + ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)); + } + template + inline constexpr_NOERR bool operator>=(half x, T y) { return x >= static_cast(y); } + template + inline constexpr_NOERR bool operator>=(T x, half y) { return static_cast(x) >= y; } + + /// \} + /// \anchor arithmetics + /// \name Arithmetic operators + /// \{ + + /// Identity. + /// \param arg operand + /// \return unchanged operand + inline constexpr half operator+(half arg) { return arg; } + + /// Negation. + /// \param arg operand + /// \return negated operand + inline constexpr half operator-(half arg) { return half(detail::binary, arg.data_^0x8000); } + + /// Addition. + /// This operation is exact to rounding for all rounding modes. + /// \param x left operand + /// \param y right operand + /// \return sum of half expressions + /// \exception FE_INVALID if \a x and \a y are infinities with different signs or signaling NaNs + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half operator+(half x, half y) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(detail::half2float(x.data_)+detail::half2float(y.data_))); + #else + int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF; + bool sub = ((x.data_^y.data_)&0x8000) != 0; + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : (absy!=0x7C00) ? x.data_ : + (sub && absx==0x7C00) ? detail::invalid() : y.data_); + if(!absx) + return absy ? y : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (x.data_|y.data_) : (x.data_&y.data_)); + if(!absy) + return x; + unsigned int sign = ((sub && absy>absx) ? y.data_ : x.data_) & 0x8000; + if(absy > absx) + std::swap(absx, absy); + int exp = (absx>>10) + (absx<=0x3FF), d = exp - (absy>>10) - (absy<=0x3FF), mx = ((absx&0x3FF)|((absx>0x3FF)<<10)) << 3, my; + if(d < 13) { + my = ((absy&0x3FF)|((absy>0x3FF)<<10)) << 3; + my = (my>>d) | ((my&((1<(half::round_style==std::round_toward_neg_infinity)<<15); + for(; mx<0x2000 && exp>1; mx<<=1,--exp) ; + } else { + mx += my; + int i = mx >> 14; + if((exp+=i) > 30) + return half(detail::binary, detail::overflow(sign)); + mx = (mx>>i) | (mx&i); + } + return half(detail::binary, detail::rounded(sign+((exp-1)<<10)+(mx>>3), (mx>>2)&1, (mx&0x3)!=0)); + #endif + } + template + inline half operator+(half x, T y) { return x + static_cast(y); } + template + inline half operator+(T x, half y) { return static_cast(x) + y; } + + /// Subtraction. + /// This operation is exact to rounding for all rounding modes. + /// \param x left operand + /// \param y right operand + /// \return difference of half expressions + /// \exception FE_INVALID if \a x and \a y are infinities with equal signs or signaling NaNs + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half operator-(half x, half y) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(detail::half2float(x.data_)-detail::half2float(y.data_))); + #else + return x + (-y); + #endif + } + template + inline half operator-(half x, T y) { return x - static_cast(y); } + template + inline half operator-(T x, half y) { return static_cast(x) - y; } + + /// Multiplication. + /// This operation is exact to rounding for all rounding modes. + /// \param x left operand + /// \param y right operand + /// \return product of half expressions + /// \exception FE_INVALID if multiplying 0 with infinity or if \a x or \a y is signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half operator*(half x, half y) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(detail::half2float(x.data_)*detail::half2float(y.data_))); + #else + int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -16; + unsigned int sign = (x.data_^y.data_) & 0x8000; + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : + ((absx==0x7C00 && !absy)||(absy==0x7C00 && !absx)) ? detail::invalid() : (sign|0x7C00)); + if(!absx || !absy) + return half(detail::binary, sign); + for(; absx<0x400; absx<<=1,--exp) ; + for(; absy<0x400; absy<<=1,--exp) ; + detail::uint32 m = static_cast((absx&0x3FF)|0x400) * static_cast((absy&0x3FF)|0x400); + int i = m >> 21, s = m & i; + exp += (absx>>10) + (absy>>10) + i; + if(exp > 29) + return half(detail::binary, detail::overflow(sign)); + else if(exp < -11) + return half(detail::binary, detail::underflow(sign)); + return half(detail::binary, detail::fixed2half(m>>i, exp, sign, s)); + #endif + } + template + inline half operator*(half x, T y) { return x * static_cast(y); } + template + inline half operator*(T x, half y) { return static_cast(x) * y; } + + /// Division. + /// This operation is exact to rounding for all rounding modes. + /// \param x left operand + /// \param y right operand + /// \return quotient of half expressions + /// \exception FE_INVALID if dividing 0s or infinities with each other or if \a x or \a y is signaling NaN + /// \exception FE_DIVBYZERO if dividing finite value by 0 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half operator/(half x, half y) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(detail::half2float(x.data_)/detail::half2float(y.data_))); + #else + int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = 14; + unsigned int sign = (x.data_^y.data_) & 0x8000; + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : + (absx==absy) ? detail::invalid() : (sign|((absx==0x7C00) ? 0x7C00 : 0))); + if(!absx) + return half(detail::binary, absy ? sign : detail::invalid()); + if(!absy) + return half(detail::binary, detail::pole(sign)); + for(; absx<0x400; absx<<=1,--exp) ; + for(; absy<0x400; absy<<=1,++exp) ; + detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400; + int i = mx < my; + exp += (absx>>10) - (absy>>10) - i; + if(exp > 29) + return half(detail::binary, detail::overflow(sign)); + else if(exp < -11) + return half(detail::binary, detail::underflow(sign)); + mx <<= 12 + i; + my <<= 1; + return half(detail::binary, detail::fixed2half(mx/my, exp, sign, mx%my!=0)); + #endif + } + template + inline half operator/(half x, T y) { return x / static_cast(y); } + template + inline half operator/(T x, half y) { return static_cast(x) / y; } + + /// \} + /// \anchor streaming + /// \name Input and output + /// \{ + + /// Output operator. + /// This uses the built-in functionality for streaming out floating-point numbers. + /// \param out output stream to write into + /// \param arg half expression to write + /// \return reference to output stream + template std::basic_ostream& operator<<(std::basic_ostream &out, half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return out << detail::half2float(arg.data_); + #else + return out << detail::half2float(arg.data_); + #endif + } + + /// Input operator. + /// This uses the built-in functionality for streaming in floating-point numbers, specifically double precision floating + /// point numbers (unless overridden with [HALF_ARITHMETIC_TYPE](\ref HALF_ARITHMETIC_TYPE)). So the input string is first + /// rounded to double precision using the underlying platform's current floating-point rounding mode before being rounded + /// to half-precision using the library's half-precision rounding mode. + /// \param in input stream to read from + /// \param arg half to read into + /// \return reference to input stream + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + template std::basic_istream& operator>>(std::basic_istream &in, half &arg) { + #ifdef HALF_ARITHMETIC_TYPE + detail::internal_t f; + #else + double f; + #endif + if(in >> f) + arg.data_ = detail::float2half(f); + return in; + } + + /// \} + /// \anchor basic + /// \name Basic mathematical operations + /// \{ + + /// Absolute value. + /// **See also:** Documentation for [std::fabs](https://en.cppreference.com/w/cpp/numeric/math/fabs). + /// \param arg operand + /// \return absolute value of \a arg + inline constexpr half fabs(half arg) { return half(detail::binary, arg.data_&0x7FFF); } + + /// Absolute value. + /// **See also:** Documentation for [std::abs](https://en.cppreference.com/w/cpp/numeric/math/fabs). + /// \param arg operand + /// \return absolute value of \a arg + inline constexpr half abs(half arg) { return fabs(arg); } + + /// Remainder of division. + /// **See also:** Documentation for [std::fmod](https://en.cppreference.com/w/cpp/numeric/math/fmod). + /// \param x first operand + /// \param y second operand + /// \return remainder of floating-point division. + /// \exception FE_INVALID if \a x is infinite or \a y is 0 or if \a x or \a y is signaling NaN + inline half fmod(half x, half y) { + unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000; + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : + (absx==0x7C00) ? detail::invalid() : x.data_); + if(!absy) + return half(detail::binary, detail::invalid()); + if(!absx) + return x; + if(absx == absy) + return half(detail::binary, sign); + return half(detail::binary, sign|detail::mod(absx, absy)); + } + + /// Remainder of division. + /// **See also:** Documentation for [std::remainder](https://en.cppreference.com/w/cpp/numeric/math/remainder). + /// \param x first operand + /// \param y second operand + /// \return remainder of floating-point division. + /// \exception FE_INVALID if \a x is infinite or \a y is 0 or if \a x or \a y is signaling NaN + inline half remainder(half x, half y) { + unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, sign = x.data_ & 0x8000; + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : + (absx==0x7C00) ? detail::invalid() : x.data_); + if(!absy) + return half(detail::binary, detail::invalid()); + if(absx == absy) + return half(detail::binary, sign); + return half(detail::binary, sign^detail::mod(absx, absy)); + } + + /// Remainder of division. + /// **See also:** Documentation for [std::remquo](https://en.cppreference.com/w/cpp/numeric/math/remquo). + /// \param x first operand + /// \param y second operand + /// \param quo address to store some bits of quotient at + /// \return remainder of floating-point division. + /// \exception FE_INVALID if \a x is infinite or \a y is 0 or if \a x or \a y is signaling NaN + inline half remquo(half x, half y, int *quo) { + unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, value = x.data_ & 0x8000; + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : + (absx==0x7C00) ? detail::invalid() : (*quo = 0, x.data_)); + if(!absy) + return half(detail::binary, detail::invalid()); + bool qsign = ((value^y.data_)&0x8000) != 0; + int q = 1; + if(absx != absy) + value ^= detail::mod(absx, absy, &q); + return *quo = qsign ? -q : q, half(detail::binary, value); + } + + /// Fused multiply add. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::fma](https://en.cppreference.com/w/cpp/numeric/math/fma). + /// \param x first operand + /// \param y second operand + /// \param z third operand + /// \return ( \a x * \a y ) + \a z rounded as one operation. + /// \exception FE_INVALID according to operator*() and operator+() unless any argument is a quiet NaN and no argument is a signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding the final addition + inline half fma(half x, half y, half z) { + #ifdef HALF_ARITHMETIC_TYPE + detail::internal_t fx = detail::half2float(x.data_), fy = detail::half2float(y.data_), fz = detail::half2float(z.data_); + #if FP_FAST_FMA + return half(detail::binary, detail::float2half(std::fma(fx, fy, fz))); + #else + return half(detail::binary, detail::float2half(fx*fy+fz)); + #endif + #else + int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, exp = -15; + unsigned int sign = (x.data_^y.data_) & 0x8000; + bool sub = ((sign^z.data_)&0x8000) != 0; + if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00) + return (absx>0x7C00 || absy>0x7C00 || absz>0x7C00) ? half(detail::binary, detail::signal(x.data_, y.data_, z.data_)) : + (absx==0x7C00) ? half(detail::binary, (!absy || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) : + (absy==0x7C00) ? half(detail::binary, (!absx || (sub && absz==0x7C00)) ? detail::invalid() : (sign|0x7C00)) : z; + if(!absx || !absy) + return absz ? z : half(detail::binary, (half::round_style==std::round_toward_neg_infinity) ? (z.data_|sign) : (z.data_&sign)); + for(; absx<0x400; absx<<=1,--exp) ; + for(; absy<0x400; absy<<=1,--exp) ; + detail::uint32 m = static_cast((absx&0x3FF)|0x400) * static_cast((absy&0x3FF)|0x400); + int i = m >> 21; + exp += (absx>>10) + (absy>>10) + i; + m <<= 3 - i; + if(absz) { + int expz = 0; + for(; absz<0x400; absz<<=1,--expz) ; + expz += absz >> 10; + detail::uint32 mz = static_cast((absz&0x3FF)|0x400) << 13; + if(expz > exp || (expz == exp && mz > m)) { + std::swap(m, mz); + std::swap(exp, expz); + if(sub) + sign = z.data_ & 0x8000; + } + int d = exp - expz; + mz = (d<23) ? ((mz>>d)|((mz&((static_cast(1)<(half::round_style==std::round_toward_neg_infinity)<<15); + for(; m<0x800000; m<<=1,--exp) ; + } else { + m += mz; + i = m >> 24; + m = (m>>i) | (m&i); + exp += i; + } + } + if(exp > 30) + return half(detail::binary, detail::overflow(sign)); + else if(exp < -10) + return half(detail::binary, detail::underflow(sign)); + return half(detail::binary, detail::fixed2half(m, exp-1, sign)); + #endif + } + + /// Maximum of half expressions. + /// **See also:** Documentation for [std::fmax](https://en.cppreference.com/w/cpp/numeric/math/fmax). + /// \param x first operand + /// \param y second operand + /// \return maximum of operands, ignoring quiet NaNs + /// \exception FE_INVALID if \a x or \a y is signaling NaN + inline constexpr_NOERR half fmax(half x, half y) { + return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) < + (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_)); + } + + /// Minimum of half expressions. + /// **See also:** Documentation for [std::fmin](https://en.cppreference.com/w/cpp/numeric/math/fmin). + /// \param x first operand + /// \param y second operand + /// \return minimum of operands, ignoring quiet NaNs + /// \exception FE_INVALID if \a x or \a y is signaling NaN + inline constexpr_NOERR half fmin(half x, half y) { + return half(detail::binary, (!isnan(y) && (isnan(x) || (x.data_^(0x8000|(0x8000-(x.data_>>15)))) > + (y.data_^(0x8000|(0x8000-(y.data_>>15)))))) ? detail::select(y.data_, x.data_) : detail::select(x.data_, y.data_)); + } + + /// Positive difference. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::fdim](https://en.cppreference.com/w/cpp/numeric/math/fdim). + /// \param x first operand + /// \param y second operand + /// \return \a x - \a y or 0 if difference negative + /// \exception FE_... according to operator-(half,half) + inline half fdim(half x, half y) { + if(isnan(x) || isnan(y)) + return half(detail::binary, detail::signal(x.data_, y.data_)); + return (x.data_^(0x8000|(0x8000-(x.data_>>15)))) <= (y.data_^(0x8000|(0x8000-(y.data_>>15)))) ? half(detail::binary, 0) : (x-y); + } + + /// Get NaN value. + /// **See also:** Documentation for [std::nan](https://en.cppreference.com/w/cpp/numeric/math/nan). + /// \param arg string code + /// \return quiet NaN + inline half nanh(const char *arg) { + unsigned int value = 0x7FFF; + while(*arg) + value ^= static_cast(*arg++) & 0xFF; + return half(detail::binary, value); + } + + /// \} + /// \anchor exponential + /// \name Exponential functions + /// \{ + + /// Exponential function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::exp](https://en.cppreference.com/w/cpp/numeric/math/exp). + /// \param arg function argument + /// \return e raised to \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half exp(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::exp(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF; + if(!abs) + return half(detail::binary, 0x3C00); + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_)); + if(abs >= 0x4C80) + return half(detail::binary, (arg.data_&0x8000) ? detail::underflow() : detail::overflow()); + detail::uint32 m = detail::multiply64(static_cast((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29); + int e = (abs>>10) + (abs<=0x3FF), exp; + if(e < 14) { + exp = 0; + m >>= 14 - e; + } else { + exp = m >> (45-e); + m = (m<<(e-14)) & 0x7FFFFFFF; + } + return half(detail::binary, detail::exp2_post(detail::exp2(m, 26), exp, (arg.data_&0x8000)!=0)); + #endif + } + + /// Binary exponential. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::exp2](https://en.cppreference.com/w/cpp/numeric/math/exp2). + /// \param arg function argument + /// \return 2 raised to \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half exp2(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::exp2(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF; + if(!abs) + return half(detail::binary, 0x3C00); + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? (0x7C00&((arg.data_>>15)-1U)) : detail::signal(arg.data_)); + if(abs >= 0x4E40) + return half(detail::binary, (arg.data_&0x8000) ? detail::underflow() : detail::overflow()); + int e = (abs>>10) + (abs<=0x3FF), exp = (abs&0x3FF) + ((abs>0x3FF)<<10); + detail::uint32 m = detail::exp2((static_cast(exp)<<(6+e))&0x7FFFFFFF, 28); + exp >>= 25 - e; + if(m == 0x80000000) { + if(arg.data_&0x8000) + exp = -exp; + else if(exp > 15) + return half(detail::binary, detail::overflow()); + return half(detail::binary, detail::fixed2half(m, exp+14)); + } + return half(detail::binary, detail::exp2_post(m, exp, (arg.data_&0x8000)!=0)); + #endif + } + + /// Exponential minus one. + /// This function may be 1 ULP off the correctly rounded exact result in <0.05% of inputs for `std::round_to_nearest` + /// and in <1% of inputs for any other rounding mode. + /// + /// **See also:** Documentation for [std::expm1](https://en.cppreference.com/w/cpp/numeric/math/expm1). + /// \param arg function argument + /// \return e raised to \a arg and subtracted by 1 + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half expm1(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::expm1(detail::half2float(arg.data_)))); + #else + unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000; + if(!abs) + return arg; + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? (0x7C00+(sign>>1)) : detail::signal(arg.data_)); + if(abs >= 0x4A00) + return half(detail::binary, (arg.data_&0x8000) ? detail::rounded(0xBBFF, 1, 1) : detail::overflow()); + detail::uint32 m = detail::multiply64(static_cast((abs&0x3FF)+((abs>0x3FF)<<10))<<21, 0xB8AA3B29); + int e = (abs>>10) + (abs<=0x3FF), exp; + if(e < 14) { + exp = 0; + m >>= 14 - e; + } else { + exp = m >> (45-e); + m = (m<<(e-14)) & 0x7FFFFFFF; + } + m = detail::exp2(m); + if(sign) { + int s = 0; + if(m > 0x80000000) { + ++exp; + m = detail::divide64(0x80000000, m, s); + } + m = 0x80000000 - ((m>>exp)|((m&((static_cast(1)<>exp) : 1; + for(exp+=14; m<0x80000000 && exp; m<<=1,--exp) ; + if(exp > 29) + return half(detail::binary, detail::overflow()); + return half(detail::binary, detail::rounded(sign+(exp<<10)+(m>>21), (m>>20)&1, (m&0xFFFFF)!=0)); + #endif + } + + /// Natural logarithm. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::log](https://en.cppreference.com/w/cpp/numeric/math/log). + /// \param arg function argument + /// \return logarithm of \a arg to base e + /// \exception FE_INVALID for signaling NaN or negative argument + /// \exception FE_DIVBYZERO for 0 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half log(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::log(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp = -15; + if(!abs) + return half(detail::binary, detail::pole(0x8000)); + if(arg.data_ & 0x8000) + return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs >= 0x7C00) + return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_)); + for(; abs<0x400; abs<<=1,--exp) ; + exp += abs >> 10; + return half(detail::binary, detail::log2_post( + detail::log2(static_cast((abs&0x3FF)|0x400)<<20, 27)+8, exp, 17)); + #endif + } + + /// Common logarithm. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::log10](https://en.cppreference.com/w/cpp/numeric/math/log10). + /// \param arg function argument + /// \return logarithm of \a arg to base 10 + /// \exception FE_INVALID for signaling NaN or negative argument + /// \exception FE_DIVBYZERO for 0 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half log10(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::log10(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp = -15; + if(!abs) + return half(detail::binary, detail::pole(0x8000)); + if(arg.data_ & 0x8000) + return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs >= 0x7C00) + return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_)); + switch(abs) { + case 0x4900: return half(detail::binary, 0x3C00); + case 0x5640: return half(detail::binary, 0x4000); + case 0x63D0: return half(detail::binary, 0x4200); + case 0x70E2: return half(detail::binary, 0x4400); + } + for(; abs<0x400; abs<<=1,--exp) ; + exp += abs >> 10; + return half(detail::binary, detail::log2_post( + detail::log2(static_cast((abs&0x3FF)|0x400)<<20, 27)+8, exp, 16)); + #endif + } + + /// Binary logarithm. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::log2](https://en.cppreference.com/w/cpp/numeric/math/log2). + /// \param arg function argument + /// \return logarithm of \a arg to base 2 + /// \exception FE_INVALID for signaling NaN or negative argument + /// \exception FE_DIVBYZERO for 0 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half log2(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::log2(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp = -15, s = 0; + if(!abs) + return half(detail::binary, detail::pole(0x8000)); + if(arg.data_ & 0x8000) + return half(detail::binary, (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs >= 0x7C00) + return (abs==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_)); + if(abs == 0x3C00) + return half(detail::binary, 0); + for(; abs<0x400; abs<<=1,--exp) ; + exp += (abs>>10); + if(!(abs&0x3FF)) { + unsigned int value = static_cast(exp<0) << 15, m = std::abs(exp) << 6; + for(exp=18; m<0x400; m<<=1,--exp) ; + return half(detail::binary, value+(exp<<10)+m); + } + detail::uint32 ilog = exp, sign = detail::sign_mask(ilog), m = + (((ilog<<27)+(detail::log2(static_cast((abs&0x3FF)|0x400)<<20, 28)>>4))^sign) - sign; + if(!m) + return half(detail::binary, 0); + for(exp=14; m<0x8000000 && exp; m<<=1,--exp) ; + for(; m>0xFFFFFFF; m>>=1,++exp) + s |= m & 1; + return half(detail::binary, detail::fixed2half(m, exp, sign&0x8000, s)); + #endif + } + + /// Natural logarithm plus one. + /// This function may be 1 ULP off the correctly rounded exact result in <0.05% of inputs for `std::round_to_nearest` + /// and in ~1% of inputs for any other rounding mode. + /// + /// **See also:** Documentation for [std::log1p](https://en.cppreference.com/w/cpp/numeric/math/log1p). + /// \param arg function argument + /// \return logarithm of \a arg plus 1 to base e + /// \exception FE_INVALID for signaling NaN or argument <-1 + /// \exception FE_DIVBYZERO for -1 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half log1p(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::log1p(detail::half2float(arg.data_)))); + #else + if(arg.data_ >= 0xBC00) + return half(detail::binary, (arg.data_==0xBC00) ? detail::pole(0x8000) : (arg.data_<=0xFC00) ? detail::invalid() : detail::signal(arg.data_)); + int abs = arg.data_ & 0x7FFF, exp = -15; + if(!abs || abs >= 0x7C00) + return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; + for(; abs<0x400; abs<<=1,--exp) ; + exp += abs >> 10; + detail::uint32 m = static_cast((abs&0x3FF)|0x400) << 20; + if(arg.data_ & 0x8000) { + m = 0x40000000 - (m>>-exp); + for(exp=0; m<0x40000000; m<<=1,--exp) ; + } else { + if(exp < 0) { + m = 0x40000000 + (m>>-exp); + exp = 0; + } else { + m += 0x40000000 >> exp; + int i = m >> 31; + m >>= i; + exp += i; + } + } + return half(detail::binary, detail::log2_post(detail::log2(m), exp, 17)); + #endif + } + + /// \} + /// \anchor power + /// \name Power functions + /// \{ + + /// Square root. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::sqrt](https://en.cppreference.com/w/cpp/numeric/math/sqrt). + /// \param arg function argument + /// \return square root of \a arg + /// \exception FE_INVALID for signaling NaN and negative arguments + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half sqrt(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::sqrt(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp = 15; + if(!abs || arg.data_ >= 0x7C00) + return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_>0x8000) ? detail::invalid() : arg.data_); + for(; abs<0x400; abs<<=1,--exp) ; + detail::uint32 r = static_cast((abs&0x3FF)|0x400) << 10, m = detail::sqrt<20>(r, exp+=abs>>10); + return half(detail::binary, detail::rounded((exp<<10)+(m&0x3FF), r>m, r!=0)); + #endif + } + + /// Cubic root. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::cbrt](https://en.cppreference.com/w/cpp/numeric/math/cbrt). + /// \param arg function argument + /// \return cubic root of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half cbrt(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::cbrt(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp = -15; + if(!abs || abs == 0x3C00 || abs >= 0x7C00) + return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; + for(; abs<0x400; abs<<=1, --exp); + detail::uint32 ilog = exp + (abs>>10), sign = detail::sign_mask(ilog), f, m = + (((ilog<<27)+(detail::log2(static_cast((abs&0x3FF)|0x400)<<20, 24)>>4))^sign) - sign; + for(exp=2; m<0x80000000; m<<=1,--exp) ; + m = detail::multiply64(m, 0xAAAAAAAB); + int i = m >> 31, s; + exp += i; + m <<= 1 - i; + if(exp < 0) { + f = m >> -exp; + exp = 0; + } else { + f = (m<> (31-exp); + } + m = detail::exp2(f, (half::round_style==std::round_to_nearest) ? 29 : 26); + if(sign) { + if(m > 0x80000000) { + m = detail::divide64(0x80000000, m, s); + ++exp; + } + exp = -exp; + } + return half(detail::binary, (half::round_style==std::round_to_nearest) ? + detail::fixed2half(m, exp+14, arg.data_&0x8000) : + detail::fixed2half((m+0x80)>>8, exp+14, arg.data_&0x8000)); + #endif + } + + /// Hypotenuse function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::hypot](https://en.cppreference.com/w/cpp/numeric/math/hypot). + /// \param x first argument + /// \param y second argument + /// \return square root of sum of squares without internal over- or underflows + /// \exception FE_INVALID if \a x or \a y is signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding of the final square root + inline half hypot(half x, half y) { + #ifdef HALF_ARITHMETIC_TYPE + detail::internal_t fx = detail::half2float(x.data_), fy = detail::half2float(y.data_); + return half(detail::binary, detail::float2half(std::hypot(fx, fy))); + #else + int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, expx = 0, expy = 0; + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, y.data_) : + (absy==0x7C00) ? detail::select(0x7C00, x.data_) : detail::signal(x.data_, y.data_)); + if(!absx) + return half(detail::binary, absy ? detail::check_underflow(absy) : 0); + if(!absy) + return half(detail::binary, detail::check_underflow(absx)); + if(absy > absx) + std::swap(absx, absy); + for(; absx<0x400; absx<<=1,--expx) ; + for(; absy<0x400; absy<<=1,--expy) ; + detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400; + mx *= mx; + my *= my; + int ix = mx >> 21, iy = my >> 21; + expx = 2*(expx+(absx>>10)) - 15 + ix; + expy = 2*(expy+(absy>>10)) - 15 + iy; + mx <<= 10 - ix; + my <<= 10 - iy; + int d = expx - expy; + my = (d<30) ? ((my>>d)|((my&((static_cast(1)<(mx+my, expx)); + #endif + } + + /// Hypotenuse function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::hypot](https://en.cppreference.com/w/cpp/numeric/math/hypot). + /// \param x first argument + /// \param y second argument + /// \param z third argument + /// \return square root of sum of squares without internal over- or underflows + /// \exception FE_INVALID if \a x, \a y or \a z is signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding of the final square root + inline half hypot(half x, half y, half z) { + #ifdef HALF_ARITHMETIC_TYPE + detail::internal_t fx = detail::half2float(x.data_), fy = detail::half2float(y.data_), fz = detail::half2float(z.data_); + return half(detail::binary, detail::float2half(std::sqrt(fx*fx+fy*fy+fz*fz))); + #else + int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0; + if(!absx) + return hypot(y, z); + if(!absy) + return hypot(x, z); + if(!absz) + return hypot(x, y); + if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00) + return half(detail::binary, (absx==0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) : + (absy==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_)) : + (absz==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_)) : + detail::signal(x.data_, y.data_, z.data_)); + if(absz > absy) + std::swap(absy, absz); + if(absy > absx) + std::swap(absx, absy); + if(absz > absy) + std::swap(absy, absz); + for(; absx<0x400; absx<<=1,--expx) ; + for(; absy<0x400; absy<<=1,--expy) ; + for(; absz<0x400; absz<<=1,--expz) ; + detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400, mz = (absz&0x3FF) | 0x400; + mx *= mx; + my *= my; + mz *= mz; + int ix = mx >> 21, iy = my >> 21, iz = mz >> 21; + expx = 2*(expx+(absx>>10)) - 15 + ix; + expy = 2*(expy+(absy>>10)) - 15 + iy; + expz = 2*(expz+(absz>>10)) - 15 + iz; + mx <<= 10 - ix; + my <<= 10 - iy; + mz <<= 10 - iz; + int d = expy - expz; + mz = (d<30) ? ((mz>>d)|((mz&((static_cast(1)<>1) | (my&1); + if(++expy > expx) { + std::swap(mx, my); + std::swap(expx, expy); + } + } + d = expx - expy; + my = (d<30) ? ((my>>d)|((my&((static_cast(1)<(mx+my, expx)); + #endif + } + + /// Power function. + /// This function may be 1 ULP off the correctly rounded exact result for any rounding mode in ~0.00025% of inputs. + /// + /// **See also:** Documentation for [std::pow](https://en.cppreference.com/w/cpp/numeric/math/pow). + /// \param x base + /// \param y exponent + /// \return \a x raised to \a y + /// \exception FE_INVALID if \a x or \a y is signaling NaN or if \a x is finite an negative and \a y is finite and not integral + /// \exception FE_DIVBYZERO if \a x is 0 and \a y is negative + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half pow(half x, half y) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::pow(detail::half2float(x.data_), detail::half2float(y.data_)))); + #else + int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, exp = -15; + if(!absy || x.data_ == 0x3C00) + return half(detail::binary, detail::select(0x3C00, (x.data_==0x3C00) ? y.data_ : x.data_)); + bool is_int = absy >= 0x6400 || (absy>=0x3C00 && !(absy&((1<<(25-(absy>>10)))-1))); + unsigned int sign = x.data_ & (static_cast((absy<0x6800)&&is_int&&((absy>>(25-(absy>>10)))&1))<<15); + if(absx >= 0x7C00 || absy >= 0x7C00) + return half(detail::binary, (absx>0x7C00 || absy>0x7C00) ? detail::signal(x.data_, y.data_) : + (absy==0x7C00) ? ((absx==0x3C00) ? 0x3C00 : (!absx && y.data_==0xFC00) ? detail::pole() : + (0x7C00&-((y.data_>>15)^(absx>0x3C00)))) : (sign|(0x7C00&((y.data_>>15)-1U)))); + if(!absx) + return half(detail::binary, (y.data_&0x8000) ? detail::pole(sign) : sign); + if((x.data_&0x8000) && !is_int) + return half(detail::binary, detail::invalid()); + if(x.data_ == 0xBC00) + return half(detail::binary, sign|0x3C00); + if(y.data_ == 0x3800) + return sqrt(x); + if(y.data_ == 0x3C00) + return half(detail::binary, detail::check_underflow(x.data_)); + if(y.data_ == 0x4000) + return x * x; + for(; absx<0x400; absx<<=1,--exp) ; + detail::uint32 ilog = exp + (absx>>10), msign = detail::sign_mask(ilog), f, m = + (((ilog<<27)+((detail::log2(static_cast((absx&0x3FF)|0x400)<<20)+8)>>4))^msign) - msign; + for(exp=-11; m<0x80000000; m<<=1,--exp) ; + for(; absy<0x400; absy<<=1,--exp) ; + m = detail::multiply64(m, static_cast((absy&0x3FF)|0x400)<<21); + int i = m >> 31; + exp += (absy>>10) + i; + m <<= 1 - i; + if(exp < 0) { + f = m >> -exp; + exp = 0; + } else { + f = (m<> (31-exp); + } + return half(detail::binary, detail::exp2_post(detail::exp2(f), exp, ((msign&1)^(y.data_>>15))!=0, sign)); + #endif + } + + /// \} + /// \anchor trigonometric + /// \name Trigonometric functions + /// \{ + + /// Compute sine and cosine simultaneously. + /// This returns the same results as sin() and cos() but is faster than calling each function individually. + /// + /// This function is exact to rounding for all rounding modes. + /// \param arg function argument + /// \param sin variable to take sine of \a arg + /// \param cos variable to take cosine of \a arg + /// \exception FE_INVALID for signaling NaN or infinity + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline void sincos(half arg, half *sin, half *cos) { + #ifdef HALF_ARITHMETIC_TYPE + detail::internal_t f = detail::half2float(arg.data_); + *sin = half(detail::binary, detail::float2half(std::sin(f))); + *cos = half(detail::binary, detail::float2half(std::cos(f))); + #else + int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15, k; + if(abs >= 0x7C00) + *sin = *cos = half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_)); + else if(!abs) { + *sin = arg; + *cos = half(detail::binary, 0x3C00); + } else if(abs < 0x2500) { + *sin = half(detail::binary, detail::rounded(arg.data_-1, 1, 1)); + *cos = half(detail::binary, detail::rounded(0x3BFF, 1, 1)); + } else { + if(half::round_style != std::round_to_nearest) { + switch(abs) { + case 0x48B7: + *sin = half(detail::binary, detail::rounded((~arg.data_&0x8000)|0x1D07, 1, 1)); + *cos = half(detail::binary, detail::rounded(0xBBFF, 1, 1)); + return; + case 0x598C: + *sin = half(detail::binary, detail::rounded((arg.data_&0x8000)|0x3BFF, 1, 1)); + *cos = half(detail::binary, detail::rounded(0x80FC, 1, 1)); + return; + case 0x6A64: + *sin = half(detail::binary, detail::rounded((~arg.data_&0x8000)|0x3BFE, 1, 1)); + *cos = half(detail::binary, detail::rounded(0x27FF, 1, 1)); + return; + case 0x6D8C: + *sin = half(detail::binary, detail::rounded((arg.data_&0x8000)|0x0FE6, 1, 1)); + *cos = half(detail::binary, detail::rounded(0x3BFF, 1, 1)); + return; + } + } + std::pair sc = detail::sincos(detail::angle_arg(abs, k), 28); + switch(k & 3) { + case 1: sc = std::make_pair(sc.second, -sc.first); break; + case 2: sc = std::make_pair(-sc.first, -sc.second); break; + case 3: sc = std::make_pair(-sc.second, sc.first); break; + } + *sin = half(detail::binary, detail::fixed2half((sc.first^-static_cast(sign))+sign)); + *cos = half(detail::binary, detail::fixed2half(sc.second)); + } + #endif + } + + /// Sine function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::sin](https://en.cppreference.com/w/cpp/numeric/math/sin). + /// \param arg function argument + /// \return sine value of \a arg + /// \exception FE_INVALID for signaling NaN or infinity + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half sin(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::sin(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, k; + if(!abs) + return arg; + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs < 0x2900) + return half(detail::binary, detail::rounded(arg.data_-1, 1, 1)); + if(half::round_style != std::round_to_nearest) + switch(abs) { + case 0x48B7: return half(detail::binary, detail::rounded((~arg.data_&0x8000)|0x1D07, 1, 1)); + case 0x6A64: return half(detail::binary, detail::rounded((~arg.data_&0x8000)|0x3BFE, 1, 1)); + case 0x6D8C: return half(detail::binary, detail::rounded((arg.data_&0x8000)|0x0FE6, 1, 1)); + } + std::pair sc = detail::sincos(detail::angle_arg(abs, k), 28); + detail::uint32 sign = -static_cast(((k>>1)&1)^(arg.data_>>15)); + return half(detail::binary, detail::fixed2half((((k&1) ? sc.second : sc.first)^sign) - sign)); + #endif + } + + /// Cosine function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::cos](https://en.cppreference.com/w/cpp/numeric/math/cos). + /// \param arg function argument + /// \return cosine value of \a arg + /// \exception FE_INVALID for signaling NaN or infinity + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half cos(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::cos(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, k; + if(!abs) + return half(detail::binary, 0x3C00); + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs < 0x2500) + return half(detail::binary, detail::rounded(0x3BFF, 1, 1)); + if(half::round_style != std::round_to_nearest && abs == 0x598C) + return half(detail::binary, detail::rounded(0x80FC, 1, 1)); + std::pair sc = detail::sincos(detail::angle_arg(abs, k), 28); + detail::uint32 sign = -static_cast(((k>>1)^k)&1); + return half(detail::binary, detail::fixed2half((((k&1) ? sc.first : sc.second)^sign) - sign)); + #endif + } + + /// Tangent function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::tan](https://en.cppreference.com/w/cpp/numeric/math/tan). + /// \param arg function argument + /// \return tangent value of \a arg + /// \exception FE_INVALID for signaling NaN or infinity + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half tan(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::tan(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp = 13, k; + if(!abs) + return arg; + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs < 0x2700) + return half(detail::binary, detail::rounded(arg.data_, 0, 1)); + if(half::round_style != std::round_to_nearest) + switch(abs) { + case 0x658C: return half(detail::binary, detail::rounded((arg.data_&0x8000)|0x07E6, 1, 1)); + case 0x7330: return half(detail::binary, detail::rounded((~arg.data_&0x8000)|0x4B62, 1, 1)); + } + std::pair sc = detail::sincos(detail::angle_arg(abs, k), 30); + if(k & 1) + sc = std::make_pair(-sc.second, sc.first); + detail::uint32 signy = detail::sign_mask(sc.first), signx = detail::sign_mask(sc.second); + detail::uint32 my = (sc.first^signy) - signy, mx = (sc.second^signx) - signx; + for(; my<0x80000000; my<<=1,--exp) ; + for(; mx<0x80000000; mx<<=1,++exp) ; + return half(detail::binary, detail::tangent_post(my, mx, exp, (signy^signx^arg.data_)&0x8000)); + #endif + } + + /// Arc sine. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::asin](https://en.cppreference.com/w/cpp/numeric/math/asin). + /// \param arg function argument + /// \return arc sine value of \a arg + /// \exception FE_INVALID for signaling NaN or if abs(\a arg) > 1 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half asin(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::asin(detail::half2float(arg.data_)))); + #else + unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000; + if(!abs) + return arg; + if(abs >= 0x3C00) + return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() : + detail::rounded(sign|0x3E48, 0, 1)); + if(abs < 0x2900) + return half(detail::binary, detail::rounded(arg.data_, 0, 1)); + if(half::round_style != std::round_to_nearest && (abs == 0x2B44 || abs == 0x2DC3)) + return half(detail::binary, detail::rounded(arg.data_+1, 1, 1)); + std::pair sc = detail::atan2_args(abs); + detail::uint32 m = detail::atan2(sc.first, sc.second, (half::round_style==std::round_to_nearest) ? 27 : 26); + return half(detail::binary, detail::fixed2half(m, 14, sign)); + #endif + } + + /// Arc cosine function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::acos](https://en.cppreference.com/w/cpp/numeric/math/acos). + /// \param arg function argument + /// \return arc cosine value of \a arg + /// \exception FE_INVALID for signaling NaN or if abs(\a arg) > 1 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half acos(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::acos(detail::half2float(arg.data_)))); + #else + unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ >> 15; + if(!abs) + return half(detail::binary, detail::rounded(0x3E48, 0, 1)); + if(abs >= 0x3C00) + return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (abs>0x3C00) ? detail::invalid() : + sign ? detail::rounded(0x4248, 0, 1) : 0); + std::pair cs = detail::atan2_args(abs); + detail::uint32 m = detail::atan2(cs.second, cs.first, 28); + return half(detail::binary, detail::fixed2half(sign ? (0xC90FDAA2-m) : m, 15, 0, sign)); + #endif + } + + /// Arc tangent function. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::atan](https://en.cppreference.com/w/cpp/numeric/math/atan). + /// \param arg function argument + /// \return arc tangent value of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half atan(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::atan(detail::half2float(arg.data_)))); + #else + unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000; + if(!abs) + return arg; + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? detail::rounded(sign|0x3E48, 0, 1) : detail::signal(arg.data_)); + if(abs <= 0x2700) + return half(detail::binary, detail::rounded(arg.data_-1, 1, 1)); + int exp = (abs>>10) + (abs<=0x3FF); + detail::uint32 my = (abs&0x3FF) | ((abs>0x3FF)<<10); + detail::uint32 m = (exp>15) ? detail::atan2(my<<19, 0x20000000>>(exp-15), (half::round_style==std::round_to_nearest) ? 26 : 24) : + detail::atan2(my<<(exp+4), 0x20000000, (half::round_style==std::round_to_nearest) ? 30 : 28); + return half(detail::binary, detail::fixed2half(m, 14, sign)); + #endif + } + + /// Arc tangent function. + /// This function may be 1 ULP off the correctly rounded exact result in ~0.005% of inputs for `std::round_to_nearest`, + /// in ~0.1% of inputs for `std::round_toward_zero` and in ~0.02% of inputs for any other rounding mode. + /// + /// **See also:** Documentation for [std::atan2](https://en.cppreference.com/w/cpp/numeric/math/atan2). + /// \param y numerator + /// \param x denominator + /// \return arc tangent value + /// \exception FE_INVALID if \a x or \a y is signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half atan2(half y, half x) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::atan2(detail::half2float(y.data_), detail::half2float(x.data_)))); + #else + unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000; + if(absx >= 0x7C00 || absy >= 0x7C00) { + if(absx > 0x7C00 || absy > 0x7C00) + return half(detail::binary, detail::signal(x.data_, y.data_)); + if(absy == 0x7C00) + return half(detail::binary, (absx<0x7C00) ? detail::rounded(signy|0x3E48, 0, 1) : + signx ? detail::rounded(signy|0x40B6, 0, 1) : + detail::rounded(signy|0x3A48, 0, 1)); + return (x.data_==0x7C00) ? half(detail::binary, signy) : half(detail::binary, detail::rounded(signy|0x4248, 0, 1)); + } + if(!absy) + return signx ? half(detail::binary, detail::rounded(signy|0x4248, 0, 1)) : y; + if(!absx) + return half(detail::binary, detail::rounded(signy|0x3E48, 0, 1)); + int d = (absy>>10) + (absy<=0x3FF) - (absx>>10) - (absx<=0x3FF); + if(d > (signx ? 18 : 12)) + return half(detail::binary, detail::rounded(signy|0x3E48, 0, 1)); + if(signx && d < -11) + return half(detail::binary, detail::rounded(signy|0x4248, 0, 1)); + if(!signx && d < ((half::round_style==std::round_toward_zero) ? -15 : -9)) { + for(; absy<0x400; absy<<=1,--d) ; + detail::uint32 mx = ((absx<<1)&0x7FF) | 0x800, my = ((absy<<1)&0x7FF) | 0x800; + int i = my < mx; + d -= i; + if(d < -25) + return half(detail::binary, detail::underflow(signy)); + my <<= 11 + i; + return half(detail::binary, detail::fixed2half(my/mx, d+14, signy, my%mx!=0)); + } + detail::uint32 m = detail::atan2( ((absy&0x3FF)|((absy>0x3FF)<<10))<<(19+((d<0) ? d : (d>0) ? 0 : -1)), + ((absx&0x3FF)|((absx>0x3FF)<<10))<<(19-((d>0) ? d : (d<0) ? 0 : 1))); + return half(detail::binary, detail::fixed2half(signx ? (0xC90FDAA2-m) : m, 15, signy, signx)); + #endif + } + + /// \} + /// \anchor hyperbolic + /// \name Hyperbolic functions + /// \{ + + /// Hyperbolic sine. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::sinh](https://en.cppreference.com/w/cpp/numeric/math/sinh). + /// \param arg function argument + /// \return hyperbolic sine value of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half sinh(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::sinh(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp; + if(!abs || abs >= 0x7C00) + return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; + if(abs <= 0x2900) + return half(detail::binary, detail::rounded(arg.data_, 0, 1)); + std::pair mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 29 : 27); + detail::uint32 m = mm.first - mm.second; + for(exp+=13; m<0x80000000 && exp; m<<=1,--exp) ; + unsigned int sign = arg.data_ & 0x8000; + if(exp > 29) + return half(detail::binary, detail::overflow(sign)); + return half(detail::binary, detail::fixed2half(m, exp, sign)); + #endif + } + + /// Hyperbolic cosine. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::cosh](https://en.cppreference.com/w/cpp/numeric/math/cosh). + /// \param arg function argument + /// \return hyperbolic cosine value of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half cosh(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::cosh(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp; + if(!abs) + return half(detail::binary, 0x3C00); + if(abs >= 0x7C00) + return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : 0x7C00); + std::pair mm = detail::hyperbolic_args(abs, exp, (half::round_style==std::round_to_nearest) ? 23 : 26); + detail::uint32 m = mm.first + mm.second, i = (~m&0xFFFFFFFF) >> 31; + m = (m>>i) | (m&i) | 0x80000000; + if((exp+=13+i) > 29) + return half(detail::binary, detail::overflow()); + return half(detail::binary, detail::fixed2half(m, exp)); + #endif + } + + /// Hyperbolic tangent. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::tanh](https://en.cppreference.com/w/cpp/numeric/math/tanh). + /// \param arg function argument + /// \return hyperbolic tangent value of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half tanh(half arg) { + #ifdef HALF_ARITHMETIC_TYPE + return half(detail::binary, detail::float2half(std::tanh(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp; + if(!abs) + return arg; + if(abs >= 0x7C00) + return half(detail::binary, (abs>0x7C00) ? detail::signal(arg.data_) : (arg.data_-0x4000)); + if(abs >= 0x4500) + return half(detail::binary, detail::rounded((arg.data_&0x8000)|0x3BFF, 1, 1)); + if(abs < 0x2700) + return half(detail::binary, detail::rounded(arg.data_-1, 1, 1)); + if(half::round_style != std::round_to_nearest && abs == 0x2D3F) + return half(detail::binary, detail::rounded(arg.data_-3, 0, 1)); + std::pair mm = detail::hyperbolic_args(abs, exp, 27); + detail::uint32 my = mm.first - mm.second - (half::round_style!=std::round_to_nearest), mx = mm.first + mm.second, i = (~mx&0xFFFFFFFF) >> 31; + for(exp=13; my<0x80000000; my<<=1,--exp) ; + mx = (mx>>i) | 0x80000000; + return half(detail::binary, detail::tangent_post(my, mx, exp-i, arg.data_&0x8000)); + #endif + } + + /// Hyperbolic area sine. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::asinh](https://en.cppreference.com/w/cpp/numeric/math/asinh). + /// \param arg function argument + /// \return area sine value of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half asinh(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::asinh(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF; + if(!abs || abs >= 0x7C00) + return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; + if(abs <= 0x2900) + return half(detail::binary, detail::rounded(arg.data_-1, 1, 1)); + if(half::round_style != std::round_to_nearest) + switch(abs) + { + case 0x32D4: return half(detail::binary, detail::rounded(arg.data_-13, 1, 1)); + case 0x3B5B: return half(detail::binary, detail::rounded(arg.data_-197, 1, 1)); + } + return half(detail::binary, detail::area(arg.data_)); + #endif + } + + /// Hyperbolic area cosine. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::acosh](https://en.cppreference.com/w/cpp/numeric/math/acosh). + /// \param arg function argument + /// \return area cosine value of \a arg + /// \exception FE_INVALID for signaling NaN or arguments <1 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half acosh(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::acosh(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF; + if((arg.data_&0x8000) || abs < 0x3C00) + return half(detail::binary, (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs == 0x3C00) + return half(detail::binary, 0); + if(arg.data_ >= 0x7C00) + return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; + return half(detail::binary, detail::area(arg.data_)); + #endif + } + + /// Hyperbolic area tangent. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::atanh](https://en.cppreference.com/w/cpp/numeric/math/atanh). + /// \param arg function argument + /// \return area tangent value of \a arg + /// \exception FE_INVALID for signaling NaN or if abs(\a arg) > 1 + /// \exception FE_DIVBYZERO for +/-1 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half atanh(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::atanh(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF, exp = 0; + if(!abs) + return arg; + if(abs >= 0x3C00) + return half(detail::binary, (abs==0x3C00) ? detail::pole(arg.data_&0x8000) : (abs<=0x7C00) ? detail::invalid() : detail::signal(arg.data_)); + if(abs < 0x2700) + return half(detail::binary, detail::rounded(arg.data_, 0, 1)); + detail::uint32 m = static_cast((abs&0x3FF)|((abs>0x3FF)<<10)) << ((abs>>10)+(abs<=0x3FF)+6), my = 0x80000000 + m, mx = 0x80000000 - m; + for(; mx<0x80000000; mx<<=1,++exp) ; + int i = my >= mx, s; + return half(detail::binary, detail::log2_post(detail::log2( + (detail::divide64(my>>i, mx, s)+1)>>1, 27)+0x10, exp+i-1, 16, arg.data_&0x8000)); + #endif + } + + /// \} + /// \anchor special + /// \name Error and gamma functions + /// \{ + + /// Error function. + /// This function may be 1 ULP off the correctly rounded exact result for any rounding mode in <0.5% of inputs. + /// + /// **See also:** Documentation for [std::erf](https://en.cppreference.com/w/cpp/numeric/math/erf). + /// \param arg function argument + /// \return error function value of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half erf(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::erf(detail::half2float(arg.data_)))); + #else + unsigned int abs = arg.data_ & 0x7FFF; + if(!abs || abs >= 0x7C00) + return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (arg.data_-0x4000) : detail::signal(arg.data_)) : arg; + if(abs >= 0x4200) + return half(detail::binary, detail::rounded((arg.data_&0x8000)|0x3BFF, 1, 1)); + return half(detail::binary, detail::erf(arg.data_)); + #endif + } + + /// Complementary error function. + /// This function may be 1 ULP off the correctly rounded exact result for any rounding mode in <0.5% of inputs. + /// + /// **See also:** Documentation for [std::erfc](https://en.cppreference.com/w/cpp/numeric/math/erfc). + /// \param arg function argument + /// \return 1 minus error function value of \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half erfc(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::erfc(detail::half2float(arg.data_)))); + #else + unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000; + if(abs >= 0x7C00) + return (abs>=0x7C00) ? half(detail::binary, (abs==0x7C00) ? (sign>>1) : detail::signal(arg.data_)) : arg; + if(!abs) + return half(detail::binary, 0x3C00); + if(abs >= 0x4400) + return half(detail::binary, detail::rounded((sign>>1)-(sign>>15), sign>>15, 1)); + return half(detail::binary, detail::erf(arg.data_)); + #endif + } + + /// Natural logarithm of gamma function. + /// This function may be 1 ULP off the correctly rounded exact result for any rounding mode in ~0.025% of inputs. + /// + /// **See also:** Documentation for [std::lgamma](https://en.cppreference.com/w/cpp/numeric/math/lgamma). + /// \param arg function argument + /// \return natural logarith of gamma function for \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_DIVBYZERO for 0 or negative integer arguments + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half lgamma(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::lgamma(detail::half2float(arg.data_)))); + #else + int abs = arg.data_ & 0x7FFF; + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_)); + if(!abs || arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1)))) + return half(detail::binary, detail::pole()); + if(arg.data_ == 0x3C00 || arg.data_ == 0x4000) + return half(detail::binary, 0); + return half(detail::binary, detail::gamma(arg.data_)); + #endif + } + + /// Gamma function. + /// This function may be 1 ULP off the correctly rounded exact result for any rounding mode in <0.25% of inputs. + /// + /// **See also:** Documentation for [std::tgamma](https://en.cppreference.com/w/cpp/numeric/math/tgamma). + /// \param arg function argument + /// \return gamma function value of \a arg + /// \exception FE_INVALID for signaling NaN, negative infinity or negative integer arguments + /// \exception FE_DIVBYZERO for 0 + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half tgamma(half arg) { + #if defined(HALF_ARITHMETIC_TYPE) + return half(detail::binary, detail::float2half(std::tgamma(detail::half2float(arg.data_)))); + #else + unsigned int abs = arg.data_ & 0x7FFF; + if(!abs) + return half(detail::binary, detail::pole(arg.data_)); + if(abs >= 0x7C00) + return (arg.data_==0x7C00) ? arg : half(detail::binary, detail::signal(arg.data_)); + if(arg.data_ >= 0xE400 || (arg.data_ >= 0xBC00 && !(abs&((1<<(25-(abs>>10)))-1)))) + return half(detail::binary, detail::invalid()); + if(arg.data_ >= 0xCA80) + return half(detail::binary, detail::underflow((1-((abs>>(25-(abs>>10)))&1))<<15)); + if(arg.data_ <= 0x100 || (arg.data_ >= 0x4900 && arg.data_ < 0x8000)) + return half(detail::binary, detail::overflow()); + if(arg.data_ == 0x3C00) + return arg; + return half(detail::binary, detail::gamma(arg.data_)); + #endif + } + + /// \} + /// \anchor rounding + /// \name Rounding + /// \{ + + /// Nearest integer not less than half value. + /// **See also:** Documentation for [std::ceil](https://en.cppreference.com/w/cpp/numeric/math/ceil). + /// \param arg half to round + /// \return nearest integer not less than \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_INEXACT if value had to be rounded + inline half ceil(half arg) { return half(detail::binary, detail::integral(arg.data_)); } + + /// Nearest integer not greater than half value. + /// **See also:** Documentation for [std::floor](https://en.cppreference.com/w/cpp/numeric/math/floor). + /// \param arg half to round + /// \return nearest integer not greater than \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_INEXACT if value had to be rounded + inline half floor(half arg) { return half(detail::binary, detail::integral(arg.data_)); } + + /// Nearest integer not greater in magnitude than half value. + /// **See also:** Documentation for [std::trunc](https://en.cppreference.com/w/cpp/numeric/math/trunc). + /// \param arg half to round + /// \return nearest integer not greater in magnitude than \a arg + /// \exception FE_INVALID for signaling NaN + /// \exception FE_INEXACT if value had to be rounded + inline half trunc(half arg) { return half(detail::binary, detail::integral(arg.data_)); } + + /// Nearest integer. + /// **See also:** Documentation for [std::round](https://en.cppreference.com/w/cpp/numeric/math/round). + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases + /// \exception FE_INVALID for signaling NaN + /// \exception FE_INEXACT if value had to be rounded + inline half round(half arg) { return half(detail::binary, detail::integral(arg.data_)); } + + /// Nearest integer. + /// **See also:** Documentation for [std::lround](https://en.cppreference.com/w/cpp/numeric/math/round). + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases + /// \exception FE_INVALID if value is not representable as `long` + inline long lround(half arg) { return detail::half2int(arg.data_); } + + /// Nearest integer using half's internal rounding mode. + /// **See also:** Documentation for [std::rint](https://en.cppreference.com/w/cpp/numeric/math/rint). + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + /// \exception FE_INVALID for signaling NaN + /// \exception FE_INEXACT if value had to be rounded + inline half rint(half arg) { return half(detail::binary, detail::integral(arg.data_)); } + + /// Nearest integer using half's internal rounding mode. + /// **See also:** Documentation for [std::lrint](https://en.cppreference.com/w/cpp/numeric/math/rint). + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + /// \exception FE_INVALID if value is not representable as `long` + /// \exception FE_INEXACT if value had to be rounded + inline long lrint(half arg) { return detail::half2int(arg.data_); } + + /// Nearest integer using half's internal rounding mode. + /// **See also:** Documentation for [std::nearbyint](https://en.cppreference.com/w/cpp/numeric/math/nearbyint). + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + /// \exception FE_INVALID for signaling NaN + inline half nearbyint(half arg) { return half(detail::binary, detail::integral(arg.data_)); } + /// Nearest integer. + /// **See also:** Documentation for [std::llround](https://en.cppreference.com/w/cpp/numeric/math/round). + /// \param arg half to round + /// \return nearest integer, rounded away from zero in half-way cases + /// \exception FE_INVALID if value is not representable as `long long` + inline long long llround(half arg) { return detail::half2int(arg.data_); } + + /// Nearest integer using half's internal rounding mode. + /// **See also:** Documentation for [std::llrint](https://en.cppreference.com/w/cpp/numeric/math/rint). + /// \param arg half expression to round + /// \return nearest integer using default rounding mode + /// \exception FE_INVALID if value is not representable as `long long` + /// \exception FE_INEXACT if value had to be rounded + inline long long llrint(half arg) { return detail::half2int(arg.data_); } + + /// \} + /// \anchor float + /// \name Floating point manipulation + /// \{ + + /// Decompress floating-point number. + /// **See also:** Documentation for [std::frexp](https://en.cppreference.com/w/cpp/numeric/math/frexp). + /// \param arg number to decompress + /// \param exp address to store exponent at + /// \return significant in range [0.5, 1) + /// \exception FE_INVALID for signaling NaN + inline half frexp(half arg, int *exp) { + *exp = 0; + unsigned int abs = arg.data_ & 0x7FFF; + if(abs >= 0x7C00 || !abs) + return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; + for(; abs<0x400; abs<<=1,--*exp) ; + *exp += (abs>>10) - 14; + return half(detail::binary, (arg.data_&0x8000)|0x3800|(abs&0x3FF)); + } + + /// Multiply by power of two. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::scalbln](https://en.cppreference.com/w/cpp/numeric/math/scalbn). + /// \param arg number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half scalbln(half arg, long exp) { + unsigned int abs = arg.data_ & 0x7FFF, sign = arg.data_ & 0x8000; + if(abs >= 0x7C00 || !abs) + return (abs>0x7C00) ? half(detail::binary, detail::signal(arg.data_)) : arg; + for(; abs<0x400; abs<<=1,--exp) ; + exp += abs >> 10; + if(exp > 30) + return half(detail::binary, detail::overflow(sign)); + else if(exp < -10) + return half(detail::binary, detail::underflow(sign)); + else if(exp > 0) + return half(detail::binary, sign|(exp<<10)|(abs&0x3FF)); + unsigned int m = (abs&0x3FF) | 0x400; + return half(detail::binary, detail::rounded(sign|(m>>(1-exp)), (m>>-exp)&1, (m&((1<<-exp)-1))!=0)); + } + + /// Multiply by power of two. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::scalbn](https://en.cppreference.com/w/cpp/numeric/math/scalbn). + /// \param arg number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half scalbn(half arg, int exp) { return scalbln(arg, exp); } + + /// Multiply by power of two. + /// This function is exact to rounding for all rounding modes. + /// + /// **See also:** Documentation for [std::ldexp](https://en.cppreference.com/w/cpp/numeric/math/ldexp). + /// \param arg number to modify + /// \param exp power of two to multiply with + /// \return \a arg multplied by 2 raised to \a exp + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + inline half ldexp(half arg, int exp) { return scalbln(arg, exp); } + + /// Extract integer and fractional parts. + /// **See also:** Documentation for [std::modf](https://en.cppreference.com/w/cpp/numeric/math/modf). + /// \param arg number to decompress + /// \param iptr address to store integer part at + /// \return fractional part + /// \exception FE_INVALID for signaling NaN + inline half modf(half arg, half *iptr) { + unsigned int abs = arg.data_ & 0x7FFF; + if(abs > 0x7C00) { + arg = half(detail::binary, detail::signal(arg.data_)); + return *iptr = arg, arg; + } + if(abs >= 0x6400) + return *iptr = arg, half(detail::binary, arg.data_&0x8000); + if(abs < 0x3C00) + return iptr->data_ = arg.data_ & 0x8000, arg; + unsigned int exp = abs >> 10, mask = (1<<(25-exp)) - 1, m = arg.data_ & mask; + iptr->data_ = arg.data_ & ~mask; + if(!m) + return half(detail::binary, arg.data_&0x8000); + for(; m<0x400; m<<=1,--exp) ; + return half(detail::binary, (arg.data_&0x8000)|(exp<<10)|(m&0x3FF)); + } + + /// Extract exponent. + /// **See also:** Documentation for [std::ilogb](https://en.cppreference.com/w/cpp/numeric/math/ilogb). + /// \param arg number to query + /// \return floating-point exponent + /// \retval FP_ILOGB0 for zero + /// \retval FP_ILOGBNAN for NaN + /// \retval INT_MAX for infinity + /// \exception FE_INVALID for 0 or infinite values + inline int ilogb(half arg) { + int abs = arg.data_ & 0x7FFF, exp; + if(!abs || abs >= 0x7C00) { + detail::raise(FE_INVALID); + return !abs ? FP_ILOGB0 : (abs==0x7C00) ? INT_MAX : FP_ILOGBNAN; + } + for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ; + return exp; + } + + /// Extract exponent. + /// **See also:** Documentation for [std::logb](https://en.cppreference.com/w/cpp/numeric/math/logb). + /// \param arg number to query + /// \return floating-point exponent + /// \exception FE_INVALID for signaling NaN + /// \exception FE_DIVBYZERO for 0 + inline half logb(half arg) { + int abs = arg.data_ & 0x7FFF, exp; + if(!abs) + return half(detail::binary, detail::pole(0x8000)); + if(abs >= 0x7C00) + return half(detail::binary, (abs==0x7C00) ? 0x7C00 : detail::signal(arg.data_)); + for(exp=(abs>>10)-15; abs<0x200; abs<<=1,--exp) ; + unsigned int value = static_cast(exp<0) << 15; + if(exp) { + unsigned int m = std::abs(exp) << 6; + for(exp=18; m<0x400; m<<=1,--exp) ; + value |= (exp<<10) + m; + } + return half(detail::binary, value); + } + + /// Next representable value. + /// **See also:** Documentation for [std::nextafter](https://en.cppreference.com/w/cpp/numeric/math/nextafter). + /// \param from value to compute next representable value for + /// \param to direction towards which to compute next value + /// \return next representable value after \a from in direction towards \a to + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW for infinite result from finite argument + /// \exception FE_UNDERFLOW for subnormal result + inline half nextafter(half from, half to) { + int fabs = from.data_ & 0x7FFF, tabs = to.data_ & 0x7FFF; + if(fabs > 0x7C00 || tabs > 0x7C00) + return half(detail::binary, detail::signal(from.data_, to.data_)); + if(from.data_ == to.data_ || !(fabs|tabs)) + return to; + if(!fabs) { + detail::raise(FE_UNDERFLOW, !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT); + return half(detail::binary, (to.data_&0x8000)+1); + } + unsigned int out = from.data_ + (((from.data_>>15)^static_cast( + (from.data_^(0x8000|(0x8000-(from.data_>>15))))<(to.data_^(0x8000|(0x8000-(to.data_>>15))))))<<1) - 1; + detail::raise(FE_OVERFLOW, fabs<0x7C00 && (out&0x7C00)==0x7C00); + detail::raise(FE_UNDERFLOW, !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT && (out&0x7C00)<0x400); + return half(detail::binary, out); + } + + /// Next representable value. + /// **See also:** Documentation for [std::nexttoward](https://en.cppreference.com/w/cpp/numeric/math/nexttoward). + /// \param from value to compute next representable value for + /// \param to direction towards which to compute next value + /// \return next representable value after \a from in direction towards \a to + /// \exception FE_INVALID for signaling NaN + /// \exception FE_OVERFLOW for infinite result from finite argument + /// \exception FE_UNDERFLOW for subnormal result + inline half nexttoward(half from, long double to) { + int fabs = from.data_ & 0x7FFF; + if(fabs > 0x7C00) + return half(detail::binary, detail::signal(from.data_)); + long double lfrom = static_cast(from); + if(detail::builtin_isnan(to) || lfrom == to) + return half(static_cast(to)); + if(!fabs) { + detail::raise(FE_UNDERFLOW, !HALF_ERRHANDLING_UNDERFLOW_TO_INEXACT); + return half(detail::binary, (static_cast(detail::builtin_signbit(to))<<15)+1); + } + unsigned int out = from.data_ + (((from.data_>>15)^static_cast(lfrom 0x7C00; } + + /// Check if normal number. + /// **See also:** Documentation for [std::isnormal](https://en.cppreference.com/w/cpp/numeric/math/isnormal). + /// \param arg number to check + /// \retval true if normal number + /// \retval false if either subnormal, zero, infinity or NaN + inline constexpr bool isnormal(half arg) { return ((arg.data_&0x7C00)!=0) & ((arg.data_&0x7C00)!=0x7C00); } + + /// Check sign. + /// **See also:** Documentation for [std::signbit](https://en.cppreference.com/w/cpp/numeric/math/signbit). + /// \param arg number to check + /// \retval true for negative number + /// \retval false for positive number + inline constexpr bool signbit(half arg) { return (arg.data_&0x8000) != 0; } + + /// \} + /// \anchor compfunc + /// \name Comparison + /// \{ + + /// Quiet comparison for greater than. + /// **See also:** Documentation for [std::isgreater](https://en.cppreference.com/w/cpp/numeric/math/isgreater). + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater than \a y + /// \retval false else + inline constexpr bool isgreater(half x, half y) { + return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) > ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y); + } + + /// Quiet comparison for greater equal. + /// **See also:** Documentation for [std::isgreaterequal](https://en.cppreference.com/w/cpp/numeric/math/isgreaterequal). + /// \param x first operand + /// \param y second operand + /// \retval true if \a x greater equal \a y + /// \retval false else + inline constexpr bool isgreaterequal(half x, half y) { + return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) >= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y); + } + + /// Quiet comparison for less than. + /// **See also:** Documentation for [std::isless](https://en.cppreference.com/w/cpp/numeric/math/isless). + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less than \a y + /// \retval false else + inline constexpr bool isless(half x, half y) { + return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) < ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y); + } + + /// Quiet comparison for less equal. + /// **See also:** Documentation for [std::islessequal](https://en.cppreference.com/w/cpp/numeric/math/islessequal). + /// \param x first operand + /// \param y second operand + /// \retval true if \a x less equal \a y + /// \retval false else + inline constexpr bool islessequal(half x, half y) { + return ((x.data_^(0x8000|(0x8000-(x.data_>>15))))+(x.data_>>15)) <= ((y.data_^(0x8000|(0x8000-(y.data_>>15))))+(y.data_>>15)) && !isnan(x) && !isnan(y); + } + + /// Quiet comarison for less or greater. + /// **See also:** Documentation for [std::islessgreater](https://en.cppreference.com/w/cpp/numeric/math/islessgreater). + /// \param x first operand + /// \param y second operand + /// \retval true if either less or greater + /// \retval false else + inline constexpr bool islessgreater(half x, half y) { + return x.data_!=y.data_ && ((x.data_|y.data_)&0x7FFF) && !isnan(x) && !isnan(y); + } + + /// Quiet check if unordered. + /// **See also:** Documentation for [std::isunordered](https://en.cppreference.com/w/cpp/numeric/math/isunordered). + /// \param x first operand + /// \param y second operand + /// \retval true if unordered (one or two NaN operands) + /// \retval false else + inline constexpr bool isunordered(half x, half y) { return isnan(x) || isnan(y); } + + /// \} + /// \anchor casting + /// \name Casting + /// \{ + + /// Cast to or from half-precision floating-point number. + /// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted + /// directly using the default rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do. + /// + /// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types + /// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler + /// error and casting between [half](\ref half_float::half)s returns the argument unmodified. + /// \tparam T destination type (half or built-in arithmetic type) + /// \tparam U source type (half or built-in arithmetic type) + /// \param arg value to cast + /// \return \a arg converted to destination type + /// \exception FE_INVALID if \a T is integer type and result is not representable as \a T + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + template T half_cast(U arg) { return detail::half_caster::cast(arg); } + + /// Cast to or from half-precision floating-point number. + /// This casts between [half](\ref half_float::half) and any built-in arithmetic type. The values are converted + /// directly using the specified rounding mode, without any roundtrip over `float` that a `static_cast` would otherwise do. + /// + /// Using this cast with neither of the two types being a [half](\ref half_float::half) or with any of the two types + /// not being a built-in arithmetic type (apart from [half](\ref half_float::half), of course) results in a compiler + /// error and casting between [half](\ref half_float::half)s returns the argument unmodified. + /// \tparam T destination type (half or built-in arithmetic type) + /// \tparam R rounding mode to use. + /// \tparam U source type (half or built-in arithmetic type) + /// \param arg value to cast + /// \return \a arg converted to destination type + /// \exception FE_INVALID if \a T is integer type and result is not representable as \a T + /// \exception FE_OVERFLOW, ...UNDERFLOW, ...INEXACT according to rounding + template T half_cast(U arg) { return detail::half_caster::cast(arg); } + /// \} + + /// \} + /// \anchor errors + /// \name Error handling + /// \{ + + /// Clear exception flags. + /// This function works even if [automatic exception flag handling](\ref HALF_ERRHANDLING_FLAGS) is disabled, + /// but in that case manual flag management is the only way to raise flags. + /// + /// **See also:** Documentation for [std::feclearexcept](https://en.cppreference.com/w/cpp/numeric/fenv/feclearexcept). + /// \param excepts OR of exceptions to clear + /// \retval 0 all selected flags cleared successfully + inline int feclearexcept(int excepts) { detail::errflags() &= ~excepts; return 0; } + + /// Test exception flags. + /// This function works even if [automatic exception flag handling](\ref HALF_ERRHANDLING_FLAGS) is disabled, + /// but in that case manual flag management is the only way to raise flags. + /// + /// **See also:** Documentation for [std::fetestexcept](https://en.cppreference.com/w/cpp/numeric/fenv/fetestexcept). + /// \param excepts OR of exceptions to test + /// \return OR of selected exceptions if raised + inline int fetestexcept(int excepts) { return detail::errflags() & excepts; } + + /// Raise exception flags. + /// This raises the specified floating point exceptions and also invokes any additional automatic exception handling as + /// configured with the [HALF_ERRHANDLIG_...](\ref HALF_ERRHANDLING_ERRNO) preprocessor symbols. + /// This function works even if [automatic exception flag handling](\ref HALF_ERRHANDLING_FLAGS) is disabled, + /// but in that case manual flag management is the only way to raise flags. + /// + /// **See also:** Documentation for [std::feraiseexcept](https://en.cppreference.com/w/cpp/numeric/fenv/feraiseexcept). + /// \param excepts OR of exceptions to raise + /// \retval 0 all selected exceptions raised successfully + inline int feraiseexcept(int excepts) { detail::errflags() |= excepts; detail::raise(excepts); return 0; } + + /// Save exception flags. + /// This function works even if [automatic exception flag handling](\ref HALF_ERRHANDLING_FLAGS) is disabled, + /// but in that case manual flag management is the only way to raise flags. + /// + /// **See also:** Documentation for [std::fegetexceptflag](https://en.cppreference.com/w/cpp/numeric/fenv/feexceptflag). + /// \param flagp adress to store flag state at + /// \param excepts OR of flags to save + /// \retval 0 for success + inline int fegetexceptflag(int *flagp, int excepts) { *flagp = detail::errflags() & excepts; return 0; } + + /// Restore exception flags. + /// This only copies the specified exception state (including unset flags) without incurring any additional exception handling. + /// This function works even if [automatic exception flag handling](\ref HALF_ERRHANDLING_FLAGS) is disabled, + /// but in that case manual flag management is the only way to raise flags. + /// + /// **See also:** Documentation for [std::fesetexceptflag](https://en.cppreference.com/w/cpp/numeric/fenv/feexceptflag). + /// \param flagp adress to take flag state from + /// \param excepts OR of flags to restore + /// \retval 0 for success + inline int fesetexceptflag(const int *flagp, int excepts) { detail::errflags() = (detail::errflags()|(*flagp&excepts)) & (*flagp|~excepts); return 0; } + + /// Throw C++ exceptions based on set exception flags. + /// This function manually throws a corresponding C++ exception if one of the specified flags is set, + /// no matter if automatic throwing (via [HALF_ERRHANDLING_THROW_...](\ref HALF_ERRHANDLING_THROW_INVALID)) is enabled or not. + /// This function works even if [automatic exception flag handling](\ref HALF_ERRHANDLING_FLAGS) is disabled, + /// but in that case manual flag management is the only way to raise flags. + /// \param excepts OR of exceptions to test + /// \param msg error message to use for exception description + /// \throw std::domain_error if `FE_INVALID` or `FE_DIVBYZERO` is selected and set + /// \throw std::overflow_error if `FE_OVERFLOW` is selected and set + /// \throw std::underflow_error if `FE_UNDERFLOW` is selected and set + /// \throw std::range_error if `FE_INEXACT` is selected and set + inline void fethrowexcept(int excepts, const char *msg = "") { + excepts &= detail::errflags(); + if(excepts & (FE_INVALID|FE_DIVBYZERO)) + throw std::domain_error(msg); + if(excepts & FE_OVERFLOW) + throw std::overflow_error(msg); + if(excepts & FE_UNDERFLOW) + throw std::underflow_error(msg); + if(excepts & FE_INEXACT) + throw std::range_error(msg); + } + /// \} +} + + +#undef HALF_UNUSED_NOERR +#undef constexpr_NOERR +#undef HALF_TWOS_COMPLEMENT_INT +#ifdef HALF_POP_WARNINGS + #pragma warning(pop) + #undef HALF_POP_WARNINGS +#endif \ No newline at end of file diff --git a/tests/regression/flash_attention/kernel.cpp b/tests/regression/flash_attention/kernel.cpp new file mode 100644 index 00000000..bc212ade --- /dev/null +++ b/tests/regression/flash_attention/kernel.cpp @@ -0,0 +1,158 @@ +#include +#include +#include +#include +#include "common.h" +#include "sgemm_impl.hpp" +#include "include/gemmini.h" +#include "gemmini_mmio.h" + +// using float_type = float; +using float_type = float16_t; + +inline void thread_block_flashattn(float *S, float *gmem, + const uint32_t tid_in_threadblock, + const uint32_t threads_per_threadblock, + const uint32_t threadblock_id_in_cluster, + uint8_t *sharedmem_per_threadblock) { + asm volatile("thread_block_flashattn_start_%=:" ::); + + constexpr uint32_t Brow = BM; // FIXME + constexpr uint32_t Bcol = BN; // FIXME + const uint32_t tid_in_warp = tid_in_threadblock % NUM_THREADS; + const uint32_t warp_id = tid_in_threadblock / NUM_THREADS; + const uint32_t warps_in_threadblock = threads_per_threadblock / NUM_THREADS; + const uint32_t warps_per_threadblock_per_core = + NUM_WARPS / threads_per_threadblock; + + // float ft[8]; + // asm volatile("fmv.s %0, f16" : "=f"(ft[0])); + // asm volatile("fmv.s %0, f17" : "=f"(ft[1])); + // asm volatile("fmv.s %0, f18" : "=f"(ft[2])); + // asm volatile("fmv.s %0, f19" : "=f"(ft[3])); + // asm volatile("fmv.s %0, f20" : "=f"(ft[4])); + // asm volatile("fmv.s %0, f21" : "=f"(ft[5])); + // asm volatile("fmv.s %0, f22" : "=f"(ft[6])); + // asm volatile("fmv.s %0, f23" : "=f"(ft[7])); + // + // one warp handles one row in tile; iterate enough times to cover all the + // rows + for (int warp_offset = 0; warp_offset < Brow; + warp_offset += warps_in_threadblock) { + const uint32_t row = warp_offset + warp_id; + const uint32_t first_thread_offset = Bcol * row; + uint32_t thread_offset = first_thread_offset + tid_in_warp; + + constexpr uint32_t load_iter = Bcol / NUM_THREADS; + float curr_max = S[first_thread_offset]; +#pragma GCC unroll + for (int iter = 0; iter < load_iter; iter++) { + asm volatile("fmax.s %0, %1, %2" + : "=f"(curr_max) + : "f"(curr_max), "f"(S[thread_offset])); + thread_offset += NUM_THREADS; + } + // get max value across the same-warp threads using smem + float *warp_smem = S + (row * NUM_THREADS); + warp_smem[tid_in_warp] = curr_max; + + // sync writes to warp_smem + threadblock_barrier(threadblock_id_in_cluster, + warps_per_threadblock_per_core); + + // 0-th thread collects all other thread's values in the warp + if (tid_in_warp == 0) { + for (int iter = 1; iter < NUM_THREADS; iter++) { + float other = warp_smem[iter]; + asm volatile("fmax.s %0, %1, %2" + : "=f"(curr_max) + : "f"(curr_max), "f"(other)); + } + gmem[row] = curr_max; + } + } + + asm volatile("thread_block_flashattn_finish_%=:" ::); +} + +void kernel_body(int task_id, kernel_arg_t *__UNIFORM__ arg) { + // @perf: All threads are running these compute whose result is mostly same + // across the threadblock + +#ifdef RADIANCE + constexpr uint32_t cores_per_cluster = CORES_PER_CLUSTER; +#else + constexpr uint32_t cores_per_cluster = 1; +#endif + + uint32_t threads_per_threadblock = (BM * BN) / (ELEM_PER_THREAD); + const uint32_t hw_threads_per_cluster = + cores_per_cluster * vx_num_threads() * vx_num_warps(); + // cap maximum threadblock size to # of HW threads in cluster, to prevent + // multiple "wave" invocations which slows down the kernel + if (threads_per_threadblock > hw_threads_per_cluster) { + threads_per_threadblock = hw_threads_per_cluster; + } + const uint32_t threadblocks_per_cluster = + hw_threads_per_cluster / threads_per_threadblock; + + const int threadblock_id = task_id / threads_per_threadblock; + const int threadblock_id_in_cluster = + threadblock_id % threadblocks_per_cluster; + const int tid_in_threadblock = task_id % threads_per_threadblock; + + const uint32_t dim_m = arg->dim_m; + const uint32_t dim_n = arg->dim_n; + const uint32_t dim_n_in_blocks = dim_n / BN; + const int threadblock_id_x = threadblock_id % dim_n_in_blocks; + const int threadblock_id_y = threadblock_id / dim_n_in_blocks; + const uint32_t problem_size = (dim_m * dim_n) / (ELEM_PER_THREAD); + const uint32_t num_threadblocks = problem_size / threads_per_threadblock; + + // "static" shared memory allocation. This would determine threadblock + // occupancy of a single cluster + uint8_t *sharedmem_per_threadblock = reinterpret_cast( + DEV_SMEM_START_ADDR + sizeof(float_type) * 2 /*overkill for non-dma*/ * + (2 * BM * BK) * threadblock_id_in_cluster); + + uint8_t *smem_S = sharedmem_per_threadblock; + + thread_block_gemm( + (const float_type *)arg->addr_a, (const float_type *)arg->addr_b, + (float *)smem_S /*write result to SMEM */, arg->dim_m, arg->dim_n, + arg->dim_k, tid_in_threadblock, threads_per_threadblock, + threadblocks_per_cluster, threadblock_id_in_cluster, + sharedmem_per_threadblock); + + // sync writes of GEMM results before softmax + const uint32_t warps_per_threadblock_per_core = + NUM_WARPS / threads_per_threadblock; + threadblock_barrier(threadblock_id_in_cluster, + warps_per_threadblock_per_core); + + thread_block_flashattn((float *)smem_S, (float *)arg->addr_c, + tid_in_threadblock, threads_per_threadblock, + threadblock_id_in_cluster, sharedmem_per_threadblock); +} + +int main() { + kernel_arg_t *arg = (kernel_arg_t *)KERNEL_ARG_DEV_MEM_ADDR; + + const uint32_t problem_size = (arg->dim_m * arg->dim_n) / (ELEM_PER_THREAD); + const uint32_t hw_threads_per_cluster = + CORES_PER_CLUSTER * vx_num_threads() * vx_num_warps(); + // prevent launching more threads than the necessary problem size + // TODO: this does not take into account multiple clusters + const uint32_t grid_size = (problem_size > hw_threads_per_cluster) + ? hw_threads_per_cluster + : problem_size; + +#ifdef RADIANCE + vx_spawn_tasks_cluster(grid_size, (vx_spawn_tasks_cb)kernel_body, arg); +#else + // NOTE: This kernel assumes contiguous thread scheduling for efficient shared + // memory allocation, and therefore does not work with original vx_spawn_tasks + vx_spawn_tasks_contiguous(grid_size, (vx_spawn_tasks_cb)kernel_body, arg); +#endif + return 0; +} diff --git a/tests/regression/flash_attention/main.cpp b/tests/regression/flash_attention/main.cpp new file mode 100644 index 00000000..7399ce6d --- /dev/null +++ b/tests/regression/flash_attention/main.cpp @@ -0,0 +1,308 @@ +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "half.hpp" + +using half_float::half; +using half_float::half_cast; + +#define RT_CHECK(_expr) \ + do { \ + int _ret = _expr; \ + if (0 == _ret) \ + break; \ + printf("Error: '%s' returned %d!\n", #_expr, (int)_ret); \ + cleanup(); \ + exit(-1); \ + } while (false) + +/////////////////////////////////////////////////////////////////////////////// + +const char* kernel_file = "kernel.bin"; +uint32_t count = 0; + +template std::vector src_a_data; +template std::vector src_b_data; +std::vector ref_data; + +vx_device_h device = nullptr; +std::vector staging_buf; +kernel_arg_t kernel_arg = {}; + +static void show_usage() { + std::cout << "Vortex Test." << std::endl; + std::cout << "Usage: [-k: kernel] [-n words] [-h: help]" << std::endl; +} + +static void parse_args(int argc, char **argv) { + int c; + while ((c = getopt(argc, argv, "n:k:h?")) != -1) { + switch (c) { + case 'n': + count = atoi(optarg); + break; + case 'k': + kernel_file = optarg; + break; + case 'h': + case '?': { + show_usage(); + exit(0); + } break; + default: + show_usage(); + exit(-1); + } + } +} + +void cleanup() { + if (device) { + // vx_mem_free(device, kernel_arg.addr_a); + // vx_mem_free(device, kernel_arg.addr_b); + // vx_mem_free(device, kernel_arg.addr_c); + vx_dev_close(device); + } +} + +template +void generate_source_matrix(uint32_t dim_m, uint32_t dim_n, uint32_t dim_k) { + static_assert(std::is_same_v || std::is_same_v, + "unsupported floating point datatype"); + + src_a_data.resize(dim_m * dim_k); + src_b_data.resize(dim_k * dim_n); + + for (uint32_t i = 0; i < src_a_data.size(); ++i) { + if constexpr (std::is_same_v) { + src_a_data[i] = half_cast(static_cast(i)); + } else if (std::is_same_v) { + src_a_data[i] = static_cast(i); + } + std::cout << "A: " << i << ": value=" << src_a_data[i] << std::endl; + } + for (uint32_t i = 0; i < src_b_data.size(); ++i) { + if constexpr (std::is_same_v) { + src_b_data[i] = half_cast(static_cast(i)); + } else if (std::is_same_v) { + src_b_data[i] = static_cast(i); + } + std::cout << "B: " << i << ": value=" << src_b_data[i] << std::endl; + } +} + +template +void generate_reference_matmul(uint32_t dim_m, uint32_t dim_n, uint32_t dim_k) { + static_assert(std::is_same_v || std::is_same_v, + "unsupported floating point datatype"); + + ref_data.resize(dim_m * dim_n); + + for (uint32_t i = 0; i < dim_m; ++i) { + for (uint32_t j = 0; j < dim_n; ++j) { + float ref = 0.0f; + for (uint32_t k = 0; k < dim_k; ++k) { + ref += static_cast(src_a_data[dim_k * i + k]) * + static_cast(src_b_data[dim_n * k + j]); + } + ref_data.at(dim_n * i + j) = ref; + } + } +} + +int run_test(const kernel_arg_t& kernel_arg, + uint32_t buf_size, + uint32_t dim_m, uint32_t dim_n) { + // start device + std::cout << "start device" << std::endl; + RT_CHECK(vx_start(device)); + + // wait for completion + std::cout << "wait for completion" << std::endl; + RT_CHECK(vx_ready_wait(device, VX_MAX_TIMEOUT)); + + // download destination buffer + std::cout << "download destination buffer" << std::endl; + RT_CHECK(vx_copy_from_dev(device, staging_buf.data(), kernel_arg.addr_c, buf_size)); + + // verify result + std::cout << "verify result" << std::endl; + { + int errors = 0; + auto buf_ptr = (float*)staging_buf.data(); + for (uint32_t i = 0; i < dim_m * dim_n; ++i) { + float ref = ref_data.at(i); + float cur = buf_ptr[i]; + if (std::abs((cur - ref) / ref) > 1e-6) { + std::cout << "error at result #" << std::dec << i + << std::hex << ": actual=" << cur << ", expected=" << ref << std::endl; + ++errors; + } + } + if (errors != 0) { + std::cout << "Found " << std::dec << errors << " errors!" << std::endl; + std::cout << "FAILED!" << std::endl; + return 1; + } + } + + return 0; +} + +int main(int argc, char *argv[]) { + // parse command arguments + parse_args(argc, argv); + + if (count == 0) { + count = 1; + } + + std::srand(50); + + // open device connection + std::cout << "open device connection" << std::endl; + RT_CHECK(vx_dev_open(&device)); + + // FIXME: hardcoded + uint32_t dim_m = 128; + uint32_t dim_n = 128; + uint32_t dim_k = 128; + + using float_type = half; + + generate_source_matrix(dim_m, dim_n, dim_k); + generate_reference_matmul(dim_m, dim_n, dim_k); + + std::cout << "write reference output" << std::endl; + std::ofstream ref_file("reference.c.bin", std::ios::binary | std::ios::out); + if (!ref_file) { + std::cerr << "error: failed to open reference.c.bin for writing\n"; + exit(EXIT_FAILURE); + } + ref_file.write(reinterpret_cast(ref_data.data()), ref_data.size() * sizeof(ref_data[0])); + ref_file.close(); + + uint32_t src_a_buf_size = src_a_data.size() * sizeof(src_a_data[0]); + uint32_t src_b_buf_size = src_b_data.size() * sizeof(src_b_data[0]); + uint32_t dst_buf_size = ref_data.size() * sizeof(src_a_data[0]); + + std::cout << "buffer size: " << dst_buf_size << " bytes" << std::endl; + + // upload program + std::cout << "upload program" << std::endl; + RT_CHECK(vx_upload_kernel_file(device, kernel_file)); + + // allocate device memory + std::cout << "allocate device memory" << std::endl; + // RT_CHECK(vx_mem_alloc(device, src_a_buf_size, VX_MEM_TYPE_GLOBAL, &kernel_arg.addr_a)); + // RT_CHECK(vx_mem_alloc(device, src_b_buf_size, VX_MEM_TYPE_GLOBAL, &kernel_arg.addr_b)); + // RT_CHECK(vx_mem_alloc(device, dst_buf_size, VX_MEM_TYPE_GLOBAL, &kernel_arg.addr_c)); + kernel_arg.addr_a = 0xa0000000; + kernel_arg.addr_b = 0xa1000000; + kernel_arg.addr_c = 0xc0000000; + + kernel_arg.dim_m = dim_m; + kernel_arg.dim_n = dim_n; + kernel_arg.dim_k = dim_k; + + std::cout << "dev_addr_a=0x" << std::hex << kernel_arg.addr_a << std::endl; + std::cout << "dev_addr_b=0x" << std::hex << kernel_arg.addr_b << std::endl; + std::cout << "dev_addr_c=0x" << std::hex << kernel_arg.addr_c << std::endl; + + // allocate staging buffer + { + std::cout << "allocate staging buffer" << std::endl; + uint32_t staging_buf_size = std::max( + src_a_buf_size, + std::max( + src_b_buf_size, + std::max(dst_buf_size, sizeof(kernel_arg_t)))); + staging_buf.resize(staging_buf_size); + } + + // upload kernel argument + { + std::cout << "upload kernel argument" << std::endl; + auto buf_ptr = staging_buf.data(); + memcpy(buf_ptr, &kernel_arg, sizeof(kernel_arg_t)); + RT_CHECK(vx_copy_to_dev(device, KERNEL_ARG_DEV_MEM_ADDR, staging_buf.data(), sizeof(kernel_arg_t))); + + std::cout << "uploading argument buffer to device, device mem address=" + << std::hex << KERNEL_ARG_DEV_MEM_ADDR << ", size=" << std::dec + << sizeof(kernel_arg_t) << " bytes\n"; + std::ofstream file("args.bin", std::ios::binary | std::ios::out); + if (!file) { + std::cerr << "error: failed to open args.bin for writing\n"; + exit(EXIT_FAILURE); + } + file.write(reinterpret_cast(staging_buf.data()), + sizeof(kernel_arg_t)); + file.close(); + } + + // upload source buffer + { + { + auto buf_ptr = staging_buf.data(); + memcpy(buf_ptr, src_a_data.data(), + src_a_data.size() * sizeof(float_type)); + RT_CHECK(vx_copy_to_dev(device, kernel_arg.addr_a, staging_buf.data(), + src_a_buf_size)); + + std::cout << "uploading source A matrix to device, device mem address=" + << std::hex << kernel_arg.addr_a << ", size=" << std::dec + << src_a_buf_size << " bytes\n"; + std::ofstream file("input.a.bin", std::ios::binary | std::ios::out); + if (!file) { + std::cerr << "error: failed to open args.bin for writing\n"; + exit(EXIT_FAILURE); + } + file.write(reinterpret_cast(buf_ptr), src_a_buf_size); + file.close(); + } + { + auto buf_ptr = staging_buf.data(); + memcpy(buf_ptr, src_b_data.data(), + src_b_data.size() * sizeof(float_type)); + RT_CHECK(vx_copy_to_dev(device, kernel_arg.addr_b, staging_buf.data(), + src_b_buf_size)); + + std::cout << "uploading source B matrix to device, device mem address=" + << std::hex << kernel_arg.addr_b << ", size=" << std::dec + << src_b_buf_size << " bytes\n"; + std::ofstream file("input.b.bin", std::ios::binary | std::ios::out); + if (!file) { + std::cerr << "error: failed to open args.bin for writing\n"; + exit(EXIT_FAILURE); + } + file.write(reinterpret_cast(buf_ptr), src_b_buf_size); + file.close(); + } + } + + // clear destination buffer + { + std::cout << "clear destination buffer" << std::endl; + auto buf_ptr = (int32_t*)staging_buf.data(); + for (uint32_t i = 0; i < ref_data.size(); ++i) { + buf_ptr[i] = 0xdeadbeef; + } + RT_CHECK(vx_copy_to_dev(device, kernel_arg.addr_c, staging_buf.data(), dst_buf_size)); + } + + // run tests + std::cout << "run tests" << std::endl; + RT_CHECK(run_test(kernel_arg, dst_buf_size, kernel_arg.dim_m, kernel_arg.dim_n)); + std::cout << "PASSED!" << std::endl; + + // cleanup + std::cout << "cleanup" << std::endl; + cleanup(); + + return 0; +}