From bedfc8f13c743e29d70a4d4ef9f157f748a8c1cc Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Tue, 20 Oct 2009 22:49:20 -0500 Subject: [PATCH] vif combinator --- basis/math/vectors/vectors-docs.factor | 12 +++++++++++- basis/math/vectors/vectors.factor | 9 ++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/basis/math/vectors/vectors-docs.factor b/basis/math/vectors/vectors-docs.factor index 71e86417f5..b831ac7dbe 100644 --- a/basis/math/vectors/vectors-docs.factor +++ b/basis/math/vectors/vectors-docs.factor @@ -101,6 +101,7 @@ $nl vxor vnot v? + vif } "Entire vector tests:" { $subsections @@ -534,10 +535,19 @@ HELP: vnot { $notes "See " { $link "math-vectors-simd-logic" } " for notes on dealing with vector boolean inputs and results when using SIMD types." } ; HELP: v? -{ $values { "mask" "a sequence of booleans" } { "true" "a sequence of numbers" } { "false" "a sequence of numbers" } { "w" "a sequence of numbers" } } +{ $values { "mask" "a sequence of booleans" } { "true" "a sequence of numbers" } { "false" "a sequence of numbers" } { "result" "a sequence of numbers" } } { $description "Creates a new sequence by selecting elements from the " { $snippet "true" } " and " { $snippet "false" } " sequences based on whether the corresponding bits of the " { $snippet "mask" } " sequence are set or not." } { $notes "See " { $link "math-vectors-simd-logic" } " for notes on dealing with vector boolean inputs and results when using SIMD types." } ; +HELP: vif +{ $values { "mask" "a sequence of booleans" } { "true-quot" { $quotation "( -- vector )" } } { "false-quot" { $quotation "( -- vector )" } } { "result" "a sequence" } } +{ $description "If all of the elements of " { $snippet "mask" } " are true, " { $snippet "true-quot" } " is called and its output value returned. If all of the elements of " { $snippet "mask" } " are false, " { $snippet "false-quot" } " is called and its output value returned. Otherwise, both quotations are called and " { $snippet "mask" } " is used to select elements from each output as with " { $link v? } "." } +{ $notes "See " { $link "math-vectors-simd-logic" } " for notes on dealing with vector boolean inputs and results when using SIMD types." +$nl +"For most conditional SIMD code, unless a case is exceptionally expensive to compute, it is usually most efficient to just compute all cases and blend them with " { $link v? } " instead of using " { $snippet "vif" } "." } ; + +{ v? vif } related-words + HELP: vany? { $values { "v" "a sequence of booleans" } { "?" "a boolean" } } { $description "Returns true if any element of " { $snippet "v" } " is true." } diff --git a/basis/math/vectors/vectors.factor b/basis/math/vectors/vectors.factor index 49ee6c3873..81af5c12d2 100644 --- a/basis/math/vectors/vectors.factor +++ b/basis/math/vectors/vectors.factor @@ -142,9 +142,16 @@ M: simd-128 vshuffle ( u perm -- v ) : vunordered? ( u v -- w ) [ unordered? ] 2map ; : v= ( u v -- w ) [ = ] 2map ; -: v? ( mask true false -- w ) +: v? ( mask true false -- result ) [ vand ] [ vandn ] bi-curry* bi vor ; inline +:: vif ( mask true-quot false-quot -- result ) + { + { [ mask vall? ] [ true-quot call ] } + { [ mask vnone? ] [ false-quot call ] } + [ mask true-quot call false-quot call v? ] + } cond ; inline + : vfloor ( u -- v ) [ floor ] map ; : vceiling ( u -- v ) [ ceiling ] map ; : vtruncate ( u -- v ) [ truncate ] map ;