Skip to content
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
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ SET (PACKAGE_INC_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/inc)
option (USE_LIBFTDI "USE_LIBFTDI" OFF)
option (USE_OPENMP "USE_OPENMP" OFF)
option (WARNINGS_AS_ERRORS "WARNINGS_AS_ERRORS" OFF)

if (APPLE AND USE_OPENMP)
if (NOT DEFINED OpenMP_ROOT AND NOT DEFINED ENV{OpenMP_ROOT})
if (EXISTS "/opt/homebrew/opt/libomp")
set (OpenMP_ROOT "/opt/homebrew/opt/libomp")
elseif (EXISTS "/usr/local/opt/libomp")
set (OpenMP_ROOT "/usr/local/opt/libomp")
endif ()
endif ()
endif ()

option (BUILD_OYMOTION_SDK "BUILD_OYMOTION_SDK" OFF)
option (BUILD_SYNCHRONI_SDK "BUILD_SYNCHRONI_SDK" ON)
option (BUILD_BLUETOOTH "BUILD_BLUETOOTH" OFF)
Expand Down
30 changes: 30 additions & 0 deletions docs/BuildBrainFlow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,36 @@ MacOS
python3 build.py --help


OpenMP Acceleration
~~~~~~~~~~~~~~~~~~~~

BrainFlow supports multi-core parallel execution via OpenMP for intensive data handling routines, including multi-channel signal filtering, wavelet denoising, and band power calculations across channels.

To build BrainFlow with OpenMP support, first ensure that the OpenMP development package is available on your system:

- **Linux:** Install the OpenMP development headers using your package manager, e.g. :code:`sudo apt-get install libomp-dev` on Debian/Ubuntu or :code:`sudo dnf install libgomp` on Fedora/RHEL.
- **MacOS:** Install OpenMP via Homebrew: :code:`brew install libomp`. BrainFlow's build configuration automatically discovers Homebrew's :code:`libomp` installation.
- **Windows:** OpenMP is included with MSVC in Visual Studio; no additional installation is needed.

.. compound::

Using :code:`build.py`: ::

python3 tools/build.py --use-openmp

.. compound::

Using CMake directly: ::

cmake -B build -DUSE_OPENMP=ON
cmake --build build --config Release

.. note::

On Apple Silicon macOS, Homebrew's :code:`libomp` is built for the native architecture (:code:`arm64`). When :code:`--use-openmp` is specified without an explicit :code:`--cmake-osx-architectures`, :code:`tools/build.py` automatically configures the build for your machine's native architecture. If invoking CMake directly on Apple Silicon, pass :code:`-DCMAKE_OSX_ARCHITECTURES=arm64` (or :code:`x86_64` on Intel Macs).



Android
---------

Expand Down
2 changes: 2 additions & 0 deletions src/data_handler/build.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

include (${CMAKE_CURRENT_SOURCE_DIR}/third_party/DSPFilters/build.cmake)
include (${CMAKE_CURRENT_SOURCE_DIR}/third_party/wavelib/build.cmake)
include (${CMAKE_CURRENT_SOURCE_DIR}/third_party/kissfft/build.cmake)


if (CMAKE_SIZEOF_VOID_P EQUAL 8)
SET (DATA_HANDLER_NAME "DataHandler")
if (APPLE)
Expand Down
16 changes: 12 additions & 4 deletions third_party/kissfft/build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,13 @@ endif()
#

if(KISSFFT_OPENMP)
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
find_package(OpenMP)
if(TARGET OpenMP::OpenMP_C)
target_link_libraries(kissfft PRIVATE OpenMP::OpenMP_C)
elseif(OpenMP_C_FOUND)
target_compile_options(kissfft PRIVATE ${OpenMP_C_FLAGS})
target_link_libraries(kissfft PRIVATE ${OpenMP_C_LIBRARIES})
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang|MSVC")
if (NOT MSVC)
target_compile_options(kissfft PRIVATE -fopenmp)
if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
Expand All @@ -159,11 +165,11 @@ if(KISSFFT_OPENMP)
target_link_options(kissfft PRIVATE "/openmp")
endif()
endif()
set(KISSFFT_EXPORT_SUFFIX "-openmp")
set(KISSFFT_OUTPUT_NAME "kissfft-${KISSFFT_DATATYPE}-openmp")
else()
message(FATAL_ERROR "Don't know how to enable OpenMP for this compiler")
endif()
set(KISSFFT_EXPORT_SUFFIX "-openmp")
set(KISSFFT_OUTPUT_NAME "kissfft-${KISSFFT_DATATYPE}-openmp")
endif()

#
Expand Down Expand Up @@ -227,7 +233,9 @@ function(add_kissfft_executable NAME)
set_target_properties(${NAME} PROPERTIES
OUTPUT_NAME "${NAME}-${KISSFFT_DATATYPE}")
else()
if (NOT MSVC)
if(TARGET OpenMP::OpenMP_C)
target_link_libraries(${NAME} PRIVATE OpenMP::OpenMP_C)
elseif (NOT MSVC)
target_compile_options(${NAME} PRIVATE -fopenmp)
if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
target_link_libraries(${NAME} PRIVATE "-fopenmp")
Expand Down
30 changes: 19 additions & 11 deletions tools/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,8 @@ def prepare_args():
'--cmake-system-version', type=str,
help='system version for win', required=False)
elif platform.system() == 'Darwin':
macos_ver = platform.mac_ver()[0]
versions = [int(x) for x in macos_ver.split('.')]
if versions[0] >= 11:
parser.add_argument('--cmake-osx-architectures', type=str,
help='archs for osx', required=False, default='arm64;x86_64')
else:
parser.add_argument('--cmake-osx-architectures',
type=str, help='archs for osx', required=False)
parser.add_argument('--cmake-osx-architectures', type=str,
help='archs for osx', required=False, default=None)
parser.add_argument('--cmake-osx-deployment-target', type=str,
help='min supported version of osx', required=False, default='10.15')
parser.add_argument('--use-libftdi', action='store_true')
Expand Down Expand Up @@ -260,9 +254,23 @@ def config(args):
cmd_config.append('-DUSE_OPENMP=ON')
if hasattr(args, 'oymotion') and args.oymotion:
cmd_config.append('-DBUILD_OYMOTION_SDK=ON')
if hasattr(args, 'cmake_osx_architectures') and args.cmake_osx_architectures:
cmd_config.append('-DCMAKE_OSX_ARCHITECTURES=%s' %
args.cmake_osx_architectures)
if hasattr(args, 'cmake_osx_architectures'):
osx_arch = args.cmake_osx_architectures
if osx_arch is None:
if args.use_openmp:
print('Building with OpenMP on macOS: defaulting architecture to native %s because Homebrew libomp is single-architecture.' % platform.machine())
osx_arch = platform.machine()
else:
macos_ver = platform.mac_ver()[0]
if macos_ver:
try:
major_ver = int(macos_ver.split('.')[0])
if major_ver >= 11:
osx_arch = 'arm64;x86_64'
except ValueError:
pass
if osx_arch:
cmd_config.append('-DCMAKE_OSX_ARCHITECTURES=%s' % osx_arch)
if hasattr(args, 'cmake_osx_deployment_target') and args.cmake_osx_deployment_target:
cmd_config.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=%s' %
args.cmake_osx_deployment_target)
Expand Down
Loading