Skip to content

Commit abb6227

Browse files
committed
Initial commit on dummy branhc
0 parents  commit abb6227

32 files changed

+2966
-0
lines changed

CMakeLists.txt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Copyright (C) 2022 Codeplay Software Ltd.
2+
cmake_minimum_required (VERSION 3.21.0)
3+
4+
set(CMAKE_CXX_STANDARD 17)
5+
set(CMAKE_CXX_STANDARD_REQUIRED True)
6+
7+
project(crowd-simulation)
8+
9+
OPTION(PROFILING_MODE "Enable profiling" off)
10+
if(PROFILING_MODE)
11+
add_definitions(-DPROFILING_MODE)
12+
else()
13+
find_package(SDL2 REQUIRED)
14+
include_directories(${SDL2_INCLUDE_DIRS})
15+
endif()
16+
17+
OPTION(STATS "Run in stats mode" off)
18+
if (STATS)
19+
add_definitions(-DSTATS)
20+
endif()
21+
22+
set(SYCL_BACKEND "SYCL_BACKEND" CACHE STRING "Backend chosen by the user at CMake configure time")
23+
set_property(CACHE SYCL_BACKEND PROPERTY STRINGS spir cuda hip)
24+
25+
if(SYCL_BACKEND STREQUAL hip)
26+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsycl -fsycl-targets=amdgcn-amd-amdhsa")
27+
elseif(SYCL_BACKEND STREQUAL cuda)
28+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsycl -fsycl-targets=nvptx64-nvidia-cuda")
29+
else()
30+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsycl -fsycl-targets=spir64")
31+
endif()
32+
33+
find_package(Python QUIET)
34+
if(Python_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/scripts/InputFileGenerator.py")
35+
execute_process(COMMAND ${Python_EXECUTABLE} ../scripts/InputFileGenerator.py)
36+
else()
37+
message(WARNING "Unable to generate input configuration files")
38+
endif()
39+
40+
add_executable(crowdsim src/main.cpp)
41+
42+
add_subdirectory(external)
43+
44+
if (PROFILING_MODE)
45+
target_link_libraries(crowdsim PUBLIC external)
46+
else()
47+
target_link_libraries(crowdsim PUBLIC ${SDL2_LIBRARIES} external)
48+
endif()
49+
target_include_directories(crowdsim PUBLIC "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/external")

LICENSE.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2022 Codeplay Software Ltd.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use these files except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.

README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# SYCL-Crowd-Simulation
2+
3+
SYCL GPU-accelerated crowd simulation engine based on Helbing et. al.'s social force model.
4+
5+
Dirk Helbing introduced the social force model in a paper in 1995, aimed at modelling the behaviour of crowds using Langevin equations. He proposed a refined model in a 2000 paper, "Simulating Dynamical Features of Escape Panic". Helbing posits that human behaviour in large crowds is determined by three component forces: A personal impulse towards one's destination, the cumulative force exerted by neighbouring people, and the repulsive force of any nearby walls. Together, these forces form the basis of a differential equation which can subsequently be integrated in order to calculate the actor's velocity.
6+
7+
## Features
8+
9+
- Performantly simulate tens of thousands of actors in real time
10+
- Define different crowds with different characteristics and different destinations
11+
- Define rooms and obstacles
12+
- Fully configurable environments (see [Input Format](#input-format))
13+
- Record and graph simulation metrics
14+
- Target and build for multiple SYCL supported backends
15+
- Apply a force heatmap across actors
16+
- The simulation kernels may be used separately from the GUI
17+
18+
## Dependencies
19+
20+
- The [DPC++ compiler](https://intel.github.io/llvm-docs/GetStartedGuide.html) is required to compile SYCL code
21+
- If targeting the DPC++ CUDA backend, the [CUDA runtime](https://intel.github.io/llvm-docs/GetStartedGuide.html#build-dpc-toolchain-with-support-for-nvidia-cuda) is required
22+
- If targeting the DPC++ OpenCL backend, an [OpenCL runtime](https://intel.github.io/llvm-docs/GetStartedGuide.html#install-low-level-runtime) is required
23+
- Graphics are rendered with [SDL2](https://lazyfoo.net/tutorials/SDL/01_hello_SDL/linux/index.php), installed with apt: `$ apt install libsdl2-dev`
24+
- Input files are parsed using [RapidJSON](https://rapidjson.org/index.html)
25+
RapidJSON is a header-only library, so can be installed by simply copying the directory `include/rapidjson` into your system include path
26+
- Python is needed to run scripts
27+
- Graphs are plotted using matplotlib, installed via pip: `$ pip install matplotlib`
28+
- To run simulations in headless mode and record video output, install [xvfb](https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml) and [ffmpeg](https://ffmpeg.org/download.html) using apt
29+
30+
## Building
31+
32+
Build configuration is carried out using CMake.
33+
34+
The option `-DSYCL_BACKEND` allows you to select which backend to build for (spir, cuda or hip). By default, it builds for spir.
35+
36+
When enabled, the `-DPROFILING_MODE` option builds a headless version which can be run without the SDL dependency.
37+
38+
When enabled, the `-DSTATS` option will collect metrics whilst the simulation is running. Results are written to `output/outputStats`.txt. Graphs can be produced from these metrics by running the python script [PlotGraphs.py](scripts/PlotGraphs.py).
39+
40+
By default, CMake should generate example input files by running [InputFileGenerator.py](scripts/InputFileGenerator.py) when generating the project makefiles.
41+
42+
The `crowdsim` executable takes an input configuration JSON as a command line argument.
43+
44+
```
45+
$ git clone https://[repo link]
46+
$ cd crowd-simulation
47+
$ mkdir build && cd build
48+
$ cmake -DCMAKE_CXX_COMPILER=path/to/llvm/build/bin/clang++ -DSYCL_BACKEND=spir -DPROFILING_MODE=off -DSTATS=on ..
49+
$ cmake --build .
50+
$ ./crowdsim ../input/evacuateRoom.json
51+
```
52+
53+
## Input Format
54+
55+
Below is an annotated example input file which creates a room containing two actors with two different destinations.
56+
57+
```
58+
{
59+
"config": { <-- Configure environment
60+
"width": 9,
61+
"height": 9,
62+
"scale": 100,
63+
"delay": 0,
64+
"bgColor": [0, 0, 0],
65+
"wallColor": [255, 255, 255]
66+
},
67+
68+
"room": {
69+
"walls": [
70+
[0.5, 0.5, 8.5, 0.5], <-- Walls are defined via their
71+
[8.5, 0.5, 8.5, 8.5], start and end points
72+
[8.5, 8.5, 0.5, 8.5],
73+
[0.5, 8.5, 0.5, 0.5]
74+
]
75+
},
76+
77+
"actors": [ <-- Populate environment with
78+
{ actors
79+
"pos": [3.4, 5.6],
80+
"velocity": [0.0123, 0.0567],
81+
"desiredSpeed": 0.6,
82+
"pathId": 0,
83+
"mass": 50,
84+
"radius": 0.05,
85+
"atDestination": false,
86+
"color": [255, 0, 0],
87+
"heatmapEnabled": true <-- Flag denoting whether the
88+
}, actor's colour should change
89+
{ with the heatmap
90+
"pos": [0.7, 7.3],
91+
"velocity": [0.0789, 0.0444],
92+
"desiredSpeed": 0.6,
93+
"pathId": 1,
94+
"mass": 45,
95+
"radius": 0.06,
96+
"atDestination": false,
97+
"color": [0, 255, 0],
98+
"heatmapEnabled": true
99+
}
100+
],
101+
102+
"paths": [
103+
{
104+
"id": 0, <-- Each path has a unique id,
105+
"checkpoints": [[[7.9, 5.6], [8.1, 5.8]]] referenced by any actor which
106+
}, takes that path
107+
{
108+
"id": 1,
109+
"checkpoints": [[[7.9, 5.6], [8.1, 5.8]], <-- Paths consist of checkpoints
110+
[[1.5, 2], [1.7, 2.2]]] Each checkpoint is a rectangular
111+
} region defined as:
112+
] [[minX, minY], [maxX, maxY]]
113+
}
114+
```
115+
116+
Larger input configurations can be generated with python scripts, as demonstrated in [InputFileGenerator.py](scripts/InputFileGenerator.py).
117+
118+
The social force model itself can be tweaked by altering the constexprs defined in [DifferentialEq.hpp](external/DifferentialEq.hpp). For example, in simulations involving large numbers of actors (10,000+), the values `WALLAi` and `PEOPLEAi` will need to be increased to prevent any clipping issues.
119+
120+
## Benchmarks
121+
122+
## Citations
123+
124+
- Helbing, D., Farkas, I. & Vicsek, T. Simulating dynamical features of escape panic. Nature 407, 487–490 (2000). https://doi.org/10.1038/35035023
125+
- Marsaglia, G. (2003). Xorshift RNGs. Journal of Statistical Software, 8(14), 1–6. https://doi.org/10.18637/jss.v008.i14

external/Actor.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/***************************************************************************
2+
*
3+
* Copyright (C) 2022 Codeplay Software Ltd.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
* Codeplay's crowd-simulation
18+
*
19+
* Actor.cpp
20+
*
21+
* Description:
22+
* Class denoting an actor in social force model
23+
*
24+
**************************************************************************/
25+
26+
#include "Actor.hpp"
27+
28+
Actor::Actor(vecType pPos, vecType pVelocity, float pDesiredSpeed, int pPathId,
29+
float pMass, float pRadius, bool pAtDestination,
30+
std::array<int, 3> pColor, bool pHeatmapEnabled)
31+
: pos(pPos), velocity(pVelocity), desiredSpeed(pDesiredSpeed),
32+
pathId(pPathId), mass(pMass), radius(pRadius),
33+
atDestination(pAtDestination), color(pColor),
34+
heatmapEnabled(pHeatmapEnabled), destinationIndex(0), bBox({0, 0}) {}
35+
36+
SYCL_EXTERNAL vecType Actor::getPos() const { return pos; }
37+
38+
SYCL_EXTERNAL vecType Actor::getVelocity() const { return velocity; }
39+
40+
SYCL_EXTERNAL float Actor::getDesiredSpeed() const { return desiredSpeed; }
41+
42+
SYCL_EXTERNAL int Actor::getPathId() const { return pathId; }
43+
44+
SYCL_EXTERNAL int Actor::getDestinationIndex() const {
45+
return destinationIndex;
46+
}
47+
48+
SYCL_EXTERNAL float Actor::getMass() const { return mass; }
49+
50+
SYCL_EXTERNAL float Actor::getRadius() const { return radius; }
51+
52+
SYCL_EXTERNAL bool Actor::getAtDestination() const { return atDestination; }
53+
54+
SYCL_EXTERNAL std::array<int, 3> Actor::getColor() const { return color; }
55+
56+
SYCL_EXTERNAL bool Actor::getHeatmapEnabled() const { return heatmapEnabled; }
57+
58+
SYCL_EXTERNAL std::array<int, 2> Actor::getBBox() const { return bBox; }
59+
60+
SYCL_EXTERNAL uint Actor::getSeed() const { return seed; }
61+
62+
SYCL_EXTERNAL float Actor::getForce() const { return force; }
63+
64+
SYCL_EXTERNAL void Actor::setPos(vecType newPos) { pos = newPos; }
65+
66+
SYCL_EXTERNAL void Actor::setVelocity(vecType newVelocity) {
67+
velocity = newVelocity;
68+
}
69+
70+
SYCL_EXTERNAL void Actor::setDesiredSpeed(float newDesiredSpeed) {
71+
desiredSpeed = newDesiredSpeed;
72+
}
73+
74+
SYCL_EXTERNAL void Actor::setAtDestination(bool param) {
75+
atDestination = param;
76+
}
77+
78+
SYCL_EXTERNAL void Actor::setColor(std::array<int, 3> newColor) {
79+
color = newColor;
80+
}
81+
82+
SYCL_EXTERNAL void Actor::setBBox(std::array<int, 2> newBBox) {
83+
bBox = newBBox;
84+
}
85+
86+
SYCL_EXTERNAL void Actor::setSeed(uint newSeed) { seed = newSeed; }
87+
88+
SYCL_EXTERNAL void Actor::setForce(float newForce) { force = newForce; }
89+
90+
SYCL_EXTERNAL void Actor::checkAtDestination(std::array<vecType, 2> destination,
91+
int pathSize) {
92+
// Destinations are defined as rectangular regions
93+
if (pos[0] >= destination[0][0] && pos[0] <= destination[1][0] &&
94+
pos[1] >= destination[0][1] && pos[1] <= destination[1][1]) {
95+
if (destinationIndex >= PATHALLOCATIONSIZE - 1 ||
96+
destinationIndex >= pathSize - 1) {
97+
this->setAtDestination(true);
98+
} else {
99+
destinationIndex++;
100+
}
101+
}
102+
}

external/Actor.hpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/***************************************************************************
2+
*
3+
* Copyright (C) 2022 Codeplay Software Ltd.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
* Codeplay's crowd-simulation
18+
*
19+
* Actor.hpp
20+
*
21+
* Description:
22+
* Class denoting an actor in social force model
23+
*
24+
**************************************************************************/
25+
26+
#ifndef Actor_hpp
27+
#define Actor_hpp
28+
29+
#include "Path.hpp"
30+
#include "RandomNumber.hpp"
31+
#include "VectorMaths.hpp"
32+
#include <array>
33+
#include <iostream>
34+
#include <random>
35+
#include <sycl/sycl.hpp>
36+
#include <vector>
37+
38+
class Actor {
39+
private:
40+
vecType pos;
41+
vecType velocity;
42+
float desiredSpeed;
43+
int pathId;
44+
int destinationIndex;
45+
float mass;
46+
float radius;
47+
bool atDestination;
48+
std::array<int, 3> color;
49+
bool heatmapEnabled;
50+
std::array<int, 2> bBox;
51+
uint seed;
52+
float force;
53+
54+
public:
55+
Actor(vecType pPos, vecType pVelocity, float pdesiredSpeed, int pPathId,
56+
float pMass, float pRadius, bool pAtDestination,
57+
std::array<int, 3> pColor, bool pHeatmapEnabled);
58+
59+
SYCL_EXTERNAL vecType getPos() const;
60+
SYCL_EXTERNAL vecType getVelocity() const;
61+
SYCL_EXTERNAL float getDesiredSpeed() const;
62+
SYCL_EXTERNAL int getPathId() const;
63+
SYCL_EXTERNAL int getDestinationIndex() const;
64+
SYCL_EXTERNAL float getMass() const;
65+
SYCL_EXTERNAL float getRadius() const;
66+
SYCL_EXTERNAL bool getAtDestination() const;
67+
SYCL_EXTERNAL std::array<int, 3> getColor() const;
68+
SYCL_EXTERNAL bool getHeatmapEnabled() const;
69+
SYCL_EXTERNAL std::array<int, 2> getBBox() const;
70+
SYCL_EXTERNAL uint getSeed() const;
71+
SYCL_EXTERNAL float getForce() const;
72+
73+
SYCL_EXTERNAL void setPos(vecType newPos);
74+
SYCL_EXTERNAL void setVelocity(vecType newVelocity);
75+
SYCL_EXTERNAL void setDesiredSpeed(float newDesiredSpeed);
76+
SYCL_EXTERNAL void setAtDestination(bool param);
77+
SYCL_EXTERNAL void setColor(std::array<int, 3> newColor);
78+
SYCL_EXTERNAL void setBBox(std::array<int, 2> newBBox);
79+
SYCL_EXTERNAL void setSeed(uint newSeed);
80+
SYCL_EXTERNAL void setForce(float newForce);
81+
82+
SYCL_EXTERNAL void checkAtDestination(std::array<vecType, 2> destination,
83+
int pathSize);
84+
};
85+
86+
#endif

external/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (C) 2022 Codeplay Software Ltd.
2+
3+
add_library(external Actor.cpp
4+
Room.cpp
5+
Path.cpp
6+
MathHelper.cpp
7+
DifferentialEq.cpp
8+
VectorMaths.cpp
9+
Heatmap.cpp
10+
ParseInputFile.cpp
11+
RandomNumber.cpp
12+
Stats.cpp
13+
)

0 commit comments

Comments
 (0)