← Back to team overview

dolfin team mailing list archive

[noreply@xxxxxxxxxxxxx: [Branch ~dolfin-core/dolfin/main] Rev 5270: Add initial interface for Zoltan.]

 

Having a common interface to ParMETIS and SCOTCH would be nice to have
(especially ParMETIS since it has a horrible interface), but I would
not want to have Trilinos as a dependency.

--
Anders
--- Begin Message ---
------------------------------------------------------------
revno: 5270
committer: Garth N. Wells <gnw20@xxxxxxxxx>
branch nick: dolfin-all
timestamp: Mon 2010-11-15 17:50:12 +0000
message:
  Add initial interface for Zoltan.
  
  Zoltan is part of Trilinos, and provides partitioning, renumbering and colouring functionality. It can act as an interface for ParMETIS, SCOTCH, etc.
added:
  dolfin/graph/Zoltan.cpp
  dolfin/graph/Zoltan.h
modified:
  dolfin/fem/UFC.cpp
  dolfin/fem/UFC.h
  dolfin/fem/dolfin_fem.h
  dolfin/graph/dolfin_graph.h
  dolfin/la/SparsityPattern.h


--
lp:dolfin
https://code.launchpad.net/~dolfin-core/dolfin/main

Your team DOLFIN Core Team is subscribed to branch lp:dolfin.
To unsubscribe from this branch go to https://code.launchpad.net/~dolfin-core/dolfin/main/+edit-subscription
=== modified file 'dolfin/fem/UFC.cpp'
--- dolfin/fem/UFC.cpp	2010-11-14 23:11:09 +0000
+++ dolfin/fem/UFC.cpp	2010-11-15 17:50:12 +0000
@@ -2,10 +2,10 @@
 // Licensed under the GNU LGPL Version 2.1.
 //
 // Modified by Ola Skavhaug, 2009
-// Modified by Garth N. Wells, 2009
+// Modified by Garth N. Wells, 2010
 //
 // First added:  2007-01-17
-// Last changed: 2010-11-09
+// Last changed: 2010-11-15
 
 #include <dolfin/common/types.h>
 #include <dolfin/function/FunctionSpace.h>
