math.vectors.specialization: first attempt at some call site splitting for vector ops. Specialized array types generate customized variants of all vector words, if input types are known at compile time, a call to the specialized version is inserted
parent
687454878a
commit
1cb0f3370b
|
@ -69,7 +69,7 @@ t specialize-method? set-global
|
||||||
dup [ array? ] all? [ first ] when length ;
|
dup [ array? ] all? [ first ] when length ;
|
||||||
|
|
||||||
SYNTAX: HINTS:
|
SYNTAX: HINTS:
|
||||||
scan-object
|
scan-object dup wrapper? [ wrapped>> ] when
|
||||||
[ changed-definition ]
|
[ changed-definition ]
|
||||||
[ parse-definition { } like "specializer" set-word-prop ] bi ;
|
[ parse-definition { } like "specializer" set-word-prop ] bi ;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ IN: math.intervals.tests
|
||||||
|
|
||||||
[ empty-interval ] [ 2 2 (a,b) ] unit-test
|
[ empty-interval ] [ 2 2 (a,b) ] unit-test
|
||||||
|
|
||||||
|
[ empty-interval ] [ 2 2.0 (a,b) ] unit-test
|
||||||
|
|
||||||
[ empty-interval ] [ 2 2 [a,b) ] unit-test
|
[ empty-interval ] [ 2 2 [a,b) ] unit-test
|
||||||
|
|
||||||
[ empty-interval ] [ 2 2 (a,b] ] unit-test
|
[ empty-interval ] [ 2 2 (a,b] ] unit-test
|
||||||
|
@ -189,6 +191,10 @@ IN: math.intervals.tests
|
||||||
|
|
||||||
[ f ] [ 0 10 [a,b] 0 [a,a] interval< ] unit-test
|
[ f ] [ 0 10 [a,b] 0 [a,a] interval< ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ 0 10 [a,b] 0.0 [a,a] interval< ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ 0.0 10 [a,b] 0 [a,a] interval< ] unit-test
|
||||||
|
|
||||||
[ f ] [ 0 10 [a,b] 10 [a,a] interval> ] unit-test
|
[ f ] [ 0 10 [a,b] 10 [a,a] interval> ] unit-test
|
||||||
|
|
||||||
[ incomparable ] [ 0 [a,a] 0 10 [a,b] interval< ] unit-test
|
[ incomparable ] [ 0 [a,a] 0 10 [a,b] interval< ] unit-test
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
! Copyright (C) 2007, 2008 Slava Pestov, Doug Coleman.
|
! Copyright (C) 2007, 2009 Slava Pestov, Doug Coleman.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
! Based on Slate's src/unfinished/interval.slate by Brian Rice.
|
! Based on Slate's src/unfinished/interval.slate by Brian Rice.
|
||||||
USING: accessors kernel sequences arrays math math.order
|
USING: accessors kernel sequences arrays math math.order
|
||||||
|
@ -14,7 +14,7 @@ TUPLE: interval { from read-only } { to read-only } ;
|
||||||
: <interval> ( from to -- interval )
|
: <interval> ( from to -- interval )
|
||||||
2dup [ first ] bi@ {
|
2dup [ first ] bi@ {
|
||||||
{ [ 2dup > ] [ 2drop 2drop empty-interval ] }
|
{ [ 2dup > ] [ 2drop 2drop empty-interval ] }
|
||||||
{ [ 2dup = ] [
|
{ [ 2dup number= ] [
|
||||||
2drop 2dup [ second ] both?
|
2drop 2dup [ second ] both?
|
||||||
[ interval boa ] [ 2drop empty-interval ] if
|
[ interval boa ] [ 2drop empty-interval ] if
|
||||||
] }
|
] }
|
||||||
|
@ -56,20 +56,23 @@ TUPLE: interval { from read-only } { to read-only } ;
|
||||||
[ 2dup [ first ] bi@ ] dip call [
|
[ 2dup [ first ] bi@ ] dip call [
|
||||||
2drop t
|
2drop t
|
||||||
] [
|
] [
|
||||||
2dup [ first ] bi@ = [
|
2dup [ first ] bi@ number= [
|
||||||
[ second ] bi@ not or
|
[ second ] bi@ not or
|
||||||
] [
|
] [
|
||||||
2drop f
|
2drop f
|
||||||
] if
|
] if
|
||||||
] if ; inline
|
] if ; inline
|
||||||
|
|
||||||
|
: endpoint= ( p1 p2 -- ? )
|
||||||
|
[ [ first ] bi@ number= ] [ [ second ] bi@ eq? ] 2bi and ;
|
||||||
|
|
||||||
: endpoint< ( p1 p2 -- ? ) [ < ] compare-endpoints ;
|
: endpoint< ( p1 p2 -- ? ) [ < ] compare-endpoints ;
|
||||||
|
|
||||||
: endpoint<= ( p1 p2 -- ? ) [ endpoint< ] 2keep = or ;
|
: endpoint<= ( p1 p2 -- ? ) [ endpoint< ] [ endpoint= ] 2bi or ;
|
||||||
|
|
||||||
: endpoint> ( p1 p2 -- ? ) [ > ] compare-endpoints ;
|
: endpoint> ( p1 p2 -- ? ) [ > ] compare-endpoints ;
|
||||||
|
|
||||||
: endpoint>= ( p1 p2 -- ? ) [ endpoint> ] 2keep = or ;
|
: endpoint>= ( p1 p2 -- ? ) [ endpoint> ] [ endpoint= ] 2bi or ;
|
||||||
|
|
||||||
: endpoint-min ( p1 p2 -- p3 ) [ endpoint< ] most ;
|
: endpoint-min ( p1 p2 -- p3 ) [ endpoint< ] most ;
|
||||||
|
|
||||||
|
@ -180,7 +183,7 @@ TUPLE: interval { from read-only } { to read-only } ;
|
||||||
] [
|
] [
|
||||||
interval>points
|
interval>points
|
||||||
2dup [ second ] both?
|
2dup [ second ] both?
|
||||||
[ [ first ] bi@ = ]
|
[ [ first ] bi@ number= ]
|
||||||
[ 2drop f ] if
|
[ 2drop f ] if
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
|
@ -278,13 +281,13 @@ SYMBOL: incomparable
|
||||||
: left-endpoint-< ( i1 i2 -- ? )
|
: left-endpoint-< ( i1 i2 -- ? )
|
||||||
[ swap interval-subset? ]
|
[ swap interval-subset? ]
|
||||||
[ nip interval-singleton? ]
|
[ nip interval-singleton? ]
|
||||||
[ [ from>> ] bi@ = ]
|
[ [ from>> ] bi@ endpoint= ]
|
||||||
2tri and and ;
|
2tri and and ;
|
||||||
|
|
||||||
: right-endpoint-< ( i1 i2 -- ? )
|
: right-endpoint-< ( i1 i2 -- ? )
|
||||||
[ interval-subset? ]
|
[ interval-subset? ]
|
||||||
[ drop interval-singleton? ]
|
[ drop interval-singleton? ]
|
||||||
[ [ to>> ] bi@ = ]
|
[ [ to>> ] bi@ endpoint= ]
|
||||||
2tri and and ;
|
2tri and and ;
|
||||||
|
|
||||||
: (interval<) ( i1 i2 -- i1 i2 ? )
|
: (interval<) ( i1 i2 -- i1 i2 ? )
|
||||||
|
@ -300,10 +303,10 @@ SYMBOL: incomparable
|
||||||
} cond 2nip ;
|
} cond 2nip ;
|
||||||
|
|
||||||
: left-endpoint-<= ( i1 i2 -- ? )
|
: left-endpoint-<= ( i1 i2 -- ? )
|
||||||
[ from>> ] dip to>> = ;
|
[ from>> ] [ to>> ] bi* endpoint= ;
|
||||||
|
|
||||||
: right-endpoint-<= ( i1 i2 -- ? )
|
: right-endpoint-<= ( i1 i2 -- ? )
|
||||||
[ to>> ] dip from>> = ;
|
[ to>> ] [ from>> ] bi* endpoint= ;
|
||||||
|
|
||||||
: interval<= ( i1 i2 -- ? )
|
: interval<= ( i1 i2 -- ? )
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
IN: math.vectors.specialization.tests
|
||||||
|
USING: compiler.tree.debugger math.vectors tools.test kernel
|
||||||
|
kernel.private math specialized-arrays.double
|
||||||
|
specialized-arrays.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
|
|
@ -0,0 +1,112 @@
|
||||||
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: words kernel make sequences effects kernel.private accessors
|
||||||
|
combinators math math.intervals math.vectors namespaces assocs fry
|
||||||
|
splitting classes.algebra generalizations
|
||||||
|
compiler.tree.propagation.info ;
|
||||||
|
IN: math.vectors.specialization
|
||||||
|
|
||||||
|
SYMBOLS: -> +vector+ +scalar+ +nonnegative+ ;
|
||||||
|
|
||||||
|
: signature-for-schema ( array-type elt-type schema -- signature )
|
||||||
|
[
|
||||||
|
{
|
||||||
|
{ +vector+ [ drop ] }
|
||||||
|
{ +scalar+ [ nip ] }
|
||||||
|
{ +nonnegative+ [ nip ] }
|
||||||
|
} 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> ] }
|
||||||
|
{ +scalar+ [ nip <class-info> ] }
|
||||||
|
{ +nonnegative+ [ nip real class-and [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+ } }
|
||||||
|
{ v*n { +vector+ +scalar+ -> +vector+ } }
|
||||||
|
{ v+ { +vector+ +vector+ -> +vector+ } }
|
||||||
|
{ v+n { +vector+ +scalar+ -> +vector+ } }
|
||||||
|
{ v- { +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+ } }
|
||||||
|
}
|
||||||
|
|
||||||
|
SYMBOL: specializations
|
||||||
|
|
||||||
|
specializations [ vector-words keys [ V{ } clone ] H{ } map>assoc ] initialize
|
||||||
|
|
||||||
|
: add-specialization ( new-word signature word -- )
|
||||||
|
specializations get at set-at ;
|
||||||
|
|
||||||
|
: word-schema ( word -- schema ) vector-words at ;
|
||||||
|
|
||||||
|
: inputs ( schema -- seq ) { -> } split first ;
|
||||||
|
|
||||||
|
: outputs ( schema -- seq ) { -> } split second ;
|
||||||
|
|
||||||
|
: specialize-vector-word ( word array-type elt-type -- word' )
|
||||||
|
pick word-schema
|
||||||
|
[ inputs (specialize-vector-word) ]
|
||||||
|
[ outputs record-output-signature ] 3bi ;
|
||||||
|
|
||||||
|
: input-signature ( word -- signature ) def>> first ;
|
||||||
|
|
||||||
|
: specialize-vector-words ( array-type elt-type -- )
|
||||||
|
[ vector-words keys ] 2dip
|
||||||
|
'[
|
||||||
|
[ _ _ specialize-vector-word ] keep
|
||||||
|
[ dup input-signature ] dip
|
||||||
|
add-specialization
|
||||||
|
] each ;
|
||||||
|
|
||||||
|
: find-specialization ( classes word -- word/f )
|
||||||
|
specializations get at
|
||||||
|
[ first [ class<= ] 2all? ] with find
|
||||||
|
swap [ second ] when ;
|
||||||
|
|
||||||
|
: vector-word-custom-inlining ( #call -- word/f )
|
||||||
|
[ in-d>> [ value-info class>> ] map ] [ word>> ] bi
|
||||||
|
find-specialization ;
|
||||||
|
|
||||||
|
vector-words keys [
|
||||||
|
[ vector-word-custom-inlining ]
|
||||||
|
"custom-inlining" set-word-prop
|
||||||
|
] each
|
|
@ -41,9 +41,13 @@ IN: math.vectors
|
||||||
: set-axis ( u v axis -- w )
|
: set-axis ( u v axis -- w )
|
||||||
[ [ zero? 2over ? ] dip swap nth ] map-index 2nip ;
|
[ [ zero? 2over ? ] dip swap nth ] map-index 2nip ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
: 2tetra@ ( p q r s t u v w quot -- )
|
: 2tetra@ ( p q r s t u v w quot -- )
|
||||||
dup [ [ 2bi@ ] curry 4dip ] dip 2bi@ ; inline
|
dup [ [ 2bi@ ] curry 4dip ] dip 2bi@ ; inline
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
: trilerp ( aaa baa aba bba aab bab abb bbb {t,u,v} -- a_tuv )
|
: trilerp ( aaa baa aba bba aab bab abb bbb {t,u,v} -- a_tuv )
|
||||||
[ first lerp ] [ second lerp ] [ third lerp ] tri-curry
|
[ first lerp ] [ second lerp ] [ third lerp ] tri-curry
|
||||||
[ 2tetra@ ] [ 2bi@ ] [ call ] tri* ;
|
[ 2tetra@ ] [ 2bi@ ] [ call ] tri* ;
|
||||||
|
|
|
@ -11,61 +11,14 @@ HINTS: <double-array> { 2 } { 3 } ;
|
||||||
|
|
||||||
HINTS: (double-array) { 2 } { 3 } ;
|
HINTS: (double-array) { 2 } { 3 } ;
|
||||||
|
|
||||||
HINTS: vneg { array } { double-array } ;
|
|
||||||
HINTS: v*n { array object } { double-array float } ;
|
|
||||||
HINTS: n*v { array object } { float double-array } ;
|
|
||||||
HINTS: v/n { array object } { double-array float } ;
|
|
||||||
HINTS: n/v { object array } { float double-array } ;
|
|
||||||
HINTS: v+ { array array } { double-array double-array } ;
|
|
||||||
HINTS: v- { array array } { double-array double-array } ;
|
|
||||||
HINTS: v* { array array } { double-array double-array } ;
|
|
||||||
HINTS: v/ { array array } { double-array double-array } ;
|
|
||||||
HINTS: vmax { array array } { double-array double-array } ;
|
|
||||||
HINTS: vmin { array array } { double-array double-array } ;
|
|
||||||
HINTS: v. { array array } { double-array double-array } ;
|
|
||||||
HINTS: norm-sq { array } { double-array } ;
|
|
||||||
HINTS: norm { array } { double-array } ;
|
|
||||||
HINTS: normalize { array } { double-array } ;
|
|
||||||
HINTS: distance { array array } { double-array double-array } ;
|
|
||||||
|
|
||||||
! Type functions
|
! Type functions
|
||||||
USING: words classes.algebra compiler.tree.propagation.info
|
USING: words classes.algebra compiler.tree.propagation.info
|
||||||
math.intervals ;
|
math.intervals ;
|
||||||
|
|
||||||
{ v+ v- v* v/ vmax vmin } [
|
|
||||||
[
|
|
||||||
[ class>> double-array class<= ] both?
|
|
||||||
double-array object ? <class-info>
|
|
||||||
] "outputs" set-word-prop
|
|
||||||
] each
|
|
||||||
|
|
||||||
{ n*v n/v } [
|
|
||||||
[
|
|
||||||
nip class>> double-array class<= double-array object ? <class-info>
|
|
||||||
] "outputs" set-word-prop
|
|
||||||
] each
|
|
||||||
|
|
||||||
{ v*n v/n } [
|
|
||||||
[
|
|
||||||
drop class>> double-array class<= double-array object ? <class-info>
|
|
||||||
] "outputs" set-word-prop
|
|
||||||
] each
|
|
||||||
|
|
||||||
{ vneg normalize } [
|
|
||||||
[
|
|
||||||
class>> double-array class<= double-array object ? <class-info>
|
|
||||||
] "outputs" set-word-prop
|
|
||||||
] each
|
|
||||||
|
|
||||||
\ norm-sq [
|
\ norm-sq [
|
||||||
class>> double-array class<= [ float 0. 1/0. [a,b] <class/interval-info> ] [ object-info ] if
|
class>> double-array class<= [ float 0. 1/0. [a,b] <class/interval-info> ] [ object-info ] if
|
||||||
] "outputs" set-word-prop
|
] "outputs" set-word-prop
|
||||||
|
|
||||||
\ v. [
|
|
||||||
[ class>> double-array class<= ] both?
|
|
||||||
float object ? <class-info>
|
|
||||||
] "outputs" set-word-prop
|
|
||||||
|
|
||||||
\ distance [
|
\ distance [
|
||||||
[ class>> double-array class<= ] both?
|
[ class>> double-array class<= ] both?
|
||||||
[ float 0. 1/0. [a,b] <class/interval-info> ] [ object-info ] if
|
[ float 0. 1/0. [a,b] <class/interval-info> ] [ object-info ] if
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: functors sequences sequences.private prettyprint.custom
|
USING: functors sequences sequences.private prettyprint.custom
|
||||||
kernel words classes math parser alien.c-types byte-arrays
|
kernel words classes math math.vectors.specialization parser
|
||||||
accessors summary ;
|
alien.c-types byte-arrays accessors summary ;
|
||||||
IN: specialized-arrays.functor
|
IN: specialized-arrays.functor
|
||||||
|
|
||||||
ERROR: bad-byte-array-length byte-array type ;
|
ERROR: bad-byte-array-length byte-array type ;
|
||||||
|
@ -74,4 +74,6 @@ SYNTAX: A{ \ } [ >A ] parse-literal ;
|
||||||
|
|
||||||
INSTANCE: A sequence
|
INSTANCE: A sequence
|
||||||
|
|
||||||
|
A T c-type class>> specialize-vector-words
|
||||||
|
|
||||||
;FUNCTOR
|
;FUNCTOR
|
||||||
|
|
|
@ -78,6 +78,8 @@ C: <sphere> sphere
|
||||||
M: sphere intersect-scene ( hit ray sphere -- hit )
|
M: sphere intersect-scene ( hit ray sphere -- hit )
|
||||||
[ [ sphere-n normalize ] keep <hit> nip ] if-ray-sphere ;
|
[ [ sphere-n normalize ] keep <hit> nip ] if-ray-sphere ;
|
||||||
|
|
||||||
|
HINTS: M\ sphere intersect-scene { hit ray sphere } ;
|
||||||
|
|
||||||
TUPLE: group < sphere { objs array read-only } ;
|
TUPLE: group < sphere { objs array read-only } ;
|
||||||
|
|
||||||
: <group> ( objs bound -- group )
|
: <group> ( objs bound -- group )
|
||||||
|
@ -89,6 +91,8 @@ TUPLE: group < sphere { objs array read-only } ;
|
||||||
M: group intersect-scene ( hit ray group -- hit )
|
M: group intersect-scene ( hit ray group -- hit )
|
||||||
[ drop objs>> [ intersect-scene ] with each ] if-ray-sphere ;
|
[ drop objs>> [ intersect-scene ] with each ] if-ray-sphere ;
|
||||||
|
|
||||||
|
HINTS: M\ group intersect-scene { hit ray group } ;
|
||||||
|
|
||||||
CONSTANT: initial-hit T{ hit f double-array{ 0.0 0.0 0.0 } 1/0. }
|
CONSTANT: initial-hit T{ hit f double-array{ 0.0 0.0 0.0 } 1/0. }
|
||||||
|
|
||||||
: initial-intersect ( ray scene -- hit )
|
: initial-intersect ( ray scene -- hit )
|
||||||
|
|
Loading…
Reference in New Issue