Распараллеливание OpenBlas из OpenMP Thread

Я попытался вызвать функцию OpenBlas из потока OpenMP, в то время как распараллеливание Blas установлено на значение, не равное единице. Я использую OpenBlas 0.3.9, после загрузки исходников я его распаковал и назвал

make USE_OPENMP=1

make PREFIX=/someFolder/ install

Однако я всегда получаю следующее сообщение об ошибке из моего исполняемого файла

Предупреждение OpenBLAS: обнаружение цикла OpenMP, и это приложение может зависнуть. Пожалуйста, перестройте библиотеку с опцией USE_OPENMP=1.

Кто-нибудь знает, почему это так и как я могу это изменить? Вот минимальный пример моего кода:

#include <complex>
#include <vector>
#include <random>
#include <iostream>
#include <algorithm>
#include <omp.h>
#include <cblas.h>
#include <lapacke.h>

int main(int, char**) {
    int const blas_threads = 2,
              omp_threads = 2,
              matrix_size = 100;
    openblas_set_num_threads(blas_threads);
    omp_set_max_active_levels(2);

    double alpha = 1.,
           beta = 0.;

    std::vector<std::vector<double>> as(omp_threads,
                                        std::vector<double>(matrix_size*matrix_size));
    std::vector<std::vector<double>> bs(omp_threads,
                                        std::vector<double>(matrix_size*matrix_size));
    std::vector<std::vector<double>> cs(omp_threads,
                                        std::vector<double>(matrix_size*matrix_size));

    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<double> dis;
    for(int i = 0; i < omp_threads; ++i) {
        std::generate(as[i].begin(),
                      as[i].end(), 
                      [&dis,&gen]() { return dis(gen); });
        std::generate(bs[i].begin(),
                      bs[i].end(), 
                      [&dis,&gen]() { return dis(gen); });
    }

    // for(int i = 0; i < matrix_size*matrix_size; ++i) {
    //  std::cout << as[0][i] << " " << bs[0][i] << std::endl;
    // } 

#pragma omp parallel for num_threads(omp_threads), schedule(static, 1)
    for(int i = 0; i < omp_threads; ++i) {
        cblas_dgemm(CblasColMajor,
                    CblasNoTrans,
                    CblasNoTrans,
                    matrix_size,
                    matrix_size,
                    matrix_size,
                    alpha,
                    as[i].data(),
                    matrix_size,
                    bs[i].data(),
                    matrix_size,
                    beta,
                    cs[i].data(),
                    matrix_size);
    }

    // for(int i = 0; i < matrix_size*matrix_size; ++i) {
    //  std::cout << cs[0][i] << std::endl;
    // } 

    return 0;
}


person sam.11100    schedule 09.03.2020    source источник
comment
OpenBlas уже использует OpenMP в cblas_dgemm. Использование #pragma omp parallel в цикле, который вызывает функцию, уже использующую #pragma omp parallel, может привести к значительному замедлению работы и более общим возможным проблемам, подобным этой, из-за вложенного parallel for. См. здесь для получения дополнительной информации о проблемах, связанных с вложенным параллелизмом. в ОпенМП.   -  person Jérôme Richard    schedule 09.03.2020
comment
Несмотря на то, что я ценю ваше беспокойство по поводу качества моего кода, я задавал не этот вопрос. По-видимому, это можно сделать, поскольку для этого существует флаг.   -  person sam.11100    schedule 09.03.2020