Beispiel #1
0
 private void FreeAllDescriptors()
 {
     lock (_lockobject) {
         if (m_descriptors != null)
         {
             foreach (IntPtr p in m_descriptors.Values)
             {
                 MKLImports.DftiFreeDescriptor(p);
             }
             m_descriptors.Clear();
         }
     }
 }
Beispiel #2
0
        /*!HC:TYPELIST:
         * <hycalper>
         * <type>
         * <source locate="after">
         *  HCretArr
         * </source>
         * </type>
         * <type>
         * <source locate="after">
         *  HCinArr
         * </source>
         * </type>
         * <type>
         * <source locate="after">
         *  mklPrec
         * </source>
         * </type>
         * </hycalper>
         */
        public ILArray </*!HC:HCretArr*/ double> FFTBackwSym(ILArray </*!HC:HCinArr*/ complex> A, int nDims)
        {
            if (A == null || nDims <= 0)
            {
                throw new ILArgumentException("invalid argument!");
            }
            if (A.IsEmpty)
            {
                return(ILArray </*!HC:HCretArr*/ double> .empty(A.Dimensions));
            }
            if (A.IsScalar || (A.Dimensions[0] == 1 && nDims == 1))
            {
                return(ILMath.real(A));
            }
            if (nDims > A.Dimensions.NumberOfDimensions)
            {
                nDims = A.Dimensions.NumberOfDimensions;
            }
            // MKL currently does not handle more than 3 dimensions this way
            if (nDims > 3)
            {
                return(ILMath.real(FFTBackward(A, nDims)));
            }
            // prepare output array, if we query the memory directly from
            // memory pool, we prevent from clearing the elements since every
            // single one will be overwritten by fft anyway
            /*!HC:HCretArr*/ double []        retArr = ILMemoryPool.Pool.New </*!HC:HCretArr*/ double>(A.Dimensions.NumberOfElements);
            ILArray </*!HC:HCretArr*/ double> ret    = new ILArray </*!HC:HCretArr*/ double>(retArr, A.Dimensions);
            IntPtr descriptor = IntPtr.Zero;
            int    error      = -1;

            int[]  tmpDims = A.Dimensions.ToIntArray(nDims + 1);
            string hash    = hashPlan(/*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, nDims, tmpDims);

            // try to reuse existing descriptor
            lock (_lockobject) {
                if (!m_descriptors.TryGetValue(hash, out descriptor))
                {
                    error = MKLImports.DftiCreateDescriptor(ref descriptor, /*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, nDims, tmpDims);
                    if (isMKLError(error))
                    {
                        throw new ILInvalidOperationException("error creating descriptor: " + MKLImports.DftiErrorMessage(error));
                    }
                    m_descriptors[hash] = descriptor;
                }
            }
            // how many transformations ?
            int tmp = A.Dimensions.SequentialIndexDistance(nDims);

            MKLImports.DftiSetValue(descriptor, MKLParameter.NUMBER_OF_TRANSFORMS, __arglist(A.Dimensions.NumberOfElements / tmp));
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_DISTANCE, __arglist(tmp));
            MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_DISTANCE, __arglist(tmp));

            error = MKLImports.DftiSetValue(descriptor, MKLParameter.PLACEMENT, __arglist(MKLValues.NOT_INPLACE));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.REAL_STORAGE, __arglist(MKLValues.REAL_REAL));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.CONJUGATE_EVEN_STORAGE, __arglist(MKLValues.COMPLEX_COMPLEX));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.BACKWARD_SCALE, __arglist(1.0 / tmp));
            // spacing between elements
            tmpDims[0] = 0;
            for (int i = 0; i < nDims; i++)
            {
                tmpDims[i + 1] = A.Dimensions.SequentialIndexDistance(i);
            }
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_STRIDES, __arglist(tmpDims));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_STRIDES, __arglist(tmpDims));
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            error = MKLImports.DftiCommitDescriptor(descriptor);
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            // do the transform(s)
            unsafe
            {
                fixed(/*!HC:HCretArr*/ double *retArrP = ret.m_data)
                fixed(/*!HC:HCinArr*/ complex * inArr = A.m_data)
                {
                    error = MKLImports.DftiComputeBackward(descriptor, __arglist(inArr, retArrP));
                }
            }
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            return(ret);
        }
