예제 #1
0
 public IEnumerable<SparseTwinIndex<float>> Distribute(IEnumerable<SparseArray<float>> productions, IEnumerable<SparseArray<float>> attractions, IEnumerable<IDemographicCategory> cat)
 {
     var productionEnum = productions.GetEnumerator();
     var attractionEnum = attractions.GetEnumerator();
     var catEnum = cat.GetEnumerator();
     var numberOfZones = this.Root.ZoneSystem.ZoneArray.GetFlatData().Length;
     using ( MultiRunGPUGravityModel multiDist = new MultiRunGPUGravityModel( numberOfZones, ( (p) => this.Progress = p ), this.Epsilon, this.MaxIterations ) )
     {
         var zoneArray = this.Root.ZoneSystem.ZoneArray;
         float[] friction = null;
         while ( productionEnum.MoveNext() && attractionEnum.MoveNext() && catEnum.MoveNext() )
         {
             yield return multiDist.ProcessFlow( ( friction = this.ComputeFriction( zoneArray.GetFlatData(), catEnum.Current, friction ) ), productionEnum.Current, attractionEnum.Current );
         }
         friction = null;
     }
 }
예제 #2
0
 private IEnumerable<SparseTwinIndex<float>> GPUDoublyConstrained(IZone[] zones, IEnumerator<SparseArray<float>> ep, IEnumerator<SparseArray<float>> ea, IEnumerator<IDemographicCategory> ec)
 {
     using ( MultiRunGPUGravityModel gm =
                 new MultiRunGPUGravityModel( zones.Length, ( p => this.Progress = p ), this.Epsilon, this.MaxIterations ) )
     {
         float[] friction = null;
         while ( ep.MoveNext() && ea.MoveNext() && ec.MoveNext() )
         {
             var production = ep.Current;
             var attraction = ea.Current;
             var cat = ec.Current;
             var ret = production.CreateSquareTwinArray<float>();
             friction = this.ComputeFriction( zones, cat, production.GetFlatData(), attraction.GetFlatData(), friction );
             yield return gm.ProcessFlow( friction, production, attraction );
         }
     }
 }
예제 #3
0
파일: PORPOW.cs 프로젝트: Cocotus/XTMF
        private void InitializeFlows()
        {
            this.Progress = 0;
            // we are going to need to split based on this information
            this.ZoneArray = this.Root.ZoneSystem.ZoneArray;
            var occupations = this.Root.Demographics.OccupationCategories;
            var validZones = this.ZoneArray.ValidIndexies().ToArray();
            var numberOfZones = validZones.Length;
            //[Occupation][O , D]
            var distribution = occupations.CreateSimilarArray<SparseTwinIndex<float>>();
            //Generate the place of work place of residence OD's
            SparseArray<float> O = this.ZoneArray.CreateSimilarArray<float>();
            SparseArray<float> D = this.ZoneArray.CreateSimilarArray<float>();
            var occupationIndexes = occupations.ValidIndexies().ToArray();
            var numCat = Categories.Count;
            // Start burning that CPU
            Thread.CurrentThread.Priority = ThreadPriority.Highest;
            SparseTwinIndex<float> workplaceDistribution = null;
            SparseTwinIndex<float> prevWorkplaceDistribution = null;
            float[] friction = null;
            float[] nextFriction = null;
            MultiRunGPUGravityModel multiRunGPU = null;
            for ( int i = 0; i < numCat; i++ )
            {
                this.CurrentOccupationIndex = i;
                Task assignToPopulation = null;
                if ( i > 0 )
                {
                    assignToPopulation = new Task( delegate()
                        {
                            if ( prevWorkplaceDistribution != null )
                            {
                                // We actually are assigning to the previous category with this data so we need i - 1
                                AssignToWorkers( prevWorkplaceDistribution, this.Categories[i - 1] );
                                prevWorkplaceDistribution = null;
                            }
                        } );
                    assignToPopulation.Start();
                }
                Task computeNextFriction = null;
                if ( i + 1 < numCat )
                {
                    computeNextFriction = new Task( delegate()
                    {
                        nextFriction = this.ComputeFriction( ZoneArray.GetFlatData(), this.Categories[i + 1], nextFriction );
                    } );
                    computeNextFriction.Start();
                }

                this.Categories[i].Generate( O, D );
                if ( this.UseGPU )
                {
                    if ( i == 0 )
                    {
                        try
                        {
                            Parallel.Invoke( () => friction = this.ComputeFriction( ZoneArray.GetFlatData(), this.Categories[i], friction ),
                            () => multiRunGPU = new MultiRunGPUGravityModel( O.GetFlatData().Length, ( progress => this.Progress = ( progress / numCat ) + ( (float)i / numCat ) ), this.Epsilon, this.MaxIterations ) );
                        }
                        catch ( AggregateException e )
                        {
                            throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
                        }
                    }
                    workplaceDistribution = multiRunGPU.ProcessFlow( friction, O, D );
                }
                else
                {
                    GravityModel gravityModel = new GravityModel( ImpedenceFunction, ( progress => this.Progress = ( progress / numCat ) + ( (float)i / numCat ) ), this.Epsilon, this.MaxIterations );
                    workplaceDistribution = gravityModel.ProcessFlow( O, D, validZones );
                }
                this.Progress = ( (float)( i + 1 ) / numCat );
                if ( assignToPopulation != null )
                {
                    try
                    {
                        assignToPopulation.Wait();
                        assignToPopulation.Dispose();
                        assignToPopulation = null;
                    }
                    catch ( AggregateException e )
                    {
                        throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
                    }
                }
                if ( computeNextFriction != null )
                {
                    try
                    {
                        computeNextFriction.Wait();
                        computeNextFriction.Dispose();
                        computeNextFriction = null;
                    }
                    catch ( AggregateException e )
                    {
                        throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
                    }
                }
                prevWorkplaceDistribution = workplaceDistribution;
                var frictionTemp = friction;
                friction = nextFriction;
                nextFriction = friction;
            }
            friction = null;
            nextFriction = null;
            prevWorkplaceDistribution = null;
            if ( multiRunGPU != null )
            {
                multiRunGPU.Dispose();
                multiRunGPU = null;
            }
            AssignToWorkers( workplaceDistribution, this.Categories[numCat - 1] );
            workplaceDistribution = null;
            // ok now we can relax
            Thread.CurrentThread.Priority = ThreadPriority.Normal;
            GC.Collect();
        }