void check_point_accum (PointAccum *point, gint *ret) { gint i; gcomplex128 err; gdouble abserr; i = point->id; err = (point->accum - check_points[i].accum) / MAX(cabs (point->accum), cabs (check_points[i].accum)); abserr = cabs (err); if (maxerr < abserr) maxerr = abserr; if (abserr > err_lim || !finite (abserr)) { g_printerr ("%d : Error on pt%d res=(%e,%e) ref(%e,%e) err=(%e,%e) pt=", rk, i, creal (point->accum), cimag (point->accum), creal (check_points[i].accum), cimag (check_points[i].accum), creal (err), cimag (err)); vsg_vector2d_write (&point->vector, stderr); g_printerr ("\n"); (*ret) ++; } }
void _check_pt_count (Pt *pt, const glong *ref) { if (pt->count != *ref) { g_printerr ("%d : error ", rk); vsg_vector2d_write (&pt->vector, stderr); g_printerr (" weight=%d count=%ld (should be %ld)\n", pt->weight, pt->count, *ref); } }
int main (int argc, char **argv) { VsgVector2d lbound = {-1., -1.}; VsgVector2d ubound = {1., 1.}; PointAccum *points[N] = {0}; VsgPRTree2d *prtree; AranSolver2d *solver; int ret = 0; guint i; aran_init(); parse_args (argc, argv); prtree = vsg_prtree2d_new_full (&lbound, &ubound, (VsgPoint2dLocFunc) vsg_vector2d_vector2d_locfunc, (VsgPoint2dDistFunc) vsg_vector2d_dist, (VsgRegion2dLocFunc) NULL, maxbox); aran_binomial_require (2*order); solver = aran_solver2d_new (prtree, ARAN_TYPE_DEVELOPMENT2D, aran_development2d_new (0, order), (AranZeroFunc) aran_development2d_set_zero); aran_solver2d_set_functions (solver, (AranParticle2ParticleFunc2d) p2p, (AranParticle2MultipoleFunc2d) p2m, (AranMultipole2MultipoleFunc2d) aran_development2d_m2m, (AranMultipole2LocalFunc2d) aran_development2d_m2l, (AranLocal2LocalFunc2d) aran_development2d_l2l, (AranLocal2ParticleFunc2d)l2p); _distribution (points, solver); aran_solver2d_solve (solver); /* vsg_prtree2d_write (prtree, stderr); */ aran_solver2d_free (solver); if (check) { for (i=0; i<np; i++) { guint j; gcomplex128 sum = 0.; gcomplex128 err; for (j=0; j<np; j++) { if (i != j) { gcomplex128 zd_m_zs = (points[i]->vector.x + I*points[i]->vector.y) - (points[j]->vector.x + I*points[j]->vector.y); sum += 1./zd_m_zs * points[j]->density; } } err = (points[i]->accum - sum) / MAX(cabs (points[i]->accum), cabs (sum)); if (cabs (err) > err_lim) { g_printerr ("Error: pt%u (%e,%e) -> ", i, creal (err), cimag (err)); vsg_vector2d_write (&points[i]->vector, stderr); g_printerr ("\n"); ret ++; } } } for (i=0; i<np; i++) { g_free (points[i]); } return ret; }
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; }