Line data Source code
1 0 : \cond NEVER 2 : Distributed under the MIT License. 3 : See LICENSE.txt for details. 4 : \endcond 5 : # Creating Executables {#dev_guide_creating_executables} 6 : 7 : \tableofcontents 8 : 9 : There are several different types of executables that can be built: 10 : - An executable that uses Charm++ to run in parallel, 11 : e.g. `Executables/ParallelInfo` 12 : - An executable that does not use Charm++, does not run in parallel, and 13 : supplies its own `main`, e.g. `Executables/Examples/HelloWorldNoCharm` 14 : - An executable that uses Charm++ to run in parallel but supplies its own `main` 15 : - An executable that uses custom compilation or linking flags, 16 : e.g. `DebugPreprocessor` 17 : - Executables used for evolutions or elliptic solves 18 : 19 : ### Executable Using Charm++ for Parallelization 20 : 21 : \ref tutorial_minimal_parallel_executable tutorial describes how to 22 : add a new parallel executable. 23 : 24 : Another simple example of an executable using Charm++ for 25 : parallelization is in `src/Executables/Examples/HelloWorld`. In this 26 : example, the only additional phase (besides `Initialization` and 27 : `Exit`) is `Execute`, and the phases are executed in order. 28 : `SingletonHelloWorld` defines a single component `HelloWorld` 29 : 30 : \snippet SingletonHelloWorld.cpp executable_example_singleton 31 : 32 : which specifies via the `chare_type` type alias that it is a singleton 33 : parallel component which means that only one such object will exist 34 : across all processors used by the executable. Each component must 35 : define the static function `execute_next_phase` which is executed 36 : during the phases (other than `Initialization` and `Exit`) defined in 37 : the metavariables struct. In `SingletonHelloWorld`, the 38 : `PrintMessage` action is called during the `Execute` phase. 39 : 40 : \snippet SingletonHelloWorld.cpp executable_example_action 41 : 42 : The `PrintMessage` action is executed on whatever process the singleton 43 : component is created upon, and prints a message. 44 : 45 : Executables can read in an input file (specified by the `--input-file` 46 : argument) that will be parsed when the executable begins. %Options 47 : specified in the input file can be used to either place items in the 48 : Parallel::GlobalCache (by specifying tags in the 49 : `const_global_cache_tags` type alias of the metavariables, component 50 : and action structs), to construct items in the db::DataBox of 51 : components during initialization (by specifying tags in the 52 : `simple_tags_from_options` type alias of action struct), or be passed to 53 : the `allocate_array` function of an array component (by specifying 54 : tags in the `array_allocation_tags` type alias of the component). 55 : `SingletonHelloWorld` specifies a single option 56 : 57 : \snippet SingletonHelloWorld.cpp executable_example_options 58 : 59 : which a string specifying a name that will be placed into the constant global 60 : cache. The string is fetched when performing the `PrintMessage` action. Items 61 : in the constant global cache are stored once per node that the executable runs 62 : on. An example input file for `SingletonHelloWorld` can be found in 63 : `tests/InputFiles/ExampleExecutables/SingletonHelloWorld.yaml` and shows how to 64 : specify the options (lines beginning with a `#` are comments and can be 65 : ignored). 66 : 67 : Furthermore among the included header files 68 : 69 : \snippet SingletonHelloWorld.cpp executable_example_includes 70 : 71 : must be the appropriate header for each parallel component type, which in the 72 : `SingletonHelloWorld` example is `AlgorithmSingleton.hpp`. Note that 73 : these headers are not in the source tree, but are generated automatically when 74 : the code is compiled. 75 : 76 : See [the Parallelization documentation](group__ParallelGroup.html#details) 77 : for more details. 78 : 79 : ### Executable Using Charm++ with Custom main() 80 : 81 : While this is technically possible, it has not been tested. We recommend using 82 : the Charm++ supplied main chare mechanism for the time being. 83 : 84 : ### Executable Not Using Charm++ 85 : 86 : An example of an executable that does not use Charm++ for parallelization but 87 : still can use all other infrastructure in SpECTRE is in 88 : `src/Executables/Examples/HelloWorldNoCharm`. Adding a non-Charm++ executable to 89 : SpECTRE mostly follows the standard way of adding an executable using CMake. The 90 : only deviation is that the `CMakeLists.txt` file must tell Charm++ not to add a 91 : `main()` by passing the link flags `-nomain-module -nomain`. This is done using 92 : CMake's `set_target_properties`: 93 : 94 : ``` 95 : set_target_properties( 96 : ${EXECUTABLE} 97 : PROPERTIES LINK_FLAGS "-nomain-module -nomain" 98 : ) 99 : ``` 100 : 101 : To add the executable as a target you must use the `add_spectre_executable` 102 : function, which is a light weight wrapper around CMake's `add_executable`. 103 : For example, 104 : 105 : ``` 106 : add_spectre_executable( 107 : ${EXECUTABLE} 108 : EXCLUDE_FROM_ALL # Exclude from calls to `make` without a specified target 109 : HelloWorld.cpp 110 : ) 111 : ``` 112 : 113 : You can link in any of the SpECTRE libraries by adding them to the 114 : `target_link_libraries`, for example: 115 : 116 : ``` 117 : target_link_libraries( 118 : ${EXECUTABLE} 119 : DataStructures 120 : ) 121 : ``` 122 : 123 : We recommend that you add a test that the executable properly runs by adding an 124 : input file to `tests/InputFiles` in an appropriate subdirectory. See 125 : [`tests/InputFiles/ExampleExecutables/HelloWorldNoCharm.yaml`] 126 : (https://github.com/sxs-collaboration/spectre/tree/develop/tests/InputFiles/ 127 : ExampleExecutables/HelloWorldNoCharm.yaml) 128 : for an example. 129 : The input file is passed to the executable using `--input-file 130 : path/to/Input.yaml`. In the case of the executable not taking any input file 131 : this is just used to generate a test that runs the executable. 132 : 133 : For these types of executables `main` can take the usual `(int argc, char 134 : *argv[])` and parse command line options. Executables not using Charm++ are just 135 : standard executables that can link in any of the libraries in SpECTRE. 136 : 137 : \warning 138 : Currently calling `Parallel::abort` results in a segfault deep inside Charm++ 139 : code. However, the error messages from `ASSERT` and `ERROR` are still printed. 140 : 141 : ### Executable With Custom Compilation or Linking Flags 142 : 143 : Use the CMake function `set_target_properties` to add flags to an executable. To 144 : call a completely custom compiler invocation you should use the 145 : `add_custom_target` CMake function. The need for the `custom_target` level of 146 : control is rare and should generally be avoided since it adds quite a bit of 147 : technical debt to the code base. Thus, it is not explained here. If you are 148 : certain you need it you can see the `DebugPreprocessor` executable's 149 : `CMakeLists.txt` file for an example. 150 : 151 : ### Executable Used for Evolution or Elliptic Solve 152 : 153 : Once they are written, see the tutorials specific to evolution and elliptic 154 : solves.