1. Development Environment and CMake
In this chapter, you will compile and run C++ programs on your own computer, and learn to build and run MISO. We set up the tools on Ubuntu and Mac, then work through how compiling and linking work, how to use CMake, how to build MISO, run its tests and run its demos, and how to configure a project that uses MISO from your own program. You will learn C++ syntax starting from Chapter 2. For the programs in this chapter, you can save them as they are without worrying about the syntax.
Required tools
You can work through this course with a CPU alone. Even without a GPU, you can practice C++, use MISO’s arrays and parallel loops, decompose the domain with MPI, do the 1D heat conduction Practice, and run MISO’s demos.
Tool |
Role in this course |
|---|---|
C++ compiler ( |
Translates C++ source into machine code. MISO uses C++17 |
CMake |
Reads from |
MPI(Open MPI) |
A library for exchanging data among multiple processes, and the run command |
yaml-cpp |
A library that reads the configuration file |
git |
Gets MISO and pulls in updates |
Python and pymiso |
Read the simulation results and plot them. pymiso is a Python package included in MISO |
MPI (Message Passing Interface) is a standard for running the same program as multiple processes and sending and receiving data between them. MISO uses MPI to divide the computational domain and assign each part to a process. We explain it in detail in Chapter 8. You can practice by starting multiple processes on a single computer.
Setup on Ubuntu
The explanation is based on Ubuntu 24.04 LTS. Open a terminal and run the following.
sudo apt update
sudo apt install build-essential cmake git openmpi-bin libopenmpi-dev \
libyaml-cpp-dev python3 python3-venv
sudo is a command for installing software with administrator privileges. When you type your password, no characters appear on the screen. On a shared computer where you do not have permission to install software, use an equivalent environment prepared by the administrator.
Package |
What it provides |
|---|---|
|
The C++ compiler GCC ( |
|
CMake |
|
git |
|
The MPI run command ( |
|
The yaml-cpp headers and library |
|
Python, and the feature for creating Python virtual environments (described later) |
Check that the tools are installed.
g++ --version
cmake --version
mpiexec --version
If the versions of GCC, CMake, and Open MPI are displayed, you are ready.
Setup on Mac
Use a macOS version that Homebrew supports. The Homebrew installation location differs between Apple Silicon and Intel Macs, so below we look up the location for your environment with brew --prefix.
Command line developer tools
Open Terminal and run the following. Follow the on-screen instructions to finish the installation. If it says the tools are already installed, you can go on to the next step.
xcode-select --install
This installs Apple’s C++ compiler (Clang, with the command name clang++; it can also be called c++ or g++). MISO’s CPU version is built with this compiler.
Installing tools with Homebrew
Homebrew is a tool for installing and updating development software in bulk. If brew --version does not work, run the installation command listed on the Homebrew website, and also run the commands shown under Next steps at the end (this setting lets Terminal find brew). Then run the following.
brew install git cmake open-mpi yaml-cpp python
Check that the tools are installed.
clang++ --version
cmake --version
mpiexec --version
brew --prefix yaml-cpp
Libraries installed with Homebrew are under the location printed by brew --prefix (usually /opt/homebrew on Apple Silicon). CMake also searches this location, starting from the Homebrew bin that is in your PATH.
Getting MISO
Choose a working folder and get MISO. Below we use $HOME/miso-work, but you may use another location.
mkdir -p "$HOME/miso-work"
cd "$HOME/miso-work"
git clone https://github.com/is-isee/MISO.git
This creates $HOME/miso-work/MISO. In this course, we write /path/to/MISO for the folder where you placed MISO. When you type commands, replace it with the absolute path of your own location (a path starting with /; in this example, $HOME/miso-work/MISO).
The main contents of the MISO folder are as follows.
Location |
Contents |
|---|---|
|
MISO’s own header files ( |
|
Build settings for MISO itself and its unit tests |
|
Unit tests ( |
|
Demo problems. Each problem folder, such as |
|
Python package for reading simulation results |
|
Development rules and procedures |
Compiling and Linking
Building an executable with a compiler
As in Fortran, C++ source is converted into an executable by a compiler before it runs. Create a working folder and save the following content as hello.cpp.
mkdir -p "$HOME/miso-work/hello"
cd "$HOME/miso-work/hello"
#include <cmath>
#include <iostream>
int main() {
const double x = 2.0;
std::cout << "sqrt(" << x << ") = " << std::sqrt(x) << '\n';
return 0;
}
main is the function that serves as the entry point of the program, and corresponds to program in Fortran. Compile and run it (on a Mac, replace g++ with clang++).
g++ -std=c++17 -O2 hello.cpp -o hello
./hello
sqrt(2) = 1.41421
-std=c++17 specifies translating according to the C++17 standard, -O2 is the optimization level, and -o hello is the name of the executable.
The two stages of compiling and linking
The command above actually performs two stages together.
Compile: Translate each
.cppfile one by one and create object files (.o).Link: Combine the object files with the contents of the libraries you use to create the executable.
You can also run the stages separately. -c specifies “compile only.”
g++ -std=c++17 -O2 -c hello.cpp -o hello.o # compile: produces hello.o
g++ hello.o -o hello # link: produces hello
Here, “object file” is a term for the file produced by compiling. It has a different meaning from the object (instance) of a class.
Headers and #include
#include <cmath> is an instruction to read the contents of the header file cmath at that point. A header contains declarations of functions and types (information on how to use them, such as names and argument types). The compiler looks at the declarations to check whether the call to std::sqrt(x) is correct. This plays a role similar to checking arguments using the information of a module you use in Fortran.
Headers are searched for in set folders. The compiler knows where the standard library headers are, but for any other headers you add the search location with -I folder. For example, MISO headers are written like #include <miso/core.hpp>, so if you pass /path/to/MISO/miso/include with -I, miso/core.hpp is found.
A declaration alone does not contain the definition of a function (the body of the computation). When the definition is in a library, you specify that library at the link stage. Let us check with a short program that uses yaml-cpp. Save the following as yaml_check.cpp.
#include <iostream>
#include <yaml-cpp/yaml.h>
int main() {
const YAML::Node node = YAML::Load("grid: {i_size: 128}");
std::cout << "i_size = " << node["grid"]["i_size"].as<int>() << '\n';
return 0;
}
-lyaml-cpp specifies “use the library libyaml-cpp when linking.”
g++ -std=c++17 yaml_check.cpp -o yaml_check -lyaml-cpp
./yaml_check
i_size = 128
On a Mac, you tell the compiler the Homebrew locations with -I and -L (the folder in which to search for libraries).
clang++ -std=c++17 yaml_check.cpp -o yaml_check \
-I"$(brew --prefix)/include" -L"$(brew --prefix)/lib" -lyaml-cpp
MISO is a header-only library. All the computational components are written, with their definitions, in headers (miso/include/miso/*.hpp), so MISO itself does not need to be compiled into a library beforehand. However, for MPI and yaml-cpp, which MISO uses, you need to specify the header location and the libraries to link. For MPI, the command mpicxx provided by Open MPI adds the MPI header and library options and calls g++ (clang++ on a Mac). With mpicxx --showme, you can display the options it adds (for Open MPI).
Exercise 1-1
Build yaml_check.cpp without -lyaml-cpp. From the output, determine and explain whether the error occurred at the compile stage or the link stage.
g++ -std=c++17 yaml_check.cpp -o yaml_check
On Ubuntu, you see output like the following (excerpt).
yaml_check.cpp:(.text+0x34): undefined reference to `YAML::Load(char const*)'
undefined reference is an error at the link stage. The declaration is visible through #include <yaml-cpp/yaml.h>, so compiling succeeds. At link time, however, the library that contains the definition of YAML::Load was not specified, so the executable cannot be created. With Clang on a Mac, Undefined symbols for architecture ... is displayed. This is also a link error.
On the other hand, when a header cannot be found, the output looks like fatal error: yaml-cpp/yaml.h: No such file or directory. This is a compile-stage error; check the -I option or the package installation.
How CMake Works
The three stages: configure, build, run
As the number of sources and libraries grows, writing compile and link commands by hand becomes tedious. make, which is also used with Fortran, builds by following the procedure written in a Makefile. With CMake, you write what to build, which sources to use, and which libraries are needed in CMakeLists.txt, and it generates a Makefile or similar suited to that computer. CMake is a tool that assembles the build procedure; the translation of C++ itself is done by GCC or Clang.
Stage |
Command form |
What it does |
|---|---|---|
Configure and generate |
|
Reads |
Build |
|
Compiles and links using the generated procedure |
Run |
|
Runs the executable that was created |
-S . means “the source (CMakeLists.txt) is in the current folder,” and -B build means “put the generated files in build/.” Because generated files go in a folder separate from the source, you can always start over by deleting build/. The configuration result is recorded in build/CMakeCache.txt and is used by later builds as well.
A minimal CMakeLists.txt
In the folder where you saved hello.cpp and yaml_check.cpp, save the following CMakeLists.txt.
cmake_minimum_required(VERSION 3.18)
project(hello LANGUAGES CXX)
find_package(yaml-cpp REQUIRED)
add_executable(hello hello.cpp)
target_compile_features(hello PRIVATE cxx_std_17)
add_executable(yaml_check yaml_check.cpp)
target_compile_features(yaml_check PRIVATE cxx_std_17)
target_link_libraries(yaml_check PRIVATE yaml-cpp::yaml-cpp)
CMakeLists.txt is written in CMake’s own language, in the form command(argument ...).
Command |
Role |
|---|---|
|
Specifies the minimum required version of CMake |
|
Names the project and tells CMake that a C++ compiler is used |
|
Finds yaml-cpp and brings in how to use it (the header location and the library). |
|
Defines a target that builds the executable |
|
Tells CMake that this target requires C++17 or later |
|
Links yaml-cpp to |
A target is the name given to something the build creates, such as an executable or a library. Sources and settings are grouped by target, so a single CMakeLists.txt can build multiple programs separately.
yaml-cpp::yaml-cpp is a target provided by find_package, and it holds not only the library location but also information such as the header location. For this reason, target_link_libraries conveys not only the link options but also the -I and other options needed for compiling. A major advantage of using CMake is that you no longer need to list -I and -l by hand.
PRIVATE means the setting is used only by this target itself. If you use PUBLIC or INTERFACE on a library target, the settings are also passed on to the targets that use that library (MISO uses this mechanism). It is unrelated to private and public of C++ classes (Chapter 4).
Configure, build, and run.
cmake -S . -B build
cmake --build build --parallel 4
./build/hello
./build/yaml_check
--parallel 4 specifies compiling up to four files at the same time, and has nothing to do with the number of processes used when running a simulation. With cmake --build build --verbose, the compiler commands that CMake actually called are displayed.
Build type
The build type is a setting that selects, as a set, how optimization and debug information are applied. You pass it with -D at the configure stage.
cmake -S . -B build_debug -DCMAKE_BUILD_TYPE=Debug
Type |
Main options passed to GCC and Clang |
When to use |
|---|---|---|
|
|
Running simulations. Prioritizes speed |
|
|
Investigating bugs. Disables optimization so that you can inspect variables in a debugger |
-DNAME=VALUE is the way to pass a value to a CMake setting (a cache variable). If you specify no build type, a CMake project such as hello above is built without optimization options. The CMakeLists.txt of MISO and the demos are written to select Release when nothing is specified.
When -DNDEBUG is given, C++ assert (a check that stops the program if a condition does not hold) is removed. MISO’s default is Release, so checks by assert do not work in the default build.
When you change the build type or the compiler, use a separate build folder such as build_debug. If you change the settings in the same folder, the previous settings remain in CMakeCache.txt and may get mixed in.
Building after changing the source
After editing the source, run cmake --build build again. Only the changed files and the files that #include them are translated again. If you change CMakeLists.txt, CMake also automatically reconfigures at the next cmake --build. You never edit the generated build/Makefile by hand.
Building MISO and Running the Unit Tests
Contents of miso/CMakeLists.txt
The build settings for MISO itself are in miso/CMakeLists.txt. Here are the main parts (some are omitted for explanation).
# CUDA
option(MISO_USE_CUDA "Enable CUDA support" OFF)
# MISO as a header-only library
add_library(MISO INTERFACE)
add_library(MISO::MISO ALIAS MISO)
target_include_directories(MISO INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
# MPI
find_package(MPI REQUIRED)
target_link_libraries(MISO INTERFACE MPI::MPI_CXX)
# yaml-cpp
find_package(yaml-cpp QUIET)
if(NOT yaml-cpp_FOUND)
message(STATUS "yaml-cpp not found; fetching with FetchContent")
include(FetchContent)
FetchContent_Declare(
yaml-cpp
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
GIT_TAG 0.8.0)
FetchContent_MakeAvailable(yaml-cpp)
endif(NOT yaml-cpp_FOUND)
target_link_libraries(MISO INTERFACE yaml-cpp::yaml-cpp)
# Unit tests
option(ENABLE_TESTING "Enable Testing" ON)
if(ENABLE_TESTING)
enable_testing()
add_subdirectory(tests)
endif(ENABLE_TESTING)
Setting |
Meaning |
|---|---|
|
Creates a library target |
|
Gives |
|
Passes |
|
Also passes the MPI headers and library to targets that use |
|
If yaml-cpp is on the computer, it is used; if not, it is fetched from GitHub and built together |
|
A switch for whether to use a GPU (CUDA). The default is not to use one |
|
A switch for whether to also build the unit tests. The default is to build them |
INTERFACE specifies “pass this to the targets that use MISO::MISO.” For this reason, by writing just one line, target_link_libraries(my_program PRIVATE MISO::MISO), the MISO header location, MPI, and yaml-cpp settings are all passed on to your program.
FetchContent is a mechanism that fetches the needed sources from the internet at the CMake configure stage. It is used when yaml-cpp is not installed, and when fetching doctest for the unit tests (explained in Testing and Comparing Results), so the first configuration requires an internet connection.
Building and running the tests
You may create the build folder outside the MISO folder. Here we use $HOME/miso-work/build_miso.
cd "$HOME/miso-work"
cmake -S /path/to/MISO/miso -B build_miso -DMISO_USE_CUDA=OFF
cmake --build build_miso --parallel 4
For -S, pass the folder that contains miso/CMakeLists.txt (/path/to/MISO/miso). Many test executables are built, which can take several minutes.
When the build finishes, run the unit tests. A unit test is a program that checks, component by component (arrays, parallel loops, and so on), whether the code behaves as expected. ctest is a tool that runs the tests registered with CMake all at once.
cd build_miso
OMPI_MCA_btl_vader_single_copy_mechanism=none \
OMPI_MCA_rmaps_base_oversubscribe=yes \
ctest --output-on-failure
The run succeeded if the following is displayed at the end (the number of tests depends on the MISO version).
100% tests passed, 0 tests failed out of 15
The first two lines are environment variables that change the behavior of Open MPI only for this command. Some of the tests run with two MPI processes, so these settings let them run even on computers or containers with few CPU cores. The meaning, how to read the tests, and how to run only selected tests are covered in Testing and Comparing Results.
Running a Demo and Reading Its Output
Building and running a demo
MISO’s demo/ contains a demo for each problem. We run the 2D Orszag-Tang vortex (demo/mhd2d_vortex). The demo’s CMakeLists.txt brings in MISO itself (../../miso) and builds an executable from src/main.cpp.
cd /path/to/MISO/demo/mhd2d_vortex
cmake -S . -B build -DUSE_CUDA=OFF
cmake --build build --parallel 4
./app_run.sh
In the demos, the GPU switch is passed with the name USE_CUDA (different from MISO_USE_CUDA in MISO itself). app_run.sh is a script that reads the Open MPI environment variables from demo/shared/openmpi_config.env and runs the simulation with two processes. It prints the command it runs before starting the computation.
+ mpiexec -np 2 /path/to/MISO/demo/mhd2d_vortex/build/mhd2d_vortex --config=/path/to/MISO/demo/mhd2d_vortex/config.yaml
time = 0.00; n_step = 0; n_output = 0
time = 0.01; n_step = 4; n_output = 1
...
time = 0.80; n_step = 354; n_output = 80
The simulation conditions are written in demo/mhd2d_vortex/config.yaml. You can change the number of grid points, the end time (time.tend), the output interval (time.dt_output), and the number of MPI divisions (mpi.x_procs and so on).
Output files
The results are written to data/ in the same folder as config.yaml (you can change this with io.save_dir in config.yaml).
File |
Contents |
|---|---|
|
The configuration actually used, with default values filled in |
|
Coordinates of the whole grid |
|
Position of the region each process (rank) is responsible for |
|
Time, output number, and step number of each output |
|
MHD variables of the region each process is responsible for (nine, including density, velocity, and magnetic field) |
mhd.*.bin are binary files split by process. Because of io.continue: true in config.yaml, if data/ contains results, the simulation continues from them. To start over from the beginning, delete build/, data/, and figs/ with ./app_clean.sh, then build and run again.
Reading with pymiso
pymiso is a Python package that joins the per-process files and reads them as arrays for the whole domain. Install the Python packages in a virtual environment for MISO (an independent Python environment that uses only the packages installed in it).
python3 -m venv "$HOME/miso-work/venv"
source "$HOME/miso-work/venv/bin/activate"
cd /path/to/MISO
pip install -e ".[viz]"
source .../activate is a command that makes this terminal use the Python of the virtual environment. Run it again whenever you open a new terminal. pip install -e ".[viz]" installs pymiso, which is in the MISO folder, and matplotlib and other packages for plotting.
The demo has a script plot_data.py that draws figures.
cd /path/to/MISO/demo/mhd2d_vortex
python plot_data.py
The density plot for each time (such as py_00000000.png) is saved in figs/. Inside plot_data.py, the results are read as follows (excerpt from demo/mhd2d_vortex/plot_data.py; ... marks omitted parts).
d = pymiso.Data(data_dir=this_dir / "data")
...
d.load(n)
ax.pcolormesh(d.x, d.y, d.ro.T, shading="auto", vmin=0.2, vmax=2.5, cmap="inferno")
Pass the location of data/ to pymiso.Data, and read the result for output number n with d.load(n). d.ro is the density, and d.x and d.y are the coordinate NumPy arrays. Other demos, how to change the settings, and how to run the GPU version are covered in the MISO_docs Quick Start.
Using MISO from Your Own Program
In the Practice of Chapter 7 and Chapter 10, you create your own folder outside the MISO folder and write programs that use MISO components. Here we create the minimal CMake configuration for that and check that MISO works.
What to create
Create a working folder outside the MISO folder.
mkdir -p "$HOME/miso-work/miso_check"
cd "$HOME/miso-work/miso_check"
In this folder, save the check program main.cpp and CMakeLists.txt.
main.cpp is a program that starts MPI, puts 0 to 99 into a MISO array, and computes the sum. miso::Array1D, miso::for_each, miso::reduce, and MISO_LAMBDA are explained in Chapter 7. For now, save it as it is.
#include <iostream>
#include <miso/core.hpp>
int main(int argc, char **argv) {
miso::Env env(argc, argv); // starts MPI, and cleans up at the end
const int n = 100;
miso::Array1D<float, miso::backend::Host> a(n);
auto av = a.view();
miso::for_each(miso::backend::Host{}, miso::Range1D{0, n},
MISO_LAMBDA(int i) { av[i] = float(i); });
const float sum = miso::reduce(
miso::backend::Host{}, miso::Range1D{0, n}, 0.0f,
MISO_LAMBDA(int i) { return av[i]; },
MISO_LAMBDA(float x, float y) { return x + y; });
if (miso::mpi::is_root()) {
std::cout << "MPI processes: " << miso::mpi::size() << '\n'
<< "sum of 0..99: " << sum << " (expected 4950)\n";
}
return 0;
}
#include <miso/core.hpp> is a header (miso/include/miso/core.hpp) that reads in MISO’s common components, such as arrays, parallel loops, and the MPI environment, all at once.
CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(miso_check LANGUAGES CXX)
set(MISO_DIR "" CACHE PATH "Root of the MISO repository")
if(NOT EXISTS "${MISO_DIR}/miso/CMakeLists.txt")
message(FATAL_ERROR "Set -DMISO_DIR=/path/to/MISO")
endif()
set(ENABLE_TESTING OFF CACHE BOOL "Build the unit tests of MISO")
add_subdirectory("${MISO_DIR}/miso" miso)
add_executable(miso_check main.cpp)
target_compile_features(miso_check PRIVATE cxx_std_17)
target_link_libraries(miso_check PRIVATE MISO::MISO)
Setting |
Role |
|---|---|
|
Provides a setting |
|
If |
|
Prevents MISO’s unit tests from being built. Write it before |
|
Reads MISO’s |
|
Builds the executable |
|
Passes the MISO header location, MPI, and yaml-cpp settings together to |
add_subdirectory is a command that reads the CMakeLists.txt of another folder as part of your own project. When the MISO folder is outside the project, the second argument (the location for generated files) is required.
We set ENABLE_TESTING to OFF so that only your own program is built quickly. Run MISO’s unit tests in a standalone MISO build, as in the previous section. option(ENABLE_TESTING ...) uses the existing value if a setting of the same name already exists, so putting OFF first removes the tests.
If you do not specify a build type, MISO’s CMakeLists.txt selects Release.
Building and running
Configure by replacing /path/to/MISO with the absolute path of the location where you placed MISO.
cmake -S . -B build -DMISO_DIR=/path/to/MISO
cmake --build build --parallel 4
mpiexec -np 2 ./build/miso_check
mpiexec -np 2 is a command that starts the same program as two processes. You are ready if the following is displayed.
MPI processes: 2
sum of 0..99: 4950 (expected 4950)
Both processes perform the same computation, but only one process (rank 0) prints the output.
The demos’ CMakeLists.txt brings in MISO with FetchContent_Declare(MISO SOURCE_DIR ...) and FetchContent_MakeAvailable(MISO) instead of add_subdirectory. When you point to a local folder, both read miso/CMakeLists.txt and create MISO::MISO, so they are the same in that respect.
Exercise 1-2
Configure in a new build folder build_nodir without -DMISO_DIR=.... Check the message that is displayed, and explain at which stage (configure, build, or run) it stopped and why, relating it to lines of CMakeLists.txt.
cmake -S . -B build_nodir
CMake Error at CMakeLists.txt:6 (message):
Set -DMISO_DIR=/path/to/MISO
It stops at the configure stage. The value of MISO_DIR stays empty, so "${MISO_DIR}/miso/CMakeLists.txt" becomes /miso/CMakeLists.txt, and the condition of if(NOT EXISTS ...) holds. The message(FATAL_ERROR ...) inside it prints an explanation and stops the configuration. Without this check, add_subdirectory would give a confusing error saying the folder does not exist. After checking, you may delete build_nodir.
Exercise 1-3
Build miso_check with the Debug build type in a separate build folder named build_debug. Display the list of settings with cmake -L -N build_debug, and check the values of CMAKE_BUILD_TYPE, MISO_DIR, ENABLE_TESTING, and MISO_USE_CUDA.
cmake -S . -B build_debug -DMISO_DIR=/path/to/MISO -DCMAKE_BUILD_TYPE=Debug
cmake --build build_debug --parallel 4
cmake -L -N build_debug | grep -E "BUILD_TYPE|MISO|ENABLE_TESTING"
CMAKE_BUILD_TYPE:STRING=Debug
ENABLE_TESTING:BOOL=OFF
MISO_DIR:PATH=/path/to/MISO
MISO_USE_CUDA:BOOL=OFF
-L displays the list of settings, and -N means to only read CMakeCache.txt without reconfiguring. MISO_USE_CUDA is a setting created by the option on the MISO side with the default value OFF. With cmake --build build_debug --verbose, you can also confirm that -g is added to the compile command and -O3 is not. build (Release) and build_debug (Debug) are separate folders, so their settings do not get mixed.
Correspondence with compiling by hand
Let us compare what CMake does with commands written by hand. On Ubuntu, you can also build miso_check with the following command.
mpicxx -std=c++17 -O2 -I/path/to/MISO/miso/include main.cpp -o miso_check_manual -lyaml-cpp
mpicxx adds the MPI options, -I gives the location of the MISO headers, and -lyaml-cpp specifies yaml-cpp. When you link MISO::MISO, CMake specifies all of these together. Because we do not have to change CMakeLists.txt even for GPU builds or differences between computers, this course uses CMake.
When Things Go Wrong
Check from the first error onward. Build after the configuration succeeds, and run after the build succeeds.
Output or symptom |
What to check |
|---|---|
|
Check whether |
A fetch failure after |
yaml-cpp was not found, and CMake is trying to fetch it from the internet. Install yaml-cpp ( |
Fetching doctest fails when configuring the unit tests |
doctest is always fetched from the internet. Check your connection |
|
Check whether you link |
|
When compiling by hand, use |
|
yaml-cpp is not linked. When compiling by hand, add |
|
You are trying to start more processes than the number of CPU cores. For a simple check, use |
|
Use |
The previous compiler is used even though you changed the compiler |
The previous settings remain in |
When You Start Using GPUs
MISO can also be built as a CUDA version that computes on NVIDIA GPUs. Pass -DMISO_USE_CUDA=ON for MISO itself, or -DUSE_CUDA=ON for the demos, at configure time. You need a CUDA development environment (the CUDA Toolkit and a matching driver), and it does not run on Mac GPUs. We explain the GPU build and the settings for running your own program on a GPU in Chapter 9.
What to Read Next
When you are ready, go on to Chapter 2: Variables, Functions, and Control Flow. The folder of miso_check that you created in this chapter and the form of its CMakeLists.txt will be used in the Practice of Chapter 7 and Chapter 10.