@@ -58,6 +58,12 @@
 //-----------------------------------------------------------------------------
 void UFC::init(const Form& form)
 {
+  // Initialize mesh
+  this->mesh.init(form.mesh());
+
+  // Get function spaces for arguments
+  std::vector<boost::shared_ptr<const FunctionSpace> > V = form.function_spaces();
+
   // Create finite elements
   for (uint i = 0; i < this->form.rank(); i++)
   {
@@ -84,27 +90,26 @@
   for (uint i = 0; i < this->form.num_interior_facet_integrals(); i++)
     interior_facet_integrals.push_back( boost::shared_ptr<ufc::interior_facet_integral>(this->form.create_interior_facet_integral(i)) );
 
-  // Initialize mesh
-  this->mesh.init(form.mesh());
-
-  // Get function spaces for arguments
-  std::vector<boost::shared_ptr<const FunctionSpace> > V = form.function_spaces();
+  // Get maximum local dimensions
+  std::vector<uint> max_local_dimension;
+  std::vector<uint> max_macro_local_dimension;
+  for (uint i = 0; i < this->form.rank(); i++)
+  {
+    max_local_dimension.push_back(V[i]->dofmap().max_local_dimension());
+    max_macro_local_dimension.push_back(2*V[i]->dofmap().max_local_dimension());
+  }
 
   // Initialize local tensor
   uint num_entries = 1;
   for (uint i = 0; i < this->form.rank(); i++)
-    num_entries *= V[i]->dofmap().max_local_dimension();
+    num_entries *= max_local_dimension[i];
   A.reset(new double[num_entries]);
-  for (uint i = 0; i < num_entries; i++)
-    A[i] = 0.0;
 
   // Initialize local tensor for macro element
   num_entries = 1;
   for (uint i = 0; i < this->form.rank(); i++)
-    num_entries *= 2*V[i]->dofmap().max_local_dimension();
+    num_entries *= max_macro_local_dimension[i];
   macro_A.reset(new double[num_entries]);
-  for (uint i = 0; i < num_entries; i++)
-    macro_A[i] = 0.0;
 
   // Allocate memory for storing local dimensions
   local_dimensions.reset(new uint[this->form.rank()]);
@@ -118,34 +123,17 @@
   // Initialize dofs
   dofs = new uint*[this->form.rank()];
   for (uint i = 0; i < this->form.rank(); i++)
-  {
-    dofs[i] = new uint[V[i]->dofmap().max_local_dimension()];
-    for (uint j = 0; j < V[i]->dofmap().max_local_dimension(); j++)
-      dofs[i][j] = 0;
-  }
-  //dofs.ressize(this->form.rank());
-  //for (uint i = 0; i < this->form.rank(); i++)
-  //  dof[i].resize(local_dimensions[i]);
+    dofs[i] = new uint[max_local_dimension[i]];
 
   // Initialize dofs on macro element
   macro_dofs = new uint*[this->form.rank()];
   for (uint i = 0; i < this->form.rank(); i++)
-  {
-    const uint max_dimension = 2*V[i]->dofmap().max_local_dimension();
-    macro_dofs[i] = new uint[max_dimension];
-    for (uint j = 0; j < max_dimension; j++)
-      macro_dofs[i][j] = 0;
-  }
+    macro_dofs[i] = new uint[max_macro_local_dimension[i]];
 
   // Initialize coefficients
   w = new double*[this->form.num_coefficients()];
   for (uint i = 0; i < this->form.num_coefficients(); i++)
-  {
-    const uint n = coefficient_elements[i].space_dimension();
-    w[i] = new double[n];
-    for (uint j = 0; j < n; j++)
-      w[i][j] = 0.0;
-  }
+    w[i] = new double[coefficient_elements[i].space_dimension()];
 
   // Initialize coefficients on macro element
   macro_w = new double*[this->form.num_coefficients()];
@@ -153,8 +141,6 @@
   {
     const uint n = 2*coefficient_elements[i].space_dimension();
     macro_w[i] = new double[n];
-    for (uint j = 0; j < n; j++)
-      macro_w[i][j] = 0.0;
   }
 }
 //-----------------------------------------------------------------------------
@@ -165,7 +151,10 @@
 
   // Update local dimensions
   for (uint i = 0; i < form.rank(); i++)
-    local_dimensions[i] = dolfin_form.function_space(i)->dofmap().local_dimension(this->cell);
+  {
+    local_dimensions[i]
+      = dolfin_form.function_space(i)->dofmap().local_dimension(this->cell);
+  }
 
   // Restrict coefficients to cell
   for (uint i = 0; i < coefficients.size(); ++i)
@@ -182,7 +171,10 @@
 
   // Update local dimensions
   for (uint i = 0; i < form.rank(); i++)
-    local_dimensions[i] = dolfin_form.function_space(i)->dofmap().local_dimension(this->cell);
+  {
+    local_dimensions[i]
+        = dolfin_form.function_space(i)->dofmap().local_dimension(this->cell);
+  }
 
   // Restrict coefficients to facet
   for (uint i = 0; i < coefficients.size(); ++i)
@@ -211,8 +203,10 @@
   for (uint i = 0; i < coefficients.size(); ++i)
   {
     const uint offset = coefficient_elements[i].space_dimension();
-    coefficients[i]->restrict(macro_w[i],          coefficient_elements[i], cell0, this->cell0, local_facet0);
-    coefficients[i]->restrict(macro_w[i] + offset, coefficient_elements[i], cell1, this->cell1, local_facet1);
+    coefficients[i]->restrict(macro_w[i],          coefficient_elements[i],
+                              cell0, this->cell0, local_facet0);
+    coefficients[i]->restrict(macro_w[i] + offset, coefficient_elements[i],
+                              cell1, this->cell1, local_facet1);
   }
 }
 //-----------------------------------------------------------------------------

