public Batch <double[]> PropagateForward(Batch <double[]> batch, bool isTraining) { if (isTraining) { var parallelOptions = new ParallelOptions(); var tuple = Tuple.Create <double[][], double[][]>(new double[batch.Size][], new double[batch.Size][]); parallelOptions.MaxDegreeOfParallelism = 2 * Environment.ProcessorCount; Parallel.ForEach <double[], List <Tuple <long, double[], double[]> > >(batch, parallelOptions, () => new List <Tuple <long, double[], double[]> >(), (vector1, state, index, local) => { Random random = random = RandomProvider.GetRandom();; double[] masks = new double[vector1.Length]; double[] vector2 = new double[vector1.Length]; for (int i = 0; i < vector1.Length; i++) { double probability = random.Binomial(1, this.rate); masks[i] = probability; vector2[i] = vector1[i] * probability; } local.Add(Tuple.Create <long, double[], double[]>(index, masks, vector2)); return(local); }, (local) => { lock (tuple) { local.ForEach(x => { tuple.Item1[x.Item1] = x.Item2; tuple.Item2[x.Item1] = x.Item3; }); } }); this.masks = tuple.Item1; return(new Batch <double[]>(tuple.Item2)); } return(batch); }