src/ScheduleFunctions.cpp
// Build a loop nest about a provide node using a schedule
Build a loop nest about a provide node using a schedule
Build a loop nest about a provide node using a schedule
Stmt build_provide_loop_nest(const map<string, Function> &env,
                             const string &prefix,
                             const Function &func,
                             const Definition &def,
                             int start_fuse,
                             bool is_update) {
    internal_assert(!is_update == def.is_init());
    vector<Expr> site(def.args().size());
    vector<Expr> values(def.values().size());
    for (size_t i = 0; i < values.size(); i++) {
        Expr v = def.values()[i];
        v = qualify(prefix, v);
        values[i] = v;
        debug(3) << "Value " << i << " = " << v << "\n";
    }
    for (size_t i = 0; i < def.args().size(); i++) {
        Expr s = def.args()[i];
        s = qualify(prefix, s);
        site[i] = s;
        debug(3) << "Site " << i << " = " << s << "\n";
    }
    Stmt body = Provide::make(func.name(), values, site);
    Stmt stmt = build_loop_nest(body, prefix, start_fuse, func, def, is_update);
    stmt = inject_placeholder_prefetch(stmt, env, prefix, def.schedule().prefetches());
    const vector<Specialization> &specializations = def.specializations();
    for (size_t i = specializations.size(); i > 0; i--) {
        const Specialization &s = specializations[i - 1];
        Stmt then_case;
        if (s.failure_message.empty()) {
            then_case = build_provide_loop_nest(env, prefix, func, s.definition, start_fuse, is_update);
        } else {
            internal_assert(equal(s.condition, const_true()));
            internal_assert(i == specializations.size());
            Expr specialize_fail_error =
                Internal::Call::make(Int(32),
                                     "halide_error_specialize_fail",
                                     {StringImm::make(s.failure_message)},
                                     Internal::Call::Extern);
            then_case = AssertStmt::make(const_false(), specialize_fail_error);
        }
        stmt = IfThenElse::make(s.condition, then_case, stmt);
    }
    return stmt;
}
Stmt build_provide_loop_nest ( const map < string , Function > & env , const string & prefix , const Function & func , const Definition & def , int start_fuse , bool is_update ) { internal_assert ( ! is_update == def . is_init ( ) ) ; vector < Expr > site ( def . args ( ) . size ( ) ) ; vector < Expr > values ( def . values ( ) . size ( ) ) ; for ( size_t i = 0 ; i < values . size ( ) ; i ++ ) { Expr v = def . values ( ) [ i ] ; v = qualify ( prefix , v ) ; values [ i ] = v ; debug ( 3 ) << " " << i << " " << v << " \n " ; } for ( size_t i = 0 ; i < def . args ( ) . size ( ) ; i ++ ) { Expr s = def . args ( ) [ i ] ; s = qualify ( prefix , s ) ; site [ i ] = s ; debug ( 3 ) << " " << i << " " << s << " \n " ; } Stmt body = Provide :: make ( func . name ( ) , values , site ) ; Stmt stmt = build_loop_nest ( body , prefix , start_fuse , func , def , is_update ) ; stmt = inject_placeholder_prefetch ( stmt , env , prefix , def . schedule ( ) . prefetches ( ) ) ; const vector < Specialization > & specializations = def . specializations ( ) ; for ( size_t i = specializations . size ( ) ; i > 0 ; i -- ) { const Specialization & s = specializations [ i - 1 ] ; Stmt then_case ; if ( s . failure_message . empty ( ) ) { then_case = build_provide_loop_nest ( env , prefix , func , s . definition , start_fuse , is_update ) ; } else { internal_assert ( equal ( s . condition , const_true ( ) ) ) ; internal_assert ( i == specializations . size ( ) ) ; Expr specialize_fail_error = Internal :: Call :: make ( Int ( 32 ) , " " , { StringImm :: make ( s . failure_message ) } , Internal :: Call :: Extern ) ; then_case = AssertStmt :: make ( const_false ( ) , specialize_fail_error ) ; } stmt = IfThenElse :: make ( s . condition , then_case , stmt ) ; } return stmt ; }
Build a loop nest about a provide node using a schedule
Build a loop nest about a provide node using a schedule
// Default stored values // Default stored locations // Make the (multi-dimensional multi-valued) store node. // Default schedule/values if there is no specialization // Make any specialized copies // specialize_fail() should only be possible on the final specialization