diff --git a/.github/workflows/Ubuntu.yml b/.github/workflows/Ubuntu.yml index 9e70d44d3..8762f488c 100644 --- a/.github/workflows/Ubuntu.yml +++ b/.github/workflows/Ubuntu.yml @@ -41,6 +41,52 @@ jobs: cuda_arch: "35" hostcxx: gcc-8 os: ubuntu-20.04 + # newest cuda with newest clang on ubuntu 22.04 + - cuda: "12.3" + cuda_arch: "50" + hostcxx: clang-14 # 7-16 + os: ubuntu-22.04 + # cuda 12.0 with oldest clang on ubuntu 20.04 which supports c++17 + - cuda: "12.0" + cuda_arch: "50" + hostcxx: clang-8 # 7-15 + os: ubuntu-20.04 + - cuda: "11.8" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.7" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.6" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.5" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.4" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.3" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.2" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.1" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 + - cuda: "11.0" + cuda_arch: "50" + hostcxx: clang-8 + os: ubuntu-20.04 python: - "3.12" config: @@ -67,13 +113,26 @@ jobs: cuda: "11.0" config: name: "Beltsoff" + # Exclude beltsoff builds with clang's + - cudacxx: + hostcxx: "clang-14" + config: + name: "Beltsoff" + - cudacxx: + hostcxx: "clang-8" + config: + name: "Beltsoff" + # Exclude vis with older clang + - cudacxx: + hostcxx: "clang-8" + VISUALISATION: "ON" # Exclude beltsoff vis builds to keep the matrix lighter. - config: name: "Beltsoff" VISUALISATION: "ON" # Name the job based on matrix/env options - name: "build (${{ matrix.cudacxx.cuda }}, ${{matrix.python}}, ${{ matrix.VISUALISATION }}, ${{ matrix.config.name }}, ${{ matrix.cudacxx.os }})" + name: "build (${{ matrix.cudacxx.cuda }}, ${{ matrix.cudacxx.hostcxx }}, ${{matrix.python}}, ${{ matrix.VISUALISATION }}, ${{ matrix.config.name }}, ${{ matrix.cudacxx.os }})" # Define job-wide env constants, and promote matrix elements to env constants for portable steps. env: @@ -113,6 +172,16 @@ jobs: echo "CXX=/usr/bin/g++-${gcc_version}" >> $GITHUB_ENV echo "CUDAHOSTCXX=/usr/bin/g++-${gcc_version}" >> $GITHUB_ENV + - name: Install/Select clang and clang++ + if: ${{ startsWith(env.HOSTCXX, 'clang-')}} + run: | + clang=${{ env.HOSTCXX }} + clang_version=${clang/clang-/} + sudo apt-get install -y clang-${clang_version} clang-tools-${clang_version} + echo "CC=/usr/bin/clang-${clang_version}" >> $GITHUB_ENV + echo "CXX=/usr/bin/clang++-${clang_version}" >> $GITHUB_ENV + echo "CUDAHOSTCXX=/usr/bin/clang++-${clang_version}" >> $GITHUB_ENV + - name: Select Python if: ${{ env.PYTHON != '' && env.FLAMEGPU_BUILD_PYTHON == 'ON' }} uses: actions/setup-python@v4 @@ -172,6 +241,7 @@ jobs: run: git config --global --add safe.directory $GITHUB_WORKSPACE - name: Configure cmake + id: configure run: > cmake . -B "${{ env.BUILD_DIR }}" -DCMAKE_BUILD_TYPE="${{ env.CONFIG }}" @@ -185,6 +255,14 @@ jobs: -DPYTHON3_EXACT_VERSION="${{ env.PYTHON }}" -DFLAMEGPU_VISUALISATION="${{ env.VISUALISATION }}" -DFLAMEGPU_ENABLE_NVTX="ON" + + - name: Log Configure Errors + if: ${{ success() || (failure() && steps.configure.conclusion == 'failure') }} + run: | + echo "${{ env.BUILD_DIR }}/CMakeFiles/CMakeOutput.log:" + cat ${{ env.BUILD_DIR }}/CMakeFiles/CMakeOutput.log || true + echo "${{ env.BUILD_DIR }}/CMakeFiles/CMakeError.log:" + cat ${{ env.BUILD_DIR }}/CMakeFiles/CMakeError.log || true - name: Build static library working-directory: ${{ env.BUILD_DIR }} diff --git a/README.md b/README.md index 10bd8cec3..7977b9816 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Building FLAME GPU has the following requirements. There are also optional depen + C++17 capable C++ compiler (host), compatible with the installed CUDA version + [Microsoft Visual Studio 2019 or 2022](https://visualstudio.microsoft.com/) (Windows) + *Note:* Visual Studio must be installed before the CUDA toolkit is installed. See the [CUDA installation guide for Windows](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html) for more information. - + [make](https://www.gnu.org/software/make/) and [GCC](https://gcc.gnu.org/) `>= 8.1` (Linux) + + [make](https://www.gnu.org/software/make/) and [GCC](https://gcc.gnu.org/) `>= 8.1` or [Clang](https://clang.llvm.org/) `>= 9` (Linux) + [git](https://git-scm.com/) Optionally: diff --git a/cmake/dependencies/flamegpu2-visualiser.cmake b/cmake/dependencies/flamegpu2-visualiser.cmake index 88f5a02c6..526d4d1db 100644 --- a/cmake/dependencies/flamegpu2-visualiser.cmake +++ b/cmake/dependencies/flamegpu2-visualiser.cmake @@ -7,7 +7,7 @@ include(FetchContent) cmake_policy(SET CMP0079 NEW) # Set the visualiser repo and tag to use unless overridden by the user. -set(DEFAULT_FLAMEGPU_VISUALISATION_GIT_VERSION "flamegpu-2.0.0-rc.1") +set(DEFAULT_FLAMEGPU_VISUALISATION_GIT_VERSION "b8e875208c1799916e8f2d826a05eb98ef8273ff") set(DEFAULT_FLAMEGPU_VISUALISATION_REPOSITORY "https://github.com/FLAMEGPU/FLAMEGPU2-visualiser.git") # Set a VISUSLAITION_ROOT cache entry so it is available in the GUI to override the location if required diff --git a/cmake/warnings.cmake b/cmake/warnings.cmake index cddae999f..2a5fff7d9 100644 --- a/cmake/warnings.cmake +++ b/cmake/warnings.cmake @@ -115,8 +115,18 @@ if(NOT COMMAND flamegpu_suppress_some_compiler_warnings) if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.6.0) target_compile_definitions(${SSCW_TARGET} PRIVATE "__CDPRT_SUPPRESS_SYNC_DEPRECATION_WARNING") endif() - else() - # Linux specific warning suppressions + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # Suppress unused function warnigns raised by clang on some vis headers + target_compile_options(${SSCW_TARGET} PRIVATE "$<$:SHELL:-Xcompiler -Wno-unused-function>") + target_compile_options(${SSCW_TARGET} PRIVATE "$<$:-Wno-unused-function>") + # Suppress unused-private-field warnings on Clang, which are falsely emitted in some cases where a private member is used in device code (i.e. ArrayMessage) + target_compile_options(${SSCW_TARGET} PRIVATE "$<$:SHELL:-Xcompiler -Wno-unused-private-field>") + target_compile_options(${SSCW_TARGET} PRIVATE "$<$:-Wno-unused-private-field>") + # Suppress unused-but-set-variable which triggers on some device code, clang 13+ + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) + target_compile_options(${SSCW_TARGET} PRIVATE "$<$:SHELL:-Xcompiler -Wno-unused-but-set-variable>") + target_compile_options(${SSCW_TARGET} PRIVATE "$<$:-Wno-unused-but-set-variable>") + endif() endif() # Generic OS/host compiler warning suppressions # Ensure NVCC outputs warning numbers diff --git a/include/flamegpu/detail/cuda.cuh b/include/flamegpu/detail/cuda.cuh index 2930416e9..be693d4df 100644 --- a/include/flamegpu/detail/cuda.cuh +++ b/include/flamegpu/detail/cuda.cuh @@ -3,6 +3,7 @@ #include #include +#include #include #include "flamegpu/exception/FLAMEGPUException.h" diff --git a/include/flamegpu/simulation/detail/CUDAAgent.h b/include/flamegpu/simulation/detail/CUDAAgent.h index 7a9971ffb..fb00ec61c 100644 --- a/include/flamegpu/simulation/detail/CUDAAgent.h +++ b/include/flamegpu/simulation/detail/CUDAAgent.h @@ -315,17 +315,17 @@ class CUDAAgent : public AgentInterface { * @param state_name Agent state to affect * @param d_vec The DeviceAgentVector to be stored */ - void setPopulationVec(const std::string& state_name, const std::shared_ptr& d_vec); + void setPopulationVec(const std::string& state_name, const std::shared_ptr& d_vec) override; /** * Used to allow HostAgentAPI to retrieve a stored DeviceAgentVector * @param state_name Agent state to affect */ - std::shared_ptr getPopulationVec(const std::string& state_name); + std::shared_ptr getPopulationVec(const std::string& state_name) override; /** * Used to allow HostAgentAPI to clear the stored DeviceAgentVector * Any changes will be synchronised first */ - void resetPopulationVecs(); + void resetPopulationVecs() override; private: /** diff --git a/src/flamegpu/model/AgentDescription.cpp b/src/flamegpu/model/AgentDescription.cpp index 942035f13..b68f3dc98 100644 --- a/src/flamegpu/model/AgentDescription.cpp +++ b/src/flamegpu/model/AgentDescription.cpp @@ -8,7 +8,7 @@ namespace flamegpu { CAgentDescription::CAgentDescription(std::shared_ptr data) : agent(std::move(data)) { } CAgentDescription::CAgentDescription(std::shared_ptr data) - : agent(std::move(std::const_pointer_cast(data))) { } + : agent(std::const_pointer_cast(data)) { } bool CAgentDescription::operator==(const CAgentDescription& rhs) const { return *this->agent == *rhs.agent; // Compare content is functionally the same diff --git a/src/flamegpu/model/AgentFunctionDescription.cpp b/src/flamegpu/model/AgentFunctionDescription.cpp index 74bbe8f94..c5774bfae 100644 --- a/src/flamegpu/model/AgentFunctionDescription.cpp +++ b/src/flamegpu/model/AgentFunctionDescription.cpp @@ -14,7 +14,7 @@ namespace flamegpu { CAgentFunctionDescription::CAgentFunctionDescription(std::shared_ptr data) : function(std::move(data)) { } CAgentFunctionDescription::CAgentFunctionDescription(std::shared_ptr data) - : function(std::move(std::const_pointer_cast(data))) { } + : function(std::const_pointer_cast(data)) { } bool CAgentFunctionDescription::operator==(const CAgentFunctionDescription& rhs) const { return *this->function == *rhs.function; // Compare content is functionally the same diff --git a/src/flamegpu/model/SubAgentDescription.cpp b/src/flamegpu/model/SubAgentDescription.cpp index 6991eefde..0bd75ca60 100644 --- a/src/flamegpu/model/SubAgentDescription.cpp +++ b/src/flamegpu/model/SubAgentDescription.cpp @@ -8,7 +8,7 @@ namespace flamegpu { CSubAgentDescription::CSubAgentDescription(std::shared_ptr data) : subagent(std::move(data)) { } CSubAgentDescription::CSubAgentDescription(std::shared_ptr data) - : subagent(std::move(std::const_pointer_cast(data))) { } + : subagent(std::const_pointer_cast(data)) { } bool CSubAgentDescription::operator==(const CSubAgentDescription& rhs) const { return *this->subagent == *rhs.subagent; // Compare content is functionally the same diff --git a/src/flamegpu/model/SubEnvironmentDescription.cpp b/src/flamegpu/model/SubEnvironmentDescription.cpp index c162bb2c6..86e8201ee 100644 --- a/src/flamegpu/model/SubEnvironmentDescription.cpp +++ b/src/flamegpu/model/SubEnvironmentDescription.cpp @@ -10,7 +10,7 @@ namespace flamegpu { CSubEnvironmentDescription::CSubEnvironmentDescription(std::shared_ptr data) : subenvironment(std::move(data)) { } CSubEnvironmentDescription::CSubEnvironmentDescription(std::shared_ptr data) - : subenvironment(std::move(std::const_pointer_cast(data))) { } + : subenvironment(std::const_pointer_cast(data)) { } bool CSubEnvironmentDescription::operator==(const CSubEnvironmentDescription& rhs) const { return *this->subenvironment == *rhs.subenvironment; // Compare content is functionally the same diff --git a/src/flamegpu/model/SubModelDescription.cpp b/src/flamegpu/model/SubModelDescription.cpp index f36510965..c37ce487f 100644 --- a/src/flamegpu/model/SubModelDescription.cpp +++ b/src/flamegpu/model/SubModelDescription.cpp @@ -12,7 +12,7 @@ namespace flamegpu { CSubModelDescription::CSubModelDescription(std::shared_ptr data) : submodel(std::move(data)) { } CSubModelDescription::CSubModelDescription(std::shared_ptr data) - : submodel(std::move(std::const_pointer_cast(data))) { } + : submodel(std::const_pointer_cast(data)) { } bool CSubModelDescription::operator==(const CSubModelDescription& rhs) const { return *this->submodel == *rhs.submodel; // Compare content is functionally the same diff --git a/src/flamegpu/runtime/messaging/MessageArray.cu b/src/flamegpu/runtime/messaging/MessageArray.cu index a2130ae8e..9cdc81856 100644 --- a/src/flamegpu/runtime/messaging/MessageArray.cu +++ b/src/flamegpu/runtime/messaging/MessageArray.cu @@ -100,9 +100,9 @@ void MessageArray::CUDAModelHandler::buildIndex(detail::CUDAScatter &scatter, un /// CDescription /// MessageArray::CDescription::CDescription(std::shared_ptr data) - : MessageBruteForce::CDescription(std::move(std::static_pointer_cast(data))) { } + : MessageBruteForce::CDescription(std::static_pointer_cast(data)) { } MessageArray::CDescription::CDescription(std::shared_ptr data) - : CDescription(std::move(std::const_pointer_cast(data))) { } + : CDescription(std::const_pointer_cast(data)) { } bool MessageArray::CDescription::operator==(const CDescription& rhs) const { return *this->message == *rhs.message; // Compare content is functionally the same diff --git a/src/flamegpu/runtime/messaging/MessageArray2D.cu b/src/flamegpu/runtime/messaging/MessageArray2D.cu index fed8a3191..086875df3 100644 --- a/src/flamegpu/runtime/messaging/MessageArray2D.cu +++ b/src/flamegpu/runtime/messaging/MessageArray2D.cu @@ -101,9 +101,9 @@ void MessageArray2D::CUDAModelHandler::buildIndex(detail::CUDAScatter &scatter, /// CDescription /// MessageArray2D::CDescription::CDescription(std::shared_ptr data) - : MessageBruteForce::CDescription(std::move(std::static_pointer_cast(data))) { } + : MessageBruteForce::CDescription(std::static_pointer_cast(data)) { } MessageArray2D::CDescription::CDescription(std::shared_ptr data) - : CDescription(std::move(std::const_pointer_cast(data))) { } + : CDescription(std::const_pointer_cast(data)) { } bool MessageArray2D::CDescription::operator==(const CDescription& rhs) const { return *this->message == *rhs.message; // Compare content is functionally the same diff --git a/src/flamegpu/runtime/messaging/MessageArray3D.cu b/src/flamegpu/runtime/messaging/MessageArray3D.cu index 8c9a227bc..c75236ab1 100644 --- a/src/flamegpu/runtime/messaging/MessageArray3D.cu +++ b/src/flamegpu/runtime/messaging/MessageArray3D.cu @@ -101,9 +101,9 @@ void MessageArray3D::CUDAModelHandler::buildIndex(detail::CUDAScatter &scatter, /// CDescription /// MessageArray3D::CDescription::CDescription(std::shared_ptr data) - : MessageBruteForce::CDescription(std::move(std::static_pointer_cast(data))) { } + : MessageBruteForce::CDescription(std::static_pointer_cast(data)) { } MessageArray3D::CDescription::CDescription(std::shared_ptr data) - : CDescription(std::move(std::const_pointer_cast(data))) { } + : CDescription(std::const_pointer_cast(data)) { } bool MessageArray3D::CDescription::operator==(const CDescription& rhs) const { return *this->message == *rhs.message; // Compare content is functionally the same diff --git a/src/flamegpu/runtime/messaging/MessageBruteForce.cu b/src/flamegpu/runtime/messaging/MessageBruteForce.cu index 38af3c213..dfbd384e7 100644 --- a/src/flamegpu/runtime/messaging/MessageBruteForce.cu +++ b/src/flamegpu/runtime/messaging/MessageBruteForce.cu @@ -96,7 +96,7 @@ std::type_index MessageBruteForce::Data::getType() const { return std::type_inde MessageBruteForce::CDescription::CDescription(std::shared_ptr data) : message(std::move(data)) { } MessageBruteForce::CDescription::CDescription(std::shared_ptr data) - : message(std::move(std::const_pointer_cast(data))) { } + : message(std::const_pointer_cast(data)) { } bool MessageBruteForce::CDescription::operator==(const CDescription& rhs) const { return *this->message == *rhs.message; // Compare content is functionally the same diff --git a/src/flamegpu/runtime/messaging/MessageBucket.cu b/src/flamegpu/runtime/messaging/MessageBucket.cu index 930504afc..47b3fde5f 100644 --- a/src/flamegpu/runtime/messaging/MessageBucket.cu +++ b/src/flamegpu/runtime/messaging/MessageBucket.cu @@ -160,9 +160,9 @@ void MessageBucket::CUDAModelHandler::resizeKeysVals(const unsigned int newSize) /// CDescription /// MessageBucket::CDescription::CDescription(std::shared_ptr data) - : MessageBruteForce::CDescription(std::move(std::static_pointer_cast(data))) { } + : MessageBruteForce::CDescription(std::static_pointer_cast(data)) { } MessageBucket::CDescription::CDescription(std::shared_ptr data) - : CDescription(std::move(std::const_pointer_cast(data))) { } + : CDescription(std::const_pointer_cast(data)) { } bool MessageBucket::CDescription::operator==(const CDescription& rhs) const { return *this->message == *rhs.message; // Compare content is functionally the same diff --git a/src/flamegpu/runtime/messaging/MessageSpatial2D.cu b/src/flamegpu/runtime/messaging/MessageSpatial2D.cu index 6059b8d90..6e97532fd 100644 --- a/src/flamegpu/runtime/messaging/MessageSpatial2D.cu +++ b/src/flamegpu/runtime/messaging/MessageSpatial2D.cu @@ -167,9 +167,9 @@ void MessageSpatial2D::CUDAModelHandler::resizeKeysVals(const unsigned int newSi /// CDescription /// MessageSpatial2D::CDescription::CDescription(std::shared_ptr data) - : MessageBruteForce::CDescription(std::move(std::static_pointer_cast(data))) { } + : MessageBruteForce::CDescription(std::static_pointer_cast(data)) { } MessageSpatial2D::CDescription::CDescription(std::shared_ptr data) - : CDescription(std::move(std::const_pointer_cast(data))) { } + : CDescription(std::const_pointer_cast(data)) { } bool MessageSpatial2D::CDescription::operator==(const CDescription& rhs) const { return *this->message == *rhs.message; // Compare content is functionally the same diff --git a/src/flamegpu/runtime/messaging/MessageSpatial3D.cu b/src/flamegpu/runtime/messaging/MessageSpatial3D.cu index a58524adf..e9fb02f59 100644 --- a/src/flamegpu/runtime/messaging/MessageSpatial3D.cu +++ b/src/flamegpu/runtime/messaging/MessageSpatial3D.cu @@ -166,9 +166,9 @@ void MessageSpatial3D::CUDAModelHandler::resizeKeysVals(const unsigned int newSi /// CDescription /// MessageSpatial3D::CDescription::CDescription(std::shared_ptr data) - : MessageSpatial2D::CDescription(std::move(std::static_pointer_cast(data))) { } + : MessageSpatial2D::CDescription(std::static_pointer_cast(data)) { } MessageSpatial3D::CDescription::CDescription(std::shared_ptr data) - : CDescription(std::move(std::const_pointer_cast(data))) { } + : CDescription(std::const_pointer_cast(data)) { } bool MessageSpatial3D::CDescription::operator==(const CDescription& rhs) const { return *this->message == *rhs.message; // Compare content is functionally the same diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt index 902071824..5800af7d7 100644 --- a/swig/CMakeLists.txt +++ b/swig/CMakeLists.txt @@ -74,7 +74,8 @@ if(NOT SWIG_FOUND) set(SWIG_EXECUTABLE "${swig_SOURCE_DIR}/swig.exe") set(SWIG_EXECUTABLE "${swig_SOURCE_DIR}/swig.exe" CACHE FILEPATH "Path to SWIG executable") endif() - else() + # If under linux, and using gcc download, extract, build and install swig + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # Under linux, download the .tar.gz, extract, build and install. # This must be done at configure time, as FindSwig requires the swig executable. # FetchContent allows download at configure time, but must use execute_process to run commands at configure time. @@ -147,6 +148,9 @@ if(NOT SWIG_FOUND) set(SWIG_EXECUTABLE "${swig_BINARY_DIR}/bin/swig") set(SWIG_EXECUTABLE "${swig_BINARY_DIR}/bin/swig" CACHE FILEPATH "Path to SWIG executable") endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR " Unable to build swig from source with some Clang versions.\n" + " Please install swig >= ${SWIG_MINIMUM_SUPPORTED_VERSION} manually.") endif() # Attempt to find swig again, but as REQUIRED. find_package(SWIG ${SWIG_MINIMUM_SUPPORTED_VERSION} REQUIRED) diff --git a/tests/test_cases/runtime/random/test_host_random.cu b/tests/test_cases/runtime/random/test_host_random.cu index f09e711be..f87aab0b6 100644 --- a/tests/test_cases/runtime/random/test_host_random.cu +++ b/tests/test_cases/runtime/random/test_host_random.cu @@ -125,8 +125,8 @@ FLAMEGPU_STEP_FUNCTION(step_uniform_int_range) { FLAMEGPU_STEP_FUNCTION(step_uniform_ulonglong_range) { for (auto &i : unsigned_longlong_out) ASSERT_NO_THROW(i = FLAMEGPU->random.uniform( - static_cast(UINT64_MAX * 0.25), - static_cast(UINT64_MAX * 0.75))); + static_cast(static_cast(UINT64_MAX) * 0.25), + static_cast(static_cast(UINT64_MAX) * 0.75))); } FLAMEGPU_STEP_FUNCTION(step_uniform_longlong_range) { for (auto &i : longlong_out) @@ -1048,8 +1048,8 @@ TEST_F(HostRandomTest, UniformULongLongRange) { ms->model.addStepFunction(step_uniform_ulonglong_range); ms->run(); for (auto &i : unsigned_longlong_out) { - EXPECT_GE(i, static_cast(UINT64_MAX*0.25)); - EXPECT_LE(i, static_cast(UINT64_MAX*0.75)); + EXPECT_GE(i, static_cast(static_cast(UINT64_MAX)*0.25)); + EXPECT_LE(i, static_cast(static_cast(UINT64_MAX)*0.75)); } } TEST_F(HostRandomTest, UniformLongLongRange) {