Exemplo n.º 1
0
void Function::define_reduction(const vector<Expr> &args, Expr value) {
    assert(defined() && "Can't add a reduction definition without a regular definition first");
    assert(!is_reduction() && "Function already has a reduction definition");
    assert(value.defined() && "Undefined expression in right-hand-side of reduction");

    // Check the dimensionality matches
    assert(args.size() == contents.ptr->args.size() && 
           "Dimensionality of reduction definition must match dimensionality of pure definition");

    // The pure args are those naked vars in the args that are not in
    // a reduction domain and are not parameters
    vector<string> pure_args;
    for (size_t i = 0; i < args.size(); i++) {
        assert(args[i].defined() && "Undefined expression in left-hand-side of reduction");
        if (const Variable *var = args[i].as<Variable>()) {           
            if (!var->param.defined() && !var->reduction_domain.defined()) {
                assert(var->name == contents.ptr->args[i] && "Pure argument to update step must have the same name as pure argument to initialization step in the same dimension");
                pure_args.push_back(var->name);
            }
        }

    }

    // Make sure all the vars in the args and the value are either
    // pure args, in the reduction domain, or a parameter
    CheckVars check;
    check.pure_args = pure_args;
    value.accept(&check);
    for (size_t i = 0; i < args.size(); i++) {
        args[i].accept(&check);
    }

    assert(check.reduction_domain.defined() && "No reduction domain referenced in reduction definition");

    contents.ptr->reduction_args = args;
    contents.ptr->reduction_value = value;
    contents.ptr->reduction_domain = check.reduction_domain;

    // First add the pure args in order
    for (size_t i = 0; i < pure_args.size(); i++) {
        Schedule::Dim d = {pure_args[i], For::Serial};
        contents.ptr->reduction_schedule.dims.push_back(d);
    }

    // Then add the reduction domain outside of that
    for (size_t i = 0; i < check.reduction_domain.domain().size(); i++) {
        Schedule::Dim d = {check.reduction_domain.domain()[i].var, For::Serial};
        contents.ptr->reduction_schedule.dims.push_back(d);
    }
}
Exemplo n.º 2
0
 inline bool implemented_as_kernel(scheduler::op_element const & op){
   return op.type_subfamily==scheduler::OPERATION_FUNCTION_TYPE_SUBFAMILY || is_reduction(op);
 }