Пример #1
0
def specialize(untyped, args, kwargs = {}, optimize = True):
  """
  Translate, specialize and begin to optimize the given function for the types
  of the supplies arguments.

  Return the untyped and typed representations, along with all the
  arguments in a linear order. 
  """

  if not isinstance(untyped, UntypedFn):
    import ast_conversion
    untyped = ast_conversion.translate_function_value(untyped)
       
  arg_values, arg_types = prepare_args(untyped, args, kwargs)
  
  # convert the awkward mix of positional, named, and starargs 
  # into a positional sequence of arguments
  linear_args = untyped.args.linearize_without_defaults(arg_values)
  
  # propagate types through function representation and all
  # other functions it calls
  typed_fn = type_inference.specialize(untyped, arg_types)
  if optimize: 
    from .. transforms.pipeline import normalize 
    # apply high level optimizations 
    typed_fn = normalize.apply(typed_fn)
  return typed_fn, linear_args 
Пример #2
0
def specialize(untyped, args, kwargs = {}, optimize = False):
  """
  Translate, specialize and begin to optimize the given function for the types
  of the supplies arguments.

  Return the untyped and typed representations, along with all the
  arguments in a linear order. 
  """

  if not isinstance(untyped, UntypedFn):
    untyped = ast_conversion.translate_function_value(untyped)
       
  arg_values, arg_types = prepare_args(untyped, args, kwargs)
  
  # convert the awkward mix of positional, named, and starargs 
  # into a positional sequence of arguments
  linear_args = untyped.args.linearize_without_defaults(arg_values)
  
  # propagate types through function representation and all
  # other functions it calls
   
  typed_fn = type_inference.specialize(untyped, arg_types)
  if optimize: 
    from .. transforms.pipeline import normalize 
    # apply high level optimizations 
    typed_fn = normalize.apply(typed_fn)
  return typed_fn, linear_args 
Пример #3
0
def run_python_fn(fn, args, kwargs = None, backend = None):
  """
  Given a python function, run it in Parakeet on the supplied args
  """
  # translate from the Python AST to Parakeet's untyped format
  untyped = ast_conversion.translate_function_value(fn)
  return run_untyped_fn(untyped, args, kwargs, backend)
Пример #4
0
def run_python_fn(fn, args, kwargs = None, backend = None):
  """
  Given a python function, run it in Parakeet on the supplied args
  """
  # translate from the Python AST to Parakeet's untyped format
  untyped = ast_conversion.translate_function_value(fn)
  return run_untyped_fn(untyped, args, kwargs, backend)
Пример #5
0
def run_python_fn(python_fn, args, kwds):
  untyped  = ast_conversion.translate_function_value(python_fn)
  # should eventually roll this up into something cleaner, since
  # top-level functions are really acting like closures over their
  # global dependencies
  global_args = [python_fn.func_globals[n] for n in untyped.nonlocals]
  all_positional = global_args + list(args)
  actuals = args.FormalArgs(all_positional, kwds)
  return eval_fn(untyped, actuals)
Пример #6
0
def prepare_args(fn, args, kwargs):
  """
  Fetch the function's nonlocals and return an ActualArgs object of both the arg
  values and their types
  """
  #assert not isinstance(fn, TypedFn), "[prepare_args] Only works for untyped functions"
  if not isinstance(fn, UntypedFn):
    fn = ast_conversion.translate_function_value(fn)   
  nonlocals = tuple(fn.python_nonlocals())
  arg_values = ActualArgs(nonlocals + tuple(args), kwargs)
  arg_types = arg_values.transform(_typeof)
  return arg_values, arg_types
Пример #7
0
def prepare_args(fn, args, kwargs):
  """
  Fetch the function's nonlocals and return an ActualArgs object of both the arg
  values and their types
  """
  #assert not isinstance(fn, TypedFn), "[prepare_args] Only works for untyped functions"
  if not isinstance(fn, UntypedFn):
    fn = ast_conversion.translate_function_value(fn)   
  nonlocals = tuple(fn.python_nonlocals())
  arg_values = ActualArgs(nonlocals + tuple(args), kwargs)
  arg_types = arg_values.transform(_typeof)
  return arg_values, arg_types
Пример #8
0
 def __call__(self, *args, **kwargs):
   if '_backend' in kwargs:
     backend_name = kwargs['_backend']
     del kwargs['_backend']
   else:
     backend_name = None
   
   if self.untyped is None:
     import ast_conversion 
     self.untyped = ast_conversion.translate_function_value(self.fn)
   
   typed_fn, linear_args = specialize(self.untyped, args, kwargs)
   return run_typed_fn(typed_fn, linear_args, backend_name)
