futhark-0.25.36: rts/c/scalar.h
// Start of scalar.h.
// Implementation of the primitive scalar operations. Very
// repetitive. This code is inserted directly into both CUDA and
// OpenCL programs, as well as the CPU code, so it has some #ifdefs to
// work everywhere. Some operations are defined as macros because
// this allows us to use them as constant expressions in things like
// array sizes and static initialisers.
// Some of the #ifdefs are because OpenCL uses type-generic functions
// for some operations (e.g. sqrt), while C and CUDA sensibly use
// distinct functions for different precisions (e.g. sqrtf() and
// sqrt()). This is quite annoying. Due to C's unfortunate casting
// rules, it is also really easy to accidentally implement
// floating-point functions in the wrong precision, so be careful.
// Double-precision definitions are only included if the preprocessor
// macro FUTHARK_F64_ENABLED is set.
#ifndef M_PI
#define M_PI 3.141592653589793
#endif
SCALAR_FUN_ATTR int32_t fptobits_f32_i32(float x);
SCALAR_FUN_ATTR float bitstofp_i32_f32(int32_t x);
SCALAR_FUN_ATTR uint8_t add8(uint8_t x, uint8_t y) { return x + y; }
SCALAR_FUN_ATTR uint16_t add16(uint16_t x, uint16_t y) { return x + y; }
SCALAR_FUN_ATTR uint32_t add32(uint32_t x, uint32_t y) { return x + y; }
SCALAR_FUN_ATTR uint64_t add64(uint64_t x, uint64_t y) { return x + y; }
SCALAR_FUN_ATTR uint8_t sub8(uint8_t x, uint8_t y) { return x - y; }
SCALAR_FUN_ATTR uint16_t sub16(uint16_t x, uint16_t y) { return x - y; }
SCALAR_FUN_ATTR uint32_t sub32(uint32_t x, uint32_t y) { return x - y; }
SCALAR_FUN_ATTR uint64_t sub64(uint64_t x, uint64_t y) { return x - y; }
SCALAR_FUN_ATTR uint8_t mul8(uint8_t x, uint8_t y) { return x * y; }
SCALAR_FUN_ATTR uint16_t mul16(uint16_t x, uint16_t y) { return x * y; }
SCALAR_FUN_ATTR uint32_t mul32(uint32_t x, uint32_t y) { return x * y; }
SCALAR_FUN_ATTR uint64_t mul64(uint64_t x, uint64_t y) { return x * y; }
#if defined(ISPC)
SCALAR_FUN_ATTR uint8_t udiv8(uint8_t x, uint8_t y) {
// This strange pattern is used to prevent the ISPC compiler from
// causing SIGFPEs and bogus results on divisions where inactive lanes
// have 0-valued divisors. It ensures that any inactive lane instead
// has a divisor of 1. https://github.com/ispc/ispc/issues/2292
uint8_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR uint16_t udiv16(uint16_t x, uint16_t y) {
uint16_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR uint32_t udiv32(uint32_t x, uint32_t y) {
uint32_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR uint64_t udiv64(uint64_t x, uint64_t y) {
uint64_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR uint8_t udiv_up8(uint8_t x, uint8_t y) {
uint8_t ys = 1;
foreach_active(i) { ys = y; }
return (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint16_t udiv_up16(uint16_t x, uint16_t y) {
uint16_t ys = 1;
foreach_active(i) { ys = y; }
return (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint32_t udiv_up32(uint32_t x, uint32_t y) {
uint32_t ys = 1;
foreach_active(i) { ys = y; }
return (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint64_t udiv_up64(uint64_t x, uint64_t y) {
uint64_t ys = 1;
foreach_active(i) { ys = y; }
return (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint8_t umod8(uint8_t x, uint8_t y) {
uint8_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR uint16_t umod16(uint16_t x, uint16_t y) {
uint16_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR uint32_t umod32(uint32_t x, uint32_t y) {
uint32_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR uint64_t umod64(uint64_t x, uint64_t y) {
uint64_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR uint8_t udiv_safe8(uint8_t x, uint8_t y) {
uint8_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR uint16_t udiv_safe16(uint16_t x, uint16_t y) {
uint16_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR uint32_t udiv_safe32(uint32_t x, uint32_t y) {
uint32_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR uint64_t udiv_safe64(uint64_t x, uint64_t y) {
uint64_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR uint8_t udiv_up_safe8(uint8_t x, uint8_t y) {
uint8_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint16_t udiv_up_safe16(uint16_t x, uint16_t y) {
uint16_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint32_t udiv_up_safe32(uint32_t x, uint32_t y) {
uint32_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint64_t udiv_up_safe64(uint64_t x, uint64_t y) {
uint64_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : (x + y - 1) / ys;
}
SCALAR_FUN_ATTR uint8_t umod_safe8(uint8_t x, uint8_t y) {
uint8_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
SCALAR_FUN_ATTR uint16_t umod_safe16(uint16_t x, uint16_t y) {
uint16_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
SCALAR_FUN_ATTR uint32_t umod_safe32(uint32_t x, uint32_t y) {
uint32_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
SCALAR_FUN_ATTR uint64_t umod_safe64(uint64_t x, uint64_t y) {
uint64_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
SCALAR_FUN_ATTR int8_t sdiv8(int8_t x, int8_t y) {
int8_t ys = 1;
foreach_active(i) { ys = y; }
int8_t q = x / ys;
int8_t r = x % ys;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int16_t sdiv16(int16_t x, int16_t y) {
int16_t ys = 1;
foreach_active(i) { ys = y; }
int16_t q = x / ys;
int16_t r = x % ys;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int32_t sdiv32(int32_t x, int32_t y) {
int32_t ys = 1;
foreach_active(i) { ys = y; }
int32_t q = x / ys;
int32_t r = x % ys;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int64_t sdiv64(int64_t x, int64_t y) {
int64_t ys = 1;
foreach_active(i) { ys = y; }
int64_t q = x / ys;
int64_t r = x % ys;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int8_t sdiv_up8(int8_t x, int8_t y) { return sdiv8(x + y - 1, y); }
SCALAR_FUN_ATTR int16_t sdiv_up16(int16_t x, int16_t y) { return sdiv16(x + y - 1, y); }
SCALAR_FUN_ATTR int32_t sdiv_up32(int32_t x, int32_t y) { return sdiv32(x + y - 1, y); }
SCALAR_FUN_ATTR int64_t sdiv_up64(int64_t x, int64_t y) { return sdiv64(x + y - 1, y); }
SCALAR_FUN_ATTR int8_t smod8(int8_t x, int8_t y) {
int8_t ys = 1;
foreach_active(i) { ys = y; }
int8_t r = x % ys;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int16_t smod16(int16_t x, int16_t y) {
int16_t ys = 1;
foreach_active(i) { ys = y; }
int16_t r = x % ys;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int32_t smod32(int32_t x, int32_t y) {
int32_t ys = 1;
foreach_active(i) { ys = y; }
int32_t r = x % ys;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int64_t smod64(int64_t x, int64_t y) {
int64_t ys = 1;
foreach_active(i) { ys = y; }
int64_t r = x % ys;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int8_t sdiv_safe8(int8_t x, int8_t y) { return y == 0 ? 0 : sdiv8(x, y); }
SCALAR_FUN_ATTR int16_t sdiv_safe16(int16_t x, int16_t y) { return y == 0 ? 0 : sdiv16(x, y); }
SCALAR_FUN_ATTR int32_t sdiv_safe32(int32_t x, int32_t y) { return y == 0 ? 0 : sdiv32(x, y); }
SCALAR_FUN_ATTR int64_t sdiv_safe64(int64_t x, int64_t y) { return y == 0 ? 0 : sdiv64(x, y); }
SCALAR_FUN_ATTR int8_t sdiv_up_safe8(int8_t x, int8_t y) { return sdiv_safe8(x + y - 1, y); }
SCALAR_FUN_ATTR int16_t sdiv_up_safe16(int16_t x, int16_t y) { return sdiv_safe16(x + y - 1, y); }
SCALAR_FUN_ATTR int32_t sdiv_up_safe32(int32_t x, int32_t y) { return sdiv_safe32(x + y - 1, y); }
SCALAR_FUN_ATTR int64_t sdiv_up_safe64(int64_t x, int64_t y) { return sdiv_safe64(x + y - 1, y); }
SCALAR_FUN_ATTR int8_t smod_safe8(int8_t x, int8_t y) { return y == 0 ? 0 : smod8(x, y); }
SCALAR_FUN_ATTR int16_t smod_safe16(int16_t x, int16_t y) { return y == 0 ? 0 : smod16(x, y); }
SCALAR_FUN_ATTR int32_t smod_safe32(int32_t x, int32_t y) { return y == 0 ? 0 : smod32(x, y); }
SCALAR_FUN_ATTR int64_t smod_safe64(int64_t x, int64_t y) { return y == 0 ? 0 : smod64(x, y); }
SCALAR_FUN_ATTR int8_t squot8(int8_t x, int8_t y) {
int8_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR int16_t squot16(int16_t x, int16_t y) {
int16_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR int32_t squot32(int32_t x, int32_t y) {
int32_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR int64_t squot64(int64_t x, int64_t y) {
int64_t ys = 1;
foreach_active(i) { ys = y; }
return x / ys;
}
SCALAR_FUN_ATTR int8_t srem8(int8_t x, int8_t y) {
int8_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR int16_t srem16(int16_t x, int16_t y) {
int16_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR int32_t srem32(int32_t x, int32_t y) {
int32_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR int64_t srem64(int64_t x, int64_t y) {
int8_t ys = 1;
foreach_active(i) { ys = y; }
return x % ys;
}
SCALAR_FUN_ATTR int8_t squot_safe8(int8_t x, int8_t y) {
int8_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR int16_t squot_safe16(int16_t x, int16_t y) {
int16_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR int32_t squot_safe32(int32_t x, int32_t y) {
int32_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR int64_t squot_safe64(int64_t x, int64_t y) {
int64_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x / ys;
}
SCALAR_FUN_ATTR int8_t srem_safe8(int8_t x, int8_t y) {
int8_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
SCALAR_FUN_ATTR int16_t srem_safe16(int16_t x, int16_t y) {
int16_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
SCALAR_FUN_ATTR int32_t srem_safe32(int32_t x, int32_t y) {
int32_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
SCALAR_FUN_ATTR int64_t srem_safe64(int64_t x, int64_t y) {
int64_t ys = 1;
foreach_active(i) { ys = y; }
return y == 0 ? 0 : x % ys;
}
#else
SCALAR_FUN_ATTR uint8_t udiv8(uint8_t x, uint8_t y) { return x / y; }
SCALAR_FUN_ATTR uint16_t udiv16(uint16_t x, uint16_t y) { return x / y; }
SCALAR_FUN_ATTR uint32_t udiv32(uint32_t x, uint32_t y) { return x / y; }
SCALAR_FUN_ATTR uint64_t udiv64(uint64_t x, uint64_t y) { return x / y; }
SCALAR_FUN_ATTR uint8_t udiv_up8(uint8_t x, uint8_t y) { return (x + y - 1) / y; }
SCALAR_FUN_ATTR uint16_t udiv_up16(uint16_t x, uint16_t y) { return (x + y - 1) / y; }
SCALAR_FUN_ATTR uint32_t udiv_up32(uint32_t x, uint32_t y) { return (x + y - 1) / y; }
SCALAR_FUN_ATTR uint64_t udiv_up64(uint64_t x, uint64_t y) { return (x + y - 1) / y; }
SCALAR_FUN_ATTR uint8_t umod8(uint8_t x, uint8_t y) { return x % y; }
SCALAR_FUN_ATTR uint16_t umod16(uint16_t x, uint16_t y) { return x % y; }
SCALAR_FUN_ATTR uint32_t umod32(uint32_t x, uint32_t y) { return x % y; }
SCALAR_FUN_ATTR uint64_t umod64(uint64_t x, uint64_t y) { return x % y; }
SCALAR_FUN_ATTR uint8_t udiv_safe8(uint8_t x, uint8_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR uint16_t udiv_safe16(uint16_t x, uint16_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR uint32_t udiv_safe32(uint32_t x, uint32_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR uint64_t udiv_safe64(uint64_t x, uint64_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR uint8_t udiv_up_safe8(uint8_t x, uint8_t y) { return y == 0 ? 0 : (x + y - 1) / y; }
SCALAR_FUN_ATTR uint16_t udiv_up_safe16(uint16_t x, uint16_t y) { return y == 0 ? 0 : (x + y - 1) / y; }
SCALAR_FUN_ATTR uint32_t udiv_up_safe32(uint32_t x, uint32_t y) { return y == 0 ? 0 : (x + y - 1) / y; }
SCALAR_FUN_ATTR uint64_t udiv_up_safe64(uint64_t x, uint64_t y) { return y == 0 ? 0 : (x + y - 1) / y; }
SCALAR_FUN_ATTR uint8_t umod_safe8(uint8_t x, uint8_t y) { return y == 0 ? 0 : x % y; }
SCALAR_FUN_ATTR uint16_t umod_safe16(uint16_t x, uint16_t y) { return y == 0 ? 0 : x % y; }
SCALAR_FUN_ATTR uint32_t umod_safe32(uint32_t x, uint32_t y) { return y == 0 ? 0 : x % y; }
SCALAR_FUN_ATTR uint64_t umod_safe64(uint64_t x, uint64_t y) { return y == 0 ? 0 : x % y; }
SCALAR_FUN_ATTR int8_t sdiv8(int8_t x, int8_t y) {
int8_t q = x / y;
int8_t r = x % y;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int16_t sdiv16(int16_t x, int16_t y) {
int16_t q = x / y;
int16_t r = x % y;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int32_t sdiv32(int32_t x, int32_t y) {
int32_t q = x / y;
int32_t r = x % y;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int64_t sdiv64(int64_t x, int64_t y) {
int64_t q = x / y;
int64_t r = x % y;
return q - ((r != 0 && r < 0 != y < 0) ? 1 : 0);
}
SCALAR_FUN_ATTR int8_t sdiv_up8(int8_t x, int8_t y) { return sdiv8(x + y - 1, y); }
SCALAR_FUN_ATTR int16_t sdiv_up16(int16_t x, int16_t y) { return sdiv16(x + y - 1, y); }
SCALAR_FUN_ATTR int32_t sdiv_up32(int32_t x, int32_t y) { return sdiv32(x + y - 1, y); }
SCALAR_FUN_ATTR int64_t sdiv_up64(int64_t x, int64_t y) { return sdiv64(x + y - 1, y); }
SCALAR_FUN_ATTR int8_t smod8(int8_t x, int8_t y) {
int8_t r = x % y;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int16_t smod16(int16_t x, int16_t y) {
int16_t r = x % y;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int32_t smod32(int32_t x, int32_t y) {
int32_t r = x % y;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int64_t smod64(int64_t x, int64_t y) {
int64_t r = x % y;
return r + (r == 0 || (x > 0 && y > 0) || (x < 0 && y < 0) ? 0 : y);
}
SCALAR_FUN_ATTR int8_t sdiv_safe8(int8_t x, int8_t y) { return y == 0 ? 0 : sdiv8(x, y); }
SCALAR_FUN_ATTR int16_t sdiv_safe16(int16_t x, int16_t y) { return y == 0 ? 0 : sdiv16(x, y); }
SCALAR_FUN_ATTR int32_t sdiv_safe32(int32_t x, int32_t y) { return y == 0 ? 0 : sdiv32(x, y); }
SCALAR_FUN_ATTR int64_t sdiv_safe64(int64_t x, int64_t y) { return y == 0 ? 0 : sdiv64(x, y); }
SCALAR_FUN_ATTR int8_t sdiv_up_safe8(int8_t x, int8_t y) { return sdiv_safe8(x + y - 1, y);}
SCALAR_FUN_ATTR int16_t sdiv_up_safe16(int16_t x, int16_t y) { return sdiv_safe16(x + y - 1, y); }
SCALAR_FUN_ATTR int32_t sdiv_up_safe32(int32_t x, int32_t y) { return sdiv_safe32(x + y - 1, y); }
SCALAR_FUN_ATTR int64_t sdiv_up_safe64(int64_t x, int64_t y) { return sdiv_safe64(x + y - 1, y); }
SCALAR_FUN_ATTR int8_t smod_safe8(int8_t x, int8_t y) { return y == 0 ? 0 : smod8(x, y); }
SCALAR_FUN_ATTR int16_t smod_safe16(int16_t x, int16_t y) { return y == 0 ? 0 : smod16(x, y); }
SCALAR_FUN_ATTR int32_t smod_safe32(int32_t x, int32_t y) { return y == 0 ? 0 : smod32(x, y); }
SCALAR_FUN_ATTR int64_t smod_safe64(int64_t x, int64_t y) { return y == 0 ? 0 : smod64(x, y); }
SCALAR_FUN_ATTR int8_t squot8(int8_t x, int8_t y) { return x / y; }
SCALAR_FUN_ATTR int16_t squot16(int16_t x, int16_t y) { return x / y; }
SCALAR_FUN_ATTR int32_t squot32(int32_t x, int32_t y) { return x / y; }
SCALAR_FUN_ATTR int64_t squot64(int64_t x, int64_t y) { return x / y; }
SCALAR_FUN_ATTR int8_t srem8(int8_t x, int8_t y) { return x % y; }
SCALAR_FUN_ATTR int16_t srem16(int16_t x, int16_t y) { return x % y; }
SCALAR_FUN_ATTR int32_t srem32(int32_t x, int32_t y) { return x % y; }
SCALAR_FUN_ATTR int64_t srem64(int64_t x, int64_t y) { return x % y; }
SCALAR_FUN_ATTR int8_t squot_safe8(int8_t x, int8_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR int16_t squot_safe16(int16_t x, int16_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR int32_t squot_safe32(int32_t x, int32_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR int64_t squot_safe64(int64_t x, int64_t y) { return y == 0 ? 0 : x / y; }
SCALAR_FUN_ATTR int8_t srem_safe8(int8_t x, int8_t y) { return y == 0 ? 0 : x % y; }
SCALAR_FUN_ATTR int16_t srem_safe16(int16_t x, int16_t y) { return y == 0 ? 0 : x % y; }
SCALAR_FUN_ATTR int32_t srem_safe32(int32_t x, int32_t y) { return y == 0 ? 0 : x % y; }
SCALAR_FUN_ATTR int64_t srem_safe64(int64_t x, int64_t y) { return y == 0 ? 0 : x % y; }
#endif
SCALAR_FUN_ATTR int8_t smin8(int8_t x, int8_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR int16_t smin16(int16_t x, int16_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR int32_t smin32(int32_t x, int32_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR int64_t smin64(int64_t x, int64_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR uint8_t umin8(uint8_t x, uint8_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR uint16_t umin16(uint16_t x, uint16_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR uint32_t umin32(uint32_t x, uint32_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR uint64_t umin64(uint64_t x, uint64_t y) { return x < y ? x : y; }
SCALAR_FUN_ATTR int8_t smax8(int8_t x, int8_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR int16_t smax16(int16_t x, int16_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR int32_t smax32(int32_t x, int32_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR int64_t smax64(int64_t x, int64_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR uint8_t umax8(uint8_t x, uint8_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR uint16_t umax16(uint16_t x, uint16_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR uint32_t umax32(uint32_t x, uint32_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR uint64_t umax64(uint64_t x, uint64_t y) { return x < y ? y : x; }
SCALAR_FUN_ATTR uint8_t shl8(uint8_t x, uint8_t y) { return (uint8_t)(x << y); }
SCALAR_FUN_ATTR uint16_t shl16(uint16_t x, uint16_t y) { return (uint16_t)(x << y); }
SCALAR_FUN_ATTR uint32_t shl32(uint32_t x, uint32_t y) { return x << y; }
SCALAR_FUN_ATTR uint64_t shl64(uint64_t x, uint64_t y) { return x << y; }
SCALAR_FUN_ATTR uint8_t lshr8(uint8_t x, uint8_t y) { return x >> y; }
SCALAR_FUN_ATTR uint16_t lshr16(uint16_t x, uint16_t y) { return x >> y; }
SCALAR_FUN_ATTR uint32_t lshr32(uint32_t x, uint32_t y) { return x >> y; }
SCALAR_FUN_ATTR uint64_t lshr64(uint64_t x, uint64_t y) { return x >> y; }
SCALAR_FUN_ATTR int8_t ashr8(int8_t x, int8_t y) { return x >> y; }
SCALAR_FUN_ATTR int16_t ashr16(int16_t x, int16_t y) { return x >> y; }
SCALAR_FUN_ATTR int32_t ashr32(int32_t x, int32_t y) { return x >> y; }
SCALAR_FUN_ATTR int64_t ashr64(int64_t x, int64_t y) { return x >> y; }
SCALAR_FUN_ATTR uint8_t and8(uint8_t x, uint8_t y) { return x & y; }
SCALAR_FUN_ATTR uint16_t and16(uint16_t x, uint16_t y) { return x & y; }
SCALAR_FUN_ATTR uint32_t and32(uint32_t x, uint32_t y) { return x & y; }
SCALAR_FUN_ATTR uint64_t and64(uint64_t x, uint64_t y) { return x & y; }
SCALAR_FUN_ATTR uint8_t or8(uint8_t x, uint8_t y) { return x | y; }
SCALAR_FUN_ATTR uint16_t or16(uint16_t x, uint16_t y) { return x | y; }
SCALAR_FUN_ATTR uint32_t or32(uint32_t x, uint32_t y) { return x | y; }
SCALAR_FUN_ATTR uint64_t or64(uint64_t x, uint64_t y) { return x | y; }
SCALAR_FUN_ATTR uint8_t xor8(uint8_t x, uint8_t y) { return x ^ y; }
SCALAR_FUN_ATTR uint16_t xor16(uint16_t x, uint16_t y) { return x ^ y; }
SCALAR_FUN_ATTR uint32_t xor32(uint32_t x, uint32_t y) { return x ^ y; }
SCALAR_FUN_ATTR uint64_t xor64(uint64_t x, uint64_t y) { return x ^ y; }
SCALAR_FUN_ATTR bool ult8(uint8_t x, uint8_t y) { return x < y; }
SCALAR_FUN_ATTR bool ult16(uint16_t x, uint16_t y) { return x < y; }
SCALAR_FUN_ATTR bool ult32(uint32_t x, uint32_t y) { return x < y; }
SCALAR_FUN_ATTR bool ult64(uint64_t x, uint64_t y) { return x < y; }
SCALAR_FUN_ATTR bool ule8(uint8_t x, uint8_t y) { return x <= y; }
SCALAR_FUN_ATTR bool ule16(uint16_t x, uint16_t y) { return x <= y; }
SCALAR_FUN_ATTR bool ule32(uint32_t x, uint32_t y) { return x <= y; }
SCALAR_FUN_ATTR bool ule64(uint64_t x, uint64_t y) { return x <= y; }
SCALAR_FUN_ATTR bool slt8(int8_t x, int8_t y) { return x < y; }
SCALAR_FUN_ATTR bool slt16(int16_t x, int16_t y) { return x < y; }
SCALAR_FUN_ATTR bool slt32(int32_t x, int32_t y) { return x < y; }
SCALAR_FUN_ATTR bool slt64(int64_t x, int64_t y) { return x < y; }
SCALAR_FUN_ATTR bool sle8(int8_t x, int8_t y) { return x <= y; }
SCALAR_FUN_ATTR bool sle16(int16_t x, int16_t y) { return x <= y; }
SCALAR_FUN_ATTR bool sle32(int32_t x, int32_t y) { return x <= y; }
SCALAR_FUN_ATTR bool sle64(int64_t x, int64_t y) { return x <= y; }
SCALAR_FUN_ATTR uint8_t pow8(uint8_t x, uint8_t y) {
uint8_t res = 1, rem = y;
while (rem != 0) {
if (rem & 1)
res *= x;
rem >>= 1;
x *= x;
}
return res;
}
SCALAR_FUN_ATTR uint16_t pow16(uint16_t x, uint16_t y) {
uint16_t res = 1, rem = y;
while (rem != 0) {
if (rem & 1)
res *= x;
rem >>= 1;
x *= x;
}
return res;
}
SCALAR_FUN_ATTR uint32_t pow32(uint32_t x, uint32_t y) {
uint32_t res = 1, rem = y;
while (rem != 0) {
if (rem & 1)
res *= x;
rem >>= 1;
x *= x;
}
return res;
}
SCALAR_FUN_ATTR uint64_t pow64(uint64_t x, uint64_t y) {
uint64_t res = 1, rem = y;
while (rem != 0) {
if (rem & 1)
res *= x;
rem >>= 1;
x *= x;
}
return res;
}
SCALAR_FUN_ATTR bool itob_i8_bool(int8_t x) { return x != 0; }
SCALAR_FUN_ATTR bool itob_i16_bool(int16_t x) { return x != 0; }
SCALAR_FUN_ATTR bool itob_i32_bool(int32_t x) { return x != 0; }
SCALAR_FUN_ATTR bool itob_i64_bool(int64_t x) { return x != 0; }
SCALAR_FUN_ATTR int8_t btoi_bool_i8(bool x) { return x; }
SCALAR_FUN_ATTR int16_t btoi_bool_i16(bool x) { return x; }
SCALAR_FUN_ATTR int32_t btoi_bool_i32(bool x) { return x; }
SCALAR_FUN_ATTR int64_t btoi_bool_i64(bool x) { return x; }
#define sext_i8_i8(x) ((int8_t) (int8_t) (x))
#define sext_i8_i16(x) ((int16_t) (int8_t) (x))
#define sext_i8_i32(x) ((int32_t) (int8_t) (x))
#define sext_i8_i64(x) ((int64_t) (int8_t) (x))
#define sext_i16_i8(x) ((int8_t) (int16_t) (x))
#define sext_i16_i16(x) ((int16_t) (int16_t) (x))
#define sext_i16_i32(x) ((int32_t) (int16_t) (x))
#define sext_i16_i64(x) ((int64_t) (int16_t) (x))
#define sext_i32_i8(x) ((int8_t) (int32_t) (x))
#define sext_i32_i16(x) ((int16_t) (int32_t) (x))
#define sext_i32_i32(x) ((int32_t) (int32_t) (x))
#define sext_i32_i64(x) ((int64_t) (int32_t) (x))
#define sext_i64_i8(x) ((int8_t) (int64_t) (x))
#define sext_i64_i16(x) ((int16_t) (int64_t) (x))
#define sext_i64_i32(x) ((int32_t) (int64_t) (x))
#define sext_i64_i64(x) ((int64_t) (int64_t) (x))
#define zext_i8_i8(x) ((int8_t) (uint8_t) (x))
#define zext_i8_i16(x) ((int16_t) (uint8_t) (x))
#define zext_i8_i32(x) ((int32_t) (uint8_t) (x))
#define zext_i8_i64(x) ((int64_t) (uint8_t) (x))
#define zext_i16_i8(x) ((int8_t) (uint16_t) (x))
#define zext_i16_i16(x) ((int16_t) (uint16_t) (x))
#define zext_i16_i32(x) ((int32_t) (uint16_t) (x))
#define zext_i16_i64(x) ((int64_t) (uint16_t) (x))
#define zext_i32_i8(x) ((int8_t) (uint32_t) (x))
#define zext_i32_i16(x) ((int16_t) (uint32_t) (x))
#define zext_i32_i32(x) ((int32_t) (uint32_t) (x))
#define zext_i32_i64(x) ((int64_t) (uint32_t) (x))
#define zext_i64_i8(x) ((int8_t) (uint64_t) (x))
#define zext_i64_i16(x) ((int16_t) (uint64_t) (x))
#define zext_i64_i32(x) ((int32_t) (uint64_t) (x))
#define zext_i64_i64(x) ((int64_t) (uint64_t) (x))
SCALAR_FUN_ATTR int8_t abs8(int8_t x) { return (int8_t)abs(x); }
SCALAR_FUN_ATTR int16_t abs16(int16_t x) { return (int16_t)abs(x); }
SCALAR_FUN_ATTR int32_t abs32(int32_t x) { return abs(x); }
SCALAR_FUN_ATTR int64_t abs64(int64_t x) {
#if defined(__OPENCL_VERSION__) || defined(ISPC)
return abs(x);
#else
return llabs(x);
#endif
}
#if defined(__OPENCL_VERSION__)
SCALAR_FUN_ATTR int32_t futrts_popc8(int8_t x) { return popcount(x); }
SCALAR_FUN_ATTR int32_t futrts_popc16(int16_t x) { return popcount(x); }
SCALAR_FUN_ATTR int32_t futrts_popc32(int32_t x) { return popcount(x); }
SCALAR_FUN_ATTR int32_t futrts_popc64(int64_t x) { return popcount(x); }
#elif defined(__CUDA_ARCH__)
SCALAR_FUN_ATTR int32_t futrts_popc8(int8_t x) { return __popc(zext_i8_i32(x)); }
SCALAR_FUN_ATTR int32_t futrts_popc16(int16_t x) { return __popc(zext_i16_i32(x)); }
SCALAR_FUN_ATTR int32_t futrts_popc32(int32_t x) { return __popc(x); }
SCALAR_FUN_ATTR int32_t futrts_popc64(int64_t x) { return __popcll(x); }
#else // Not OpenCL or CUDA, but plain C.
SCALAR_FUN_ATTR int32_t futrts_popc8(uint8_t x) {
int c = 0;
for (; x; ++c) { x &= x - 1; }
return c;
}
SCALAR_FUN_ATTR int32_t futrts_popc16(uint16_t x) {
int c = 0;
for (; x; ++c) { x &= x - 1; }
return c;
}
SCALAR_FUN_ATTR int32_t futrts_popc32(uint32_t x) {
int c = 0;
for (; x; ++c) { x &= x - 1; }
return c;
}
SCALAR_FUN_ATTR int32_t futrts_popc64(uint64_t x) {
int c = 0;
for (; x; ++c) { x &= x - 1; }
return c;
}
#endif
#if defined(__OPENCL_VERSION__)
SCALAR_FUN_ATTR uint8_t futrts_umul_hi8 ( uint8_t a, uint8_t b) { return mul_hi(a, b); }
SCALAR_FUN_ATTR uint16_t futrts_umul_hi16(uint16_t a, uint16_t b) { return mul_hi(a, b); }
SCALAR_FUN_ATTR uint32_t futrts_umul_hi32(uint32_t a, uint32_t b) { return mul_hi(a, b); }
SCALAR_FUN_ATTR uint64_t futrts_umul_hi64(uint64_t a, uint64_t b) { return mul_hi(a, b); }
SCALAR_FUN_ATTR uint8_t futrts_smul_hi8 ( int8_t a, int8_t b) { return mul_hi(a, b); }
SCALAR_FUN_ATTR uint16_t futrts_smul_hi16(int16_t a, int16_t b) { return mul_hi(a, b); }
SCALAR_FUN_ATTR uint32_t futrts_smul_hi32(int32_t a, int32_t b) { return mul_hi(a, b); }
SCALAR_FUN_ATTR uint64_t futrts_smul_hi64(int64_t a, int64_t b) { return mul_hi(a, b); }
#elif defined(__CUDA_ARCH__)
SCALAR_FUN_ATTR uint8_t futrts_umul_hi8(uint8_t a, uint8_t b) { return ((uint16_t)a) * ((uint16_t)b) >> 8; }
SCALAR_FUN_ATTR uint16_t futrts_umul_hi16(uint16_t a, uint16_t b) { return ((uint32_t)a) * ((uint32_t)b) >> 16; }
SCALAR_FUN_ATTR uint32_t futrts_umul_hi32(uint32_t a, uint32_t b) { return __umulhi(a, b); }
SCALAR_FUN_ATTR uint64_t futrts_umul_hi64(uint64_t a, uint64_t b) { return __umul64hi(a, b); }
SCALAR_FUN_ATTR uint8_t futrts_smul_hi8 ( int8_t a, int8_t b) { return ((int16_t)a) * ((int16_t)b) >> 8; }
SCALAR_FUN_ATTR uint16_t futrts_smul_hi16(int16_t a, int16_t b) { return ((int32_t)a) * ((int32_t)b) >> 16; }
SCALAR_FUN_ATTR uint32_t futrts_smul_hi32(int32_t a, int32_t b) { return __mulhi(a, b); }
SCALAR_FUN_ATTR uint64_t futrts_smul_hi64(int64_t a, int64_t b) { return __mul64hi(a, b); }
#elif defined(ISPC)
SCALAR_FUN_ATTR uint8_t futrts_umul_hi8(uint8_t a, uint8_t b) { return ((uint16_t)a) * ((uint16_t)b) >> 8; }
SCALAR_FUN_ATTR uint16_t futrts_umul_hi16(uint16_t a, uint16_t b) { return ((uint32_t)a) * ((uint32_t)b) >> 16; }
SCALAR_FUN_ATTR uint32_t futrts_umul_hi32(uint32_t a, uint32_t b) { return ((uint64_t)a) * ((uint64_t)b) >> 32; }
SCALAR_FUN_ATTR uint64_t futrts_umul_hi64(uint64_t a, uint64_t b) {
uint64_t ah = a >> 32;
uint64_t al = a & 0xffffffff;
uint64_t bh = b >> 32;
uint64_t bl = b & 0xffffffff;
uint64_t p1 = al * bl;
uint64_t p2 = al * bh;
uint64_t p3 = ah * bl;
uint64_t p4 = ah * bh;
uint64_t p1h = p1 >> 32;
uint64_t p2h = p2 >> 32;
uint64_t p3h = p3 >> 32;
uint64_t p2l = p2 & 0xffffffff;
uint64_t p3l = p3 & 0xffffffff;
uint64_t l = p1h + p2l + p3l;
uint64_t m = (p2 >> 32) + (p3 >> 32);
uint64_t h = (l >> 32) + m + p4;
return h;
}
SCALAR_FUN_ATTR int8_t futrts_smul_hi8 ( int8_t a, int8_t b) { return ((uint16_t)a) * ((uint16_t)b) >> 8; }
SCALAR_FUN_ATTR int16_t futrts_smul_hi16(int16_t a, int16_t b) { return ((uint32_t)a) * ((uint32_t)b) >> 16; }
SCALAR_FUN_ATTR int32_t futrts_smul_hi32(int32_t a, int32_t b) { return ((uint64_t)a) * ((uint64_t)b) >> 32; }
SCALAR_FUN_ATTR int64_t futrts_smul_hi64(int64_t a, int64_t b) {
uint64_t ah = a >> 32;
uint64_t al = a & 0xffffffff;
uint64_t bh = b >> 32;
uint64_t bl = b & 0xffffffff;
uint64_t p1 = al * bl;
int64_t p2 = al * bh;
int64_t p3 = ah * bl;
uint64_t p4 = ah * bh;
uint64_t p1h = p1 >> 32;
uint64_t p2h = p2 >> 32;
uint64_t p3h = p3 >> 32;
uint64_t p2l = p2 & 0xffffffff;
uint64_t p3l = p3 & 0xffffffff;
uint64_t l = p1h + p2l + p3l;
uint64_t m = (p2 >> 32) + (p3 >> 32);
uint64_t h = (l >> 32) + m + p4;
return h;
}
#else // Not OpenCL, ISPC, or CUDA, but plain C.
SCALAR_FUN_ATTR uint8_t futrts_umul_hi8(uint8_t a, uint8_t b) { return ((uint16_t)a) * ((uint16_t)b) >> 8; }
SCALAR_FUN_ATTR uint16_t futrts_umul_hi16(uint16_t a, uint16_t b) { return ((uint32_t)a) * ((uint32_t)b) >> 16; }
SCALAR_FUN_ATTR uint32_t futrts_umul_hi32(uint32_t a, uint32_t b) { return ((uint64_t)a) * ((uint64_t)b) >> 32; }
SCALAR_FUN_ATTR uint64_t futrts_umul_hi64(uint64_t a, uint64_t b) { return ((__uint128_t)a) * ((__uint128_t)b) >> 64; }
SCALAR_FUN_ATTR int8_t futrts_smul_hi8(int8_t a, int8_t b) { return ((int16_t)a) * ((int16_t)b) >> 8; }
SCALAR_FUN_ATTR int16_t futrts_smul_hi16(int16_t a, int16_t b) { return ((int32_t)a) * ((int32_t)b) >> 16; }
SCALAR_FUN_ATTR int32_t futrts_smul_hi32(int32_t a, int32_t b) { return ((int64_t)a) * ((int64_t)b) >> 32; }
SCALAR_FUN_ATTR int64_t futrts_smul_hi64(int64_t a, int64_t b) { return ((__int128_t)a) * ((__int128_t)b) >> 64; }
#endif
#if defined(__OPENCL_VERSION__)
SCALAR_FUN_ATTR uint8_t futrts_umad_hi8 ( uint8_t a, uint8_t b, uint8_t c) { return mad_hi(a, b, c); }
SCALAR_FUN_ATTR uint16_t futrts_umad_hi16(uint16_t a, uint16_t b, uint16_t c) { return mad_hi(a, b, c); }
SCALAR_FUN_ATTR uint32_t futrts_umad_hi32(uint32_t a, uint32_t b, uint32_t c) { return mad_hi(a, b, c); }
SCALAR_FUN_ATTR uint64_t futrts_umad_hi64(uint64_t a, uint64_t b, uint64_t c) { return mad_hi(a, b, c); }
SCALAR_FUN_ATTR uint8_t futrts_smad_hi8( int8_t a, int8_t b, int8_t c) { return mad_hi(a, b, c); }
SCALAR_FUN_ATTR uint16_t futrts_smad_hi16(int16_t a, int16_t b, int16_t c) { return mad_hi(a, b, c); }
SCALAR_FUN_ATTR uint32_t futrts_smad_hi32(int32_t a, int32_t b, int32_t c) { return mad_hi(a, b, c); }
SCALAR_FUN_ATTR uint64_t futrts_smad_hi64(int64_t a, int64_t b, int64_t c) { return mad_hi(a, b, c); }
#else // Not OpenCL
SCALAR_FUN_ATTR uint8_t futrts_umad_hi8( uint8_t a, uint8_t b, uint8_t c) { return futrts_umul_hi8(a, b) + c; }
SCALAR_FUN_ATTR uint16_t futrts_umad_hi16(uint16_t a, uint16_t b, uint16_t c) { return futrts_umul_hi16(a, b) + c; }
SCALAR_FUN_ATTR uint32_t futrts_umad_hi32(uint32_t a, uint32_t b, uint32_t c) { return futrts_umul_hi32(a, b) + c; }
SCALAR_FUN_ATTR uint64_t futrts_umad_hi64(uint64_t a, uint64_t b, uint64_t c) { return futrts_umul_hi64(a, b) + c; }
SCALAR_FUN_ATTR uint8_t futrts_smad_hi8 ( int8_t a, int8_t b, int8_t c) { return futrts_smul_hi8(a, b) + c; }
SCALAR_FUN_ATTR uint16_t futrts_smad_hi16(int16_t a, int16_t b, int16_t c) { return futrts_smul_hi16(a, b) + c; }
SCALAR_FUN_ATTR uint32_t futrts_smad_hi32(int32_t a, int32_t b, int32_t c) { return futrts_smul_hi32(a, b) + c; }
SCALAR_FUN_ATTR uint64_t futrts_smad_hi64(int64_t a, int64_t b, int64_t c) { return futrts_smul_hi64(a, b) + c; }
#endif
#if defined(__OPENCL_VERSION__)
SCALAR_FUN_ATTR int32_t futrts_clzz8(int8_t x) { return clz(x); }
SCALAR_FUN_ATTR int32_t futrts_clzz16(int16_t x) { return clz(x); }
SCALAR_FUN_ATTR int32_t futrts_clzz32(int32_t x) { return clz(x); }
SCALAR_FUN_ATTR int32_t futrts_clzz64(int64_t x) { return clz(x); }
#elif defined(__CUDA_ARCH__)
SCALAR_FUN_ATTR int32_t futrts_clzz8(int8_t x) { return __clz(zext_i8_i32(x)) - 24; }
SCALAR_FUN_ATTR int32_t futrts_clzz16(int16_t x) { return __clz(zext_i16_i32(x)) - 16; }
SCALAR_FUN_ATTR int32_t futrts_clzz32(int32_t x) { return __clz(x); }
SCALAR_FUN_ATTR int32_t futrts_clzz64(int64_t x) { return __clzll(x); }
#elif defined(ISPC)
SCALAR_FUN_ATTR int32_t futrts_clzz8(int8_t x) { return count_leading_zeros((int32_t)(uint8_t)x)-24; }
SCALAR_FUN_ATTR int32_t futrts_clzz16(int16_t x) { return count_leading_zeros((int32_t)(uint16_t)x)-16; }
SCALAR_FUN_ATTR int32_t futrts_clzz32(int32_t x) { return count_leading_zeros(x); }
SCALAR_FUN_ATTR int32_t futrts_clzz64(int64_t x) { return count_leading_zeros(x); }
#else // Not OpenCL, ISPC or CUDA, but plain C.
SCALAR_FUN_ATTR int32_t futrts_clzz8(int8_t x)
{ return x == 0 ? 8 : __builtin_clz((uint32_t)zext_i8_i32(x)) - 24; }
SCALAR_FUN_ATTR int32_t futrts_clzz16(int16_t x)
{ return x == 0 ? 16 : __builtin_clz((uint32_t)zext_i16_i32(x)) - 16; }
SCALAR_FUN_ATTR int32_t futrts_clzz32(int32_t x)
{ return x == 0 ? 32 : __builtin_clz((uint32_t)x); }
SCALAR_FUN_ATTR int32_t futrts_clzz64(int64_t x)
{ return x == 0 ? 64 : __builtin_clzll((uint64_t)x); }
#endif
#if defined(__OPENCL_VERSION__)
SCALAR_FUN_ATTR int32_t futrts_ctzz8(int8_t x) {
int i = 0;
for (; i < 8 && (x & 1) == 0; i++, x >>= 1) ;
return i;
}
SCALAR_FUN_ATTR int32_t futrts_ctzz16(int16_t x) {
int i = 0;
for (; i < 16 && (x & 1) == 0; i++, x >>= 1) ;
return i;
}
SCALAR_FUN_ATTR int32_t futrts_ctzz32(int32_t x) {
int i = 0;
for (; i < 32 && (x & 1) == 0; i++, x >>= 1) ;
return i;
}
SCALAR_FUN_ATTR int32_t futrts_ctzz64(int64_t x) {
int i = 0;
for (; i < 64 && (x & 1) == 0; i++, x >>= 1) ;
return i;
}
#elif defined(__CUDA_ARCH__)
SCALAR_FUN_ATTR int32_t futrts_ctzz8(int8_t x) {
int y = __ffs(x);
return y == 0 ? 8 : y - 1;
}
SCALAR_FUN_ATTR int32_t futrts_ctzz16(int16_t x) {
int y = __ffs(x);
return y == 0 ? 16 : y - 1;
}
SCALAR_FUN_ATTR int32_t futrts_ctzz32(int32_t x) {
int y = __ffs(x);
return y == 0 ? 32 : y - 1;
}
SCALAR_FUN_ATTR int32_t futrts_ctzz64(int64_t x) {
int y = __ffsll(x);
return y == 0 ? 64 : y - 1;
}
#elif defined(ISPC)
SCALAR_FUN_ATTR int32_t futrts_ctzz8(int8_t x) { return x == 0 ? 8 : count_trailing_zeros((int32_t)x); }
SCALAR_FUN_ATTR int32_t futrts_ctzz16(int16_t x) { return x == 0 ? 16 : count_trailing_zeros((int32_t)x); }
SCALAR_FUN_ATTR int32_t futrts_ctzz32(int32_t x) { return count_trailing_zeros(x); }
SCALAR_FUN_ATTR int32_t futrts_ctzz64(int64_t x) { return count_trailing_zeros(x); }
#else // Not OpenCL or CUDA, but plain C.
SCALAR_FUN_ATTR int32_t futrts_ctzz8(int8_t x) { return x == 0 ? 8 : __builtin_ctz((uint32_t)x); }
SCALAR_FUN_ATTR int32_t futrts_ctzz16(int16_t x) { return x == 0 ? 16 : __builtin_ctz((uint32_t)x); }
SCALAR_FUN_ATTR int32_t futrts_ctzz32(int32_t x) { return x == 0 ? 32 : __builtin_ctz((uint32_t)x); }
SCALAR_FUN_ATTR int32_t futrts_ctzz64(int64_t x) { return x == 0 ? 64 : __builtin_ctzll((uint64_t)x); }
#endif
SCALAR_FUN_ATTR float fdiv32(float x, float y) { return x / y; }
SCALAR_FUN_ATTR float fadd32(float x, float y) { return x + y; }
SCALAR_FUN_ATTR float fsub32(float x, float y) { return x - y; }
SCALAR_FUN_ATTR float fmul32(float x, float y) { return x * y; }
SCALAR_FUN_ATTR bool cmplt32(float x, float y) { return x < y; }
SCALAR_FUN_ATTR bool cmple32(float x, float y) { return x <= y; }
SCALAR_FUN_ATTR float sitofp_i8_f32(int8_t x) { return (float) x; }
SCALAR_FUN_ATTR float sitofp_i16_f32(int16_t x) { return (float) x; }
SCALAR_FUN_ATTR float sitofp_i32_f32(int32_t x) { return (float) x; }
SCALAR_FUN_ATTR float sitofp_i64_f32(int64_t x) { return (float) x; }
SCALAR_FUN_ATTR float uitofp_i8_f32(uint8_t x) { return (float) x; }
SCALAR_FUN_ATTR float uitofp_i16_f32(uint16_t x) { return (float) x; }
SCALAR_FUN_ATTR float uitofp_i32_f32(uint32_t x) { return (float) x; }
SCALAR_FUN_ATTR float uitofp_i64_f32(uint64_t x) { return (float) x; }
#ifdef __OPENCL_VERSION__
SCALAR_FUN_ATTR float fabs32(float x) { return fabs(x); }
SCALAR_FUN_ATTR float fmax32(float x, float y) { return fmax(x, y); }
SCALAR_FUN_ATTR float fmin32(float x, float y) { return fmin(x, y); }
SCALAR_FUN_ATTR float fpow32(float x, float y) { return pow(x, y); }
#elif defined(ISPC)
SCALAR_FUN_ATTR float fabs32(float x) { return abs(x); }
SCALAR_FUN_ATTR float fmax32(float x, float y) { return isnan(x) ? y : isnan(y) ? x : max(x, y); }
SCALAR_FUN_ATTR float fmin32(float x, float y) { return isnan(x) ? y : isnan(y) ? x : min(x, y); }
SCALAR_FUN_ATTR float fpow32(float a, float b) {
float ret;
foreach_active (i) {
uniform float r = pow(extract(a, i), extract(b, i));
ret = insert(ret, i, r);
}
return ret;
}
#else // Not OpenCL, but CUDA or plain C.
SCALAR_FUN_ATTR float fabs32(float x) { return fabsf(x); }
SCALAR_FUN_ATTR float fmax32(float x, float y) { return fmaxf(x, y); }
SCALAR_FUN_ATTR float fmin32(float x, float y) { return fminf(x, y); }
SCALAR_FUN_ATTR float fpow32(float x, float y) { return powf(x, y); }
#endif
SCALAR_FUN_ATTR bool futrts_isnan32(float x) { return isnan(x); }
#if defined(ISPC)
SCALAR_FUN_ATTR bool futrts_isinf32(float x) { return !isnan(x) && isnan(x - x); }
SCALAR_FUN_ATTR bool futrts_isfinite32(float x) { return !isnan(x) && !futrts_isinf32(x); }
#else
SCALAR_FUN_ATTR bool futrts_isinf32(float x) { return isinf(x); }
#endif
SCALAR_FUN_ATTR int8_t fptosi_f32_i8(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (int8_t) x;
}
}
SCALAR_FUN_ATTR int16_t fptosi_f32_i16(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (int16_t) x;
}
}
SCALAR_FUN_ATTR int32_t fptosi_f32_i32(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (int32_t) x;
}
}
SCALAR_FUN_ATTR int64_t fptosi_f32_i64(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (int64_t) x;
};
}
SCALAR_FUN_ATTR uint8_t fptoui_f32_i8(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (uint8_t) (int8_t) x;
}
}
SCALAR_FUN_ATTR uint16_t fptoui_f32_i16(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (uint16_t) (int16_t) x;
}
}
SCALAR_FUN_ATTR uint32_t fptoui_f32_i32(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (uint32_t) (int32_t) x;
}
}
SCALAR_FUN_ATTR uint64_t fptoui_f32_i64(float x) {
if (futrts_isnan32(x) || futrts_isinf32(x)) {
return 0;
} else {
return (uint64_t) (int64_t) x;
}
}
SCALAR_FUN_ATTR bool ftob_f32_bool(float x) { return x != 0; }
SCALAR_FUN_ATTR float btof_bool_f32(bool x) { return x ? 1 : 0; }
#ifdef __OPENCL_VERSION__
SCALAR_FUN_ATTR float futrts_log32(float x) { return log(x); }
SCALAR_FUN_ATTR float futrts_log2_32(float x) { return log2(x); }
SCALAR_FUN_ATTR float futrts_log10_32(float x) { return log10(x); }
SCALAR_FUN_ATTR float futrts_log1p_32(float x) { return log1p(x); }
SCALAR_FUN_ATTR float futrts_sqrt32(float x) { return sqrt(x); }
SCALAR_FUN_ATTR float futrts_rsqrt32(float x) { return rsqrt(x); }
SCALAR_FUN_ATTR float futrts_cbrt32(float x) { return cbrt(x); }
SCALAR_FUN_ATTR float futrts_exp32(float x) { return exp(x); }
SCALAR_FUN_ATTR float futrts_cos32(float x) { return cos(x); }
SCALAR_FUN_ATTR float futrts_cospi32(float x) { return cospi(x); }
SCALAR_FUN_ATTR float futrts_sin32(float x) { return sin(x); }
SCALAR_FUN_ATTR float futrts_sinpi32(float x) { return sinpi(x); }
SCALAR_FUN_ATTR float futrts_tan32(float x) { return tan(x); }
SCALAR_FUN_ATTR float futrts_tanpi32(float x) { return tanpi(x); }
SCALAR_FUN_ATTR float futrts_acos32(float x) { return acos(x); }
SCALAR_FUN_ATTR float futrts_acospi32(float x) { return acospi(x); }
SCALAR_FUN_ATTR float futrts_asin32(float x) { return asin(x); }
SCALAR_FUN_ATTR float futrts_asinpi32(float x) { return asinpi(x); }
SCALAR_FUN_ATTR float futrts_atan32(float x) { return atan(x); }
SCALAR_FUN_ATTR float futrts_atanpi32(float x) { return atanpi(x); }
SCALAR_FUN_ATTR float futrts_cosh32(float x) { return cosh(x); }
SCALAR_FUN_ATTR float futrts_sinh32(float x) { return sinh(x); }
SCALAR_FUN_ATTR float futrts_tanh32(float x) { return tanh(x); }
SCALAR_FUN_ATTR float futrts_acosh32(float x) { return acosh(x); }
SCALAR_FUN_ATTR float futrts_asinh32(float x) { return asinh(x); }
SCALAR_FUN_ATTR float futrts_atanh32(float x) { return atanh(x); }
SCALAR_FUN_ATTR float futrts_atan2_32(float x, float y) { return atan2(x, y); }
SCALAR_FUN_ATTR float futrts_atan2pi_32(float x, float y) { return atan2pi(x, y); }
SCALAR_FUN_ATTR float futrts_hypot32(float x, float y) { return hypot(x, y); }
SCALAR_FUN_ATTR float futrts_gamma32(float x) { return tgamma(x); }
SCALAR_FUN_ATTR float futrts_lgamma32(float x) { return lgamma(x); }
SCALAR_FUN_ATTR float futrts_erf32(float x) { return erf(x); }
SCALAR_FUN_ATTR float futrts_erfc32(float x) { return erfc(x); }
SCALAR_FUN_ATTR float fmod32(float x, float y) { return fmod(x, y); }
SCALAR_FUN_ATTR float futrts_round32(float x) { return rint(x); }
SCALAR_FUN_ATTR float futrts_floor32(float x) { return floor(x); }
SCALAR_FUN_ATTR float futrts_ceil32(float x) { return ceil(x); }
SCALAR_FUN_ATTR float futrts_nextafter32(float x, float y) { return nextafter(x, y); }
SCALAR_FUN_ATTR float futrts_lerp32(float v0, float v1, float t) { return mix(v0, v1, t); }
SCALAR_FUN_ATTR float futrts_ldexp32(float x, int32_t y) { return ldexp(x, y); }
SCALAR_FUN_ATTR float futrts_copysign32(float x, float y) { return copysign(x, y); }
SCALAR_FUN_ATTR float futrts_mad32(float a, float b, float c) { return mad(a, b, c); }
SCALAR_FUN_ATTR float futrts_fma32(float a, float b, float c) { return fma(a, b, c); }
#elif defined(ISPC)
SCALAR_FUN_ATTR float futrts_log32(float x) { return futrts_isfinite32(x) || (futrts_isinf32(x) && x < 0)? log(x) : x; }
SCALAR_FUN_ATTR float futrts_log2_32(float x) { return futrts_log32(x) / log(2.0f); }
SCALAR_FUN_ATTR float futrts_log10_32(float x) { return futrts_log32(x) / log(10.0f); }
SCALAR_FUN_ATTR float futrts_log1p_32(float x) {
if(x == -1.0f || (futrts_isinf32(x) && x > 0.0f)) return x / 0.0f;
float y = 1.0f + x;
float z = y - 1.0f;
return log(y) - (z-x)/y;
}
SCALAR_FUN_ATTR float futrts_sqrt32(float x) { return sqrt(x); }
SCALAR_FUN_ATTR float futrts_rsqrt32(float x) { return 1/sqrt(x); }
extern "C" unmasked uniform float cbrtf(uniform float);
SCALAR_FUN_ATTR float futrts_cbrt32(float x) {
float res;
foreach_active (i) {
uniform float r = cbrtf(extract(x, i));
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR float futrts_exp32(float x) { return exp(x); }
SCALAR_FUN_ATTR float futrts_cos32(float x) { return cos(x); }
SCALAR_FUN_ATTR float futrts_cospi32(float x) { return cos((float)M_PI*x); }
SCALAR_FUN_ATTR float futrts_sin32(float x) { return sin(x); }
SCALAR_FUN_ATTR float futrts_sinpi32(float x) { return sin(M_PI*x); }
SCALAR_FUN_ATTR float futrts_tan32(float x) { return tan(x); }
SCALAR_FUN_ATTR float futrts_tanpi32(float x) { return tan((float)M_PI*x); }
SCALAR_FUN_ATTR float futrts_acos32(float x) { return acos(x); }
SCALAR_FUN_ATTR float futrts_acospi32(float x) { return acos(x)/(float)M_PI; }
SCALAR_FUN_ATTR float futrts_asin32(float x) { return asin(x); }
SCALAR_FUN_ATTR float futrts_asinpi32(float x) { return asin(x)/(float)M_PI; }
SCALAR_FUN_ATTR float futrts_atan32(float x) { return atan(x); }
SCALAR_FUN_ATTR float futrts_atanpi32(float x) { return atan(x)/(float)M_PI; }
SCALAR_FUN_ATTR float futrts_cosh32(float x) { return (exp(x)+exp(-x)) / 2.0f; }
SCALAR_FUN_ATTR float futrts_sinh32(float x) { return (exp(x)-exp(-x)) / 2.0f; }
SCALAR_FUN_ATTR float futrts_tanh32(float x) { return futrts_sinh32(x)/futrts_cosh32(x); }
SCALAR_FUN_ATTR float futrts_acosh32(float x) {
float f = x+sqrt(x*x-1);
if (futrts_isfinite32(f)) return log(f);
return f;
}
SCALAR_FUN_ATTR float futrts_asinh32(float x) {
float f = x+sqrt(x*x+1);
if (futrts_isfinite32(f)) return log(f);
return f;
}
SCALAR_FUN_ATTR float futrts_atanh32(float x) {
float f = (1+x)/(1-x);
if (futrts_isfinite32(f)) return log(f)/2.0f;
return f;
}
SCALAR_FUN_ATTR float futrts_atan2_32(float x, float y)
{ return (x == 0.0f && y == 0.0f) ? 0.0f : atan2(x, y); }
SCALAR_FUN_ATTR float futrts_atan2pi_32(float x, float y)
{ return (x == 0.0f && y == 0.0f) ? 0.0f : atan2(x, y) / (float)M_PI; }
SCALAR_FUN_ATTR float futrts_hypot32(float x, float y) {
if (futrts_isfinite32(x) && futrts_isfinite32(y)) {
x = abs(x);
y = abs(y);
float a;
float b;
if (x >= y){
a = x;
b = y;
} else {
a = y;
b = x;
}
if(b == 0){
return a;
}
int e;
float an;
float bn;
an = frexp (a, &e);
bn = ldexp (b, - e);
float cn;
cn = sqrt (an * an + bn * bn);
return ldexp (cn, e);
} else {
if (futrts_isinf32(x) || futrts_isinf32(y)) return INFINITY;
else return x + y;
}
}
extern "C" unmasked uniform float tgammaf(uniform float x);
SCALAR_FUN_ATTR float futrts_gamma32(float x) {
float res;
foreach_active (i) {
uniform float r = tgammaf(extract(x, i));
res = insert(res, i, r);
}
return res;
}
extern "C" unmasked uniform float lgammaf(uniform float x);
SCALAR_FUN_ATTR float futrts_lgamma32(float x) {
float res;
foreach_active (i) {
uniform float r = lgammaf(extract(x, i));
res = insert(res, i, r);
}
return res;
}
extern "C" unmasked uniform float erff(uniform float x);
SCALAR_FUN_ATTR float futrts_erf32(float x) {
float res;
foreach_active (i) {
uniform float r = erff(extract(x, i));
res = insert(res, i, r);
}
return res;
}
extern "C" unmasked uniform float erfcf(uniform float x);
SCALAR_FUN_ATTR float futrts_erfc32(float x) {
float res;
foreach_active (i) {
uniform float r = erfcf(extract(x, i));
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR float fmod32(float x, float y) { return x - y * trunc(x/y); }
SCALAR_FUN_ATTR float futrts_round32(float x) { return round(x); }
SCALAR_FUN_ATTR float futrts_floor32(float x) { return floor(x); }
SCALAR_FUN_ATTR float futrts_ceil32(float x) { return ceil(x); }
extern "C" unmasked uniform float nextafterf(uniform float x, uniform float y);
SCALAR_FUN_ATTR float futrts_nextafter32(float x, float y) {
float res;
foreach_active (i) {
uniform float r = nextafterf(extract(x, i), extract(y, i));
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR float futrts_lerp32(float v0, float v1, float t) {
return v0 + (v1 - v0) * t;
}
SCALAR_FUN_ATTR float futrts_ldexp32(float x, int32_t y) {
return x * pow((uniform float)2.0, (float)y);
}
SCALAR_FUN_ATTR float futrts_copysign32(float x, float y) {
int32_t xb = fptobits_f32_i32(x);
int32_t yb = fptobits_f32_i32(y);
return bitstofp_i32_f32((xb & ~(1<<31)) | (yb & (1<<31)));
}
SCALAR_FUN_ATTR float futrts_mad32(float a, float b, float c) {
return a * b + c;
}
SCALAR_FUN_ATTR float futrts_fma32(float a, float b, float c) {
return a * b + c;
}
#else // Not OpenCL or ISPC, but CUDA or plain C.
SCALAR_FUN_ATTR float futrts_log32(float x) { return logf(x); }
SCALAR_FUN_ATTR float futrts_log2_32(float x) { return log2f(x); }
SCALAR_FUN_ATTR float futrts_log10_32(float x) { return log10f(x); }
SCALAR_FUN_ATTR float futrts_log1p_32(float x) { return log1pf(x); }
SCALAR_FUN_ATTR float futrts_sqrt32(float x) { return sqrtf(x); }
SCALAR_FUN_ATTR float futrts_rsqrt32(float x) { return 1/sqrtf(x); }
SCALAR_FUN_ATTR float futrts_cbrt32(float x) { return cbrtf(x); }
SCALAR_FUN_ATTR float futrts_exp32(float x) { return expf(x); }
SCALAR_FUN_ATTR float futrts_cos32(float x) { return cosf(x); }
SCALAR_FUN_ATTR float futrts_cospi32(float x) {
#if defined(__CUDA_ARCH__)
return cospif(x);
#else
return cosf(((float)M_PI)*x);
#endif
}
SCALAR_FUN_ATTR float futrts_sin32(float x) { return sinf(x); }
SCALAR_FUN_ATTR float futrts_sinpi32(float x) {
#if defined(__CUDA_ARCH__)
return sinpif(x);
#else
return sinf((float)M_PI*x);
#endif
}
SCALAR_FUN_ATTR float futrts_tan32(float x) { return tanf(x); }
SCALAR_FUN_ATTR float futrts_tanpi32(float x) { return tanf((float)M_PI*x); }
SCALAR_FUN_ATTR float futrts_acos32(float x) { return acosf(x); }
SCALAR_FUN_ATTR float futrts_acospi32(float x) { return acosf(x)/(float)M_PI; }
SCALAR_FUN_ATTR float futrts_asin32(float x) { return asinf(x); }
SCALAR_FUN_ATTR float futrts_asinpi32(float x) { return asinf(x)/(float)M_PI; }
SCALAR_FUN_ATTR float futrts_atan32(float x) { return atanf(x); }
SCALAR_FUN_ATTR float futrts_atanpi32(float x) { return atanf(x)/(float)M_PI; }
SCALAR_FUN_ATTR float futrts_cosh32(float x) { return coshf(x); }
SCALAR_FUN_ATTR float futrts_sinh32(float x) { return sinhf(x); }
SCALAR_FUN_ATTR float futrts_tanh32(float x) { return tanhf(x); }
SCALAR_FUN_ATTR float futrts_acosh32(float x) { return acoshf(x); }
SCALAR_FUN_ATTR float futrts_asinh32(float x) { return asinhf(x); }
SCALAR_FUN_ATTR float futrts_atanh32(float x) { return atanhf(x); }
SCALAR_FUN_ATTR float futrts_atan2_32(float x, float y) { return atan2f(x, y); }
SCALAR_FUN_ATTR float futrts_atan2pi_32(float x, float y) { return atan2f(x, y) / (float)M_PI; }
SCALAR_FUN_ATTR float futrts_hypot32(float x, float y) { return hypotf(x, y); }
SCALAR_FUN_ATTR float futrts_gamma32(float x) { return tgammaf(x); }
SCALAR_FUN_ATTR float futrts_lgamma32(float x) { return lgammaf(x); }
SCALAR_FUN_ATTR float futrts_erf32(float x) { return erff(x); }
SCALAR_FUN_ATTR float futrts_erfc32(float x) { return erfcf(x); }
SCALAR_FUN_ATTR float fmod32(float x, float y) { return fmodf(x, y); }
SCALAR_FUN_ATTR float futrts_round32(float x) { return rintf(x); }
SCALAR_FUN_ATTR float futrts_floor32(float x) { return floorf(x); }
SCALAR_FUN_ATTR float futrts_ceil32(float x) { return ceilf(x); }
SCALAR_FUN_ATTR float futrts_nextafter32(float x, float y) { return nextafterf(x, y); }
SCALAR_FUN_ATTR float futrts_lerp32(float v0, float v1, float t) { return v0 + (v1 - v0) * t; }
SCALAR_FUN_ATTR float futrts_ldexp32(float x, int32_t y) { return ldexpf(x, y); }
SCALAR_FUN_ATTR float futrts_copysign32(float x, float y) { return copysignf(x, y); }
SCALAR_FUN_ATTR float futrts_mad32(float a, float b, float c) { return a * b + c; }
SCALAR_FUN_ATTR float futrts_fma32(float a, float b, float c) { return fmaf(a, b, c); }
#endif
#if defined(ISPC)
SCALAR_FUN_ATTR int32_t fptobits_f32_i32(float x) { return intbits(x); }
SCALAR_FUN_ATTR float bitstofp_i32_f32(int32_t x) { return floatbits(x); }
SCALAR_FUN_ATTR uniform int32_t fptobits_f32_i32(uniform float x) { return intbits(x); }
SCALAR_FUN_ATTR uniform float bitstofp_i32_f32(uniform int32_t x) { return floatbits(x); }
#else
SCALAR_FUN_ATTR int32_t fptobits_f32_i32(float x) {
union {
float f;
int32_t t;
} p;
p.f = x;
return p.t;
}
SCALAR_FUN_ATTR float bitstofp_i32_f32(int32_t x) {
union {
int32_t f;
float t;
} p;
p.f = x;
return p.t;
}
#endif
SCALAR_FUN_ATTR float fsignum32(float x) {
return futrts_isnan32(x) ? x : (x > 0 ? 1 : 0) - (x < 0 ? 1 : 0);
}
#ifdef FUTHARK_F64_ENABLED
SCALAR_FUN_ATTR double bitstofp_i64_f64(int64_t x);
SCALAR_FUN_ATTR int64_t fptobits_f64_i64(double x);
#if defined(ISPC)
SCALAR_FUN_ATTR bool futrts_isinf64(double x) { return !isnan(x) && isnan(x - x); }
SCALAR_FUN_ATTR bool futrts_isfinite64(double x) { return !isnan(x) && !futrts_isinf64(x); }
SCALAR_FUN_ATTR double fdiv64(double x, double y) { return x / y; }
SCALAR_FUN_ATTR double fadd64(double x, double y) { return x + y; }
SCALAR_FUN_ATTR double fsub64(double x, double y) { return x - y; }
SCALAR_FUN_ATTR double fmul64(double x, double y) { return x * y; }
SCALAR_FUN_ATTR bool cmplt64(double x, double y) { return x < y; }
SCALAR_FUN_ATTR bool cmple64(double x, double y) { return x <= y; }
SCALAR_FUN_ATTR double sitofp_i8_f64(int8_t x) { return (double) x; }
SCALAR_FUN_ATTR double sitofp_i16_f64(int16_t x) { return (double) x; }
SCALAR_FUN_ATTR double sitofp_i32_f64(int32_t x) { return (double) x; }
SCALAR_FUN_ATTR double sitofp_i64_f64(int64_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i8_f64(uint8_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i16_f64(uint16_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i32_f64(uint32_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i64_f64(uint64_t x) { return (double) x; }
SCALAR_FUN_ATTR double fabs64(double x) { return abs(x); }
SCALAR_FUN_ATTR double fmax64(double x, double y) { return isnan(x) ? y : isnan(y) ? x : max(x, y); }
SCALAR_FUN_ATTR double fmin64(double x, double y) { return isnan(x) ? y : isnan(y) ? x : min(x, y); }
SCALAR_FUN_ATTR double fpow64(double a, double b) {
float ret;
foreach_active (i) {
uniform float r = pow(extract(a, i), extract(b, i));
ret = insert(ret, i, r);
}
return ret;
}
SCALAR_FUN_ATTR double futrts_log64(double x) { return futrts_isfinite64(x) || (futrts_isinf64(x) && x < 0)? log(x) : x; }
SCALAR_FUN_ATTR double futrts_log2_64(double x) { return futrts_log64(x)/log(2.0d); }
SCALAR_FUN_ATTR double futrts_log10_64(double x) { return futrts_log64(x)/log(10.0d); }
SCALAR_FUN_ATTR double futrts_log1p_64(double x) {
if(x == -1.0d || (futrts_isinf64(x) && x > 0.0d)) return x / 0.0d;
double y = 1.0d + x;
double z = y - 1.0d;
return log(y) - (z-x)/y;
}
SCALAR_FUN_ATTR double futrts_sqrt64(double x) { return sqrt(x); }
SCALAR_FUN_ATTR double futrts_rsqrt64(double x) { return 1/sqrt(x); }
SCALAR_FUN_ATTR double futrts_cbrt64(double x) {
double res;
foreach_active (i) {
uniform double r = cbrtf(extract(x, i));
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR double futrts_exp64(double x) { return exp(x); }
SCALAR_FUN_ATTR double futrts_cos64(double x) { return cos(x); }
SCALAR_FUN_ATTR double futrts_cospi64(double x) { return cos(M_PI*x); }
SCALAR_FUN_ATTR double futrts_sin64(double x) { return sin(x); }
SCALAR_FUN_ATTR double futrts_sinpi64(double x) { return sin(M_PI*x); }
SCALAR_FUN_ATTR double futrts_tan64(double x) { return tan(x); }
SCALAR_FUN_ATTR double futrts_tanpi64(double x) { return tan(M_PI*x); }
SCALAR_FUN_ATTR double futrts_acos64(double x) { return acos(x); }
SCALAR_FUN_ATTR double futrts_acospi64(double x) { return acos(x)/M_PI; }
SCALAR_FUN_ATTR double futrts_asin64(double x) { return asin(x); }
SCALAR_FUN_ATTR double futrts_asinpi64(double x) { return asin(x)/M_PI; }
SCALAR_FUN_ATTR double futrts_atan64(double x) { return atan(x); }
SCALAR_FUN_ATTR double futrts_atanpi64(double x) { return atan(x)/M_PI; }
SCALAR_FUN_ATTR double futrts_cosh64(double x) { return (exp(x)+exp(-x)) / 2.0d; }
SCALAR_FUN_ATTR double futrts_sinh64(double x) { return (exp(x)-exp(-x)) / 2.0d; }
SCALAR_FUN_ATTR double futrts_tanh64(double x) { return futrts_sinh64(x)/futrts_cosh64(x); }
SCALAR_FUN_ATTR double futrts_acosh64(double x) {
double f = x+sqrt(x*x-1.0d);
if(futrts_isfinite64(f)) return log(f);
return f;
}
SCALAR_FUN_ATTR double futrts_asinh64(double x) {
double f = x+sqrt(x*x+1.0d);
if(futrts_isfinite64(f)) return log(f);
return f;
}
SCALAR_FUN_ATTR double futrts_atanh64(double x) {
double f = (1.0d+x)/(1.0d-x);
if(futrts_isfinite64(f)) return log(f)/2.0d;
return f;
}
SCALAR_FUN_ATTR double futrts_atan2_64(double x, double y) { return atan2(x, y); }
SCALAR_FUN_ATTR double futrts_atan2pi_64(double x, double y) { return atan2(x, y) / M_PI; }
extern "C" unmasked uniform double hypot(uniform double x, uniform double y);
SCALAR_FUN_ATTR double futrts_hypot64(double x, double y) {
double res;
foreach_active (i) {
uniform double r = hypot(extract(x, i), extract(y, i));
res = insert(res, i, r);
}
return res;
}
extern "C" unmasked uniform double tgamma(uniform double x);
SCALAR_FUN_ATTR double futrts_gamma64(double x) {
double res;
foreach_active (i) {
uniform double r = tgamma(extract(x, i));
res = insert(res, i, r);
}
return res;
}
extern "C" unmasked uniform double lgamma(uniform double x);
SCALAR_FUN_ATTR double futrts_lgamma64(double x) {
double res;
foreach_active (i) {
uniform double r = lgamma(extract(x, i));
res = insert(res, i, r);
}
return res;
}
extern "C" unmasked uniform double erf(uniform double x);
SCALAR_FUN_ATTR double futrts_erf64(double x) {
double res;
foreach_active (i) {
uniform double r = erf(extract(x, i));
res = insert(res, i, r);
}
return res;
}
extern "C" unmasked uniform double erfc(uniform double x);
SCALAR_FUN_ATTR double futrts_erfc64(double x) {
double res;
foreach_active (i) {
uniform double r = erfc(extract(x, i));
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR double futrts_fma64(double a, double b, double c) { return a * b + c; }
SCALAR_FUN_ATTR double futrts_round64(double x) { return round(x); }
SCALAR_FUN_ATTR double futrts_ceil64(double x) { return ceil(x); }
extern "C" unmasked uniform double nextafter(uniform float x, uniform double y);
SCALAR_FUN_ATTR double futrts_nextafter64(double x, double y) {
double res;
foreach_active (i) {
uniform double r = nextafter(extract(x, i), extract(y, i));
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR double futrts_floor64(double x) { return floor(x); }
SCALAR_FUN_ATTR bool futrts_isnan64(double x) { return isnan(x); }
SCALAR_FUN_ATTR int8_t fptosi_f64_i8(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int8_t) x;
}
}
SCALAR_FUN_ATTR int16_t fptosi_f64_i16(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int16_t) x;
}
}
SCALAR_FUN_ATTR int32_t fptosi_f64_i32(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int32_t) x;
}
}
SCALAR_FUN_ATTR int64_t fptosi_f64_i64(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int64_t) x;
}
}
SCALAR_FUN_ATTR uint8_t fptoui_f64_i8(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint8_t) (int8_t) x;
}
}
SCALAR_FUN_ATTR uint16_t fptoui_f64_i16(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint16_t) (int16_t) x;
}
}
SCALAR_FUN_ATTR uint32_t fptoui_f64_i32(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint32_t) (int32_t) x;
}
}
SCALAR_FUN_ATTR uint64_t fptoui_f64_i64(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint64_t) (int64_t) x;
}
}
SCALAR_FUN_ATTR bool ftob_f64_bool(double x) { return x != 0.0; }
SCALAR_FUN_ATTR double btof_bool_f64(bool x) { return x ? 1.0 : 0.0; }
SCALAR_FUN_ATTR int64_t fptobits_f64_i64(double x) {
int64_t res;
foreach_active (i) {
uniform double tmp = extract(x, i);
uniform int64_t r = *((uniform int64_t* uniform)&tmp);
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR double bitstofp_i64_f64(int64_t x) {
double res;
foreach_active (i) {
uniform int64_t tmp = extract(x, i);
uniform double r = *((uniform double* uniform)&tmp);
res = insert(res, i, r);
}
return res;
}
SCALAR_FUN_ATTR uniform int64_t fptobits_f64_i64(uniform double x) {
return intbits(x);
}
SCALAR_FUN_ATTR uniform double bitstofp_i64_f64(uniform int64_t x) {
return doublebits(x);
}
SCALAR_FUN_ATTR double fmod64(double x, double y) {
return x - y * trunc(x/y);
}
SCALAR_FUN_ATTR double fsignum64(double x) {
return futrts_isnan64(x) ? x : (x > 0 ? 1.0d : 0.0d) - (x < 0 ? 1.0d : 0.0d);
}
SCALAR_FUN_ATTR double futrts_lerp64(double v0, double v1, double t) {
return v0 + (v1 - v0) * t;
}
SCALAR_FUN_ATTR double futrts_ldexp64(double x, int32_t y) {
return x * pow((uniform double)2.0, (double)y);
}
SCALAR_FUN_ATTR double futrts_copysign64(double x, double y) {
int64_t xb = fptobits_f64_i64(x);
int64_t yb = fptobits_f64_i64(y);
return bitstofp_i64_f64((xb & ~(((int64_t)1)<<63)) | (yb & (((int64_t)1)<<63)));
}
SCALAR_FUN_ATTR double futrts_mad64(double a, double b, double c) { return a * b + c; }
SCALAR_FUN_ATTR float fpconv_f32_f32(float x) { return (float) x; }
SCALAR_FUN_ATTR double fpconv_f32_f64(float x) { return (double) x; }
SCALAR_FUN_ATTR float fpconv_f64_f32(double x) { return (float) x; }
SCALAR_FUN_ATTR double fpconv_f64_f64(double x) { return (double) x; }
#else
SCALAR_FUN_ATTR double fdiv64(double x, double y) { return x / y; }
SCALAR_FUN_ATTR double fadd64(double x, double y) { return x + y; }
SCALAR_FUN_ATTR double fsub64(double x, double y) { return x - y; }
SCALAR_FUN_ATTR double fmul64(double x, double y) { return x * y; }
SCALAR_FUN_ATTR bool cmplt64(double x, double y) { return x < y; }
SCALAR_FUN_ATTR bool cmple64(double x, double y) { return x <= y; }
SCALAR_FUN_ATTR double sitofp_i8_f64(int8_t x) { return (double) x; }
SCALAR_FUN_ATTR double sitofp_i16_f64(int16_t x) { return (double) x; }
SCALAR_FUN_ATTR double sitofp_i32_f64(int32_t x) { return (double) x; }
SCALAR_FUN_ATTR double sitofp_i64_f64(int64_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i8_f64(uint8_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i16_f64(uint16_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i32_f64(uint32_t x) { return (double) x; }
SCALAR_FUN_ATTR double uitofp_i64_f64(uint64_t x) { return (double) x; }
SCALAR_FUN_ATTR double fabs64(double x) { return fabs(x); }
SCALAR_FUN_ATTR double fmax64(double x, double y) { return fmax(x, y); }
SCALAR_FUN_ATTR double fmin64(double x, double y) { return fmin(x, y); }
SCALAR_FUN_ATTR double fpow64(double x, double y) { return pow(x, y); }
SCALAR_FUN_ATTR double futrts_log64(double x) { return log(x); }
SCALAR_FUN_ATTR double futrts_log2_64(double x) { return log2(x); }
SCALAR_FUN_ATTR double futrts_log10_64(double x) { return log10(x); }
SCALAR_FUN_ATTR double futrts_log1p_64(double x) { return log1p(x); }
SCALAR_FUN_ATTR double futrts_sqrt64(double x) { return sqrt(x); }
SCALAR_FUN_ATTR double futrts_rsqrt64(double x) { return 1/sqrt(x); }
SCALAR_FUN_ATTR double futrts_cbrt64(double x) { return cbrt(x); }
SCALAR_FUN_ATTR double futrts_exp64(double x) { return exp(x); }
SCALAR_FUN_ATTR double futrts_cos64(double x) { return cos(x); }
SCALAR_FUN_ATTR double futrts_cospi64(double x) {
#ifdef __OPENCL_VERSION__
return cospi(x);
#elif defined(__CUDA_ARCH__)
return cospi(x);
#else
return cos(M_PI*x);
#endif
}
SCALAR_FUN_ATTR double futrts_sin64(double x) {
return sin(x);
}
SCALAR_FUN_ATTR double futrts_sinpi64(double x) {
#ifdef __OPENCL_VERSION__
return sinpi(x);
#elif defined(__CUDA_ARCH__)
return sinpi(x);
#else
return sin(M_PI*x);
#endif
}
SCALAR_FUN_ATTR double futrts_tan64(double x) {
return tan(x);
}
SCALAR_FUN_ATTR double futrts_tanpi64(double x) {
#ifdef __OPENCL_VERSION__
return tanpi(x);
#else
return tan(M_PI*x);
#endif
}
SCALAR_FUN_ATTR double futrts_acos64(double x) {
return acos(x);
}
SCALAR_FUN_ATTR double futrts_acospi64(double x) {
#ifdef __OPENCL_VERSION__
return acospi(x);
#else
return acos(x) / M_PI;
#endif
}
SCALAR_FUN_ATTR double futrts_asin64(double x) {
return asin(x);
}
SCALAR_FUN_ATTR double futrts_asinpi64(double x) {
#ifdef __OPENCL_VERSION__
return asinpi(x);
#else
return asin(x) / M_PI;
#endif
}
SCALAR_FUN_ATTR double futrts_atan64(double x) {
return atan(x);
}
SCALAR_FUN_ATTR double futrts_atanpi64(double x) {
#ifdef __OPENCL_VERSION__
return atanpi(x);
#else
return atan(x) / M_PI;
#endif
}
SCALAR_FUN_ATTR double futrts_cosh64(double x) { return cosh(x); }
SCALAR_FUN_ATTR double futrts_sinh64(double x) { return sinh(x); }
SCALAR_FUN_ATTR double futrts_tanh64(double x) { return tanh(x); }
SCALAR_FUN_ATTR double futrts_acosh64(double x) { return acosh(x); }
SCALAR_FUN_ATTR double futrts_asinh64(double x) { return asinh(x); }
SCALAR_FUN_ATTR double futrts_atanh64(double x) { return atanh(x); }
SCALAR_FUN_ATTR double futrts_atan2_64(double x, double y) { return atan2(x, y); }
SCALAR_FUN_ATTR double futrts_atan2pi_64(double x, double y) {
#ifdef __OPENCL_VERSION__
return atan2pi(x, y);
#else
return atan2(x, y) / M_PI;
#endif
}
SCALAR_FUN_ATTR double futrts_hypot64(double x, double y) { return hypot(x, y); }
SCALAR_FUN_ATTR double futrts_gamma64(double x) { return tgamma(x); }
SCALAR_FUN_ATTR double futrts_lgamma64(double x) { return lgamma(x); }
SCALAR_FUN_ATTR double futrts_erf64(double x) { return erf(x); }
SCALAR_FUN_ATTR double futrts_erfc64(double x) { return erfc(x); }
SCALAR_FUN_ATTR double futrts_fma64(double a, double b, double c) { return fma(a, b, c); }
SCALAR_FUN_ATTR double futrts_round64(double x) { return rint(x); }
SCALAR_FUN_ATTR double futrts_ceil64(double x) { return ceil(x); }
SCALAR_FUN_ATTR double futrts_nextafter64(double x, double y) { return nextafter(x, y); }
SCALAR_FUN_ATTR double futrts_floor64(double x) { return floor(x); }
SCALAR_FUN_ATTR bool futrts_isnan64(double x) { return isnan(x); }
SCALAR_FUN_ATTR bool futrts_isinf64(double x) { return isinf(x); }
SCALAR_FUN_ATTR int8_t fptosi_f64_i8(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int8_t) x;
}
}
SCALAR_FUN_ATTR int16_t fptosi_f64_i16(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int16_t) x;
}
}
SCALAR_FUN_ATTR int32_t fptosi_f64_i32(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int32_t) x;
}
}
SCALAR_FUN_ATTR int64_t fptosi_f64_i64(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (int64_t) x;
}
}
SCALAR_FUN_ATTR uint8_t fptoui_f64_i8(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint8_t) (int8_t) x;
}
}
SCALAR_FUN_ATTR uint16_t fptoui_f64_i16(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint16_t) (int16_t) x;
}
}
SCALAR_FUN_ATTR uint32_t fptoui_f64_i32(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint32_t) (int32_t) x;
}
}
SCALAR_FUN_ATTR uint64_t fptoui_f64_i64(double x) {
if (futrts_isnan64(x) || futrts_isinf64(x)) {
return 0;
} else {
return (uint64_t) (int64_t) x;
}
}
SCALAR_FUN_ATTR bool ftob_f64_bool(double x) { return x != 0; }
SCALAR_FUN_ATTR double btof_bool_f64(bool x) { return x ? 1 : 0; }
SCALAR_FUN_ATTR int64_t fptobits_f64_i64(double x) {
union {
double f;
int64_t t;
} p;
p.f = x;
return p.t;
}
SCALAR_FUN_ATTR double bitstofp_i64_f64(int64_t x) {
union {
int64_t f;
double t;
} p;
p.f = x;
return p.t;
}
SCALAR_FUN_ATTR double fmod64(double x, double y) {
return fmod(x, y);
}
SCALAR_FUN_ATTR double fsignum64(double x) {
return futrts_isnan64(x) ? x : (x > 0) - (x < 0);
}
SCALAR_FUN_ATTR double futrts_lerp64(double v0, double v1, double t) {
#ifdef __OPENCL_VERSION__
return mix(v0, v1, t);
#else
return v0 + (v1 - v0) * t;
#endif
}
SCALAR_FUN_ATTR double futrts_ldexp64(double x, int32_t y) {
return ldexp(x, y);
}
SCALAR_FUN_ATTR double futrts_copysign64(double x, double y) {
return copysign(x, y);
}
SCALAR_FUN_ATTR double futrts_mad64(double a, double b, double c) {
#ifdef __OPENCL_VERSION__
return mad(a, b, c);
#else
return a * b + c;
#endif
}
SCALAR_FUN_ATTR float fpconv_f32_f32(float x) { return (float) x; }
SCALAR_FUN_ATTR double fpconv_f32_f64(float x) { return (double) x; }
SCALAR_FUN_ATTR float fpconv_f64_f32(double x) { return (float) x; }
SCALAR_FUN_ATTR double fpconv_f64_f64(double x) { return (double) x; }
#endif
#endif
#define futrts_cond_f16(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_f32(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_f64(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_i8(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_i16(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_i32(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_i64(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_bool(x,y,z) ((x) ? (y) : (z))
#define futrts_cond_unit(x,y,z) ((x) ? (y) : (z))
// End of scalar.h.