Ejemplo n.º 1
0
nd::arrfunc dynd::make_rolling_arrfunc(const nd::arrfunc &window_op,
                                       intptr_t window_size)
{
  // Validate the input arrfunc
  if (window_op.is_null()) {
    throw invalid_argument("make_rolling_arrfunc() 'window_op' cannot be null");
  }
  const arrfunc_type *window_af_tp = window_op.get_type();
  if (window_af_tp->get_npos() != 1) {
    stringstream ss;
    ss << "To make a rolling window arrfunc, an operation with one "
          "argument is required, got " << window_af_tp;
    throw invalid_argument(ss.str());
  }
  const ndt::type &window_src_tp = window_af_tp->get_arg_type(0);
  if (window_src_tp.get_ndim() < 1) {
    stringstream ss;
    ss << "To make a rolling window arrfunc, an operation with which "
          "accepts a dimension is required, got " << window_af_tp;
    throw invalid_argument(ss.str());
  }

  nd::string rolldimname("RollDim");
  ndt::type roll_src_tp = ndt::make_typevar_dim(
      rolldimname, window_src_tp.get_type_at_dimension(NULL, 1));
  ndt::type roll_dst_tp =
      ndt::make_typevar_dim(rolldimname, window_af_tp->get_return_type());

  nd::array af = nd::empty(ndt::make_funcproto(roll_src_tp, roll_dst_tp));
  arrfunc_type_data *out_af =
      reinterpret_cast<arrfunc_type_data *>(af.get_readwrite_originptr());

  // Create the data for the arrfunc
  rolling_arrfunc_data *data = new rolling_arrfunc_data;
  *out_af->get_data_as<rolling_arrfunc_data *>() = data;
  out_af->free = &free_rolling_arrfunc_data;
  out_af->resolve_dst_type = &resolve_rolling_dst_type;
  out_af->instantiate = &instantiate_strided;
  data->window_size = window_size;
  data->window_op = window_op;
  af.flag_as_immutable();
  return af;
}
Ejemplo n.º 2
0
nd::arrfunc dynd::lift_arrfunc(const nd::arrfunc &child_af)
{
  nd::array af = nd::empty(lift_proto(child_af.get_type()));
  arrfunc_type_data *out_af =
      reinterpret_cast<arrfunc_type_data *>(af.get_readwrite_originptr());
  out_af->free_func = &delete_lifted_expr_arrfunc_data;
  *out_af->get_data_as<const array_preamble *>() =
      nd::array(child_af).release();
  out_af->instantiate = &instantiate_lifted_expr_arrfunc_data;
  out_af->resolve_dst_type = &resolve_lifted_dst_type;
  af.flag_as_immutable();
  return af;
}
Ejemplo n.º 3
0
nd::arrfunc nd::functional::neighborhood(const nd::arrfunc &neighborhood_op,
                                         intptr_t nh_ndim)
{
  const ndt::arrfunc_type *funcproto_tp =
      neighborhood_op.get_array_type().extended<ndt::arrfunc_type>();

  nd::array arg_tp = nd::empty(3, ndt::make_type());
  arg_tp(0).vals() = ndt::type("?" + std::to_string(nh_ndim) + " * int");
  arg_tp(1).vals() = ndt::type("?" + std::to_string(nh_ndim) + " * int");
  arg_tp(2).vals() =
      ndt::type("?Fixed**" + std::to_string(nh_ndim) + " * bool");
  std::vector<std::string> arg_names;
  arg_names.push_back("shape");
  arg_names.push_back("offset");
  arg_names.push_back("mask");
  ndt::type ret_tp = funcproto_tp->get_pos_type(0)
                         .with_replaced_dtype(funcproto_tp->get_return_type());
  ndt::type self_tp =
      ndt::make_arrfunc(funcproto_tp->get_pos_tuple(),
                        ndt::make_struct(arg_names, arg_tp), ret_tp);

  std::ostringstream oss;
  oss << "Fixed**" << nh_ndim;
  ndt::type nhop_pattern("(" + oss.str() + " * NH) -> OUT");
  ndt::type result_pattern("(" + oss.str() + " * NH) -> " + oss.str() +
                           " * OUT");

  map<nd::string, ndt::type> typevars;
  if (!nhop_pattern.match(neighborhood_op.get_array_type(), typevars)) {
    stringstream ss;
    ss << "provided neighborhood op proto " << neighborhood_op.get_array_type()
       << " does not match pattern " << nhop_pattern;
    throw invalid_argument(ss.str());
  }

  std::shared_ptr<neighborhood_data> nh(new nd::functional::neighborhood_data(neighborhood_op, nh_ndim));
  return arrfunc::make<neighborhood_ck<1>>(self_tp, nh, 0);
}
Ejemplo n.º 4
0
nd::arrfunc nd::functional::rolling(const nd::arrfunc &window_op,
                                    intptr_t window_size)
{
  // Validate the input arrfunc
  if (window_op.is_null()) {
    throw invalid_argument("make_rolling_arrfunc() 'window_op' cannot be null");
  }
  const ndt::arrfunc_type *window_af_tp = window_op.get_type();
  if (window_af_tp->get_npos() != 1) {
    stringstream ss;
    ss << "To make a rolling window arrfunc, an operation with one "
          "argument is required, got " << window_af_tp;
    throw invalid_argument(ss.str());
  }
  const ndt::type &window_src_tp = window_af_tp->get_pos_type(0);
  if (window_src_tp.get_ndim() < 1) {
    stringstream ss;
    ss << "To make a rolling window arrfunc, an operation with which "
          "accepts a dimension is required, got " << window_af_tp;
    throw invalid_argument(ss.str());
  }

  nd::string rolldimname("RollDim");
  ndt::type roll_src_tp = ndt::make_typevar_dim(
      rolldimname, window_src_tp.get_type_at_dimension(NULL, 1));
  ndt::type roll_dst_tp =
      ndt::make_typevar_dim(rolldimname, window_af_tp->get_return_type());

  // Create the data for the arrfunc
  std::shared_ptr<rolling_arrfunc_data> data(new rolling_arrfunc_data);
  data->window_size = window_size;
  data->window_op = window_op;

  return arrfunc::make<rolling_ck>(
      ndt::make_arrfunc(ndt::make_tuple(roll_src_tp), roll_dst_tp), data, 0);
}
void dynd::lift_reduction_arrfunc(arrfunc_type_data *out_ar,
                const nd::arrfunc& elwise_reduction_arr,
                const ndt::type& lifted_arr_type,
                const nd::arrfunc& dst_initialization_arr,
                bool keepdims,
                intptr_t reduction_ndim,
                const bool *reduction_dimflags,
                bool associative,
                bool commutative,
                bool right_associative,
                const nd::array& reduction_identity)
{
    // Validate the input elwise_reduction arrfunc
    if (elwise_reduction_arr.is_null()) {
        throw runtime_error("lift_reduction_arrfunc: 'elwise_reduction' may not be empty");
    }
    const arrfunc_type_data *elwise_reduction = elwise_reduction_arr.get();
    if (elwise_reduction->get_param_count() != 1 &&
            !(elwise_reduction->get_param_count() == 2 &&
              elwise_reduction->get_param_type(0) ==
                  elwise_reduction->get_param_type(1) &&
              elwise_reduction->get_param_type(0) ==
                  elwise_reduction->get_return_type())) {
        stringstream ss;
        ss << "lift_reduction_arrfunc: 'elwise_reduction' must contain a"
              " unary operation ckernel or a binary expr ckernel with all "
              "equal types, its prototype is " << elwise_reduction->func_proto;
        throw invalid_argument(ss.str());
    }

    lifted_reduction_arrfunc_data *self = new lifted_reduction_arrfunc_data;
    *out_ar->get_data_as<lifted_reduction_arrfunc_data *>() = self;
    out_ar->free_func = &delete_lifted_reduction_arrfunc_data;
    self->child_elwise_reduction = elwise_reduction_arr;
    self->child_dst_initialization = dst_initialization_arr;
    if (!reduction_identity.is_null()) {
        if (reduction_identity.is_immutable() &&
                reduction_identity.get_type() == elwise_reduction->get_return_type()) {
            self->reduction_identity = reduction_identity;
        } else {
            self->reduction_identity = nd::empty(elwise_reduction->get_return_type());
            self->reduction_identity.vals() = reduction_identity;
            self->reduction_identity.flag_as_immutable();
        }
    }

    // Figure out the result type
    ndt::type lifted_dst_type = elwise_reduction->get_return_type();
    for (intptr_t i = reduction_ndim - 1; i >= 0; --i) {
        if (reduction_dimflags[i]) {
            if (keepdims) {
                lifted_dst_type = ndt::make_strided_dim(lifted_dst_type);
            }
        } else {
            ndt::type subtype = lifted_arr_type.get_type_at_dimension(NULL, i);
            switch (subtype.get_type_id()) {
                case strided_dim_type_id:
                case cfixed_dim_type_id:
                    lifted_dst_type = ndt::make_strided_dim(lifted_dst_type);
                    break;
                case var_dim_type_id:
                    lifted_dst_type = ndt::make_var_dim(lifted_dst_type);
                    break;
                default: {
                    stringstream ss;
                    ss << "lift_reduction_arrfunc: don't know how to process ";
                    ss << "dimension of type " << subtype;
                    throw type_error(ss.str());
                }
            }
        }
    }
    self->data_types[0] = lifted_dst_type;
    self->data_types[1] = lifted_arr_type;
    self->reduction_ndim = reduction_ndim;
    self->associative = associative;
    self->commutative = commutative;
    self->right_associative = right_associative;
    self->reduction_dimflags.init(reduction_ndim);
    memcpy(self->reduction_dimflags.get(), reduction_dimflags, sizeof(bool) * reduction_ndim);

    out_ar->instantiate = &instantiate_lifted_reduction_arrfunc_data;
    out_ar->func_proto = ndt::make_funcproto(lifted_arr_type, lifted_dst_type);
}