Пример #9
0
def get_fundef(fn):
  """
  Get the function definition in case I want to pass in the name of an untyped
  function or an untranslated python fn.
  """
  import ast_conversion 
  if isinstance(fn, str):
    assert fn  in syntax.Fn.registry, "Function not found: %s" % fn
    return syntax.Fn.registry[fn]
  elif not isinstance(fn, syntax.Fn):
    return ast_conversion.translate_function_value(fn)
  else:
    return fn
Пример #10
0
def prepare_args(fn, args, kwargs):
  """
  Fetch the function's nonlocals and return an ActualArgs object of both the arg
  values and their types
  """

  if isinstance(fn, syntax.Fn):
    untyped = fn
  else:
    # translate from the Python AST to Parakeet's untyped format
    untyped = ast_conversion.translate_function_value(fn)

  nonlocals = list(untyped.python_nonlocals())
  arg_values = ActualArgs(nonlocals + list(args), kwargs)

  # get types of all inputs
  arg_types = arg_values.transform(type_conv.typeof)
  return untyped, arg_values, arg_types
Пример #11
0
  def from_python(self, python_fn):
    import ast_conversion
    untyped_fundef = ast_conversion.translate_function_value(python_fn)
    closure_args = untyped_fundef.python_nonlocals()
    closure_arg_types = map(type_conv.typeof, closure_args)

    closure_t = make_closure_type(untyped_fundef, closure_arg_types)
    closure_id = id_of_closure_type(closure_t)

    def field_value(closure_arg):
      obj = type_conv.from_python(closure_arg)
      parakeet_type = type_conv.typeof(closure_arg)
      if isinstance(parakeet_type, StructT):
        return ctypes.pointer(obj)
      else:
        return obj

    converted_args = [field_value(closure_arg) for closure_arg in closure_args]
    return closure_t.ctypes_repr(closure_id, *converted_args)
Пример #12
0
def prepare_args(fn, args, kwargs):
  """
  Fetch the function's nonlocals and return an ActualArgs object of both the arg
  values and their types
  """
  assert not isinstance(fn, TypedFn), "[prepare_args] Only works for untyped functions"
  if not isinstance(fn, UntypedFn):
    import ast_conversion
    fn = ast_conversion.translate_function_value(fn)   
    
  nonlocals = list(fn.python_nonlocals())
  arg_values = ActualArgs(nonlocals + list(args), kwargs)

  # get types of all inputs
  def _typeof(arg):
    if hasattr(arg, 'type') and isinstance(arg.type, Type):
      return arg.type 
    else:
      return type_conv.typeof(arg)
  arg_types = arg_values.transform(_typeof)
  return arg_values, arg_types
Пример #13
0
    closure_set = closure_type.ClosureSet(fn)
  else:
    assert isinstance(fn, closure_type.ClosureSet), \
        "Invoke expected closure, but got %s" % (fn,)
    closure_set = fn

  result_type = Unknown
  for closure_t in closure_set.closures:
    typed_fundef = specialize(closure_t, arg_types)
    result_type = result_type.combine(typed_fundef.return_type)
  _invoke_type_cache[key] = result_type
  return result_type

def identity(x):
  return x
untyped_identity_function = ast_conversion.translate_function_value(identity)


class Annotator(Transform):
  
  def __init__(self, tenv, var_map):
    Transform.__init__(self)
    self.type_env = tenv 
    self.var_map = var_map
    
  
  def transform_expr(self, expr):
    if not isinstance(expr, syntax.Expr):
      expr = ast_conversion.value_to_syntax(expr)
    
    result = Transform.transform_expr(self, expr)  
Пример #14
0
def typeof_fn(f):
    import ast_conversion
    untyped_fn = ast_conversion.translate_function_value(f)
    closure_args = untyped_fn.python_nonlocals()
    closure_arg_types = map(typeof, closure_args)
    return make_closure_type(untyped_fn, closure_arg_types)
