]> https://gitweb.dealii.org/ - dealii.git/commitdiff
enable multithreading
authorThomas Richter <thomas.richter@iwr.uni-heidelberg.de>
Fri, 11 Feb 2000 13:27:47 +0000 (13:27 +0000)
committerThomas Richter <thomas.richter@iwr.uni-heidelberg.de>
Fri, 11 Feb 2000 13:27:47 +0000 (13:27 +0000)
git-svn-id: https://svn.dealii.org/trunk@2388 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/deal.II/source/numerics/data_out.cc

index 5fc709eac66ea4d1724f54b31a6f7624884dbe98..65c8e67ca1b9a4e2feea2e6a61343d84936e9615 100644 (file)
@@ -11,6 +11,9 @@
 #include <fe/fe.h>
 #include <fe/fe_values.h>
 
+#ifdef DEAL_II_USE_MT
+#include <base/thread_manager.h>
+#endif
 
 template <int dim>
 DataOut_DoFData<dim>::DataEntry::DataEntry (const Vector<double> *data,
@@ -19,24 +22,17 @@ DataOut_DoFData<dim>::DataEntry::DataEntry (const Vector<double> *data,
                names(names)
 {};
 
-
-
-
 template <int dim>
 DataOut_DoFData<dim>::DataOut_DoFData () :
                dofs(0)
 {};
 
-
-
 template <int dim>
 DataOut_DoFData<dim>::~DataOut_DoFData ()
 {
   clear ();
 };
 
-
-
 template <int dim>
 void DataOut_DoFData<dim>::attach_dof_handler (const DoFHandler<dim> &d)
 {
@@ -51,8 +47,6 @@ void DataOut_DoFData<dim>::attach_dof_handler (const DoFHandler<dim> &d)
     dofs->subscribe ();
 };
 
-
-
 template <int dim>
 void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
                                            const vector<string> &names)
@@ -144,92 +138,59 @@ DataOut_DoFData<dim>::get_patches () const
 };
 
 
-
-
-
-
 template <int dim>
-void DataOut<dim>::build_patches (const unsigned int n_subdivisions) 
+void * DataOut<dim>::build_some_patches (Data data)
 {
-  Assert (dofs != 0, ExcNoDoFHandlerSelected());
-  
-  const unsigned int n_components   = dofs->get_fe().n_components();
-  const unsigned int n_datasets     = dof_data.size() * n_components +
-                                     cell_data.size();
-  
-                                  // clear the patches array
-  if (true)
-    {
-      vector<DataOutBase::Patch<dim> > dummy;
-      patches.swap (dummy);
-    };
+  QTrapez<1>     q_trapez;
+  QIterated<dim> patch_points (q_trapez, data.n_subdivisions);
   
+  FEValues<dim> fe_patch_values(dofs->get_fe(),
+                               patch_points,
+                               update_default);
 
-                                  // first count the cells we want to
-                                  // create patches of and make sure
-                                  // there is enough memory for that
-  unsigned int n_patches = 0;
-  for (DoFHandler<dim>::cell_iterator cell=first_cell();
-       cell != dofs->end();
-       cell = next_cell(cell))
-    ++n_patches;
-
-
-                                  // before we start the loop:
-                                  // create a quadrature rule that
-                                  // actually has the points on this
-                                  // patch, and an object that
-                                  // extracts the data on each
-                                  // cell to these points
-  QTrapez<1>     q_trapez;
-  QIterated<dim> patch_points (q_trapez, n_subdivisions);
-  FEValues<dim>  fe_patch_values (dofs->get_fe(),
-                                 patch_points,
-                                 update_default);
   const unsigned int n_q_points = patch_points.n_quadrature_points;
-  vector<double>          patch_values (n_q_points);
-  vector<Vector<double> > patch_values_system (n_q_points,
-                                              Vector<double>(n_components));
   
-  DataOutBase::Patch<dim>  default_patch;
-  default_patch.n_subdivisions = n_subdivisions;
-  default_patch.data.reinit (n_datasets, n_q_points);
-  patches.insert (patches.end(), n_patches, default_patch);
+  unsigned int cell_number = 0;
+  vector<DataOutBase::Patch<dim> >::iterator patch = patches.begin();
+  DoFHandler<dim>::cell_iterator cell=first_cell();
 
-                                  // now loop over all cells and
+                                  // get first cell in this thread
+  for (unsigned int i=0;i<data.this_thread;++i,++patch,++cell_number,
+                cell=next_cell(cell));
+  
+                                  // now loop over all cells and
                                   // actually create the patches
-  vector<DataOutBase::Patch<dim> >::iterator patch = patches.begin();
-  unsigned int                               cell_number = 0;
-  for (DoFHandler<dim>::cell_iterator cell=first_cell();
-       cell != dofs->end(); cell=next_cell(cell), ++patch, ++cell_number)
+  for (;cell != dofs->end();)
     {
       Assert (patch != patches.end(), ExcInternalError());
       
       for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
        patch->vertices[vertex] = cell->vertex(vertex);
-
-      if (n_datasets > 0)
+      
+      if (data.n_datasets > 0)
        {
          fe_patch_values.reinit (cell);
          
                                           // first fill dof_data
          for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
            {
-             if (n_components == 1)
+             if (data.n_components == 1)
                {
                  fe_patch_values.get_function_values (*dof_data[dataset].data,
-                                                      patch_values);
+                                                      data.patch_values);
                  for (unsigned int q=0; q<n_q_points; ++q)
-                   patch->data(dataset,q) = patch_values[q];
+                   patch->data(dataset,q) = data.patch_values[q];
                }
              else
                                                 // system of components
                {
                  fe_patch_values.get_function_values (*dof_data[dataset].data,
-                                                      patch_values_system);
-                 for (unsigned int component=0; component<n_components; ++component)
+                                                      data.patch_values_system);
+                 for (unsigned int component=0; component<data.n_components;
+                      ++component)
                    for (unsigned int q=0; q<n_q_points; ++q)
-                     patch->data(dataset*n_components+component,q) = patch_values_system[q](component);
+                     patch->data(dataset*data.n_components+component,q) =
+                       data.patch_values_system[q](component);
                };
            };
 
@@ -238,10 +199,115 @@ void DataOut<dim>::build_patches (const unsigned int n_subdivisions)
            {
              const double value = (*cell_data[dataset].data)(cell_number);
              for (unsigned int q=0; q<n_q_points; ++q)
-               patch->data(dataset+dof_data.size()*n_components,q) = value;
+               patch->data(dataset+dof_data.size()*data.n_components,q) =
+                 value;
            };
        };
