Example #1
0
fg::Plot3* setup_plot3(const af_array P, fg::PlotType ptype, fg::MarkerType mtype)
{
    Array<T> pIn = getArray<T>(P);
    ArrayInfo Pinfo = getInfo(P);
    af::dim4 P_dims = Pinfo.dims();

    DIM_ASSERT(0, Pinfo.ndims() == 1 || Pinfo.ndims() == 2);
    DIM_ASSERT(0, (P_dims[0] == 3 || P_dims[1] == 3) ||
                    (Pinfo.isVector() && P_dims[0]%3 == 0));

    if(Pinfo.isVector()){
        dim4 rdims(P_dims.elements()/3, 3, 1, 1);
        pIn.modDims(rdims);
        P_dims = pIn.dims();
    }

    if(P_dims[1] == 3){
        pIn = transpose(pIn, false);
    }

    T max[3], min[3];
    copyData(max, reduce<af_max_t, T, T>(pIn, 1));
    copyData(min, reduce<af_min_t, T, T>(pIn, 1));

    ForgeManager& fgMngr = ForgeManager::getInstance();
    fg::Plot3* plot3 = fgMngr.getPlot3(P_dims.elements()/3, getGLType<T>(), ptype, mtype);
    plot3->setColor(1.0, 0.0, 0.0);
    plot3->setAxesLimits(max[0], min[0],
                         max[1], min[1],
                         max[2], min[2]);
    plot3->setAxesTitles("X Axis", "Y Axis", "Z Axis");
    copy_plot3<T>(pIn, plot3);
    return plot3;
}
Example #2
0
af_err af_replace_scalar(af_array a, const af_array cond, const double b)
{
    try {
        ArrayInfo ainfo = getInfo(a);
        ArrayInfo cinfo = getInfo(cond);

        ARG_ASSERT(1, cinfo.getType() == b8);
        DIM_ASSERT(1, cinfo.ndims() == ainfo.ndims());

        dim4 adims = ainfo.dims();
        dim4 cdims = cinfo.dims();

        for (int i = 0; i < 4; i++) {
            DIM_ASSERT(1, cdims[i] == adims[i]);
        }

        switch (ainfo.getType()) {
        case f32: replace_scalar<float  >(a, cond, b); break;
        case f64: replace_scalar<double >(a, cond, b); break;
        case c32: replace_scalar<cfloat >(a, cond, b); break;
        case c64: replace_scalar<cdouble>(a, cond, b); break;
        case s32: replace_scalar<int    >(a, cond, b); break;
        case u32: replace_scalar<uint   >(a, cond, b); break;
        case s64: replace_scalar<intl   >(a, cond, b); break;
        case u64: replace_scalar<uintl  >(a, cond, b); break;
        case u8:  replace_scalar<uchar  >(a, cond, b); break;
        case b8:  replace_scalar<char   >(a, cond, b); break;
        default:  TYPE_ERROR(2, ainfo.getType());
        }

    } CATCHALL;
    return AF_SUCCESS;
}
Example #3
0
af_err af_matmul(af_array *out,
                 const af_array lhs, const af_array rhs,
                 const af_mat_prop optLhs, const af_mat_prop optRhs)
{
    using namespace detail;

    try {
        ArrayInfo lhsInfo = getInfo(lhs, false, true);
        ArrayInfo rhsInfo = getInfo(rhs, true, true);

        if(lhsInfo.isSparse())
            return af_sparse_matmul(out, lhs, rhs, optLhs, optRhs);

        af_dtype lhs_type = lhsInfo.getType();
        af_dtype rhs_type = rhsInfo.getType();

        if (!(optLhs == AF_MAT_NONE ||
              optLhs == AF_MAT_TRANS ||
              optLhs == AF_MAT_CTRANS)) {
            AF_ERROR("Using this property is not yet supported in matmul", AF_ERR_NOT_SUPPORTED);
        }

        if (!(optRhs == AF_MAT_NONE ||
              optRhs == AF_MAT_TRANS ||
              optRhs == AF_MAT_CTRANS)) {
            AF_ERROR("Using this property is not yet supported in matmul", AF_ERR_NOT_SUPPORTED);
        }


        if (lhsInfo.ndims() > 2 ||
            rhsInfo.ndims() > 2) {
            AF_ERROR("matmul can not be used in batch mode", AF_ERR_BATCH);
        }

        TYPE_ASSERT(lhs_type == rhs_type);
        af_array output = 0;

        int aColDim = (optLhs == AF_MAT_NONE) ? 1 : 0;
        int bRowDim = (optRhs == AF_MAT_NONE) ? 0 : 1;

        DIM_ASSERT(1, lhsInfo.dims()[aColDim] == rhsInfo.dims()[bRowDim]);

        switch(lhs_type) {
            case f32: output = matmul<float  >(lhs, rhs, optLhs, optRhs);   break;
            case c32: output = matmul<cfloat >(lhs, rhs, optLhs, optRhs);   break;
            case f64: output = matmul<double >(lhs, rhs, optLhs, optRhs);   break;
            case c64: output = matmul<cdouble>(lhs, rhs, optLhs, optRhs);   break;
            default:  TYPE_ERROR(1, lhs_type);
        }
        std::swap(*out, output);
    }
    CATCHALL
    return AF_SUCCESS;
}
Example #4
0
af_err af_select(af_array *out, const af_array cond, const af_array a, const af_array b)
{
    try {
        ArrayInfo ainfo = getInfo(a);
        ArrayInfo binfo = getInfo(b);
        ArrayInfo cinfo = getInfo(cond);

        if(cinfo.ndims() == 0) {
            return af_retain_array(out, cond);
        }

        ARG_ASSERT(2, ainfo.getType() == binfo.getType());
        ARG_ASSERT(1, cinfo.getType() == b8);

        DIM_ASSERT(1, cinfo.ndims() == std::min(ainfo.ndims(), binfo.ndims()));

        dim4 adims = ainfo.dims();
        dim4 bdims = binfo.dims();
        dim4 cdims = cinfo.dims();
        dim4 odims(1, 1, 1, 1);

        for (int i = 0; i < 4; i++) {
            DIM_ASSERT(1, cdims[i] == std::min(adims[i], bdims[i]));
            DIM_ASSERT(2, adims[i] == bdims[i] || adims[i] == 1 || bdims[i] == 1);
            odims[i] = std::max(adims[i], bdims[i]);
        }

        af_array res;

        switch (ainfo.getType()) {
        case f32: res = select<float  >(cond, a, b, odims); break;
        case f64: res = select<double >(cond, a, b, odims); break;
        case c32: res = select<cfloat >(cond, a, b, odims); break;
        case c64: res = select<cdouble>(cond, a, b, odims); break;
        case s32: res = select<int    >(cond, a, b, odims); break;
        case u32: res = select<uint   >(cond, a, b, odims); break;
        case s64: res = select<intl   >(cond, a, b, odims); break;
        case u64: res = select<uintl  >(cond, a, b, odims); break;
        case s16: res = select<short  >(cond, a, b, odims); break;
        case u16: res = select<ushort >(cond, a, b, odims); break;
        case u8:  res = select<uchar  >(cond, a, b, odims); break;
        case b8:  res = select<char   >(cond, a, b, odims); break;
        default:  TYPE_ERROR(2, ainfo.getType());
        }

        std::swap(*out, res);
    } CATCHALL;
    return AF_SUCCESS;
}
Example #5
0
af_err af_cplx(af_array *out, const af_array in)
{
    try {

        ArrayInfo info = getInfo(in);
        af_dtype type = info.getType();

        if (type == c32 || type == c64) {
            AF_ERROR("Inputs to cplx2 can not be of complex type", AF_ERR_ARG);
        }

        af_array tmp;
        AF_CHECK(af_constant(&tmp,
                             0, info.ndims(),
                             info.dims().get(),
                             type));

        af_array res;
        switch (type) {

        case f32: res = cplx<cfloat , float >(in, tmp, false); break;
        case f64: res = cplx<cdouble, double>(in, tmp, false); break;

        default: TYPE_ERROR(0, type);
        }

        AF_CHECK(af_destroy_array(tmp));

        std::swap(*out, res);
    }
    CATCHALL;
    return AF_SUCCESS;
}
Example #6
0
af_err af_imag(af_array *out, const af_array in)
{
    try {

        ArrayInfo info = getInfo(in);
        af_dtype type = info.getType();

        if (type != c32 && type != c64) {
            return af_constant(out, 0, info.ndims(), info.dims().get(), type);
        }

        af_array res;
        switch (type) {

        case c32: res = getHandle(imag<float , cfloat >(getArray<cfloat >(in))); break;
        case c64: res = getHandle(imag<double, cdouble>(getArray<cdouble>(in))); break;

        default: TYPE_ERROR(0, type);
        }

        std::swap(*out, res);
    }
    CATCHALL;
    return AF_SUCCESS;
}
Example #7
0
//Strong Exception Guarantee
af_err af_copy_array(af_array *out, const af_array in)
{
    try {
        ArrayInfo info = getInfo(in);
        const af_dtype type = info.getType();

        if(info.ndims() == 0) {
            dim_t my_dims[] = {0, 0, 0, 0};
            return af_create_handle(out, AF_MAX_DIMS, my_dims, type);
        }

        af_array res;
        switch(type) {
        case f32:   res = copyArray<float   >(in); break;
        case c32:   res = copyArray<cfloat  >(in); break;
        case f64:   res = copyArray<double  >(in); break;
        case c64:   res = copyArray<cdouble >(in); break;
        case b8:    res = copyArray<char    >(in); break;
        case s32:   res = copyArray<int     >(in); break;
        case u32:   res = copyArray<uint    >(in); break;
        case u8:    res = copyArray<uchar   >(in); break;
        case s64:   res = copyArray<intl    >(in); break;
        case u64:   res = copyArray<uintl   >(in); break;
        case s16:   res = copyArray<short   >(in); break;
        case u16:   res = copyArray<ushort  >(in); break;
        default:    TYPE_ERROR(1, type);
        }
        std::swap(*out, res);
    }
    CATCHALL
    return AF_SUCCESS;
}
Example #8
0
static void print(af_array arr)
{
    const ArrayInfo info = getInfo(arr);
    T *data = new T[info.elements()];

    af_array arrT;
    AF_CHECK(af_reorder(&arrT, arr, 1, 0, 2, 3));

    //FIXME: Use alternative function to avoid copies if possible
    AF_CHECK(af_get_data_ptr(data, arrT));
    const ArrayInfo infoT = getInfo(arrT);
    AF_CHECK(af_destroy_array(arrT));

    std::ios_base::fmtflags backup = std::cout.flags();

    std::cout << "[" << info.dims() << "]\n";
#ifndef NDEBUG
    std::cout <<"   Offsets: ["<<info.offsets()<<"]"<<std::endl;
    std::cout <<"   Strides: ["<<info.strides()<<"]"<<std::endl;
#endif

    printer(std::cout, data, infoT, infoT.ndims() - 1);

    delete[] data;

    std::cout.flags(backup);
}
Example #9
0
af_err af_tile(af_array *out, const af_array in, const af::dim4 &tileDims)
{
    try {
        ArrayInfo info = getInfo(in);
        af_dtype type = info.getType();

        if(info.ndims() == 0) {
            return af_retain_array(out, in);
        }
        DIM_ASSERT(1, info.dims().elements() > 0);
        DIM_ASSERT(2, tileDims.elements() > 0);

        af_array output;

        switch(type) {
            case f32: output = tile<float  >(in, tileDims);  break;
            case c32: output = tile<cfloat >(in, tileDims);  break;
            case f64: output = tile<double >(in, tileDims);  break;
            case c64: output = tile<cdouble>(in, tileDims);  break;
            case b8:  output = tile<char   >(in, tileDims);  break;
            case s32: output = tile<int    >(in, tileDims);  break;
            case u32: output = tile<uint   >(in, tileDims);  break;
            case s64: output = tile<intl   >(in, tileDims);  break;
            case u64: output = tile<uintl  >(in, tileDims);  break;
            case s16: output = tile<short  >(in, tileDims);  break;
            case u16: output = tile<ushort >(in, tileDims);  break;
            case u8:  output = tile<uchar  >(in, tileDims);  break;
            default:  TYPE_ERROR(1, type);
        }
        std::swap(*out,output);
    }
    CATCHALL;

    return AF_SUCCESS;
}
Example #10
0
//Strong Exception Guarantee
af_err af_copy_array(af_array *out, const af_array in)
{
    ArrayInfo info = getInfo(in);
    const unsigned ndims = info.ndims();
    const af::dim4 dims = info.dims();
    const af_dtype type = info.getType();

    af_err ret = AF_ERR_ARG;

    ret = af_create_handle(out, ndims, dims.get(), type);
    if(ret != AF_SUCCESS) {
        return ret;
    }

    try {
        switch(type) {
        case f32:   copyArray<float   >(out, in); break;
        case c32:   copyArray<cfloat  >(out, in); break;
        case f64:   copyArray<double  >(out, in); break;
        case c64:   copyArray<cdouble >(out, in); break;
        case b8:    copyArray<char    >(out, in); break;
        case s32:   copyArray<int     >(out, in); break;
        case u32:   copyArray<unsigned>(out, in); break;
        case u8:    copyArray<uchar   >(out, in); break;
        default:    ret = AF_ERR_NOT_SUPPORTED;   break;
        }
    }
    CATCHALL
    return ret;
}
Example #11
0
af_err af_dot(      af_array *out,
                    const af_array lhs, const af_array rhs,
                    const af_mat_prop optLhs, const af_mat_prop optRhs)
{
    using namespace detail;

    try {
        ArrayInfo lhsInfo = getInfo(lhs);
        ArrayInfo rhsInfo = getInfo(rhs);

        if (optLhs != AF_MAT_NONE && optLhs != AF_MAT_CONJ) {
            AF_ERROR("Using this property is not yet supported in dot", AF_ERR_NOT_SUPPORTED);
        }

        if (optRhs != AF_MAT_NONE && optRhs != AF_MAT_CONJ) {
            AF_ERROR("Using this property is not yet supported in dot", AF_ERR_NOT_SUPPORTED);
        }

        DIM_ASSERT(1, lhsInfo.dims()[0] == rhsInfo.dims()[0]);
        af_dtype lhs_type = lhsInfo.getType();
        af_dtype rhs_type = rhsInfo.getType();

        if(lhsInfo.ndims() == 0) {
            return af_retain_array(out, lhs);
        }
        if (lhsInfo.ndims() > 1 ||
            rhsInfo.ndims() > 1) {
            AF_ERROR("dot can not be used in batch mode", AF_ERR_BATCH);
        }

        TYPE_ASSERT(lhs_type == rhs_type);

        af_array output = 0;

        switch(lhs_type) {
        case f32: output = dot<float  >(lhs, rhs, optLhs, optRhs);    break;
        case c32: output = dot<cfloat >(lhs, rhs, optLhs, optRhs);    break;
        case f64: output = dot<double >(lhs, rhs, optLhs, optRhs);    break;
        case c64: output = dot<cdouble>(lhs, rhs, optLhs, optRhs);    break;
        default:  TYPE_ERROR(1, lhs_type);
        }
        std::swap(*out, output);
    }
    CATCHALL
        return AF_SUCCESS;
}
Example #12
0
af_err af_get_numdims(unsigned *nd, const af_array in)
{
    try {
        ArrayInfo info = getInfo(in);
        *nd = info.ndims();
    }
    CATCHALL
    return AF_SUCCESS;
}
Example #13
0
af_err af_get_numdims(unsigned *nd, const af_array in)
{
    try {
        // Do not check for device mismatch
        ArrayInfo info = getInfo(in, false, false);
        *nd = info.ndims();
    }
    CATCHALL
    return AF_SUCCESS;
}
Example #14
0
af_err af_sparse_matmul(af_array *out,
                        const af_array lhs, const af_array rhs,
                        const af_mat_prop optLhs, const af_mat_prop optRhs)
{
    using namespace detail;

    try {
        common::SparseArrayBase lhsBase = getSparseArrayBase(lhs);
        ArrayInfo rhsInfo = getInfo(rhs);

        ARG_ASSERT(2, lhsBase.isSparse() == true && rhsInfo.isSparse() == false);

        af_dtype lhs_type = lhsBase.getType();
        af_dtype rhs_type = rhsInfo.getType();

        ARG_ASSERT(1, lhsBase.getStorage() == AF_STORAGE_CSR);

        if (!(optLhs == AF_MAT_NONE ||
              optLhs == AF_MAT_TRANS ||
              optLhs == AF_MAT_CTRANS)) {   // Note the ! operator.
            AF_ERROR("Using this property is not yet supported in sparse matmul", AF_ERR_NOT_SUPPORTED);
        }

        // No transpose options for RHS
        if (optRhs != AF_MAT_NONE) {
            AF_ERROR("Using this property is not yet supported in matmul", AF_ERR_NOT_SUPPORTED);
        }

        if (rhsInfo.ndims() > 2) {
            AF_ERROR("Sparse matmul can not be used in batch mode", AF_ERR_BATCH);
        }

        TYPE_ASSERT(lhs_type == rhs_type);

        af::dim4 ldims = lhsBase.dims();
        int lColDim = (optLhs == AF_MAT_NONE) ? 1 : 0;
        int rRowDim = (optRhs == AF_MAT_NONE) ? 0 : 1;

        DIM_ASSERT(1, ldims[lColDim] == rhsInfo.dims()[rRowDim]);

        af_array output = 0;
        switch(lhs_type) {
            case f32: output = sparseMatmul<float  >(lhs, rhs, optLhs, optRhs);   break;
            case c32: output = sparseMatmul<cfloat >(lhs, rhs, optLhs, optRhs);   break;
            case f64: output = sparseMatmul<double >(lhs, rhs, optLhs, optRhs);   break;
            case c64: output = sparseMatmul<cdouble>(lhs, rhs, optLhs, optRhs);   break;
            default:  TYPE_ERROR(1, lhs_type);
        }
        std::swap(*out, output);

    } CATCHALL;

    return AF_SUCCESS;
}
Example #15
0
af_err af_get_numdims(unsigned *nd, const af_array in)
{
    af_err ret = AF_ERR_ARG;
    try {
        ArrayInfo info = getInfo(in);
        *nd = info.ndims();
        ret = AF_SUCCESS;
    }
    CATCHALL
    return ret;
}
Example #16
0
af_err af_select_scalar_r(af_array *out, const af_array cond, const af_array a, const double b)
{
    try {
        ArrayInfo ainfo = getInfo(a);
        ArrayInfo cinfo = getInfo(cond);

        ARG_ASSERT(1, cinfo.getType() == b8);
        DIM_ASSERT(1, cinfo.ndims() == ainfo.ndims());

        dim4 adims = ainfo.dims();
        dim4 cdims = cinfo.dims();

        for (int i = 0; i < 4; i++) {
            DIM_ASSERT(1, cdims[i] == adims[i]);
        }

        af_array res;

        switch (ainfo.getType()) {
        case f32: res = select_scalar<float  , false>(cond, a, b, adims); break;
        case f64: res = select_scalar<double , false>(cond, a, b, adims); break;
        case c32: res = select_scalar<cfloat , false>(cond, a, b, adims); break;
        case c64: res = select_scalar<cdouble, false>(cond, a, b, adims); break;
        case s32: res = select_scalar<int    , false>(cond, a, b, adims); break;
        case u32: res = select_scalar<uint   , false>(cond, a, b, adims); break;
        case s16: res = select_scalar<short  , false>(cond, a, b, adims); break;
        case u16: res = select_scalar<ushort , false>(cond, a, b, adims); break;
        case s64: res = select_scalar<intl   , false>(cond, a, b, adims); break;
        case u64: res = select_scalar<uintl  , false>(cond, a, b, adims); break;
        case u8:  res = select_scalar<uchar  , false>(cond, a, b, adims); break;
        case b8:  res = select_scalar<char   , false>(cond, a, b, adims); break;
        default:  TYPE_ERROR(2, ainfo.getType());
        }

        std::swap(*out, res);
    } CATCHALL;
    return AF_SUCCESS;
}
Example #17
0
af_err af_topk(af_array *values, af_array *indices, const af_array in,
               const int k, const int dim, const af_topk_function order) {
    try {
        af::topkFunction ord = (order == AF_TOPK_DEFAULT ? AF_TOPK_MAX : order);

        ArrayInfo inInfo = getInfo(in);

        ARG_ASSERT(2, (inInfo.ndims() > 0));

        if (inInfo.elements() == 1) {
            dim_t dims[1]   = {1};
            af_err errValue = af_constant(indices, 0, 1, dims, u32);
            return errValue == AF_SUCCESS ? af_retain_array(values, in)
                                          : errValue;
        }

        int rdim     = dim;
        auto &inDims = inInfo.dims();

        if (rdim == -1) {
            for (dim_t d = 0; d < 4; d++) {
                if (inDims[d] > 1) {
                    rdim = d;
                    break;
                }
            }
        }

        ARG_ASSERT(2, (inInfo.dims()[rdim] >= k));
        ARG_ASSERT(4, (k <= 256));  // TODO(umar): Remove this limitation

        if (rdim != 0)
            AF_ERROR("topk is supported along dimenion 0 only.",
                     AF_ERR_NOT_SUPPORTED);

        af_dtype type = inInfo.getType();

        switch (type) {
            // TODO(umar): FIX RETURN VALUES HERE
            case f32: topk<float>(values, indices, in, k, rdim, ord); break;
            case f64: topk<double>(values, indices, in, k, rdim, ord); break;
            case u32: topk<uint>(values, indices, in, k, rdim, ord); break;
            case s32: topk<int>(values, indices, in, k, rdim, ord); break;
            default: TYPE_ERROR(1, type);
        }
    }
    CATCHALL;

    return AF_SUCCESS;
}
Example #18
0
static void print(const char *exp, af_array arr, const int precision, std::ostream &os = std::cout, bool transpose = true)
{
    if(exp == NULL) {
        os << "No Name Array" << std::endl;
    } else {
        os << exp << std::endl;
    }

    const ArrayInfo info = getInfo(arr);
    vector<T> data(info.elements());

    af_array arrT;
    if(transpose) {
        AF_CHECK(af_reorder(&arrT, arr, 1, 0, 2, 3));
    } else {
        arrT = arr;
    }

    //FIXME: Use alternative function to avoid copies if possible
    AF_CHECK(af_get_data_ptr(&data.front(), arrT));
    const ArrayInfo infoT = getInfo(arrT);

    if(transpose) {
        AF_CHECK(af_release_array(arrT));
    }

    std::ios_base::fmtflags backup = os.flags();

    os << "[" << info.dims() << "]\n";
#ifndef NDEBUG
    os <<"   Offsets: [" << info.offsets() << "]" << std::endl;
    os <<"   Strides: [" << info.strides() << "]" << std::endl;
#endif

    printer(os, &data.front(), infoT, infoT.ndims() - 1, precision);

    os.flags(backup);
}
Example #19
0
af_err af_index(af_array *result, const af_array in, const unsigned ndims, const af_seq* index)
{
    af_array out;
    try {

        ArrayInfo iInfo = getInfo(in);
        if (ndims == 1 && ndims != (dim_t)iInfo.ndims()) {
            af_array tmp_in;
            AF_CHECK(af_flat(&tmp_in, in));
            AF_CHECK(af_index(result, tmp_in, ndims, index));
            AF_CHECK(af_release_array(tmp_in));
            return AF_SUCCESS;
        }

        af_dtype in_type = iInfo.getType();

        switch(in_type) {
        case f32:    indexArray<float>   (out, in, ndims, index);  break;
        case c32:    indexArray<cfloat>  (out, in, ndims, index);  break;
        case f64:    indexArray<double>  (out, in, ndims, index);  break;
        case c64:    indexArray<cdouble> (out, in, ndims, index);  break;
        case b8:     indexArray<char>    (out, in, ndims, index);  break;
        case s32:    indexArray<int>     (out, in, ndims, index);  break;
        case u32:    indexArray<unsigned>(out, in, ndims, index);  break;
        case s16:    indexArray<short>   (out, in, ndims, index);  break;
        case u16:    indexArray<ushort>  (out, in, ndims, index);  break;
        case s64:    indexArray<intl>    (out, in, ndims, index);  break;
        case u64:    indexArray<uintl>   (out, in, ndims, index);  break;
        case u8:     indexArray<uchar>   (out, in, ndims, index);  break;
        default:    TYPE_ERROR(1, in_type);
        }
    }
    CATCHALL

    swap(*result, out);
    return AF_SUCCESS;
}
Example #20
0
af_err af_root(af_array *out, const af_array lhs, const af_array rhs, const bool batchMode)
{
    try {
        ArrayInfo linfo = getInfo(lhs);
        ArrayInfo rinfo = getInfo(rhs);
        if (linfo.isComplex() || rinfo.isComplex()) {
            AF_ERROR("Powers of Complex numbers not supported", AF_ERR_NOT_SUPPORTED);
        }

        af_array one;
        AF_CHECK(af_constant(&one, 1, linfo.ndims(), linfo.dims().get(), linfo.getType()));

        af_array inv_lhs;
        AF_CHECK(af_div(&inv_lhs, one, lhs, batchMode));

        AF_CHECK(af_arith_real<af_pow_t>(out, rhs, inv_lhs, batchMode));

        AF_CHECK(af_release_array(one));
        AF_CHECK(af_release_array(inv_lhs));

    } CATCHALL;

    return AF_SUCCESS;
}
Example #21
0
static af_err reduce_promote(af_array *out, const af_array in, const int dim)
{
    try {

        ARG_ASSERT(2, dim >= 0);
        ARG_ASSERT(2, dim <  4);

        const ArrayInfo in_info = getInfo(in);

        if (dim >= (int)in_info.ndims()) {
            *out = weakCopy(in);
            return AF_SUCCESS;
        }

        af_dtype type = in_info.getType();
        af_array res;

        switch(type) {
        case f32:  res = reduce<op, float  , float  >(in, dim); break;
        case f64:  res = reduce<op, double , double >(in, dim); break;
        case c32:  res = reduce<op, cfloat , cfloat >(in, dim); break;
        case c64:  res = reduce<op, cdouble, cdouble>(in, dim); break;
        case u32:  res = reduce<op, uint   , uint   >(in, dim); break;
        case s32:  res = reduce<op, int    , int    >(in, dim); break;
        case u8:   res = reduce<op, uchar  , uint   >(in, dim); break;
        case s8:   res = reduce<op, char   , int    >(in, dim); break;
            // Make sure you are adding only "1" for every non zero value, even if op == af_add_t
        case b8:   res = reduce<af_notzero_t, uchar  , uint   >(in, dim); break;
        default:   TYPE_ERROR(1, type);
        }
        std::swap(*out, res);
    }
    CATCHALL;

    return AF_SUCCESS;
}
Example #22
0
static af_err reduce_common(af_array *out, const af_array in, const int dim)
{
    try {

        ARG_ASSERT(2, dim >= 0);
        ARG_ASSERT(2, dim <  4);

        const ArrayInfo in_info = getInfo(in);

        if (dim >= (int)in_info.ndims()) {
            *out = weakCopy(in);
            return AF_SUCCESS;
        }

        af_dtype type = in_info.getType();
        af_array res;

        switch(type) {
        case f32:  res = reduce<op, float  , float  >(in, dim); break;
        case f64:  res = reduce<op, double , double >(in, dim); break;
        case c32:  res = reduce<op, cfloat , cfloat >(in, dim); break;
        case c64:  res = reduce<op, cdouble, cdouble>(in, dim); break;
        case u32:  res = reduce<op, uint   , uint   >(in, dim); break;
        case s32:  res = reduce<op, int    , int    >(in, dim); break;
        case b8:   res = reduce<op, uchar  , uchar  >(in, dim); break;
        case u8:   res = reduce<op, uchar  , uchar  >(in, dim); break;
        case s8:   res = reduce<op, char   , char   >(in, dim); break;
        default:   TYPE_ERROR(1, type);
        }

        std::swap(*out, res);
    }
    CATCHALL;

    return AF_SUCCESS;
}
Example #23
0
af_err af_index_gen(af_array *out, const af_array in, const dim_t ndims, const af_index_t* indexs)
{
    af_array output = 0;
    // spanner is sequence index used for indexing along the
    // dimensions after ndims
    af_index_t spanner;
    spanner.idx.seq = af_span;
    spanner.isSeq = true;

    try {
        ARG_ASSERT(2, (ndims>0));
        ARG_ASSERT(3, (indexs!=NULL));

        ArrayInfo iInfo = getInfo(in);
        if (ndims == 1 && ndims != (dim_t)iInfo.ndims()) {
            af_array tmp_in;
            AF_CHECK(af_flat(&tmp_in, in));
            AF_CHECK(af_index_gen(out, tmp_in, ndims, indexs));
            AF_CHECK(af_release_array(tmp_in));
            return AF_SUCCESS;
        }

        int track = 0;
        af_seq seqs[] = {af_span, af_span, af_span, af_span};
        for (dim_t i = 0; i < ndims; i++) {
            if (indexs[i].isSeq) {
                track++;
                seqs[i] = indexs[i].idx.seq;
            }
        }

        if (track==(int)ndims) {
            // all indexs are sequences, redirecting to af_index
            return af_index(out, in, ndims, seqs);
        }

        af_index_t idxrs[4];
        // set all dimensions above ndims to spanner index
        for (dim_t i=ndims; i<4; ++i) idxrs[i] = spanner;

        for (dim_t i=0; i<ndims; ++i) {
            if (!indexs[i].isSeq) {
                // check if all af_arrays have atleast one value
                // to enable indexing along that dimension
                ArrayInfo idxInfo = getInfo(indexs[i].idx.arr);
                af_dtype idxType  = idxInfo.getType();

                ARG_ASSERT(3, (idxType!=c32));
                ARG_ASSERT(3, (idxType!=c64));
                ARG_ASSERT(3, (idxType!=b8 ));

                idxrs[i].idx.arr = indexs[i].idx.arr;
                idxrs[i].isSeq = indexs[i].isSeq;
            } else {
                // af_seq is being used for this dimension
                // just copy the index to local variable
                idxrs[i] = indexs[i];
            }
        }

        dim4 iDims = iInfo.dims();

        ARG_ASSERT(1, (iDims.ndims()>0));

        af_dtype inType = getInfo(in).getType();
        switch(inType) {
            case c64: output = genIndex<cdouble>(in, idxrs); break;
            case f64: output = genIndex<double >(in, idxrs); break;
            case c32: output = genIndex<cfloat >(in, idxrs); break;
            case f32: output = genIndex<float  >(in, idxrs); break;
            case u64: output = genIndex<uintl  >(in, idxrs); break;
            case s64: output = genIndex<intl   >(in, idxrs); break;
            case u32: output = genIndex<uint   >(in, idxrs); break;
            case s32: output = genIndex<int    >(in, idxrs); break;
            case u16: output = genIndex<ushort >(in, idxrs); break;
            case s16: output = genIndex<short  >(in, idxrs); break;
            case  u8: output = genIndex<uchar  >(in, idxrs); break;
            case  b8: output = genIndex<char   >(in, idxrs); break;
            default: TYPE_ERROR(1, inType);
        }
    }
    CATCHALL;

    std::swap(*out, output);

    return AF_SUCCESS;
}
Example #24
0
// Save an image to memory.
af_err af_save_image_memory(void **ptr, const af_array in_, const af_image_format format)
{
    try {

        FI_Init();

        // set your own FreeImage error handler
        FreeImage_SetOutputMessage(FreeImageErrorHandler);

        // try to guess the file format from the file extension
        FREE_IMAGE_FORMAT fif = (FREE_IMAGE_FORMAT)format;

        if(fif == FIF_UNKNOWN || fif > 34) { // FreeImage FREE_IMAGE_FORMAT has upto 34 enums as of 3.17
            AF_ERROR("FreeImage Error: Unknown Filetype", AF_ERR_NOT_SUPPORTED);
        }

        ArrayInfo info = getInfo(in_);
        // check image color type
        uint channels = info.dims()[2];
        DIM_ASSERT(1, channels <= 4);
        DIM_ASSERT(1, channels != 2);

        int fi_bpp = channels * 8;

        // sizes
        uint fi_w = info.dims()[1];
        uint fi_h = info.dims()[0];

        // create the result image storage using FreeImage
        FIBITMAP* pResultBitmap = FreeImage_Allocate(fi_w, fi_h, fi_bpp);
        if(pResultBitmap == NULL) {
            AF_ERROR("FreeImage Error: Error creating image or file", AF_ERR_RUNTIME);
        }

        // FI assumes [0-255]
        // If array is in 0-1 range, multiply by 255
        af_array in;
        double max_real, max_imag;
        bool free_in = false;
        AF_CHECK(af_max_all(&max_real, &max_imag, in_));
        if (max_real <= 1) {
            af_array c255;
            AF_CHECK(af_constant(&c255, 255.0, info.ndims(), info.dims().get(), f32));
            AF_CHECK(af_mul(&in, in_, c255, false));
            AF_CHECK(af_release_array(c255));
            free_in = true;
        } else {
            in = in_;
        }

        // FI = row major | AF = column major
        uint nDstPitch = FreeImage_GetPitch(pResultBitmap);
        uchar* pDstLine = FreeImage_GetBits(pResultBitmap) + nDstPitch * (fi_h - 1);
        af_array rr = 0, gg = 0, bb = 0, aa = 0;
        AF_CHECK(channel_split(in, info.dims(), &rr, &gg, &bb, &aa)); // convert array to 3 channels if needed

        uint step = channels; // force 3 channels saving
        uint indx = 0;

        af_array rrT = 0, ggT = 0, bbT = 0, aaT = 0;
        if(channels == 4) {

            AF_CHECK(af_transpose(&rrT, rr, false));
            AF_CHECK(af_transpose(&ggT, gg, false));
            AF_CHECK(af_transpose(&bbT, bb, false));
            AF_CHECK(af_transpose(&aaT, aa, false));

            ArrayInfo cinfo = getInfo(rrT);
            float* pSrc0 = pinnedAlloc<float>(cinfo.elements());
            float* pSrc1 = pinnedAlloc<float>(cinfo.elements());
            float* pSrc2 = pinnedAlloc<float>(cinfo.elements());
            float* pSrc3 = pinnedAlloc<float>(cinfo.elements());

            AF_CHECK(af_get_data_ptr((void*)pSrc0, rrT));
            AF_CHECK(af_get_data_ptr((void*)pSrc1, ggT));
            AF_CHECK(af_get_data_ptr((void*)pSrc2, bbT));
            AF_CHECK(af_get_data_ptr((void*)pSrc3, aaT));

            // Copy the array into FreeImage buffer
            for (uint y = 0; y < fi_h; ++y) {
                for (uint x = 0; x < fi_w; ++x) {
                    *(pDstLine + x * step + 2) = (uchar) pSrc0[indx]; // b
                    *(pDstLine + x * step + 1) = (uchar) pSrc1[indx]; // g
                    *(pDstLine + x * step + 0) = (uchar) pSrc2[indx]; // r
                    *(pDstLine + x * step + 3) = (uchar) pSrc3[indx]; // a
                    ++indx;
                }
                pDstLine -= nDstPitch;
            }
            pinnedFree(pSrc0);
            pinnedFree(pSrc1);
            pinnedFree(pSrc2);
            pinnedFree(pSrc3);
        } else if(channels == 3) {
            AF_CHECK(af_transpose(&rrT, rr, false));
            AF_CHECK(af_transpose(&ggT, gg, false));
            AF_CHECK(af_transpose(&bbT, bb, false));

            ArrayInfo cinfo = getInfo(rrT);
            float* pSrc0 = pinnedAlloc<float>(cinfo.elements());
            float* pSrc1 = pinnedAlloc<float>(cinfo.elements());
            float* pSrc2 = pinnedAlloc<float>(cinfo.elements());

            AF_CHECK(af_get_data_ptr((void*)pSrc0, rrT));
            AF_CHECK(af_get_data_ptr((void*)pSrc1, ggT));
            AF_CHECK(af_get_data_ptr((void*)pSrc2, bbT));

            // Copy the array into FreeImage buffer
            for (uint y = 0; y < fi_h; ++y) {
                for (uint x = 0; x < fi_w; ++x) {
                    *(pDstLine + x * step + 2) = (uchar) pSrc0[indx]; // b
                    *(pDstLine + x * step + 1) = (uchar) pSrc1[indx]; // g
                    *(pDstLine + x * step + 0) = (uchar) pSrc2[indx]; // r
                    ++indx;
                }
                pDstLine -= nDstPitch;
            }
            pinnedFree(pSrc0);
            pinnedFree(pSrc1);
            pinnedFree(pSrc2);
        } else {
            AF_CHECK(af_transpose(&rrT, rr, false));
            ArrayInfo cinfo = getInfo(rrT);
            float* pSrc0 = pinnedAlloc<float>(cinfo.elements());
            AF_CHECK(af_get_data_ptr((void*)pSrc0, rrT));

            for (uint y = 0; y < fi_h; ++y) {
                for (uint x = 0; x < fi_w; ++x) {
                    *(pDstLine + x * step) = (uchar) pSrc0[indx];
                    ++indx;
                }
                pDstLine -= nDstPitch;
            }
            pinnedFree(pSrc0);
        }

        FIMEMORY *stream = FreeImage_OpenMemory();

        // now save the result image
        if (!(FreeImage_SaveToMemory(fif, pResultBitmap, stream, 0) == TRUE)) {
            AF_ERROR("FreeImage Error: Failed to save image", AF_ERR_RUNTIME);
        }

        *ptr = stream;

        FreeImage_Unload(pResultBitmap);

        if(free_in) AF_CHECK(af_release_array(in ));
        if(rr != 0) AF_CHECK(af_release_array(rr ));
        if(gg != 0) AF_CHECK(af_release_array(gg ));
        if(bb != 0) AF_CHECK(af_release_array(bb ));
        if(aa != 0) AF_CHECK(af_release_array(aa ));
        if(rrT!= 0) AF_CHECK(af_release_array(rrT));
        if(ggT!= 0) AF_CHECK(af_release_array(ggT));
        if(bbT!= 0) AF_CHECK(af_release_array(bbT));
        if(aaT!= 0) AF_CHECK(af_release_array(aaT));

    } CATCHALL

    return AF_SUCCESS;
}
Example #25
0
af_err af_assign_gen(af_array *out,
                    const af_array lhs,
                    const dim_t ndims, const af_index_t* indexs,
                    const af_array rhs_)
{
    af_array output = 0;
    af_array rhs = rhs_;
    // spanner is sequence index used for indexing along the
    // dimensions after ndims
    af_index_t spanner;
    spanner.idx.seq = af_span;
    spanner.isSeq = true;

    try {
        ARG_ASSERT(2, (ndims>0));
        ARG_ASSERT(3, (indexs!=NULL));

        int track = 0;
        vector<af_seq> seqs(4, af_span);
        for (dim_t i = 0; i < ndims; i++) {
            if (indexs[i].isSeq) {
                track++;
                seqs[i] = indexs[i].idx.seq;
            }
        }

        if (track==(int)ndims) {
            // all indexs are sequences, redirecting to af_assign
            return af_assign_seq(out, lhs, ndims, &(seqs.front()), rhs);
        }

        ARG_ASSERT(1, (lhs!=0));
        ARG_ASSERT(4, (rhs!=0));

        ArrayInfo lInfo = getInfo(lhs);
        ArrayInfo rInfo = getInfo(rhs);
        dim4 lhsDims    = lInfo.dims();
        dim4 rhsDims    = rInfo.dims();
        af_dtype lhsType= lInfo.getType();
        af_dtype rhsType= rInfo.getType();

        ARG_ASSERT(2, (ndims == 1) || (ndims == (dim_t)lInfo.ndims()));

        if (ndims == 1 && ndims != (dim_t)lInfo.ndims()) {
            af_array tmp_in = 0, tmp_out = 0;
            AF_CHECK(af_flat(&tmp_in, lhs));
            AF_CHECK(af_assign_gen(&tmp_out, tmp_in, ndims, indexs, rhs_));
            AF_CHECK(af_moddims(out, tmp_out, lInfo.ndims(), lInfo.dims().get()));
            AF_CHECK(af_release_array(tmp_in));
            AF_CHECK(af_release_array(tmp_out));
            return AF_SUCCESS;
        }

        ARG_ASSERT(1, (lhsType==rhsType));
        ARG_ASSERT(3, (rhsDims.ndims()>0));
        ARG_ASSERT(1, (lhsDims.ndims()>=rhsDims.ndims()));
        ARG_ASSERT(2, (lhsDims.ndims()>=ndims));

        if (*out != lhs) {
            int count = 0;
            AF_CHECK(af_get_data_ref_count(&count, lhs));
            if (count > 1) {
                AF_CHECK(af_copy_array(&output, lhs));
            } else {
                AF_CHECK(af_retain_array(&output, lhs));
            }
        } else {
            output = lhs;
        }

        dim4 oDims = toDims(seqs, lhsDims);
        // if af_array are indexs along any
        // particular dimension, set the length of
        // that dimension accordingly before any checks
        for (dim_t i=0; i<ndims; i++) {
            if (!indexs[i].isSeq) {
                oDims[i] = getInfo(indexs[i].idx.arr).elements();
            }
        }

        for (dim_t i = ndims; i < (dim_t)lInfo.ndims(); i++) {
            oDims[i] = 1;
        }

        bool is_vector = true;
        for (int i = 0; is_vector && i < oDims.ndims() - 1; i++) {
            is_vector &= oDims[i] == 1;
        }

        //TODO: Move logic out of this
        is_vector &= rInfo.isVector() || rInfo.isScalar();
        if (is_vector) {
            if (oDims.elements() != (dim_t)rInfo.elements() &&
                rInfo.elements() != 1) {
                AF_ERROR("Size mismatch between input and output", AF_ERR_SIZE);
            }

            if (rInfo.elements() == 1) {
                AF_CHECK(af_tile(&rhs, rhs_, oDims[0], oDims[1], oDims[2], oDims[3]));
            } else {
                // If both out and rhs are vectors of equal elements, reshape rhs to out dims
                AF_CHECK(af_moddims(&rhs, rhs_, oDims.ndims(), oDims.get()));
            }
        } else {
            for (int i = 0; i < 4; i++) {
                if (oDims[i] != rhsDims[i]) {
                    AF_ERROR("Size mismatch between input and output", AF_ERR_SIZE);
                }
            }
        }

        af_index_t idxrs[4];
        // set all dimensions above ndims to spanner index
        for (dim_t i=ndims; i<4; ++i) idxrs[i] = spanner;

        for (dim_t i=0; i<ndims; ++i) {
            if (!indexs[i].isSeq) {
                // check if all af_arrays have atleast one value
                // to enable indexing along that dimension
                ArrayInfo idxInfo = getInfo(indexs[i].idx.arr);
                af_dtype idxType  = idxInfo.getType();

                ARG_ASSERT(3, (idxType!=c32));
                ARG_ASSERT(3, (idxType!=c64));
                ARG_ASSERT(3, (idxType!=b8 ));

                idxrs[i].idx.arr = indexs[i].idx.arr;
                idxrs[i].isSeq = indexs[i].isSeq;
            } else {
                // af_seq is being used for this dimension
                // just copy the index to local variable
                idxrs[i] = indexs[i];
            }
        }

        try {
            switch(rhsType) {
                case c64: genAssign<cdouble>(output, idxrs, rhs); break;
                case f64: genAssign<double >(output, idxrs, rhs); break;
                case c32: genAssign<cfloat >(output, idxrs, rhs); break;
                case f32: genAssign<float  >(output, idxrs, rhs); break;
                case u64: genAssign<uintl  >(output, idxrs, rhs); break;
                case u32: genAssign<uint   >(output, idxrs, rhs); break;
                case s64: genAssign<intl   >(output, idxrs, rhs); break;
                case s32: genAssign<int    >(output, idxrs, rhs); break;
                case  u8: genAssign<uchar  >(output, idxrs, rhs); break;
                case  b8: genAssign<char   >(output, idxrs, rhs); break;
                default: TYPE_ERROR(1, rhsType);
            }
        } catch(...) {
            if (*out != lhs) {
                AF_CHECK(af_release_array(output));
                if (is_vector) { AF_CHECK(af_release_array(rhs)); }
            }
            throw;
        }
        if (is_vector) { AF_CHECK(af_release_array(rhs)); }
    }
    CATCHALL;

    std::swap(*out, output);

    return AF_SUCCESS;
}
Example #26
0
af_err af_assign_seq(af_array *out,
                     const af_array lhs, const unsigned ndims,
                     const af_seq *index, const af_array rhs)
{
    try {
        ARG_ASSERT(0, (lhs!=0));
        ARG_ASSERT(1, (ndims>0));
        ARG_ASSERT(3, (rhs!=0));

        ArrayInfo lInfo = getInfo(lhs);

        if (ndims == 1 && ndims != (dim_t)lInfo.ndims()) {
            af_array tmp_in, tmp_out;
            AF_CHECK(af_flat(&tmp_in, lhs));
            AF_CHECK(af_assign_seq(&tmp_out, tmp_in, ndims, index, rhs));
            AF_CHECK(af_moddims(out, tmp_out, lInfo.ndims(), lInfo.dims().get()));
            AF_CHECK(af_release_array(tmp_in));
            AF_CHECK(af_release_array(tmp_out));
            return AF_SUCCESS;
        }

        for(dim_t i=0; i<(dim_t)ndims; ++i) {
            ARG_ASSERT(2, (index[i].step>=0));
        }

        af_array res = 0;

        if (*out != lhs) {
            int count = 0;
            AF_CHECK(af_get_data_ref_count(&count, lhs));
            if (count > 1) {
                AF_CHECK(af_copy_array(&res, lhs));
            } else {
                AF_CHECK(af_retain_array(&res, lhs));
            }
        } else {
            res = lhs;
        }

        try {

            if (lhs != rhs) {
                ArrayInfo oInfo = getInfo(lhs);
                af_dtype oType  = oInfo.getType();
                switch(oType) {
                case c64: assign_helper<cdouble>(getWritableArray<cdouble>(res), ndims, index, rhs);  break;
                case c32: assign_helper<cfloat >(getWritableArray<cfloat >(res), ndims, index, rhs);  break;
                case f64: assign_helper<double >(getWritableArray<double >(res), ndims, index, rhs);  break;
                case f32: assign_helper<float  >(getWritableArray<float  >(res), ndims, index, rhs);  break;
                case s32: assign_helper<int    >(getWritableArray<int    >(res), ndims, index, rhs);  break;
                case u32: assign_helper<uint   >(getWritableArray<uint   >(res), ndims, index, rhs);  break;
                case s64: assign_helper<intl   >(getWritableArray<intl   >(res), ndims, index, rhs);  break;
                case u64: assign_helper<uintl  >(getWritableArray<uintl  >(res), ndims, index, rhs);  break;
                case u8 : assign_helper<uchar  >(getWritableArray<uchar  >(res), ndims, index, rhs);  break;
                case b8 : assign_helper<char   >(getWritableArray<char   >(res), ndims, index, rhs);  break;
                default : TYPE_ERROR(1, oType); break;
                }
            }
        } catch(...) {
            af_release_array(res);
            throw;
        }
        std::swap(*out, res);
    }
    CATCHALL;

    return AF_SUCCESS;
}