Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Functions/builtin/SumMT.cs @ 9407

Last change on this file since 9407 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 34.1 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Collections.Generic;
42using System.Text;
43using System.Threading;
44using ILNumerics.Storage;
45using ILNumerics.Misc;
46using ILNumerics.Exceptions;
47 
48
49
50namespace ILNumerics  {
51    public partial class ILMath {
52
53        /// <summary>
54        /// Sum elements of A along specified dimension
55        /// </summary>
56        /// <param name="A">Input array</param>
57        /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
58        /// <returns>Array, same size as A, but having the 'dim's dimension
59        /// reduced to the length 1 with the sum of all
60        /// elements along that dimension.</returns>
61        public static  ILRetArray<double>  sum (ILInArray<double> A, int dim = -1) {
62            using (ILScope.Enter(A)) {
63                if (dim < 0)
64                    dim = A.Size.WorkingDimension();
65                if (dim >= A.Size.NumberOfDimensions)
66                    throw new ILArgumentException("dimension parameter out of range!");
67                if (A.IsEmpty)
68                    return  ILRetArray<double>.empty(A.Size);
69                if (A.IsScalar) {
70                   
71                    return new  ILRetArray<double>(new double[] { A.GetValue(0) }, 1, 1);
72                }
73               
74                if (A.S[dim] == 1) return A.C;
75
76                int[] newDims = A.S.ToIntArray();
77                newDims[dim] = 1;
78                ILSize retDimension = new ILSize(newDims);
79                 double[] retArr = ILMemoryPool.Pool.New< double>(retDimension.NumberOfElements);
80
81                int inc = A.Size.SequentialIndexDistance(dim);
82                int dimLen = A.Size[dim];
83                int maxRuns = retDimension.NumberOfElements;
84                int modHelp = A.Size.NumberOfElements - 1;
85                int modOut = retDimension.NumberOfElements - 1;
86                int incOut = retDimension.SequentialIndexDistance(dim);
87                int numelA = A.S.NumberOfElements;
88               
89                double[] aArray = A.GetArrayForRead();
90                if (maxRuns == 1) {
91                   
92                    double tmp = 0;
93                    for (int j = 0; j < dimLen; j++) {
94                        tmp += aArray[j];
95                    }
96                    retArr[0] = tmp;
97                } else {
98                    #region may run parallel
99                    int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
100                    if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
101                        && numelA / 2 >= Settings.s_minParallelElement1Count) {
102
103                        if (maxRuns >= Settings.s_maxNumberThreads
104                            && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
105                            workItemLength = maxRuns / workItemCount;
106                        } else {
107                            workItemLength = maxRuns / 2;
108                            workItemCount = 2;
109                        }
110                       
111                    } else {
112                        workItemLength = maxRuns;
113                        workItemCount = 1;
114                    }
115                    Action<object> action = (data) => {
116                        Tuple<int, int> range = (Tuple<int, int>)data;
117                        int from = range.Item1, to = range.Item2;
118                        for (int c = from; c < to; c++) {
119                            int pos = (int)(((long)dimLen * c * inc) % modHelp);
120                            long posOut = ((long)c * incOut);
121                            if (posOut > modOut)
122                                posOut = ((posOut - 1) % modOut) + 1;
123                           
124                            double tmp = 0;
125                            int end = pos + dimLen * inc;
126                            for (int j = pos; j < end; j += inc) {
127                                tmp += aArray[j];
128                            }
129                            retArr[posOut] = tmp;
130                        }
131                        System.Threading.Interlocked.Decrement(ref workerCount);
132                    };
133                    for (; i < workItemCount - 1; i++) {
134                        Interlocked.Increment(ref workerCount);
135
136                        ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
137                    }
138                    action(Tuple.Create(i * workItemLength, maxRuns));
139                    ILThreadPool.Wait4Workers(ref workerCount);
140                    #endregion
141                }
142                return new  ILRetArray<double>(retArr, newDims);
143            }
144        }
145
146#region HYCALPER AUTO GENERATED CODE
147
148        /// <summary>
149        /// Sum elements of A along specified dimension
150        /// </summary>
151        /// <param name="A">Input array</param>
152        /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
153        /// <returns>Array, same size as A, but having the 'dim's dimension
154        /// reduced to the length 1 with the sum of all
155        /// elements along that dimension.</returns>
156        public static  ILRetArray<Int64>  sum (ILInArray<Int64> A, int dim = -1) {
157            using (ILScope.Enter(A)) {
158                if (dim < 0)
159                    dim = A.Size.WorkingDimension();
160                if (dim >= A.Size.NumberOfDimensions)
161                    throw new ILArgumentException("dimension parameter out of range!");
162                if (A.IsEmpty)
163                    return  ILRetArray<Int64>.empty(A.Size);
164                if (A.IsScalar) {
165                   
166                    return new  ILRetArray<Int64>(new Int64[] { A.GetValue(0) }, 1, 1);
167                }
168               
169                if (A.S[dim] == 1) return A.C;
170
171                int[] newDims = A.S.ToIntArray();
172                newDims[dim] = 1;
173                ILSize retDimension = new ILSize(newDims);
174                Int64[] retArr = ILMemoryPool.Pool.New< Int64>(retDimension.NumberOfElements);
175
176                int inc = A.Size.SequentialIndexDistance(dim);
177                int dimLen = A.Size[dim];
178                int maxRuns = retDimension.NumberOfElements;
179                int modHelp = A.Size.NumberOfElements - 1;
180                int modOut = retDimension.NumberOfElements - 1;
181                int incOut = retDimension.SequentialIndexDistance(dim);
182                int numelA = A.S.NumberOfElements;
183               
184                Int64[] aArray = A.GetArrayForRead();
185                if (maxRuns == 1) {
186                   
187                    Int64 tmp = 0;
188                    for (int j = 0; j < dimLen; j++) {
189                        tmp += aArray[j];
190                    }
191                    retArr[0] = tmp;
192                } else {
193                    #region may run parallel
194                    int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
195                    if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
196                        && numelA / 2 >= Settings.s_minParallelElement1Count) {
197
198                        if (maxRuns >= Settings.s_maxNumberThreads
199                            && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
200                            workItemLength = maxRuns / workItemCount;
201                        } else {
202                            workItemLength = maxRuns / 2;
203                            workItemCount = 2;
204                        }
205                       
206                    } else {
207                        workItemLength = maxRuns;
208                        workItemCount = 1;
209                    }
210                    Action<object> action = (data) => {
211                        Tuple<int, int> range = (Tuple<int, int>)data;
212                        int from = range.Item1, to = range.Item2;
213                        for (int c = from; c < to; c++) {
214                            int pos = (int)(((long)dimLen * c * inc) % modHelp);
215                            long posOut = ((long)c * incOut);
216                            if (posOut > modOut)
217                                posOut = ((posOut - 1) % modOut) + 1;
218                           
219                            Int64 tmp = 0;
220                            int end = pos + dimLen * inc;
221                            for (int j = pos; j < end; j += inc) {
222                                tmp += aArray[j];
223                            }
224                            retArr[posOut] = tmp;
225                        }
226                        System.Threading.Interlocked.Decrement(ref workerCount);
227                    };
228                    for (; i < workItemCount - 1; i++) {
229                        Interlocked.Increment(ref workerCount);
230
231                        ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
232                    }
233                    action(Tuple.Create(i * workItemLength, maxRuns));
234                    ILThreadPool.Wait4Workers(ref workerCount);
235                    #endregion
236                }
237                return new  ILRetArray<Int64>(retArr, newDims);
238            }
239        }
240        /// <summary>
241        /// Sum elements of A along specified dimension
242        /// </summary>
243        /// <param name="A">Input array</param>
244        /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
245        /// <returns>Array, same size as A, but having the 'dim's dimension
246        /// reduced to the length 1 with the sum of all
247        /// elements along that dimension.</returns>
248        public static  ILRetArray<Int32>  sum (ILInArray<Int32> A, int dim = -1) {
249            using (ILScope.Enter(A)) {
250                if (dim < 0)
251                    dim = A.Size.WorkingDimension();
252                if (dim >= A.Size.NumberOfDimensions)
253                    throw new ILArgumentException("dimension parameter out of range!");
254                if (A.IsEmpty)
255                    return  ILRetArray<Int32>.empty(A.Size);
256                if (A.IsScalar) {
257                   
258                    return new  ILRetArray<Int32>(new Int32[] { A.GetValue(0) }, 1, 1);
259                }
260               
261                if (A.S[dim] == 1) return A.C;
262
263                int[] newDims = A.S.ToIntArray();
264                newDims[dim] = 1;
265                ILSize retDimension = new ILSize(newDims);
266                Int32[] retArr = ILMemoryPool.Pool.New< Int32>(retDimension.NumberOfElements);
267
268                int inc = A.Size.SequentialIndexDistance(dim);
269                int dimLen = A.Size[dim];
270                int maxRuns = retDimension.NumberOfElements;
271                int modHelp = A.Size.NumberOfElements - 1;
272                int modOut = retDimension.NumberOfElements - 1;
273                int incOut = retDimension.SequentialIndexDistance(dim);
274                int numelA = A.S.NumberOfElements;
275               
276                Int32[] aArray = A.GetArrayForRead();
277                if (maxRuns == 1) {
278                   
279                    Int32 tmp = 0;
280                    for (int j = 0; j < dimLen; j++) {
281                        tmp += aArray[j];
282                    }
283                    retArr[0] = tmp;
284                } else {
285                    #region may run parallel
286                    int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
287                    if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
288                        && numelA / 2 >= Settings.s_minParallelElement1Count) {
289
290                        if (maxRuns >= Settings.s_maxNumberThreads
291                            && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
292                            workItemLength = maxRuns / workItemCount;
293                        } else {
294                            workItemLength = maxRuns / 2;
295                            workItemCount = 2;
296                        }
297                       
298                    } else {
299                        workItemLength = maxRuns;
300                        workItemCount = 1;
301                    }
302                    Action<object> action = (data) => {
303                        Tuple<int, int> range = (Tuple<int, int>)data;
304                        int from = range.Item1, to = range.Item2;
305                        for (int c = from; c < to; c++) {
306                            int pos = (int)(((long)dimLen * c * inc) % modHelp);
307                            long posOut = ((long)c * incOut);
308                            if (posOut > modOut)
309                                posOut = ((posOut - 1) % modOut) + 1;
310                           
311                            Int32 tmp = 0;
312                            int end = pos + dimLen * inc;
313                            for (int j = pos; j < end; j += inc) {
314                                tmp += aArray[j];
315                            }
316                            retArr[posOut] = tmp;
317                        }
318                        System.Threading.Interlocked.Decrement(ref workerCount);
319                    };
320                    for (; i < workItemCount - 1; i++) {
321                        Interlocked.Increment(ref workerCount);
322
323                        ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
324                    }
325                    action(Tuple.Create(i * workItemLength, maxRuns));
326                    ILThreadPool.Wait4Workers(ref workerCount);
327                    #endregion
328                }
329                return new  ILRetArray<Int32>(retArr, newDims);
330            }
331        }
332        /// <summary>
333        /// Sum elements of A along specified dimension
334        /// </summary>
335        /// <param name="A">Input array</param>
336        /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
337        /// <returns>Array, same size as A, but having the 'dim's dimension
338        /// reduced to the length 1 with the sum of all
339        /// elements along that dimension.</returns>
340        public static  ILRetArray<byte>  sum (ILInArray<byte> A, int dim = -1) {
341            using (ILScope.Enter(A)) {
342                if (dim < 0)
343                    dim = A.Size.WorkingDimension();
344                if (dim >= A.Size.NumberOfDimensions)
345                    throw new ILArgumentException("dimension parameter out of range!");
346                if (A.IsEmpty)
347                    return  ILRetArray<byte>.empty(A.Size);
348                if (A.IsScalar) {
349                   
350                    return new  ILRetArray<byte>(new byte[] { A.GetValue(0) }, 1, 1);
351                }
352               
353                if (A.S[dim] == 1) return A.C;
354
355                int[] newDims = A.S.ToIntArray();
356                newDims[dim] = 1;
357                ILSize retDimension = new ILSize(newDims);
358                byte[] retArr = ILMemoryPool.Pool.New< byte>(retDimension.NumberOfElements);
359
360                int inc = A.Size.SequentialIndexDistance(dim);
361                int dimLen = A.Size[dim];
362                int maxRuns = retDimension.NumberOfElements;
363                int modHelp = A.Size.NumberOfElements - 1;
364                int modOut = retDimension.NumberOfElements - 1;
365                int incOut = retDimension.SequentialIndexDistance(dim);
366                int numelA = A.S.NumberOfElements;
367               
368                byte[] aArray = A.GetArrayForRead();
369                if (maxRuns == 1) {
370                   
371                    byte tmp = 0;
372                    for (int j = 0; j < dimLen; j++) {
373                        tmp += aArray[j];
374                    }
375                    retArr[0] = tmp;
376                } else {
377                    #region may run parallel
378                    int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
379                    if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
380                        && numelA / 2 >= Settings.s_minParallelElement1Count) {
381
382                        if (maxRuns >= Settings.s_maxNumberThreads
383                            && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
384                            workItemLength = maxRuns / workItemCount;
385                        } else {
386                            workItemLength = maxRuns / 2;
387                            workItemCount = 2;
388                        }
389                       
390                    } else {
391                        workItemLength = maxRuns;
392                        workItemCount = 1;
393                    }
394                    Action<object> action = (data) => {
395                        Tuple<int, int> range = (Tuple<int, int>)data;
396                        int from = range.Item1, to = range.Item2;
397                        for (int c = from; c < to; c++) {
398                            int pos = (int)(((long)dimLen * c * inc) % modHelp);
399                            long posOut = ((long)c * incOut);
400                            if (posOut > modOut)
401                                posOut = ((posOut - 1) % modOut) + 1;
402                           
403                            byte tmp = 0;
404                            int end = pos + dimLen * inc;
405                            for (int j = pos; j < end; j += inc) {
406                                tmp += aArray[j];
407                            }
408                            retArr[posOut] = tmp;
409                        }
410                        System.Threading.Interlocked.Decrement(ref workerCount);
411                    };
412                    for (; i < workItemCount - 1; i++) {
413                        Interlocked.Increment(ref workerCount);
414
415                        ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
416                    }
417                    action(Tuple.Create(i * workItemLength, maxRuns));
418                    ILThreadPool.Wait4Workers(ref workerCount);
419                    #endregion
420                }
421                return new  ILRetArray<byte>(retArr, newDims);
422            }
423        }
424        /// <summary>
425        /// Sum elements of A along specified dimension
426        /// </summary>
427        /// <param name="A">Input array</param>
428        /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
429        /// <returns>Array, same size as A, but having the 'dim's dimension
430        /// reduced to the length 1 with the sum of all
431        /// elements along that dimension.</returns>
432        public static  ILRetArray<fcomplex>  sum (ILInArray<fcomplex> A, int dim = -1) {
433            using (ILScope.Enter(A)) {
434                if (dim < 0)
435                    dim = A.Size.WorkingDimension();
436                if (dim >= A.Size.NumberOfDimensions)
437                    throw new ILArgumentException("dimension parameter out of range!");
438                if (A.IsEmpty)
439                    return  ILRetArray<fcomplex>.empty(A.Size);
440                if (A.IsScalar) {
441                   
442                    return new  ILRetArray<fcomplex>(new fcomplex[] { A.GetValue(0) }, 1, 1);
443                }
444               
445                if (A.S[dim] == 1) return A.C;
446
447                int[] newDims = A.S.ToIntArray();
448                newDims[dim] = 1;
449                ILSize retDimension = new ILSize(newDims);
450                fcomplex[] retArr = ILMemoryPool.Pool.New< fcomplex>(retDimension.NumberOfElements);
451
452                int inc = A.Size.SequentialIndexDistance(dim);
453                int dimLen = A.Size[dim];
454                int maxRuns = retDimension.NumberOfElements;
455                int modHelp = A.Size.NumberOfElements - 1;
456                int modOut = retDimension.NumberOfElements - 1;
457                int incOut = retDimension.SequentialIndexDistance(dim);
458                int numelA = A.S.NumberOfElements;
459               
460                fcomplex[] aArray = A.GetArrayForRead();
461                if (maxRuns == 1) {
462                   
463                    fcomplex tmp = 0;
464                    for (int j = 0; j < dimLen; j++) {
465                        tmp += aArray[j];
466                    }
467                    retArr[0] = tmp;
468                } else {
469                    #region may run parallel
470                    int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
471                    if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
472                        && numelA / 2 >= Settings.s_minParallelElement1Count) {
473
474                        if (maxRuns >= Settings.s_maxNumberThreads
475                            && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
476                            workItemLength = maxRuns / workItemCount;
477                        } else {
478                            workItemLength = maxRuns / 2;
479                            workItemCount = 2;
480                        }
481                       
482                    } else {
483                        workItemLength = maxRuns;
484                        workItemCount = 1;
485                    }
486                    Action<object> action = (data) => {
487                        Tuple<int, int> range = (Tuple<int, int>)data;
488                        int from = range.Item1, to = range.Item2;
489                        for (int c = from; c < to; c++) {
490                            int pos = (int)(((long)dimLen * c * inc) % modHelp);
491                            long posOut = ((long)c * incOut);
492                            if (posOut > modOut)
493                                posOut = ((posOut - 1) % modOut) + 1;
494                           
495                            fcomplex tmp = 0;
496                            int end = pos + dimLen * inc;
497                            for (int j = pos; j < end; j += inc) {
498                                tmp += aArray[j];
499                            }
500                            retArr[posOut] = tmp;
501                        }
502                        System.Threading.Interlocked.Decrement(ref workerCount);
503                    };
504                    for (; i < workItemCount - 1; i++) {
505                        Interlocked.Increment(ref workerCount);
506
507                        ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
508                    }
509                    action(Tuple.Create(i * workItemLength, maxRuns));
510                    ILThreadPool.Wait4Workers(ref workerCount);
511                    #endregion
512                }
513                return new  ILRetArray<fcomplex>(retArr, newDims);
514            }
515        }
516        /// <summary>
517        /// Sum elements of A along specified dimension
518        /// </summary>
519        /// <param name="A">Input array</param>
520        /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
521        /// <returns>Array, same size as A, but having the 'dim's dimension
522        /// reduced to the length 1 with the sum of all
523        /// elements along that dimension.</returns>
524        public static  ILRetArray<float>  sum (ILInArray<float> A, int dim = -1) {
525            using (ILScope.Enter(A)) {
526                if (dim < 0)
527                    dim = A.Size.WorkingDimension();
528                if (dim >= A.Size.NumberOfDimensions)
529                    throw new ILArgumentException("dimension parameter out of range!");
530                if (A.IsEmpty)
531                    return  ILRetArray<float>.empty(A.Size);
532                if (A.IsScalar) {
533                   
534                    return new  ILRetArray<float>(new float[] { A.GetValue(0) }, 1, 1);
535                }
536               
537                if (A.S[dim] == 1) return A.C;
538
539                int[] newDims = A.S.ToIntArray();
540                newDims[dim] = 1;
541                ILSize retDimension = new ILSize(newDims);
542                float[] retArr = ILMemoryPool.Pool.New< float>(retDimension.NumberOfElements);
543
544                int inc = A.Size.SequentialIndexDistance(dim);
545                int dimLen = A.Size[dim];
546                int maxRuns = retDimension.NumberOfElements;
547                int modHelp = A.Size.NumberOfElements - 1;
548                int modOut = retDimension.NumberOfElements - 1;
549                int incOut = retDimension.SequentialIndexDistance(dim);
550                int numelA = A.S.NumberOfElements;
551               
552                float[] aArray = A.GetArrayForRead();
553                if (maxRuns == 1) {
554                   
555                    float tmp = 0;
556                    for (int j = 0; j < dimLen; j++) {
557                        tmp += aArray[j];
558                    }
559                    retArr[0] = tmp;
560                } else {
561                    #region may run parallel
562                    int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
563                    if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
564                        && numelA / 2 >= Settings.s_minParallelElement1Count) {
565
566                        if (maxRuns >= Settings.s_maxNumberThreads
567                            && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
568                            workItemLength = maxRuns / workItemCount;
569                        } else {
570                            workItemLength = maxRuns / 2;
571                            workItemCount = 2;
572                        }
573                       
574                    } else {
575                        workItemLength = maxRuns;
576                        workItemCount = 1;
577                    }
578                    Action<object> action = (data) => {
579                        Tuple<int, int> range = (Tuple<int, int>)data;
580                        int from = range.Item1, to = range.Item2;
581                        for (int c = from; c < to; c++) {
582                            int pos = (int)(((long)dimLen * c * inc) % modHelp);
583                            long posOut = ((long)c * incOut);
584                            if (posOut > modOut)
585                                posOut = ((posOut - 1) % modOut) + 1;
586                           
587                            float tmp = 0;
588                            int end = pos + dimLen * inc;
589                            for (int j = pos; j < end; j += inc) {
590                                tmp += aArray[j];
591                            }
592                            retArr[posOut] = tmp;
593                        }
594                        System.Threading.Interlocked.Decrement(ref workerCount);
595                    };
596                    for (; i < workItemCount - 1; i++) {
597                        Interlocked.Increment(ref workerCount);
598
599                        ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
600                    }
601                    action(Tuple.Create(i * workItemLength, maxRuns));
602                    ILThreadPool.Wait4Workers(ref workerCount);
603                    #endregion
604                }
605                return new  ILRetArray<float>(retArr, newDims);
606            }
607        }
608        /// <summary>
609        /// Sum elements of A along specified dimension
610        /// </summary>
611        /// <param name="A">Input array</param>
612        /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
613        /// <returns>Array, same size as A, but having the 'dim's dimension
614        /// reduced to the length 1 with the sum of all
615        /// elements along that dimension.</returns>
616        public static  ILRetArray<complex>  sum (ILInArray<complex> A, int dim = -1) {
617            using (ILScope.Enter(A)) {
618                if (dim < 0)
619                    dim = A.Size.WorkingDimension();
620                if (dim >= A.Size.NumberOfDimensions)
621                    throw new ILArgumentException("dimension parameter out of range!");
622                if (A.IsEmpty)
623                    return  ILRetArray<complex>.empty(A.Size);
624                if (A.IsScalar) {
625                   
626                    return new  ILRetArray<complex>(new complex[] { A.GetValue(0) }, 1, 1);
627                }
628               
629                if (A.S[dim] == 1) return A.C;
630
631                int[] newDims = A.S.ToIntArray();
632                newDims[dim] = 1;
633                ILSize retDimension = new ILSize(newDims);
634                complex[] retArr = ILMemoryPool.Pool.New< complex>(retDimension.NumberOfElements);
635
636                int inc = A.Size.SequentialIndexDistance(dim);
637                int dimLen = A.Size[dim];
638                int maxRuns = retDimension.NumberOfElements;
639                int modHelp = A.Size.NumberOfElements - 1;
640                int modOut = retDimension.NumberOfElements - 1;
641                int incOut = retDimension.SequentialIndexDistance(dim);
642                int numelA = A.S.NumberOfElements;
643               
644                complex[] aArray = A.GetArrayForRead();
645                if (maxRuns == 1) {
646                   
647                    complex tmp = 0;
648                    for (int j = 0; j < dimLen; j++) {
649                        tmp += aArray[j];
650                    }
651                    retArr[0] = tmp;
652                } else {
653                    #region may run parallel
654                    int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
655                    if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
656                        && numelA / 2 >= Settings.s_minParallelElement1Count) {
657
658                        if (maxRuns >= Settings.s_maxNumberThreads
659                            && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
660                            workItemLength = maxRuns / workItemCount;
661                        } else {
662                            workItemLength = maxRuns / 2;
663                            workItemCount = 2;
664                        }
665                       
666                    } else {
667                        workItemLength = maxRuns;
668                        workItemCount = 1;
669                    }
670                    Action<object> action = (data) => {
671                        Tuple<int, int> range = (Tuple<int, int>)data;
672                        int from = range.Item1, to = range.Item2;
673                        for (int c = from; c < to; c++) {
674                            int pos = (int)(((long)dimLen * c * inc) % modHelp);
675                            long posOut = ((long)c * incOut);
676                            if (posOut > modOut)
677                                posOut = ((posOut - 1) % modOut) + 1;
678                           
679                            complex tmp = 0;
680                            int end = pos + dimLen * inc;
681                            for (int j = pos; j < end; j += inc) {
682                                tmp += aArray[j];
683                            }
684                            retArr[posOut] = tmp;
685                        }
686                        System.Threading.Interlocked.Decrement(ref workerCount);
687                    };
688                    for (; i < workItemCount - 1; i++) {
689                        Interlocked.Increment(ref workerCount);
690
691                        ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
692                    }
693                    action(Tuple.Create(i * workItemLength, maxRuns));
694                    ILThreadPool.Wait4Workers(ref workerCount);
695                    #endregion
696                }
697                return new  ILRetArray<complex>(retArr, newDims);
698            }
699        }
700
701#endregion HYCALPER AUTO GENERATED CODE
702   }
703}
Note: See TracBrowser for help on using the repository browser.