Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Native/FFT/ILACMLFFT.cs @ 9102

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

#1967: ILNumerics source for experimentation

File size: 27.5 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
40#pragma warning disable 1591
41
42using System;
43using System.Collections.Generic;
44using System.Text;
45using System.Security;
46using System.Runtime.InteropServices;
47using ILNumerics.Exceptions;
48using ILNumerics.Misc;
49
50namespace ILNumerics.Native {
51   
52    /// <summary>
53    /// Wrapper for FFT interface using ACML ver. 3.6
54    /// </summary>
55    public unsafe class ILACMLFFT : IILFFT, IDisposable {
56
57        #region pinvoke definitions
58       
59        [DllImport("libacml_dll"),SuppressUnmanagedCodeSecurity]
60    private static extern void zfft1mx(int MODE, double SCALE, int INPL, int NSEQ, int N, IntPtr X, int INCX1, int INCX2, IntPtr Y, int INCY1, int INCY2, IntPtr COMM, ref int INFO);
61        [DllImport("libacml_dll"),SuppressUnmanagedCodeSecurity]
62    private static extern void cfft1mx(int MODE, float SCALE, int INPL, int NSEQ, int N,  IntPtr X, int INCX1, int INCX2, IntPtr Y, int INCY1, int INCY2, IntPtr COMM, ref int INFO);
63        [DllImport("libacml_dll"),SuppressUnmanagedCodeSecurity]
64    private static extern void zfft2dx(int MODE, double SCALE, int LTRANS, int INPL, int M, int N, IntPtr X, int INCX1, int INCX2, IntPtr Y, int INCY1, int INCY2, IntPtr COMM, ref int INFO);
65        [DllImport("libacml_dll"),SuppressUnmanagedCodeSecurity]
66    private static extern void cfft2dx(int MODE, float SCALE,  int LTRANS, int INPL, int M, int N, IntPtr X, int INCX1, int INCX2, IntPtr Y, int INCY1, int INCY2, IntPtr COMM, ref int INFO);
67
68        #endregion
69
70        #region value constants
71        private class ACMLValues {
72            public static readonly int Double = 8;
73            public static readonly int Single = 4;
74            public static readonly int Real = 1;
75            public static readonly int Complex = 2;
76            public static readonly int Backwards = 1;
77            public static readonly int Forward = -1;
78        }
79        #endregion
80
81        #region attributes
82        Dictionary<string,IntPtr> m_descriptors;
83        object _lockobject = new object();
84        #endregion
85
86        #region constructor
87        public ILACMLFFT () {
88            m_descriptors = new Dictionary<string,IntPtr>(10);
89        }
90        #endregion
91
92        #region IILFFT Member - 1-D
93       
94
95
96        public ILRetArray< complex>  FFTForward1D(ILInArray< double> A, int dim) {
97            using (ILScope.Enter(A)) {
98                if (object.Equals(A, null) || dim < 0)
99                    throw new ILArgumentException("FFTForward1D: invalid parameter!");
100                if (A.IsEmpty) return ILMath.array< complex>(A.Size);
101                if (A.IsScalar || A.Size[dim] == 1)
102                    return  ILMath.tocomplex(A);
103                // prepare output array
104                ILArray< complex> ret =  ILMath.tocomplex(A);
105                fft1dInplace(dim, ret, ACMLValues.Forward);
106                return ret;
107            }
108        }
109
110#region HYCALPER AUTO GENERATED CODE
111
112
113        public ILRetArray< fcomplex>  FFTBackward1D(ILInArray< fcomplex> A, int dim) {
114            using (ILScope.Enter(A)) {
115                if (object.Equals(A, null) || dim < 0)
116                    throw new ILArgumentException("FFTForward1D: invalid parameter!");
117                if (A.IsEmpty) return ILMath.array< fcomplex>(A.Size);
118                if (A.IsScalar || A.Size[dim] == 1)
119                    return  A.C;
120                // prepare output array
121                ILArray< fcomplex> ret =  A.C;
122                fft1dInplace(dim, ret, ACMLValues.Backwards);
123                return ret;
124            }
125        }
126
127        public ILRetArray< complex>  FFTBackward1D(ILInArray< complex> A, int dim) {
128            using (ILScope.Enter(A)) {
129                if (object.Equals(A, null) || dim < 0)
130                    throw new ILArgumentException("FFTForward1D: invalid parameter!");
131                if (A.IsEmpty) return ILMath.array< complex>(A.Size);
132                if (A.IsScalar || A.Size[dim] == 1)
133                    return  A.C;
134                // prepare output array
135                ILArray< complex> ret =  A.C;
136                fft1dInplace(dim, ret, ACMLValues.Backwards);
137                return ret;
138            }
139        }
140
141        public ILRetArray< fcomplex>  FFTForward1D(ILInArray< fcomplex> A, int dim) {
142            using (ILScope.Enter(A)) {
143                if (object.Equals(A, null) || dim < 0)
144                    throw new ILArgumentException("FFTForward1D: invalid parameter!");
145                if (A.IsEmpty) return ILMath.array< fcomplex>(A.Size);
146                if (A.IsScalar || A.Size[dim] == 1)
147                    return  A.C;
148                // prepare output array
149                ILArray< fcomplex> ret =  A.C;
150                fft1dInplace(dim, ret, ACMLValues.Forward);
151                return ret;
152            }
153        }
154
155        public ILRetArray< fcomplex>  FFTForward1D(ILInArray< float> A, int dim) {
156            using (ILScope.Enter(A)) {
157                if (object.Equals(A, null) || dim < 0)
158                    throw new ILArgumentException("FFTForward1D: invalid parameter!");
159                if (A.IsEmpty) return ILMath.array< fcomplex>(A.Size);
160                if (A.IsScalar || A.Size[dim] == 1)
161                    return  ILMath.tofcomplex(A);
162                // prepare output array
163                ILArray< fcomplex> ret =  ILMath.tofcomplex(A);
164                fft1dInplace(dim, ret, ACMLValues.Forward);
165                return ret;
166            }
167        }
168
169        public ILRetArray< complex>  FFTForward1D(ILInArray< complex> A, int dim) {
170            using (ILScope.Enter(A)) {
171                if (object.Equals(A, null) || dim < 0)
172                    throw new ILArgumentException("FFTForward1D: invalid parameter!");
173                if (A.IsEmpty) return ILMath.array< complex>(A.Size);
174                if (A.IsScalar || A.Size[dim] == 1)
175                    return  A.C;
176                // prepare output array
177                ILArray< complex> ret =  A.C;
178                fft1dInplace(dim, ret, ACMLValues.Forward);
179                return ret;
180            }
181        }
182
183#endregion HYCALPER AUTO GENERATED CODE
184
185        public ILRetArray<double> FFTBackwSym1D(ILInArray<complex> A, int dim) {
186            return ILMath.real(FFTBackward1D(A,dim));   
187        }
188
189        public ILRetArray<float> FFTBackwSym1D(ILInArray<fcomplex> A, int dim) {
190            return ILMath.real(FFTBackward1D(A,dim));   
191        }
192
193        #endregion
194
195        #region IILFFT Member n-D
196
197
198
199        public ILRetArray< complex>  FFTForward(ILInArray< double> A, int nDims) {
200            using (ILScope.Enter(A)) {
201                if (object.Equals(A, null) || nDims <= 0)
202                    throw new ILArgumentException("invalid parameter!");
203                if (A.IsEmpty) return ILMath.array< complex>(A.Size);
204                if (A.IsScalar || (A.Size[0] == 1 && nDims == 1))
205                    return  ILMath.tocomplex(A);
206                if (nDims > A.Size.NumberOfDimensions)
207                    return  FFTForward(A, A.Size.NumberOfDimensions);
208
209                // prepare output array + transform each dimension inplace
210                ILArray< complex> ret =  ILMath.tocomplex(A);
211                switch (nDims) {
212                    case 2:
213                        fft2dInplace(ret, ACMLValues.Forward);
214                        break;
215                    default:
216                        for (int i = 0; i < nDims; i++) {
217                            fft1dInplace(i, ret, ACMLValues.Forward);
218                        }
219                        break;
220                }
221                return ret;
222            }
223        }
224
225#region HYCALPER AUTO GENERATED CODE
226
227
228        public ILRetArray< fcomplex>  FFTBackward(ILInArray< fcomplex> A, int nDims) {
229            using (ILScope.Enter(A)) {
230                if (object.Equals(A, null) || nDims <= 0)
231                    throw new ILArgumentException("invalid parameter!");
232                if (A.IsEmpty) return ILMath.array< fcomplex>(A.Size);
233                if (A.IsScalar || (A.Size[0] == 1 && nDims == 1))
234                    return  A.C;
235                if (nDims > A.Size.NumberOfDimensions)
236                    return  FFTBackward(A, A.Size.NumberOfDimensions);
237
238                // prepare output array + transform each dimension inplace
239                ILArray< fcomplex> ret =  A.C;
240                switch (nDims) {
241                    case 2:
242                        fft2dInplace(ret, ACMLValues.Backwards);
243                        break;
244                    default:
245                        for (int i = 0; i < nDims; i++) {
246                            fft1dInplace(i, ret, ACMLValues.Backwards);
247                        }
248                        break;
249                }
250                return ret;
251            }
252        }
253
254        public ILRetArray< complex>  FFTBackward(ILInArray< complex> A, int nDims) {
255            using (ILScope.Enter(A)) {
256                if (object.Equals(A, null) || nDims <= 0)
257                    throw new ILArgumentException("invalid parameter!");
258                if (A.IsEmpty) return ILMath.array< complex>(A.Size);
259                if (A.IsScalar || (A.Size[0] == 1 && nDims == 1))
260                    return  A.C;
261                if (nDims > A.Size.NumberOfDimensions)
262                    return  FFTBackward(A, A.Size.NumberOfDimensions);
263
264                // prepare output array + transform each dimension inplace
265                ILArray< complex> ret =  A.C;
266                switch (nDims) {
267                    case 2:
268                        fft2dInplace(ret, ACMLValues.Backwards);
269                        break;
270                    default:
271                        for (int i = 0; i < nDims; i++) {
272                            fft1dInplace(i, ret, ACMLValues.Backwards);
273                        }
274                        break;
275                }
276                return ret;
277            }
278        }
279
280        public ILRetArray< fcomplex>  FFTForward(ILInArray< fcomplex> A, int nDims) {
281            using (ILScope.Enter(A)) {
282                if (object.Equals(A, null) || nDims <= 0)
283                    throw new ILArgumentException("invalid parameter!");
284                if (A.IsEmpty) return ILMath.array< fcomplex>(A.Size);
285                if (A.IsScalar || (A.Size[0] == 1 && nDims == 1))
286                    return  A.C;
287                if (nDims > A.Size.NumberOfDimensions)
288                    return  FFTForward(A, A.Size.NumberOfDimensions);
289
290                // prepare output array + transform each dimension inplace
291                ILArray< fcomplex> ret =  A.C;
292                switch (nDims) {
293                    case 2:
294                        fft2dInplace(ret, ACMLValues.Forward);
295                        break;
296                    default:
297                        for (int i = 0; i < nDims; i++) {
298                            fft1dInplace(i, ret, ACMLValues.Forward);
299                        }
300                        break;
301                }
302                return ret;
303            }
304        }
305
306        public ILRetArray< fcomplex>  FFTForward(ILInArray< float> A, int nDims) {
307            using (ILScope.Enter(A)) {
308                if (object.Equals(A, null) || nDims <= 0)
309                    throw new ILArgumentException("invalid parameter!");
310                if (A.IsEmpty) return ILMath.array< fcomplex>(A.Size);
311                if (A.IsScalar || (A.Size[0] == 1 && nDims == 1))
312                    return  ILMath.tofcomplex(A);
313                if (nDims > A.Size.NumberOfDimensions)
314                    return  FFTForward(A, A.Size.NumberOfDimensions);
315
316                // prepare output array + transform each dimension inplace
317                ILArray< fcomplex> ret =  ILMath.tofcomplex(A);
318                switch (nDims) {
319                    case 2:
320                        fft2dInplace(ret, ACMLValues.Forward);
321                        break;
322                    default:
323                        for (int i = 0; i < nDims; i++) {
324                            fft1dInplace(i, ret, ACMLValues.Forward);
325                        }
326                        break;
327                }
328                return ret;
329            }
330        }
331
332        public ILRetArray< complex>  FFTForward(ILInArray< complex> A, int nDims) {
333            using (ILScope.Enter(A)) {
334                if (object.Equals(A, null) || nDims <= 0)
335                    throw new ILArgumentException("invalid parameter!");
336                if (A.IsEmpty) return ILMath.array< complex>(A.Size);
337                if (A.IsScalar || (A.Size[0] == 1 && nDims == 1))
338                    return  A.C;
339                if (nDims > A.Size.NumberOfDimensions)
340                    return  FFTForward(A, A.Size.NumberOfDimensions);
341
342                // prepare output array + transform each dimension inplace
343                ILArray< complex> ret =  A.C;
344                switch (nDims) {
345                    case 2:
346                        fft2dInplace(ret, ACMLValues.Forward);
347                        break;
348                    default:
349                        for (int i = 0; i < nDims; i++) {
350                            fft1dInplace(i, ret, ACMLValues.Forward);
351                        }
352                        break;
353                }
354                return ret;
355            }
356        }
357
358#endregion HYCALPER AUTO GENERATED CODE
359
360        public ILRetArray<float> FFTBackwSym(ILInArray<fcomplex> A, int nDims) {
361            return ILMath.real(FFTBackward(A,nDims));
362        }
363
364        public ILRetArray<double> FFTBackwSym(ILInArray<complex> A, int nDims) {
365            return ILMath.real(FFTBackward(A,nDims));
366        }
367
368        public bool CachePlans {
369            get { return true; }
370        }
371
372        public void FreePlans() {
373            FreeAllDescriptors();
374        }
375
376        public bool SpeedyHermitian {
377            get { return false; }
378        }
379
380        #endregion
381
382        #region private helper
383
384        private void fft1dInplace(int dim, ILInArray<complex> ret, int mode) {
385            using (ILScope.Enter(ret)) {
386                int N = ret.Size[dim], info = 0;
387                // spacing between elements
388                int incx1 = ret.Size.SequentialIndexDistance(dim);
389                // storage of subsequent transformations
390                int incx2 = incx1 * N;
391                // number of transformations
392                int nseq = ret.Size.NumberOfElements / incx2;
393                double scale = (mode == ACMLValues.Backwards) ? 1.0 / N : 1.0;
394                string hash = hashPlan(ACMLValues.Double, ACMLValues.Complex, N, "zfft1mx");
395                IntPtr descriptor;
396                lock (_lockobject) {
397                    if (!m_descriptors.TryGetValue(hash, out descriptor)) {
398                        int commLength = (3 * N + 100) * ACMLValues.Double * 2;
399                        try {
400                            descriptor = Marshal.AllocCoTaskMem(commLength);
401                            zfft1mx(0, scale, 1, nseq, N, IntPtr.Zero, incx1, incx2, IntPtr.Zero, 0, 0, descriptor, ref info);
402                            if (info != 0)
403                                throw new ILInvalidOperationException("error creating fft-plan");
404                            m_descriptors[hash] = descriptor;
405                        } catch (OutOfMemoryException exc) {
406                            if (m_descriptors.Count > 0) {
407                                FreeAllDescriptors();
408                                descriptor = Marshal.AllocCoTaskMem(commLength);
409                                zfft1mx(0, scale, 1, nseq, N, IntPtr.Zero, incx1, incx2, IntPtr.Zero, 0, 0, descriptor, ref info);
410                                if (info != 0)
411                                    throw new ILInvalidOperationException("error creating fft-plan");
412                                m_descriptors[hash] = descriptor;
413                            }
414                            throw exc;
415                        }
416                    }
417                    // do the transform(s)
418                    fixed (complex* start = ret.GetArrayForWrite()) {
419                        for (int i = 0; i < incx1 && info == 0; i++)
420                            zfft1mx(mode, scale, 1, nseq, N, (IntPtr)(start + i), incx1, incx2, IntPtr.Zero, 0, 0, descriptor, ref info);
421                    }
422                }
423                if (info != 0) {
424                    throw new ILInvalidOperationException(String.Format("error: {0}th parameter was invalid", -info));
425                }
426            }
427        }
428        private void fft2dInplace(ILInArray<complex> ret, int mode) {
429            using (ILScope.Enter(ret)) {
430                System.Diagnostics.Debug.Assert(ret.Size.NumberOfDimensions >= 2);
431                int N = ret.Size[1], M = ret.Size[0], info = 0;
432                int MN = M * N;
433                // number of transformations
434                int nseq = ret.Size.NumberOfElements / (MN);
435                double scale = (mode == ACMLValues.Backwards) ? 1.0 / MN : 1.0;
436                string hash = hashPlan(ACMLValues.Double, ACMLValues.Complex, M, N, "zfft2dx");
437                IntPtr descriptor;
438                lock (_lockobject) {
439                    if (!m_descriptors.TryGetValue(hash, out descriptor)) {
440                        int commLength = (3 * (N + M) + MN + 200) * ACMLValues.Double * 2;
441                        try {
442                            descriptor = Marshal.AllocCoTaskMem(commLength);
443                            zfft2dx(0, scale, 1, 1, M, N, IntPtr.Zero, 1, M, IntPtr.Zero, 0, 0, descriptor, ref info);
444                            if (info != 0)
445                                throw new ILInvalidOperationException("error creating fft-plan");
446                            m_descriptors[hash] = descriptor;
447                        } catch (OutOfMemoryException exc) {
448                            if (m_descriptors.Count > 0) {
449                                FreeAllDescriptors();
450                                descriptor = Marshal.AllocCoTaskMem(commLength);
451                                zfft2dx(0, scale, 1, 1, M, N, IntPtr.Zero, 1, M, IntPtr.Zero, 0, 0, descriptor, ref info);
452                                if (info != 0)
453                                    throw new ILInvalidOperationException("error creating fft-plan");
454                                m_descriptors[hash] = descriptor;
455                            }
456                            throw exc;
457                        }
458                    }
459                    // do the transform(s)
460                    fixed (complex* start = ret.GetArrayForWrite()) {
461                        for (int i = 0; i < nseq && info == 0; i++)
462                            zfft2dx(mode, scale, 1, 1, M, N, (IntPtr)(start + i * MN), 1, M, IntPtr.Zero, 0, 0, descriptor, ref info);
463                    }
464                }
465                if (info != 0) {
466                    throw new ILInvalidOperationException(String.Format("error: {0}th parameter was invalid", -info));
467                }
468            }
469        }
470
471        private void fft1dInplace(int dim, ILInArray<fcomplex> ret, int mode) {
472            using (ILScope.Enter(ret)) {
473                int N = ret.Size[dim], info = 0;
474                // spacing between elements
475                int incx1 = ret.Size.SequentialIndexDistance(dim);
476                // storage of subsequent transformations
477                int incx2 = incx1 * N;
478                // number of transformations
479                int nseq = ret.Size.NumberOfElements / incx2;
480                float scale = (mode == ACMLValues.Backwards) ? 1.0f / N : 1.0f;
481                string hash = hashPlan(ACMLValues.Single, ACMLValues.Complex, N, "cfft1mx");
482                IntPtr descriptor;
483                lock (_lockobject) {
484                    if (!m_descriptors.TryGetValue(hash, out descriptor)) {
485                        int commLength = (3 * N + 100) * ACMLValues.Single * 2;
486                        try {
487                            descriptor = Marshal.AllocCoTaskMem(commLength);
488                            cfft1mx(0, 1.0f, 1, 1, N, IntPtr.Zero, 1, 1, IntPtr.Zero, 0, 0, descriptor, ref info);
489                            if (info != 0)
490                                throw new ILInvalidOperationException("error creating fft-plan");
491                            m_descriptors[hash] = descriptor;
492                        } catch (OutOfMemoryException exc) {
493                            if (m_descriptors.Count > 0) {
494                                FreeAllDescriptors();
495                                descriptor = Marshal.AllocCoTaskMem(commLength);
496                                cfft1mx(0, 1.0f, 1, 1, N, IntPtr.Zero, 1, 1, IntPtr.Zero, 0, 0, descriptor, ref info);
497                                if (info != 0)
498                                    throw new ILInvalidOperationException("error creating fft-plan");
499                                m_descriptors[hash] = descriptor;
500                            }
501                            throw exc;
502                        }
503                    }
504                    // do the transform(s)
505                    fixed (fcomplex* start = ret.GetArrayForWrite()) {
506                        for (int i = 0; i < incx1 && info == 0; i++)
507                            cfft1mx(mode, scale, 1, nseq, N, (IntPtr)(start + i), incx1, incx2, IntPtr.Zero, 0, 0, descriptor, ref info);
508                    }
509                }
510                if (info != 0) {
511                    throw new ILInvalidOperationException(String.Format("error: {0}th parameter was invalid", -info));
512                }
513            }
514        }
515        private void fft2dInplace(ILInArray<fcomplex> ret, int mode) {
516            using (ILScope.Enter(ret)) {
517                System.Diagnostics.Debug.Assert(ret.Size.NumberOfDimensions >= 2);
518                int N = ret.Size[1], M = ret.Size[0], info = 0;
519                int MN = M * N;
520                // number of transformations
521                int nseq = ret.Size.NumberOfElements / (MN);
522                float scale = (mode == ACMLValues.Backwards) ? 1.0f / MN : 1.0f;
523                string hash = hashPlan(ACMLValues.Single, ACMLValues.Complex, M, N, "cfft2dx");
524                IntPtr descriptor;
525                lock (_lockobject) {
526                    if (!m_descriptors.TryGetValue(hash, out descriptor)) {
527                        int commLength = (3 * (N + M) + MN + 200) * ACMLValues.Single * 2;
528                        try {
529                            descriptor = Marshal.AllocCoTaskMem(commLength);
530                            cfft2dx(0, scale, 1, 1, M, N, IntPtr.Zero, 1, M, IntPtr.Zero, 0, 0, descriptor, ref info);
531                            if (info != 0)
532                                throw new ILInvalidOperationException("error creating fft-plan");
533                            m_descriptors[hash] = descriptor;
534                        } catch (OutOfMemoryException exc) {
535                            if (m_descriptors.Count > 0) {
536                                FreeAllDescriptors();
537                                descriptor = Marshal.AllocCoTaskMem(commLength);
538                                cfft2dx(0, scale, 1, 1, M, N, IntPtr.Zero, 1, M, IntPtr.Zero, 0, 0, descriptor, ref info);
539                                if (info != 0)
540                                    throw new ILInvalidOperationException("error creating fft-plan");
541                                m_descriptors[hash] = descriptor;
542                            }
543                            throw exc;
544                        }
545                    }
546                    // do the transform(s)
547                    fixed (fcomplex* start = ret.GetArrayForWrite()) {
548                        for (int i = 0; i < nseq && info == 0; i++)
549                            cfft2dx(mode, scale, 1, 1, M, N, (IntPtr)(start + i * MN), 1, M, IntPtr.Zero, 0, 0, descriptor, ref info);
550                    }
551                }
552                if (info != 0) {
553                    throw new ILInvalidOperationException(String.Format("error: {0}th parameter was invalid", -info));
554                }
555            }
556        }
557
558        private static string hashPlan(int precision, int realcomplex, int N, string funcname) {
559            return hashPlan(precision,realcomplex,0,N,funcname);
560        }
561        private static string hashPlan(int precision, int realcomplex, int M, int N, string funcname) {
562            return String.Format("{0}|{1}|{2}|{3}|{4}",precision, realcomplex,M,N,funcname);
563        }
564        private void FreeAllDescriptors() {
565            lock (_lockobject) {
566                if (m_descriptors != null) {
567                    foreach (IntPtr p in m_descriptors.Values) {
568                        if (p != IntPtr.Zero)
569                            Marshal.FreeCoTaskMem(p);
570                    }
571                    m_descriptors.Clear();
572                }
573            }
574        }   
575       
576        #endregion
577
578        #region IDisposable Member
579
580        public void Dispose() {
581            Dispose(true);
582            /* we cannot supress finalize,since the class will only wipe all
583             * cached cotask memory. Supsequent calls will again allocate those.
584             * Therefore the finalizer must check at the end again.
585             */
586            // GC.SuppressFinalize(this);
587        }
588
589        public virtual void Dispose (bool manual) {
590            if (m_descriptors != null && m_descriptors.Count > 0) {
591                if (manual) {
592                    FreeAllDescriptors();             
593                }
594            }
595        }
596
597        ~ILACMLFFT () {
598            Dispose(true);     
599        }
600        #endregion
601
602    }
603}
Note: See TracBrowser for help on using the repository browser.