Question

I'm solving a much larger problem and have run into a bug when I try to use OpenMP to parallelize some loops. I've reproduced the problem with some simpler code below that mimics my own code.

The problem is that when I run the program, it will randomly go into some sort of infinite loop/deadlock (CPU is 100%, but doesn't do anything). From what I can tell from my testing, one of the threads attempts to compute the matrix-matrix product but never finishes for some reason.

I know that if you enable OpenMP, Eigen will parallelize matrix-matrix products using OpenMP . I'm also adding another parallel loop outside of this. However, this bug still occurs if I disable Eigen's parallelization by defining EIGEN_DONT_PARALLELIZE.

I'm using gcc version 4.6.0 20101127 on MacOS 10.6.8 with Eigen 3.0.4.

I can't figure out what could be going wrong...

#include <iostream>
#include <Eigen/Core>

using namespace std;
using namespace Eigen;

MatrixXd Test(MatrixXd const& F, MatrixXd const& G)
{
  MatrixXd H(F.rows(), G.cols());
  H.noalias() = F*G;

  return H;
}

int main()
{
  MatrixXd F = MatrixXd::Random(2,2);
  MatrixXd G = MatrixXd::Random(2,2);

  #pragma omp parallel for
  for (unsigned int i = 0; i < 10000; ++i)
    MatrixXd H = Test(F,G);

  cout << "Done!" << endl;
}
Was it helpful?

Solution

After some debugging, I think the problem is located in Eigen. In the file src/Core/products/GeneralBlockPanelKernel.h there is a function called manage_caching_sizes that declares two static variables:

static std::ptrdiff_t m_l1CacheSize = 0;
static std::ptrdiff_t m_l2CacheSize = 0;

Changing this to:

static std::ptrdiff_t m_l1CacheSize = 0;
static std::ptrdiff_t m_l2CacheSize = 0;
#pragma omp threadprivate(m_l1CacheSize, m_l2CacheSize)

fixed my problem.

OTHER TIPS

I had the same problem, even with the most recent version of Eigen (3.0.5). I tried the fix proposed above and it is not possible with version 3.0.5, because of the new initializers. So I made the following change :

static std::ptrdiff_t m_l1CacheSize;
static std::ptrdiff_t m_l2CacheSize;
#pragma omp threadprivate(m_l1CacheSize, m_l2CacheSize)

if (m_l1CacheSize==0)
{
    m_l1CacheSize = manage_caching_sizes_second_if_negative(queryL1CacheSize(),8 * 1024);
    m_l2CacheSize = manage_caching_sizes_second_if_negative(queryTopLevelCacheSize(),1*1024*1024);
}

fixed my problem.

I was having the same problem using Microsoft Visual Studio 2010 SP1 PPL / parallel_for. The solution is described in

http://eigen.tuxfamily.org/dox/TopicMultiThreading.html

Using Eigen in a multi-threaded application

In the case your own application is multithreaded, and multiple threads make calls to Eigen, then you have to initialize Eigen by calling the following routine before creating the threads:

#include <Eigen/Core>

int main(int argc, char** argv)
{
  Eigen::initParallel();

  ...
}

In the case your application is parallelized with OpenMP, you might want to disable Eigen's own parallization as detailed in the previous section.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top