static SymPtr Lhs(void) { char *name=NULL; SymPtr sym,clas=NULL; sym = LookupIdent(&name); if( sym==COMPILE_ERROR ) { return NULL; } NextToken(); /* if a field has the same name as a global, it will override */ if( in_class && SymGetScope()==2 && sym!=NULL ) { if( sym->kind==GLOBAL_KIND ) { sym=NULL; } } if( sym==NULL ) { sym = SymAdd(name); if( Token==tCONST ) { sym->flags |= SYM_CONSTANT; } if( SymGetScope()==1 ) { sym->kind = GLOBAL_KIND; sym->num = global_num++; } else { /* MCC */ if(in_class && !in_method) { sym->kind = FIELD_KIND; sym->flags |= cur_scope; sym->clas = base_class; } else { sym->kind = LOCAL_KIND; sym->flags = 0; sym->clas = NULL; } sym->num = local_num++; } return sym; } /* check for field access */ if( Token==tPERIOD ) { clas = sym; sym = FieldReference(clas); if( sym==NULL ) { return NULL; } } /* check for function call */ if( is_func_kind(sym) ) { FunctionCall(sym,clas); vm_gen0(op_pop); return NULL; } /* check for array access */ if( Token==tLBRACK ) { switch(sym->kind) { case GLOBAL_KIND: vm_genI(op_getglobal,sym->num); break; case LOCAL_KIND: vm_genI(op_getlocal,sym->num); break; case CONSTANT_KIND: switch(sym->object.type) { case INT_TYPE: vm_genI(op_pushint,sym->object.u.ival); break; case REAL_TYPE: vm_genR(op_pushreal,sym->object.u.rval); break; case STRING_TYPE: vm_genS(op_pushstring,sym->object.u.pval); break; default: /* TODO: error */ break; } break; case FIELD_KIND: CheckClassMember(sym); vm_genI(op_getfield,sym->num); break; default: compileError("invalid assignment"); break; } if( Token==tLBRACK ) /* array */ { SkipToken(tLBRACK); Expr(); SkipToken(tRBRACK); while( Token==tLBRACK ) { /* handle multi-dimension arrays */ vm_gen0(op_getarray); SkipToken(tLBRACK); Expr(); SkipToken(tRBRACK); } SkipToken(tEQUALS); Expr(); vm_gen0(op_setarray); return NULL; } } return sym; }
Expr cast_to_expr(Var v) { return Expr(v); }
Expr cast_to_expr(RDom r) { return Expr(r); }
LFSCProof* LFSCProof::Make_CNF( const Expr& form, const Expr& reason, int pos ) { Expr ec = cascade_expr( form ); #ifdef PRINT_MAJOR_METHODS cout << ";[M] CNF " << reason << " " << pos << std::endl; #endif int m = queryM( ec ); if( m>0 ) { ostringstream os1; ostringstream os2; RefPtr< LFSCProof > p; if( reason==d_or_final_s ) { #if 0 //this is the version that cascades //make the proof for the or p = LFSCPfVar::Make( "@v", abs(m) ); //clausify the or statement p = LFSCClausify::Make( ec, p.get(), true ); //return return LFSCAssume::Make( m, p.get(), true ); #else //this is the version that does not expand the last ostringstream oss1, oss2; p = LFSCPfVar::Make( "@v", abs(m) ); for( int a=(form.arity()-2); a>=0; a-- ){ int m1 = queryM( form[a] ); oss1 << "(or_elim_1 _ _ "; oss1 << ( m1<0 ? "(not_not_intro _ " : "" ); oss1 << "@v" << abs( m1 ); oss1 << ( m1<0 ? ") " : " " ); oss2 << ")"; } p = LFSCProofGeneric::Make( oss1.str(), p.get(), oss2.str() ); //p = LFSCClausify::Make( form[form.arity()-1], p.get() ); p = LFSCClausify::Make( queryM( form[form.arity()-1] ), p.get() ); for( int a=0; a<(form.arity()-1); a++ ){ p = LFSCAssume::Make( queryM( form[a] ), p.get(), false ); } return LFSCAssume::Make( m, p.get() ); #endif } else if( reason==d_and_final_s ) { #if 1 //this is the version that does not expand the last p = LFSCPfVar::Make( "@v", abs(m) ); os1 << "(contra _ "; for( int a=0; a<form.arity(); a++ ){ if( a<(form.arity()-1)) os1 << "(and_intro _ _ "; os1 << "@v" << abs( queryM( form[a] ) ); if( a<(form.arity()-1)){ os1 << " "; os2 << ")"; } } os2 << " @v" << abs(m) << ")"; os1 << os2.str(); p = LFSCProofGeneric::MakeStr( os1.str().c_str() ); for( int a=0; a<form.arity(); a++ ){ p = LFSCAssume::Make( queryM( form[a] ), p.get() ); } return LFSCAssume::Make( m, p.get(), false ); #else //this is the version that cascades std::vector< Expr > assumes; Expr ce = cascade_expr( form ); Expr curr = ce; os1 << "(contra _ "; while( curr.getKind()==AND ){ os1 << "(and_intro _ _ "; os1 << "@v" << abs( queryM( curr[0] ) ) << " "; os2 << ")"; assumes.push_back( curr[0] ); curr = curr[1]; } os2 << " @v" << abs(m) << ")"; p = LFSCProofGeneric::Make( os1.str(), p.get(), os2.str() ); for( int a=0; a<(int)assumes.size(); a++ ){ p = LFSCAssume::Make( queryM( assumes[a] ), p.get() ); } return LFSCAssume::Make( m, p.get(), false ); #endif } else if( reason==d_imp_s ) { int m1 = queryM( ec[0] ); int m2 = queryM( ec[1] ); switch( pos ) { case 0: break; case 1: break; case 2: { //make a proof of the RHS ostringstream os; os << "(impl_elim _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); //clausify the RHS p = LFSCClausify::Make( form[1], p.get() ); //cascadeOr? p = LFSCAssume::Make( queryM( ec[0] ), p.get() ); return LFSCAssume::Make( queryM( ec ), p.get() ); } break; } } else if( reason==d_ite_s ) { int m1 = queryM( ec[0] ); int m2 = queryM( ec[1] ); switch( pos ) { case 1: { ostringstream os; os << "(ite_elim_2" << (m1<0 ? "n" : "" ); os << " _ _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); p = LFSCClausify::Make( form[2], p.get() ); p = LFSCAssume::Make( queryM( ec[0] ), p.get(), false ); return LFSCAssume::Make( queryM( ec ), p.get() ); } break; case 2: { ostringstream os; os << "(not_ite_elim_2 _ _ _ @v" << (m1<0 ? "n" : "" ); os << abs( m1 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); Expr e = Expr( NOT, form[2] ); p = LFSCClausify::Make( e, p.get() ); p = LFSCAssume::Make( queryM( ec[0] ), p.get(), false ); return LFSCAssume::Make( queryM( ec ), p.get(), false ); } break; case 3: { ostringstream os; os << "(not_ite_elim_1 _ _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); Expr e = Expr( NOT, form[1] ); p = LFSCClausify::Make( e, p.get() ); p = LFSCAssume::Make( queryM( ec[0] ), p.get() ); return LFSCAssume::Make( queryM( ec ), p.get(), false ); } break; case 4: { ostringstream os; os << "(ite_elim_1";// << (m1<0 ? "n" : "" ); os << " _ _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); p = LFSCClausify::Make( form[1], p.get() ); p = LFSCAssume::Make( queryM( ec[0] ), p.get() ); return LFSCAssume::Make( queryM( ec ), p.get() ); } break; case 5: { ostringstream os; os << "(not_ite_elim_3 _ _ _ @v" << abs( m2 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); Expr e = Expr( NOT, form[2] ); p = LFSCClausify::Make( e, p.get() ); p = LFSCAssume::Make( queryM( ec[1] ), p.get() ); return LFSCAssume::Make( queryM( ec ), p.get(), false ); } break; case 6: { ostringstream os; os << "(ite_elim_3";// << (m1<0 ? "n" : "" ); os << " _ _ _ @v" << abs( m2 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); p = LFSCClausify::Make( form[2], p.get() ); p = LFSCAssume::Make( queryM( ec[1] ), p.get(), false ); return LFSCAssume::Make( queryM( ec ), p.get() ); } break; } } else if( reason==d_iff_s ) { int m1 = queryM( ec[0] ); int m2 = queryM( ec[1] ); switch( pos ) { case 0: { ostringstream os; os << "(not_iff_elim_1 _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); p = LFSCClausify::Make( form[1], p.get() ); p = LFSCAssume::Make( queryM( ec[0] ), p.get(), false ); return LFSCAssume::Make( queryM( ec ), p.get(), false ); } break; case 1: { ostringstream os; os << "(not_iff_elim_2 _ _ @v" << abs( m1 ) << " @v" << abs( m ) << ")"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); p = LFSCClausify::Make( Expr( NOT, form[1] ), p.get() ); p = LFSCAssume::Make( queryM( ec[0] ), p.get() ); return LFSCAssume::Make( queryM( ec ), p.get(), false ); } break; case 2: { ostringstream os; os << "(impl_elim _ _ @v" << abs( m1 ) << "(iff_elim_1 _ _ @v" << abs( m ) << "))"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); //clausify the RHS p = LFSCClausify::Make( form[1], p.get() ); //cascadeOr? p = LFSCAssume::Make( queryM( ec[0] ), p.get() ); return LFSCAssume::Make( queryM( ec ), p.get() ); } break; case 3: { ostringstream os; os << "(impl_elim _ _ @v" << abs( m2 ) << "(iff_elim_2 _ _ @v" << abs( m ) << "))"; p = LFSCProofGeneric::MakeStr( os.str().c_str() ); //clausify the RHS p = LFSCClausify::Make( form[0], p.get() ); //cascadeOr? p = LFSCAssume::Make( queryM( ec[1] ), p.get() ); return LFSCAssume::Make( m, p.get() ); } break; } } else if( reason==d_or_mid_s ) { ostringstream os1, os2; if( form[pos].isNot() ) os1 << "(not_not_elim _ "; os1 << "(or_elim" << ( (pos==form.arity()) ? "_end" : "" ); os1 << " _ _ " << pos << " "; os2 << ")"; if( form[pos].isNot() ) os2 << ")"; p = LFSCPfVar::Make( "@v", abs( m ) ); p = LFSCProofGeneric::Make( os1.str(), p.get(), os2.str() ); Expr ea = Expr( NOT, form[pos] ); p = LFSCClausify::Make( ea, p.get() ); return LFSCAssume::Make( m, p.get(), false ); } else if( reason==d_and_mid_s ) { //make a proof of the pos-th statement p = LFSCPfVar::Make( "@v", abs( m ) ); p = LFSCProof::Make_and_elim( form, p.get(), pos, form[pos] ); p = LFSCClausify::Make( form[pos], p.get() ); return LFSCAssume::Make( m, p.get() ); } } ostringstream ose; ose << "CNF, " << reason << " unknown position = " << pos << std::endl; print_error( ose.str().c_str(), cout ); return NULL; }
Expr cast_to_expr(float a) { return Expr(a); }
Int(Expr const & expr = Expr()) : base_type(expr) {}
virtual Expr getParams() const { return Expr();}
ExprCore::ExprCore(ExprImp::Operator op, uint32_t lhs, int32_t rhs) : m_op(op), m_lhs(Expr(lhs).imp()), m_rhs(Expr(rhs).imp()) { }
Func opticalFlow_estimate (Func stBasis, uint8_t nAngle, uint8_t * orders, \ Expr filterthreshold, Expr divisionthreshold,\ Expr divisionthreshold2) { // This function estimates components of optical flow fields as well as its speed and direction of movement // basis: from spatio-temporal filters, angle: number of considered angles // orders: x (spatial index), y ( spatial index ), t (time index) and s ? // ColorMgather function in MATLAB // Pipeline: // 1. Compute oriented filter basis at a particular angle // { // basis -> X // -> Y // -> T // -> Xrg // -> Yrg // -> Trg // -> Xk // -> Yk // -> Tk // } // Expr M0,M1,M2,M3,temp_a,temp_b,Tkd; // Expr M0 = cast<float>(0.0f); // Expr M1 = cast<float>(0.0f); // Expr M2 = cast<float>(0.0f); // Expr M3 = cast<float>(0.0f); // Expr temp_a = cast<float>(0.0f); // Expr temp_b = cast<float>(0.0f); // Expr Tkd = cast<float>(0.0f); // Expr D0 = cast<float>(0.0f); // Expr D1 = cast<float>(0.0f); // Expr D2 = cast<float>(0.0f); // Expr D3 = cast<float>(0.0f); // Expr N0 = cast<float>(0.0f); // Expr N1 = cast<float>(0.0f); // Expr N2 = cast<float>(0.0f); // Expr N3 = cast<float>(0.0f); // Expr A0 = cast<float>(0.0f); // Expr A1 = cast<float>(0.0f); // Expr A2 = cast<float>(0.0f); // Expr A3 = cast<float>(0.0f); Func Tkd; Func fA0; fA0(x,y,t) = Expr(0.0f); Func fA1; fA1(x,y,t) = Expr(0.0f); Func fA2; fA2(x,y,t) = Expr(0.0f); Func fA3; fA3(x,y,t) = Expr(0.0f); Func fD0; fD0(x,y,t) = Expr(0.0f); Func fD1; fD1(x,y,t) = Expr(0.0f); Func fD2; fD2(x,y,t) = Expr(0.0f); Func fD3; fD3(x,y,t) = Expr(0.0f); Func fN0; fN0(x,y,t) = Expr(0.0f); Func fN1; fN1(x,y,t) = Expr(0.0f); Func fN2; fN2(x,y,t) = Expr(0.0f); Func fN3; fN3(x,y,t) = Expr(0.0f); // std::vector<Expr> basisAtAngleExpr(5,cast<float>(0.0f)); // Tuple basisAtAngle = Tuple(basisAtAngleExpr); Func basisAtAngle[nAngle/2]; // Compute spatial-temporal basis for (int iA = 0; iA <= nAngle / 2 - 1; iA++) { float aAngle = 2*iA*M_PI/nAngle; basisAtAngle[iA] = ColorMgather(stBasis, aAngle, orders, filterthreshold, divisionthreshold, divisionthreshold2); basisAtAngle[iA].compute_root(); Expr M0,M1,M2,M3; M0 = basisAtAngle[iA](x,y,t)[0]; M1 = basisAtAngle[iA](x,y,t)[1]; M2 = basisAtAngle[iA](x,y,t)[2]; M3 = basisAtAngle[iA](x,y,t)[3]; fD0(x,y,t) += M0 * M0; fD1(x,y,t) += M0 * M2; fD2(x,y,t) += M2 * M0; fD3(x,y,t) += M2 * M2; fN0(x,y,t) += M1 * M0; fN1(x,y,t) += M1 * M2; fN2(x,y,t) += M3 * M0; fN3(x,y,t) += M3 * M2; // temp_a = abs(M0) * M1; // temp_b = abs(M2) * M3; Expr cosaAngle((float) cos(aAngle)); Expr sinaAngle((float) sin(aAngle)); // A0 += temp_a * cosaAngle; // A1 += temp_b * sinaAngle; // A2 += temp_a * sinaAngle; // A3 += temp_b * cosaAngle; // fA0(x,y,c,t) += abs(M0) * M1 * cosaAngle; fA0(x,y,t) += abs(M0) * M1 * cosaAngle; fA1(x,y,t) += abs(M2) * M3 * sinaAngle; fA2(x,y,t) += abs(M0) * M1 * sinaAngle; fA3(x,y,t) += abs(M2) * M3 * cosaAngle; } Tkd(x,y,t) = basisAtAngle[nAngle/2-1](x,y,t)[4]; // return basisAtAngle[0]; // 4 debug // // Schedule basis // for (int iA = 0; iA <= nAngle / 2 - 1; iA++) { // fD0.update(iA); // fD1.update(iA); // fD2.update(iA); // fD3.update(iA); // fN0.update(iA); // fN1.update(iA); // fN2.update(iA); // fN3.update(iA); // fA0.update(iA); // fA1.update(iA); // fA2.update(iA); // fA3.update(iA); // } fD0.compute_root(); fD1.compute_root(); fD2.compute_root(); fD3.compute_root(); fN0.compute_root(); fN1.compute_root(); fN2.compute_root(); fN3.compute_root(); fA0.compute_root(); fA1.compute_root(); fA2.compute_root(); fA3.compute_root(); Tkd.compute_root(); Func top_func; Func bottom_func; Expr speed0; Expr speed1; // Polar fig ? top_func(x,y,t) = fN0(x,y,t) * fN3(x,y,t) - fN1(x,y,t) * fN2(x,y,t); top_func.compute_root(); bottom_func(x,y,t) = fD0(x,y,t) * fD3(x,y,t) - fD1(x,y,t) * fD2(x,y,t); bottom_func.compute_root(); speed0 = sqrt(sqrt(abs(Mdefdiv(top_func(x,y,t) , bottom_func(x,y,t), Expr(0.0f))))); speed1 = Manglecalc(fA0(x,y,t) , fA1(x,y,t) , fA2(x,y,t) , fA3(x,y,t)); // Display the results ? speed0 = select(abs(Tkd(x,y,t)) > filterthreshold,speed0,Expr(0.0f)); speed1 = select(abs(Tkd(x,y,t)) > filterthreshold,speed1,Expr(0.0f)); Func speed("speed"); speed(x,y,t) = Tuple(speed0,speed1); return speed; //Bimg = [T0n speed0 speed1] ? // Func img = outputvelocity(T0n,Func(speed0),Func(speed1),16, speedthreshold, filterthreshold); }
expression( Expr const& xpr = Expr() ) : parent(xpr) {}
ExprCore::ExprCore(ExprImp::Operator op, const Expr &lhs, int32_t rhs) : m_op(op), m_lhs(lhs.imp()), m_rhs(Expr(rhs).imp()) { }
Node* Parser::Expr() { Node* pNode = Term(); EToken token = _scanner.Token(); if (token == tPlus || token == tMinus) { MultiNode* pMultiNode = new SumNode(pNode); do { _scanner.Accept(); Node* pRight = Term(); pMultiNode->AddChild(pRight, (token == tPlus)); token = _scanner.Token(); }while (token == tPlus || token == tMinus); pNode = pMultiNode; } else if (token == tAssign) { _scanner.Accept(); Node* pRight = Expr(); if(pNode->IsLvalue() ) { pNode = new AssignNode(pNode, pRight); } else { _status = stError; delete pNode; pNode = Expr(); } //return pNode; } return pNode; /* if (token == tPlus) { _scanner.Accept(); Node* pRight = Expr(); pNode = new AddNode (pNode, pRight); } else if (token == tMinus) { _scanner.Accept(); Node* pRight = Expr(); pNode = new SubNode (pNode, pRight); } else if(token == tAssign) { _scanner.Accept(); Node* pRight = Expr(); if (pNode -> IsLvalue() ) { pNode = new AssignNode (pNode, pRight); } else { _status = stError; delete pNode; pNode = Expr(); } } return pNode; */ }
Node* Parser::Factor() { Node* pNode; EToken token = _scanner.Token(); if(token == tLParen) { _scanner.Accept(); //接受( pNode = Expr(); if(_scanner.Token() != tRParen ) _status = stError; else _scanner.Accept(); } else if (token == tNumber) { pNode = new NumNode (_scanner.Number() ); _scanner.Accept(); } else if (token == tIdent) { char strSymbol[Scanner::maxSymLen + 1]; int lenSym = _scanner.GetSymbolName (strSymbol, Scanner::maxSymLen + 1 ); int id = _symTab.Find(strSymbol); _scanner.Accept(); if (_scanner.Token() == tLParen ) //函数调用 { _scanner.Accept(); //接受'(' pNode = Expr (); if (_scanner.Token() == tRParen ) _scanner.Accept(); //接受')' else _status = stError; if (id != SymbolTable::idNotFound && id < _funTab.Size() ) { pNode = new FunNode (_funTab.GetFun(id), pNode); } else { std::cout << "未知函数:\"" << strSymbol <<"\"\n"; } } else { if (id == SymbolTable::idNotFound) id = _symTab.ForceAdd(strSymbol); if (id == SymbolTable::idNotFound) { std::cerr << "Error: Too many variable!!!" << std::endl; _status = stError; pNode = 0; } if (id != SymbolTable::idNotFound) pNode = new VarNode (id,_store); } /* if (id == idNotFound) { std::cerr << "Error: Too many variable!!!" << std::endl; _status = stError; pNode = 0; } //pNode = new VarNode (id,_store); if (id != idNotFound) pNode = new VarNode (id,_store); */ } else if(token == tMinus) { _scanner.Accept(); pNode = new UMinusNode (Factor()); } else { _scanner.Accept(); _status = stError; pNode = 0; } return pNode; }
static Int32 Rhs(void) { char *name=NULL; SymPtr sym,clas=NULL; sym = LookupIdent(&name); if( sym == COMPILE_ERROR ) { return INT_TYPE; } NextToken(); if( sym==NULL ) { compileError("invalid identifier '%s'",name); return INT_TYPE; } /* check for field access */ if( Token==tPERIOD ) { if( in_class && !in_method ) { compileError("cannot initialize fields with objects"); return INT_TYPE; } clas = sym; sym = FieldReference(clas); if( sym==NULL ) { return INT_TYPE; } if( xstrcmp(sym->name,NEW)==0 ) { new_class = clas; vm_genI(op_newclass,new_class->nlocs); return CLASS_TYPE; } } switch(sym->kind) { case NIL_KIND: compileError("invalid type"); break; case GLOBAL_KIND: vm_genI(op_getglobal,sym->num); break; case LOCAL_KIND: vm_genI(op_getlocal,sym->num); break; case CONSTANT_KIND: switch(sym->object.type) { case INT_TYPE: vm_genI(op_pushint,sym->object.u.ival); break; case REAL_TYPE: vm_genR(op_pushreal,sym->object.u.rval); break; case STRING_TYPE: vm_genS(op_pushstring,sym->object.u.pval); break; default: /* TODO: error */ break; } break; case FUNCTION_KIND: case CFUNCTION_KIND: FunctionCall(sym,clas); break; case CLASS_KIND: compileError("invalid type"); break; case FIELD_KIND: CheckClassMember(sym); vm_genI(op_getfield,sym->num); break; } /* check for array access */ if( Token==tLBRACK ) { /* allow multi-dimensional arrays */ while( Token==tLBRACK ) { /* valid array is checked at runtime */ SkipToken(tLBRACK); Expr(); SkipToken(tRBRACK); vm_gen0(op_getarray); } } return sym->object.type; }
// Needs a constructor msm_terminal(Expr const &e = Expr()) : base_type(e) {}
Func ColorMgather(Func stBasis, float angle, uint8_t * orders, Expr filterthreshold, Expr divisionthreshold, Expr divisionthreshold2) { uint8_t x_order = orders[0]; uint8_t y_order = orders[1]; uint8_t t_order = orders[2]; uint8_t c_order = orders[3]; Func X("X"),Y("Y"),T("T"),Xrg("Xrg"),Yrg("Yrg"),Trg("Trg"); uint8_t max_order = x_order; // std::vector<Expr>Xk_expr (max_order,cast<float>(0.0f)); // std::vector<Expr>Yk_expr (max_order,cast<float>(0.0f)); // std::vector<Expr>Tk_expr (max_order,cast<float>(0.0f)); uint8_t Xk_uI[max_order]; uint8_t Yk_uI[max_order]; uint8_t Tk_uI[max_order]; Func Xk[max_order]; Func Yk[max_order]; Func Tk[max_order]; // Expr Xk[max_order],Yk[max_order],Tk[max_order]; for (int iO=0; iO < x_order; iO++) { Xk[iO](x,y,t) = Expr(0.0f); Yk[iO](x,y,t) = Expr(0.0f); Tk[iO](x,y,t) = Expr(0.0f); Xk_uI[iO] = 0; Yk_uI[iO] = 0; Tk_uI[iO] = 0; } int k = 0; for (int iXo = 0; iXo < x_order; iXo++) // x_order for (int iYo = 0; iYo < y_order; iYo++) // y_oder for (int iTo = 0; iTo < t_order; iTo++) // t_order for (int iCo = 0; iCo < c_order; iCo ++ ) // c_order: index of color channel { if ((iYo+iTo+iCo == 0 || iYo+iTo+iCo == 1) && ((iXo+iYo+iTo+iCo+1) < (x_order + 1))) { X = ColorMgetfilter(stBasis, angle, iXo+1, iYo, iTo, iCo); Y = ColorMgetfilter(stBasis, angle, iXo, iYo+1, iTo, iCo); T = ColorMgetfilter(stBasis, angle, iXo, iYo, iTo+1, iCo); Xrg = ColorMgetfilter(stBasis, angle, iXo+1, iYo, iTo, iCo+1); Yrg = ColorMgetfilter(stBasis, angle, iXo, iYo+1, iTo, iCo+1); Trg = ColorMgetfilter(stBasis, angle, iXo, iYo, iTo+1, iCo+1); k = iXo + iYo + iTo + iCo; Xk[k](x,y,t) += X(x,y,t) + Xrg(x,y,t); Yk[k](x,y,t) += Y(x,y,t) + Yrg(x,y,t); Tk[k](x,y,t) += T(x,y,t) + Trg(x,y,t); Xk[k].update(Xk_uI[k]); Xk_uI[k]++; Yk[k].update(Yk_uI[k]); Yk_uI[k]++; Tk[k].update(Tk_uI[k]); Tk_uI[k]++; } } // Scheduling for (int iO = 0; iO <= k; iO++) { Xk[iO].compute_root(); Yk[iO].compute_root(); Tk[iO].compute_root(); } std::vector<Expr> st_expr(6,cast<float>(0.0f)); for (int iK=0; iK <= k; iK++) { st_expr[0] += Xk[iK](x,y,t)*Tk[iK](x,y,t); st_expr[1] += Tk[iK](x,y,t)*Tk[iK](x,y,t); st_expr[2] += Xk[iK](x,y,t)*Xk[iK](x,y,t); st_expr[3] += Yk[iK](x,y,t)*Tk[iK](x,y,t); st_expr[4] += Yk[iK](x,y,t)*Yk[iK](x,y,t); st_expr[5] += Xk[iK](x,y,t)*Yk[iK](x,y,t); } Func st("st"); st(x,y,t) = Tuple(st_expr); st.compute_root(); Expr x_clamped = clamp(x,0,width-1); Expr y_clamped = clamp(y,0,height-1); Func st_clamped("st_clamped"); st_clamped(x,y,t) = st(x_clamped,y_clamped,t); // float win = 7.0; // Image<float> meanfilter(7,7,"meanfilter_data"); // meanfilter(x,y) = Expr(1.0f/(win*win)); // RDom rMF(meanfilter); uint8_t win = 7; RDom rMF(0,win,0,win); Func st_filtered[6]; for (uint8_t iPc=0; iPc<6; iPc++) { // iPc: index of product component // Apply average filter st_filtered[iPc](x,y,t) = sum(rMF,st_clamped(x + rMF.x,y + rMF.y,t)[iPc]/Expr(float(win*win)),"mean_filter"); st_filtered[iPc].compute_root(); } // Tuple st_tuple = Tuple(st_expr); // 4 debug // Func tmpOut("tmpOut"); tmpOut(x,y,t) = Tuple(st_filtered[0](x,y,t),st_filtered[1](x,y,t),st_filtered[2](x,y,t),st_filtered[3](x,y,t),st_filtered[4](x,y,t),st_filtered[5](x,y,t)); // return tmpOut; Tuple pbx = Tuple(st_filtered[2](x,y,t),st_filtered[5](x,y,t),st_filtered[0](x,y,t)); Tuple pby = Tuple(st_filtered[5](x,y,t),st_filtered[4](x,y,t),st_filtered[3](x,y,t)); Tuple pbt = Tuple(st_filtered[0](x,y,t),st_filtered[3](x,y,t),st_filtered[1](x,y,t)); Func pbxy("pbxy"); pbxy = cross(pby,pbx); pbxy.compute_root(); Func pbxt("pbxt"); pbxt = cross(pbx,pbt); pbxt.compute_root(); Func pbyt("pbyt"); pbyt = cross(pby,pbt); pbyt.compute_root(); Func pbxyd("pbxyd"); pbxyd = dot(pby,pbx); pbxyd.compute_root(); Func pbxtd("pbxtd"); pbxtd = dot(pbx,pbt); pbxtd.compute_root(); Func pbytd("pbytd"); pbytd = dot(pby,pbt); pbytd.compute_root(); // 4 debug // Func tmpOut("tmpOut"); tmpOut(x,y,t) = Tuple(pbxy(x,y,t)[0],pbxt(x,y,t)[0],pbyt(x,y,t)[0],pbxyd(x,y,t),pbxtd(x,y,t),pbytd(x,y,t)); // return tmpOut; Func yt_xy("yt_xy"); yt_xy = dot(pbyt(x,y,t),pbxy(x,y,t)); yt_xy.compute_root(); Func xt_yt("xt_yt"); xt_yt = dot(pbxt(x,y,t),pbyt(x,y,t)); xt_yt.compute_root(); Func xt_xy("xt_xy"); xt_xy = dot(pbxt(x,y,t),pbxy(x,y,t)); xt_xy.compute_root(); Func yt_yt("yt_yt"); yt_yt = dot(pbyt(x,y,t),pbyt(x,y,t)); yt_yt.compute_root(); Func xt_xt("xt_xt"); xt_xt = dot(pbxt(x,y,t),pbxt(x,y,t)); xt_xt.compute_root(); Func xy_xy("xy_xy"); xy_xy = dot(pbxy(x,y,t),pbxy(x,y,t)); xy_xy.compute_root(); Tuple Tk_tuple = Tuple(Tk[0](x,y,t),Tk[1](x,y,t),Tk[2](x,y,t), Tk[3](x,y,t),Tk[4](x,y,t)); Func Tkd("Tkd"); Tkd = dot(Tk_tuple,Tk_tuple); Tkd.compute_root(); // Expr Dimen = pbxyd/xy_xy; Expr kill(1.0f); Func Oxy; Oxy(x,y,t) = Mdefdiv(st_filtered[5](x,y,t) - Mdefdivang(yt_xy(x,y,t),yt_yt(x,y,t),pbxyd(x,y,t),divisionthreshold2)*st_filtered[3](x,y,t)*kill,st_filtered[4](x,y,t),divisionthreshold); Oxy.compute_root(); Func Oyx; Oyx(x,y,t) = Mdefdiv(st_filtered[5](x,y,t) + Mdefdivang(xt_xy(x,y,t),xt_xt(x,y,t),pbxyd(x,y,t),divisionthreshold2)*st_filtered[0](x,y,t)*kill,st_filtered[2](x,y,t),divisionthreshold); Oyx.compute_root(); Func C0; C0(x,y,t) = st_filtered[3](x,y,t) * Mdefdivang(Expr(-1.0f)*xt_yt(x,y,t),yt_yt(x,y,t),pbxyd(x,y,t),divisionthreshold2)*kill; C0.compute_root(); Func M0; M0(x,y,t) = Mdefdiv(st_filtered[0](x,y,t) + C0(x,y,t), st_filtered[1](x,y,t)*pow(Mdefdivang(xt_yt(x,y,t),yt_yt(x,y,t),pbxyd(x,y,t),divisionthreshold2),Expr(2.0f)),divisionthreshold); M0.compute_root(); Func C1; C1(x,y,t) = st_filtered[5](x,y,t) * Mdefdivang(Expr(-1.0f)*xt_xy(x,y,t),xy_xy(x,y,t),pbxyd(x,y,t),divisionthreshold2)*kill; C1.compute_root(); Func P1; P1(x,y,t) = pow(Mdefdivang(xt_yt(x,y,t),xt_xt(x,y,t),pbxyd(x,y,t),divisionthreshold2),Expr(2.0f))*kill + 1.0f; P1.compute_root(); // 4 debug // Func tmpOut("tmpOut"); tmpOut(x,y,t) = Tuple(Oxy(x,y,t),Oyx(x,y,t),C0(x,y,t),M0(x,y,t),C1(x,y,t),P1(x,y,t)); // return tmpOut; Func Q1; Q1(x,y,t) = st_filtered[2](x,y,t) * (pow(Oyx(x,y,t),Expr(2.0f))+Expr(1.0f)); Q1.compute_root(); Func M1; M1(x,y,t) = Mdefdiv(((st_filtered[0](x,y,t)-C1(x,y,t))*P1(x,y,t)),Q1(x,y,t),divisionthreshold); M1.compute_root(); Func C2; C2(x,y,t) = st_filtered[0](x,y,t) * Mdefdivang(Expr(-1.0f)*xt_yt(x,y,t),xt_xt(x,y,t),pbxyd(x,y,t),divisionthreshold2)*kill; C2.compute_root(); Func M2; M2(x,y,t) = Mdefdiv(st_filtered[3](x,y,t)+C2(x,y,t),st_filtered[1](x,y,t)*(pow(Mdefdivang(xt_yt(x,y,t),xt_xt(x,y,t),pbxyd(x,y,t),divisionthreshold2),Expr(2.0f))*kill+Expr(1.0f)),divisionthreshold); M2.compute_root(); Func C3; C3(x,y,t) = st_filtered[5](x,y,t) * Mdefdivang(yt_xy(x,y,t),xy_xy(x,y,t),pbxyd(x,y,t),divisionthreshold2)*kill; C3.compute_root(); Func P3; P3(x,y,t) = pow(Mdefdivang(xt_yt(x,y,t),yt_yt(x,y,t),pbxyd(x,y,t),divisionthreshold2),Expr(2.0f))*kill + Expr(1.0f); P3.compute_root(); Func Q3; Q3(x,y,t) = st_filtered[4](x,y,t) * (pow(Oxy(x,y,t),Expr(2.0f))+Expr(1.0f)); Q3.compute_root(); Func M3; M3(x,y,t) = Mdefdiv(((st_filtered[3](x,y,t)-C3(x,y,t))*P3(x,y,t)),Q3(x,y,t),divisionthreshold); M3.compute_root(); Func basisAtAngle; basisAtAngle(x,y,t) = Tuple(M0(x,y,t),M1(x,y,t),M2(x,y,t),M3(x,y,t),Tkd(x,y,t)); return basisAtAngle; // Func hsv2rgb(Func colorImage) { // Took this function // Var x, y, c, t; // Func output; // output(x,y,c,t) = cast <float> (0.0f); // Expr fR, fG, fB; // R,G & B values // Expr fH = (colorImage(x,y,0,t)); //H value [0-360) // Expr fS = (colorImage(x,y,1,t)); //S value // Expr fV = (colorImage(x,y,2,t)); //V value // //Conversion (I took the one on Wikipedia) // // https://fr.wikipedia.org/wiki/Teinte_Saturation_Valeur#Conversion_de_TSV_vers_RVB // Expr fHi = floor(fH / Expr(60.0f)); // Expr fF = fH / 60.0f - fHi; // Expr fL = fV * (1 - fS); // Expr fM = fV * (1 - fF * fS) ; // Expr fN = fV * (1 - (1 - fF) * fS); // fR = select((0 == fHi),fV, // (1 == fHi),fM, // (2 == fHi),fL, // (3 == fHi),fL, // (4 == fHi),fN, // (5 == fHi),fV, // 0.0f); // fG = select((0 == fHi),fN, // (1 == fHi),fV, // (2 == fHi),fV, // (3 == fHi),fM, // (4 == fHi),fL, // (5 == fHi),fL, // 0.0f); // fB = select((0 == fHi),fL, // (1 == fHi),fL, // (2 == fHi),fN, // (3 == fHi),fV, // (4 == fHi),fV, // (5 == fHi),fM, // 0.0f); // output(x,y,0,t) = fR; // output(x,y,1,t) = fG; // output(x,y,2,t) = fB; // return output; // } // Func angle2rgb (Func v) { // Var x, y, c, t; // Func ov, a; // ov(x,y,c,t) = cast <float> (0.0f); // Expr pi2(2*M_PI); // a(x,y,c,t) = v(x,y,c,t) / pi2; // ov(x,y,0,t) = a(x,y,c,t); // ov(x,y,1,t) = 1; // ov(x,y,2,t) = 1; // return ov; // } // Func outputvelocity(Func Blur, Func Speed, Func Angle, int border, Expr speedthreshold, Expr filterthreshold) { // extern Expr width; // extern Expr height; // Func Blur3, Speed3; // Blur3(x,y,c,t) = cast <float> (0.0f); // Speed3(x,y,c,t) = cast <float> (0.0f); // //Scale the grey level images // Blur(x,y,0,t) = (Blur(x,y,0,t) - minimum(Blur(x,y,0,t))) / (maximum(Blur(x,y,0,t)) - minimum(Blur(x,y,0,t))); // //Concatenation along the third dimension // Blur3(x,y,0,t) = Blur(x,y,0,t); // Blur3(x,y,1,t) = Blur(x,y,0,t); // Blur3(x,y,2,t) = Blur(x,y,0,t); // //Speed scaled to 1 // //Concatenation along the third dimension // Speed3(x,y,1,t) = Speed(x,y,0,t); // Speed3(x,y,2,t) = Speed(x,y,0,t); // //Use the log speed to visualise speed // Func LogSpeed; // LogSpeed(x,y,c,t) = fast_log(Speed3(x,y,c,t) + Expr(0.0000001f))/fast_log(Expr(10.0f)); // LogSpeed(x,y,c,t) = (LogSpeed(x,y,c,t) - minimum(LogSpeed(x,y,c,t))) / (maximum(LogSpeed(x,y,c,t)) - minimum(LogSpeed(x,y,c,t))); // //Make a colour image // // uint16_t rows = height; // // uint16_t cols = width; // // int depth = Angle.channels(); // //Do it the HSV way // Func colorImage; // colorImage(x,y,0,t) = Angle(x,y,0,t); // //Do hsv to rgb // Func colorImage1; // colorImage1 = hsv2rgb(colorImage); // // Assume the border equals to the size of spatial filter // //Make the border // // int bir = rows + 2 * border; // // int bic = cols + 2 * border; // Expr orows = height / Expr(2); // Expr ocols = width / Expr(2); // //Rotation matrix // int ph = 0; // Func mb, sb; // // if (rx < border - 1 || rx >= rows+border -1 || ry < border - 1 || ry >= cols+border - 1) { // Expr co1 = x - orows; // Expr co2 = - (y - ocols); // Expr cosPh(cos(ph)); // Expr sinPh(sin(ph)); // Expr rco1 = cosPh * co1 - sinPh * co2; //Using rotation matrix // Expr rco2 = sinPh * co1 + cosPh * co2; // // Expr justPi (M_PI); // mb(x,y,c,t) = // select (((x < (border - 1)) || // (x >= (height+border -1)) || // (y < (border - 1)) || // (y >= (width+border - 1))), // atan2(rco1,rco2) + Expr(M_PI),mb(x,y,c,t)); // sb(x,y,c,t) = // select (((x < (border - 1)) || // (x >= (height+border -1)) || // (y < (border - 1) ) || // (y >= (width+border - 1))), // 1, sb (x,y,c,t)); // Func cb; // cb = angle2rgb(mb); // //Get the old data // // Expr pi2(2*M_PI); // colorImage1(x,y,0,t)=colorImage(x,y,0,t) * Expr(2*M_PI); // colorImage1=angle2rgb(colorImage1); // colorImage1(x,y,c,t)=select(abs(Speed3(x,y,c,t))<speedthreshold,Expr(0.0f),colorImage1(x,y,c,t)); // Func colorImage2; // colorImage2(x,y,c,t) = colorImage1(x,y,c,t) * Speed(x,y,c,t); // //Put the data in the border // RDom bordx (border,rows + border); // RDom bordy (border,cols + border); // Func ang1, ang2; // ang1 (x,y,c,t) = cast <float> (0.0f); // ang2 (x,y,c,t) = cast <float> (0.0f); // cb(bordx, bordy,c,t) = colorImage1(x,y,c,t); // ang1 = cb; // cb(bordx, bordy,c,t) = colorImage2(x,y,c,t); // ang2 = cb; // sb(bordx, bordy,c,t) = Speed3(x,y,c,t); // Speed3 = sb; // sb(bordx, bordy,c,t) = Blur3(x,y,c,t); // Blur3 = sb; // // Func I; // // I (x,y,c,t) = Blur3(x,y,c,t) + Speed3(x,y - height,c,t) + ang1(x - width,y,c,t) + ang2(x - width,y - height,c,t); // //I = cat(2,cat(1,Blur,Speed),cat(1,ang1,ang2)); // return I; // } }
Expr Var::type_expr() const { return type and type->ptr ? type->ptr->expr() : Expr(); }
void Parser::Parse() { tree_ = Expr(); }
Expr implicit_expr_wrap(Base const &expr, mpl::false_, Expr *) { return Expr(expr); }
Expr lower_lerp(Expr zero_val, Expr one_val, Expr weight) { Expr result; internal_assert(zero_val.type() == one_val.type()); internal_assert(weight.type().is_uint() || weight.type().is_float()); Type result_type = zero_val.type(); Expr bias_value = make_zero(result_type); Type computation_type = result_type; if (zero_val.type().is_int()) { computation_type = UInt(zero_val.type().bits(), zero_val.type().lanes()); bias_value = result_type.min(); } // For signed integer types, just convert everything to unsigned // and then back at the end to ensure proper rounding, etc. // There is likely a better way to handle this. if (result_type != computation_type) { zero_val = Cast::make(computation_type, zero_val - bias_value); one_val = Cast::make(computation_type, one_val - bias_value); } if (result_type.is_bool()) { Expr half_weight; if (weight.type().is_float()) half_weight = 0.5f; else { half_weight = weight.type().max() / 2; } result = select(weight > half_weight, one_val, zero_val); } else { Expr typed_weight; Expr inverse_typed_weight; if (weight.type().is_float()) { typed_weight = weight; if (computation_type.is_uint()) { // TODO: Verify this reduces to efficient code or // figure out a better way to express a multiply // of unsigned 2^32-1 by a double promoted weight if (computation_type.bits() == 32) { typed_weight = Cast::make(computation_type, cast<double>(Expr(65535.0f)) * cast<double>(Expr(65537.0f)) * Cast::make(Float(64, typed_weight.type().lanes()), typed_weight)); } else { typed_weight = Cast::make(computation_type, computation_type.max() * typed_weight); } inverse_typed_weight = computation_type.max() - typed_weight; } else { inverse_typed_weight = 1.0f - typed_weight; } } else { if (computation_type.is_float()) { int weight_bits = weight.type().bits(); if (weight_bits == 32) { // Should use ldexp, but can't make Expr from result // that is double typed_weight = Cast::make(computation_type, cast<double>(weight) / (pow(cast<double>(2), 32) - 1)); } else { typed_weight = Cast::make(computation_type, weight / ((float)ldexp(1.0f, weight_bits) - 1)); } inverse_typed_weight = 1.0f - typed_weight; } else { // This code rescales integer weights to the right number of bits. // It takes advantage of (2^n - 1) == (2^(n/2) - 1)(2^(n/2) + 1) // e.g. 65535 = 255 * 257. (Ditto for the 32-bit equivalent.) // To recale a weight of m bits to be n bits, we need to do: // scaled_weight = (weight / (2^m - 1)) * (2^n - 1) // which power of two values for m and n, results in a series like // so: // (2^(m/2) + 1) * (2^(m/4) + 1) ... (2^(n*2) + 1) // The loop below computes a scaling constant and either multiples // or divides by the constant and relies on lowering and llvm to // generate efficient code for the operation. int bit_size_difference = weight.type().bits() - computation_type.bits(); if (bit_size_difference == 0) { typed_weight = weight; } else { typed_weight = Cast::make(computation_type, weight); int bits_left = ::abs(bit_size_difference); int shift_amount = std::min(computation_type.bits(), weight.type().bits()); uint64_t scaling_factor = 1; while (bits_left != 0) { internal_assert(bits_left > 0); scaling_factor = scaling_factor + (scaling_factor << shift_amount); bits_left -= shift_amount; shift_amount *= 2; } if (bit_size_difference < 0) { typed_weight = Cast::make(computation_type, weight) * cast(computation_type, (int32_t)scaling_factor); } else { typed_weight = Cast::make(computation_type, weight / cast(weight.type(), (int32_t)scaling_factor)); } } inverse_typed_weight = Cast::make(computation_type, computation_type.max() - typed_weight); } } if (computation_type.is_float()) { result = zero_val * inverse_typed_weight + one_val * typed_weight; } else { int32_t bits = computation_type.bits(); switch (bits) { case 1: result = select(typed_weight, one_val, zero_val); break; case 8: case 16: case 32: { Expr zero_expand = Cast::make(UInt(2 * bits, computation_type.lanes()), zero_val); Expr one_expand = Cast::make(UInt(2 * bits, one_val.type().lanes()), one_val); Expr rounding = Cast::make(UInt(2 * bits), 1) << Cast::make(UInt(2 * bits), (bits - 1)); Expr divisor = Cast::make(UInt(2 * bits), 1) << Cast::make(UInt(2 * bits), bits); Expr prod_sum = zero_expand * inverse_typed_weight + one_expand * typed_weight + rounding; Expr divided = ((prod_sum / divisor) + prod_sum) / divisor; result = Cast::make(UInt(bits, computation_type.lanes()), divided); break; } case 64: // TODO: 64-bit lerp is not supported as current approach // requires double-width multiply. // There is an informative error message in IROperator.h. internal_error << "Can't do a 64-bit lerp.\n"; break; default: break; } } if (!is_zero(bias_value)) { result = Cast::make(result_type, result) + bias_value; } } return simplify(result); }
void CodeGenerator::Assign() { string arg1 = getToken().value; match("="); string arg2 = Expr(); addQuad("=", arg1, arg2, arg1); match(";"); }
int main( int argc, char *argv[] ) { /* *************************************************************************** COMMAND LINE ARGUMENTS *************************************************************************** */ int eps = 54; // Number of bits of absolute precision desired // default to 54 bits (= machine double precision) int DOsqrt = 1; // a flag: defaults to 1 // (i.e., compute sqrt) int DOvalidate = 1; // a flag to validate Pi: defaults to 1 // (i.e., validate to 250 digits) if (argc > 1) eps = atoi(argv[1]); if (argc > 2) DOsqrt = atoi(argv[2]); if (argc > 3) { DOvalidate = atoi(argv[3]); if ((DOvalidate < 0) || (DOvalidate >2)) { std::cout << " !! Third argument in error, defaults to 1\n"; DOvalidate = 1; }; }; std::cout << "DOsqrt = " << DOsqrt << "; DOvalidate = " << DOvalidate << std::endl; /* *************************************************************************** COMPUTING Pi *************************************************************************** */ // Translates eps (in bits) to outputPrec (in digits) int outputPrec; // desired precision in digits outputPrec = (int) (eps * log(2.0)/log(10.0)); std::cout << " Output precision is " << outputPrec << " digits \n"; // Computing Auxilliary Values double t1 = arctan(5, eps + 6); // debugging output: // std::cout << std::setprecision(outputPrec+1) << "arctan(1/5) = " << t1 << std::endl; double t2 = arctan(239, eps + 4); // debugging output: // std::cout << std::setprecision(outputPrec+1) << "arctan(1/239) = " << t2 << std::endl; double pi = (4 * t1 - t2) * 4; pi.approx(CORE_posInfty, eps); // Output of Pi std::cout << " Pi = " << std::setprecision(outputPrec+1) << pi << std::endl; // Note: setprecision in C++ is actually "width" (=number of characters // in output. So we use "outputPrec + 1" to account for the decimal point. /* *************************************************************************** AUTOMATIC CHECK that (1) our internal value of Pi (2) our output value of Pi are both correct to 250 (or 2000) digits *************************************************************************** */ // Reading in digits of Pi from Files int prec = 0; // bit precision for the comparison std::ifstream from; // input stream from file if (DOvalidate == 0) { // no validation prec = 1; } if (DOvalidate == 1) { prec = core_min(eps, 830); // 830 bits = 250 digits. from.open("inputs/PI250", std::ios::in); // read 250 digits of Pi from file } if (DOvalidate == 2) { prec = core_min(eps, 6644); // 6644 bits = 2000 digits from.open("inputs/PI2000", std::ios::in); // read 2000 digits of Pi from file } if (DOvalidate > 0) { // validation needed std::string piStr; char c; while (from.get(c)) if ((c >= '0' && c <= '9') || (c=='.')) piStr += c; if (!from.eof()) std::cout << "!! Error in reading from PI250 \n"; from.close(); double bigPi(piStr.c_str()); // bigPi is the value of Pi from file // debug: // std::cout << " bigPi = " << std::setprecision(outputPrec + 1) << bigPi << std::endl; // CHECKING OUTPUT VALUE OF Pi: std::ostringstream ost; ost << std::setprecision(outputPrec+1) << pi << std::endl; piStr = ost.str(); // Need to take the min of outputPrec and the number of digits in bigPi int minPrec = 0; if (DOvalidate == 1) minPrec = core_min(outputPrec, 250); if (DOvalidate == 2) minPrec = core_min(outputPrec, 2000); double ee = pow(Expr(10), -minPrec+4); ee.approx(eps); std::cout << "pow(Expr(10), -minPrec+4)) = " << std::setprecision(outputPrec) << ee << std::endl; if ( fabs(Expr(piStr.c_str()) - bigPi) <= pow(Expr(10), -minPrec+4)) std::cout << " >> Output value of Pi verified to "<< minPrec << " digits\n"; else std::cout << " !! Output value of Pi INCORRECT to " << minPrec << " digits! \n"; // CHECKING INTERNAL VALUE of Pi: if ( fabs(pi - bigPi) <= (Expr)BigFloat::exp2(- prec +1)) std::cout << " >> Internal value of Pi verified up to " << prec << " bits\n"; else std::cout << " !! Internal value of Pi INCORRECT to " << prec << " bits! \n"; }; /* *************************************************************************** COMPUTING THE SQUARE ROOT of Pi to (eps - 2) bits of absolute precision *************************************************************************** */ if (DOsqrt == 0) return 0; // do not compute sqrt(Pi) // Here is sqrt(Pi) to 100 digits from Knuth: Expr SQRTPI="1.772453850905516027298167483341145182797549456122387128213807789852911284591032181374950656738544665"; double sPi = sqrt(pi); sPi.approx(CORE_posInfty, eps + 2); std::cout << " sqrt(Pi) = " << std::setprecision(outputPrec-1) << sPi << std::endl; /* *************************************************************************** AUTOMATIC CHECK that the internal value of computed sqrt(Pi) is correct up to the first 100 digits. *************************************************************************** */ prec = core_min(eps-1, 332); // 332 bits == 100 digits double d3 = fabs(sPi - SQRTPI); double tmp = pow(Expr(10), -(int) (prec * log(2.0)/log(10.0)) ); if ( d3 <= tmp ) std::cout << " >> Internal value of sqrt(Pi) verified to " << prec << " bits\n"; else std::cout << " !! Internal value of sqrt(Pi) INCORRECT to " << prec << " bits! \n"; return 0; }
Expr cast_to_expr(int a) { return Expr(a); }
Expr Ast_While::_parse_in( ParsingContext &context ) const { // watch modified variables IpSnapshot nsv( ip->ip_snapshot ); // we repeat until there are no external modified values int ne = ip->error_list.size(); std::map<Expr,Expr> unknowns; for( unsigned old_nsv_size = 0, cpt = 0; ; old_nsv_size = nsv.rooms.size(), ++cpt ) { if ( cpt == 20 ) return context.ret_error( "infinite loop during while parsing" ); ParsingContext wh_scope( &context, 0, "while_" + to_string( ok ) ); wh_scope.cont = true; ok->parse_in( wh_scope ); if ( ne != ip->error_list.size() ) return Expr(); // if no new modified variables if ( old_nsv_size == nsv.rooms.size() ) break; // replace each modified variable to a new unknown variables // (to avoid simplifications during the next round) for( std::pair<Inst *const,Expr> &it : nsv.rooms ) { Expr unk = unknown_inst( it.second->type(), cpt ); unknowns[ it.first ] = unk; const_cast<Inst *>( it.first )->set( unk, true ); } nsv.undo_parsing_contexts(); } // corr table (output number -> input number) // -> find if Unknown inst are used to compute the outputs ++Inst::cur_op_id; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) const_cast<Inst *>( it.first )->get( context.cond )->mark_children(); int cpt = 0; Vec<int> corr; Vec<Type *> inp_types; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) { if ( unknowns[ it.first ]->op_id == Inst::cur_op_id ) { corr << cpt++; inp_types << it.second->type(); } else corr << -1; } // prepare a while inp (for initial values of variables modified in the loop) Expr winp = while_inp( inp_types ); // set winp[...] as initial values of modified variables cpt = 0; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) { int num_inp = corr[ cpt++ ]; if ( num_inp >= 0 ) const_cast<Inst *>( it.first )->set( get_nout( winp, num_inp ), true ); else const_cast<Inst *>( it.first )->set( it.second, true ); } nsv.undo_parsing_contexts(); // relaunch the while inst ParsingContext wh_scope( &context, 0, "while_" + to_string( ok ) ); wh_scope.cont = true; ok->parse_in( wh_scope ); if ( wh_scope.cont->always( false ) ) { ip->ip_snapshot = nsv.prev; } else { // make the while instruction Vec<Expr> out_exprs; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) out_exprs << const_cast<Inst *>( it.first )->get( context.cond ); Expr wout = while_out( out_exprs, wh_scope.cont ); cpt = 0; Vec<Expr> inp_exprs; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) if ( corr[ cpt++ ] >= 0 ) inp_exprs << it.second->simplified( context.cond ); Expr wins = while_inst( inp_exprs, winp, wout, corr ); ip->ip_snapshot = nsv.prev; // replace changed variable by while_inst outputs cpt = 0; for( std::pair<Inst *const,Expr> &it : nsv.rooms ) const_cast<Inst *>( it.first )->set( get_nout( wins, cpt++ ), context.cond ); } // break(s) to transmit ? for( ParsingContext::RemBreak rb : wh_scope.rem_breaks ) context.BREAK( rb.count, rb.cond ); return ip->void_var(); }
Expr cast_to_expr(const FuncRefExpr &f) { return Expr(f); }
Expr Def::TrialDef::call( int nu, Expr *vu, int nn, const String *names, Expr *vn, int pnu, Expr *pvu, int pnn, const String *pnames, Expr *pvn, int apply_mode, ParsingContext *caller, const Expr &cond, Expr self, Varargs *va_size_init ) { if ( apply_mode != ParsingContext::APPLY_MODE_STD ) TODO; // ns.cond = and_boolean( ns.cond, cond ); // particular case if ( orig->ast_item->name == "init" and not self.error() ) { Type *self_type = self->ptype(); if ( self_type->size() < 0 ) ASSERT( va_size_init, "If size is not known, expecting a va_size_init" ); Vec<Expr> offsets, lengths; // ancestors const Ast_Class *ac = static_cast<const Ast_Class *>( self_type->orig->ast_item ); if ( ac->inheritance.size() ) TODO; // offsets Expr off( 0 ); for( Type::Attr &a : self_type->attributes ) { if ( a.off_expr ) { int ali = a.val->ptype()->alig(); if ( a.val->ptype() == ip->type_Repeated ) { SI64 rep_dat[ 2 ]; if ( not a.val->get()->get_val( rep_dat, 2 * 64 ) ) ERROR( "..." ); Type *rep_type = reinterpret_cast<Type *>( (ST)rep_dat[ 0 ] ); ali = rep_type->alig(); } // alig Expr args[] = { room( off ), room( ali ) }; off = caller->apply( ns.get_var( "ceil" ), 2, args ); if ( not off ) return off; off = off->get( caller->cond ); // reg offset offsets << off; // add length Expr arga[] = { room( off ), Expr() }; int s = a.val->ptype()->size(); if ( s < 0 or a.val->ptype() == ip->type_Repeated ) { ASSERT( va_size_init, "..." ); for( int i = 0; ; ++i ) { if ( i == va_size_init->names.size() ) return caller->ret_error( "attribute of variable size does not have a size_init value" ); if ( va_size_init->names[ i ] == a.name ) { arga[ 1 ] = va_size_init->exprs[ i ]; break; } } } else arga[ 1 ] = room( s ); lengths << arga[ 1 ]; off = ns.apply( ns.get_var( "add" ), 2, arga )->get( ns.cond ); } else { offsets << Expr(); lengths << Expr(); } } // for( auto p : offsets ) // PRINT( p.second ); // : attr( val ), ... const Ast_Def *ad = static_cast<const Ast_Def *>( orig->ast_item ); Vec<Bool> initialised_args( Size(), self_type->attributes.size(), false ); for( const Ast_Def::StartsWith_Item &d : ad->starts_with ) { for( int i = 0; ; ++i ) { if ( i == self_type->attributes.size() ) return ns.ret_error( "no attribute " + d.attr + " in class" ); Type::Attr &a = self_type->attributes[ i ]; if ( d.attr == a.name ) { // parse args Vec<Expr> args; int nu = d.args.size() - d.names.size(); for( int i = 0; i < d.args.size(); ++i ) args << d.args[ i ]->parse_in( ns ); // ns.call_init( self_type->attr_expr( self, a ), nu, args.ptr(), d.names.size(), d.names.ptr(), args.ptr() + nu ); initialised_args[ i ] = true; break; } } } // default initialization int cpt = 0; for( int num_attr = 0; num_attr < self_type->attributes.size(); ++num_attr ) { Type::Attr &a = self_type->attributes[ num_attr ]; if ( a.off_expr and initialised_args[ cpt ] == false ) { ns.current_off = a.off; ns.current_src = a.src; if ( a.val->ptype() == ip->type_Repeated ) { // call ___repeated_init rep, var, len, varargs Vec<Expr> init_exprs; Vec<String> init_names; Expr args[] = { a.val, add( self, offsets[ num_attr ] ), lengths[ num_attr ], ns._make_varars( init_exprs, init_names ) }; ns.apply( ns.get_var( "___repeated_init" ), 4, args ); } else ns.call_init( self_type->attr_expr( self, a ), not ( a.val->flags & Inst::PART_INST ), &a.val ); } } ++cpt; } // inline call ns.scope_type = ParsingContext::SCOPE_TYPE_DEF; orig->ast_item->block->parse_in( ns ); return ns.ret; }
Expr cast_to_expr(RVar r) { return Expr(r); }
void visit(const Pipeline *op) { if (op->buffer != func.name()) { IRMutator::visit(op); } else { // We're interested in the case where exactly one of the // mins of the buffer depends on the loop_var, and none of // the extents do. string dim = ""; Expr min, extent; for (size_t i = 0; i < func.args().size(); i++) { string min_name = func.name() + "." + func.args()[i] + ".min"; string extent_name = func.name() + "." + func.args()[i] + ".extent"; assert(scope.contains(min_name) && scope.contains(extent_name)); Expr this_min = scope.get(min_name); Expr this_extent = scope.get(extent_name); if (ExprDependsOnVar(this_extent, loop_var).result) { min = Expr(); extent = Expr(); break; } if (ExprDependsOnVar(this_min, loop_var).result) { if (min.defined()) { min = Expr(); extent = Expr(); break; } else { dim = func.args()[i]; min = this_min; extent = this_extent; } } } if (min.defined()) { // Ok, we've isolated a function, a dimension to slide along, and loop variable to slide over log(2) << "Sliding " << func.name() << " over dimension " << dim << " along loop variable " << loop_var << "\n"; Expr loop_var_expr = new Variable(Int(32), loop_var); Expr steady_state = loop_var_expr > loop_min; Expr initial_min = substitute(loop_var, loop_min, min); // The new min is one beyond the max we reached on the last loop iteration Expr new_min = substitute(loop_var, loop_var_expr - 1, min + extent); // The new extent is the old extent shrunk by how much we trimmed off the min Expr new_extent = extent + min - new_min; new_min = new Select(steady_state, new_min, initial_min); new_extent = new Select(steady_state, new_extent, extent); stmt = new LetStmt(func.name() + "." + dim + ".extent", new_extent, op); stmt = new LetStmt(func.name() + "." + dim + ".min", new_min, stmt); } else { log(2) << "Could not perform sliding window optimization of " << func.name() << " over " << loop_var << "\n"; stmt = op; } } }
Expr cast_to_expr(const ImageParam &I) { return Expr(I); }
static void AssignmentStatement(void) { Int32 type,count; SymPtr sym,clas_init=NULL; SymPtr parents[16]; sym = Lhs(); if( sym==NULL ) { return; } CheckClassMember(sym); SkipToken(tEQUALS); if(sym->flags&SYM_DEFINED) { compileError("cannot reassign constant"); return; } else if(sym->flags&SYM_CONSTANT) { sym->flags |= SYM_DEFINED; } /* CheckClassMember(sym); */ new_class=NULL; type=Expr(); sym->object.type = type; switch(sym->kind) { case LOCAL_KIND: vm_genI(op_setlocal,sym->num); break; case GLOBAL_KIND: vm_genI(op_setglobal,sym->num); break; case FIELD_KIND: vm_genI(op_setfield,sym->num); break; default: compileError("invalid assignment"); break; } if( type==CLASS_TYPE && new_class != NULL ) { sym->clas = new_class; sym->super = new_class->super; sym->locals = new_class->locals; /* First build a list of all super classes */ count=0; clas_init=sym; while( clas_init!=NULL ) { parents[count++] = clas_init; clas_init = clas_init->super; } /* Now call all constructors in reverse order */ count--; while( count>=0 ) { clas_init = SymFindLocal(NEW,parents[count]); FunctionCall(clas_init,sym); vm_gen0(op_pop); count--; } /* call user defined constructor */ clas_init=SymFindLocal("init",sym); if( clas_init!=NULL ) { if( (Token==tLPAREN && clas_init->nargs!=0) || (Token!=tLPAREN && clas_init->nargs==0) ) { FunctionCall(clas_init,sym); vm_gen0(op_pop); } } } }