WEAK void default_error_handler(void *user_context, const char *msg) {
    char buf[4096];
    char *dst = halide_string_to_string(buf, buf + 4095, "Error: ");
    dst = halide_string_to_string(dst, buf + 4095, msg);
    // We still have one character free. Add a newline if there
    // isn't one already.
    if (dst[-1] != '\n') {
        dst[0] = '\n';
        dst[1] = 0;
    }
    halide_print(user_context, buf);
    exit(1);
}
WEAK void halide_default_error(void *user_context, const char *msg) {
    char buf[4096];
    char *dst = halide_string_to_string(buf, buf + 4094, "Error: ");
    dst = halide_string_to_string(dst, buf + 4094, msg);
    // We still have one character free. Add a newline if there
    // isn't one already.
    if (dst[-1] != '\n') {
        dst[0] = '\n';
        dst[1] = 0;
        dst += 1;
    }
    halide_msan_annotate_memory_is_initialized(user_context, buf, dst - buf + 1);
    halide_print(user_context, buf);
    Halide::Runtime::Internal::halide_abort();
}
Beispiel #3
0
WEAK char *halide_uint64_to_string(char *dst, char *end, uint64_t arg, int min_digits) {
    // 32 is more than enough chars to contain any 64-bit int.
    char buf[32];
    buf[31] = 0;
    char *digits = buf+30;

    for (int i = 0; i < min_digits || arg; i++) {
        uint64_t top = arg / 10;
        uint64_t bottom = arg - top * 10;
        *digits = bottom + '0';
        digits--;
        arg = top;
    }
    digits++;

    return halide_string_to_string(dst, end, digits);
}
Beispiel #4
0
WEAK char *halide_double_to_string(char *dst, char *end, double arg, int scientific) {
    uint64_t bits = 0;
    memcpy(&bits, &arg, sizeof(double));

    uint64_t one = 1;
    uint64_t mantissa = bits & ((one << 52) - 1);
    int biased_exponent = (bits >> 52) & ((1 << 11) - 1);
    int negative = (bits >> 63);

    // Handle special values
    if (biased_exponent == 2047) {
        if (mantissa) {
            if (negative) {
                return halide_string_to_string(dst, end, "-nan");
            } else {
                return halide_string_to_string(dst, end, "nan");
            }
        } else {
            if (negative) {
                return halide_string_to_string(dst, end, "-inf");
            } else {
                return halide_string_to_string(dst, end, "inf");
            }
        }
    } else if (biased_exponent == 0 && mantissa == 0) {
        if (scientific) {
            if (negative) {
                return halide_string_to_string(dst, end, "-0.000000e+00");
            } else {
                return halide_string_to_string(dst, end, "0.000000e+00");
            }
        } else {
            if (negative) {
                return halide_string_to_string(dst, end, "-0.000000");
            } else {
                return halide_string_to_string(dst, end, "0.000000");
            }
        }
    }

    if (negative) {
        dst = halide_string_to_string(dst, end, "-");
        arg = -arg;
    }


    // The desired number of decimal places.
    const int decimal_places = 6;

    // 10 ^ decimal places
    const uint64_t scale = 1000000;

    // The number of bits in the mantissa of an IEEE double.
    const int mantissa_bits = 52;

    if (scientific) {

        // Compute base 10 exponent and normalize the number to within [1, 10)
        int exponent_base_10 = 0;
        while (arg < 1) {
            arg *= 10;
            exponent_base_10--;
        }

        while (arg >= 10) {
            arg /= 10;
            exponent_base_10++;
        }

        // Convert to fixed-point;
        uint64_t fixed = (uint64_t)(arg * scale + 0.5);
        uint64_t top_digit = fixed / scale;
        uint64_t other_digits = fixed - top_digit * scale;

        dst = halide_int64_to_string(dst, end, top_digit, 1);
        dst = halide_string_to_string(dst, end, ".");
        dst = halide_int64_to_string(dst, end, other_digits, decimal_places);

        if (exponent_base_10 >= 0) {
            dst = halide_string_to_string(dst, end, "e+");
        } else {
            dst = halide_string_to_string(dst, end, "e-");
            exponent_base_10 = -exponent_base_10;
        }
        dst = halide_int64_to_string(dst, end, exponent_base_10, 2);

    } else {
        // Denormals flush to zero in non-scientific mode. We've
        // already printed the sign.
        if (biased_exponent == 0) {
            return halide_double_to_string(dst, end, 0.0, false);
        }

        // Express it as an integer times a power of two.
        uint64_t n = mantissa + (one << mantissa_bits);
        int exponent = biased_exponent - 1023 - mantissa_bits;

        // Break it into integer and fractional parts.
        uint64_t integer_part = n;
        int integer_exponent = exponent;

        uint64_t fractional_part = 0;
        if (exponent < 0) {
            // There is a fractional component.

            double f;
            if (exponent < -mantissa_bits) {
                // There's no integer component.
                integer_part = 0;
                f = n;
            } else {
                integer_part >>= (-exponent);
                f = n - (integer_part << (-exponent));
            }
            integer_exponent = 0;

            // Construct 10^decimal_places * 2^exponent exactly
            // (recall exponent is negative).
            union {
                uint64_t bits;
                double as_double;
            } multiplier;
            multiplier.as_double = scale;
            multiplier.bits += (uint64_t)(exponent) << mantissa_bits;

            // Use it to get the first 6 digits of the fractional part
            // into the integer part.
            f = f * multiplier.as_double + 0.5;

            // Round-to-even, to match glibc.
            fractional_part = (uint64_t)f;
            if (fractional_part == f &&
                (fractional_part & 1)) {
                fractional_part--;
            }

            // If we rounded the fractional part up to the scale
            // factor, we'd better reattribute it to the integer part.
            if (fractional_part == scale) {
                fractional_part = 0;
                integer_part++;
            }
        }

        // The number is now:
        // integer_part * 2^integer_exponent + fractional_part * 2^exponent.

        // Convert integer_part to decimal, then repeatedly double it.

        // The largest double is 310 digits long.
        char buf[512];
        // Start 32 chars before the end of the scratch buffer and work
        // backwards to allow space for carried digits.
        char *int_part_ptr = buf + 512 - 32;
        char *buf_end = halide_int64_to_string(int_part_ptr, buf + 512, integer_part, 1);
        for (int i = 0; i < integer_exponent; i++) {
            // Double each digit, with ripple carry.
            int carry = 0;
            for (char *p = buf_end - 1; p != int_part_ptr - 1; p--) {
                char old_digit = *p - '0';
                char new_digit = old_digit * 2 + carry;
                if (new_digit > 9) {
                    new_digit -= 10;
                    carry = 1;
                } else {
                    carry = 0;
                }
                *p = new_digit + '0';
            }
            if (carry) {
                // There was a carry in the last digit. Add a new '1'
                // at the start.
                int_part_ptr--;
                *int_part_ptr = '1';
            }
        }
        dst = halide_string_to_string(dst, end, int_part_ptr);
        dst = halide_string_to_string(dst, end, ".");
        dst = halide_int64_to_string(dst, end, fractional_part, decimal_places);
    }