This atan2 optimisation is easy, done in 
https://github.com/grame-cncm/faust/commit/26537a42f0fe55c7d471cdbb968755bec92c1707

Stéphane 

> Le 29 avr. 2023 à 18:41, Oleg Nesterov <o...@redhat.com> a écrit :
> 
> Stephane, Yann,
> 
> Can I suggest another feature? The patch is not for inclusion yet,
> but I'd like to discuss the idea / implementation.
> 
> It adds the new keyword `meta` which returns the environment with
> 2 primitives (so far):
> 
>       1. serial(sig)  - returns sig->serial()
>       2. order(sig)   - getSigOrder(sig)
> 
> Note that they compute the returned value at compile time.
> 
> Why the environment? Because this way it is very easy to add more
> primitives (e.g. typeof(sig) which returns kBool / kInt / kReal)
> using a single keyword.
> 
> Why do we want this feature? Well, I certainly do ;) but I do not
> have a simple and convincing example.
> 
> -------------------------------------------------------------------------------
> But let me provide a basic example even if it is not convincing.
> Consider:
> 
>       process(x,y) = atan2(x,x), atan2(x,y);
>       
> it compiles to
> 
>       float fTemp0 = float(input0[i0]);
>       output0[i0] = FAUSTFLOAT(std::atan2(fTemp0, fTemp0));
>       output1[i0] = FAUSTFLOAT(std::atan2(fTemp0, float(input1[i0])));
> 
> note that atan2(fTemp0, fTemp0) == %pi/4 (lets ignore the fTemp0 == 0
> case for the sake of simplicity), so this code is suboptimal.
> 
> Let's try to improve this code:
> 
>       my_atan2(a,b) = select2(a == b, atan2(a,b), ma.PI/4);
>       process(x,y) = my_atan2(x,x), my_atan2(x,y);
> 
> result:
> 
>       float fTemp0 = float(input0[i0]);
>       output0[i0] = FAUSTFLOAT(((fTemp0 == fTemp0) ? 0.7853982f : 
> std::atan2(fTemp0, fTemp0)));
>       float fTemp1 = float(input1[i0]);
>       output1[i0] = FAUSTFLOAT(((fTemp0 == fTemp1) ? 0.7853982f : 
> std::atan2(fTemp0, fTemp1)));
> 
> doesn't look very good although the compiler will optimize out the 1st 
> `fTemp0 == fTemp0` check.
> 
> Now let's use meta.serial:
> 
>       same_signal(a,b) = meta.serial(a) == meta.serial(b);
> 
>       my_atan2(a,b) = select2(same_signal(a,b), atan2(a,b), ma.PI/4);
>       process(x,y) = my_atan2(x,x), my_atan2(x,y);
> 
> result:
> 
>       output0[i0] = FAUSTFLOAT(0.7853982f);
>       output1[i0] = FAUSTFLOAT(std::atan2(float(input0[i0]), 
> float(input1[i0])));
> 
> Oleg.
> ---
> compiler/extended/metaprim.hh | 94 +++++++++++++++++++++++++++++++++++
> compiler/global.cpp           |  3 ++
> compiler/global.hh            |  2 +
> compiler/parser/faustlexer.l  |  2 +
> compiler/parser/faustparser.y |  3 ++
> 5 files changed, 104 insertions(+)
> create mode 100644 compiler/extended/metaprim.hh
> 
> diff --git a/compiler/extended/metaprim.hh b/compiler/extended/metaprim.hh
> new file mode 100644
> index 000000000..20cc5982e
> --- /dev/null
> +++ b/compiler/extended/metaprim.hh
> @@ -0,0 +1,94 @@
> +/************************************************************************
> + ************************************************************************
> +    FAUST compiler
> +    Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
> +    ---------------------------------------------------------------------
> +    This program is free software; you can redistribute it and/or modify
> +    it under the terms of the GNU Lesser General Public License as published 
> by
> +    the Free Software Foundation; either version 2.1 of the License, or
> +    (at your option) any later version.
> +
> +    This program is distributed in the hope that it will be useful,
> +    but WITHOUT ANY WARRANTY; without even the implied warranty of
> +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +    GNU Lesser General Public License for more details.
> +
> +    You should have received a copy of the GNU Lesser General Public License
> +    along with this program; if not, write to the Free Software
> +    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + ************************************************************************
> + ************************************************************************/
> +
> +#include "xtended.hh"
> +#include "simplify.hh"
> +#include "sigorderrules.hh"
> +
> +class MetaPrim : public xtended {
> +    private:
> +     int fOp;
> +    public:
> +     MetaPrim(int op, const char *name) : xtended(name), fOp(op) {}
> +
> +     virtual unsigned int arity() { return 1; }
> +
> +     virtual bool needCache() { return true; }
> +
> +     virtual int infereSigOrder(const std::vector<int>& args) { return 0; }
> +
> +     virtual Tree computeSigOutput(const std::vector<Tree>& args)
> +     {
> +             Tree sig = simplify(args[0]);
> +             int ret = -1;
> +
> +             switch (fOp) {
> +             case 0:
> +                     ret = sig->serial();
> +                     break;
> +             case 1:
> +                     ret = getSigOrder(sig);
> +                     break;
> +             default:
> +                     faustassert(false);
> +             }
> +
> +             return tree(ret);
> +     }
> +
> +     virtual ::Type infereSigType(ConstTypes args)
> +     {
> +             faustassert(false); return 0;
> +     }
> +
> +     virtual ValueInst* generateCode(CodeContainer* container, Values& args, 
> ::Type result, ConstTypes types)
> +     {
> +             faustassert(false); return 0;
> +     }
> +
> +     virtual std::string generateCode(Klass* klass, const 
> std::vector<std::string>& args, ConstTypes types)
> +     {
> +             faustassert(false); return 0;
> +     }
> +
> +     virtual std::string generateLateq(Lateq* lateq, const 
> std::vector<std::string>& args, ConstTypes types)
> +     {
> +             return "TODO";
> +     }
> +};
> +
> +static Tree add_meta_def(Tree defs, int op, const char *d_n)
> +{
> +     Tree id = boxIdent(d_n);
> +     std::string x_n = std::string("meta_") + d_n;
> +     MetaPrim *meta = new MetaPrim(op, x_n.c_str());
> +     return cons(cons(id, meta->box()), defs);
> +}
> +
> +static Tree mkMetaEnv()
> +{
> +     Tree defs = gGlobal->nil;
> +
> +     defs = add_meta_def(defs, 0, "serial");
> +     defs = add_meta_def(defs, 1, "order");
> +
> +     return boxWithLocalDef(boxEnvironment(), defs);
> +}
> diff --git a/compiler/global.cpp b/compiler/global.cpp
> index 29af5eb9d..6636eac92 100644
> --- a/compiler/global.cpp
> +++ b/compiler/global.cpp
> @@ -48,6 +48,7 @@
> #include "sourcereader.hh"
> #include "sqrtprim.hh"
> #include "tanprim.hh"
> +#include "metaprim.hh"
> #include "tree.hh"
> #include "occur.hh"
> #include "enrobage.hh"
> @@ -592,6 +593,8 @@ void global::init()
>     // Predefined nil tree
>     nil = tree(NIL);
> 
> +    gMetaEnv = mkMetaEnv();
> +
>     PROCESS = symbol("process");
> 
>     BOXTYPEPROP      = tree(symbol("boxTypeProp"));
> diff --git a/compiler/global.hh b/compiler/global.hh
> index e8ced28c8..dbb001e7c 100644
> --- a/compiler/global.hh
> +++ b/compiler/global.hh
> @@ -322,6 +322,8 @@ struct global {
>     xtended* gAtan2Prim;
>     xtended* gAsinPrim;
> 
> +    Tree gMetaEnv;
> +
>     // Signals
>     Sym BOXIDENT;
>     Sym BOXCUT;
> diff --git a/compiler/parser/faustlexer.l b/compiler/parser/faustlexer.l
> index c92210cb5..c9342848f 100644
> --- a/compiler/parser/faustlexer.l
> +++ b/compiler/parser/faustlexer.l
> @@ -198,6 +198,8 @@ NSID     {ID}("::"{ID})*
> "sum"         return ISUM;
> "prod"        return IPROD;
> 
> +"meta"        return META;
> +
> "inputs"      return INPUTS;
> "outputs"     return OUTPUTS;
> 
> diff --git a/compiler/parser/faustparser.y b/compiler/parser/faustparser.y
> index 0f29d3403..5c9d49379 100644
> --- a/compiler/parser/faustparser.y
> +++ b/compiler/parser/faustparser.y
> @@ -217,6 +217,8 @@ inline Tree unquote(char* str)
> %token ISUM
> %token IPROD
> 
> +%token META
> +
> %token INPUTS
> %token OUTPUTS
> 
> @@ -587,6 +589,7 @@ primitive       : INT                           { $$ = 
> boxInt(str2int(FAUSTtext)
>                 | ffunction                     { $$ = boxFFun($1); }
>                 | fconst                        { $$ = $1; }
>                 | fvariable                     { $$ = $1; }
> +                | META                          { $$ = gGlobal->gMetaEnv; }
>                 | COMPONENT LPAR uqstring RPAR  { $$ = boxComponent($3); }
>                 | LIBRARY LPAR uqstring RPAR    { $$ = boxLibrary($3); }
>                 | ENVIRONMENT LBRAQ stmtlist RBRAQ { $$ = 
> boxWithLocalDef(boxEnvironment(),formatDefinitions($3)); }
> -- 
> 2.39.2
> 
> 



_______________________________________________
Faudiostream-devel mailing list
Faudiostream-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/faudiostream-devel

Reply via email to