Exemple #1
0
void Config::_registerModels()
{
    // Register distribution helpers on each config run
    const bool createDist = _modelDist.empty(); //first run, create distributors
    const size_t  nModels = _models.size();
    LBASSERT( createDist || _modelDist.size() == nModels );

    for( size_t i = 0; i < nModels; ++i )
    {
        const Model* model = _models[i];
        ModelDist* modelDist = 0;
        if( createDist )
        {
            modelDist = new ModelDist( model );
            _modelDist.push_back( modelDist );
        }
        else
            modelDist = _modelDist[i];

        modelDist->registerTree( getClient( ));
        LBASSERT( modelDist->isAttached() );

        _frameData.setModelID( modelDist->getID( ));
    }

    LBASSERT( _modelDist.size() == nModels );

    if( !_modelDist.empty( ))
    {
        ModelAssigner assigner( _modelDist );
        accept( assigner );
    }
}
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);
}
    inline void apply(InputGeometry const& geometry, partitions& state) const
    {
        // First pass.
        // Get min/max (in most cases left / right) points
        // This makes use of the geometry::less/greater predicates

        // For the left boundary it is important that multiple points
        // are sorted from bottom to top. Therefore the less predicate
        // does not take the x-only template parameter (this fixes ticket #6019.
        // For the right boundary it is not necessary (though also not harmful),
        // because points are sorted from bottom to top in a later stage.
        // For symmetry and to get often more balanced lower/upper halves
        // we keep it.

        typedef typename geometry::detail::range_type<InputGeometry>::type range_type;

        typedef typename boost::range_iterator
            <
                range_type const
            >::type range_iterator;

        detail::get_extremes
            <
                range_type,
                range_iterator,
                geometry::less<point_type>,
                geometry::greater<point_type>
            > extremes;
        geometry::detail::for_each_range(geometry, extremes);

        // Bounding left/right points
        // Second pass, now that extremes are found, assign all points
        // in either lower, either upper
        detail::assign_range
            <
                range_type,
                range_iterator,
                container_type,
                typename strategy::side::services::default_strategy<cs_tag>::type
            > assigner(extremes.left, extremes.right);

        geometry::detail::for_each_range(geometry, assigner);


        // Sort both collections, first on x(, then on y)
        detail::sort(assigner.lower_points);
        detail::sort(assigner.upper_points);

        //std::cout << boost::size(assigner.lower_points) << std::endl;
        //std::cout << boost::size(assigner.upper_points) << std::endl;

        // And decide which point should be in the final hull
        build_half_hull<-1>(assigner.lower_points, state.m_lower_hull,
                extremes.left, extremes.right);
        build_half_hull<1>(assigner.upper_points, state.m_upper_hull,
                extremes.left, extremes.right);
    }
