Exemplo n.º 1
0
/**
 * aran_solver2d_solve:
 * @solver: an #AranSolver2d.
 *
 * Solves the FMM problem for @solver.
 */
void aran_solver2d_solve (AranSolver2d *solver)
{
    g_return_if_fail (solver != NULL);

    /* clear multipole and local develoments before the big work */
    vsg_prtree2d_traverse (solver->prtree, G_POST_ORDER,
                           (VsgPRTree2dFunc) clear_func,
                           solver);

    /* gather information in Multipole development */
    vsg_prtree2d_traverse (solver->prtree, G_POST_ORDER,
                           (VsgPRTree2dFunc) up_func,
                           solver);

    /* transmit info from Multipole to Local developments */
    vsg_prtree2d_near_far_traversal (solver->prtree,
                                     (VsgPRTree2dInteractionFunc) far_func,
                                     (VsgPRTree2dInteractionFunc) near_func,
                                     solver);

    /* distribute information through Local developments towards particles */
    vsg_prtree2d_traverse (solver->prtree, G_PRE_ORDER,
                           (VsgPRTree2dFunc) down_func,
                           solver);
}
Exemplo n.º 2
0
void _do_upward_pass (VsgPRTree2d *tree)
{
  /* zero counts  */
  vsg_prtree2d_traverse (tree, G_POST_ORDER, (VsgPRTree2dFunc) _zero, NULL);

  /* accumulate from leaves to top */
  vsg_prtree2d_traverse (tree, G_POST_ORDER, (VsgPRTree2dFunc) _up, NULL);

  /* gather shared in_counts */
  vsg_prtree2d_shared_nodes_allreduce (tree, &pconfig.node_data.visit_forward);
}
Exemplo n.º 3
0
void _tree_write (VsgPRTree2d *tree, gchar *prefix)
{
  gchar fn[1024];
  FILE *f;
  VsgVector2d lb, ub;
  gdouble x;
  gdouble y;
  gdouble w;
  gdouble h;

  vsg_prtree2d_get_bounds (tree, &lb, &ub);

  x = lb.x;
  y = -ub.y;
  w = ub.x - x;
  h = -lb.y - y;

  g_sprintf (fn, "%s%03d.svg", prefix, rk);
  f = fopen (fn, "w");

  fprintf (f, _svg_header, rk);

  fprintf (f, "<rect x=\"0\" y=\"0\" width=\"100%%\" height=\"100%%\" fill=\"white\"/>\n");
  fprintf (f, "<svg x=\"0\" y=\"0\" width=\"500px\" height=\"500px\" " \
           "viewBox=\"%g %g %g %g\">\n", x, y, w, h);
  vsg_prtree2d_traverse (tree, G_PRE_ORDER,
                         (VsgPRTree2dFunc) _traverse_bg_write,
                         f);

  vsg_prtree2d_traverse (tree, G_PRE_ORDER,
                         (VsgPRTree2dFunc) _traverse_fg_write,
                         f);
  fprintf (f, "<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" " \
           "href=\"comm-%03d.svg\" xpointer=\"/1\" " \
           "parse=\"xml\" />\n", rk);
  fprintf (f, "</svg>\n");

  fprintf (f, "<g id=\"ToolTip\" opacity=\"0.8\" visibility=\"hidden\" pointer-events=\"none\">\n" \
           "<rect id=\"tipbox\" x=\"0\" y=\"5\" width=\"88\" height=\"20\" rx=\"2\" ry=\"2\" fill=\"white\" stroke=\"black\"/>\n" \
           "<text id=\"tipText\" x=\"5\" y=\"20\" font-family=\"Arial\" font-size=\"12\">\n" \
           "<tspan id=\"tipTitle\" x=\"5\" font-weight=\"bold\"><![CDATA[]]></tspan>\n" \
           "<tspan id=\"tipDesc\" x=\"5\" dy=\"15\" fill=\"blue\"><![CDATA[]]></tspan>\n" \
           "</text>\n</g>\n</svg>\n");

  fclose (f);

}
Exemplo n.º 4
0
gint main (gint argc, gchar ** argv)
{
  gint ret = 0;

  VsgVector2d lb = {-1., -1.};
  VsgVector2d ub = {1., 1.};
  NodeCounter counter = {0, 0};
  const guint n = 1000;

  Pt points[n];

  VsgPRTree2d *tree;
  gint i;

  if (argc > 1 && g_strncasecmp (argv[1], "--version", 9) == 0)
    {
      g_print ("%s\n", PACKAGE_VERSION);
      return 0;
    }

  vsg_init_gdouble ();

  /* create the tree */
  tree = vsg_prtree2d_new (&lb, &ub, NULL, 1);

  vsg_prtree2d_set_node_data (tree, TYPE_NODE_COUNTER, &counter);

  /* create the points */
  create_points (points, n);

  /* insert the points into the tree */
  for (i=0; i<n; i++)
    {
      vsg_prtree2d_insert_point (tree, &points[i]);
    }

  /* accumulate the point counts across the tree */
  vsg_prtree2d_traverse (tree, G_POST_ORDER, (VsgPRTree2dFunc) up, NULL);

  /* do some near/far traversal */
  vsg_prtree2d_near_far_traversal (tree, (VsgPRTree2dFarInteractionFunc) far,
                                   (VsgPRTree2dInteractionFunc) near,
                                   &ret);

  /*  distribute back the point counts across the tree */
  vsg_prtree2d_traverse (tree, G_PRE_ORDER, (VsgPRTree2dFunc) down, NULL);

  /* check the results */
  for (i=0; i<n; i++)
    {
      if (points[i].count != n)
        {
          g_printerr ("ERROR: wrong count on point %d: %d (should be %d).\n",
                      i, points[i].count, n);
          ret ++;
        }
    }

  /* remove the points */
  for (i=0; i<n; i++)
    {
      vsg_prtree2d_remove_point (tree, &points[i]);
    }

  /* destroy the tree */
  vsg_prtree2d_free (tree);

  return ret;
}
Exemplo n.º 5
0
gint main (gint argc, gchar ** argv)
{
  gint ret = 0;

  VsgPRTree2d *tree;

  VsgVector2d lb;
  VsgVector2d ub;
  GTimer *timer = NULL;

  MPI_Init (&argc, &argv);

  MPI_Comm_size (MPI_COMM_WORLD, &sz);
  MPI_Comm_rank (MPI_COMM_WORLD, &rk);

  vsg_init_gdouble ();

  parse_args (argc, argv);

  if (nc_padding > 0)
    {
      if (_verbose && rk == 0)
        g_printerr ("%d: NodeCounter padding: %d\n", rk, nc_padding);
      _nc_padding_buffer = g_malloc (nc_padding * sizeof (char));
    }

  points = g_ptr_array_new ();

  lb.x = -1.; lb.y = -1.;
  ub.x = 1.; ub.y = 1.;

  /* create the tree */
  tree =
    vsg_prtree2d_new_full (&lb, &ub,
                           (VsgPoint2dLocFunc) vsg_vector2d_vector2d_locfunc,
                           (VsgPoint2dDistFunc) vsg_vector2d_dist,
                           NULL, _maxbox);

  if (_hilbert)
    {
      /* configure for hilbert curve order traversal */
      vsg_prtree2d_set_children_order_hilbert (tree);
    }

  if (_verbose)
    {
      MPI_Barrier (MPI_COMM_WORLD);
      g_printerr ("%d: set_parallel begin\n", rk);
    }

  vsg_prtree2d_set_parallel (tree, &pconfig);

  if (_verbose)
    {
      MPI_Barrier (MPI_COMM_WORLD);
      g_printerr ("%d: set_parallel ok\n", rk);
    }

  if (_verbose)
    {
      MPI_Barrier (MPI_COMM_WORLD);
      g_printerr ("%d: fill begin\n", rk);
    }

  _fill (tree, _np);

/*   /\* try one exterior point *\/ */
/*   if (sz > 1) */
/*     { */
/*       if (rk == 1) */
/*         { */
/*           Pt *pt; */

/*           _ref_count += _np+1; */

/*           pt = pt_alloc (TRUE, NULL); */
/*           pt->vector.x = ub.x+1.; */
/*           pt->vector.y = ub.y+1.; */
/*           pt->weight = _np+1; */

/*           vsg_prtree2d_insert_point (tree, pt); */
/*         } */
/*       else */
/*         { */
/*           _ref_count += _np+1; */
/*         } */

/*       vsg_prtree2d_migrate_flush (tree); */
/*       _distribute (tree); */
/*     } */


  if (_verbose)
    {
      MPI_Barrier (MPI_COMM_WORLD);
      g_printerr ("%d: fill ok\n", rk);
    }

  if (_do_write)
    {
      gchar fn[1024];
      FILE *f;

      sprintf (fn, "comm-%03d.svg", rk);
      f = fopen (fn, "w");

      fprintf (f, "\n<g style=\"stroke-width:0.01; stroke:black; " \
               "fill:none\">\n");
      fclose (f);
    }

  if (_verbose)
    {
      g_printerr ("%d: near/far traversal begin\n", rk);
          MPI_Barrier (MPI_COMM_WORLD);
      timer = g_timer_new ();
    }

  /* accumulate the point counts across the tree */
  _do_upward_pass (tree);

  /* do some near/far traversal */
  vsg_prtree2d_near_far_traversal (tree, (VsgPRTree2dFarInteractionFunc) _far,
                                   (VsgPRTree2dInteractionFunc) _near,
                                   &ret);
  /* accumulate from top to leaves */
  vsg_prtree2d_traverse (tree, G_PRE_ORDER, (VsgPRTree2dFunc) _down, NULL);

  if (_verbose)
    {
      MPI_Barrier (MPI_COMM_WORLD);

      g_printerr ("%d: near/far traversal ok elapsed=%f seconds\n", rk,
                  g_timer_elapsed (timer, NULL));

      g_timer_destroy (timer);
    }

  if (_do_write)
    {
      gchar fn[1024];
      FILE *f;

      MPI_Barrier (MPI_COMM_WORLD);

      g_sprintf (fn, "prtree2parallel-%03d.txt", rk);
      f = fopen (fn, "w");
      vsg_prtree2d_write (tree, f);
      fclose (f);

      _tree_write (tree, "prtree2parallel-");
    }

  if (_do_write)
    {
      gchar fn[1024];
      FILE *f;

      sprintf (fn, "comm-%03d.svg", rk);
      f = fopen (fn, "a");
      fprintf (f, "</g>\n");
      fclose (f);
    }

  if (_verbose)
    {
      gint near_count_sum, far_count_sum;
      MPI_Barrier (MPI_COMM_WORLD);
      g_printerr ("%d: processor msg stats fw=%d bw=%d\n",
                  rk, _fw_count, _bw_count);
      g_printerr ("%d: processor call stats near=%d far=%d\n",
                  rk, _near_count, _far_count);

      MPI_Reduce (&_near_count, &near_count_sum, 1, MPI_INT, MPI_SUM, 0,
                  MPI_COMM_WORLD);
      MPI_Reduce (&_far_count, &far_count_sum, 1, MPI_INT, MPI_SUM, 0,
                  MPI_COMM_WORLD);
      if (rk == 0)
        {
          g_printerr ("%d: mean call stats near=%f far=%f\n",
                      rk, (1.*near_count_sum)/sz, (1.*far_count_sum)/sz);
        }
    }

  /* check correctness of results */
  g_ptr_array_foreach (points, (GFunc) _check_pt_count,
                       &_ref_count);

  /* destroy the points */
  g_ptr_array_foreach (points, empty_array, NULL);
  g_ptr_array_free (points, TRUE);

  /* destroy the tree */
  vsg_prtree2d_free (tree);

  if (nc_padding > 0) g_free (_nc_padding_buffer);

  MPI_Finalize ();

  return ret;
}
Exemplo n.º 6
0
gint main (gint argc, gchar ** argv)
{
  gint ret = 0;

  VsgVector2d lb = {-1., -1.};
  VsgVector2d ub = {1., 1.};

  VsgVector2d points[] = {
    {-0.5, -0.5},
    {0.5, -0.5},
    {-0.5, 0.5},
    {0.25, 0.25},
    {0.75, 0.75},
    {1.75, 1.75}, /* exterior point */
  };

  const guint n = sizeof (points) / sizeof (VsgVector2d);

  VsgPRTree2d *tree;
  VsgPRTree2d *tree_clone;
  gint i;

  if (argc > 1 && g_ascii_strncasecmp (argv[1], "--version", 9) == 0)
    {
      g_print ("%s\n", PACKAGE_VERSION);
      return 0;
    }

  vsg_init_gdouble ();

  /* create the tree */
  tree =
    vsg_prtree2d_new_full (&lb, &ub,
                           (VsgPoint2dLocFunc) vsg_vector2d_vector2d_locfunc,
                           (VsgPoint2dDistFunc) vsg_vector2d_dist,
                           NULL, 1);

  /* insert some points */
  for (i=0; i<n; i++)
    {
      vsg_prtree2d_insert_point (tree, &points[i]);
    }

  /* clone the tree and destroy it */
  tree_clone = vsg_prtree2d_clone (tree);
  vsg_prtree2d_free (tree);

  /* do some traversal */
  i=0;
  vsg_prtree2d_traverse (tree_clone, G_PRE_ORDER,
                         (VsgPRTree2dFunc) traverse_point_count, &i);

  /* check the results */
  if (i != n)
    {
      g_printerr ("ERROR: traverse point count %d (should be %d)\n",
                  i, n);

      ret ++;
    }

  /* remove the points */
  for (i=0; i<n; i++)
    {
      vsg_prtree2d_remove_point (tree_clone, &points[i]);
    }

  /* destroy the cloned tree */
  vsg_prtree2d_free (tree_clone);

  return ret;
}
Exemplo n.º 7
0
gint main (gint argc, gchar ** argv)
{
  gint ret = 0;

  VsgVector2d lb = {-1., -1.};
  VsgVector2d ub = {1., 1.};

  VsgPRTree2d *tree;
  VsgPRTree2d *treeref;
  gint i;
  gint ref_far_count;

  vsg_init_gdouble ();

  parse_args (argc, argv);

#ifdef VSG_HAVE_MPI
  if (_mpi)
    {
      MPI_Init (&argc, &argv);

      MPI_Comm_size (MPI_COMM_WORLD, &sz);
      MPI_Comm_rank (MPI_COMM_WORLD, &rk);

      if (counts != NULL)
        {
          gint i = 0;
          gint tmp = 0;

          while (counts[i+1] != NULL && i<rk) i ++;

	  if (sscanf (counts[i], "%u", &tmp) == 1)
            _expect_far_count = tmp;
	  else
	    test_printerr ("Invalid expected far count list (--expect-far-counts)\n");

          g_strfreev (counts);
        }
    }
#endif

  points_array = g_ptr_array_new ();

  if (rk == 0) _fill (&_npoints, points_array);
  else _npoints = 0;

  pointsref_array = g_ptr_array_sized_new (_npoints);
  for (i=0; i<_npoints; i++)
    {
      Pt *ptref = pt_alloc (TRUE, pointsref_array);
      memcpy (ptref, (Pt *) g_ptr_array_index (points_array, i), sizeof (Pt));
    }

  /* create the trees */
  tree =
    vsg_prtree2d_new_full (&lb, &ub,
                           (VsgPoint2dLocFunc) vsg_vector2d_vector2d_locfunc,
                           (VsgPoint2dDistFunc) vsg_vector2d_dist,
                           NULL, _maxbox);
  treeref = vsg_prtree2d_clone (tree);

  vsg_prtree2d_set_nf_isleaf (tree, _nf_isleaf_virtual_maxbox,
                              &_virtual_maxbox);

  vsg_parallel_vtable_set (&pconfig.node_data,
                           node_counter_alloc, NULL,
                           node_counter_destroy, NULL);
  vsg_prtree2d_set_node_data_vtable (tree, &pconfig.node_data);

  vsg_parallel_vtable_set (&prefconfig.node_data,
                           node_counter_alloc, NULL,
                           node_counter_destroy, NULL);
  vsg_prtree2d_set_node_data_vtable (treeref, &prefconfig.node_data);

#ifdef VSG_HAVE_MPI

  if (_mpi)
    {
      vsg_parallel_vtable_set (&pconfig.point,
                               pt_alloc, points_array,
                               pt_destroy, points_array);

      vsg_parallel_vtable_set (&prefconfig.point,
                               pt_alloc, pointsref_array,
                               pt_destroy, pointsref_array);

      vsg_parallel_vtable_set_parallel (&pconfig.point,
                                        pt_migrate_pack, NULL,
                                        pt_migrate_unpack, NULL,
                                        NULL, NULL,
                                        pt_visit_fw_pack, NULL,
                                        pt_visit_fw_unpack, NULL,
                                        NULL, NULL,
                                        pt_visit_bw_pack, NULL,
                                        pt_visit_bw_unpack, NULL,
                                        pt_visit_bw_reduce, NULL);

      vsg_parallel_vtable_set_parallel (&pconfig.node_data,
                                        nc_migrate_pack, NULL,
                                        nc_migrate_unpack, NULL,
                                        NULL, NULL,
                                        nc_visit_fw_pack, NULL,
                                        nc_visit_fw_unpack, NULL,
                                        nc_visit_fw_reduce, NULL,
                                        nc_visit_bw_pack, NULL,
                                        nc_visit_bw_unpack, NULL,
                                        nc_visit_bw_reduce, NULL);

      vsg_parallel_vtable_set_parallel (&prefconfig.point,
                                        pt_migrate_pack, NULL,
                                        pt_migrate_unpack, NULL,
                                        NULL, NULL,
                                        pt_visit_fw_pack, NULL,
                                        pt_visit_fw_unpack, NULL,
                                        NULL, NULL,
                                        pt_visit_bw_pack, NULL,
                                        pt_visit_bw_unpack, NULL,
                                        pt_visit_bw_reduce, NULL);

      vsg_parallel_vtable_set_parallel (&prefconfig.node_data,
                                        nc_migrate_pack, NULL,
                                        nc_migrate_unpack, NULL,
                                        NULL, NULL,
                                        nc_visit_fw_pack, NULL,
                                        nc_visit_fw_unpack, NULL,
                                        nc_visit_fw_reduce, NULL,
                                        nc_visit_bw_pack, NULL,
                                        nc_visit_bw_unpack, NULL,
                                        nc_visit_bw_reduce, NULL);

      vsg_prtree_parallel_config_set_communicator (&pconfig, MPI_COMM_WORLD);
      vsg_prtree_parallel_config_set_communicator (&prefconfig, MPI_COMM_WORLD);

      vsg_prtree2d_set_parallel (tree, &pconfig);

      vsg_prtree2d_set_parallel (treeref, &prefconfig);
    }
#endif

  /* insert points */
  for (i=0; i<_npoints; i++)
    {
      if (_verbose)
	{
	  test_printerr ("points[%d]: ", i);
	  vsg_vector2d_write (g_ptr_array_index (points_array, i), stderr);
	  g_printerr ("\n");
	}

      vsg_prtree2d_insert_point (tree, g_ptr_array_index (points_array, i));
      vsg_prtree2d_insert_point (treeref,
                                 g_ptr_array_index (pointsref_array, i));
    }

#ifdef VSG_HAVE_MPI
  if (_mpi)
    {
      vsg_prtree2d_migrate_flush (tree);
      vsg_prtree2d_migrate_flush (treeref);

      vsg_prtree2d_distribute_contiguous_leaves (tree);
      vsg_prtree2d_distribute_contiguous_leaves (treeref);
    }
#endif

  if (_write)
    {
      gchar fn[128];
      FILE *f;

      g_sprintf (fn, "tree-%03d.txt", rk);
      f = fopen (fn, "w");
      vsg_prtree2d_write (tree, f);
      fclose (f);
      g_sprintf (fn, "treeref-%03d.txt", rk);
      f = fopen (fn, "w");
      vsg_prtree2d_write (treeref, f);
      fclose (f);
    }

  /* compute neaf/far interactions for treeref */
  _far_count = 0;
  _do_upward_pass (treeref);
  vsg_prtree2d_near_far_traversal (treeref, (VsgPRTree2dFarInteractionFunc) _far,
                                   (VsgPRTree2dInteractionFunc) _near,
                                   &ret);
  vsg_prtree2d_traverse (treeref, G_PRE_ORDER, (VsgPRTree2dFunc) _down, NULL);
  ref_far_count = _far_count;

  /* compute neaf/far interactions for tree */
  _far_count = 0;
  _do_upward_pass (tree);
  vsg_prtree2d_near_far_traversal (tree, (VsgPRTree2dFarInteractionFunc) _far,
                                   (VsgPRTree2dInteractionFunc) _near,
                                   &ret);
  vsg_prtree2d_traverse (tree, G_PRE_ORDER, (VsgPRTree2dFunc) _down, NULL);

#ifdef VSG_HAVE_MPI
  if (_mpi)
    {
      /* migrate points back to processor 0 before checking */
      vsg_prtree2d_distribute_concentrate (tree, 0);
      vsg_prtree2d_distribute_concentrate (treeref, 0);
    }
#endif

  /* check results */
  for (i=0; i<points_array->len; i++)
    {
      Pt *pt = g_ptr_array_index (points_array, i);
      /* FIXME: what if pointsref and points are no longer in the same order? */
      Pt *ptref = g_ptr_array_index (pointsref_array, i);

      if (pt->count != ptref->count)
        {
          test_printerr ("error pt[");
          vsg_vector2d_write (&pt->vector, stderr);
          g_printerr ("]=%ld ptref[", pt->count);
          vsg_vector2d_write (&ptref->vector, stderr);
          g_printerr ("]=%ld\n", ptref->count);
        }
      else if (_verbose)
        {
          test_printerr ("correct comparison [");
          vsg_vector2d_write (&pt->vector, stderr);
          g_printerr ("]=%ld ptref[", pt->count);
          vsg_vector2d_write (&ptref->vector, stderr);
          g_printerr ("]=%ld\n", ptref->count);
        }
    }

  if ((_expect_far_count >= 0) && (_expect_far_count != _far_count))
    test_printerr ("far_count=%d != expected far_count=%d (ref=%d)\n",
                   _far_count, _expect_far_count, ref_far_count);
  else if (_verbose)
    test_printerr ("far_count=%d == expected far_count=%d (ref=%d)\n",
                   _far_count, _expect_far_count, ref_far_count);

  /* remove the points */
  for (i=0; i<points_array->len; i++)
    {
      vsg_prtree2d_remove_point (tree, g_ptr_array_index (points_array, i));
      vsg_prtree2d_remove_point (treeref,
                                 g_ptr_array_index (pointsref_array, i));
    }

  /* destroy the trees */
  vsg_prtree2d_free (tree);
  vsg_prtree2d_free (treeref);

  for (i=0; i<points_array->len; i++)
    pt_destroy (g_ptr_array_index (points_array, i), FALSE, points_array);

  for (i=0; i<pointsref_array->len; i++)
    pt_destroy (g_ptr_array_index (pointsref_array, i), FALSE, pointsref_array);


  g_ptr_array_free (points_array, TRUE);
  g_ptr_array_free (pointsref_array, TRUE);

#ifdef VSG_HAVE_MPI
  if (_mpi)
    MPI_Finalize ();
#endif

  return ret;
}