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); }
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); }
/// <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(); }