math.vectors.simd: fix all tests

db4
Slava Pestov 2009-09-23 01:05:19 -05:00
parent d23826906f
commit 15ba7e299b
2 changed files with 50 additions and 38 deletions

View File

@ -1,5 +1,5 @@
USING: help.markup help.syntax sequences math math.vectors USING: help.markup help.syntax help.vocabs sequences math
multiline kernel.private classes.tuple.private math.vectors multiline kernel.private classes.tuple.private
math.vectors.simd.intrinsics cpu.architecture ; math.vectors.simd.intrinsics cpu.architecture ;
IN: math.vectors.simd IN: math.vectors.simd
@ -159,22 +159,8 @@ ARTICLE: "math.vectors.simd.intrinsics" "Low-level SIMD primitives"
} }
"The compiler converts " { $link "math-vectors" } " into SIMD primitives automatically in cases where it is safe; this means that the input types are known to be SIMD vectors, and the CPU supports SIMD." "The compiler converts " { $link "math-vectors" } " into SIMD primitives automatically in cases where it is safe; this means that the input types are known to be SIMD vectors, and the CPU supports SIMD."
$nl $nl
"It is best to avoid calling these primitives directly. To write efficient high-level code that compiles down to primitives and avoids memory allocation, see " { $link "math.vectors.simd.efficiency" } "." "It is best to avoid calling SIMD primitives directly. To write efficient high-level code that compiles down to primitives and avoids memory allocation, see " { $link "math.vectors.simd.efficiency" } "."
{ $subsection (simd-v+) } $nl
{ $subsection (simd-vs+) }
{ $subsection (simd-v+-) }
{ $subsection (simd-v-) }
{ $subsection (simd-vs-) }
{ $subsection (simd-v*) }
{ $subsection (simd-vs*) }
{ $subsection (simd-v/) }
{ $subsection (simd-vmin) }
{ $subsection (simd-vmax) }
{ $subsection (simd-vsqrt) }
{ $subsection (simd-sum) }
{ $subsection (simd-broadcast) }
{ $subsection (simd-gather-2) }
{ $subsection (simd-gather-4) }
"There are two primitives which are used to implement accessing SIMD vector fields of " { $link "classes.struct" } ":" "There are two primitives which are used to implement accessing SIMD vector fields of " { $link "classes.struct" } ":"
{ $subsection alien-vector } { $subsection alien-vector }
{ $subsection set-alien-vector } { $subsection set-alien-vector }
@ -185,12 +171,18 @@ ARTICLE: "math.vectors.simd.alien" "SIMD data in struct classes"
$nl $nl
"Only SIMD struct fields are allowed at the moment; passing SIMD data as function parameters is not yet supported." ; "Only SIMD struct fields are allowed at the moment; passing SIMD data as function parameters is not yet supported." ;
ARTICLE: "math.vectors.simd.accuracy" "Numerical accuracy of SIMD primitives"
"No guarantees are made that " { $vocab-link "math.vectors.simd" } " words will give identical results on different SSE versions, or between the hardware intrinsics and the software fallbacks."
$nl
"In particular, horizontal operations on " { $snippet "float-4" } " and " { $snippet "float-8" } " are affected by this. They are computed with lower precision in intrinsics than the software fallback. Horizontal opeartions include anything involving adding together the components of a vector, such as " { $link sum } " or " { $link normalize } "." ;
ARTICLE: "math.vectors.simd" "Hardware vector arithmetic (SIMD)" ARTICLE: "math.vectors.simd" "Hardware vector arithmetic (SIMD)"
"The " { $vocab-link "math.vectors.simd" } " vocabulary extends the " { $vocab-link "math.vectors" } " vocabulary to support efficient vector arithmetic on small, fixed-size vectors." "The " { $vocab-link "math.vectors.simd" } " vocabulary extends the " { $vocab-link "math.vectors" } " vocabulary to support efficient vector arithmetic on small, fixed-size vectors."
{ $subsection "math.vectors.simd.intro" } { $subsection "math.vectors.simd.intro" }
{ $subsection "math.vectors.simd.types" } { $subsection "math.vectors.simd.types" }
{ $subsection "math.vectors.simd.words" } { $subsection "math.vectors.simd.words" }
{ $subsection "math.vectors.simd.support" } { $subsection "math.vectors.simd.support" }
{ $subsection "math.vectors.simd.accuracy" }
{ $subsection "math.vectors.simd.efficiency" } { $subsection "math.vectors.simd.efficiency" }
{ $subsection "math.vectors.simd.alien" } { $subsection "math.vectors.simd.alien" }
{ $subsection "math.vectors.simd.intrinsics" } ; { $subsection "math.vectors.simd.intrinsics" } ;

View File

