remove math.vectors .specialization, .simd.functor, .simd.intrinsics
parent
9cf3ab3da1
commit
73d2a75644
|
@ -1 +0,0 @@
|
|||
Slava Pestov
|
|
@ -1,522 +0,0 @@
|
|||
! Copyright (C) 2009 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors assocs byte-arrays classes classes.algebra effects fry
|
||||
functors generalizations kernel literals locals math math.functions
|
||||
math.vectors math.vectors.private math.vectors.simd.intrinsics
|
||||
math.vectors.conversion.backend
|
||||
math.vectors.specialization parser prettyprint.custom sequences
|
||||
sequences.private strings words definitions macros cpu.architecture
|
||||
namespaces arrays quotations combinators combinators.short-circuit sets
|
||||
layouts ;
|
||||
QUALIFIED-WITH: alien.c-types c
|
||||
QUALIFIED: math.private
|
||||
IN: math.vectors.simd.functor
|
||||
|
||||
ERROR: bad-length got expected ;
|
||||
|
||||
: vector-true-value ( class -- value )
|
||||
{
|
||||
{ [ dup integer class<= ] [ drop -1 ] }
|
||||
{ [ dup float class<= ] [ drop -1 bits>double ] }
|
||||
} cond ; foldable
|
||||
|
||||
: vector-false-value ( class -- value )
|
||||
{
|
||||
{ [ dup integer class<= ] [ drop 0 ] }
|
||||
{ [ dup float class<= ] [ drop 0.0 ] }
|
||||
} cond ; foldable
|
||||
|
||||
: boolean>element ( bool/elt class -- elt )
|
||||
swap {
|
||||
{ t [ vector-true-value ] }
|
||||
{ f [ vector-false-value ] }
|
||||
[ nip ]
|
||||
} case ; inline
|
||||
|
||||
MACRO: simd-boa ( rep class -- simd-array )
|
||||
[ rep-components ] [ new ] bi* '[ _ _ nsequence ] ;
|
||||
|
||||
: can-be-unboxed? ( type -- ? )
|
||||
{
|
||||
{ c:float [ \ math.private:float+ "intrinsic" word-prop ] }
|
||||
{ c:double [ \ math.private:float+ "intrinsic" word-prop ] }
|
||||
[ c:heap-size cell < ]
|
||||
} case ;
|
||||
|
||||
: simd-boa-fast? ( rep -- ? )
|
||||
[ dup rep-gather-word supported-simd-op? ]
|
||||
[ rep-component-type can-be-unboxed? ]
|
||||
bi and ;
|
||||
|
||||
:: define-boa-custom-inlining ( word rep class -- )
|
||||
word [
|
||||
drop
|
||||
rep simd-boa-fast? [
|
||||
[ rep (simd-boa) class boa ]
|
||||
] [ word def>> ] if
|
||||
] "custom-inlining" set-word-prop ;
|
||||
|
||||
: simd-with ( rep class x -- simd-array )
|
||||
[ rep-components ] [ new ] [ '[ _ ] ] tri* swap replicate-as ; inline
|
||||
|
||||
: simd-with/nth-fast? ( rep -- ? )
|
||||
[ \ (simd-vshuffle-elements) supported-simd-op? ]
|
||||
[ rep-component-type can-be-unboxed? ]
|
||||
bi and ;
|
||||
|
||||
:: define-with-custom-inlining ( word rep class -- )
|
||||
word [
|
||||
drop
|
||||
rep simd-with/nth-fast? [
|
||||
[ rep rep-coerce rep (simd-with) class boa ]
|
||||
] [ word def>> ] if
|
||||
] "custom-inlining" set-word-prop ;
|
||||
|
||||
: simd-nth-fast ( rep -- quot )
|
||||
[ rep-components ] keep
|
||||
'[ swap _ '[ _ _ (simd-select) ] 2array ] map-index
|
||||
'[ swap >fixnum _ case ] ;
|
||||
|
||||
: simd-nth-slow ( rep -- quot )
|
||||
rep-component-type dup c:c-type-getter-boxer c:array-accessor ;
|
||||
|
||||
MACRO: simd-nth ( rep -- x )
|
||||
dup simd-with/nth-fast? [ simd-nth-fast ] [ simd-nth-slow ] if ;
|
||||
|
||||
: boa-effect ( rep n -- effect )
|
||||
[ rep-components ] dip *
|
||||
[ CHAR: a + 1string ] map
|
||||
{ "simd-vector" } <effect> ;
|
||||
|
||||
: supported-simd-ops ( assoc rep -- assoc' )
|
||||
[ simd-ops get ] dip
|
||||
'[ nip _ swap supported-simd-op? ] assoc-filter
|
||||
'[ drop _ key? ] assoc-filter ;
|
||||
|
||||
ERROR: bad-schema op schema ;
|
||||
|
||||
:: op-wrapper ( op specials schemas -- wrapper )
|
||||
op {
|
||||
[ specials at ]
|
||||
[ word-schema schemas at ]
|
||||
[ dup word-schema bad-schema ]
|
||||
} 1|| ;
|
||||
|
||||
: low-level-ops ( simd-ops specials schemas -- alist )
|
||||
'[ 1quotation over _ _ op-wrapper [ ] 2sequence ] assoc-map ;
|
||||
|
||||
:: high-level-ops ( ctor elt-class -- assoc )
|
||||
! Some SIMD operations are defined in terms of others.
|
||||
{
|
||||
{ vbroadcast [ swap nth ctor execute ] }
|
||||
{ n+v [ [ ctor execute ] dip v+ ] }
|
||||
{ v+n [ ctor execute v+ ] }
|
||||
{ n-v [ [ ctor execute ] dip v- ] }
|
||||
{ v-n [ ctor execute v- ] }
|
||||
{ n*v [ [ ctor execute ] dip v* ] }
|
||||
{ v*n [ ctor execute v* ] }
|
||||
{ n/v [ [ ctor execute ] dip v/ ] }
|
||||
{ v/n [ ctor execute v/ ] }
|
||||
{ norm-sq [ dup v. assert-positive ] }
|
||||
{ norm [ norm-sq sqrt ] }
|
||||
{ normalize [ dup norm v/n ] }
|
||||
}
|
||||
! To compute dot product and distance with integer vectors, we
|
||||
! have to do things less efficiently, with integer overflow checks,
|
||||
! in the general case.
|
||||
elt-class float = [ { distance [ v- norm ] } suffix ] when ;
|
||||
|
||||
TUPLE: simd class elt-class ops special-wrappers schema-wrappers ctor rep ;
|
||||
|
||||
: define-simd ( simd -- )
|
||||
dup rep>> rep-component-type c:c-type-boxed-class >>elt-class
|
||||
{
|
||||
[ class>> ]
|
||||
[ elt-class>> ]
|
||||
[ [ ops>> ] [ special-wrappers>> ] [ schema-wrappers>> ] tri low-level-ops ]
|
||||
[ rep>> supported-simd-ops ]
|
||||
[ [ ctor>> ] [ elt-class>> ] bi high-level-ops assoc-union ]
|
||||
} cleave
|
||||
specialize-vector-words ;
|
||||
|
||||
:: define-simd-128-type ( class rep -- )
|
||||
c:<c-type>
|
||||
byte-array >>class
|
||||
class >>boxed-class
|
||||
[ rep alien-vector class boa ] >>getter
|
||||
[ [ underlying>> ] 2dip rep set-alien-vector ] >>setter
|
||||
16 >>size
|
||||
8 >>align
|
||||
rep >>rep
|
||||
class c:typedef ;
|
||||
|
||||
: (define-simd-128) ( simd -- )
|
||||
simd-ops get >>ops
|
||||
[ define-simd ]
|
||||
[ [ class>> ] [ rep>> ] bi define-simd-128-type ] bi ;
|
||||
|
||||
FUNCTOR: define-simd-128 ( T -- )
|
||||
|
||||
N [ 16 T c:heap-size /i ]
|
||||
|
||||
A DEFINES-CLASS ${T}-${N}
|
||||
A-boa DEFINES ${A}-boa
|
||||
A-with DEFINES ${A}-with
|
||||
A-cast DEFINES ${A}-cast
|
||||
>A DEFINES >${A}
|
||||
A{ DEFINES ${A}{
|
||||
|
||||
SET-NTH [ T dup c:c-setter c:array-accessor ]
|
||||
|
||||
A-rep [ A name>> "-rep" append "cpu.architecture" lookup ]
|
||||
A-vv->v-op DEFINES-PRIVATE ${A}-vv->v-op
|
||||
A-vn->v-op DEFINES-PRIVATE ${A}-vn->v-op
|
||||
A-vv->n-op DEFINES-PRIVATE ${A}-vv->n-op
|
||||
A-v->v-op DEFINES-PRIVATE ${A}-v->v-op
|
||||
A-v->n-op DEFINES-PRIVATE ${A}-v->n-op
|
||||
A-v-conversion-op DEFINES-PRIVATE ${A}-v-conversion-op
|
||||
A-vv-conversion-op DEFINES-PRIVATE ${A}-vv-conversion-op
|
||||
|
||||
A-element-class [ A-rep rep-component-type c:c-type-boxed-class ]
|
||||
|
||||
WHERE
|
||||
|
||||
TUPLE: A
|
||||
{ underlying byte-array read-only initial: $[ 16 <byte-array> ] } ;
|
||||
|
||||
INSTANCE: A simd-128
|
||||
|
||||
M: A clone underlying>> clone \ A boa ; inline
|
||||
|
||||
M: A length drop N ; inline
|
||||
|
||||
M: A equal?
|
||||
over \ A instance? [ v= vall? ] [ 2drop f ] if ;
|
||||
|
||||
M: A nth-unsafe underlying>> A-rep simd-nth ; inline
|
||||
|
||||
M: A set-nth-unsafe
|
||||
[ A-element-class boolean>element ] 2dip
|
||||
underlying>> SET-NTH call ; inline
|
||||
|
||||
: >A ( seq -- simd-array ) \ A new clone-like ;
|
||||
|
||||
M: A like drop dup \ A instance? [ >A ] unless ; inline
|
||||
|
||||
M: A new-underlying drop \ A boa ; inline
|
||||
|
||||
M: A new-sequence
|
||||
drop dup N =
|
||||
[ drop 16 <byte-array> \ A boa ]
|
||||
[ N bad-length ]
|
||||
if ; inline
|
||||
|
||||
M: A c:byte-length underlying>> length ; inline
|
||||
|
||||
M: A element-type drop A-rep rep-component-type ;
|
||||
|
||||
M: A pprint-delims drop \ A{ \ } ;
|
||||
|
||||
M: A >pprint-sequence ;
|
||||
|
||||
M: A pprint* pprint-object ;
|
||||
|
||||
SYNTAX: A{ \ } [ >A ] parse-literal ;
|
||||
|
||||
: A-with ( x -- simd-array ) [ A-rep A ] dip simd-with ;
|
||||
|
||||
\ A-with \ A-rep \ A define-with-custom-inlining
|
||||
|
||||
\ A-boa [ \ A-rep \ A simd-boa ] \ A-rep 1 boa-effect define-declared
|
||||
|
||||
\ A-rep rep-gather-word [
|
||||
\ A-boa \ A-rep \ A define-boa-custom-inlining
|
||||
] when
|
||||
|
||||
: A-cast ( simd-array -- simd-array' )
|
||||
underlying>> \ A boa ; inline
|
||||
|
||||
INSTANCE: A sequence
|
||||
|
||||
<PRIVATE
|
||||
|
||||
: A-vv->v-op ( v1 v2 quot -- v3 )
|
||||
[ [ underlying>> ] bi@ A-rep ] dip call \ A boa ; inline
|
||||
|
||||
: A-vn->v-op ( v1 v2 quot -- v3 )
|
||||
[ [ underlying>> ] dip A-rep ] dip call \ A boa ; inline
|
||||
|
||||
: A-vv->n-op ( v1 v2 quot -- n )
|
||||
[ [ underlying>> ] bi@ A-rep ] dip call ; inline
|
||||
|
||||
: A-v->v-op ( v1 quot -- v2 )
|
||||
[ underlying>> A-rep ] dip call \ A boa ; inline
|
||||
|
||||
: A-v->n-op ( v quot -- n )
|
||||
[ underlying>> A-rep ] dip call ; inline
|
||||
|
||||
: A-v-conversion-op ( v1 to-type quot -- v2 )
|
||||
swap [ underlying>> A-rep ] [ call ] [ '[ _ boa ] call( u -- v ) ] tri* ; inline
|
||||
|
||||
: A-vv-conversion-op ( v1 v2 to-type quot -- v2 )
|
||||
swap {
|
||||
[ underlying>> ]
|
||||
[ underlying>> A-rep ]
|
||||
[ call ]
|
||||
[ '[ _ boa ] call( u -- v ) ]
|
||||
} spread ; inline
|
||||
|
||||
simd new
|
||||
\ A >>class
|
||||
\ A-with >>ctor
|
||||
\ A-rep >>rep
|
||||
{
|
||||
{ (v>float) A-v-conversion-op }
|
||||
{ (v>integer) A-v-conversion-op }
|
||||
{ (vpack-signed) A-vv-conversion-op }
|
||||
{ (vpack-unsigned) A-vv-conversion-op }
|
||||
{ (vunpack-head) A-v-conversion-op }
|
||||
{ (vunpack-tail) A-v-conversion-op }
|
||||
} >>special-wrappers
|
||||
{
|
||||
{ { +vector+ +vector+ -> +vector+ } A-vv->v-op }
|
||||
{ { +vector+ +any-vector+ -> +vector+ } A-vv->v-op }
|
||||
{ { +vector+ +scalar+ -> +vector+ } A-vn->v-op }
|
||||
{ { +vector+ +literal+ -> +vector+ } A-vn->v-op }
|
||||
{ { +vector+ +vector+ -> +scalar+ } A-vv->n-op }
|
||||
{ { +vector+ +vector+ -> +boolean+ } A-vv->n-op }
|
||||
{ { +vector+ -> +vector+ } A-v->v-op }
|
||||
{ { +vector+ -> +scalar+ } A-v->n-op }
|
||||
{ { +vector+ -> +boolean+ } A-v->n-op }
|
||||
{ { +vector+ -> +nonnegative+ } A-v->n-op }
|
||||
} >>schema-wrappers
|
||||
(define-simd-128)
|
||||
|
||||
PRIVATE>
|
||||
|
||||
;FUNCTOR
|
||||
|
||||
! Synthesize 256-bit vectors from a pair of 128-bit vectors
|
||||
SLOT: underlying1
|
||||
SLOT: underlying2
|
||||
|
||||
:: define-simd-256-type ( class rep -- )
|
||||
c:<c-type>
|
||||
class >>class
|
||||
class >>boxed-class
|
||||
[
|
||||
[ rep alien-vector ]
|
||||
[ 16 + >fixnum rep alien-vector ] 2bi
|
||||
class boa
|
||||
] >>getter
|
||||
[
|
||||
[ [ underlying1>> ] 2dip rep set-alien-vector ]
|
||||
[ [ underlying2>> ] 2dip 16 + >fixnum rep set-alien-vector ]
|
||||
3bi
|
||||
] >>setter
|
||||
32 >>size
|
||||
8 >>align
|
||||
rep >>rep
|
||||
class c:typedef ;
|
||||
|
||||
: (define-simd-256) ( simd -- )
|
||||
simd-ops get { vshuffle-elements vshuffle-bytes hlshift hrshift } unique assoc-diff >>ops
|
||||
[ define-simd ]
|
||||
[ [ class>> ] [ rep>> ] bi define-simd-256-type ] bi ;
|
||||
|
||||
FUNCTOR: define-simd-256 ( T -- )
|
||||
|
||||
N [ 32 T c:heap-size /i ]
|
||||
|
||||
N/2 [ N 2 /i ]
|
||||
A/2 IS ${T}-${N/2}
|
||||
A/2-boa IS ${A/2}-boa
|
||||
A/2-with IS ${A/2}-with
|
||||
|
||||
A DEFINES-CLASS ${T}-${N}
|
||||
A-boa DEFINES ${A}-boa
|
||||
A-with DEFINES ${A}-with
|
||||
A-cast DEFINES ${A}-cast
|
||||
>A DEFINES >${A}
|
||||
A{ DEFINES ${A}{
|
||||
|
||||
A-deref DEFINES-PRIVATE ${A}-deref
|
||||
|
||||
A-rep [ A/2 name>> "-rep" append "cpu.architecture" lookup ]
|
||||
A-vv->v-op DEFINES-PRIVATE ${A}-vv->v-op
|
||||
A-vn->v-op DEFINES-PRIVATE ${A}-vn->v-op
|
||||
A-v->v-op DEFINES-PRIVATE ${A}-v->v-op
|
||||
A-v.-op DEFINES-PRIVATE ${A}-v.-op
|
||||
(A-v->n-op) DEFINES-PRIVATE (${A}-v->v-op)
|
||||
A-sum-op DEFINES-PRIVATE ${A}-sum-op
|
||||
A-vany-op DEFINES-PRIVATE ${A}-vany-op
|
||||
A-vall-op DEFINES-PRIVATE ${A}-vall-op
|
||||
A-vmerge-head-op DEFINES-PRIVATE ${A}-vmerge-head-op
|
||||
A-vmerge-tail-op DEFINES-PRIVATE ${A}-vmerge-tail-op
|
||||
A-v-conversion-op DEFINES-PRIVATE ${A}-v-conversion-op
|
||||
A-vpack-op DEFINES-PRIVATE ${A}-vpack-op
|
||||
A-vunpack-head-op DEFINES-PRIVATE ${A}-vunpack-head-op
|
||||
A-vunpack-tail-op DEFINES-PRIVATE ${A}-vunpack-tail-op
|
||||
|
||||
WHERE
|
||||
|
||||
SLOT: underlying1
|
||||
SLOT: underlying2
|
||||
|
||||
TUPLE: A
|
||||
{ underlying1 byte-array initial: $[ 16 <byte-array> ] read-only }
|
||||
{ underlying2 byte-array initial: $[ 16 <byte-array> ] read-only } ;
|
||||
|
||||
INSTANCE: A simd-256
|
||||
|
||||
M: A clone
|
||||
[ underlying1>> clone ] [ underlying2>> clone ] bi
|
||||
\ A boa ; inline
|
||||
|
||||
M: A length drop N ; inline
|
||||
|
||||
M: A equal?
|
||||
over \ A instance? [ v= vall? ] [ 2drop f ] if ;
|
||||
|
||||
: A-deref ( n seq -- n' seq' )
|
||||
over N/2 < [ underlying1>> ] [ [ N/2 - ] dip underlying2>> ] if \ A/2 boa ; inline
|
||||
|
||||
M: A nth-unsafe A-deref nth-unsafe ; inline
|
||||
|
||||
M: A set-nth-unsafe A-deref set-nth-unsafe ; inline
|
||||
|
||||
: >A ( seq -- simd-array ) \ A new clone-like ;
|
||||
|
||||
M: A like drop dup \ A instance? [ >A ] unless ; inline
|
||||
|
||||
M: A new-sequence
|
||||
drop dup N =
|
||||
[ drop 16 <byte-array> 16 <byte-array> \ A boa ]
|
||||
[ N bad-length ]
|
||||
if ; inline
|
||||
|
||||
M: A c:byte-length drop 32 ; inline
|
||||
|
||||
M: A element-type drop A-rep rep-component-type ;
|
||||
|
||||
SYNTAX: A{ \ } [ >A ] parse-literal ;
|
||||
|
||||
M: A pprint-delims drop \ A{ \ } ;
|
||||
|
||||
M: A >pprint-sequence ;
|
||||
|
||||
M: A pprint* pprint-object ;
|
||||
|
||||
: A-with ( x -- simd-array )
|
||||
[ A/2-with ] [ A/2-with ] bi [ underlying>> ] bi@
|
||||
\ A boa ; inline
|
||||
|
||||
: A-boa ( ... -- simd-array )
|
||||
[ A/2-boa ] N/2 ndip A/2-boa [ underlying>> ] bi@
|
||||
\ A boa ; inline
|
||||
|
||||
\ A-rep 2 boa-effect \ A-boa set-stack-effect
|
||||
|
||||
: A-cast ( simd-array -- simd-array' )
|
||||
[ underlying1>> ] [ underlying2>> ] bi \ A boa ; inline
|
||||
|
||||
INSTANCE: A sequence
|
||||
|
||||
: A-vv->v-op ( v1 v2 quot -- v3 )
|
||||
[ [ [ underlying1>> ] bi@ A-rep ] dip call ]
|
||||
[ [ [ underlying2>> ] bi@ A-rep ] dip call ] 3bi
|
||||
\ A boa ; inline
|
||||
|
||||
: A-vn->v-op ( v1 v2 quot -- v3 )
|
||||
[ [ [ underlying1>> ] dip A-rep ] dip call ]
|
||||
[ [ [ underlying2>> ] dip A-rep ] dip call ] 3bi
|
||||
\ A boa ; inline
|
||||
|
||||
: A-v->v-op ( v1 combine-quot -- v2 )
|
||||
[ [ underlying1>> A-rep ] dip call ]
|
||||
[ [ underlying2>> A-rep ] dip call ] 2bi
|
||||
\ A boa ; inline
|
||||
|
||||
: A-v.-op ( v1 v2 quot -- n )
|
||||
[ [ [ underlying1>> ] bi@ A-rep ] dip call ]
|
||||
[ [ [ underlying2>> ] bi@ A-rep ] dip call ] 3bi
|
||||
+ ; inline
|
||||
|
||||
: (A-v->n-op) ( v1 quot reduce-quot -- n )
|
||||
'[ [ underlying1>> ] [ underlying2>> ] bi A-rep @ A-rep ] dip call ; inline
|
||||
|
||||
: A-sum-op ( v1 quot -- n )
|
||||
[ (simd-v+) ] (A-v->n-op) ; inline
|
||||
|
||||
: A-vany-op ( v1 quot -- n )
|
||||
[ (simd-vbitor) ] (A-v->n-op) ; inline
|
||||
: A-vall-op ( v1 quot -- n )
|
||||
[ (simd-vbitand) ] (A-v->n-op) ; inline
|
||||
|
||||
: A-vmerge-head-op ( v1 v2 quot -- v )
|
||||
drop
|
||||
[ underlying1>> ] bi@
|
||||
[ A-rep (simd-(vmerge-head)) ]
|
||||
[ A-rep (simd-(vmerge-tail)) ] 2bi
|
||||
\ A boa ; inline
|
||||
|
||||
: A-vmerge-tail-op ( v1 v2 quot -- v )
|
||||
drop
|
||||
[ underlying2>> ] bi@
|
||||
[ A-rep (simd-(vmerge-head)) ]
|
||||
[ A-rep (simd-(vmerge-tail)) ] 2bi
|
||||
\ A boa ; inline
|
||||
|
||||
: A-v-conversion-op ( v1 to-type quot -- v )
|
||||
swap [
|
||||
[ [ underlying1>> A-rep ] dip call ]
|
||||
[ [ underlying2>> A-rep ] dip call ] 2bi
|
||||
] dip '[ _ boa ] call( u1 u2 -- v ) ; inline
|
||||
|
||||
: A-vpack-op ( v1 v2 to-type quot -- v )
|
||||
swap [
|
||||
'[ [ underlying1>> ] [ underlying2>> ] bi A-rep @ ] bi*
|
||||
] dip '[ _ boa ] call( u1 u2 -- v ) ; inline
|
||||
|
||||
: A-vunpack-head-op ( v1 to-type quot -- v )
|
||||
'[
|
||||
underlying1>>
|
||||
[ A-rep @ ]
|
||||
[ A-rep (simd-(vunpack-tail)) ] bi
|
||||
] dip '[ _ boa ] call( u1 u2 -- v ) ; inline
|
||||
|
||||
: A-vunpack-tail-op ( v1 to-type quot -- v )
|
||||
'[
|
||||
underlying2>>
|
||||
[ A-rep (simd-(vunpack-head)) ]
|
||||
[ A-rep @ ] bi
|
||||
] dip '[ _ boa ] call( u1 u2 -- v ) ; inline
|
||||
|
||||
simd new
|
||||
\ A >>class
|
||||
\ A-with >>ctor
|
||||
\ A-rep >>rep
|
||||
{
|
||||
{ v. A-v.-op }
|
||||
{ sum A-sum-op }
|
||||
{ vnone? A-vany-op }
|
||||
{ vany? A-vany-op }
|
||||
{ vall? A-vall-op }
|
||||
{ (vmerge-head) A-vmerge-head-op }
|
||||
{ (vmerge-tail) A-vmerge-tail-op }
|
||||
{ (v>integer) A-v-conversion-op }
|
||||
{ (v>float) A-v-conversion-op }
|
||||
{ (vpack-signed) A-vpack-op }
|
||||
{ (vpack-unsigned) A-vpack-op }
|
||||
{ (vunpack-head) A-vunpack-head-op }
|
||||
{ (vunpack-tail) A-vunpack-tail-op }
|
||||
} >>special-wrappers
|
||||
{
|
||||
{ { +vector+ +vector+ -> +vector+ } A-vv->v-op }
|
||||
{ { +vector+ +scalar+ -> +vector+ } A-vn->v-op }
|
||||
{ { +vector+ +literal+ -> +vector+ } A-vn->v-op }
|
||||
{ { +vector+ -> +vector+ } A-v->v-op }
|
||||
} >>schema-wrappers
|
||||
(define-simd-256)
|
||||
|
||||
;FUNCTOR
|
|
@ -1 +0,0 @@
|
|||
Slava Pestov
|
|
@ -1,18 +0,0 @@
|
|||
IN: math.vectors.simd.intrinsics.tests
|
||||
USING: math.vectors.simd.intrinsics cpu.architecture tools.test ;
|
||||
|
||||
[ 16 ] [ uchar-16-rep rep-components ] unit-test
|
||||
[ 16 ] [ char-16-rep rep-components ] unit-test
|
||||
[ 8 ] [ ushort-8-rep rep-components ] unit-test
|
||||
[ 8 ] [ short-8-rep rep-components ] unit-test
|
||||
[ 4 ] [ uint-4-rep rep-components ] unit-test
|
||||
[ 4 ] [ int-4-rep rep-components ] unit-test
|
||||
[ 4 ] [ float-4-rep rep-components ] unit-test
|
||||
[ 2 ] [ double-2-rep rep-components ] unit-test
|
||||
|
||||
{ 4 1 } [ uint-4-rep (simd-boa) ] must-infer-as
|
||||
{ 4 1 } [ int-4-rep (simd-boa) ] must-infer-as
|
||||
{ 4 1 } [ float-4-rep (simd-boa) ] must-infer-as
|
||||
{ 2 1 } [ double-2-rep (simd-boa) ] must-infer-as
|
||||
|
||||
|
|
@ -1,207 +0,0 @@
|
|||
! Copyright (C) 2009 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien alien.c-types alien.data assocs combinators
|
||||
cpu.architecture compiler.cfg.comparisons fry generalizations
|
||||
kernel libc macros math
|
||||
math.vectors.conversion.backend
|
||||
sequences sets effects accessors namespaces
|
||||
lexer parser vocabs.parser words arrays math.vectors ;
|
||||
IN: math.vectors.simd.intrinsics
|
||||
|
||||
ERROR: bad-simd-call word ;
|
||||
|
||||
<<
|
||||
|
||||
: simd-effect ( word -- effect )
|
||||
stack-effect [ in>> "rep" suffix ] [ out>> ] bi <effect> ;
|
||||
: simd-conversion-effect ( word -- effect )
|
||||
stack-effect [ in>> but-last "rep" suffix ] [ out>> ] bi <effect> ;
|
||||
|
||||
SYMBOL: simd-ops
|
||||
|
||||
V{ } clone simd-ops set-global
|
||||
|
||||
: (SIMD-OP:) ( accum quot -- accum )
|
||||
[
|
||||
scan-word dup name>> "(simd-" ")" surround create-in
|
||||
[ nip dup '[ _ bad-simd-call ] define ]
|
||||
] dip
|
||||
'[ _ dip set-stack-effect ]
|
||||
[ 2array simd-ops get push ]
|
||||
2tri ; inline
|
||||
|
||||
SYNTAX: SIMD-OP:
|
||||
[ simd-effect ] (SIMD-OP:) ;
|
||||
|
||||
SYNTAX: SIMD-CONVERSION-OP:
|
||||
[ simd-conversion-effect ] (SIMD-OP:) ;
|
||||
|
||||
>>
|
||||
|
||||
SIMD-OP: v+
|
||||
SIMD-OP: v-
|
||||
SIMD-OP: vneg
|
||||
SIMD-OP: v+-
|
||||
SIMD-OP: vs+
|
||||
SIMD-OP: vs-
|
||||
SIMD-OP: vs*
|
||||
SIMD-OP: v*
|
||||
SIMD-OP: v/
|
||||
SIMD-OP: vmin
|
||||
SIMD-OP: vmax
|
||||
SIMD-OP: v.
|
||||
SIMD-OP: vsqrt
|
||||
SIMD-OP: sum
|
||||
SIMD-OP: vabs
|
||||
SIMD-OP: vbitand
|
||||
SIMD-OP: vbitandn
|
||||
SIMD-OP: vbitor
|
||||
SIMD-OP: vbitxor
|
||||
SIMD-OP: vbitnot
|
||||
SIMD-OP: vand
|
||||
SIMD-OP: vandn
|
||||
SIMD-OP: vor
|
||||
SIMD-OP: vxor
|
||||
SIMD-OP: vnot
|
||||
SIMD-OP: vlshift
|
||||
SIMD-OP: vrshift
|
||||
SIMD-OP: hlshift
|
||||
SIMD-OP: hrshift
|
||||
SIMD-OP: vshuffle-elements
|
||||
SIMD-OP: vshuffle-bytes
|
||||
SIMD-OP: (vmerge-head)
|
||||
SIMD-OP: (vmerge-tail)
|
||||
SIMD-OP: v<=
|
||||
SIMD-OP: v<
|
||||
SIMD-OP: v=
|
||||
SIMD-OP: v>
|
||||
SIMD-OP: v>=
|
||||
SIMD-OP: vunordered?
|
||||
SIMD-OP: vany?
|
||||
SIMD-OP: vall?
|
||||
SIMD-OP: vnone?
|
||||
|
||||
SIMD-CONVERSION-OP: (v>float)
|
||||
SIMD-CONVERSION-OP: (v>integer)
|
||||
SIMD-CONVERSION-OP: (vpack-signed)
|
||||
SIMD-CONVERSION-OP: (vpack-unsigned)
|
||||
SIMD-CONVERSION-OP: (vunpack-head)
|
||||
SIMD-CONVERSION-OP: (vunpack-tail)
|
||||
|
||||
: (simd-with) ( x rep -- v ) bad-simd-call ;
|
||||
: (simd-gather-2) ( a b rep -- v ) bad-simd-call ;
|
||||
: (simd-gather-4) ( a b c d rep -- v ) bad-simd-call ;
|
||||
: (simd-select) ( v n rep -- x ) bad-simd-call ;
|
||||
|
||||
: assert-positive ( x -- y ) ;
|
||||
|
||||
: alien-vector ( c-ptr n rep -- value )
|
||||
! Inefficient version for when intrinsics are missing
|
||||
[ swap <displaced-alien> ] dip rep-size memory>byte-array ;
|
||||
|
||||
: set-alien-vector ( value c-ptr n rep -- )
|
||||
! Inefficient version for when intrinsics are missing
|
||||
[ swap <displaced-alien> swap ] dip rep-size memcpy ;
|
||||
|
||||
<<
|
||||
|
||||
: rep-components ( rep -- n )
|
||||
16 swap rep-component-type heap-size /i ; foldable
|
||||
|
||||
: rep-coercer ( rep -- quot )
|
||||
{
|
||||
{ [ dup int-vector-rep? ] [ [ >fixnum ] ] }
|
||||
{ [ dup float-vector-rep? ] [ [ >float ] ] }
|
||||
} cond nip ; foldable
|
||||
|
||||
: rep-coerce ( value rep -- value' )
|
||||
rep-coercer call( value -- value' ) ; inline
|
||||
|
||||
CONSTANT: rep-gather-words
|
||||
{
|
||||
{ 2 (simd-gather-2) }
|
||||
{ 4 (simd-gather-4) }
|
||||
}
|
||||
|
||||
: rep-gather-word ( rep -- word )
|
||||
rep-components rep-gather-words at ;
|
||||
|
||||
>>
|
||||
|
||||
MACRO: (simd-boa) ( rep -- quot )
|
||||
{
|
||||
[ rep-coercer ]
|
||||
[ rep-components ]
|
||||
[ ]
|
||||
[ rep-gather-word ]
|
||||
} cleave
|
||||
'[ _ _ napply _ _ execute ] ;
|
||||
|
||||
GENERIC# supported-simd-op? 1 ( rep intrinsic -- ? )
|
||||
|
||||
: (%unpack-reps) ( -- reps )
|
||||
%merge-vector-reps [ int-vector-rep? ] filter
|
||||
%unpack-vector-head-reps union ;
|
||||
|
||||
: (%abs-reps) ( -- reps )
|
||||
cc> %compare-vector-reps [ int-vector-rep? ] filter
|
||||
%xor-vector-reps [ float-vector-rep? ] filter
|
||||
union
|
||||
[ { } ] [ { uchar-16-rep ushort-8-rep uint-4-rep ulonglong-2-rep } union ] if-empty ;
|
||||
|
||||
: (%shuffle-imm-reps) ( -- reps )
|
||||
%shuffle-vector-reps %shuffle-vector-imm-reps union ;
|
||||
|
||||
M: vector-rep supported-simd-op?
|
||||
{
|
||||
{ \ (simd-v+) [ %add-vector-reps ] }
|
||||
{ \ (simd-vs+) [ %saturated-add-vector-reps ] }
|
||||
{ \ (simd-v+-) [ %add-sub-vector-reps ] }
|
||||
{ \ (simd-v-) [ %sub-vector-reps ] }
|
||||
{ \ (simd-vs-) [ %saturated-sub-vector-reps ] }
|
||||
{ \ (simd-vneg) [ %sub-vector-reps ] }
|
||||
{ \ (simd-v*) [ %mul-vector-reps ] }
|
||||
{ \ (simd-vs*) [ %saturated-mul-vector-reps ] }
|
||||
{ \ (simd-v/) [ %div-vector-reps ] }
|
||||
{ \ (simd-vmin) [ %min-vector-reps cc< %compare-vector-reps union ] }
|
||||
{ \ (simd-vmax) [ %max-vector-reps cc> %compare-vector-reps union ] }
|
||||
{ \ (simd-v.) [ %dot-vector-reps ] }
|
||||
{ \ (simd-vsqrt) [ %sqrt-vector-reps ] }
|
||||
{ \ (simd-sum) [ %horizontal-add-vector-reps ] }
|
||||
{ \ (simd-vabs) [ (%abs-reps) ] }
|
||||
{ \ (simd-vbitand) [ %and-vector-reps ] }
|
||||
{ \ (simd-vbitandn) [ %andn-vector-reps ] }
|
||||
{ \ (simd-vbitor) [ %or-vector-reps ] }
|
||||
{ \ (simd-vbitxor) [ %xor-vector-reps ] }
|
||||
{ \ (simd-vbitnot) [ %xor-vector-reps ] }
|
||||
{ \ (simd-vand) [ %and-vector-reps ] }
|
||||
{ \ (simd-vandn) [ %andn-vector-reps ] }
|
||||
{ \ (simd-vor) [ %or-vector-reps ] }
|
||||
{ \ (simd-vxor) [ %xor-vector-reps ] }
|
||||
{ \ (simd-vnot) [ %xor-vector-reps ] }
|
||||
{ \ (simd-vlshift) [ %shl-vector-reps ] }
|
||||
{ \ (simd-vrshift) [ %shr-vector-reps ] }
|
||||
{ \ (simd-hlshift) [ %horizontal-shl-vector-imm-reps ] }
|
||||
{ \ (simd-hrshift) [ %horizontal-shr-vector-imm-reps ] }
|
||||
{ \ (simd-vshuffle-elements) [ (%shuffle-imm-reps) ] }
|
||||
{ \ (simd-vshuffle-bytes) [ %shuffle-vector-reps ] }
|
||||
{ \ (simd-(vmerge-head)) [ %merge-vector-reps ] }
|
||||
{ \ (simd-(vmerge-tail)) [ %merge-vector-reps ] }
|
||||
{ \ (simd-(v>float)) [ %integer>float-vector-reps ] }
|
||||
{ \ (simd-(v>integer)) [ %float>integer-vector-reps ] }
|
||||
{ \ (simd-(vpack-signed)) [ %signed-pack-vector-reps ] }
|
||||
{ \ (simd-(vpack-unsigned)) [ %unsigned-pack-vector-reps ] }
|
||||
{ \ (simd-(vunpack-head)) [ (%unpack-reps) ] }
|
||||
{ \ (simd-(vunpack-tail)) [ (%unpack-reps) ] }
|
||||
{ \ (simd-v<=) [ unsign-rep cc<= %compare-vector-reps ] }
|
||||
{ \ (simd-v<) [ unsign-rep cc< %compare-vector-reps ] }
|
||||
{ \ (simd-v=) [ unsign-rep cc= %compare-vector-reps ] }
|
||||
{ \ (simd-v>) [ unsign-rep cc> %compare-vector-reps ] }
|
||||
{ \ (simd-v>=) [ unsign-rep cc>= %compare-vector-reps ] }
|
||||
{ \ (simd-vunordered?) [ unsign-rep cc/<>= %compare-vector-reps ] }
|
||||
{ \ (simd-gather-2) [ %gather-vector-2-reps ] }
|
||||
{ \ (simd-gather-4) [ %gather-vector-4-reps ] }
|
||||
{ \ (simd-vany?) [ %test-vector-reps ] }
|
||||
{ \ (simd-vall?) [ %test-vector-reps ] }
|
||||
{ \ (simd-vnone?) [ %test-vector-reps ] }
|
||||
} case member? ;
|
|
@ -1,28 +0,0 @@
|
|||
IN: math.vectors.specialization.tests
|
||||
USING: compiler.tree.debugger math.vectors tools.test kernel
|
||||
kernel.private math specialized-arrays ;
|
||||
QUALIFIED-WITH: alien.c-types c
|
||||
QUALIFIED-WITH: alien.complex c
|
||||
SPECIALIZED-ARRAY: c:double
|
||||
SPECIALIZED-ARRAY: c:complex-float
|
||||
SPECIALIZED-ARRAY: c:float
|
||||
|
||||
[ V{ t } ] [
|
||||
[ { double-array double-array } declare distance 0.0 < not ] final-literals
|
||||
] unit-test
|
||||
|
||||
[ V{ float } ] [
|
||||
[ { float-array float } declare v*n norm ] final-classes
|
||||
] unit-test
|
||||
|
||||
[ V{ complex } ] [
|
||||
[ { complex-float-array complex-float-array } declare v. ] final-classes
|
||||
] unit-test
|
||||
|
||||
[ V{ float } ] [
|
||||
[ { float-array float } declare v*n norm ] final-classes
|
||||
] unit-test
|
||||
|
||||
[ V{ float } ] [
|
||||
[ { complex-float-array complex } declare v*n norm ] final-classes
|
||||
] unit-test
|
|
@ -1,207 +0,0 @@
|
|||
! Copyright (C) 2009 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: words kernel make sequences effects sets kernel.private
|
||||
accessors combinators math math.intervals math.vectors
|
||||
math.vectors.conversion.backend namespaces assocs fry splitting
|
||||
classes.algebra generalizations locals
|
||||
compiler.tree.propagation.info ;
|
||||
IN: math.vectors.specialization
|
||||
|
||||
SYMBOLS: -> +vector+ +any-vector+ +scalar+ +boolean+ +nonnegative+ +literal+ ;
|
||||
|
||||
: parent-vector-class ( type -- type' )
|
||||
{
|
||||
{ [ dup simd-128 class<= ] [ drop simd-128 ] }
|
||||
{ [ dup simd-256 class<= ] [ drop simd-256 ] }
|
||||
[ "Not a vector class" throw ]
|
||||
} cond ;
|
||||
|
||||
: signature-for-schema ( array-type elt-type schema -- signature )
|
||||
[
|
||||
{
|
||||
{ +vector+ [ drop ] }
|
||||
{ +any-vector+ [ drop parent-vector-class ] }
|
||||
{ +scalar+ [ nip ] }
|
||||
{ +boolean+ [ 2drop boolean ] }
|
||||
{ +nonnegative+ [ nip ] }
|
||||
{ +literal+ [ 2drop f ] }
|
||||
} case
|
||||
] with with map ;
|
||||
|
||||
: (specialize-vector-word) ( word array-type elt-type schema -- word' )
|
||||
signature-for-schema
|
||||
[ [ name>> ] [ [ name>> ] map "," join ] bi* "=>" glue f <word> ]
|
||||
[ [ , \ declare , def>> % ] [ ] make ]
|
||||
[ drop stack-effect ]
|
||||
2tri
|
||||
[ define-declared ] [ 2drop ] 3bi ;
|
||||
|
||||
: output-infos ( array-type elt-type schema -- value-infos )
|
||||
[
|
||||
{
|
||||
{ +vector+ [ drop <class-info> ] }
|
||||
{ +any-vector+ [ drop parent-vector-class <class-info> ] }
|
||||
{ +scalar+ [ nip <class-info> ] }
|
||||
{ +boolean+ [ 2drop boolean <class-info> ] }
|
||||
{
|
||||
+nonnegative+
|
||||
[
|
||||
nip
|
||||
dup complex class<= [ drop float ] when
|
||||
[0,inf] <class/interval-info>
|
||||
]
|
||||
}
|
||||
} case
|
||||
] with with map ;
|
||||
|
||||
: record-output-signature ( word array-type elt-type schema -- word )
|
||||
output-infos
|
||||
[ drop ]
|
||||
[ drop ]
|
||||
[ [ stack-effect in>> length '[ _ ndrop ] ] dip append ] 2tri
|
||||
"outputs" set-word-prop ;
|
||||
|
||||
CONSTANT: vector-words
|
||||
H{
|
||||
{ [v-] { +vector+ +vector+ -> +vector+ } }
|
||||
{ distance { +vector+ +vector+ -> +nonnegative+ } }
|
||||
{ n*v { +scalar+ +vector+ -> +vector+ } }
|
||||
{ n+v { +scalar+ +vector+ -> +vector+ } }
|
||||
{ n-v { +scalar+ +vector+ -> +vector+ } }
|
||||
{ n/v { +scalar+ +vector+ -> +vector+ } }
|
||||
{ norm { +vector+ -> +nonnegative+ } }
|
||||
{ norm-sq { +vector+ -> +nonnegative+ } }
|
||||
{ normalize { +vector+ -> +vector+ } }
|
||||
{ v* { +vector+ +vector+ -> +vector+ } }
|
||||
{ vs* { +vector+ +vector+ -> +vector+ } }
|
||||
{ v*n { +vector+ +scalar+ -> +vector+ } }
|
||||
{ v+ { +vector+ +vector+ -> +vector+ } }
|
||||
{ vs+ { +vector+ +vector+ -> +vector+ } }
|
||||
{ v+- { +vector+ +vector+ -> +vector+ } }
|
||||
{ v+n { +vector+ +scalar+ -> +vector+ } }
|
||||
{ v- { +vector+ +vector+ -> +vector+ } }
|
||||
{ vneg { +vector+ -> +vector+ } }
|
||||
{ vs- { +vector+ +vector+ -> +vector+ } }
|
||||
{ v-n { +vector+ +scalar+ -> +vector+ } }
|
||||
{ v. { +vector+ +vector+ -> +scalar+ } }
|
||||
{ v/ { +vector+ +vector+ -> +vector+ } }
|
||||
{ v/n { +vector+ +scalar+ -> +vector+ } }
|
||||
{ vceiling { +vector+ -> +vector+ } }
|
||||
{ vfloor { +vector+ -> +vector+ } }
|
||||
{ vmax { +vector+ +vector+ -> +vector+ } }
|
||||
{ vmin { +vector+ +vector+ -> +vector+ } }
|
||||
{ vneg { +vector+ -> +vector+ } }
|
||||
{ vtruncate { +vector+ -> +vector+ } }
|
||||
{ sum { +vector+ -> +scalar+ } }
|
||||
{ vabs { +vector+ -> +vector+ } }
|
||||
{ vsqrt { +vector+ -> +vector+ } }
|
||||
{ vbitand { +vector+ +vector+ -> +vector+ } }
|
||||
{ vbitandn { +vector+ +vector+ -> +vector+ } }
|
||||
{ vbitor { +vector+ +vector+ -> +vector+ } }
|
||||
{ vbitxor { +vector+ +vector+ -> +vector+ } }
|
||||
{ vbitnot { +vector+ -> +vector+ } }
|
||||
{ vand { +vector+ +vector+ -> +vector+ } }
|
||||
{ vandn { +vector+ +vector+ -> +vector+ } }
|
||||
{ vor { +vector+ +vector+ -> +vector+ } }
|
||||
{ vxor { +vector+ +vector+ -> +vector+ } }
|
||||
{ vnot { +vector+ -> +vector+ } }
|
||||
{ vlshift { +vector+ +scalar+ -> +vector+ } }
|
||||
{ vrshift { +vector+ +scalar+ -> +vector+ } }
|
||||
{ hlshift { +vector+ +literal+ -> +vector+ } }
|
||||
{ hrshift { +vector+ +literal+ -> +vector+ } }
|
||||
{ vshuffle-elements { +vector+ +literal+ -> +vector+ } }
|
||||
{ vshuffle-bytes { +vector+ +any-vector+ -> +vector+ } }
|
||||
{ vbroadcast { +vector+ +literal+ -> +vector+ } }
|
||||
{ (vmerge-head) { +vector+ +vector+ -> +vector+ } }
|
||||
{ (vmerge-tail) { +vector+ +vector+ -> +vector+ } }
|
||||
{ (v>float) { +vector+ +literal+ -> +vector+ } }
|
||||
{ (v>integer) { +vector+ +literal+ -> +vector+ } }
|
||||
{ (vpack-signed) { +vector+ +vector+ +literal+ -> +vector+ } }
|
||||
{ (vpack-unsigned) { +vector+ +vector+ +literal+ -> +vector+ } }
|
||||
{ (vunpack-head) { +vector+ +literal+ -> +vector+ } }
|
||||
{ (vunpack-tail) { +vector+ +literal+ -> +vector+ } }
|
||||
{ v<= { +vector+ +vector+ -> +vector+ } }
|
||||
{ v< { +vector+ +vector+ -> +vector+ } }
|
||||
{ v= { +vector+ +vector+ -> +vector+ } }
|
||||
{ v> { +vector+ +vector+ -> +vector+ } }
|
||||
{ v>= { +vector+ +vector+ -> +vector+ } }
|
||||
{ vunordered? { +vector+ +vector+ -> +vector+ } }
|
||||
{ vany? { +vector+ -> +boolean+ } }
|
||||
{ vall? { +vector+ -> +boolean+ } }
|
||||
{ vnone? { +vector+ -> +boolean+ } }
|
||||
}
|
||||
|
||||
PREDICATE: vector-word < word vector-words key? ;
|
||||
|
||||
: specializations ( word -- assoc )
|
||||
dup "specializations" word-prop
|
||||
[ ] [ V{ } clone [ "specializations" set-word-prop ] keep ] ?if ;
|
||||
|
||||
M: vector-word subwords specializations values [ word? ] filter ;
|
||||
|
||||
: add-specialization ( new-word signature word -- )
|
||||
specializations set-at ;
|
||||
|
||||
ERROR: bad-vector-word word ;
|
||||
|
||||
: word-schema ( word -- schema )
|
||||
vector-words ?at [ bad-vector-word ] unless ;
|
||||
|
||||
: inputs ( schema -- seq ) { -> } split first ;
|
||||
|
||||
: outputs ( schema -- seq ) { -> } split second ;
|
||||
|
||||
: loop-vector-op ( word array-type elt-type -- word' )
|
||||
pick word-schema
|
||||
[ inputs (specialize-vector-word) ]
|
||||
[ outputs record-output-signature ] 3bi ;
|
||||
|
||||
:: specialize-vector-word ( word array-type elt-type simd -- word/quot' )
|
||||
word simd key? [ word simd at ] [ word array-type elt-type loop-vector-op ] if ;
|
||||
|
||||
:: input-signature ( word array-type elt-type -- signature )
|
||||
array-type elt-type word word-schema inputs signature-for-schema ;
|
||||
|
||||
: vector-words-for-type ( elt-type -- words )
|
||||
{
|
||||
! Can't do shifts on floats
|
||||
{ [ dup float class<= ] [ vector-words keys { vlshift vrshift } diff ] }
|
||||
! Can't divide integers
|
||||
{ [ dup integer class<= ] [ vector-words keys { vsqrt n/v v/n v/ normalize } diff ] }
|
||||
! Can't compute square root of complex numbers (vsqrt uses fsqrt not sqrt)
|
||||
{ [ dup complex class<= ] [ vector-words keys { vsqrt } diff ] }
|
||||
[ { } ]
|
||||
} cond
|
||||
! Don't specialize horizontal shifts, shuffles, and conversions at all, they're only for SIMD
|
||||
{
|
||||
hlshift hrshift vshuffle-elements vshuffle-bytes vbroadcast
|
||||
(v>integer) (v>float)
|
||||
(vpack-signed) (vpack-unsigned)
|
||||
(vunpack-head) (vunpack-tail)
|
||||
} diff
|
||||
nip ;
|
||||
|
||||
:: specialize-vector-words ( array-type elt-type simd -- )
|
||||
elt-type vector-words-for-type simd keys union [
|
||||
[ array-type elt-type simd specialize-vector-word ]
|
||||
[ array-type elt-type input-signature ]
|
||||
[ ]
|
||||
tri add-specialization
|
||||
] each ;
|
||||
|
||||
: specialization-matches? ( value-infos signature -- ? )
|
||||
[ [ [ class>> ] dip class<= ] [ literal?>> ] if* ] 2all? ;
|
||||
|
||||
: find-specialization ( classes word -- word/f )
|
||||
specializations
|
||||
[ first specialization-matches? ] with find
|
||||
swap [ second ] when ;
|
||||
|
||||
: vector-word-custom-inlining ( #call -- word/f )
|
||||
[ in-d>> [ value-info ] map ] [ word>> ] bi
|
||||
find-specialization ;
|
||||
|
||||
vector-words keys [
|
||||
[ vector-word-custom-inlining ]
|
||||
"custom-inlining" set-word-prop
|
||||
] each
|
Loading…
Reference in New Issue