Esempio n. 1
0
void test(int n, int k)
{
    int dim = 2;

    diy::DiscreteBounds global_bounds(dim);
    global_bounds.min[0] = global_bounds.min[1] = 0;
    global_bounds.max[0] = global_bounds.min[1] = 1023;

    diy::RegularDecomposer<diy::DiscreteBounds> decomposer(dim, global_bounds, n);

    diy::RegularPartners partners(decomposer, k, false);

    int kvs_product = 1;
    for (size_t i = 0; i < partners.rounds(); ++i)
        kvs_product *= partners.size(i);
    REQUIRE(kvs_product == n);

    for (int gid = 0; gid < n; ++gid)
        for (size_t i = 0; i < partners.rounds(); ++i)
        {
            std::vector<int> nbr_gids;
            partners.fill(i, gid, nbr_gids);
            for (int nbr_gid : nbr_gids)
                CHECK(nbr_gid <= n);
        }
}
    void sort(Master&                   master,               //!< master object
              const Assigner&           assigner,             //!< assigner object
              std::vector<T> Block::*   values,               //!< all values to sort
              std::vector<T> Block::*   samples,              //!< (output) boundaries of blocks
              size_t                    num_samples,          //!< desired number of samples
              const Cmp&                cmp,                  //!< comparison function
              int                       k   = 2,              //!< k-ary reduction will be used
              bool                      samples_only = false) //!< false: results will be all_to_all exchanged; true: only sort but don't exchange results
    {
        bool immediate = master.immediate();
        master.set_immediate(false);

        // NB: although sorter will go out of scope, its member functions sample()
        //     and exchange() will return functors whose copies get saved inside reduce
        detail::SampleSort<Block,T,Cmp> sorter(values, samples, cmp, num_samples);

        // swap-reduce to all-gather samples
        RegularDecomposer<DiscreteBounds> decomposer(1, interval(0,assigner.nblocks()), assigner.nblocks());
        RegularSwapPartners   partners(decomposer, k);
        reduce(master, assigner, partners, sorter.sample(), detail::SkipIntermediate(partners.rounds()));

        // all_to_all to exchange the values
        if (!samples_only)
            all_to_all(master, assigner, sorter.exchange(), k);

        master.set_immediate(immediate);
    }
