У меня возникают проблемы с пониманием того, как справиться с segfault heisenbug в моей программе OMP

У меня возникли проблемы в стороннем проекте, который я делаю для персональной структуры нейронной сети. Проблема, с которой я сталкиваюсь, — это ошибка Seisfault Heisenbug, которая возникает в параллельном разделе кода для пользовательского алгоритма Монте-Карло, который я пишу.

Потоки не должны каким-либо образом взаимодействовать для этого раздела кода, пока они не достигнут критической секции, которую я определил, но кое-каким образом, области памяти для локальных переменных в вызове функции переопределяются другим потоком или самим вызовом функции переопределяет позицию памяти, выделенную предыдущим потоком.

Я считаю, что проблема этого человека такая же, как и у меня, но мне не хватает понимания, как использовать его просветление для исправления моего кода, поскольку он не уточнил, как он исправил свою проблему.
OpenMP вызывает Seisfault Heisenbug

Вот параллельный раздел кода, который я написал с «протестированным» критическим дополнением в закомментированном виде, так как это не помогло с ошибкой. Раздел, где происходит ошибка

#include "Network.h"#include <vector>
#include <cmath>
#include <thread>
#include <omp.h>
#include <stdint.h>
#include <iostream>
using namespace std;
using namespace AeroSW;
int main(){
// Generate X amount of blueprints
vector<vector<double> > inputs;
vector<vector<double> > outputs;
double sf = 1100000;
double lr = 0.1;
uint32_t duration = 3;
for(uint32_t i = 0; i < 1000; i++){
vector<double>* in = new vector<double>(3);
vector<double>* out = new vector<double>(1); // These can be different sizes, but for simplicity for example
(*in)[0] = i;
(*in)[1] = i+1;
(*in)[2] = i+2;
(*out)[0] = i * 1000;
inputs.push_back(*in);
outputs.push_back(*out);
}
vector<vector<int> > bps;
int n_i = 3;
int n_o = 1;
for(uint32_t i = 0; i <= 3; i++){
int num_bps_for_this_layer = pow(7, i);
int* val_array = new int[i];
for(uint32_t j = 0; j < i; j++){
val_array[j] = 7;
}
for(uint32_t j = 0; j < (unsigned)num_bps_for_this_layer; j++){
vector<int>* vec_i = new vector<int>(2+i);
(*vec_i)[0] = n_i;
(*vec_i)[i+1] = n_o;
for(uint32_t k = 0; k < i; k++){
(*vec_i)[k+1] = val_array[k];
}
bps.push_back(*vec_i);
if(i > 0){
uint32_t t_i = i-1; // Temp i
val_array[t_i]--;
bool b_flag = false; // break flag
while(val_array[t_i] == 0){
val_array[t_i] = 7;
if(t_i == 0){
b_flag = true;
break;
}
t_i--;
val_array[t_i]--;
}
if(b_flag) break;
}
}
}
//cout << "Hello World\n";
uint32_t num_bins = 10;
uint32_t num_threads = std::thread::hardware_concurrency(); // Find # of cores
if(num_threads == 0) // Assume 1 core for systems w/out multiple cores
num_threads = 1;
if(num_bins < num_threads){
num_threads = num_bins;
}
uint32_t bp_slice = bps.size() / num_threads;
#pragma omp parallel num_threads(num_threads) firstprivate(num_bins, n_i, n_o, lr)
{
uint32_t my_id = omp_get_thread_num();
uint32_t my_si = my_id * bp_slice; // my starting index
uint32_t my_ei; // my ending index, exclusive
if(my_id == num_threads -1) my_ei = bps.size();
else my_ei = my_si + bp_slice;
std::vector<Network*> my_nets;
for(uint32_t i = my_si; i < my_ei; i++){
uint32_t nl = bps[i].size();
uint32_t* bp = new uint32_t[nl];
for(uint32_t j = 0; j < nl; j++){
bp[j] = bps[i][j];
}
Network* t_net = new Network(lr, bp, nl);
my_nets.push_back(t_net);
}
for(uint32_t i = 0; i < my_nets.size(); i++){
for(uint32_t j = 0; j < num_bins; j++){
my_nets[i]->train(inputs, outputs, sf, inputs.size(), duration);
}
}
}
}

Если кто-то видит что-то, чего я не вижу, или знает, что я могу сделать, чтобы решить эту проблему, пожалуйста, дайте мне знать!

Вот пример выходных данных отладчика Valgrind с активным инструментом Helgrind, который также описывает проблему, в которую я верю.

==26386==
==26386== Possible data race during read of size 8 at 0x6213348 by thread #1
==26386== Locks held: none
==26386==    at 0x40CB26: AeroSW::Node::get_weight(unsigned int) (Node.cpp:84)
==26386==    by 0x40E688: AeroSW::Network::train_tim(std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >, double, unsigned int, unsigned long) (Network.cpp:227)
==26386==    by 0x4058F1: monte_carlo(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, double, double, double, std::vector<double*, std::allocator<double*> >&) [clone ._omp_fn.0] (Validation.cpp:196)
==26386==    by 0x5462E5E: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==26386==    by 0x404B86: monte_carlo(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, double, double, double, std::vector<double*, std::allocator<double*> >&) (Validation.cpp:136)
==26386==    by 0x402467: main (NeuralNetworkArchitectureDriver.cpp:85)
==26386==  Address 0x6213348 is 24 bytes inside a block of size 32 in arena "client"==26386==

-ОБНОВИТЬ-
Это проблема кучи коррупции. Мне пришлось изменить тонну кода, но я получил его с помощью shared_ptrs и векторов. Потоки переопределяли области памяти, к которым у них не должно было быть доступа, что приводило к сбою других потоков, поскольку информация, к которой они пытались получить доступ, была изменена.

0

Решение

Я пишу пост, потому что я определил свою проблему с помощью профессора местного университета. Проблема, которая у меня возникла, оказалась проблемой повреждения кучи из-за объема памяти, используемого в программе. Это заставило потоки обходить собственное выделение памяти и начать использовать пространство памяти другого потока в куче для хранения информации, которую они не могли поместить в свою собственную кучу.

Я смог справиться с этим, изменив все указатели объекта на shared_ptrs что предотвращало переопределение областей памяти, пока все ссылки на объекты не были должным образом удалены. Я также изменил все указатели массивов или указатели, используемые в качестве массивов, на векторы. После этого моя проблема растворилась в воздухе и перестала случайно падать.

И спасибо Зулан за рекомендацию!

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]