Beispiel #3
0
        public ILArray <complex> FFTForward(ILArray <complex> A, int nDims)
        {
            if (A == null || nDims <= 0)
            {
                throw new ILArgumentException("invalid argument!");
            }
            if (A.IsEmpty)
            {
                return(ILArray <complex> .empty(A.Dimensions));
            }
            if (A.IsScalar || (A.Dimensions[0] == 1 && nDims == 1))
            {
                return(A.C);
            }
            if (nDims > A.Dimensions.NumberOfDimensions)
            {
                nDims = A.Dimensions.NumberOfDimensions;
            }

            // prepare output array
            ILArray <complex> ret        = A.C;
            IntPtr            descriptor = IntPtr.Zero;
            int error = -1;

            int[]  tmpDims = A.Dimensions.ToIntArray(nDims + 1);
            string hash    = hashPlan(MKLValues.DOUBLE, MKLValues.COMPLEX, nDims, tmpDims);

            lock (_lockobject) {
                // try to reuse existing descriptor
                if (!m_descriptors.TryGetValue(hash, out descriptor))
                {
                    error = MKLImports.DftiCreateDescriptor(ref descriptor, MKLValues.DOUBLE, MKLValues.COMPLEX, nDims, tmpDims);
                    if (isMKLError(error))
                    {
                        throw new ILInvalidOperationException("error creating descriptor: " + MKLImports.DftiErrorMessage(error));
                    }
                    m_descriptors[hash] = descriptor;
                }
            }
            // how many transformations ?
            int tmp = A.Dimensions.SequentialIndexDistance(nDims);

            MKLImports.DftiSetValue(descriptor, MKLParameter.NUMBER_OF_TRANSFORMS, __arglist(A.Dimensions.NumberOfElements / tmp));
            //error = MKLImports.DftiSetValue(descriptor,MKLParameter.PLACEMENT,MKLValues.NOT_INPLACE);
            //error = MKLImports.DftiSetValue(descriptor,MKLParameter.REAL_STORAGE, MKLValues.REAL_COMPLEX);
            // storage of subsequent transformations
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_DISTANCE, __arglist(tmp));
            MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_DISTANCE, __arglist(tmp));

            // spacing between elements
            tmpDims[0] = 0;
            for (int i = 0; i < nDims; i++)
            {
                tmpDims[i + 1] = A.Dimensions.SequentialIndexDistance(i);
            }
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_STRIDES, __arglist(tmpDims));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_STRIDES, __arglist(tmpDims));
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            error = MKLImports.DftiCommitDescriptor(descriptor);
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            // do the transform(s)
            unsafe
            {
                fixed(complex *retArr = ret.m_data)
                {
                    error = MKLImports.DftiComputeForward(descriptor, __arglist(retArr));
                }
            }
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            return(ret);
        }
Beispiel #4
0
/*!HC:TYPELIST:
 * <hycalper>
 *  <type>
 *      <source locate="after">
 *          HCretArr
 *      </source>
 *  </type>
 *  <type>
 *      <source locate="after">
 *          inArr
 *      </source>
 *  </type>
 *  <type>
 *      <source locate="after">
 *          mklPrec
 *      </source>
 *  </type>
 * </hycalper>
 */

        public ILArray </*!HC:HCretArr*/ double> FFTBackwSym1D(ILArray </*!HC:inArr*/ complex> A, int dim)
        {
            if (A == null || dim < 0)
            {
                throw new ILArgumentException("invalid parameter!");
            }
            if (A.IsEmpty)
            {
                return(ILArray </*!HC:HCretArr*/ double> .empty(A.Dimensions));
            }
            if (A.IsScalar || A.Dimensions[dim] == 1)
            {
                return(ILMath.real(A));
            }
            // prepare output array, if we query the memory directly from
            // memory pool, we prevent from clearing the elements since every
            // single one will be overwritten by fft anyway
            int error = 0, inDim = A.Dimensions[dim];

            /*!HC:HCretArr*/ double []        retArr = ILMemoryPool.Pool.New </*!HC:HCretArr*/ double>(A.Dimensions.NumberOfElements);
            ILArray </*!HC:HCretArr*/ double> ret    = new ILArray </*!HC:HCretArr*/ double>(retArr, A.Dimensions);
            string hash       = hashPlan(/*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, 1, inDim);
            IntPtr descriptor = IntPtr.Zero;

            // try to reuse existing descriptor
            lock (_lockobject) {
                if (!m_descriptors.TryGetValue(hash, out descriptor))
                {
                    error = MKLImports.DftiCreateDescriptor(ref descriptor, /*!HC:mklPrec*/ MKLValues.DOUBLE, MKLValues.REAL, 1, inDim);
                    if (isMKLError(error))
                    {
                        throw new ILInvalidOperationException("error creating descriptor: " + MKLImports.DftiErrorMessage(error));
                    }
                    m_descriptors[hash] = descriptor;
                }
            }
            // spacing between elements
            int tmp = A.Dimensions.SequentialIndexDistance(dim);

            int[] stride = new int[] { 0, tmp };
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_STRIDES, __arglist(stride));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_STRIDES, __arglist(stride));
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            // storage of subsequent transformations
            tmp = inDim * tmp;
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_DISTANCE, __arglist(tmp));
            MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_DISTANCE, __arglist(tmp));
            // how many transformations ?
            tmp = A.Dimensions.NumberOfElements / tmp;
            MKLImports.DftiSetValue(descriptor, MKLParameter.NUMBER_OF_TRANSFORMS, __arglist(tmp));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.PLACEMENT, __arglist(MKLValues.NOT_INPLACE));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.REAL_STORAGE, __arglist(MKLValues.REAL_REAL));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.CONJUGATE_EVEN_STORAGE, __arglist(MKLValues.COMPLEX_COMPLEX));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.BACKWARD_SCALE, __arglist(1.0 / inDim));
            error = MKLImports.DftiCommitDescriptor(descriptor);
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            // do the transform(s)
            tmp = A.Dimensions.SequentialIndexDistance(dim);
            unsafe
            {
                fixed(/*!HC:HCretArr*/ double *retArrP = ret.m_data)
                fixed(/*!HC:inArr*/ complex * pA = A.m_data)
                {
                    for (int i = 0; i < tmp && error == 0; i++)
                    {
                        error = MKLImports.DftiComputeBackward(descriptor, __arglist(pA + i, retArrP + i));
                    }
                }
            }
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            return(ret);
        }
