Expr lossless_cast(Type t, Expr e) {
    if (t == e.type()) {
        return e;
    } else if (t.can_represent(e.type())) {
        return cast(t, e);
    }

    if (const Cast *c = e.as<Cast>()) {
        if (t.can_represent(c->value.type())) {
            // We can recurse into widening casts.
            return lossless_cast(t, c->value);
        } else {
            return Expr();
        }
    }

    if (const Broadcast *b = e.as<Broadcast>()) {
        Expr v = lossless_cast(t.element_of(), b->value);
        if (v.defined()) {
            return Broadcast::make(v, b->lanes);
        } else {
            return Expr();
        }
    }

    if (const IntImm *i = e.as<IntImm>()) {
        if (t.can_represent(i->value)) {
            return make_const(t, i->value);
        } else {
            return Expr();
        }
    }

    if (const UIntImm *i = e.as<UIntImm>()) {
        if (t.can_represent(i->value)) {
            return make_const(t, i->value);
        } else {
            return Expr();
        }
    }

    if (const FloatImm *f = e.as<FloatImm>()) {
        if (t.can_represent(f->value)) {
            return make_const(t, f->value);
        } else {
            return Expr();
        }
    }

    return Expr();
}
// Factor a float into 2^exponent * reduced, where reduced is between 0.75 and 1.5
void range_reduce_log(Expr input, Expr *reduced, Expr *exponent) {
    Type type = input.type();
    Type int_type = Int(32, type.lanes());
    Expr int_version = reinterpret(int_type, input);

    // single precision = SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
    // exponent mask    = 0111 1111 1000 0000 0000 0000 0000 0000
    //                    0x7  0xF  0x8  0x0  0x0  0x0  0x0  0x0
    // non-exponent     = 1000 0000 0111 1111 1111 1111 1111 1111
    //                  = 0x8  0x0  0x7  0xF  0xF  0xF  0xF  0xF
    Expr non_exponent_mask = make_const(int_type, 0x807fffff);

    // Extract a version with no exponent (between 1.0 and 2.0)
    Expr no_exponent = int_version & non_exponent_mask;

    // If > 1.5, we want to divide by two, to normalize back into the
    // range (0.75, 1.5). We can detect this by sniffing the high bit
    // of the mantissa.
    Expr new_exponent = no_exponent >> 22;

    Expr new_biased_exponent = 127 - new_exponent;
    Expr old_biased_exponent = int_version >> 23;
    *exponent = old_biased_exponent - new_biased_exponent;

    Expr blended = (int_version & non_exponent_mask) | (new_biased_exponent << 23);

    *reduced = reinterpret(type, blended);
}
Beispiel #3
0
Expr make_zero(Type t) {
    if (t.is_handle()) {
        return reinterpret(t, make_zero(UInt(64)));
    } else {
        return make_const(t, 0);
    }
}
Expr make_zero(Type t) {
    if (t.is_handle()) {
        return Call::make(t, Call::null_handle, std::vector<Expr>(), Call::PureIntrinsic);
    } else {
        return make_const(t, 0);
    }
}
Beispiel #5
0
Expr make_const(Type t, int val) {
    if (t == Int(32)) return val;
    if (t == Float(32)) return (float)val;
    if (t.is_vector()) {
        return new Broadcast(make_const(t.element_of(), val), t.width);
    }
    return new Cast(t, val);
}
Beispiel #6
0
void bind_static_axis_aligned_box_library (Environment& environment)
{
  InvokerRegistry aabox_box_corner_lib = environment.CreateLibrary (BV_STATIC_AXIS_ALIGNED_BOX_CORNER_LIBRARY);

  aabox_box_corner_lib.Register ("get_nxnynz", make_const (box_corner_nxnynz));
  aabox_box_corner_lib.Register ("get_pxnynz", make_const (box_corner_pxnynz));
  aabox_box_corner_lib.Register ("get_nxpynz", make_const (box_corner_nxpynz));
  aabox_box_corner_lib.Register ("get_pxpynz", make_const (box_corner_pxpynz));
  aabox_box_corner_lib.Register ("get_nxnypz", make_const (box_corner_nxnypz));
  aabox_box_corner_lib.Register ("get_pxnypz", make_const (box_corner_pxnypz));
  aabox_box_corner_lib.Register ("get_nxpypz", make_const (box_corner_nxpypz));
  aabox_box_corner_lib.Register ("get_pxpypz", make_const (box_corner_pxpypz));
}  
void check_representable(Type dst, int64_t x) {
    if (dst.is_handle()) {
        user_assert(dst.can_represent(x))
                << "Integer constant " << x
                << " will be implicitly coerced to type " << dst
                << ", but Halide does not support pointer arithmetic.\n";
    } else {
        user_assert(dst.can_represent(x))
                << "Integer constant " << x
                << " will be implicitly coerced to type " << dst
                << ", which changes its value to " << make_const(dst, x)
                << ".\n";
    }
}
Expr make_two(Type t) {
    return make_const(t, 2);
}
Expr make_one(Type t) {
    return make_const(t, 1);
}
Expr make_bool(bool val, int w) {
    return make_const(UInt(1, w), val);
}
Beispiel #11
0
Expr BufferBuilder::build() const {
    std::vector<Expr> args(10);
    if (buffer_memory.defined()) {
        args[0] = buffer_memory;
    } else {
        args[0] = Call::make(type_of<struct halide_buffer_t *>(), Call::alloca, {(int)sizeof(halide_buffer_t)}, Call::Intrinsic);
    }

    std::string shape_var_name = unique_name('t');
    Expr shape_var = Variable::make(type_of<halide_dimension_t *>(), shape_var_name);
    if (shape_memory.defined()) {
        args[1] = shape_memory;
    } else if (dimensions == 0) {
        args[1] = make_zero(type_of<halide_dimension_t *>());
    } else {
        args[1] = shape_var;
    }

    if (host.defined()) {
        args[2] = host;
    } else {
        args[2] = make_zero(type_of<void *>());
    }

    if (device.defined()) {
        args[3] = device;
    } else {
        args[3] = make_zero(UInt(64));
    }

    if (device_interface.defined()) {
        args[4] = device_interface;
    } else {
        args[4] = make_zero(type_of<struct halide_device_interface_t *>());
    }

    args[5] = (int)type.code();
    args[6] = type.bits();
    args[7] = dimensions;

    std::vector<Expr> shape;
    for (size_t i = 0; i < (size_t)dimensions; i++) {
        if (i < mins.size()) {
            shape.push_back(mins[i]);
        } else {
            shape.push_back(0);
        }
        if (i < extents.size()) {
            shape.push_back(extents[i]);
        } else {
            shape.push_back(0);
        }
        if (i < strides.size()) {
            shape.push_back(strides[i]);
        } else {
            shape.push_back(0);
        }
        // per-dimension flags, currently unused.
        shape.push_back(0);
    }
    for (const Expr &e : shape) {
        internal_assert(e.type() == Int(32))
            << "Buffer shape fields must be int32_t:" << e << "\n";
    }
    Expr shape_arg = Call::make(type_of<halide_dimension_t *>(), Call::make_struct, shape, Call::Intrinsic);
    if (shape_memory.defined()) {
        args[8] = shape_arg;
    } else if (dimensions == 0) {
        args[8] = make_zero(type_of<halide_dimension_t *>());
    } else {
        args[8] = shape_var;
    }

    Expr flags = make_zero(UInt(64));
    if (host_dirty.defined()) {
        flags = select(host_dirty,
                       make_const(UInt(64), halide_buffer_flag_host_dirty),
                       make_zero(UInt(64)));
    }
    if (device_dirty.defined()) {
        flags = flags | select(device_dirty,
                               make_const(UInt(64), halide_buffer_flag_device_dirty),
                               make_zero(UInt(64)));
    }
    args[9] = flags;

    Expr e = Call::make(type_of<struct halide_buffer_t *>(), Call::buffer_init, args, Call::Extern);

    if (!shape_memory.defined() && dimensions != 0) {
        e = Let::make(shape_var_name, shape_arg, e);
    }

    return e;
}
Beispiel #12
0
Expr make_zero(Type t) {
    return make_const(t, 0);
}
void halide_pipeline_to_c(
    Stmt s, const vector<Function> &outputs, const map<string, Function> &env,
    const map<string, vector<int32_t>> &output_buffers_size,
    const string &func)
{

    std::ostringstream stream;

    stream << "tiramisu::function " << func << "(\"" << func << "\")" << ";\n";

    set<string> output_buffers;
    Scope<Expr> scope;

    std::ostringstream output_buffers_stream;
    output_buffers_stream << "{";
    // Allocate the output buffers
    for (size_t k = 0; k < outputs.size(); ++k)
    {
        const Function &f = outputs[k];
        const auto iter = output_buffers_size.find(f.name());
        assert(iter != output_buffers_size.end());
        assert(iter->second.size() == f.args().size());

        std::ostringstream sizes;
        sizes << "{";
        for (size_t i = 0; i < iter->second.size(); ++i)
        {
            sizes << "tiramisu::expr(" << iter->second[i] << ")";
            scope.push(f.name() + "_min_" + std::to_string(i), make_const(Int(32), 0));
            scope.push(f.name() + "_extent_" + std::to_string(i), make_const(Int(32), iter->second[i]));
            if (i != iter->second.size() - 1)
            {
                sizes << ", ";
            }
        }
        sizes << "}";

        string buffer_name = "buff_" + f.name();
        // TODO(psuriana): should make the buffer data type variable instead of uint8_t always
        stream << "tiramisu::buffer " << buffer_name << "(\"" << buffer_name << "\", "
               << f.args().size() << ", " << sizes.str() << ", tiramisu::p_uint8, NULL, tiramisu::a_output, "
               << "&" << func << ");\n";
        output_buffers.insert(buffer_name);

        output_buffers_stream << "&" << buffer_name;
        if (k != outputs.size() - 1)
        {
            output_buffers_stream << ", ";
        }
    }
    output_buffers_stream << "}";

    HalideToC converter(scope, outputs, env, output_buffers, func, stream);
    converter.print(s);

    stream << func << ".set_arguments(" << output_buffers_stream.str() << ");\n";
    stream << func << ".gen_isl_ast();\n";
    stream << func << ".gen_halide_stmt();\n";
    stream << func << ".dump_halide_stmt();\n";
    stream << func << ".gen_halide_obj(\"build/generated_fct_test_06.o\");\n";

    std::cout << "\nTiramisu C output:\n\n" << stream.str() << "\n";
}
Beispiel #14
0
//Регистрация статических переменных
void bind_static_media_player_library (Environment& environment)
{
  InvokerRegistry player_state_lib       = environment.CreateLibrary (MEDIA_STATIC_PLAYER_STATE_LIBRARY);
  InvokerRegistry player_repeat_mode_lib = environment.CreateLibrary (MEDIA_STATIC_PLAYER_REPEAT_MODE_LIBRARY);
  InvokerRegistry player_event_lib       = environment.CreateLibrary (MEDIA_STATIC_PLAYER_EVENT_LIBRARY);

  player_state_lib.Register       ("get_Stopped",            make_const (MediaPlayerState_Stopped));
  player_state_lib.Register       ("get_Playing",            make_const (MediaPlayerState_Playing));
  player_state_lib.Register       ("get_Paused",             make_const (MediaPlayerState_Paused));
  player_repeat_mode_lib.Register ("get_Off",                make_const (MediaPlayerRepeatMode_Off));
  player_repeat_mode_lib.Register ("get_Last",               make_const (MediaPlayerRepeatMode_Last));
  player_repeat_mode_lib.Register ("get_All",                make_const (MediaPlayerRepeatMode_All));
  player_event_lib.Register       ("get_OnChangeName",       make_const (MediaPlayerEvent_OnChangeName));
  player_event_lib.Register       ("get_OnChangeTarget",     make_const (MediaPlayerEvent_OnChangeTarget));
  player_event_lib.Register       ("get_OnChangePlaylist",   make_const (MediaPlayerEvent_OnChangePlaylist));
  player_event_lib.Register       ("get_OnChangeTrack",      make_const (MediaPlayerEvent_OnChangeTrack));
  player_event_lib.Register       ("get_OnChangePlayback",   make_const (MediaPlayerEvent_OnChangePlayback));
  player_event_lib.Register       ("get_OnChangeVolume",     make_const (MediaPlayerEvent_OnChangeVolume));
  player_event_lib.Register       ("get_OnChangeRepeatMode", make_const (MediaPlayerEvent_OnChangeRepeatMode));
}