Пример #15
0
  def eval_expr(expr):
    # print ">>", expr
    if hasattr(expr, 'wrapper'):
      expr = expr.wrapper
    assert isinstance(expr, syntax.Expr), "Not an expression-- %s : %s" % \
         (expr, type(expr))
    def expr_Const():
      return expr.value

    def expr_Attribute():
      value = eval_expr(expr.value)
      if expr.name == 'offset':
        if value.base is None:
          return 0
        else:
          return value.ctypes.data - value.base.ctypes.data
      else:
        return getattr(value, expr.name)

    def expr_ArrayView():
      data = eval_expr(expr.data)
      shape  = eval_expr(expr.shape)
      strides = eval_expr(expr.strides)
      offset = eval_expr(expr.offset)
      dtype = expr.type.elt_type.dtype
      return np.ndarray(shape = shape, 
                        offset = offset, 
                        buffer = data, 
                        strides = strides, 
                        dtype = np.dtype(dtype))
      
      
    def expr_Array():
      elt_values = map(eval_expr, expr.elts)
      return np.array(elt_values)

    def expr_Index():
      array = eval_expr(expr.value)
      index = eval_expr(expr.index)
      return array[index]

    def expr_PrimCall():
      return expr.prim.fn (*eval_args(expr.args))
    
    def expr_Slice():
      return slice(eval_expr(expr.start), eval_expr(expr.stop),
                   eval_expr(expr.step))

    def expr_Var():
      return env[expr.name]

    def expr_Call():
      fn = eval_expr(expr.fn)
      arg_values = eval_args(expr.args)
      return eval_fn(fn, arg_values)

    def expr_Closure():
      if isinstance(expr.fn, (syntax.Fn, syntax.TypedFn)):
        fundef = expr.fn
      else:
        assert isinstance(expr.fn, str)
        fundef = syntax.Fn.registry[expr.fn]
      closure_arg_vals = map(eval_expr, expr.args)
      return ClosureVal(fundef, closure_arg_vals)

    def expr_Fn():
      return ClosureVal(expr, [])

    def expr_TypedFn():
      return ClosureVal(expr, [])

    def expr_Cast():
      x = eval_expr(expr.value)
      t = expr.type
      assert isinstance(t, ScalarT)
      # use numpy's conversion function
      return t.dtype.type(x)

    def expr_Struct():
      assert expr.type, "Expected type on %s!" % expr
      assert isinstance(expr.type, StructT), \
          "Expected %s : %s to be a struct" % (expr, expr.type)
      elts = map(eval_expr, expr.args)
      return expr.type.ctypes_repr(elts)

    def expr_Tuple():
      return tuple(map(eval_expr, expr.elts))
    
    def expr_TupleProj():
      return eval_expr(expr.tuple)[expr.index]

    def expr_ClosureElt():
      assert isinstance(expr.closure, syntax.Expr), \
          "Invalid closure expression-- %s : %s" % \
          (expr.closure, type(expr.closure))
      clos = eval_expr(expr.closure)
      return clos.fixed_args[expr.index]

    def expr_Range():
      return np.arange(eval_expr(expr.start), eval_expr(expr.stop), eval_expr(expr.step))
    
    def expr_Len():
      return len(eval_expr(expr.value))
    
    def expr_IndexMap():
      fn = eval_expr(expr.fn)
      shape = eval_expr(expr.shape)
      ranges = [xrange(n) for n in shape]
      def wrap_idx(idx):
        if len(idx) == 1:
          idx = idx[0]
        return eval_fn(fn, (idx,))
      elts = [wrap_idx(idx) for idx in itertools.product(*ranges)]
      return np.array(elts).reshape((shape))
    
    def expr_IndexReduce():
      fn = eval_expr(expr.fn)
      combine = eval_expr(expr.combine)
      shape = eval_expr(expr.shape)
      ranges = [xrange(n) for n in shape]
        
      acc = eval_if_expr(expr.init)
      for idx in itertools.product(*ranges):
        if len(idx) == 1:
          idx = idx[0]
        elt = eval_fn(fn, (idx,))
        if acc is None:
          acc = elt 
        else:
          elt = eval_fn(combine, (acc, elt))
      return elt 
    
    def expr_Map():
      fn = eval_expr(expr.fn)
      args = eval_args(expr.args)
      axis = eval_if_expr(expr.axis)
      return adverb_evaluator.eval_map(fn, args, axis)

    def expr_AllPairs():
      fn = eval_expr(expr.fn)
      x,y = eval_args(expr.args)
      axis = eval_if_expr(expr.axis)
      return adverb_evaluator.eval_allpairs(fn, x, y, axis)

    def expr_Reduce():
      
      map_fn = eval_expr(expr.fn)
      combine_fn = eval_expr(expr.combine)
      args = eval_args(expr.args)
      init = eval_expr(expr.init) if expr.init else None
      axis = eval_if_expr(expr.axis)
      if axis is None:
        args = [np.ravel(x) for x in args]
        axis = 0
      return adverb_evaluator.eval_reduce(map_fn, combine_fn, init, args, axis)

    def expr_Scan():
      map_fn = eval_expr(expr.fn)
      combine = eval_expr(expr.combine)
      emit = eval_expr(expr.emit)
      args = eval_args(expr.args)
      init = eval_expr(expr.init)
      axis = eval_if_expr(expr.axis)
      return adverb_evaluator.eval_scan(map_fn, combine, emit, init, args, axis)
  
        
    result = dispatch(expr, 'expr')
    # we don't support python function's inside parakeet,
    # they have to be translated into Parakeet functions
    if isinstance(result, types.FunctionType):
      fundef = ast_conversion.translate_function_value(result)
      return ClosureVal(fundef, fundef.python_nonlocals())
    else:
      return result