static int kl_script_event_dequeue_wrap(lua_State* L)
{
   kl_script_context_t sctx = (kl_script_context_t)lua_topointer(L, 1);
   
   kl_script_event_t event;
   if(kl_script_event_dequeue(sctx, &event) == KL_SUCCESS)
   {
      uint32_t context_type = kl_get_script_event_context_type(event.event.id);
      int ret = 3;
      lua_pushinteger(L, event.event.id);

      if(context_type == KL_SCRIPT_CONTEXT_TYPE_ASSIGNER)
      {
         kl_script_event_context_assigner_fn assigner =
            kl_get_script_event_context_assigner(event.event.id);
         ret = assigner(L, &event) + 1;
      }
      else
      {
         switch(context_type)
         {
            case 0:
            {
               lua_pushlightuserdata(L, event.event.context.as_ptr);
               break;
            }

            case LUA_TNUMBER:
            {
               lua_pushnumber(L, *((lua_Number*)event.event.context.as_ptr));
               kl_heap_free(event.event.context.as_ptr);
               break;
            }

            case LUA_TSTRING:
            {
               lua_pushstring(L, event.event.context.as_ptr);
               kl_heap_free(event.event.context.as_ptr);
               break;
            }

         }
         lua_pushinteger(L, event.event.arg.as_uint32);
      }
      return ret;
   }
   
   lua_pushnil(L);
   return 1;
}
Exemple #5
0
int main(int argc, char* argv[])
{
  diy::mpi::environment     env(argc, argv);
  diy::mpi::communicator    world;

  diy::Master               master(world, 1, -1,
                                   &create_block,           // master will take ownership after read_blocks(),
                                   &destroy_block);         // so it needs create and destroy functions
  diy::ContiguousAssigner   assigner(world.size(), 0);
  //diy::RoundRobinAssigner   assigner(world.size(), 0);      // nblocks will be filled by read_blocks()

  diy::io::read_blocks("blocks.out", world, assigner, master, &load_block);

  master.foreach(&output);
}
Exemple #6
0
int main(int argc, char* argv[])
{
  diy::mpi::environment     env(argc, argv);
  diy::mpi::communicator    world;

  int                       nblocks = 4*world.size();

  diy::FileStorage          storage("./DIY.XXXXXX");

  diy::Master               master(world,
                                   -1,
                                   2,
                                   &create_block,
                                   &destroy_block,
                                   &storage,
                                   &save_block,
                                   &load_block);

  srand(time(NULL));

  //diy::ContiguousAssigner   assigner(world.size(), nblocks);
  diy::RoundRobinAssigner   assigner(world.size(), nblocks);

  for (int gid = 0; gid < nblocks; ++gid)
    if (assigner.rank(gid) == world.rank())
      master.add(gid, new Block, new diy::Link);

  bool all_done = false;
  while (!all_done)
  {
    master.foreach(&flip_coin);
    master.exchange();
    all_done = master.proxy(master.loaded_block()).read<bool>();
  }

  if (world.rank() == 0)
    std::cout << "Total iterations: " << master.block<Block>(master.loaded_block())->count << std::endl;
}
Exemple #7
0
/*!
 * \param[in]  data  Data for the current frame.
 * \param[in]  sel   Selection element being evaluated.
 * \param[in]  g     Group for which \p sel should be evaluated.
 * \returns    0 on success, a non-zero error code on error.
 *
 * Finds the part of \p g for which the subexpression
 * has not yet been evaluated by comparing \p g to \p sel->u.cgrp.
 * If the part is not empty, the child expression is evaluated for this
 * part, and the results merged to the old values of the child.
 * The value of \p sel itself is undefined after the call.
 *
 * \todo
 * The call to gmx_ana_index_difference() can take quite a lot of unnecessary
 * time if the subexpression is evaluated either several times for the same
 * group or for completely distinct groups.
 * However, in the majority of cases, these situations occur when
 * _gmx_sel_evaluate_subexpr_staticeval() can be used, so this should not be a
 * major problem.
 */
