1 USING: accessors arrays classes compiler compiler.tree.debugger
2 effects fry io kernel kernel.private math math.functions
3 math.private math.vectors math.vectors.simd
4 math.vectors.simd.private prettyprint random sequences system
5 tools.test vocabs assocs compiler.cfg.debugger words
6 locals math.vectors.specialization combinators cpu.architecture
7 math.vectors.conversion.backend
8 math.vectors.simd.intrinsics namespaces byte-arrays alien
9 specialized-arrays classes.struct eval classes.algebra sets
10 quotations math.constants compiler.units ;
11 QUALIFIED-WITH: alien.c-types c
12 SPECIALIZED-ARRAY: c:float
14 SIMDS: c:uchar c:short c:ushort c:int c:uint c:longlong c:ulonglong c:float c:double ;
15 IN: math.vectors.simd.tests
17 ! Make sure the functor doesn't generate bogus vocabularies
18 2 [ [ "USE: math.vectors.simd SIMD: rubinius" eval( -- ) ] must-fail ] times
20 [ f ] [ "math.vectors.simd.instances.rubinius" vocab ] unit-test
22 ! Test type propagation
23 [ V{ float } ] [ [ { float-4 } declare norm-sq ] final-classes ] unit-test
25 [ V{ float } ] [ [ { float-4 } declare norm ] final-classes ] unit-test
27 [ V{ float-4 } ] [ [ { float-4 } declare normalize ] final-classes ] unit-test
29 [ V{ float-4 } ] [ [ { float-4 float-4 } declare v+ ] final-classes ] unit-test
31 [ V{ float } ] [ [ { float-4 } declare second ] final-classes ] unit-test
33 [ V{ int-4 } ] [ [ { int-4 int-4 } declare v+ ] final-classes ] unit-test
35 [ t ] [ [ { int-4 } declare second ] final-classes first integer class<= ] unit-test
37 [ V{ longlong-2 } ] [ [ { longlong-2 longlong-2 } declare v+ ] final-classes ] unit-test
39 [ V{ integer } ] [ [ { longlong-2 } declare second ] final-classes ] unit-test
41 [ V{ int-8 } ] [ [ { int-8 int-8 } declare v+ ] final-classes ] unit-test
43 [ t ] [ [ { int-8 } declare second ] final-classes first integer class<= ] unit-test
45 ! Test puns; only on x86
47 [ double-2{ 4 1024 } ] [
49 [ { float-4 } declare dup v+ underlying>> double-2 boa dup v+ ] compile-call
53 double-2{ 1 2 } double-2{ 10 20 }
54 [ { double-2 double-2 } declare v+ underlying>> 3.0 float* ] compile-call
59 CONSTANT: simd-classes
83 : with-ctors ( -- seq )
84 simd-classes [ [ name>> "-with" append ] [ vocabulary>> ] bi lookup ] map ;
86 : boa-ctors ( -- seq )
87 simd-classes [ [ name>> "-boa" append ] [ vocabulary>> ] bi lookup ] map ;
89 : check-optimizer ( seq quot eq-quot -- failures )
92 [ dup [ class ] { } map-as ] dip '[ _ declare @ ]
94 [ "print-mr" get [ nip test-mr mr. ] [ 2drop ] if ]
95 [ "print-checks" get [ [ . ] bi@ ] [ 2drop ] if ]
97 [ [ call ] dip compile-call ]
102 "== Checking -new constructors" print
105 simd-classes [ [ [ ] ] dip '[ _ new ] ] [ = ] check-optimizer
109 simd-classes [ '[ _ new ] compile-call [ zero? ] all? not ] filter
112 "== Checking -with constructors" print
116 [ 1000 random '[ _ ] ] dip '[ _ execute ]
117 ] [ = ] check-optimizer
120 [ HEX: ffffffff ] [ HEX: ffffffff uint-4-with first ] unit-test
122 [ HEX: ffffffff ] [ HEX: ffffffff [ uint-4-with ] compile-call first ] unit-test
124 [ HEX: ffffffff ] [ [ HEX: ffffffff uint-4-with ] compile-call first ] unit-test
126 "== Checking -boa constructors" print
130 [ stack-effect in>> length [ 1000 random ] [ ] replicate-as ] keep
132 ] [ = ] check-optimizer
135 [ HEX: ffffffff ] [ HEX: ffffffff 2 3 4 [ uint-4-boa ] compile-call first ] unit-test
137 "== Checking vector operations" print
139 : random-int-vector ( class -- vec )
140 new [ drop 1,000 random ] map ;
141 : random-float-vector ( class -- vec )
145 10 swap <array> 0/0. suffix random
148 : random-vector ( class elt-class -- vec )
150 [ random-float-vector ]
151 [ random-int-vector ] if ;
153 :: check-vector-op ( word inputs class elt-class -- inputs quot )
156 { +vector+ [ class elt-class random-vector ] }
157 { +scalar+ [ 1000 random elt-class float = [ >float ] when ] }
160 word '[ _ execute ] ;
162 : remove-float-words ( alist -- alist' )
163 { vsqrt n/v v/n v/ normalize } unique assoc-diff ;
165 : remove-integer-words ( alist -- alist' )
166 { vlshift vrshift } unique assoc-diff ;
168 : boolean-ops ( -- words )
169 { vand vandn vor vxor vnot } ;
171 : remove-boolean-words ( alist -- alist' )
172 boolean-ops unique assoc-diff ;
174 : remove-special-words ( alist -- alist' )
175 ! These have their own tests later
177 hlshift hrshift vshuffle vbroadcast
179 (v>float) (v>integer)
180 (vpack-signed) (vpack-unsigned)
181 (vunpack-head) (vunpack-tail)
182 } unique assoc-diff ;
184 : ops-to-check ( elt-class -- alist )
185 [ vector-words >alist ] dip
186 float = [ remove-integer-words ] [ remove-float-words ] if
188 remove-special-words ;
190 : check-vector-ops ( class elt-class compare-quot -- )
192 [ nip ops-to-check ] 2keep
193 '[ first2 inputs _ _ check-vector-op ]
194 ] dip check-optimizer ; inline
196 : approx= ( x y -- ? )
198 { [ 2dup [ fp-nan? ] both? ] [ 2drop t ] }
199 { [ 2dup [ float? ] both? ] [ -1.e8 ~ ] }
200 { [ 2dup [ fp-infinity? ] either? ] [ fp-bitwise= ] }
201 { [ 2dup [ sequence? ] both? ] [
204 { [ 2dup [ fp-nan? ] both? ] [ 2drop t ] }
205 { [ 2dup [ fp-infinity? ] either? ] [ fp-bitwise= ] }
206 { [ 2dup [ fp-nan? ] either? not ] [ -1.e8 ~ ] }
212 : exact= ( x y -- ? )
214 { [ 2dup [ float? ] both? ] [ fp-bitwise= ] }
215 { [ 2dup [ sequence? ] both? ] [ [ fp-bitwise= ] 2all? ] }
218 : simd-classes&reps ( -- alist )
221 { [ dup name>> "float" head? ] [ float [ approx= ] ] }
222 { [ dup name>> "double" head? ] [ float [ exact= ] ] }
228 [ [ { } ] ] dip first3 '[ _ _ _ check-vector-ops ] unit-test
231 "== Checking boolean operations" print
233 : random-boolean-vector ( class -- vec )
234 new [ drop 2 random zero? ] map ;
236 :: check-boolean-op ( word inputs class elt-class -- inputs quot )
239 { +vector+ [ class random-boolean-vector ] }
240 { +scalar+ [ 1000 random elt-class float = [ >float ] when ] }
243 word '[ _ execute ] ;
245 : check-boolean-ops ( class elt-class compare-quot -- )
247 [ boolean-ops [ dup word-schema ] { } map>assoc ] 2dip
248 '[ first2 inputs _ _ check-boolean-op ]
249 ] dip check-optimizer ; inline
252 [ [ { } ] ] dip first3 '[ _ _ _ check-boolean-ops ] unit-test
255 "== Checking vector blend" print
257 [ char-16{ 0 1 22 33 4 5 6 77 8 99 110 121 12 143 14 15 } ]
259 char-16{ t t f f t t t f t f f f t f t t }
260 char-16{ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 }
261 char-16{ 0 11 22 33 44 55 66 77 88 99 110 121 132 143 154 165 } v?
264 [ char-16{ 0 1 22 33 4 5 6 77 8 99 110 121 12 143 14 15 } ]
266 char-16{ t t f f t t t f t f f f t f t t }
267 char-16{ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 }
268 char-16{ 0 11 22 33 44 55 66 77 88 99 110 121 132 143 154 165 }
269 [ { char-16 char-16 char-16 } declare v? ] compile-call
272 [ int-4{ 1 22 33 4 } ]
273 [ int-4{ t f f t } int-4{ 1 2 3 4 } int-4{ 11 22 33 44 } v? ] unit-test
275 [ int-4{ 1 22 33 4 } ]
277 int-4{ t f f t } int-4{ 1 2 3 4 } int-4{ 11 22 33 44 }
278 [ { int-4 int-4 int-4 } declare v? ] compile-call
281 [ float-4{ 1.0 22.0 33.0 4.0 } ]
282 [ float-4{ t f f t } float-4{ 1.0 2.0 3.0 4.0 } float-4{ 11.0 22.0 33.0 44.0 } v? ] unit-test
284 [ float-4{ 1.0 22.0 33.0 4.0 } ]
286 float-4{ t f f t } float-4{ 1.0 2.0 3.0 4.0 } float-4{ 11.0 22.0 33.0 44.0 }
287 [ { float-4 float-4 float-4 } declare v? ] compile-call
290 "== Checking shifts and permutations" print
292 [ int-4{ 256 512 1024 2048 } ]
293 [ int-4{ 1 2 4 8 } 1 hlshift ] unit-test
295 [ int-4{ 256 512 1024 2048 } ]
296 [ int-4{ 1 2 4 8 } [ { int-4 } declare 1 hlshift ] compile-call ] unit-test
298 [ int-4{ 256 512 1024 2048 } ]
299 [ int-4{ 1 2 4 8 } 1 [ { int-4 fixnum } declare hlshift ] compile-call ] unit-test
302 [ int-4{ 256 512 1024 2048 } 1 hrshift ] unit-test
305 [ int-4{ 256 512 1024 2048 } [ { int-4 } declare 1 hrshift ] compile-call ] unit-test
308 [ int-4{ 256 512 1024 2048 } 1 [ { int-4 fixnum } declare hrshift ] compile-call ] unit-test
310 ! Invalid inputs should not cause the compiler to throw errors
312 [ [ { int-4 } declare t hrshift ] (( a -- b )) define-temp drop ] with-compilation-unit
316 [ [ { int-4 } declare { 3 2 1 } vshuffle ] (( a -- b )) define-temp drop ] with-compilation-unit
320 : shuffles-for ( n -- shuffles )
351 [ dup '[ _ random ] replicate 1array ]
356 [ new length shuffles-for ] keep
358 _ [ [ _ new [ length iota ] keep like 1quotation ] dip '[ _ vshuffle ] ]
359 [ = ] check-optimizer
363 "== Checking vector tests" print
365 :: test-vector-tests-bool ( vector declaration -- none? any? all? )
367 [ [ declaration declare vnone? ] compile-call ]
368 [ [ declaration declare vany? ] compile-call ]
369 [ [ declaration declare vall? ] compile-call ] tri ; inline
374 :: test-vector-tests-branch ( vector declaration -- none? any? all? )
376 [ [ declaration declare vnone? [ yes ] [ no ] if ] compile-call ]
377 [ [ declaration declare vany? [ yes ] [ no ] if ] compile-call ]
378 [ [ declaration declare vall? [ yes ] [ no ] if ] compile-call ] tri ; inline
380 SYMBOL: !!inconsistent!!
382 : ?inconsistent ( a b -- ab/inconsistent )
383 2dup = [ drop ] [ 2drop !!inconsistent!! ] if ;
385 :: test-vector-tests ( vector decl -- none? any? all? )
386 vector decl test-vector-tests-bool :> bool-all :> bool-any :> bool-none
387 vector decl test-vector-tests-branch :> branch-all :> branch-any :> branch-none
389 bool-none branch-none ?inconsistent
390 bool-any branch-any ?inconsistent
391 bool-all branch-all ?inconsistent ; inline
394 [ float-4{ t t t t } { float-4 } test-vector-tests ] unit-test
396 [ float-4{ f t t t } { float-4 } test-vector-tests ] unit-test
398 [ float-4{ f f f f } { float-4 } test-vector-tests ] unit-test
401 [ double-2{ t t } { double-2 } test-vector-tests ] unit-test
403 [ double-2{ f t } { double-2 } test-vector-tests ] unit-test
405 [ double-2{ f f } { double-2 } test-vector-tests ] unit-test
408 [ int-4{ t t t t } { int-4 } test-vector-tests ] unit-test
410 [ int-4{ f t t t } { int-4 } test-vector-tests ] unit-test
412 [ int-4{ f f f f } { int-4 } test-vector-tests ] unit-test
415 [ float-8{ t t t t t t t t } { float-8 } test-vector-tests ] unit-test
417 [ float-8{ f t t t t f t t } { float-8 } test-vector-tests ] unit-test
419 [ float-8{ f f f f f f f f } { float-8 } test-vector-tests ] unit-test
422 [ double-4{ t t t t } { double-4 } test-vector-tests ] unit-test
424 [ double-4{ f t t f } { double-4 } test-vector-tests ] unit-test
426 [ double-4{ f f f f } { double-4 } test-vector-tests ] unit-test
429 [ int-8{ t t t t t t t t } { int-8 } test-vector-tests ] unit-test
431 [ int-8{ f t t t t f f f } { int-8 } test-vector-tests ] unit-test
433 [ int-8{ f f f f f f f f } { int-8 } test-vector-tests ] unit-test
435 "== Checking element access" print
437 ! Test element access -- it should box bignums for int-4 on x86
438 : test-accesses ( seq -- failures )
439 [ length >array ] keep
440 '[ [ _ 1quotation ] dip '[ _ swap nth ] ] [ = ] check-optimizer ; inline
442 [ { } ] [ float-4{ 1.0 2.0 3.0 4.0 } test-accesses ] unit-test
443 [ { } ] [ int-4{ HEX: 7fffffff 3 4 -8 } test-accesses ] unit-test
444 [ { } ] [ uint-4{ HEX: ffffffff 2 3 4 } test-accesses ] unit-test
446 [ HEX: 7fffffff ] [ int-4{ HEX: 7fffffff 3 4 -8 } first ] unit-test
447 [ -8 ] [ int-4{ HEX: 7fffffff 3 4 -8 } last ] unit-test
448 [ HEX: ffffffff ] [ uint-4{ HEX: ffffffff 2 3 4 } first ] unit-test
450 [ { } ] [ double-2{ 1.0 2.0 } test-accesses ] unit-test
451 [ { } ] [ longlong-2{ 1 2 } test-accesses ] unit-test
452 [ { } ] [ ulonglong-2{ 1 2 } test-accesses ] unit-test
454 [ { } ] [ float-8{ 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 } test-accesses ] unit-test
455 [ { } ] [ int-8{ 1 2 3 4 5 6 7 8 } test-accesses ] unit-test
456 [ { } ] [ uint-8{ 1 2 3 4 5 6 7 8 } test-accesses ] unit-test
458 [ { } ] [ double-4{ 1.0 2.0 3.0 4.0 } test-accesses ] unit-test
459 [ { } ] [ longlong-4{ 1 2 3 4 } test-accesses ] unit-test
460 [ { } ] [ ulonglong-4{ 1 2 3 4 } test-accesses ] unit-test
462 "== Checking broadcast" print
463 : test-broadcast ( seq -- failures )
464 [ length >array ] keep
465 '[ [ _ 1quotation ] dip '[ _ vbroadcast ] ] [ = ] check-optimizer ; inline
467 [ { } ] [ float-4{ 1.0 2.0 3.0 4.0 } test-broadcast ] unit-test
468 [ { } ] [ int-4{ HEX: 7fffffff 3 4 -8 } test-broadcast ] unit-test
469 [ { } ] [ uint-4{ HEX: ffffffff 2 3 4 } test-broadcast ] unit-test
471 [ { } ] [ double-2{ 1.0 2.0 } test-broadcast ] unit-test
472 [ { } ] [ longlong-2{ 1 2 } test-broadcast ] unit-test
473 [ { } ] [ ulonglong-2{ 1 2 } test-broadcast ] unit-test
475 [ { } ] [ float-8{ 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 } test-broadcast ] unit-test
476 [ { } ] [ int-8{ 1 2 3 4 5 6 7 8 } test-broadcast ] unit-test
477 [ { } ] [ uint-8{ 1 2 3 4 5 6 7 8 } test-broadcast ] unit-test
479 [ { } ] [ double-4{ 1.0 2.0 3.0 4.0 } test-broadcast ] unit-test
480 [ { } ] [ longlong-4{ 1 2 3 4 } test-broadcast ] unit-test
481 [ { } ] [ ulonglong-4{ 1 2 3 4 } test-broadcast ] unit-test
483 ! Make sure we use the fallback in the correct situations
484 [ int-4{ 3 3 3 3 } ] [ int-4{ 12 34 3 17 } 2 [ { int-4 fixnum } declare vbroadcast ] compile-call ] unit-test
486 "== Checking alien operations" print
488 [ float-4{ 1 2 3 4 } ] [
491 underlying>> 0 float-4-rep alien-vector
492 ] compile-call float-4 boa
495 [ B{ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 } ] [
496 16 [ 1 ] B{ } replicate-as 16 <byte-array>
499 { byte-array c-ptr fixnum } declare
500 float-4-rep set-alien-vector
505 [ float-array{ 1 2 3 4 } ] [
507 float-array{ 1 2 3 4 } underlying>>
508 float-array{ 4 3 2 1 } clone
509 [ underlying>> 0 float-4-rep set-alien-vector ] keep
519 [ t ] [ [ simd-struct <struct> ] compile-call >c-ptr [ 0 = ] all? ] unit-test
525 float-8{ 1 2 3 4 5 6 7 8 }
528 float-4{ 1 2 3 4 } >>x
530 double-4{ 4 3 2 1 } >>z
531 float-8{ 1 2 3 4 5 6 7 8 } >>w
532 { [ x>> ] [ y>> ] [ z>> ] [ w>> ] } cleave
539 float-8{ 1 2 3 4 5 6 7 8 }
543 float-4{ 1 2 3 4 } >>x
545 double-4{ 4 3 2 1 } >>z
546 float-8{ 1 2 3 4 5 6 7 8 } >>w
547 { [ x>> ] [ y>> ] [ z>> ] [ w>> ] } cleave
551 "== Misc tests" print
553 [ ] [ char-16 new 1array stack. ] unit-test
557 int-8{ 1000 1000 1000 1000 1000 1000 1000 1000 }
558 [ { int-8 } declare dup [ * ] [ + ] 2map-reduce ] compile-call
561 ! Coalescing was too aggressive
562 :: broken ( axis theta -- a b c )
563 axis { float-4 } declare drop
564 theta { float } declare drop
566 theta cos float-4-with :> cc
567 theta sin float-4-with :> ss
569 axis cc v+ :> diagonal
571 diagonal cc ss ; inline
574 float-4{ 1.0 0.0 1.0 0.0 } pi [ broken 3array ]
575 [ compile-call ] [ call ] 3bi =