Пример #16
0
def typeof_fn(f):
  import ast_conversion
  untyped_fn = ast_conversion.translate_function_value(f)
  closure_args = untyped_fn.python_nonlocals()
  closure_arg_types = map(type_conv.typeof, closure_args)
  return make_closure_type(untyped_fn, closure_arg_types)
Пример #17
0
  def eval_expr(expr):
    if hasattr(expr, 'wrapper'):
      expr = expr.wrapper
    assert isinstance(expr, syntax.Expr), "Not an expression-- %s : %s" % \
         (expr, type(expr))
    def expr_Const():
      return expr.value

    def expr_Attribute():
      value = eval_expr(expr.value)
      return getattr(value, expr.name)

    def expr_Array():
      elt_values = map(eval_expr, expr.elts)
      return np.array(elt_values)

    def expr_Index():
      array = eval_expr(expr.value)
      index = eval_expr(expr.index)
      return array[index]

    def expr_PrimCall():
      return expr.prim.fn (*eval_args(expr.args))
    
    def expr_Slice():
      return slice(eval_expr(expr.start), eval_expr(expr.stop),
                   eval_expr(expr.step))

    def expr_Var():
      return env[expr.name]

    def expr_Call():
      fn = eval_expr(expr.fn)
      arg_values = eval_args(expr.args)
      return eval_fn(fn, arg_values)

    def expr_Closure():
      if isinstance(expr.fn, (syntax.Fn, syntax.TypedFn)):
        fundef = expr.fn
      else:
        assert isinstance(expr.fn, str)
        fundef = syntax.Fn.registry[expr.fn]
      closure_arg_vals = map(eval_expr, expr.args)
      return ClosureVal(fundef, closure_arg_vals)

    def expr_Fn():
      return ClosureVal(expr, [])

    def expr_TypedFn():
      return ClosureVal(expr, [])

    def expr_Cast():
      x = eval_expr(expr.value)
      t = expr.type
      assert isinstance(t, ScalarT)
      # use numpy's conversion function
      return t.dtype.type(x)

    def expr_Struct():
      assert expr.type, "Expected type on %s!" % expr
      assert isinstance(expr.type, StructT), \
          "Expected %s : %s to be a struct" % (expr, expr.type)
      elts = map(eval_expr, expr.args)
      return expr.type.ctypes_repr(elts)

    def expr_Tuple():
      return tuple(map(eval_expr, expr.elts))

    def expr_TupleProj():
      return eval_expr(expr.tuple)[expr.index]

    def expr_ClosureElt():
      assert isinstance(expr.closure, syntax.Expr), \
          "Invalid closure expression-- %s : %s" % \
          (expr.closure, type(expr.closure))
      clos = eval_expr(expr.closure)
      return clos.fixed_args[expr.index]

    def expr_Map():
      fn = eval_expr(expr.fn)
      args = eval_args(expr.args)
      axis = syntax_helpers.unwrap_constant(expr.axis)
      return adverb_evaluator.eval_map(fn, args, axis)

    def expr_AllPairs():
      fn = eval_expr(expr.fn)
      x,y = eval_args(expr.args)
      axis = syntax_helpers.unwrap_constant(expr.axis)
      return adverb_evaluator.eval_allpairs(fn, x, y, axis)

    def expr_Reduce():
      map_fn = eval_expr(expr.fn)
      combine_fn = eval_expr(expr.combine)
      args = eval_args(expr.args)
      init = eval_expr(expr.init) if expr.init else None
      axis = syntax_helpers.unwrap_constant(expr.axis)
      return adverb_evaluator.eval_reduce(map_fn, combine_fn, init, args, axis)

    def expr_Scan():
      map_fn = eval_expr(expr.fn)
      combine = eval_expr(expr.combine)
      emit = eval_expr(expr.emit)
      args = eval_args(expr.args)
      init = eval_expr(expr.init)
      axis = syntax_helpers.unwrap_constant(expr.axis)
      return adverb_evaluator.eval_scan(map_fn, combine, emit, init, args, axis)

    result = dispatch(expr, 'expr')
    # we don't support python function's inside parakeet,
    # they have to be translated into Parakeet functions
    if isinstance(result, types.FunctionType):
      fundef = ast_conversion.translate_function_value(result)
      return ClosureVal(fundef, fundef.python_nonlocals())
    else:
      return result