1 / 1 / 0
Регистрация: 06.02.2019
Сообщений: 158
1

Баг с мультипоточным программированием

01.05.2019, 16:08. Показов 1526. Ответов 0

Всем привет! Помогите, пожалуйста, с отловом бага, связанным с распараллеливанием программы. Пишу нейронную сеть LSTM на C++. Столкнулся с багом, не могу понять причину его появления. Весь код, пока что, не вижу смысла выкладывать - он очень громоздкий и объемный. Если понадобится - выложу. Суть бага в следующем:

Есть два 2-мерных массива (а точнее массива указателей на указатели). weights и deltaWeights одинаковой размерности. Для тех, кто не разбирается в нейронных сетях - это просто массивы, заполненные ненулевыми числами двоичной точности (double).

Есть следующий код:

Файл TrainLayer.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void TrainLayer::AcceptWeights(double learningSpeed)
{
    static unsigned int numCores = thread::hardware_concurrency();
    list<thread> ts;
 
    for (unsigned int t = 0; t < numCores; t++)
        ts.push_back(thread([&]() {
        MultiThreadAcceptWeights(t, numCores, learningSpeed);
    }));
 
    for (auto &el : ts)
        el.join();
}
 
void TrainLayer::MultiThreadAcceptWeights(unsigned int start, unsigned int step, double learningSpeed)
{
    static mutex consoleOutput;
    double minCS = 0, maxCS = 0;
 
    unsigned int i = start;
    for (; i <= numInputs; i += step)
    {
        for (unsigned int j = 0; j < numNeurons; j++)
        {
            Clip(deltaWeights[i][j], -CLIPRANGE, CLIPRANGE);
 
            if ((learningSpeed * deltaWeights[i][j]) < minCS)
                minCS = (learningSpeed * deltaWeights[i][j]);
            else if ((learningSpeed * deltaWeights[i][j]) > maxCS)
                maxCS = (learningSpeed * deltaWeights[i][j]);
 
 
            weights[i][j] += learningSpeed * deltaWeights[i][j];
            deltaWeights[i][j] = 0;
        }
    }
 
    consoleOutput.lock();
    cout << minCS << "   " << maxCS << endl;
    if (!minCS && !maxCS)
    {
        cout << "BUG!" << endl;
    }
    consoleOutput.unlock();
}
Clip(deltaWeights[i][j], -CLIPRANGE, CLIPRANGE); просто ограничивает минимальное и максимальное значение параметра deltaWeights[i][j].

Функция TrainLayer::AcceptWeights(double learningSpeed) вызывается так:
Файл TrainLSTMCell.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void TrainLSTMCell::AcceptWeights(double learningSpeed)
{
    thread forgetAcceptWeights([&]() {
        forgetGate.AcceptWeights(learningSpeed);
    });
 
    thread inputAcceptWeights([&]() {
        inputGate.AcceptWeights(learningSpeed);
    });
 
    thread hypothesisAcceptWeights([&]() {
        hypothesisGate.AcceptWeights(learningSpeed);
    });
 
    outputGate.AcceptWeights(learningSpeed);
 
    forgetAcceptWeights.join();
    inputAcceptWeights.join();
    hypothesisAcceptWeights.join();
}
Здесь forgetGate, inputGate, hypothesisGate, outputGate - это 4 экземпляра объекта типа TrainLayer.

Функция TrainLSTMCell::AcceptWeights(double learningSpeed) вызывается так:
Файл TrainLSTMNeuralNet.cpp

C++
1
2
3
4
5
void TrainLSTMNeuralNet::AcceptWeights(double learningSpeed)
{
    for (auto &cell : cells)
        cell.AcceptWeights(learningSpeed);
}
cells - это вектор объектов TrainLSTMCell.

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

0 0
BUG!


Это значит, что программа после выполнения строчки
C++
1
deltaWeights[i][j] = 0;
каким-то образом еще раз попадает на нее же. Если эту строку закомментировать, сообщение не появляется. Если функцию TrainLayer::MultiThreadAcceptWeights(unsigned int start, unsigned int step, double learningSpeed) вызывать в однопотоке, бага не происходит. Если из функции TrainLSTMCell::AcceptWeights(double learningSpeed) убрать потоки и все вызывать по очереди - то же самое.

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

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.05.2019, 16:08
Ответы с готовыми решениями:

Баг в программе. Без цикла работает нормально. С циклом выдает баг
Здравствуйте. Пишу программу. И как не пытался ее переписать, как дохожу до момента включения в код...

std::regex : баг на сайте или баг компилятора?
http://en.cppreference.com/w/cpp/regex/regex_match этот код выкидывает throw... Добавлено через...

Баг asio? или баг TCP стека?
всем привет. повстречался с очень странным багом. и не могу определить кто бажит, asio, или...

Letter-spacing баг или не баг?
Здравствуйте! Использовал letter-spacing для увеличения расстояния между буквами. Как оказалось...

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.05.2019, 16:08

Забавный баг Делфи ...или не баг?
кароч кидаем на форму 2 editа и кнопку и пишем такой код unit Unit1; interface uses ...

Проблема с программированием С#
Добрый день уважаемые форумчане У меня мак и я запретил использовать терминал в С# и теперь мне...

Линейно программированием
Здравствуйте, кто может помочь с заданием del. Нужно решить с помощью линейного программирования,...

Проблемы с программированием
помогите сделать не получается return (&quot;В массиве&quot; K ) не выводит К

Не разберусь с программированием
Пишу программу, но при выполнении пишет &quot;задайте Х&quot; кто может, помогите плисс составлением, завтра...

Вопросы связанные с программированием
Здравствуй я хотел бы задать пару вопросов 1.как в DELPHI при нажатии Shift+alt или Shift+ctrl...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.