Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrency bugs in PruneIncremental #52

Closed
Decatf opened this issue Oct 5, 2013 · 1 comment
Closed

Concurrency bugs in PruneIncremental #52

Decatf opened this issue Oct 5, 2013 · 1 comment
Milestone

Comments

@Decatf
Copy link

Decatf commented Oct 5, 2013

The PruneIncremental class runs into errors when running with multiple threads. The _hiddenCounts and _pattern are shared across threads.

The hidden counts are modified by each thread in IncreaseHiddenCounts when a RequestNextTask call occurs. The same _pattern object is used by all threads to generate a network. So multiple threads trying to generate a network at the same time can lead to unintended hidden layers being created.

I think these objects could use a lock around the critical sections.

        /// <summary>
        /// Generate a network according to the current hidden layer counts.
        /// </summary>
        ///
        /// <returns>The network based on current hidden layer counts.</returns>
        private BasicNetwork GenerateNetwork()
        {
            BasicNetwork network = null;
            lock (_pattern)
            {
                _pattern.Clear();

                lock (this._hiddenCounts.SyncRoot)
                {
                    foreach (int element in _hiddenCounts)
                    {
                        if (element > 0)
                        {
                            _pattern.AddHiddenLayer(element);
                        }
                    }
                }
                network = (BasicNetwork)_pattern.Generate();
            }
            return network;
        }


        /// <summary>
        /// Increase the hidden layer counts according to the hidden layer
        /// parameters. Increase the first hidden layer count by one, if it is maxed
        /// out, then set it to zero and increase the next hidden layer.
        /// </summary>
        ///
        /// <returns>False if no more increases can be done, true otherwise.</returns>
        private bool IncreaseHiddenCounts()
        {
            lock (_hiddenCounts.SyncRoot)
            {
                int i = 0;
                do
                {
                    HiddenLayerParams param = _hidden[i];
                    _hiddenCounts[i]++;

                    // is this hidden layer still within the range?
                    if (_hiddenCounts[i] <= param.Max)
                    {
                        return true;
                    }

                    // increase the next layer if we've maxed out this one
                    _hiddenCounts[i] = param.Min;
                    i++;
                } while (i < _hiddenCounts.Length);
            }
            // can't increase anymore, we're done!

            return false;
        }
@jeffheaton
Copy link
Owner

Thank you, very good catch. Just checked in a fix.

@jeffheaton jeffheaton added this to the Encog v3.2 milestone Mar 26, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants