Термин не относится к функции, принимающей 2 аргумента - PullRequest
0 голосов
/ 06 декабря 2018

Я пытаюсь получить блокировки для каждого элемента в моей матрице для этого я пишу следующий код:

std::map<unsigned int, omp_lock_t> ds_lock;
void Sparse_Matrix_FL::setValue(unsigned int rid, unsigned int cid, double value)
{
    omp_set_lock(&ds_lock(rid,cid));
    std::map<unsigned int, double>::iterator str = data_Matrix[rid].begin();
    std::map<unsigned int, double>::iterator end = data_Matrix[rid].end();

    while (str->first != cid && str != end) str++;
    if (str != end)
        if (value != 0)
            str->second = value;
        else
            data_Matrix[rid].erase(str);
    else
        if (value != 0)
            data_Matrix[rid][cid] = value;
omp_unset_lock(&ds_lock(rid,cid));
}

Но я получил ошибки:

вызов объектатипа класса без соответствующего оператора () или функций преобразования в указатель на тип функции

Это еще одна ошибка.

член не оценивает функцию, принимающую2 аргумента

Я не могу понять, где я делаю это неправильно.

1 Ответ

0 голосов
/ 07 декабря 2018

Вы можете искать std::map элементы либо через оператор индекса [], либо используя метод find.std::map не вызывается, поэтому вы не можете использовать синтаксис ds_lock(rid,cid).

Ваша карта должна использовать std::pair< unsigned int, unsigned int > в качестве типа ключа.

После этого вы сможете заблокироватьиспользование omp_set_lock(&ds_lock[std::make_pair(rid,cid)]);

Однако вам необходимо убедиться, что каждый использованный элемент карты был инициализирован заранее, в противном случае, поскольку std::map не является потокобезопасным, вы столкнетесь с проблемами, когда оператор индекса автоматически создаст новыйэлементам, вам также нужно будет вызвать omp_init_lock для вновь созданных значений.

Чтобы гарантировать, что omp_unset_lock всегда вызывается с использованием шаблона RAII , будет целесообразно.Полностью работающий пример устранения вышеуказанных проблем может выглядеть примерно так:

class omp_locker
{
  public:
    omp_locker( omp_lock_t& lock )
    : lock( lock )
    {
      omp_set_lock( &lock );
    }
    omp_locker( const omp_locker& ) = delete;
    omp_locker& operator=( const omp_locker& ) = delete;

    ~omp_locker()
    {
      omp_unset_lock( &lock );
    }

  private:
    omp_lock_t& lock;
};

std::map< std::pair< unsigned int, unsigned int >, omp_lock_t> ds_lock;
std::mutex ds_lock_mutex;

omp_lock_t& getLock( unsigned int rid, unsigned int cid )
{
  std::lock_guard lock( ds_lock_mutex );
  auto key = std::make_pair( rid, cid );
  auto it = ds_lock.find( key );
  if ( it == ds_lock.end() )
  {
    it = ds_lock.insert( it, std::make_pair( key, omp_lock_t() ) );
    omp_init_lock( it->second );
  }
  return it->second;
}

void Sparse_Matrix_FL::setValue(unsigned int rid, unsigned int cid, double value)
{
    omp_locker lock( getLock( rid, cid ) );
    std::map<unsigned int, double>::iterator str = data_Matrix[rid].begin();
    std::map<unsigned int, double>::iterator end = data_Matrix[rid].end();

    while (str->first != cid && str != end) str++;
    if (str != end)
        if (value != 0)
            str->second = value;
        else
            data_Matrix[rid].erase(str);
    else
        if (value != 0)
            data_Matrix[rid][cid] = value;
}

Вам нужно будет вызвать omp_destroy_lock для каждого элемента std::map в конце вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...