public static void Execute(int[,] clusters) { using (MemoryBuffer2D <int> clusterBuff = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(clusters.GetLength(0), clusters.GetLength(1))) { clusterBuff.CopyFrom(clusters, Index2.Zero, Index2.Zero, clusterBuff.Extent); using (MemoryBuffer3D <int> diffs = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(clusterBuff.Extent.X, clusterBuff.Extent.X, 5)) using (MemoryBuffer2D <int> bests = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(clusterBuff.Extent.X, 3 + clusterBuff.Extent.X)) { bool change = true; while (change) { change = false; diffs.MemSetToZero(); bests.MemSetToZero(); kernel(new Index2(clusterBuff.Extent.X, clusterBuff.Extent.X), clusterBuff, diffs); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); kernelBests(bests.Extent.X, diffs, bests); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); int[,] best = new int[bests.Extent.X, bests.Extent.Y]; bests.CopyTo(best, Index2.Zero, Index2.Zero, bests.Extent); int eq = -1; int diffl = -1; int ts = -1; for (int i = 0; i < best.GetLength(0); i++) { if (best[i, 0] > eq) { eq = best[i, 0]; diffl = best[i, 1]; ts = best[i, 2]; } else if (best[i, 0] == eq && best[i, 1] > diffl) { diffl = best[i, 1]; ts = best[i, 2]; } else if (best[i, 0] == eq && best[i, 1] == diffl && ts < best[i, 2]) { ts = best[i, 2]; } } if (eq >= 0) { change = true; List <int> bestofbest = new List <int>(); List <int> bestofbestID = new List <int>(); for (int i = 0; i < best.GetLength(0); i++) { if (eq == best[i, 0] && diffl == best[i, 1] && ts == best[i, 2]) { for (int j = 3; j < best.GetLength(1); j++) { if (best[i, j] < 0) { break; } else { bestofbest.Add(i); bestofbestID.Add(best[i, j]); } } } } int[] bob1 = bestofbest.ToArray(); int[] bob2 = bestofbestID.ToArray(); int[] bob3 = new int[bob1.Length]; bool repeated; for (int i = 0, k = 0; i < bob1.Length; i++) { bob3[i] = bob1[i]; repeated = false; for (int j = 0; j < i; j++) { if (bob3[i] == bob3[j]) { repeated = true; } } if (repeated) { for (int j = k; j < bob2.Length; j++) { repeated = false; for (int q = 0; q < i; q++) { if (bob3[q] == bob2[j]) { repeated = true; break; } } if (!repeated) { bob3[i] = bob2[j]; k = j; break; } } } } using (MemoryBuffer <int> bobbuff1 = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(bestofbest.Count)) using (MemoryBuffer <int> bobbuff2 = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(bestofbestID.Count)) using (MemoryBuffer <int> newPos = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(bestofbest.Count)) using (MemoryBuffer2D <int> newPals = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(bestofbestID.Count, clusterBuff.Extent.Y)) { newPals.MemSetToZero(); bobbuff1.CopyFrom(bob1, 0, 0, bobbuff1.Extent); bobbuff2.CopyFrom(bob2, 0, 0, bobbuff2.Extent); newPos.CopyFrom(bob3, 0, 0, newPos.Extent); kernelInvalidateCluster(bobbuff1.Extent, bobbuff1, bobbuff2, newPals, clusterBuff); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); kernelCopyNewPal(newPos.Extent, newPos, newPals, clusterBuff); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); kernelFilter(bobbuff1.Extent, bobbuff1, newPos, clusterBuff); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); kernelFilter(bobbuff2.Extent, bobbuff2, newPos, clusterBuff); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); } kernelRemoveRepeated(new Index2(clusterBuff.Extent.X, clusterBuff.Extent.X), clusterBuff); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); } } } clusterBuff.CopyTo(clusters, Index2.Zero, Index2.Zero, clusterBuff.Extent); } }
public static void Execute(ConcurrentDictionary <ConcurrentDictionary <Int32, int>, ConcurrentDictionary <TileKey, int> > tilesperPal, ConcurrentDictionary <TileKey, ConcurrentDictionary <Int32, int> > tilePals) { int l = 0; TileKey[] tilespositions = new TileKey[tilePals.Count]; int i = 0; foreach (var kvp in tilePals) { tilespositions[i] = kvp.Key; i++; } foreach (var kvp in tilesperPal) { if (kvp.Key.Count > l) { l = kvp.Key.Count; } } int[,] pals = new int[tilesperPal.Count, l]; Parallel.For(0, pals.GetLength(0), k => { Parallel.For(0, pals.GetLength(1), q => { pals[k, q] = 0; }); }); i = 0; int j; int[,] tilepals = new int[tilePals.Count, l]; l = 0; foreach (var kvp1 in tilesperPal) { j = 0; foreach (var kvp2 in kvp1.Key) { pals[i, j] = kvp2.Key; j++; } if (kvp1.Value.Count > l) { l = kvp1.Value.Count; } i++; } int[,] tilesPerPal = new int[tilesperPal.Count, l]; Parallel.For(0, tilepals.GetLength(0), k => { Parallel.For(0, tilepals.GetLength(1), q => { tilepals[k, q] = 0; }); }); Parallel.For(0, tilesPerPal.GetLength(0), k => { Parallel.For(0, tilesPerPal.GetLength(1), q => { tilesPerPal[k, q] = -1; }); }); i = 0; foreach (var kvp1 in tilePals) { j = 0; foreach (var kvp2 in kvp1.Value) { tilepals[i, j] = kvp2.Key; j++; } i++; } i = 0; foreach (var kvp1 in tilesperPal) { j = 0; foreach (var kvp2 in kvp1.Value) { for (int k = 0; k < tilespositions.GetLength(0); k++) { if (kvp2.Key.X == tilespositions[k].X && kvp2.Key.Y == tilespositions[k].Y) { tilesPerPal[i, j] = k; break; } } j++; } i++; } int[,,] results = new int[pals.GetLength(0), pals.GetLength(0), 1 + pals.GetLength(1)]; int[,,] results2 = new int[pals.GetLength(0), pals.GetLength(0), tilesPerPal.GetLength(1)]; using (MemoryBuffer2D <int> palsBuff = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(pals.GetLength(0), pals.GetLength(1))) using (MemoryBuffer2D <int> tilepalsBuff = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(tilepals.GetLength(0), tilepals.GetLength(1))) using (MemoryBuffer2D <int> tilesPerPalBuff = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(tilesPerPal.GetLength(0), tilesPerPal.GetLength(1))) using (MemoryBuffer3D <int> palres = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(pals.GetLength(0), pals.GetLength(0), 1 + pals.GetLength(1))) using (MemoryBuffer3D <int> palres2 = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(pals.GetLength(0), pals.GetLength(0), tilesPerPal.GetLength(1))) { palsBuff.CopyFrom(pals, Index2.Zero, Index2.Zero, palsBuff.Extent); tilepalsBuff.CopyFrom(tilepals, Index2.Zero, Index2.Zero, tilepalsBuff.Extent); tilesPerPalBuff.CopyFrom(tilesPerPal, Index2.Zero, Index2.Zero, tilesPerPalBuff.Extent); bool change = true; while (change) { palres.MemSetToZero(); palres2.MemSetToZero(); change = false; kernel(palres.Extent.XY, palres, palres2, palsBuff, tilepalsBuff, tilesPerPalBuff); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); kernelBestEach(palres.Extent.X, palres); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); palres.CopyTo(results, Index3.Zero, Index3.Zero, palres.Extent); palres2.CopyTo(results2, Index3.Zero, Index3.Zero, palres2.Extent); int bestOfBest = int.MaxValue; List <int> inds = new List <int>(); List <int> inds2 = new List <int>(); for (i = 0; i < results.GetLength(0); i++) { if (results[i, i, 0] >= 0) { if (results[i, i, 1] < bestOfBest) { bestOfBest = results[i, i, 1]; inds2.Clear(); inds.Clear(); inds.Add(i); inds2.Add(results[i, i, 0]); } else if (results[i, i, 1] == bestOfBest) { inds.Add(i); inds2.Add(results[i, i, 0]); } } } if (inds.Count > 0) { change = true; while (change) { change = false; int addMax = 0; int remIndex = 0; int add = 0; int curindex = 0; foreach (var id1 in inds) { add = 0; foreach (var id2 in inds2) { if (id1 == id2) { add++; } } if (add > addMax) { addMax = add; remIndex = curindex; } curindex++; } if (addMax > 0) { change = true; inds.RemoveAt(remIndex); inds2.RemoveAt(remIndex); } } int[,] reduceInds = new int[inds.Count, 2]; IEnumerator <int> en1 = inds.GetEnumerator(); IEnumerator <int> en2 = inds2.GetEnumerator(); en1.Reset(); en2.Reset(); for (int en = 0; en < inds.Count; en++) { en1.MoveNext(); en2.MoveNext(); reduceInds[en, 0] = en1.Current; reduceInds[en, 1] = en2.Current; } using (MemoryBuffer2D <int> indsbuff = HardwareAcceleratorManager.GPUAccelerator.Allocate <int>(reduceInds.GetLength(0), reduceInds.GetLength(1))) { indsbuff.CopyFrom(reduceInds, Index2.Zero, Index2.Zero, indsbuff.Extent); kernelReduceColors(indsbuff.Extent.X, palres, palres2, palsBuff, indsbuff, tilesPerPalBuff); HardwareAcceleratorManager.GPUAccelerator.Synchronize(); } change = true; } else { palsBuff.CopyTo(pals, Index2.Zero, Index2.Zero, palsBuff.Extent); tilesPerPalBuff.CopyTo(tilesPerPal, Index2.Zero, Index2.Zero, tilesPerPalBuff.Extent); } } } tilesperPal.Clear(); ConcurrentDictionary <Int32, int> curpal; ConcurrentDictionary <TileKey, int> curtiles; for (i = 0; i < tilesPerPal.GetLength(0); i++) { curpal = new ConcurrentDictionary <Int32, int>(); curtiles = new ConcurrentDictionary <TileKey, int>(); if (tilesPerPal[i, 0] >= 0) { for (j = 0; j < tilesPerPal.GetLength(1); j++) { if (tilesPerPal[i, j] >= 0) { curtiles.TryAdd(tilespositions[tilesPerPal[i, j]], 0); } } for (j = 0; j < pals.GetLength(1); j++) { if (pals[i, j] != 0) { curpal.TryAdd(pals[i, j], 0); } } tilesperPal.TryAdd(curpal, curtiles); } } }