/* Special xdr_db_dict_desc that understands optional version number at end. */ bool_t xdr_db_dict_desc(XDR *xdrs, db_dict_desc *objp) { if (!xdr_db_dict_version(xdrs, &objp->impl_vers)) return (FALSE); if (!xdr_array(xdrs, (char **)&objp->tables.tables_val, (uint_t *)&objp->tables.tables_len, ~0, sizeof (db_table_desc_p), (xdrproc_t)xdr_db_table_desc_p)) return (FALSE); if (!xdr_int(xdrs, &objp->count)) return (FALSE); if (xdrs->x_op == XDR_DECODE) { /* If no version was found, set version to 0. */ if (!xdr_vers(xdrs, (void**) &db_update_version)) make_zero(&db_update_version); return (TRUE); } else if (xdrs->x_op == XDR_ENCODE) { /* Always write out version */ if (!xdr_vers(xdrs, (void**) &db_update_version)) return (FALSE); } /* else XDR_FREE: do nothing */ return (TRUE); }
Expr make_zero(Type t) { if (t.is_handle()) { return reinterpret(t, make_zero(UInt(64))); } else { return make_const(t, 0); } }
//============================================================================== // calculates the exact result, as an expansion. static void expansion_orientation_time3d(const double* x0, int time0, const double* x1, int time1, const double* x2, int time2, const double* x3, int time3, const double* x4, int time4, expansion& result) { make_zero(result); expansion d; if(time0){ expansion_orientation3d(x1, x2, x3, x4, d); negative(d, result); } if(time1){ expansion_orientation3d(x0, x2, x3, x4, d); add(result, d, result); } if(time2){ expansion_orientation3d(x0, x1, x3, x4, d); subtract(result, d, result); } if(time3){ expansion_orientation3d(x0, x1, x2, x4, d); add(result, d, result); } if(time3){ expansion_orientation3d(x0, x1, x2, x3, d); subtract(result, d, result); } }
ieee_floatt &ieee_floatt::operator /= (const ieee_floatt &other) { assert(other.spec.f==spec.f); // NaN/x = NaN if(NaN) return *this; // x/Nan = NaN if(other.NaN) { make_NaN(); return *this; } // 0/0 = NaN if(is_zero() && other.is_zero()) { make_NaN(); return *this; } // x/0 = +-inf if(other.is_zero()) { infinity=true; if(other.sign) negate(); return *this; } // x/inf = NaN if(other.infinity) { if(infinity) { make_NaN(); return *this; } bool old_sign = sign; make_zero(); sign = old_sign; if(other.sign) negate(); return *this; } // inf/x = inf else if(infinity) { if(other.sign) negate(); return *this; } exponent-=other.exponent; fraction*=power(2, spec.f); // to account for error fraction*=power(2, spec.f); exponent-=spec.f; fraction/=other.fraction; if(other.sign) negate(); align(); return *this; }
void visit(const Variable *op) { if (op->name == var) { expr = make_one(op->type); } else if (scope.contains(op->name)) { expr = scope.get(op->name); } else { expr = make_zero(op->type); } }
int main() { char a[SIZE], b[SIZE], c[SIZE]; make_num_from_str("12",a); make_num_from_str("12",b); make_zero(c); //mul_simple(a,2,c); mul_simple(a,7,b); print_big_num(b); return 0; }
int make_zero(long long int no, long long int* result){ if ((no == 0)||(no == 1) || (no % 2 != 0)) return 0; if ( (no % 2 ) == 0){ result[no/2] = 0; make_zero(no/2, result ); } }
Expr halide_exp(Expr x_full) { Type type = x_full.type(); internal_assert(type.element_of() == Float(32)); float ln2_part1 = 0.6931457519f; float ln2_part2 = 1.4286067653e-6f; float one_over_ln2 = 1.0f/logf(2.0f); Expr scaled = x_full * one_over_ln2; Expr k_real = floor(scaled); Expr k = cast(Int(32, type.lanes()), k_real); Expr x = x_full - k_real * ln2_part1; x -= k_real * ln2_part2; float coeff[] = { 0.00031965933071842413f, 0.00119156835564003744f, 0.00848988645943932717f, 0.04160188091348320655f, 0.16667983794100929562f, 0.49999899033463041098f, 1.0f, 1.0f }; Expr result = evaluate_polynomial(x, coeff, sizeof(coeff)/sizeof(coeff[0])); // Compute 2^k. int fpbias = 127; Expr biased = k + fpbias; Expr inf = Call::make(type, "inf_f32", {}, Call::PureExtern); // Shift the bits up into the exponent field and reinterpret this // thing as float. Expr two_to_the_n = reinterpret(type, biased << 23); result *= two_to_the_n; // Catch overflow and underflow result = select(biased < 255, result, inf); result = select(biased > 0, result, make_zero(type)); // This introduces lots of common subexpressions result = common_subexpression_elimination(result); return result; }
void mul_big_num(char num1[SIZE], char num2[SIZE], char res[SIZE]) { int i = 0, times; char temp[SIZE]; make_zero(temp); while(num2[i] == '0') { i += 1; } times = num2[i] - '0'; mul_simple(num1,times,temp); while(i <= SIZE - 1) { add_big_num(temp, res, res); i += 1; times = num2[i] - '0'; mul_simple(num1,times,temp); shift_left(temp); } add_big_num(temp,res,res); }
Expr const_false(int w) { return make_zero(UInt(1, w)); }
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; }
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); }