/// <inheritdoc /> public override unsafe void DoStepOpenCL(OpenCLDispatcher dispatcher, OpenCLDevice device) { var timerTotal = Stopwatch.StartNew(); OpenCLKernelSet kernelSet = dispatcher.Compile(device, "CellBasedSim.cl"); currentStep++; // Increase random seed randomSeed++; int cellsLength = Current.Cells.Length; int junctionsLength = Current.Junctions.Length; int generatorsLength = Current.Generators.Length; int carsLength = Current.Cars.Length; // Reset waiting count on every junction Parallel.ForEach(Partitioner.Create(0, Current.Junctions.Length), range => { for (int i = range.Item1; i < range.Item2; i++) { Current.Junctions[i].WaitingCount = 0; } }); fixed(Cell *cellsPtr = Current.Cells) fixed(CellToCar * cellsToCarPtr = Current.CellsToCar) fixed(Junction * junctionsPtr = Current.Junctions) fixed(Generator * generatorsPtr = Current.Generators) fixed(Car * carsPtr = Current.Cars) fixed(float *randomPtr = random) { var timer = Stopwatch.StartNew(); // Process all cars kernelSet["DoStepCar"] .BindBuffer(cellsPtr, sizeof(Cell) * cellsLength, true) .BindBuffer(cellsToCarPtr, sizeof(CellToCar) * cellsLength, false) .BindValue(cellsLength) .BindBuffer(junctionsPtr, sizeof(Junction) * junctionsLength, false) .BindValue(junctionsLength) .BindBuffer(carsPtr, sizeof(Car) * carsLength, false) .BindValue(carsLength) .BindBuffer(randomPtr, sizeof(float) * randomLength, true) .BindValue(randomLength) .BindValue(randomSeed) .Run(carsLength) .Finish(); LastTimeCars = timer.Elapsed; timer.Restart(); // Process all generators if ((flags & SimulationFlags.NoSpawn) == 0) { kernelSet["SpawnCars"] .BindBuffer(cellsPtr, sizeof(Cell) * cellsLength, true) .BindBuffer(cellsToCarPtr, sizeof(CellToCar) * cellsLength, false) .BindValue(cellsLength) .BindBuffer(generatorsPtr, sizeof(Generator) * generatorsLength, false) .BindValue(generatorsLength) .BindBuffer(carsPtr, sizeof(Car) * carsLength, false) .BindValue(carsLength) .BindBuffer(randomPtr, sizeof(float) * randomLength, true) .BindValue(randomLength) .BindValue(randomSeed) .Run(generatorsLength) .Finish(); } LastTimeGenerators = timer.Elapsed; } LastTimeTotal = timerTotal.Elapsed; }
/// <inheritdoc /> public override unsafe void DoBatchOpenCL(OpenCLDispatcher dispatcher, OpenCLDevice device, int steps) { OpenCLKernelSet kernelSet = dispatcher.Compile(device, "CellBasedSim.cl"); int cellsLength = Current.Cells.Length; int junctionsLength = Current.Junctions.Length; int generatorsLength = Current.Generators.Length; int carsLength = Current.Cars.Length; fixed(Cell *cellsPtr = Current.Cells) fixed(CellToCar * cellsToCarPtr = Current.CellsToCar) fixed(Junction * junctionsPtr = Current.Junctions) fixed(Generator * generatorsPtr = Current.Generators) fixed(Car * carsPtr = Current.Cars) fixed(float *randomPtr = random) { var kernelDoStepCar = kernelSet["DoStepCar"]; var kernelSpawnCars = kernelSet["SpawnCars"]; // Create all buffers using (var cellsBuffer = dispatcher.CreateBuffer(device, cellsPtr, sizeof(Cell) * cellsLength, true)) using (var cellsToCarBuffer = dispatcher.CreateBuffer(device, cellsToCarPtr, sizeof(CellToCar) * cellsLength, false)) using (var junctionsBuffer = dispatcher.CreateBuffer(device, junctionsPtr, sizeof(Junction) * junctionsLength, false)) using (var generatorsBuffer = dispatcher.CreateBuffer(device, generatorsPtr, sizeof(Generator) * generatorsLength, false)) using (var carsBuffer = dispatcher.CreateBuffer(device, carsPtr, sizeof(Car) * carsLength, false)) using (var randomBuffer = dispatcher.CreateBuffer(device, randomPtr, sizeof(float) * randomLength, true)) { // Prepare kernels kernelDoStepCar .BindBuffer(cellsBuffer) .BindBuffer(cellsToCarBuffer) .BindValue(cellsLength) .BindBuffer(junctionsBuffer) .BindValue(junctionsLength) .BindBuffer(carsBuffer) .BindValue(carsLength) .BindBuffer(randomBuffer) .BindValue(randomLength) .BindValue(randomSeed); kernelSpawnCars .BindBuffer(cellsBuffer) .BindBuffer(cellsToCarBuffer) .BindValue(cellsLength) .BindBuffer(generatorsBuffer) .BindValue(generatorsLength) .BindBuffer(carsBuffer) .BindValue(carsLength) .BindBuffer(randomBuffer) .BindValue(randomLength) .BindValue(randomSeed); // Call kernels, compute simulation for (int i = 0; i < steps; i++) { currentStep++; // Increase random seed randomSeed++; // Process all cars kernelDoStepCar .BindValueByIndex(9, randomSeed) .Run(carsLength); // Process all generators if ((flags & SimulationFlags.NoSpawn) == 0) { kernelSpawnCars .BindValueByIndex(9, randomSeed) .Run(generatorsLength); } } // Cleanup kernelDoStepCar.Finish(); kernelSpawnCars.Finish(); } } }
/// <inheritdoc /> public override unsafe void DoBatchOpenCL(OpenCLDispatcher dispatcher, OpenCLDevice device, int steps) { OpenCLKernelSet kernelSet = dispatcher.Compile(device, "CarFollowingSim.cl"); int cellsLength = Current.Cells.Length; int junctionsLength = Current.Junctions.Length; int generatorsLength = Current.Generators.Length; int carsLength = Current.Cars.Length; int isChanged = 0; // Reset waiting count on every junction /*Parallel.ForEach(Partitioner.Create(0, Current.Junctions.Length), range => { * for (int i = range.Item1; i < range.Item2; i++) * { * Current.Junctions[i].WaitingCount = 0; * } * });*/ fixed(Cell *cellsPtr = Current.Cells) fixed(int *cellsToCarPtr = Current.CellsToCar) fixed(Junction * junctionsPtr = Current.Junctions) fixed(Generator * generatorsPtr = Current.Generators) fixed(Car * carsPtr = Current.Cars) fixed(float *randomPtr = random) { var kernelDoStepCarPre = kernelSet["DoStepCarPre"]; var kernelDoStepCarPost = kernelSet["DoStepCarPost"]; var kernelSpawnCars = kernelSet["SpawnCars"]; // Create all buffers using (var cellsBuffer = dispatcher.CreateBuffer(device, cellsPtr, sizeof(Cell) * cellsLength, false)) using (var cellsToCarBuffer = dispatcher.CreateBuffer(device, cellsToCarPtr, sizeof(int) * cellsLength * Current.CarsPerCell, false)) using (var junctionsBuffer = dispatcher.CreateBuffer(device, junctionsPtr, sizeof(Junction) * junctionsLength, false)) using (var generatorsBuffer = dispatcher.CreateBuffer(device, generatorsPtr, sizeof(Generator) * generatorsLength, false)) using (var carsBuffer = dispatcher.CreateBuffer(device, carsPtr, sizeof(Car) * carsLength, false)) using (var randomBuffer = dispatcher.CreateBuffer(device, randomPtr, sizeof(float) * randomLength, true)) using (var isChangedBuffer = dispatcher.CreateBuffer(device, &isChanged, sizeof(int), false)) { // Prepare kernels kernelDoStepCarPre .BindBuffer(cellsBuffer) .BindBuffer(cellsToCarBuffer) .BindValue(cellsLength) .BindBuffer(junctionsBuffer) .BindValue(junctionsLength) .BindBuffer(carsBuffer) .BindValue(carsLength) .BindValue(Current.CarsPerCell) .BindBuffer(randomBuffer) .BindValue(randomLength) .BindValue(randomSeed) .BindValue(dt); kernelDoStepCarPost .BindBuffer(cellsBuffer) .BindBuffer(cellsToCarBuffer) .BindValue(cellsLength) .BindBuffer(junctionsBuffer) .BindValue(junctionsLength) .BindBuffer(carsBuffer) .BindValue(carsLength) .BindValue(Current.CarsPerCell) .BindBuffer(randomBuffer) .BindValue(randomLength) .BindValue(randomSeed) .BindBuffer(isChangedBuffer); kernelSpawnCars .BindBuffer(cellsBuffer) .BindBuffer(cellsToCarBuffer) .BindValue(cellsLength) .BindBuffer(generatorsBuffer) .BindValue(generatorsLength) .BindBuffer(carsBuffer) .BindValue(carsLength) .BindValue(Current.CarsPerCell) .BindBuffer(randomBuffer) .BindValue(randomLength) .BindValue(randomSeed) .BindValue(dt); // Call kernels, compute simulation for (int i = 0; i < steps; i++) { currentStep++; // Increase random seed randomSeed++; // Process all cells kernelDoStepCarPre .BindValueByIndex(10, randomSeed) .Run(cellsLength); bool isFirst = true; while (true) { if (isFirst) { isFirst = false; } else { using (isChangedBuffer.MapAsWritable()) { if (isChanged == 0) { break; } isChanged = 0; } } kernelDoStepCarPost .BindValueByIndex(10, randomSeed) .Run(cellsLength); } // Process all generators if ((flags & SimulationFlags.NoSpawn) == 0) { kernelSpawnCars .BindValueByIndex(10, randomSeed) .Run(generatorsLength); } } // Cleanup kernelDoStepCarPre.Finish(); kernelDoStepCarPost.Finish(); kernelSpawnCars.Finish(); } } }