Beispiel #5
0
        public ILArray <complex> FFTForward1D(ILArray <complex> A, int dim)
        {
            if (object.Equals(A, null) || dim < 0)
            {
                throw new ILArgumentException("invalid parameter!");
            }
            if (A.IsEmpty)
            {
                return(ILArray <complex> .empty(A.Dimensions));
            }
            if (dim >= A.Dimensions.NumberOfDimensions || A.Dimensions[dim] == 1)
            {
                return(A.C);
            }
            // prepare output array
            ILArray <complex> ret = A.C;
            string            hash = hashPlan(MKLValues.DOUBLE, MKLValues.COMPLEX, 1, A.Dimensions[dim]);
            IntPtr            descriptor = IntPtr.Zero;
            int error, inDim = A.Dimensions[dim];

            // try to reuse existing descriptor
            lock (_lockobject) {
                if (!m_descriptors.TryGetValue(hash, out descriptor))
                {
                    error = MKLImports.DftiCreateDescriptor(ref descriptor, MKLValues.DOUBLE, MKLValues.COMPLEX, 1, inDim);
                    if (isMKLError(error))
                    {
                        throw new ILInvalidOperationException("error creating descriptor: " + MKLImports.DftiErrorMessage(error));
                    }
                    m_descriptors[hash] = descriptor;
                }
            }
            // spacing between elements
            int tmp = A.Dimensions.SequentialIndexDistance(dim);

            int[] stride = new int[] { 0, tmp };
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_STRIDES, __arglist(stride));
            error = MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_STRIDES, __arglist(stride));
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            // storage of subsequent transformations
            tmp = inDim * tmp;
            MKLImports.DftiSetValue(descriptor, MKLParameter.INPUT_DISTANCE, __arglist(tmp));
            MKLImports.DftiSetValue(descriptor, MKLParameter.OUTPUT_DISTANCE, __arglist(tmp));
            // how many transformations ?
            tmp = A.Dimensions.NumberOfElements / tmp;
            MKLImports.DftiSetValue(descriptor, MKLParameter.NUMBER_OF_TRANSFORMS, __arglist(tmp));
            //error = MKLImports.DftiSetValue(descriptor,MKLParameter.PLACEMENT,MKLValues.NOT_INPLACE);

            error = MKLImports.DftiCommitDescriptor(descriptor);
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            // do the transform(s)
            unsafe {
                tmp = A.Dimensions.SequentialIndexDistance(dim);
                fixed(complex *retArr = ret.m_data)
                {
                    for (int i = 0; i < tmp && error == 0; i++)
                    {
                        error = MKLImports.DftiComputeForward(descriptor, __arglist(retArr + i));
                    }
                }
            }
            if (isMKLError(error))
            {
                throw new ILInvalidOperationException("error: " + MKLImports.DftiErrorMessage(error));
            }
            return(ret);
        }