void
_gmx_sel_evaluate_subexpr(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g)
{
    gmx_ana_index_t  gmiss;

    MempoolGroupReserver gmissreserver(data->mp);
    if (sel->u.cgrp.isize == 0)
    {
        {
            SelelemTemporaryValueAssigner assigner(sel->child, sel);
            sel->child->evaluate(data, sel->child, g);
        }
        /* We need to keep the name for the cgrp across the copy to avoid
         * problems if g has a name set. */
        char *name = sel->u.cgrp.name;
        gmx_ana_index_copy(&sel->u.cgrp, g, false);
        sel->u.cgrp.name = name;
        gmiss.isize = 0;
    }
    else
    {
        gmissreserver.reserve(&gmiss, g->isize);
        gmx_ana_index_difference(&gmiss, g, &sel->u.cgrp);
    }
    if (gmiss.isize > 0)
    {
        MempoolSelelemReserver reserver(sel->child, gmiss.isize);
        /* Evaluate the missing values for the child */
        sel->child->evaluate(data, sel->child, &gmiss);
        /* Merge the missing values to the existing ones. */
        if (sel->v.type == GROUP_VALUE)
        {
            gmx_ana_index_merge(sel->v.u.g, sel->child->v.u.g, sel->v.u.g);
        }
        else
        {
            int  i, j, k;

            i = sel->u.cgrp.isize - 1;
            j = gmiss.isize - 1;
            /* TODO: This switch is kind of ugly, but it may be difficult to
             * do this portably without C++ templates. */
            switch (sel->v.type)
            {
                case INT_VALUE:
                    for (k = sel->u.cgrp.isize + gmiss.isize - 1; k >= 0; k--)
                    {
                        if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
                        {
                            sel->v.u.i[k] = sel->v.u.i[j--];
                        }
                        else
                        {
                            sel->v.u.i[k] = sel->child->v.u.i[i--];
                        }
                    }
                    break;

                case REAL_VALUE:
                    for (k = sel->u.cgrp.isize + gmiss.isize - 1; k >= 0; k--)
                    {
                        if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
                        {
                            sel->v.u.r[k] = sel->v.u.r[j--];
                        }
                        else
                        {
                            sel->v.u.r[k] = sel->child->v.u.r[i--];
                        }
                    }
                    break;

                case STR_VALUE:
                    for (k = sel->u.cgrp.isize + gmiss.isize - 1; k >= 0; k--)
                    {
                        if (i < 0 || (j >= 0 && sel->u.cgrp.index[i] < gmiss.index[j]))
                        {
                            sel->v.u.s[k] = sel->v.u.s[j--];
                        }
                        else
                        {
                            sel->v.u.s[k] = sel->child->v.u.s[i--];
                        }
                    }
                    break;

                case POS_VALUE:
                    /* TODO: Implement this */
                    GMX_THROW(gmx::NotImplementedError("position subexpressions not implemented properly"));

                case NO_VALUE:
                case GROUP_VALUE:
                    GMX_THROW(gmx::InternalError("Invalid subexpression type"));
            }
        }
        gmx_ana_index_merge(&sel->u.cgrp, &sel->u.cgrp, &gmiss);
    }
}
Exemple #8
0
int main(int argc, char *argv[])
{
  int tot_blocks;                           // total number of blocks in the domain
  int mem_blocks;                           // max blocks in memory
  int dsize[3];                             // domain grid size
  float jitter;                             // max amount to randomly displace particles
  float minvol, maxvol;                     // volume range, -1.0 = unused
  double times[TESS_MAX_TIMES];             // timing
  int wrap;                                 // wraparound neighbors flag
  int walls;                                // apply walls to simulation (wrap must be off)
  char outfile[256];                        // output file name
  int num_threads = 1;                      // threads diy can use

  // init MPI
  MPI_Comm comm = MPI_COMM_WORLD;
  MPI_Init(&argc, &argv);

  GetArgs(argc, argv, tot_blocks, mem_blocks, dsize, &jitter, &minvol, &maxvol, &wrap, &walls,
          outfile);

  // data extents
  typedef     diy::ContinuousBounds         Bounds;
  Bounds domain { 3 };
  for(int i = 0; i < 3; i++)
  {
    domain.min[i] = 0;
    domain.max[i] = dsize[i] - 1.0;
  }

  // init diy
  diy::mpi::communicator    world(comm);
  diy::FileStorage          storage("./DIY.XXXXXX");
  diy::Master               master(world,
				   num_threads,
                                   mem_blocks,
                                   &create_block,
                                   &destroy_block,
                                   &storage,
                                   &save_block,
                                   &load_block);
  diy::RoundRobinAssigner   assigner(world.size(), tot_blocks);
  AddAndGenerate            create(master, jitter);

  // decompose
  std::vector<int> my_gids;
  assigner.local_gids(world.rank(), my_gids);
  diy::RegularDecomposer<Bounds>::BoolVector          wraps;
  diy::RegularDecomposer<Bounds>::BoolVector          share_face;
  diy::RegularDecomposer<Bounds>::CoordinateVector    ghosts;
  if (wrap)
    wraps.assign(3, true);
  diy::decompose(3, world.rank(), domain, assigner, create, share_face, wraps, ghosts);

  // tessellate
  quants_t quants;
  timing(times, -1, -1, world);
  timing(times, TOT_TIME, -1, world);
  tess(master, quants, times);

  // output
  tess_save(master, outfile, times);
  timing(times, -1, TOT_TIME, world);
  tess_stats(master, quants, times);

  MPI_Finalize();

  return 0;
}