=== modified file 'dolfin/fem/UFC.h'
--- dolfin/fem/UFC.h	2010-11-14 23:11:09 +0000
+++ dolfin/fem/UFC.h	2010-11-15 17:50:12 +0000
@@ -104,7 +104,6 @@
 
     // Mapped dofs for primary arguments
     uint** dofs;
-    //std::vector<std::vector<uint> > dofs;
 
     // Mapped dofs of macro element for primary arguments
     uint** macro_dofs;

=== modified file 'dolfin/fem/dolfin_fem.h'
--- dolfin/fem/dolfin_fem.h	2010-11-08 09:16:09 +0000
+++ dolfin/fem/dolfin_fem.h	2010-11-15 17:50:12 +0000
@@ -14,6 +14,7 @@
 #include <dolfin/fem/assemble.h>
 #include <dolfin/fem/Form.h>
 #include <dolfin/fem/Assembler.h>
+#include <dolfin/fem/SparsityPatternBuilder.h>
 #include <dolfin/fem/SystemAssembler.h>
 #include <dolfin/fem/MulticoreAssembler.h>
 #include <dolfin/fem/VariationalProblem.h>

=== added file 'dolfin/graph/Zoltan.cpp'
--- dolfin/graph/Zoltan.cpp	1970-01-01 00:00:00 +0000
+++ dolfin/graph/Zoltan.cpp	2010-11-15 17:50:12 +0000
@@ -0,0 +1,156 @@
+// Copyright (C) 2010 Garth N. Wells.
+// Licensed under the GNU LGPL Version 2.1.
+//
+// First added:  2010-11-15
+// Last changed:
+
+#ifdef HAS_TRILINOS
+
+#include "dolfin/log/log.h"
+#include "Zoltan.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+ZoltanInterface::ZoltanInterface(const SparsityPattern& sparsity_pattern)
+      : sparsity_pattern(sparsity_pattern)
+{
+  if (sparsity_pattern.rank() != 2)
+    error("Can only create Zoltan object for SparsityPattern of rank 2.");
+
+  if (sparsity_pattern.size(0) != sparsity_pattern.size(1))
+    error("Can only create Zoltan object square SparsityPattern (for now).");
+}
+//-----------------------------------------------------------------------------
+int ZoltanInterface::num_global_objects() const
+{
+  return sparsity_pattern.size(0);
+}
+//-----------------------------------------------------------------------------
+int ZoltanInterface::num_local_objects() const
+{
+  return sparsity_pattern.size(0);
+}
+//-----------------------------------------------------------------------------
+void ZoltanInterface::num_edges_per_vertex(uint* num_edges) const
+{
+  sparsity_pattern.num_nonzeros_diagonal(num_edges);
+}
+//-----------------------------------------------------------------------------
+const std::vector<Set<dolfin::uint> >& ZoltanInterface::edges() const
+{
+  return sparsity_pattern.diagonal_pattern();
+}
+//-----------------------------------------------------------------------------
+std::vector<dolfin::uint> ZoltanInterface::local_renumbering_map()
+{
+  // Initialise Zoltan
+  float version;
+  int argc = 0;
+  char** argv = NULL;
+  Zoltan_Initialize(argc, argv, &version);
+
+  // Create Zoltan object
+  Zoltan zoltan(MPI::COMM_WORLD);
+
+  // Set parameters
+  zoltan.Set_Param( "ORDER_METHOD", "METIS");
+  zoltan.Set_Param( "NUM_GID_ENTRIES", "1");  /* global ID is 1 integer */
+  zoltan.Set_Param( "NUM_LID_ENTRIES", "1");  /* local ID is 1 integer */
+  zoltan.Set_Param( "OBJ_WEIGHT_DIM", "0");   /* omit object weights */
+
+  // Set call-back functions
+  zoltan.Set_Num_Obj_Fn(ZoltanInterface::get_number_of_objects, this);
+  zoltan.Set_Obj_List_Fn(ZoltanInterface::get_object_list, this);
+  zoltan.Set_Num_Edges_Multi_Fn(ZoltanInterface::get_number_edges, this);
+  zoltan.Set_Edge_List_Multi_Fn(ZoltanInterface::get_all_edges, this);
+
+  // Create array for global ids that should be renumbered
+  ZOLTAN_ID_PTR  global_ids = new ZOLTAN_ID_TYPE[num_global_objects()];
+  for (int i = 0; i < num_global_objects(); ++i)
+    global_ids[i] = i;
+
+  // Create array for renumbered vertices
+  ZOLTAN_ID_PTR new_id = new ZOLTAN_ID_TYPE[num_global_objects()];
+
+  // Perform re-ordering
+  int rc = zoltan.Order(1, num_global_objects(), global_ids, new_id);
+
+  // Check for errors
+  if (rc != ZOLTAN_OK)
+    error("Partitioning failed");
+
+  // Copy renumber into a vector
+  std::vector<uint> map(num_global_objects());
+  for (uint i = 0; i < map.size(); ++i)
+    map[i] = new_id[i];
+
+  // Clean up
+  delete global_ids;
+  delete new_id;
+
+  return map;
+}
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+int ZoltanInterface::get_number_of_objects(void *data, int *ierr)
+{
+  ZoltanInterface *objs = (ZoltanInterface *)data;
+  *ierr = ZOLTAN_OK;
+  return objs->num_local_objects();
+}
+//-----------------------------------------------------------------------------
+void ZoltanInterface::get_object_list(void *data, int sizeGID, int sizeLID,
+          ZOLTAN_ID_PTR globalID, ZOLTAN_ID_PTR localID,
+          int wgt_dim, float *obj_wgts, int *ierr)
+{
+  ZoltanInterface *objs = (ZoltanInterface *)data;
+  *ierr = ZOLTAN_OK;
+  for (int i = 0; i< objs->num_local_objects(); i++)
+  {
+    globalID[i] = i;
+    localID[i] = i;
+  }
+}
+//-----------------------------------------------------------------------------
+void ZoltanInterface::get_number_edges(void *data, int num_gid_entries,
+                                       int num_lid_entries,
+                                       int num_obj, ZOLTAN_ID_PTR global_ids,
+                                       ZOLTAN_ID_PTR local_ids, int *num_edges,
+                                       int *ierr)
+{
+  ZoltanInterface *objs = (ZoltanInterface *)data;
+
+  //std::cout << "Testing global id entires: " << num_gid_entries << "  " << objs->num_global_objects() << std::endl;
+  //std::cout << "Testing local id entires: "  << num_lid_entries << "  " << objs->num_local_objects() << std::endl;
+  //assert(num_gid_entries == objs->num_global_objects());
+  //assert(num_lid_entries == objs->num_local_objects());
+
+  objs->num_edges_per_vertex(reinterpret_cast<uint*>(num_edges));
+}
+//-----------------------------------------------------------------------------
+void ZoltanInterface::get_all_edges(void *data, int num_gid_entries,
+                              int num_lid_entries, int num_obj,
+                              ZOLTAN_ID_PTR global_ids,
+                              ZOLTAN_ID_PTR local_ids,
+                              int *num_edges,
+                              ZOLTAN_ID_PTR nbor_global_id,
+                              int *nbor_procs, int wgt_dim,
+                              float *ewgts, int *ierr)
+{
+  std::cout << "Testing:" << num_gid_entries << "  " << num_lid_entries << std::endl;
+
+  ZoltanInterface *objs = (ZoltanInterface *)data;
+  const std::vector<Set<uint> >& edges = objs->edges();
+
+  uint sum = 0;
+  for (uint i = 0; i < edges.size(); ++i)
+  {
+    assert(edges[i].size() == (uint) num_edges[i]);
+    for (uint j = 0; j < edges[i].size(); ++j)
+      nbor_global_id[sum*num_gid_entries + j] = edges[i][j];
+    sum += edges[i].size();
+  }
+}
+//-----------------------------------------------------------------------------
+#endif

