array constant(cfloat val, const dim4 &dims) { af_array res; AF_THROW(af_constant_complex(&res, real(val), imag(val), dims.ndims(), dims.get(), c32)); return array(res); }
array constant(T val, const dim4 &dims, const af::dtype type) { af_array res; if (type != s64 && type != u64) { AF_THROW(af_constant(&res, (double)val, dims.ndims(), dims.get(), type)); } else if (type == s64) { AF_THROW(af_constant_long (&res, ( intl)val, dims.ndims(), dims.get())); } else { AF_THROW(af_constant_ulong(&res, (uintl)val, dims.ndims(), dims.get())); } return array(res); }
dim4 calcStrides(const dim4 &parentDim) { dim4 out(1, 1, 1, 1); dim_t *out_dims = out.get(); const dim_t *parent_dims = parentDim.get(); for (dim_t i=1; i < 4; i++) { out_dims[i] = out_dims[i - 1] * parent_dims[i-1]; } return out; }
AFAPI array constant(cdouble val, const dim4 &dims, const af::dtype type) { if (type != c32 && type != c64) { return constant(real(val), dims, type); } af_array res; AF_THROW(af_constant_complex(&res, real(val), imag(val), dims.ndims(), dims.get(), type)); return array(res); }
void fast_pyramid(std::vector<unsigned>& feat_pyr, std::vector<float*>& d_x_pyr, std::vector<float*>& d_y_pyr, std::vector<unsigned>& lvl_best, std::vector<float>& lvl_scl, std::vector<CParam<T> >& img_pyr, CParam<T> in, const float fast_thr, const unsigned max_feat, const float scl_fctr, const unsigned levels, const unsigned patch_size) { unsigned min_side = std::min(in.dims[0], in.dims[1]); unsigned max_levels = 0; float scl_sum = 0.f; for (unsigned i = 0; i < levels; i++) { min_side /= scl_fctr; // Minimum image side for a descriptor to be computed if (min_side < patch_size || max_levels == levels) break; max_levels++; scl_sum += 1.f / (float)std::pow(scl_fctr,(float)i); } // Compute number of features to keep for each level lvl_best.resize(max_levels); lvl_scl.resize(max_levels); unsigned feat_sum = 0; for (unsigned i = 0; i < max_levels-1; i++) { float scl = (float)std::pow(scl_fctr,(float)i); lvl_scl[i] = scl; lvl_best[i] = ceil((max_feat / scl_sum) / lvl_scl[i]); feat_sum += lvl_best[i]; } lvl_scl[max_levels-1] = (float)std::pow(scl_fctr,(float)max_levels-1); lvl_best[max_levels-1] = max_feat - feat_sum; // Hold multi-scale image pyramids static const dim4 dims0; static const CParam<T> emptyCParam(NULL, dims0.get(), dims0.get()); // Need to do this as CParam does not have a default constructor // And resize needs a default constructor or default value prior to C++11 img_pyr.resize(max_levels, emptyCParam); // Create multi-scale image pyramid for (unsigned i = 0; i < max_levels; i++) { if (i == 0) { // First level is used in its original size img_pyr[i].ptr = in.ptr; for (int k = 0; k < 4; k++) { img_pyr[i].dims[k] = in.dims[k]; img_pyr[i].strides[k] = in.strides[k]; } } else { // Resize previous level image to current level dimensions Param<T> lvl_img; lvl_img.dims[0] = round(in.dims[0] / lvl_scl[i]); lvl_img.dims[1] = round(in.dims[1] / lvl_scl[i]); lvl_img.strides[0] = 1; lvl_img.strides[1] = lvl_img.dims[0] * lvl_img.strides[0]; for (int k = 2; k < 4; k++) { lvl_img.dims[k] = 1; lvl_img.strides[k] = lvl_img.dims[k - 1] * lvl_img.strides[k - 1]; } int lvl_elem = lvl_img.strides[3] * lvl_img.dims[3]; lvl_img.ptr = memAlloc<T>(lvl_elem); resize<T, AF_INTERP_BILINEAR>(lvl_img, img_pyr[i-1]); img_pyr[i].ptr = lvl_img.ptr; for (int k = 0; k < 4; k++) { img_pyr[i].dims[k] = lvl_img.dims[k]; img_pyr[i].strides[k] = lvl_img.strides[k]; } } } feat_pyr.resize(max_levels); d_x_pyr.resize(max_levels); d_y_pyr.resize(max_levels); for (unsigned i = 0; i < max_levels; i++) { unsigned lvl_feat = 0; float* d_x_feat = NULL; float* d_y_feat = NULL; float* d_score_feat = NULL; // Round feature size to nearest odd integer float size = 2.f * floor(patch_size / 2.f) + 1.f; // Avoid keeping features that are too wide and might not fit the image, // sqrt(2.f) is the radius when angle is 45 degrees and represents // widest case possible unsigned edge = ceil(size * sqrt(2.f) / 2.f); // Detects FAST features fast(&lvl_feat, &d_x_feat, &d_y_feat, &d_score_feat, img_pyr[i], fast_thr, 9, 1, 0.15f, edge); // FAST score is not used memFree(d_score_feat); if (lvl_feat == 0) { feat_pyr[i] = 0; d_x_pyr[i] = NULL; d_x_pyr[i] = NULL; } else { feat_pyr[i] = lvl_feat; d_x_pyr[i] = d_x_feat; d_y_pyr[i] = d_y_feat; } } }
// Assign values to an array array::array_proxy& af::array::array_proxy::operator=(const array &other) { unsigned nd = numDims(impl->parent_->get()); const dim4 this_dims = getDims(impl->parent_->get()); const dim4 other_dims = other.dims(); int dim = gforDim(impl->indices_); af_array other_arr = other.get(); bool batch_assign = false; bool is_reordered = false; if (dim >= 0) { //FIXME: Figure out a faster, cleaner way to do this dim4 out_dims = seqToDims(impl->indices_, this_dims, false); batch_assign = true; for (int i = 0; i < AF_MAX_DIMS; i++) { if (this->impl->indices_[i].isBatch) batch_assign &= (other_dims[i] == 1); else batch_assign &= (other_dims[i] == out_dims[i]); } if (batch_assign) { af_array out; AF_THROW(af_tile(&out, other_arr, out_dims[0] / other_dims[0], out_dims[1] / other_dims[1], out_dims[2] / other_dims[2], out_dims[3] / other_dims[3])); other_arr = out; } else if (out_dims != other_dims) { // HACK: This is a quick check to see if other has been reordered inside gfor // TODO: Figure out if this breaks and implement a cleaner method other_arr = gforReorder(other_arr, dim); is_reordered = true; } } af_array par_arr = 0; if (impl->is_linear_) { AF_THROW(af_flat(&par_arr, impl->parent_->get())); nd = 1; } else { par_arr = impl->parent_->get(); } af_array tmp = 0; AF_THROW(af_assign_gen(&tmp, par_arr, nd, impl->indices_, other_arr)); af_array res = 0; if (impl->is_linear_) { AF_THROW(af_moddims(&res, tmp, this_dims.ndims(), this_dims.get())); AF_THROW(af_release_array(par_arr)); AF_THROW(af_release_array(tmp)); } else { res = tmp; } impl->parent_->set(res); if (dim >= 0 && (is_reordered || batch_assign)) { if (other_arr) AF_THROW(af_release_array(other_arr)); } return *this; }
array::array(const array& input, const dim4& dims) : arr(0) { AF_THROW(af_moddims(&arr, input.get(), AF_MAX_DIMS, dims.get())); }
array moddims(const array& in, const dim4& dims) { return af::moddims(in, dims.ndims(), dims.get()); }
array identity(const dim4 &dims, const af::dtype type) { af_array res; AF_THROW(af_identity(&res, dims.ndims(), dims.get(), type)); return array(res); }
array iota(const dim4 &dims, const dim4 &tile_dims, const af::dtype ty) { af_array out; AF_THROW(af_iota(&out, dims.ndims(), dims.get(), tile_dims.ndims(), tile_dims.get(), ty)); return array(out); }
array range(const dim4 &dims, const int seq_dim, const af::dtype ty) { af_array out; AF_THROW(af_range(&out, dims.ndims(), dims.get(), seq_dim, ty)); return array(out); }
array randn(const dim4 &dims, const af::dtype type) { af_array res; AF_THROW(af_randn(&res, dims.ndims(), dims.get(), type)); return array(res); }
array iota(const dim4 &dims, const unsigned rep, af_dtype ty) { af_array out; AF_THROW(af_iota(&out, dims.ndims(), dims.get(), rep, ty)); return array(out); }
array constant(double val, const dim4 &dims, af_dtype type) { af_array res; AF_THROW(af_constant(&res, val, dims.ndims(), dims.get(), type)); return array(res); }
array randn(const dim4 &dims, const dtype ty, randomEngine &r) { af_array out; AF_THROW(af_random_normal(&out, dims.ndims(), dims.get(), ty, r.get())); return array(out); }