0

I have a C/C++ package where I make use of some GPU acceleration methods, CUDA for Nvidia hardware and using OpenCL for non-Nvidia hardware. I also have SIMD functions specific to Intel CPUs and some specific for ARM. I want to be able to install these different acceleration methods based on the install flags passed in when building with CMake but I am unsure how to also structure my header file.

The two things I am trying to tackle with preprocessor directives and the optional installation piece with CMake is:

  1. Check if the headers were installed from the optional CMake flags (is this possible?)
  2. Check if the given host machine matches one of the compatible platforms I wrote code for (OpenCL compatible platforms and CUDA) AND include the optional header files based on that

I am thinking of the header file for this project looking something like this but am unsure of the directives themselves

#ifdef Intel/Apple... OpenCL compatible GPUs
    // include GPU code that uses OpenCL
#endif

#ifdef Nvidia GPU
    // include GPU code that uses CUDA
#endif

#ifdef Intel CPUs
   // include SIMD code that uses Intel intrinsics 
#endif

#ifdef ARM CPUs
   // include SIMD code that uses ARM intrinsics
#endif

Is this the proper way to go about creating code to run on multiple platforms? I am curious how projects do something similar like OpenCV being compatible with CUDA and OpenCL.

aaries
  • 111
  • 1
  • 6
  • 2
    I would abstract it out to separate source files, and let the build-system decide which source file to build (depending on target). Or if you want to decide at runtime then create classes that can be instantiated depending on the target the program is currently running on, possibly loading libraries dynamically. – Some programmer dude Apr 24 '23 at 06:07
  • 1
    It might be meaningful to provide one common interface for all of these implementations. Then I'd pack this in a header with all its types and functions and provide different implementations in separate source files as @Someprogrammerdude suggested already. If there's still functionality shared between all of them then keep that in yet another separate source file that will be part of all of these separate builds. – Aconcagua Apr 24 '23 at 07:25
  • `Is this the proper way to go about creating code to run on multiple platforms?` ? Yes. Your question is too broad, there are multiple questions. Yes, you have to write it that way. `how projects do something similar like OpenCV` So have you browsed the source code of projects similar to OpenCV? Have you browsed the source code of OpenCV to know the answer? – KamilCuk Apr 24 '23 at 08:43
  • 1
    Do not tag C for C++ questions. – Eric Postpischil Apr 24 '23 at 09:02
  • @EricPostpischil To my knowledge preprocessing directives are synonymous between C and C++. – aaries Apr 24 '23 at 09:03
  • @aaries: That is not a reason to tag a C++ question as C. If people want to answer questions about using preprocessor questions in C++, they can follow the C++ tag and/or other relevant tags. By tagging C, you consume some time and attention of people who have chosen to follow the C tag but not others. Do not do that; respect other people’s time and choices. It is policy not to tag both C and C++ except for questions that involve differences or interactions between the two languages. Tagging both may result in votes down. – Eric Postpischil Apr 24 '23 at 09:11

1 Answers1

0

Check if the headers were installed from the optional CMake flags (is this possible?)

Compile a sample program with that header, and check if it compiles. https://cmake.org/cmake/help/latest/module/CheckIncludeFile.html or https://cmake.org/cmake/help/latest/command/try_compile.html

Check if the given host machine matches one of the compatible platforms I wrote code for (OpenCL compatible platforms and CUDA)

How to identify platform/compiler from preprocessor macros? and https://github.com/Kitware/CMake/blob/master/Modules/CMakePlatformId.h.in etc.

s this the proper way to go about creating code to run on multiple platforms?

There is no "proper" way. It is one of the ways, and it's fine.

how projects do something similar like OpenCV being compatible with CUDA and OpenCL.

OpenCV is an open source project. https://github.com/opencv/opencv/blob/a4a9f56c8bbb11fd4a017d3c1819b89f43160474/cmake/OpenCVDetectCUDA.cmake#L82 https://github.com/opencv/opencv/blob/a4a9f56c8bbb11fd4a017d3c1819b89f43160474/modules/core/src/matrix_wrap.cpp#L319 etc.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111