@ -74,17 +74,18 @@ CONSTANT: simd-classes
: boa-ctors ( -- seq ) : boa-ctors ( -- seq )
simd-classes [ [ name>> "-boa" append ] [ vocabulary>> ] bi lookup ] map ; simd-classes [ [ name>> "-boa" append ] [ vocabulary>> ] bi lookup ] map ;
: check-optimizer ( seq inputs quot -- ) : check-optimizer ( seq inputs quot eq-quot -- )
[ '[
@
[ "print-mr" get [ nip test-mr mr. ] [ 2drop ] if ] [ "print-mr" get [ nip test-mr mr. ] [ 2drop ] if ]
[ [ call ] dip call ] [ [ call ] dip call ]
[ [ call ] dip compile-call ] 2tri = not [ [ call ] dip compile-call ] 2tri @ not
] compose filter ; inline ] filter ; inline
"== Checking -new constructors" print "== Checking -new constructors" print
[ { } ] [ [ { } ] [
simd-classes [ [ [ ] ] dip '[ _ new ] ] check-optimizer simd-classes [ [ [ ] ] dip '[ _ new ] ] [ = ] check-optimizer
] unit-test ] unit-test
[ { } ] [ [ { } ] [
@ -96,7 +97,7 @@ CONSTANT: simd-classes
[ { } ] [ [ { } ] [
with-ctors [ with-ctors [
[ 1000 random '[ _ ] ] dip '[ { fixnum } declare _ execute ] [ 1000 random '[ _ ] ] dip '[ { fixnum } declare _ execute ]
] check-optimizer ] [ = ] check-optimizer
] unit-test ] unit-test
"== Checking -boa constructors" print "== Checking -boa constructors" print
@ -107,7 +108,7 @@ CONSTANT: simd-classes
[ nip [ 1000 random ] [ ] replicate-as ] [ nip [ 1000 random ] [ ] replicate-as ]
[ fixnum <array> swap '[ _ declare _ execute ] ] [ fixnum <array> swap '[ _ declare _ execute ] ]
2bi 2bi
] check-optimizer ] [ = ] check-optimizer
] unit-test ] unit-test
"== Checking vector operations" print "== Checking vector operations" print
@ -133,24 +134,44 @@ CONSTANT: simd-classes
] bi ] bi
word '[ _ declare _ execute ] ; word '[ _ declare _ execute ] ;
: ops-to-check ( elt-class -- alist ) : remove-float-words ( alist -- alist' )
[ vector-words >alist ] dip float = [ [ drop { n/v v/n v/ normalize } member? not ] assoc-filter ;
[ drop { n/v v/n v/ normalize } member? not ] assoc-filter
] unless ;
: check-vector-ops ( class elt-class -- ) : ops-to-check ( elt-class -- alist )
[ vector-words >alist ] dip
float = [ remove-float-words ] unless ;
: check-vector-ops ( class elt-class compare-quot -- )
[
[ nip ops-to-check ] 2keep [ nip ops-to-check ] 2keep
'[ first2 inputs _ _ check-vector-op ] check-optimizer ; inline '[ first2 inputs _ _ check-vector-op ]
] dip check-optimizer ; inline
: approx= ( x y -- ? )
{
{ [ 2dup [ float? ] both? ] [ -1.e8 ~ ] }
{ [ 2dup [ sequence? ] both? ] [
[
{
{ [ 2dup [ fp-nan? ] both? ] [ 2drop t ] }
{ [ 2dup [ fp-nan? ] either? not ] [ -1.e8 ~ ] }
} cond
] 2all?
] }
} cond ;
: simd-classes&reps ( -- alist ) : simd-classes&reps ( -- alist )
simd-classes [ simd-classes [
dup name>> [ "float" head? ] [ "double" head? ] bi or {
float fixnum ? { [ dup name>> "float" head? ] [ float [ approx= ] ] }
] { } map>assoc ; { [ dup name>> "double" tail? ] [ float [ = ] ] }
[ fixnum [ = ] ]
} cond 3array
] map ;
simd-classes&reps [ simd-classes&reps [
[ [ { } ] ] 2dip '[ _ _ check-vector-ops ] unit-test [ [ { } ] ] dip first3 '[ _ _ _ check-vector-ops ] unit-test
] assoc-each ] each
! Other regressions ! Other regressions
[ 8000000 ] [ [ 8000000 ] [
@ -158,7 +179,6 @@ simd-classes&reps [
[ { int-8 } declare dup [ * ] [ + ] 2map-reduce ] compile-call [ { int-8 } declare dup [ * ] [ + ] 2map-reduce ] compile-call
] unit-test ] unit-test
! Vector alien intrinsics ! Vector alien intrinsics
[ float-4{ 1 2 3 4 } ] [ [ float-4{ 1 2 3 4 } ] [
[ [