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