/**
 * This function promotes the requested `axis` from
 * a strided dim to a var dim. It modifies `shape`, `coord`,
 * `elem`, and `arr` to point to a new array, and
 * copies the data over.
 */
static void promote_nd_arr_dim(std::vector<intptr_t> &shape,
                               std::vector<afpd_coordentry> &coord,
                               afpd_dtype &elem, nd::array &arr, intptr_t axis,
                               bool copy_final_coord)
{
  vector<afpd_coordentry> newcoord;
  afpd_dtype newelem;
  newelem.dtp = elem.dtp;
  // Convert the axis into a var dim
  shape[axis] = -1;
  // Create the new array
  nd::array newarr = allocate_nd_arr(shape, newcoord, newelem, axis);
  // Copy the data up to, but not including, the current `coord`
  // from the old `arr` to the new one. The recursion stops
  // at `axis`, where all subsequent dimensions are handled by the
  // created kernel.
  ckernel_builder<kernel_request_host> k;
  if (elem.dtp.get_type_id() != uninitialized_type_id) {
    make_assignment_kernel(&k, 0, newcoord[axis].tp, newcoord[axis].arrmeta_ptr,
                           coord[axis].tp, coord[axis].arrmeta_ptr,
                           kernel_request_strided, &eval::default_eval_context);
  }
  copy_to_promoted_nd_arr(shape, newarr.get_readwrite_originptr(), newcoord,
                          newelem, arr.get_readonly_originptr(), coord, elem, k,
                          0, axis, copy_final_coord, true);
  arr.swap(newarr);
  coord.swap(newcoord);
  elem.swap(newelem);
}
示例#2
0
 inline static bool run(nd::array &a)
 {
   const ndt::type &tp = a.get_type();
   if (a.is_immutable() && tp.get_type_id() == fixed_dim_type_id) {
     // It's immutable and "N * <something>"
     const ndt::type &et = tp.extended<fixed_dim_type>()->get_element_type();
     const fixed_dim_type_arrmeta *md =
         reinterpret_cast<const fixed_dim_type_arrmeta *>(a.get_arrmeta());
     if (et.get_type_id() == type_type_id &&
         md->stride == sizeof(ndt::type)) {
       // It also has the right type and is contiguous,
       // so no modification necessary.
       return true;
     }
   }
   // We have to make a copy, check that it's a 1D array, and that
   // it has the same array kind as the requested type.
   if (tp.get_ndim() == 1) {
     // It's a 1D array
     const ndt::type &et = tp.get_type_at_dimension(NULL, 1).value_type();
     if (et.get_type_id() == type_type_id) {
       // It also has the same array type as requested
       nd::array tmp = nd::empty(a.get_dim_size(), ndt::make_type());
       tmp.vals() = a;
       tmp.flag_as_immutable();
       a.swap(tmp);
       return true;
     }
   }
   // It's not compatible, so return false
   return false;
 }
/**
 * This function promotes the dtype the array currently has with
 * `tp`, allocates a new one, then copies all the data up to the
 * current index in `coord`. This modifies coord and elem in place.
 */
static void promote_nd_arr_dtype(const std::vector<intptr_t> &shape,
                                 std::vector<afpd_coordentry> &coord,
                                 afpd_dtype &elem, nd::array &arr,
                                 const ndt::type &tp)
{
  intptr_t ndim = shape.size();
  vector<afpd_coordentry> newcoord;
  afpd_dtype newelem;
  if (elem.dtp.get_type_id() == uninitialized_type_id) {
    // If the `elem` dtype is uninitialized, it means a dummy
    // array was created to capture dimensional structure until
    // the first value is encountered
    newelem.dtp = tp;
  } else {
    newelem.dtp = promote_types_arithmetic(elem.dtp, tp);
  }
  // Create the new array
  nd::array newarr = allocate_nd_arr(shape, newcoord, newelem, ndim);
  // Copy the data up to, but not including, the current `coord`
  // from the old `arr` to the new one
  ckernel_builder<kernel_request_host> k;
  if (elem.dtp.get_type_id() != uninitialized_type_id) {
    make_assignment_kernel(&k, 0, newelem.dtp, newelem.arrmeta_ptr, elem.dtp,
                           elem.arrmeta_ptr, kernel_request_strided,
                           &eval::default_eval_context);
  } else {
    // An assignment kernel which copies one byte - will only
    // be called with count==0 when dtp is uninitialized
    make_assignment_kernel(&k, 0, ndt::type::make<char>(), NULL,
                           ndt::type::make<char>(), NULL,
                           kernel_request_strided, &eval::default_eval_context);
  }
  copy_to_promoted_nd_arr(shape, newarr.get_readwrite_originptr(), newcoord,
                          newelem, arr.get_readonly_originptr(), coord, elem, k,
                          0, ndim, false, true);
  arr.swap(newarr);
  coord.swap(newcoord);
  elem.swap(newelem);
}
示例#4
0
 inline void swap(nd::arrfunc &rhs) { m_value.swap(rhs.m_value); }