author | Stefan Vogel <sv@exept.de> |
Fri, 20 Mar 2020 13:01:09 +0100 | |
changeset 5469 | d78065ee4cff |
parent 5217 | d2ab1dc1961b |
permissions | -rw-r--r-- |
4982 | 1 |
"{ Encoding: utf8 }" |
2 |
||
3159 | 3 |
" |
3221 | 4 |
COPYRIGHT (c) 2014 by Claus Gittinger |
4980 | 5 |
All Rights Reserved |
3159 | 6 |
|
7 |
This software is furnished under a license and may be used |
|
8 |
only in accordance with the terms of that license and with the |
|
9 |
inclusion of the above copyright notice. This software may not |
|
10 |
be provided or otherwise made available to, or used by, any |
|
11 |
other person. No title to or ownership of the software is |
|
12 |
hereby transferred. |
|
13 |
" |
|
14 |
"{ Package: 'stx:libbasic2' }" |
|
15 |
||
4044 | 16 |
"{ NameSpace: Smalltalk }" |
17 |
||
4835 | 18 |
UnboxedFloatArray variableWordSubclass:#HalfFloatArray |
3159 | 19 |
instanceVariableNames:'' |
20 |
classVariableNames:'' |
|
21 |
poolDictionaries:'' |
|
22 |
category:'Collections-Arrayed' |
|
23 |
! |
|
24 |
||
25 |
!HalfFloatArray primitiveFunctions! |
|
26 |
%{ |
|
27 |
typedef unsigned short uint16; |
|
28 |
typedef unsigned int uint32; |
|
4889 | 29 |
#if 0 |
4888 | 30 |
#if defined(__GNUC__) || defined(__CLANG__) || defined(__MINGW__) |
4980 | 31 |
inline float |
4991 | 32 |
XMConvertHalfToFloat(float16_t Value) { |
4980 | 33 |
__m128i V1 = _mm_cvtsi32_si128( (uint32)(Value) ); |
4888 | 34 |
__m128 V2 = _mm_cvtph_ps( V1 ); |
35 |
return _mm_cvtss_f32( V2 ); |
|
36 |
} |
|
37 |
||
4991 | 38 |
inline float16_t |
4888 | 39 |
XMConvertFloatToHalf(float Value) { |
40 |
__m128 V1 = _mm_set_ss( Value ); |
|
41 |
__m128i V2 = _mm_cvtps_ph( V1, 0 ); |
|
4991 | 42 |
return (float16_t)( _mm_cvtsi128_si32(V2) ); |
4888 | 43 |
} |
44 |
#endif |
|
4889 | 45 |
#endif |
3159 | 46 |
// |
47 |
// convert a halffloat (16-bit float) to a float |
|
48 |
// |
|
4991 | 49 |
extern float __STX_halffloat_to_float(float16_t h); |
3159 | 50 |
|
51 |
// |
|
52 |
// convert a float to a halffloat (16-bit float) |
|
53 |
// |
|
4991 | 54 |
extern float16_t __STX_float_to_halffloat(float f32); |
3159 | 55 |
|
56 |
%} |
|
3160 | 57 |
! ! |
3159 | 58 |
|
59 |
!HalfFloatArray class methodsFor:'documentation'! |
|
60 |
||
61 |
copyright |
|
62 |
" |
|
3221 | 63 |
COPYRIGHT (c) 2014 by Claus Gittinger |
4980 | 64 |
All Rights Reserved |
3159 | 65 |
|
66 |
This software is furnished under a license and may be used |
|
67 |
only in accordance with the terms of that license and with the |
|
68 |
inclusion of the above copyright notice. This software may not |
|
69 |
be provided or otherwise made available to, or used by, any |
|
70 |
other person. No title to or ownership of the software is |
|
71 |
hereby transferred. |
|
72 |
" |
|
73 |
! |
|
74 |
||
75 |
documentation |
|
76 |
" |
|
77 |
HalfFloatArrays store half precision (16bit) floats (and nothing else). |
|
3221 | 78 |
HalfFloats were traditionally seldom used, but seem to become more popular |
3159 | 79 |
these days, as some 3D graphics accelerators and game engines use them |
3304 | 80 |
for very dense and compact storage of texture and vertex data. |
3160 | 81 |
|
3304 | 82 |
Notice, that HalfFloats are not supported as first class objects by the ST/X system; |
3160 | 83 |
i.e. outside of a HalfFloatArray, these values are represented as floats |
3304 | 84 |
or doubles. When accessing a HalfFloatArray's element via getters/setters, |
85 |
shortFloat (i.e. single precision 32bit floats) are exchanged. |
|
86 |
||
3160 | 87 |
Be aware that the numeric range of a half-float is very very limited. |
3159 | 88 |
|
89 |
[memory requirements:] |
|
4991 | 90 |
OBJ-HEADER + (size * 2) |
3159 | 91 |
|
92 |
[See also:] |
|
4991 | 93 |
FloatArray DoubleArray Array |
94 |
http://www.opengl.org/wiki/Small_Float_Formats |
|
95 |
https://en.wikipedia.org/wiki/Half-precision |
|
96 |
||
3159 | 97 |
[author:] |
4991 | 98 |
Claus Gittinger |
3159 | 99 |
" |
100 |
! ! |
|
101 |
||
102 |
!HalfFloatArray class methodsFor:'queries'! |
|
103 |
||
104 |
elementByteSize |
|
3335
deeaf91b9227
comment/format in: #elementByteSize
Claus Gittinger <cg@exept.de>
parents:
3305
diff
changeset
|
105 |
"for bit-like containers, return the number of bytes stored per element. |
deeaf91b9227
comment/format in: #elementByteSize
Claus Gittinger <cg@exept.de>
parents:
3305
diff
changeset
|
106 |
Here, 2 is returned" |
deeaf91b9227
comment/format in: #elementByteSize
Claus Gittinger <cg@exept.de>
parents:
3305
diff
changeset
|
107 |
|
3159 | 108 |
^ 2 |
5055 | 109 |
! |
110 |
||
111 |
epsilon |
|
112 |
"return the maximum relative spacing of elements of mySelf |
|
113 |
(i.e. the value-delta of the least significant bit)" |
|
114 |
||
115 |
^ 2.0 raisedToInteger:(self precision negated). |
|
116 |
||
117 |
" |
|
118 |
HalfFloatArray epsilon printStringScientific |
|
119 |
" |
|
120 |
||
121 |
"Created: / 19-07-2019 / 17:20:20 / Claus Gittinger" |
|
122 |
! |
|
123 |
||
124 |
precision |
|
125 |
"answer the precision (the number of bits in the mantissa) of my elements (in bits) |
|
126 |
This is an IEEE halffloat, where only the fraction from the normalized mantissa is stored |
|
127 |
and so there is a hidden bit and the mantissa is actually represented by 11 binary digits |
|
128 |
(although only 10 are needed in the binary representation)" |
|
129 |
||
130 |
^ 11 |
|
131 |
||
132 |
"Created: / 19-07-2019 / 17:20:25 / Claus Gittinger" |
|
3159 | 133 |
! ! |
134 |
||
135 |
!HalfFloatArray methodsFor:'accessing'! |
|
136 |
||
137 |
at:index |
|
138 |
%{ /* NOCONTEXT */ |
|
139 |
if (__isSmallInteger(index)) { |
|
5217 | 140 |
int i = __intVal(index)-1; |
141 |
int n = __wordArraySize(self); |
|
3159 | 142 |
|
5217 | 143 |
if ((unsigned)i < n) { |
144 |
float16_t h; |
|
145 |
OBJ newFloat; |
|
146 |
float f; |
|
3159 | 147 |
|
5217 | 148 |
h = (float16_t)(__WordArrayInstPtr(self)->s_element[i]); |
3159 | 149 |
|
5217 | 150 |
f = __STX_halffloat_to_float(h); |
151 |
__qMKSFLOAT(newFloat, f); |
|
152 |
RETURN ( newFloat ); |
|
153 |
} |
|
3159 | 154 |
} |
155 |
%}. |
|
156 |
self primitiveFailed |
|
157 |
! |
|
158 |
||
159 |
at:index put:aFloat |
|
160 |
%{ |
|
5015 | 161 |
if (! __isImmutable(self)) { |
162 |
if (__isSmallInteger(index)) { |
|
5217 | 163 |
int i = __intVal(index)-1; |
5015 | 164 |
int n = __wordArraySize(self); |
3159 | 165 |
|
5217 | 166 |
if ((unsigned)i < n) { |
5015 | 167 |
float16_t h; |
168 |
float f; |
|
3159 | 169 |
|
5015 | 170 |
if (__isFloat(aFloat)) { |
171 |
f = (float)(__floatVal(aFloat)); |
|
172 |
} else if (__isShortFloat(aFloat)) { |
|
173 |
f = __shortFloatVal(aFloat); |
|
174 |
} else if (__isSmallInteger(aFloat)) { |
|
175 |
f = (float)(__intVal(aFloat)); |
|
176 |
} else |
|
177 |
goto error; |
|
3159 | 178 |
|
5015 | 179 |
h = __STX_float_to_halffloat(f); |
5217 | 180 |
__WordArrayInstPtr(self)->s_element[i] = h; |
5015 | 181 |
RETURN (aFloat); |
182 |
} |
|
183 |
} |
|
3159 | 184 |
} |
185 |
error: ; |
|
186 |
%}. |
|
5015 | 187 |
"/ arrive here only in case of an error |
188 |
self isImmutable ifTrue:[ |
|
189 |
self noModificationError |
|
190 |
]. |
|
3159 | 191 |
self primitiveFailed |
5015 | 192 |
|
193 |
"Modified: / 09-06-2019 / 15:32:32 / Claus Gittinger" |
|
3159 | 194 |
! ! |
195 |
||
196 |
!HalfFloatArray methodsFor:'queries'! |
|
197 |
||
198 |
defaultElement |
|
199 |
^ ShortFloat zero |
|
200 |
! |
|
201 |
||
4044 | 202 |
isValidElement:anObject |
203 |
"return true, if I can hold this kind of object" |
|
204 |
||
205 |
^ anObject isNumber |
|
206 |
! |
|
207 |
||
3159 | 208 |
numFloats |
209 |
^ self size |
|
210 |
! ! |
|
211 |
||
4834 | 212 |
!HalfFloatArray methodsFor:'testing'! |
213 |
||
214 |
isFloatArray |
|
215 |
"return true if the receiver has float elements. |
|
216 |
These are Float, Double- and HalfFloat arrays" |
|
217 |
||
218 |
^ true |
|
219 |
||
220 |
"Created: / 02-03-2019 / 23:14:00 / Claus Gittinger" |
|
221 |
! ! |
|
222 |
||
3159 | 223 |
!HalfFloatArray class methodsFor:'documentation'! |
224 |
||
3305 | 225 |
version |
4044 | 226 |
^ '$Header$' |
3305 | 227 |
! |
228 |
||
3159 | 229 |
version_CVS |
4044 | 230 |
^ '$Header$' |
3159 | 231 |
! ! |
5015 | 232 |