Beispiel #1
0
        //[/commonTester]

        //[commonPerfTester]
        public static void Performance(ISimulatorTester simulator, int numBodies)
        {
            const float clusterScale     = 1.0f;
            const float velocityScale    = 1.0f;
            const float deltaTime        = 0.001f;
            const float softeningSquared = 0.00125f;
            const float damping          = 0.9995f;
            const int   steps            = 10;

            Console.WriteLine("Perfomancing {0} with {1} bodies...", simulator.Description, numBodies);

            float4[] pos, vel;
            BodyInitializer.Initialize(new BodyInitializer1(), clusterScale, velocityScale, numBodies,
                                       out pos, out vel);
            simulator.Integrate(pos, vel, numBodies, deltaTime, softeningSquared, damping, steps);
        }
Beispiel #2
0
        static public void Initialize(BodyInitializer initializer, float clusterScale,
                                      float velocityScale, int numBodies,
                                      out float4[] positions, out float4[] velocities)
        {
            var pscale = clusterScale * Math.Max(1.0f, numBodies / 1024.0f);
            var vscale = velocityScale * pscale;

            initializer.NumBodies = numBodies;
            initializer.PScale    = pscale;
            initializer.VScale    = vscale;
            positions             = Enumerable.Range(0, numBodies).Select(initializer.Position).ToArray();
            velocities            = positions.Select(initializer.Velocity).ToArray();

            // now we try to adjust velocity to make total momentum = zero.
            var momentums     = velocities.Select(Momentum).ToArray();
            var totalMomentum = momentums.Aggregate(new float4(0.0f, 0.0f, 0.0f, 0.0f),
                                                    (accum, momentum) =>
                                                    new float4(accum.x + momentum.x,
                                                               accum.y + momentum.y,
                                                               accum.z + momentum.z,
                                                               accum.w + momentum.w));

            Console.WriteLine("total momentum and mass 0 = {0}", totalMomentum);

            var len = velocities.Length;

            // adjust velocities
            velocities = velocities.Select((vel, i) => new float4(
                                               vel.x - totalMomentum.x / len / vel.w,
                                               vel.y - totalMomentum.y / len / vel.w,
                                               vel.z - totalMomentum.z / len / vel.w,
                                               vel.w)).ToArray();

            // see total momentum after adjustment
            momentums     = velocities.Select(Momentum).ToArray();
            totalMomentum = momentums.Aggregate(new float4(0.0f, 0.0f, 0.0f, 0.0f),
                                                (accum, momentum) =>
                                                new float4(accum.x + momentum.x,
                                                           accum.y + momentum.y,
                                                           accum.z + momentum.z,
                                                           accum.w + momentum.w));
            Console.WriteLine("total momentum and mass 1 = {0}", totalMomentum);
        }
