Skip to content
This repository has been archived by the owner on Apr 2, 2021. It is now read-only.

Rudimentary CMake support #29

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,23 @@ paket-files/
/TEST/FastNoiseSIMD Preview
/cellModel.skp
/cellModel.skb

# CMake
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
[Bb]uild

# VSCode
.vscode/

# FastNoiseSIMD
FastNoiseSIMD_config.h
30 changes: 30 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
sudo: required

# Enable C++ support
language: cpp

# Use Linux by default
os: linux

# Use Ubuntu 18.04 for GCC 7.4.0
dist: bionic

# Compiler selection
compiler: gcc

install:
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
- |
CMAKE_URL="https://cmake.org/files/v3.16/cmake-3.16.2-Linux-x86_64.tar.gz"
mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
- ../install-catch2.sh

# Build steps
script:
- cd ${TRAVIS_BUILD_DIR}
- mkdir build
- cd build
- cmake -DFN_COMPILE_AVX2=ON -DFN_COMPILE_AVX512=OFF -DBUILD_TESTING=ON .. && make
- ctest
158 changes: 158 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
cmake_minimum_required(VERSION 3.10)

# detect if FastNoiseSIMD is being bundled,
# disable testsuite in that case
if(NOT DEFINED PROJECT_NAME)
set(NOT_SUBPROJECT ON)
endif()

project(FastNoiseSIMD
VERSION 0.7.0
DESCRIPTION "C++ SIMD Noise Library"
LANGUAGES CXX
)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

if(BUILD_TESTING)
# Catch2 needed for testing
find_package(Catch2 CONFIG REQUIRED)
endif()

# Do stuff depending on the compiler
option(FN_SET_c0rp3n_CXX_FLAGS
"Set CMAKE_CXX_FLAGS[_DEBUG][_RELEASE] defaults from the c0rp3n/fastnoise-simd fork."
OFF)
if(FN_SET_c0rp3n_CXX_FLAGS)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "-W -Wall -Wextra -Wpedantic -Wunused-value -Wold-style-cast")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(CMAKE_CXX_FLAGS "/W4")
set(CMAKE_CXX_FLAGS_DEBUG "/O0 /ZI")
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /Ob2")
endif()
endif()

set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT FastNoiseSIMD)

if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm" OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
option(FN_COMPILE_NEON
"Only on arm or aarch64."
ON)
endif()

option(FN_COMPILE_SSE2 "" ON)

option(FN_COMPILE_SSE41 "" ON)

option(
FN_COMPILE_AVX2
"This does not break support for pre AVX CPUs, AVX code is only run if \
support is detected."
OFF
)

option(FN_COMPILE_AVX512 "Only the latest compilers will support this." OFF)

option(
FN_USE_FMA
"Using FMA instructions with AVX(51)2/NEON provides a small performance \
increase but can cause minute variations in noise output compared to other \
SIMD levels due to higher calculation precision."
ON
)

option(
FN_ALIGNED_SETS
"Using aligned sets of memory for float arrays allows faster storing of \
SIMD data."
ON
)

configure_file(
${CMAKE_CURRENT_LIST_DIR}/cmake/FastNoiseSIMD_config.h.in
${CMAKE_CURRENT_LIST_DIR}/include/FastNoiseSIMD/FastNoiseSIMD_config.h
@ONLY
)

add_library(FastNoiseSIMD STATIC
src/FastNoiseSIMD.cpp
src/FastNoiseSIMD_avx2.cpp
src/FastNoiseSIMD_avx512.cpp
src/FastNoiseSIMD_internal.cpp
src/FastNoiseSIMD_neon.cpp
src/FastNoiseSIMD_sse2.cpp
src/FastNoiseSIMD_sse41.cpp
)

set_target_properties(FastNoiseSIMD
PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
CMAKE_DEBUG_POSTFIX "d"
)

target_include_directories(FastNoiseSIMD PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

set(FN_CXX_FLAGS)
if(${FN_COMPILE_AVX512})
if(${MSVC})
list(APPEND FN_CXX_FLAGS "/arch:AVX512")
else()
list(APPEND FN_CXX_FLAGS "-march=skylake-avx512")
endif()
elseif(${FN_COMPILE_AVX2})
if(${MSVC})
list(APPEND FN_CXX_FLAGS "/arch:AVX2")
else()
list(APPEND FN_CXX_FLAGS "-march=core-avx2")
endif()
endif()

target_compile_options(FastNoiseSIMD PRIVATE "${FN_CXX_FLAGS}")

if(BUILD_TESTING)
include(test/tests.cmake)
endif()

# Only perform the installation steps when not being used as
# a subproject via `add_subdirectory`, or the destinations will break
if(NOT_SUBPROJECT)
set(FN_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/FastNoiseSIMD")

configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/cmake/FastNoiseSIMDConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/FastNoiseSIMDConfig.cmake
INSTALL_DESTINATION ${FN_CMAKE_CONFIG_DESTINATION}
)

# create and install an export set for FastNoiseSIMD target as FastNoiseSIMD
install(
TARGETS FastNoiseSIMD EXPORT FastNoiseSIMDTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)


install(EXPORT FastNoiseSIMDTargets DESTINATION ${FN_CMAKE_CONFIG_DESTINATION})

write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/FastNoiseSIMDConfigVersion.cmake"
COMPATIBILITY SameMajorVersion
)

