Beispiel #1
0
        protected void LoadNextField()
        {
            // Keep t1 timestep as new t0. Update mapping on device side.
            _t0X = _t1X;
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0X);
            _t0Y = _t1Y;
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0Y);
            CurrentTime++;

            // Load new t1.
            LoaderNCF   ncFile = RedSea.Singleton.GetLoaderNCF(CurrentTime);
            ScalarField t1X    = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            ScalarField t1Y    = ncFile.LoadFieldSlice(_ensembleRanges[1]);

            ncFile.Close();

            // All members are above each other.
            int vHeight = _height * _numMembers;

            // vX, t=1
            _t1X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            _t1X.CopyFromHostToThis(t1X.Data);
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1X);

            // vY, t=1
            _t1Y = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            _t1Y.CopyFromHostToThis(t1Y.Data);
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1Y);
        }
Beispiel #2
0
        public VectorFieldUnsteady LoadMeanField()
        {
            SliceRange[] mean = new SliceRange[] { new SliceRange(_ensembleRanges[0]), new SliceRange(_ensembleRanges[1]) };
            mean[0].SetMember(RedSea.Dimension.MEMBER, 0);
            mean[1].SetMember(RedSea.Dimension.MEMBER, 0);

            return(LoaderNCF.LoadTimeSeries(mean, 0, 10));
        }
Beispiel #3
0
            public SliceRange(LoaderNCF file, RedSea.Variable var) : base()
            {
                // Query number of dimensions of variable.
                int numDims;

                NetCDF.ResultCode ncState = NetCDF.nc_inq_varndims(file.GetID(), (int)var, out numDims);
                Debug.Assert(ncState == NetCDF.ResultCode.NC_NOERR);
                int[] dimIDs = new int[numDims];

                // Query relevant dimensions.
                ncState = NetCDF.nc_inq_vardimid(file.GetID(), (int)var, dimIDs);
                Debug.Assert(ncState == NetCDF.ResultCode.NC_NOERR);

                Initialize(dimIDs, var);
            }
Beispiel #4
0
        protected void LoadNextField()
        {
            // Keep t1 timestep as new t0. Update mapping on device side.
            var tmp = _t0X;

            _t0X = _t1X;
            _t1X = tmp;
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0X);

            tmp  = _t0X;
            _t0Y = _t1Y;
            _t1Y = tmp;
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0Y);
            CurrentTime++;

            // Load new t1.
            LoaderNCF   ncFile = RedSea.Singleton.GetLoaderNCF(CurrentTime);
            ScalarField t1X    = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            ScalarField t1Y    = ncFile.LoadFieldSlice(_ensembleRanges[1]);

            ncFile.Close();

            // All members are above each other.
            int vHeight = _height * _numMembers;

            float[] paddedArray = new float[_t1X.Width * _t1X.Height];
            Array.Copy(t1X.Data, paddedArray, t1X.Data.Length);
            // vX, t=1
            _t1X.CopyFromHostToThis <float>(paddedArray);
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1X);

            Array.Copy(t1Y.Data, paddedArray, t1Y.Data.Length);
            // vY, t=1
            _t1Y.CopyFromHostToThis <float>(paddedArray);
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1Y);
        }
