/// <summary> /// Gets the absolute of the specified value. /// </summary> /// <param name="x">The value.</param> /// <returns>Absolute.</returns> public static double Abs(ComplexD x) { double a = x.x; double b = x.y; double v, w, t; a = Math.Abs(a); b = Math.Abs(b); if (a > b) { v = a; w = b; } else { v = b; w = a; } t = w / v; t = 1.0f + t * t; t = v * Math.Sqrt(t); if ((v == 0.0) || (v > 1.79769313486231570e+308) || (w > 1.79769313486231570e+308)) { t = v + w; } return(t); }
/// <summary> /// Multiplies value x and y. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value two.</param> /// <returns>New value.</returns> public static ComplexD Multiply(ComplexD x, ComplexD y) { ComplexD c = new ComplexD(); c.x = x.x * y.x - x.y * y.y; c.y = x.x * y.y + x.y * y.x; return(c); }
/// <summary> /// Divides value x by y. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value two.</param> /// <returns>New value.</returns> public static ComplexD Divide(ComplexD x, ComplexD y) { double s = Math.Abs(y.x) + Math.Abs(y.y); double oos = 1.0f / s; double ars = x.x * oos; double ais = x.y * oos; double brs = y.x * oos; double bis = y.y * oos; s = (brs * brs) + (bis * bis); oos = 1.0f / s; ComplexD quot = new ComplexD(((ars * brs) + (ais * bis)) * oos, ((ais * brs) - (ars * bis)) * oos); return(quot); }
private static extern CUBLASStatusv2 cublasZrot_v2(cublasHandle handle, int n, IntPtr x, int incx, IntPtr y, int incy, ref double c, ref ComplexD s);
private static extern CUBLASStatusv2 cublasZaxpy_v2(cublasHandle handle, int n, ref ComplexD alpha, IntPtr x, int incx, IntPtr y, int incy);
/// <summary> /// Subtracts value y from value x. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value to be subtracted.</param> /// <returns>New value.</returns> public static ComplexD Subtract(ComplexD x, ComplexD y) { x.x = x.x - y.x; x.y = x.y - y.y; return x; }
/// <summary> /// Conjugates the specified value. /// </summary> /// <param name="x">The value.</param> /// <returns>Conjugated value.</returns> public static ComplexD Conj(ComplexD x) { return new ComplexD(x.x, -1 * x.y); }
/// <summary> /// Divides value x by y. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value two.</param> /// <returns>New value.</returns> public static ComplexD Divide(ComplexD x, ComplexD y) { double s = Math.Abs(y.x) + Math.Abs(y.y); double oos = 1.0f / s; double ars = x.x * oos; double ais = x.y * oos; double brs = y.x * oos; double bis = y.y * oos; s = (brs * brs) + (bis * bis); oos = 1.0f / s; ComplexD quot = new ComplexD(((ars * brs) + (ais * bis)) * oos, ((ais * brs) - (ars * bis)) * oos); return quot; }
/// <summary> /// SCALs the specified alpha. /// </summary> /// <param name="alpha">The alpha.</param> /// <param name="vectorx">The vectorx.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> public void SCAL(ComplexD alpha, ComplexD[] vectorx, int n = 0, int rowx = 0, int incx = 1) { SCAL(new []{ alpha }, vectorx, n, rowx, incx); }
public static void complexAbs(GThread thread, ComplexD[,] a, ComplexD[,] c) { int x = thread.blockIdx.x; int y = 0; double j = 1.0; double k = 2.0; ComplexD cf = new ComplexD(3 + j, 7 + k); while (y < YSIZE) { c[x, y].x = ComplexD.Abs(a[x, y]); c[x, y].y = cf.y;// 0.0F; y++; } }
public static void complexDiv(GThread thread, ComplexD[,] a, ComplexD[,] b, ComplexD[,] c) { int x = thread.blockIdx.x; int y = 0; while (y < YSIZE) { c[x, y] = ComplexD.Divide(a[x, y], b[x, y]); y++; } }
private static bool Verify(ComplexD x, ComplexD y, float delta) { if (Math.Abs(x.x - y.x) > delta || Math.Abs(x.y - y.y) > delta) return false; return true; }
/// <summary> /// Subtracts value y from value x. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value to be subtracted.</param> /// <returns>New value.</returns> public static ComplexD Subtract(ComplexD x, ComplexD y) { x.x = x.x - y.x; x.y = x.y - y.y; return(x); }
/// <summary> /// Adds value y to value x. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value to be added.</param> /// <returns>New value.</returns> public static ComplexD Add(ComplexD x, ComplexD y) { x.x = x.x + y.x; x.y = x.y + y.y; return(x); }
/// <summary> /// Conjugates the specified value. /// </summary> /// <param name="x">The value.</param> /// <returns>Conjugated value.</returns> public static ComplexD Conj(ComplexD x) { return(new ComplexD(x.x, -1 * x.y)); }
public CUBLASStatusv2 cublasZaxpy(cublasHandle handle, int n, ref ComplexD alpha, IntPtr x, int incx, IntPtr y, int incy) { return cublasZaxpy_v2(handle, n, ref alpha, x, incx, y, incy); }
public CUBLASStatusv2 cublasZrot(cublasHandle handle, int n, IntPtr x, int incx, IntPtr y, int incy, ref double c, ref ComplexD s) { return cublasZrot_v2(handle, n, x, incx, y, incy, ref c, ref s); }
public static void Execute() { CudafyModule km = CudafyTranslator.Cudafy(); GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target); gpu.LoadModule(km); // 2D Console.WriteLine("kernel"); ComplexD[,] host_A = new ComplexD[XSIZE, YSIZE]; ComplexD[,] host_B = new ComplexD[XSIZE, YSIZE]; ComplexD[,] host_C = new ComplexD[XSIZE, YSIZE]; int i = 0; for (int x = 0; x < XSIZE; x++) for (int y = 0; y < YSIZE; y++) { host_A[x, y] = new ComplexD(i, i); host_B[x, y] = new ComplexD(2, 0); i++; } ComplexD[,] dev_A = gpu.CopyToDevice(host_A); ComplexD[,] dev_B = gpu.CopyToDevice(host_B); ComplexD[,] dev_C = gpu.Allocate<ComplexD>(XSIZE, YSIZE); Console.WriteLine("complexAdd"); gpu.Launch(XSIZE, 1, "complexAdd", dev_A, dev_B, dev_C); gpu.CopyFromDevice(dev_C, host_C); i = 0; bool pass = true; for (int x = 0; x < XSIZE; x++) { for (int y = 0; y < YSIZE && pass; y++) { ComplexD expected = ComplexD.Add(host_A[x, y], host_B[x, y]); pass = host_C[x, y].x == expected.x && host_C[x, y].y == expected.y; } } Console.WriteLine(pass ? "Pass" : "Fail"); Console.WriteLine("complexSub"); gpu.Launch(XSIZE, 1, "complexSub", dev_A, dev_B, dev_C); gpu.CopyFromDevice(dev_C, host_C); i = 0; pass = true; for (int x = 0; x < XSIZE; x++) { for (int y = 0; y < YSIZE && pass; y++) { ComplexD expected = ComplexD.Subtract(host_A[x, y], host_B[x, y]); pass = host_C[x, y].x == expected.x && host_C[x, y].y == expected.y; } } Console.WriteLine(pass ? "Pass" : "Fail"); Console.WriteLine("complexMpy"); gpu.Launch(XSIZE, 1, "complexMpy", dev_A, dev_B, dev_C); gpu.CopyFromDevice(dev_C, host_C); i = 0; pass = true; for (int x = 0; x < XSIZE; x++) { for (int y = 0; y < YSIZE && pass; y++) { ComplexD expected = ComplexD.Multiply(host_A[x, y], host_B[x, y]); //Console.WriteLine("{0} {1} : {2} {3}", host_C[x, y].R, host_C[x, y].I, expected.R, expected.I); pass = Verify(host_C[x, y], expected, 1e-14F); i++; } } Console.WriteLine(pass ? "Pass" : "Fail"); Console.WriteLine("complexDiv"); gpu.Launch(XSIZE, 1, "complexDiv", dev_A, dev_B, dev_C); gpu.CopyFromDevice(dev_C, host_C); i = 0; pass = true; for (int x = 0; x < XSIZE; x++) { for (int y = 0; y < YSIZE && pass; y++) { ComplexD expected = ComplexD.Divide(host_A[x, y], host_B[x, y]); //Console.WriteLine("{0} {1} : {2} {3}", host_C[x, y].R, host_C[x, y].I, expected.R, expected.I); if (i > 0) pass = Verify(host_C[x, y], expected, 1e-13F); i++; } } Console.WriteLine(pass ? "Pass" : "Fail"); Console.WriteLine("complexAbs"); gpu.Launch(XSIZE, 1, "complexAbs", dev_A, dev_C); gpu.CopyFromDevice(dev_C, host_C); i = 0; pass = true; for (int x = 0; x < XSIZE; x++) { for (int y = 0; y < YSIZE && pass; y++) { double expected = ComplexD.Abs(host_A[x, y]); pass = Verify(host_C[x, y].x, expected, 1e-2F); //Console.WriteLine("{0} {1} : {2}", host_C[x, y].x, host_C[x, y].y, expected); i++; } } Console.WriteLine(pass ? "Pass" : "Fail"); gpu.FreeAll(); }
/// <summary> /// ROTGs the specified a. /// </summary> /// <param name="a">A.</param> /// <param name="b">The b.</param> /// <param name="c">The c.</param> /// <param name="s">The s.</param> public abstract void ROTG(ComplexD[] a, ComplexD[] b, double[] c, ComplexD[] s);
/// <summary> /// SCALs the specified alpha. /// </summary> /// <param name="alpha">The alpha.</param> /// <param name="vectorx">The vectorx.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> public abstract void SCAL(double[] alpha, ComplexD[] vectorx, int n = 0, int rowx = 0, int incx = 1);
public void SetUp() { _gpu = CudafyHost.CreateDevice(CudafyModes.Target); _hostInput = new double[N * BATCH]; _hostInputCplx = new ComplexD[N * BATCH]; _hostOutput = new double[N * BATCH]; _hostOutputCplx = new ComplexD[N * BATCH]; _devInput = _gpu.Allocate(_hostInput); _devInputCplx = _gpu.Allocate(_hostInputCplx); _devInter = _gpu.Allocate<double>(N * 2 * BATCH); _devInterCplx = _gpu.Allocate<ComplexD>(N * BATCH); _devOutput = _gpu.Allocate(_hostOutput); _devOutputCplx = _gpu.Allocate(_hostOutputCplx); _fft = GPGPUFFT.Create(_gpu); for (int b = 0; b < BATCH; b++) { for (int i = 0; i < N; i++) { ComplexD cf = new ComplexD(); cf.x = (double)((10.0F * Math.Sin(100 * 2 * Math.PI * i / N * Math.PI / 180))); cf.y = (double)((10.0F * Math.Sin(200 * 2 * Math.PI * i / N * Math.PI / 180))); _hostInput[i + b * N] = cf.x; _hostInputCplx[i + b * N] = cf; } } }
/// <summary> /// IAMINs the specified vectorx. /// </summary> /// <param name="vectorx">The vectorx.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <returns></returns> public abstract int IAMIN(ComplexD[] vectorx, int n = 0, int rowx = 0, int incx = 1);
/// <summary> /// Gets the absolute of the specified value. /// </summary> /// <param name="x">The value.</param> /// <returns>Absolute.</returns> public static double Abs(ComplexD x) { double a = x.x; double b = x.y; double v, w, t; a = Math.Abs(a); b = Math.Abs(b); if (a > b) { v = a; w = b; } else { v = b; w = a; } t = w / v; t = 1.0f + t * t; t = v * Math.Sqrt(t); if ((v == 0.0) || (v > 1.79769313486231570e+308) || (w > 1.79769313486231570e+308)) { t = v + w; } return t; }
/// <summary> /// AXPYs the specified alpha. /// </summary> /// <param name="alpha">The alpha.</param> /// <param name="vectorx">The vectorx.</param> /// <param name="vectory">The vectory.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <param name="rowy">The rowy.</param> /// <param name="incy">The incy.</param> public void AXPY(ComplexD alpha, ComplexD[] vectorx, ComplexD[] vectory, int n = 0, int rowx = 0, int incx = 1, int rowy = 0, int incy = 1) { AXPY(new[] { alpha }, vectorx, vectory, n, rowx, incx, rowy, incy); }
/// <summary> /// Adds value y to value x. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value to be added.</param> /// <returns>New value.</returns> public static ComplexD Add(ComplexD x, ComplexD y) { x.x = x.x + y.x; x.y = x.y + y.y; return x; }
/// <summary> /// AXPYs the specified alpha. /// </summary> /// <param name="alpha">The alpha.</param> /// <param name="vectorx">The vectorx.</param> /// <param name="vectory">The vectory.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <param name="rowy">The rowy.</param> /// <param name="incy">The incy.</param> protected abstract void AXPY(ComplexD[] alpha, ComplexD[] vectorx, ComplexD[] vectory, int n = 0, int rowx = 0, int incx = 1, int rowy = 0, int incy = 1);
/// <summary> /// Multiplies value x and y. /// </summary> /// <param name="x">Value one.</param> /// <param name="y">Value two.</param> /// <returns>New value.</returns> public static ComplexD Multiply(ComplexD x, ComplexD y) { ComplexD c = new ComplexD(); c.x = x.x * y.x - x.y * y.y; c.y = x.x * y.y + x.y * y.x; return c; }
/// <summary> /// COPYs the specified vectorx. /// </summary> /// <param name="vectorx">The vectorx.</param> /// <param name="vectory">The vectory.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <param name="rowy">The rowy.</param> /// <param name="incy">The incy.</param> public abstract void COPY(ComplexD[] vectorx, ComplexD[] vectory, int n = 0, int rowx = 0, int incx = 1, int rowy = 0, int incy = 1);
private static extern CUBLASStatusv2 cublasZdotc_v2(cublasHandle handle, int n, IntPtr x, int incx, IntPtr y, int incy, ref ComplexD result);
/// <summary> /// DOTCs the specified vectorx. /// </summary> /// <param name="vectorx">The vectorx.</param> /// <param name="vectory">The vectory.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <param name="rowy">The rowy.</param> /// <param name="incy">The incy.</param> /// <returns></returns> public abstract ComplexD DOTC(ComplexD[] vectorx, ComplexD[] vectory, int n = 0, int rowx = 0, int incx = 1, int rowy = 0, int incy = 1);
private static extern CUBLASStatusv2 cublasZrotg_v2(cublasHandle handle, ref ComplexD a, ref ComplexD b, ref double c, ref ComplexD s);
/// <summary> /// NRs the m2. /// </summary> /// <param name="vectorx">The vectorx.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <returns></returns> public abstract double NRM2(ComplexD[] vectorx, int n = 0, int rowx = 0, int incx = 1);
public CUBLASStatusv2 cublasZdotc(cublasHandle handle, int n, IntPtr x, int incx, IntPtr y, int incy, ref ComplexD result) { return cublasZdotc_v2(handle, n, x, incx, y, incy, ref result); }
/// <summary> /// ROTs the specified vectorx. /// </summary> /// <param name="vectorx">The vectorx.</param> /// <param name="vectory">The vectory.</param> /// <param name="c">The c.</param> /// <param name="s">The s.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <param name="rowy">The rowy.</param> /// <param name="incy">The incy.</param> public void ROT(ComplexD[] vectorx, ComplexD[] vectory, double c, double s, int n = 0, int rowx = 0, int incx = 1, int rowy = 0, int incy = 1) { ROT(vectorx, vectory, new[] { c }, new[] { s }, n, rowx, incx, rowy, incy); }
public CUBLASStatusv2 cublasZrotg(cublasHandle handle, ref ComplexD a, ref ComplexD b, ref double c, ref ComplexD s) { return cublasZrotg_v2(handle, ref a, ref b, ref c, ref s); }
/// <summary> /// ROTs the specified vectorx. /// </summary> /// <param name="vectorx">The vectorx.</param> /// <param name="vectory">The vectory.</param> /// <param name="c">The c.</param> /// <param name="s">The s.</param> /// <param name="n">The n.</param> /// <param name="rowx">The rowx.</param> /// <param name="incx">The incx.</param> /// <param name="rowy">The rowy.</param> /// <param name="incy">The incy.</param> public abstract void ROT(ComplexD[] vectorx, ComplexD[] vectory, double[] c, double[] s, int n = 0, int rowx = 0, int incx = 1, int rowy = 0, int incy = 1);