install(TARGETS FastNoiseSIMD LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
install(DIRECTORY "include/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/FastNoiseSIMDConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/FastNoiseSIMDConfigVersion.cmake"
DESTINATION ${FN_CMAKE_CONFIG_DESTINATION}
)
endif()
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# FastNoise SIMD
FastNoise SIMD is the SIMD implementation of my noise library [FastNoise](https://github.com/Auburns/FastNoise). It aims to provide faster performance through the use of intrinsic(SIMD) CPU functions. Vectorisation of the code allows noise functions to process data in sets of 4/8/16 increasing performance by 700% in some cases (Simplex).

After releasing FastNoise I got in contact with the author of [FastNoise SIMD](https://github.com/jackmott/FastNoise-SIMD) (naming is coincidence) and was inspired to work with SIMD functions myself. Through his code and discussions with him I created my implementation with even more optimisation thanks to the removal of lookup tables.
<h1 align="center">
FastNoise SIMD
</h1>
<p align="center">
<a href="https://travis-ci.org/open-terra/terra">
<img src="https://img.shields.io/travis/c0rp3n/fastnoise-simd/master.svg?label=Travis&style=flat-square&logo=travis" alt="Travis Build Status">
</a>
<a href="https://ci.appveyor.com/project/C0RP3N/terra">
<img src="https://img.shields.io/appveyor/ci/C0RP3N/fastnoise-simd/master.svg?label=AppVeyor&style=flat-square&logo=appveyor" alt="Appveyor Build Status">
</a>
<br>
<strong>FastNoise SIMD is the SIMD implementation of <a href="https://github.com/Auburns/FastNoise">FastNoise</a>.</strong>
</p>

FastNoise SIMD aims to provide faster performance through the use of intrinsic(SIMD) CPU functions. Vectorisation of the code allows noise functions to process data in sets of 4/8/16 increasing performance by 700% in some cases (Simplex).

Inspired by [FastNoise SIMD](https://github.com/jackmott/FastNoise-SIMD) (naming is coincidence). FastNoise SIMD was created with even more optimisation thanks to the removal of lookup tables.

Runtime detection of highest supported instruction set ensures the fastest possible performance with only 1 compile needed. If no support is found it will fallback to standard types (float/int).

Expand Down Expand Up @@ -66,7 +79,7 @@ Timings below are x1000 ns to generate 32x32x32 points of noise on a single thre
| Cellular | 851 | 1283 | 2679 | 2959 | 2979 | 58125 |
| Cubic | 615 | 952 | 1970 | 3516 | 2979 | |

Comparision of fractals and sampling performance [here](https://github.com/Auburns/FastNoiseSIMD/wiki/In-depth-SIMD-level).
Comparison of fractals and sampling performance [here](https://github.com/Auburns/FastNoiseSIMD/wiki/In-depth-SIMD-level).

# Examples
### Cellular Noise
Expand Down
25 changes: 25 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: 1.0.{build}
image: Visual Studio 2019
configuration: Debug
clone_depth: 50
platform: x64

cache:
- c:\tools\vcpkg\installed

install:
- vcpkg install Catch2:x64-windows
- vcpkg integrate install

before_build:
- mkdir build
- cd build
- cmake -DFN_COMPILE_AVX2=ON -DFN_COMPILE_AVX512=OFF -DBUILD_TESTING=ON -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows -G "Visual Studio 16 2019" ..

build:
project: build/FastNoiseSIMD.sln
parallel: true
verbosity: minimal

test_script:
- ctest
7 changes: 7 additions & 0 deletions cmake/FastNoiseSIMD.pc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@

Name: FastNoiseSIMD
Description:
URL: https://github.com/c0rp3n/fastnoise-simd
Version: @FastNoiseSIMD_VERSION@
Cflags: -I${includedir}
6 changes: 6 additions & 0 deletions cmake/FastNoiseSIMDConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@PACKAGE_INIT@

# Provide path for scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")

include(${CMAKE_CURRENT_LIST_DIR}/FastNoiseSIMDTargets.cmake)
33 changes: 33 additions & 0 deletions cmake/FastNoiseSIMD_config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef FASTNOISE_SIMD_CONFIG_H
#define FASTNOISE_SIMD_CONFIG_H

#pragma once

#if defined(__arm__) || defined(__aarch64__)
#define FN_ARM
//#define FN_IOS
#cmakedefine FN_COMPILE_NEON
#else

// Comment out lines to not compile for certain instruction sets
#cmakedefine FN_COMPILE_SSE2
#cmakedefine FN_COMPILE_SSE41

// To compile AVX2 set C++ code generation to use /arch:AVX(2) on FastNoiseSIMD_avx2.cpp
// Note: This does not break support for pre AVX CPUs, AVX code is only run if support is detected
#cmakedefine FN_COMPILE_AVX2

// Only the latest compilers will support this
#cmakedefine FN_COMPILE_AVX512

// Using FMA instructions with AVX(51)2/NEON provides a small performance increase but can cause
// minute variations in noise output compared to other SIMD levels due to higher calculation precision
// Intel compiler will always generate FMA instructions, use /Qfma- or -no-fma to disable
#cmakedefine FN_USE_FMA
#endif

// Using aligned sets of memory for float arrays allows faster storing of SIMD data
// Comment out to allow unaligned float arrays to be used as sets
#cmakedefine FN_ALIGNED_SETS

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,7 @@
#ifndef FASTNOISE_SIMD_H
#define FASTNOISE_SIMD_H

#if defined(__arm__) || defined(__aarch64__)
#define FN_ARM
//#define FN_IOS
#define FN_COMPILE_NEON
#else

// Comment out lines to not compile for certain instruction sets
#define FN_COMPILE_SSE2
#define FN_COMPILE_SSE41

// To compile AVX2 set C++ code generation to use /arch:AVX(2) on FastNoiseSIMD_avx2.cpp
// Note: This does not break support for pre AVX CPUs, AVX code is only run if support is detected
#define FN_COMPILE_AVX2

// Only the latest compilers will support this
//#define FN_COMPILE_AVX512

// Using FMA instructions with AVX(51)2/NEON provides a small performance increase but can cause
// minute variations in noise output compared to other SIMD levels due to higher calculation precision
// Intel compiler will always generate FMA instructions, use /Qfma- or -no-fma to disable
#define FN_USE_FMA
#endif

// Using aligned sets of memory for float arrays allows faster storing of SIMD data
// Comment out to allow unaligned float arrays to be used as sets
#define FN_ALIGNED_SETS
#include "FastNoiseSIMD_config.h"

// SSE2/NEON support is guaranteed on 64bit CPUs so no fallback is needed
#if !(defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__) || defined(__aarch64__) || defined(FN_IOS)) || defined(_DEBUG)
Expand Down Expand Up @@ -102,7 +77,7 @@ class FastNoiseSIMD
{
public:

enum NoiseType { Value, ValueFractal, Perlin, PerlinFractal, Simplex, SimplexFractal, WhiteNoise, Cellular, Cubic, CubicFractal };
enum NoiseType { Value, ValueFractal, Perlin, PerlinFractal, Simplex, SimplexFractal, OpenSimplex2, OpenSimplex2Fractal, WhiteNoise, Cellular, Cubic, CubicFractal };
enum FractalType { FBM, Billow, RigidMulti };
enum PerturbType { None, Gradient, GradientFractal, Normalise, Gradient_Normalise, GradientFractal_Normalise };

Expand Down Expand Up @@ -279,6 +254,13 @@ class FastNoiseSIMD
virtual void FillSimplexSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;
virtual void FillSimplexFractalSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;

float* GetOpenSimplex2Set(int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f);
float* GetOpenSimplex2FractalSet(int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f);
virtual void FillOpenSimplex2Set(float* noiseSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) = 0;
virtual void FillOpenSimplex2FractalSet(float* noiseSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) = 0;
virtual void FillOpenSimplex2Set(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;
virtual void FillOpenSimplex2FractalSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;

float* GetCellularSet(int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f);
virtual void FillCellularSet(float* noiseSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) = 0;
virtual void FillCellularSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;
Expand Down
6 changes: 6 additions & 0 deletions install-catch2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
git clone https://github.com/catchorg/Catch2.git
mkdir Catch2/build
cd Catch2/build
cmake -DBUILD_TESTING=OFF ..
make && sudo make install
File renamed without changes.
Loading