Beispiel #5
0
        /// <summary>
        /// Setup as empty map with only one value at 1.
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="fieldEnsemble"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        public void SetupPoint(Int2 pos, int startTime)
        {
            // ~~~~~~~~~~~~~~ Copy relevant data ~~~~~~~~~~~~~~ \\
            // Count up when advection was executed.
            CurrentTime = startTime;
            _startTime  = startTime;

            // ~~~~~~~~~~~~ Load ensemble ~~~~~~~~~~~~ \\
            // Load fields first to get the grid size.
            //Loader ncFile = new Loader(RedSea.Singleton.DataFolder + (_startTime + 1) + RedSea.Singleton.FileName);
            //ScalarField t0X = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            //ScalarField t0Y = ncFile.LoadFieldSlice(_ensembleRanges[1]);
            //ncFile.Close();

            LoaderNCF   ncFile = RedSea.Singleton.GetLoaderNCF(_startTime);
            ScalarField t1X    = ncFile.LoadFieldSlice(_ensembleRanges[0]);
            ScalarField t1Y    = ncFile.LoadFieldSlice(_ensembleRanges[1]);

            ncFile.Close();

            // ~~~~~~~~~~~~~~ Copy relevant data ~~~~~~~~~~~~~~ \\
            // Keep for plane creation and size reference.
            _ensembleGrid = t1X.Grid as RectlinearGrid;
            // Mapper for binding the SlimDX texture to CUDA easily.
            _cudaDxMapper = new CudaGraphicsInteropResourceCollection();
            // Tell CUDA which value is a border.
            _texInvalidValue = t1X.InvalidValue ?? float.MaxValue;

            // ~~~~~~~~~~~~ Fill CUDA resources ~~~~~~~~~~~~ \\
            // All members are above each other.
            int vHeight = _height * _numMembers;

            //// vX, t=0
            //_t0X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            //_t0X.CopyFromHostToThis<float>(t0X.Data);
            //new CudaTextureArray2D(_advectParticlesKernel, "vX_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0X);

            //// vY, t=0
            //_t0Y = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            //_t0Y.CopyFromHostToThis<float>(t0Y.Data);
            //new CudaTextureArray2D(_advectParticlesKernel, "vY_t0", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t0Y);

            // vX, t=1
            _t1X = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            _t1X.CopyFromHostToThis <float>(t1X.Data);
            new CudaTextureArray2D(_advectParticlesKernel, "vX_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1X);

            // vY, t=1
            _t1Y = new CudaArray2D(CUArrayFormat.Float, _width, vHeight, CudaArray2DNumChannels.One);
            _t1Y.CopyFromHostToThis <float>(t1Y.Data);
            new CudaTextureArray2D(_advectParticlesKernel, "vY_t1", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, _t1Y);

            // ~~~~~~~~~~~~~ Create texture ~~~~~~~~~~~~~~~~~~~~ \\
            // Create texture. Completely zero, except for one point.
            Texture2DDescription desc = new Texture2DDescription
            {
                ArraySize         = 1,
                BindFlags         = BindFlags.ShaderResource,
                CpuAccessFlags    = CpuAccessFlags.None,
                Format            = Format.R32_Float,
                Width             = _width,
                Height            = _height,
                MipLevels         = 1,
                OptionFlags       = ResourceOptionFlags.None,
                SampleDescription = new SampleDescription(1, 0),
                Usage             = ResourceUsage.Default
            };

            // Put field data into stream/rectangle object
            float[] zeros = new float[_width * _height];
            Array.Clear(zeros, 0, zeros.Length);

            // Fill the empty texture.
            DataRectangle texData = new DataRectangle(_width * sizeof(float), new DataStream(zeros, true, true));

            _pongFlowMap = new CudaDeviceVariable <float>(_width * _height);//new Texture2D(_device, desc, texData);
            // Magically, copy to device happens here.
            _pongFlowMap = zeros;

            // Add one pixel for integration.
            zeros[pos.X + pos.Y * _width] = 1;
            texData = new DataRectangle(_width * sizeof(float), new DataStream(zeros, true, true));

            // Create texture.
            FlowMap = new Texture2D(_device, desc, texData);

            // ~~~~~~~~~ Make textures mappable to CUDA ~~~~~~~~~~ \\
            _cudaDxMapper.Add(new CudaDirectXInteropResource(FlowMap.ComPointer, CUGraphicsRegisterFlags.None, CudaContext.DirectXVersion.D3D11));


            _cudaDxMapper.MapAllResources();
            CudaArray2D lastFlowMap = _cudaDxMapper[0].GetMappedArray2D(0, 0);

            new CudaTextureArray2D(_advectParticlesKernel, "flowMap", CUAddressMode.Wrap, CUFilterMode.Linear, CUTexRefSetFlags.None, lastFlowMap);
            _cudaDxMapper.UnmapAllResources();
        }