Beispiel #3
0
        //[commonTester]
        public static void Test(
            BodyInitializer initializer,
            ISimulatorTester expectedSimulator,
            ISimulatorTester actualSimulator,
            int numBodies)
        {
            const float clusterScale     = 1.0f;
            const float velocityScale    = 1.0f;
            const float deltaTime        = 0.001f;
            const float softeningSquared = 0.00125f;
            const float damping          = 0.9995f;
            const int   steps            = 5;

            Console.WriteLine("Testing {0} against {1} with {2} bodies...",
                              actualSimulator.Description,
                              expectedSimulator.Description,
                              numBodies);
            Console.WriteLine("Using body initializer {0}...", initializer);

            float4[] expectedPos, expectedVel;
            BodyInitializer.Initialize(initializer, clusterScale, velocityScale, numBodies,
                                       out expectedPos, out expectedVel);

            for (var i = 0; i < steps; i++)
            {
                const double tol       = 1e-5;
                var          actualPos = new float4[numBodies];
                var          actualVel = new float4[numBodies];
                Array.Copy(expectedPos, actualPos, numBodies);
                Array.Copy(expectedVel, actualVel, numBodies);
                expectedSimulator.Integrate(expectedPos, expectedVel, numBodies, deltaTime,
                                            softeningSquared, damping, 1);
                actualSimulator.Integrate(actualPos, actualVel, numBodies, deltaTime,
                                          softeningSquared, damping, 1);
                for (var j = 0; j < expectedPos.Length; j++)
                {
                    Assert.AreEqual(actualPos[j].x, expectedPos[j].x, tol);
                    Assert.AreEqual(actualPos[j].y, expectedPos[j].y, tol);
                    Assert.AreEqual(actualPos[j].z, expectedPos[j].z, tol);
                    Assert.AreEqual(actualPos[j].w, expectedPos[j].w, tol);
                }
            }
        }
        static public void Initialize(BodyInitializer initializer, float clusterScale,
                                      float velocityScale, int numBodies, 
                                      out float4[] positions, out float4[] velocities)
        {
            var pscale = clusterScale*Math.Max(1.0f, numBodies/1024.0f);
            var vscale = velocityScale*pscale;
            initializer.NumBodies = numBodies;
            initializer.PScale = pscale;
            initializer.VScale = vscale;
            positions = Enumerable.Range(0, numBodies).Select(initializer.Position).ToArray();
            velocities = positions.Select(initializer.Velocity).ToArray();

            // now we try to adjust velocity to make total momentum = zero.
            var momentums = velocities.Select(Momentum).ToArray();
            var totalMomentum = momentums.Aggregate(new float4(0.0f, 0.0f, 0.0f, 0.0f),
                (accum, momentum) =>
                    new float4(accum.x + momentum.x,
                               accum.y + momentum.y,
                               accum.z + momentum.z, 
                               accum.w + momentum.w));
            Console.WriteLine("total momentum and mass 0 = {0}", totalMomentum);

            var len = velocities.Length;
            // adjust velocities
            velocities = velocities.Select((vel, i) => new float4(
                vel.x - totalMomentum.x / len / vel.w,
                vel.y - totalMomentum.y / len / vel.w,
                vel.z - totalMomentum.z / len / vel.w,
                vel.w)).ToArray();

            // see total momentum after adjustment
            momentums = velocities.Select(Momentum).ToArray();
            totalMomentum = momentums.Aggregate(new float4(0.0f, 0.0f, 0.0f, 0.0f),
                (accum, momentum) =>
                    new float4(accum.x + momentum.x,
                               accum.y + momentum.y,
                               accum.z + momentum.z,
                               accum.w + momentum.w));
            Console.WriteLine("total momentum and mass 1 = {0}", totalMomentum);
        }
        //[commonTester]
        public static void Test(
            BodyInitializer initializer,
            ISimulatorTester expectedSimulator,
            ISimulatorTester actualSimulator,
            int numBodies)
        {
            const float clusterScale = 1.0f;
            const float velocityScale = 1.0f;
            const float deltaTime = 0.001f;
            const float softeningSquared = 0.00125f;
            const float damping = 0.9995f;
            const int steps = 5;

            Console.WriteLine("Testing {0} against {1} with {2} bodies...",
                actualSimulator.Description,
                expectedSimulator.Description,
                numBodies);
            Console.WriteLine("Using body initializer {0}...", initializer);

            float4[] expectedPos, expectedVel;
            BodyInitializer.Initialize(initializer, clusterScale, velocityScale, numBodies, 
                                       out expectedPos, out expectedVel);

            for (var i = 0; i < steps; i++)
            {
                const double tol = 1e-5;
                var actualPos = new float4[numBodies];
                var actualVel = new float4[numBodies];
                Array.Copy(expectedPos, actualPos, numBodies);
                Array.Copy(expectedVel, actualVel, numBodies);
                expectedSimulator.Integrate(expectedPos, expectedVel, numBodies, deltaTime, 
                                            softeningSquared, damping, 1);
                actualSimulator.Integrate(actualPos, actualVel, numBodies, deltaTime, 
                                          softeningSquared, damping, 1);
                for (var j = 0; j < expectedPos.Length; j++)
                {
                    Assert.AreEqual(actualPos[j].x, expectedPos[j].x, tol);
                    Assert.AreEqual(actualPos[j].y, expectedPos[j].y, tol);
                    Assert.AreEqual(actualPos[j].z, expectedPos[j].z, tol);
                    Assert.AreEqual(actualPos[j].w, expectedPos[j].w, tol);
                }
            }
        }