+                                      // next cell (patch) in this thread
+      for (unsigned int i=0;((i<data.n_threads)&&(cell != dofs->end()));
+          ++i,++patch,++cell_number,cell=next_cell(cell));
+      
+    };
+  
+  return 0;
+}
+
+
+
+
+template <int dim>
+void DataOut<dim>::build_patches (const unsigned int n_subdivisions,
+                                 const unsigned int n_threads_) 
+{
+  unsigned int n_threads = n_threads_;
+
+  Assert (dofs != 0, ExcNoDoFHandlerSelected());
+
+                                  // if not in multithread mode
+                                  // set nr of threads to one
+#ifndef DEAL_II_USE_MT
+  n_threads = 1;
+#endif
+
+
+                                  // before we start the loop:
+                                  // create a quadrature rule that
+                                  // actually has the points on this
+                                  // patch
+  QTrapez<1>     q_trapez;
+  QIterated<dim> patch_points (q_trapez, n_subdivisions);
+
+  const unsigned int n_q_points     = patch_points.n_quadrature_points;
+  const unsigned int n_components   = dofs->get_fe().n_components();
+  const unsigned int n_datasets     = dof_data.size() * n_components +
+                                     cell_data.size();
+  
+                                  // clear the patches array
+  if (true)
+    {
+      vector<DataOutBase::Patch<dim> > dummy;
+      patches.swap (dummy);
     };
+  
+                                  // first count the cells we want to
+                                  // create patches of and make sure
+                                  // there is enough memory for that
+  unsigned int n_patches = 0;
+  for (DoFHandler<dim>::cell_iterator cell=first_cell();
+       cell != dofs->end();
+       cell = next_cell(cell))
+    ++n_patches;
+
+  vector<Data> thread_data(n_threads);
+
+                                  // init data for the threads
+  for (unsigned int i=0;i<n_threads;++i)
+    {
+      thread_data[i].n_threads      = n_threads;
+      thread_data[i].this_thread    = i;
+      thread_data[i].n_components   = n_components;
+      thread_data[i].n_datasets     = n_datasets;
+      thread_data[i].n_subdivisions = n_subdivisions;
+      thread_data[i].patch_values.resize(n_q_points);
+      thread_data[i].patch_values_system.resize(n_q_points);
+      
+      for (unsigned int k=0;k<n_components;++k)
+       thread_data[i].patch_values_system[k].reinit(n_components);
+    }
+
+                                  // create the patches with
+                                  // default values
+  DataOutBase::Patch<dim>  default_patch;
+  default_patch.n_subdivisions = n_subdivisions;
+  default_patch.data.reinit (n_datasets, n_q_points);
+  patches.insert (patches.end(), n_patches, default_patch);
+
+#ifdef DEAL_II_USE_MT
+
+  ThreadManager thread_manager;
+  
+  typedef ThreadManager::Mem_Fun_Data1
+    <DataOut<dim>, Data > MemFunData;
+  
+                                  // One struct of this type for every thread
+  vector<MemFunData> mem_fun_data (n_threads,
+                                  MemFunData (this,
+                                              thread_data[0],
+                                              &DataOut<dim>::build_some_patches));
+  
+                                  // get start cells for each thread
+  for (unsigned int l=0;l<n_threads;++l)
+    {
+      mem_fun_data[l].arg=thread_data[l];
+      thread_manager.spawn(&mem_fun_data[l],THR_SCOPE_SYSTEM | THR_DETACHED);
+    };
+                                  // wait for all threads to return
+  thread_manager.wait();
+  
+                                  // just one thread
+#else
+  build_some_patches(thread_data[0]);
+#endif
 };
 
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.