Esempio n. 3
0
int main(int argc, char* argv[])
{
    diy::mpi::environment     env(argc, argv);         // diy equivalent of MPI_Init
    diy::mpi::communicator    world;                   // diy equivalent of MPI communicator

    int                       size    = 8;             // total number of MPI processes
    int                       nblocks = 32;            // total number of blocks in global domain
    diy::ContiguousAssigner   assigner(size, nblocks);

    Bounds domain;                                     // global data size
    domain.min[0] = domain.min[1] = domain.min[2] = 0;
    domain.max[0] = domain.max[1] = domain.max[2] = 255;

    int rank = world.rank();                           // MPI rank of this process
    std::cout << "Rank " << rank << ":" << std::endl;
    diy::Master master(world,
                       1,                              // one thread
                       -1,                             // all blocks in memory
                       &Block::create,
                       &Block::destroy);
    AddBlock     addblock(master);                     // object for adding new blocks to master

    // share_face is an n-dim (size 3 in this example) vector of bools
    // indicating whether faces are shared in each dimension
    // uninitialized values default to false
    diy::RegularDecomposer<Bounds>::BoolVector          share_face;
    share_face.push_back(true);

    // wrap is an n-dim (size 3 in this example) vector of bools
    // indicating whether boundary conditions are periodic in each dimension
    // uninitialized values default to false
    diy::RegularDecomposer<Bounds>::BoolVector          wrap;
    wrap.push_back(true);
    wrap.push_back(true);

    // ghosts is an n-dim (size 3 in this example) vector of ints
    // indicating number of ghost cells per side in each dimension
    // uninitialized values default to 0
    diy::RegularDecomposer<Bounds>::CoordinateVector    ghosts;
    ghosts.push_back(1); ghosts.push_back(2);

    // either create the regular decomposer and call its decompose function
    // (having the decomposer available is useful for its other member functions
    diy::RegularDecomposer<Bounds> decomposer(3,
                                              domain,
                                              assigner,
                                              share_face,
                                              wrap,
                                              ghosts);
    decomposer.decompose(rank, addblock);

    // or combine the two lines above into the following helper function
    // but the decomposer gets destroyed afterwards
    // diy::decompose(3, rank, domain, assigner, addblock, share_face, wrap, ghosts);

    // display the decomposition
    master.foreach(&Block::show_link);
}
Esempio n. 4
0
//------------------------------------------------------------------------
// DecomposeLongs::DecomposeRange:
//    Do LONG decomposition on all the nodes in the given range. This must
//    be done before inserting a range of un-decomposed IR into a block
//    that has already been decomposed.
//
// Arguments:
//    compiler    - The compiler context.
//    blockWeight - The weight of the block into which the range will be
//                  inserted.
//    range       - The range to decompose.
//
// Return Value:
//    None.
//
void DecomposeLongs::DecomposeRange(Compiler* compiler, unsigned blockWeight, LIR::Range& range)
{
    assert(compiler != nullptr);

    DecomposeLongs decomposer(compiler);
    decomposer.m_blockWeight = blockWeight;
    decomposer.m_range = &range;

    decomposer.DecomposeRangeHelper();
}
Esempio n. 5
0
//----------------------------------------------------------------------------
int ExtractRidges::Main (int, char**)
{
    std::string imageName = Environment::GetPathR("Head.im");
    ImageDouble2D image(imageName.c_str());

    // Normalize the image values to be in [0,1].
    int quantity = image.GetQuantity();
    double minValue = image[0], maxValue = minValue;
    int i;
    for (i = 1; i < quantity; ++i)
    {
        if (image[i] < minValue)
        {
            minValue = image[i];
        }
        else if (image[i] > maxValue)
        {
            maxValue = image[i];
        }
    }
    double invRange = 1.0/(maxValue - minValue);
    for (i = 0; i < quantity; ++i)
    {
        image[i] = (image[i] - minValue)*invRange;
    }

    // Use first-order centered finite differences to estimate the image
    // derivatives.  The gradient is DF = (df/dx, df/dy) and the Hessian
    // is D^2F = {{d^2f/dx^2, d^2f/dxdy}, {d^2f/dydx, d^2f/dy^2}}.
    int xBound = image.GetBound(0);
    int yBound = image.GetBound(1);
    int xBoundM1 = xBound - 1;
    int yBoundM1 = yBound - 1;
    ImageDouble2D dx(xBound, yBound);
    ImageDouble2D dy(xBound, yBound);
    ImageDouble2D dxx(xBound, yBound);
    ImageDouble2D dxy(xBound, yBound);
    ImageDouble2D dyy(xBound, yBound);
    int x, y;
    for (y = 1; y < yBoundM1; ++y)
    {
        for (x = 1; x < xBoundM1; ++x)
        {
            dx(x, y) = 0.5*(image(x+1, y) - image(x-1, y));
            dy(x, y) = 0.5*(image(x, y+1) - image(x, y-1));
            dxx(x, y) = image(x+1, y) - 2.0*image(x, y) + image(x-1, y);
            dxy(x, y) = 0.25*(image(x+1, y+1) + image(x-1, y-1)
                - image(x+1, y-1) - image(x-1, y+1));
            dyy(x, y) = image(x, y+1) - 2.0*image(x, y) + image(x, y+1);
        }
    }
    dx.Save("dx.im");
    dy.Save("dy.im");
    dxx.Save("dxx.im");
    dxy.Save("dxy.im");
    dyy.Save("dyy.im");

    // The eigensolver produces eigenvalues a and b and corresponding
    // eigenvectors U and V:  D^2F*U = a*U, D^2F*V = b*V.  Define
    // P = Dot(U,DF) and Q = Dot(V,DF).  The classification is as follows.
    //   ridge:   P = 0 with a < 0
    //   valley:  Q = 0 with b > 0
    ImageDouble2D aImage(xBound, yBound);
    ImageDouble2D bImage(xBound, yBound);
    ImageDouble2D pImage(xBound, yBound);
    ImageDouble2D qImage(xBound, yBound);
    for (y = 1; y < yBoundM1; ++y)
    {
        for (x = 1; x < xBoundM1; ++x)
        {
            Vector2d gradient(dx(x, y), dy(x, y));
            Matrix2d hessian(dxx(x, y), dxy(x, y), dxy(x, y), dyy(x, y));
            EigenDecompositiond decomposer(hessian);
            decomposer.Solve(true);
            aImage(x,y) = decomposer.GetEigenvalue(0);
            bImage(x,y) = decomposer.GetEigenvalue(1);
            Vector2d u = decomposer.GetEigenvector2(0);
            Vector2d v = decomposer.GetEigenvector2(1);
            pImage(x,y) = u.Dot(gradient);
            qImage(x,y) = v.Dot(gradient);
        }
    }
    aImage.Save("a.im");
    bImage.Save("b.im");
    pImage.Save("p.im");
    qImage.Save("q.im");

    // Use a cheap classification of the pixels by testing for sign changes
    // between neighboring pixels.
    ImageRGB82D result(xBound, yBound);
    for (y = 1; y < yBoundM1; ++y)
    {
        for (x = 1; x < xBoundM1; ++x)
        {
            unsigned char gray = (unsigned char)(255.0f*image(x, y));

            double pValue = pImage(x, y);
            bool isRidge = false;
            if (pValue*pImage(x-1 ,y) < 0.0
            ||  pValue*pImage(x+1, y) < 0.0
            ||  pValue*pImage(x, y-1) < 0.0
            ||  pValue*pImage(x, y+1) < 0.0)
            {
                if (aImage(x, y) < 0.0)
                {
                    isRidge = true;
                }
            }

            double qValue = qImage(x,y);
            bool isValley = false;
            if (qValue*qImage(x-1, y) < 0.0
            ||  qValue*qImage(x+1, y) < 0.0
            ||  qValue*qImage(x, y-1) < 0.0
            ||  qValue*qImage(x, y+1) < 0.0)
            {
                if (bImage(x,y) > 0.0)
                {
                    isValley = true;
                }
            }

            if (isRidge)
            {
                if (isValley)
                {
                    result(x, y) = GetColor24(gray, 0, gray);
                }
                else
                {
                    result(x, y) = GetColor24(gray, 0, 0);
                }
            }
            else if (isValley)
            {
                result(x, y) = GetColor24(0, 0, gray);
            }
            else
            {
                result(x, y) = GetColor24(gray, gray, gray);
            }
        }
    }
    result.Save("result.im");

    return 0;
}