Beispiel #6
0
        //[/LockPositions]

        public SimWindow() : base(800, 600, GraphicsMode.Default, "Gravitational n-body simulation")
        {
            _numBodies = 256 * 64;
            const float clusterScale  = 1.0f;
            const float velocityScale = 1.0f;

            _deltaTime        = 0.001f;
            _softeningSquared = 0.00125f;
            _damping          = 0.9995f;
            //[CreateWorker]
            _worker = Worker.CreateByFunc(Generate);
            //[/CreateWorker]

            _stopwatch    = Stopwatch.StartNew();
            _fpsCalcLag   = 128;
            _frameCounter = 0;

            //[CreateSimulatros]
            _simulators = new Queue <ISimulator>();
            var target = GPUModuleTarget.Worker(_worker);

            var simulatorGpuDynamicBlockSizeModule = new GpuDynamicSimulatorModule(target);         // need dispose
            var simulatorGpuDynamicBlockSize64     = simulatorGpuDynamicBlockSizeModule.Create(64);
            var simulatorGpuDynamicBlockSize128    = simulatorGpuDynamicBlockSizeModule.Create(128);
            var simulatorGpuDynamicBlockSize256    = simulatorGpuDynamicBlockSizeModule.Create(256);
            var simulatorGpuDynamicBlockSize512    = simulatorGpuDynamicBlockSizeModule.Create(512);

            var simulatorGpuStaticBlockSizeModule64  = new GpuStaticSimulatorModule64(target);      // need dispose
            var simulatorGpuStaticBlockSizeModule128 = new GpuStaticSimulatorModule128(target);     // need dispose
            var simulatorGpuStaticBlockSizeModule256 = new GpuStaticSimulatorModule256(target);     // need dispose
            var simulatorGpuStaticBlockSizeModule512 = new GpuStaticSimulatorModule512(target);     // need dispose

            // First, enquene one simulator which is 256 blocksize so we can compare with C code for performance.
            _simulators.Enqueue(simulatorGpuStaticBlockSizeModule256);

            // Enqueue several dynamic block size simulators.
            _simulators.Enqueue(simulatorGpuDynamicBlockSize64);
            _simulators.Enqueue(simulatorGpuDynamicBlockSize128);
            _simulators.Enqueue(simulatorGpuDynamicBlockSize256);
            _simulators.Enqueue(simulatorGpuDynamicBlockSize512);

            // Enqueue several static block size simulators.
            _simulators.Enqueue(simulatorGpuStaticBlockSizeModule64);
            _simulators.Enqueue(simulatorGpuStaticBlockSizeModule128);
            _simulators.Enqueue(simulatorGpuStaticBlockSizeModule256);
            _simulators.Enqueue(simulatorGpuStaticBlockSizeModule512);

            // We do not enqueue any cpu simulator as it is much too slow.
            //_simulators.Enqueue(new CpuSimulator(_worker, _numBodies));

            _disposeSimulators = () =>
            {
                simulatorGpuDynamicBlockSizeModule.Dispose();
                simulatorGpuStaticBlockSizeModule64.Dispose();
                simulatorGpuStaticBlockSizeModule128.Dispose();
                simulatorGpuStaticBlockSizeModule256.Dispose();
                simulatorGpuStaticBlockSizeModule512.Dispose();
            };

            _simulator = _simulators.Dequeue();
            //[/CreateSimulatros]

            //[CreateBuffers]
            _buffers = new uint[2];
            for (var i = 0; i < _buffers.Length; i++)
            {
                _buffers[i] = 0;
            }
            GL.GenBuffers(_buffers.Length, _buffers);
            foreach (var buffer in _buffers)
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
                GL.BufferData(BufferTarget.ArrayBuffer,
                              (IntPtr)(Microsoft.FSharp.Core.Operators.SizeOf <float4>() * _numBodies),
                              IntPtr.Zero, BufferUsageHint.DynamicDraw);
                var size = 0;
                unsafe
                {
                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, &size);
                }
                if (size != Microsoft.FSharp.Core.Operators.SizeOf <float4>() * _numBodies)
                {
                    throw new Exception("Pixel Buffer Object allocation failed!");
                }
                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                CUDAInterop.cuSafeCall(CUDAInterop.cuGLRegisterBufferObject(buffer));
            }

            _resources = new IntPtr[_buffers.Length];
            for (var i = 0; i < _buffers.Length; i++)
            {
                var res = IntPtr.Zero;
                unsafe
                {
                    CUDAInterop.cuSafeCall(CUDAInterop.cuGraphicsGLRegisterBuffer(&res, _buffers[i], 0u));
                }
                _resources[i] = res;
            }
            //[/CreateBuffers]

            //[FinalizeGL]
            _vel = _worker.Malloc <float4>(_numBodies);

            float4[] hpos, hvel;
            BodyInitializer.Initialize(new BodyInitializer3(), clusterScale, velocityScale, _numBodies,
                                       out hpos, out hvel);
            _worker.Scatter(hvel, _vel.Ptr, Microsoft.FSharp.Core.FSharpOption <int> .None,
                            Microsoft.FSharp.Core.FSharpOption <int> .None);
            LockPos(
                (pos0, pos1) =>
                _worker.Scatter(hpos, pos1, Microsoft.FSharp.Core.FSharpOption <int> .None,
                                Microsoft.FSharp.Core.FSharpOption <int> .None));

            Help();
            Description();
            //[/FinalizeGL]
        }