=== added file 'dolfin/graph/Zoltan.h'
--- dolfin/graph/Zoltan.h	1970-01-01 00:00:00 +0000
+++ dolfin/graph/Zoltan.h	2010-11-15 17:50:12 +0000
@@ -0,0 +1,84 @@
+// Copyright (C) 2010 Garth N. Wells.
+// Licensed under the GNU LGPL Version 2.1.
+//
+// First added:  2010-11-15
+// Last changed:
+
+#ifndef __DOLFIN_ZOLTAN_H
+#define __DOLFIN_ZOLTAN_H
+
+#ifdef HAS_TRILINOS
+
+#include <vector>
+#include <zoltan_cpp.h>
+#include "dolfin/common/Set.h"
+#include "dolfin/common/types.h"
+#include <dolfin/la/SparsityPattern.h>
+
+namespace dolfin
+{
+
+  /// This class provides an interface for Zoltan
+
+  class ZoltanInterface
+  {
+
+  public:
+
+    /// Build distribted dual graph for mesh
+    ZoltanInterface(const SparsityPattern& sparsity_pattern);
+
+  private:
+
+    /// Number of global graph vertices
+    int num_global_objects() const;
+
+    /// Number of local graph vertices
+    int num_local_objects() const;
+
+    /// Number of edges per vertex
+    void num_edges_per_vertex(uint* num_edges) const;
+
+    /// Vertex edges
+    const std::vector<Set<uint> >& edges() const;
+
+  public:
+
+    /// Runumbering map on on process (map[old] -> new)
+    std::vector<uint> local_renumbering_map();
+
+  private:
+
+    // Zoltan call-back functions
+
+    static int get_number_of_objects(void *data, int *ierr);
+
+    static void get_object_list(void *data, int sizeGID, int sizeLID,
+                                ZOLTAN_ID_PTR globalID,
+                                ZOLTAN_ID_PTR localID, int wgt_dim,
+                                float *obj_wgts, int *ierr);
+
+    static void get_number_edges(void *data, int num_gid_entries,
+                                 int num_lid_entries,
+                                 int num_obj, ZOLTAN_ID_PTR global_ids,
+                                 ZOLTAN_ID_PTR local_ids, int *num_edges,
+                                 int *ierr);
+
+    static void get_all_edges(void *data, int num_gid_entries,
+                              int num_lid_entries, int num_obj,
+                              ZOLTAN_ID_PTR global_ids,
+                              ZOLTAN_ID_PTR local_ids,
+                              int *num_edges,
+                              ZOLTAN_ID_PTR nbor_global_id,
+                              int *nbor_procs, int wgt_dim,
+                              float *ewgts, int *ierr);
+
+
+    const SparsityPattern& sparsity_pattern;
+
+  };
+
+}
+
+#endif
+#endif

=== modified file 'dolfin/graph/dolfin_graph.h'
--- dolfin/graph/dolfin_graph.h	2010-02-10 19:28:38 +0000
+++ dolfin/graph/dolfin_graph.h	2010-11-15 17:50:12 +0000
@@ -3,5 +3,6 @@
 
 // DOLFIN graph
 
+#include <dolfin/graph/Zoltan.h>
 
 #endif

=== modified file 'dolfin/la/SparsityPattern.h'
--- dolfin/la/SparsityPattern.h	2010-02-24 21:47:47 +0000
+++ dolfin/la/SparsityPattern.h	2010-11-15 17:50:12 +0000
@@ -11,6 +11,7 @@
 
 #include <vector>
 #include "dolfin/common/Set.h"
+#include "dolfin/common/types.h"
 #include "GenericSparsityPattern.h"
 
 namespace dolfin


--- End Message ---

Follow ups