def _gauss_impl(context, builder, sig, args, state):
# The type for all computations (either float or double)
ty = sig.return_type
llty = context.get_data_type(ty)
state_ptr = get_state_ptr(context, builder, state)
_random = {"py": random.random,
"np": np.random.random}[state]
ret = cgutils.alloca_once(builder, llty, name="result")
gauss_ptr = get_gauss_ptr(builder, state_ptr)
has_gauss_ptr = get_has_gauss_ptr(builder, state_ptr)
has_gauss = cgutils.is_true(builder, builder.load(has_gauss_ptr))
with cgutils.ifelse(builder, has_gauss) as (then, otherwise):
with then:
# if has_gauss: return it
builder.store(builder.load(gauss_ptr), ret)
builder.store(const_int(0), has_gauss_ptr)
with otherwise:
# if not has_gauss: compute a pair of numbers using the Box-Muller
# transform; keep one and return the other
pair = context.compile_internal(builder,
_gauss_pair_impl(_random),
signature(types.UniTuple(ty, 2)),
())
first, second = cgutils.unpack_tuple(builder, pair, 2)
builder.store(first, gauss_ptr)
builder.store(second, ret)
builder.store(const_int(1), has_gauss_ptr)
mu, sigma = args
return builder.fadd(mu,
builder.fmul(sigma, builder.load(ret)))
def timedelta_abs_impl(context, builder, sig, args):
val, = args
ret = alloc_timedelta_result(builder)
with cgutils.ifelse(builder,
cgutils.is_scalar_neg(builder, val)) as (then, otherwise):
with then:
builder.store(builder.neg(val), ret)
with otherwise:
builder.store(val, ret)
return builder.load(ret)
开发者ID:genba,项目名称:numba,代码行数:10,代码来源:npdatetime.py
示例9: year_to_days
def year_to_days(builder, year_val):
"""
Given a year *year_val* (offset to 1970), return the number of days
since the 1970 epoch.
"""
# The algorithm below is copied from Numpy's get_datetimestruct_days()
# (src/multiarray/datetime.c)
ret = cgutils.alloca_once(builder, TIMEDELTA64)
# First approximation
days = scale_by_constant(builder, year_val, 365)
# Adjust for leap years
with cgutils.ifelse(builder, cgutils.is_neg_int(builder, year_val)) \
as (if_neg, if_pos):
with if_pos:
# At or after 1970:
# 1968 is the closest leap year before 1970.
# Exclude the current year, so add 1.
from_1968 = add_constant(builder, year_val, 1)
# Add one day for each 4 years
p_days = builder.add(days,
unscale_by_constant(builder, from_1968, 4))
# 1900 is the closest previous year divisible by 100
from_1900 = add_constant(builder, from_1968, 68)
# Subtract one day for each 100 years
p_days = builder.sub(p_days,
unscale_by_constant(builder, from_1900, 100))
# 1600 is the closest previous year divisible by 400
from_1600 = add_constant(builder, from_1900, 300)
# Add one day for each 400 years
p_days = builder.add(p_days,
unscale_by_constant(builder, from_1600, 400))
builder.store(p_days, ret)
with if_neg:
# Before 1970:
# NOTE `year_val` is negative, and so will be `from_1972` and `from_2000`.
# 1972 is the closest later year after 1970.
# Include the current year, so subtract 2.
from_1972 = add_constant(builder, year_val, -2)
# Subtract one day for each 4 years (`from_1972` is negative)
n_days = builder.add(days,
unscale_by_constant(builder, from_1972, 4))
# 2000 is the closest later year divisible by 100
from_2000 = add_constant(builder, from_1972, -28)
# Add one day for each 100 years
n_days = builder.sub(n_days,
unscale_by_constant(builder, from_2000, 100))
# 2000 is also the closest later year divisible by 400
# Subtract one day for each 400 years
n_days = builder.add(n_days,
unscale_by_constant(builder, from_2000, 400))
builder.store(n_days, ret)
return builder.load(ret)
开发者ID:genba,项目名称:numba,代码行数:52,代码来源:npdatetime.py
示例10: store
def store(retval):
is_error = cgutils.is_null(builder, retval)
with cgutils.ifelse(builder, is_error) as (if_error, if_ok):
with if_error:
msg = context.insert_const_string(pyapi.module,
"object mode ufunc")
msgobj = pyapi.string_from_string(msg)
pyapi.err_write_unraisable(msgobj)
pyapi.decref(msgobj)
with if_ok:
# Unbox
retval = pyapi.to_native_value(retval, signature.return_type)
# Store
out.store_direct(retval, builder.load(store_offset))
def impl(context, builder, sig, args):
[va, vb] = args
[ta, tb] = sig.args
ret = alloc_boolean_result(builder)
with cgutils.ifelse(builder, are_not_nat(builder, [va, vb])) as (then, otherwise):
with then:
norm_a, norm_b = normalize_timedeltas(context, builder, va, vb, ta, tb)
builder.store(builder.icmp(ll_op, norm_a, norm_b), ret)
with otherwise:
# No scaling when comparing NaT with something else
# (i.e. NaT is <= everything else, since it's the smallest
# int64 value)
builder.store(builder.icmp(ll_op, va, vb), ret)
return builder.load(ret)
开发者ID:genba,项目名称:numba,代码行数:14,代码来源:npdatetime.py
示例12: from_range_state
def from_range_state(cls, context, builder, state):
"""
Create a RangeIter initialized from the given RangeState *state*.
"""
self = cls(context, builder)
start = state.start
stop = state.stop
step = state.step
startptr = cgutils.alloca_once(builder, start.type)
builder.store(start, startptr)
countptr = cgutils.alloca_once(builder, start.type)
self.iter = startptr
self.stop = stop
self.step = step
self.count = countptr
diff = builder.sub(stop, start)
zero = context.get_constant(int_type, 0)
one = context.get_constant(int_type, 1)
pos_diff = builder.icmp(lc.ICMP_SGT, diff, zero)
pos_step = builder.icmp(lc.ICMP_SGT, step, zero)
sign_differs = builder.xor(pos_diff, pos_step)
zero_step = builder.icmp(lc.ICMP_EQ, step, zero)
with cgutils.if_unlikely(builder, zero_step):
# step shouldn't be zero
context.call_conv.return_user_exc(builder, ValueError,
("range() arg 3 must not be zero",))
with cgutils.ifelse(builder, sign_differs) as (then, orelse):
with then:
builder.store(zero, self.count)
with orelse:
rem = builder.srem(diff, step)
rem = builder.select(pos_diff, rem, builder.neg(rem))
uneven = builder.icmp(lc.ICMP_SGT, rem, zero)
newcount = builder.add(builder.sdiv(diff, step),
builder.select(uneven, one, zero))
builder.store(newcount, self.count)
return self
def reduce_datetime_for_unit(builder, dt_val, src_unit, dest_unit):
dest_unit_code = npdatetime.DATETIME_UNITS[dest_unit]
src_unit_code = npdatetime.DATETIME_UNITS[src_unit]
if dest_unit_code < 2 or src_unit_code >= 2:
return dt_val, src_unit
# Need to compute the day ordinal for *dt_val*
if src_unit_code == 0:
# Years to days
year_val = dt_val
days_val = year_to_days(builder, year_val)
else:
# Months to days
leap_array = cgutils.global_constant(builder, "leap_year_months_acc",
leap_year_months_acc)
normal_array = cgutils.global_constant(builder, "normal_year_months_acc",
normal_year_months_acc)
days = cgutils.alloca_once(builder, TIMEDELTA64)
# First compute year number and month number
year, month = cgutils.divmod_by_constant(builder, dt_val, 12)
# Then deduce the number of days
with cgutils.ifelse(builder,
is_leap_year(builder, year)) as (then, otherwise):
with then:
addend = builder.load(cgutils.gep(builder, leap_array,
0, month))
builder.store(addend, days)
with otherwise:
addend = builder.load(cgutils.gep(builder, normal_array,
0, month))
builder.store(addend, days)
days_val = year_to_days(builder, year)
days_val = builder.add(days_val, builder.load(days))
if dest_unit_code == 2:
# Need to scale back to weeks
weeks, _ = cgutils.divmod_by_constant(builder, days_val, 7)
return weeks, 'W'
else:
return days_val, 'D'
开发者ID:genba,项目名称:numba,代码行数:44,代码来源:npdatetime.py
示例14: lower_expr
def lower_expr(self, expr):
if expr.op == 'binop':
return self.lower_binop(expr, inplace=False)
elif expr.op == 'inplace_binop':
return self.lower_binop(expr, inplace=True)
elif expr.op == 'unary':
value = self.loadvar(expr.value.name)
if expr.fn == '-':
res = self.pyapi.number_negative(value)
elif expr.fn == '+':
res = self.pyapi.number_positive(value)
elif expr.fn == 'not':
res = self.pyapi.object_not(value)
self.check_int_status(res)
longval = self.builder.zext(res, self.pyapi.long)
res = self.pyapi.bool_from_long(longval)
elif expr.fn == '~':
res = self.pyapi.number_invert(value)
else:
raise NotImplementedError(expr)
self.check_error(res)
return res
elif expr.op == 'call':
argvals = [self.loadvar(a.name) for a in expr.args]
fn = self.loadvar(expr.func.name)
if not expr.kws:
# No keyword
ret = self.pyapi.call_function_objargs(fn, argvals)
else:
# Have Keywords
keyvalues = [(k, self.loadvar(v.name)) for k, v in expr.kws]
args = self.pyapi.tuple_pack(argvals)
kws = self.pyapi.dict_pack(keyvalues)
ret = self.pyapi.call(fn, args, kws)
self.decref(kws)
self.decref(args)
self.check_error(ret)
return ret
elif expr.op == 'getattr':
obj = self.loadvar(expr.value.name)
res = self.pyapi.object_getattr(obj, self._freeze_string(expr.attr))
self.check_error(res)
return res
elif expr.op == 'build_tuple':
items = [self.loadvar(it.name) for it in expr.items]
res = self.pyapi.tuple_pack(items)
self.check_error(res)
return res
elif expr.op == 'build_list':
items = [self.loadvar(it.name) for it in expr.items]
res = self.pyapi.list_pack(items)
self.check_error(res)
return res
elif expr.op == 'build_map':
res = self.pyapi.dict_new(expr.size)
self.check_error(res)
return res
elif expr.op == 'build_set':
items = [self.loadvar(it.name) for it in expr.items]
res = self.pyapi.set_new()
self.check_error(res)
for it in items:
ok = self.pyapi.set_add(res, it)
self.check_int_status(ok)
return res
elif expr.op == 'getiter':
obj = self.loadvar(expr.value.name)
res = self.pyapi.object_getiter(obj)
self.check_error(res)
return res
elif expr.op == 'iternext':
iterobj = self.loadvar(expr.value.name)
item = self.pyapi.iter_next(iterobj)
is_valid = cgutils.is_not_null(self.builder, item)
pair = self.pyapi.tuple_new(2)
with cgutils.ifelse(self.builder, is_valid) as (then, otherwise):
with then:
self.pyapi.tuple_setitem(pair, 0, item)
with otherwise:
self.check_occurred()
# Make the tuple valid by inserting None as dummy
# iteration "result" (it will be ignored).
self.pyapi.tuple_setitem(pair, 0, self.pyapi.make_none())
self.pyapi.tuple_setitem(pair, 1, self.pyapi.bool_from_bool(is_valid))
return pair
elif expr.op == 'pair_first':
pair = self.loadvar(expr.value.name)
first = self.pyapi.tuple_getitem(pair, 0)
self.incref(first)
return first
elif expr.op == 'pair_second':
pair = self.loadvar(expr.value.name)
second = self.pyapi.tuple_getitem(pair, 1)
self.incref(second)
return second
elif expr.op == 'exhaust_iter':
iterobj = self.loadvar(expr.value.name)
tup = self.pyapi.sequence_tuple(iterobj)
self.check_error(tup)
#.........这里部分代码省略.........
#.........这里部分代码省略.........
# If the shape of this dimension is 1, then leave the
# index at 0 so that this dimension is broadcasted over
# the corresponding input and output dimensions.
cond = builder.icmp(ICMP_UGT, inp_shape[i], ONE)
with cgutils.ifthen(builder, cond):
builder.store(indices[out_ndim-inp_ndim+i], inp_indices[i])
if i + 1 == inp_ndim:
builder.branch(bb_end_inc_index)
else:
builder.branch(bb_inc_inp_index[i+1])
builder.position_at_end(bb_end_inc_index)
if not scalar_inp1:
build_increment_blocks(inp1_indices, inp1_shape, inp1_ndim, '1')
if not scalar_inp2:
build_increment_blocks(inp2_indices, inp2_shape, inp2_ndim, '2')
if scalar_inp1:
x = inp1
else:
inds = [builder.load(index) for index in inp1_indices]
px = cgutils.get_item_pointer2(builder,
data=inp1_data,
shape=inp1_shape,
strides=inp1_strides,
layout=inp1_layout,
inds=inds)
x = builder.load(px)
if scalar_inp2:
y = inp2
else:
inds = [builder.load(index) for index in inp2_indices]
py = cgutils.get_item_pointer2(builder,
data=inp2_data,
shape=inp2_shape,
strides=inp2_strides,
layout=inp2_layout,
inds=inds)
y = builder.load(py)
po = cgutils.get_item_pointer2(builder,
data=out_data,
shape=out_shape,
strides=out_strides,
layout=out_layout,
inds=indices)
if divbyzero:
# Handle division
iszero = cgutils.is_scalar_zero(builder, y)
with cgutils.ifelse(builder, iszero, expect=False) as (then,
orelse):
with then:
# Divide by zero
if (scalar_tyinp1 in types.real_domain or
scalar_tyinp2 in types.real_domain) or \
not numpy_support.int_divbyzero_returns_zero:
# If y is float and is 0 also, return Nan; else
# return Inf
outltype = context.get_data_type(result_type)
shouldretnan = cgutils.is_scalar_zero(builder, x)
nan = Constant.real(outltype, float("nan"))
inf = Constant.real(outltype, float("inf"))
tempres = builder.select(shouldretnan, nan, inf)
res = context.cast(builder, tempres, result_type,
tyout.dtype)
elif tyout.dtype in types.signed_domain and \
not numpy_support.int_divbyzero_returns_zero:
res = Constant.int(context.get_data_type(tyout.dtype),
0x1 << (y.type.width-1))
else:
res = Constant.null(context.get_data_type(tyout.dtype))
assert res.type == po.type.pointee, \
(str(res.type), str(po.type.pointee))
builder.store(res, po)
with orelse:
# Normal
d_x = context.cast(builder, x, scalar_tyinp1, promote_type)
d_y = context.cast(builder, y, scalar_tyinp2, promote_type)
tempres = fnwork(builder, [d_x, d_y])
res = context.cast(builder, tempres, result_type, tyout.dtype)
assert res.type == po.type.pointee, (res.type,
po.type.pointee)
builder.store(res, po)
else:
# Handle non-division operations
d_x = context.cast(builder, x, scalar_tyinp1, promote_type)
d_y = context.cast(builder, y, scalar_tyinp2, promote_type)
tempres = fnwork(builder, [d_x, d_y])
res = context.cast(builder, tempres, result_type, tyout.dtype)
assert res.type == po.type.pointee, (res.type,
po.type.pointee)
builder.store(res, po)
return out
开发者ID:B-Rich,项目名称:numba,代码行数:101,代码来源:npyimpl.py
示例17: build_ufunc_wrapper
def build_ufunc_wrapper(context, func, signature):
"""
Wrap the scalar function with a loop that iterates over the arguments
"""
module = func.module
byte_t = Type.int(8)
byte_ptr_t = Type.pointer(byte_t)
byte_ptr_ptr_t = Type.pointer(byte_ptr_t)
intp_t = context.get_value_type(types.intp)
intp_ptr_t = Type.pointer(intp_t)
fnty = Type.function(Type.void(), [byte_ptr_ptr_t, intp_ptr_t,
intp_ptr_t, byte_ptr_t])
wrapper = module.add_function(fnty, "__ufunc__." + func.name)
arg_args, arg_dims, arg_steps, arg_data = wrapper.args
arg_args.name = "args"
arg_dims.name = "dims"
arg_steps.name = "steps"
arg_data.name = "data"
builder = Builder.new(wrapper.append_basic_block("entry"))
loopcount = builder.load(arg_dims, name="loopcount")
actual_args = context.get_arguments(func)
# Prepare inputs
arrays = []
for i, typ in enumerate(signature.args):
arrays.append(UArrayArg(context, builder, arg_args, arg_steps, i,
context.get_argument_type(typ)))
# Prepare output
valty = context.get_data_type(signature.return_type)
out = UArrayArg(context, builder, arg_args, arg_steps, len(actual_args),
valty)
# Setup indices
offsets = []
zero = context.get_constant(types.intp, 0)
for _ in arrays:
p = cgutils.alloca_once(builder, intp_t)
offsets.append(p)
builder.store(zero, p)
store_offset = cgutils.alloca_once(builder, intp_t)
builder.store(zero, store_offset)
unit_strided = cgutils.true_bit
for ary in arrays:
unit_strided = builder.and_(unit_strided, ary.is_unit_strided)
with cgutils.ifelse(builder, unit_strided) as (is_unit_strided,
is_strided):
with is_unit_strided:
with cgutils.for_range(builder, loopcount, intp=intp_t) as ind:
fastloop = build_fast_loop_body(context, func, builder,
arrays, out, offsets,
store_offset, signature, ind)
builder.ret_void()
with is_strided:
# General loop
with cgutils.for_range(builder, loopcount, intp=intp_t):
slowloop = build_slow_loop_body(context, func, builder,
arrays, out, offsets,
store_offset, signature)
builder.ret_void()
builder.ret_void()
del builder
# Set core function to internal so that it is not generated
func.linkage = LINKAGE_INTERNAL
# Force inline of code function
inline_function(slowloop)
inline_function(fastloop)
# Run optimizer
context.optimize(module)
if config.DUMP_OPTIMIZED:
print(module)
return wrapper
开发者ID:genba,项目名称:numba,代码行数:88,代码来源:wrappers.py
示例18: impl
def impl(context, builder, sig, args):
[tyinp1, tyinp2, tyout] = sig.args
[inp1, inp2, out] = args
if scalar_inputs:
ndim = 1
else:
ndim = tyinp1.ndim
# Temporary hack for __ftol2 llvm bug. Don't allow storing
# float results in uint64 array on windows.
if scalar_inputs and tyinp1 in types.real_domain and \
tyout.dtype is types.uint64 and \
sys.platform.startswith('win32'):
raise TypeError('Cannot store result in uint64 array')
if not scalar_inputs and tyinp1.dtype in types.real_domain and \
tyout.dtype is types.uint64 and \
sys.platform.startswith('win32'):
raise TypeError('Cannot store result in uint64 array')
if not scalar_inputs:
i1ary = context.make_array(tyinp1)(context, builder, inp1)
i2ary = context.make_array(tyinp2)(context, builder, inp2)
oary = context.make_array(tyout)(context, builder, out)
if asfloat and not divbyzero:
sig = typing.signature(types.float64, types.float64, types.float64)
else:
if scalar_inputs:
sig = typing.signature(tyout.dtype, tyinp1, tyinp2)
else:
sig = typing.signature(tyout.dtype, tyinp1.dtype, tyinp2.dtype)
fnwork = context.get_function(funckey, sig)
intpty = context.get_value_type(types.intp)
# TODO handle differing shape by mimicking broadcasting
loopshape = cgutils.unpack_tuple(builder, oary.shape, ndim)
if scalar_inputs:
xyo_shape = [cgutils.unpack_tuple(builder, ary.shape, ndim)
for ary in (oary,)]
xyo_strides = [cgutils.unpack_tuple(builder, ary.strides, ndim)
for ary in (oary,)]
xyo_data = [ary.data for ary in (oary,)]
xyo_layout = [ty.layout for ty in (tyout,)]
else:
xyo_shape = [cgutils.unpack_tuple(builder, ary.shape, ndim)
for ary in (i1ary, i2ary, oary)]
xyo_strides = [cgutils.unpack_tuple(builder, ary.strides, ndim)
for ary in (i1ary, i2ary, oary)]
xyo_data = [ary.data for ary in (i1ary, i2ary, oary)]
xyo_layout = [ty.layout for ty in (tyinp1, tyinp2, tyout)]
with cgutils.loop_nest(builder, loopshape, intp=intpty) as indices:
if scalar_inputs:
[po] = [cgutils.get_item_pointer2(builder,
data=data, shape=shape,
strides=strides,
layout=layout,
inds=indices)
for data, shape, strides, layout
in zip(xyo_data, xyo_shape, xyo_strides,
xyo_layout)]
else:
[px, py, po] = [cgutils.get_item_pointer2(builder,
data=data, shape=shape,
strides=strides,
layout=layout,
inds=indices)
for data, shape, strides, layout
in zip(xyo_data, xyo_shape, xyo_strides,
xyo_layout)]
if scalar_inputs:
x = inp1
y = inp2
else:
x = builder.load(px)
y = builder.load(py)
if divbyzero:
# Handle division
iszero = cgutils.is_scalar_zero(builder, y)
with cgutils.ifelse(builder, iszero, expect=False) as (then,
orelse):
with then:
# Divide by zero
if ((scalar_inputs and tyinp2 in types.real_domain) or
(not scalar_inputs and
tyinp2.dtype in types.real_domain) or
not numpy_support.int_divbyzero_returns_zero):
# If y is float and is 0 also, return Nan; else
# return Inf
outltype = context.get_data_type(tyout.dtype)
shouldretnan = cgutils.is_scalar_zero(builder, x)
nan = Constant.real(outltype, float("nan"))
inf = Constant.real(outltype, float("inf"))
res = builder.select(shouldretnan, nan, inf)
elif (scalar_inputs and tyout in types.signed_domain and
not numpy_support.int_divbyzero_returns_zero):
res = Constant.int(context.get_data_type(tyout),
#.........这里部分代码省略.........
请发表评论