(use_cases_macro_relauncher_thread_test_cpp)= # Macro "**relauncherCJitFunctionThreadTest.C**" ## Objective The goal of this macro is to show how to handle thread-safe compiled function (or code) that would contain `TDataServer` objects (this is not particularly recommended, but has been requested to us). This example is only written in C++ as the CJit interface only works for this, but the idea is the same if one has a code and use the python interface. This will be further discussed below. The function is pointless, a pure illustrative toy and the results is not important as long as one sees that in one case, the macro runs smoothly while on the other hand, it crashes. ## Macro {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/relauncher/use_cases/cpp/relauncherCJitFunctionThreadTest.C" + "\n" + ":language: cpp\n" + ":lines: 1-50,53-60,63-66\n" + "```" }} The very first part of the macro is a function that would be applied to all points of our {{doe}}. The general context is simple: let's assume one wants to find the maximum value of a variable in a given dataset, and let's assume that this maximum should have to be scaled by some factor. We create the `multiply` function to do so, as done here: {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/relauncher/use_cases/cpp/relauncherCJitFunctionThreadTest.C" + "\n" + ":language: cpp\n" + ":lines: 1-17\n" + "```" }} In this function the dataset is always the same (`flowrateUniformDesign.dat`) and the multiplier is the only input attribute. The maximum of the dataset is found by creating a `TDataServer` object, by calling the `fileDataRead` method to read the dataset and by looping over the events (this is not at all the best way to do it, but it is a toy model to show what problems can arise when a `TDataServer` object is created in an evaluator use in multi-thread approach). Few important points in this function to prevent from race condition (not thread-safe behaviour): - the `TDataServer` object is created statistically so that at the end of the function it is automatically destroyed; - the line below is used to tell the `TDataServer` object not to write his data tree in the ROOT internal list and not to dump it in the archive file when the object is destroyed {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/relauncher/use_cases/cpp/relauncherCJitFunctionThreadTest.C" + "\n" + ":language: cpp\n" + ":lines: 5\n" + "```" }} - the line below is used to tell the `fileDataRead` method not to create the archive ROOT file once the dataset is read (thanks to the optional boolean set to false here) {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/relauncher/use_cases/cpp/relauncherCJitFunctionThreadTest.C" + "\n" + ":language: cpp\n" + ":lines: 6\n" + "```" }} The main function starts then with a block that allows to test the main point here: the method develop by {{root}} to prevent the internal list to store object which would lead to race conditions. This block is commented to explain how to run the use-case macro discuss here. The important part is, if one wants to run the macro properly, to call {{ "```{literalinclude} " + parent_dir + "/roottest/uranie/doc/relauncher/use_cases/cpp/relauncherCJitFunctionThreadTest.C" + "\n" + ":language: cpp\n" + ":lines: 28\n" + "```" }} Once this is done, then the macro can be briefly described in the few key steps 1. create the input (multiplier) and output (MultMean) attribute; 2. create the interface to the `multiply` function; 3. create the interface for the runner; 4. create the `TDataServer` object that would contain the multiplier and the results. This object is created within the `onMaster()` part because otherwise there would have been as many dataserver object as there are threads. 5. create a sampler and a {{doe}} to read 24 times the given dataset; 6. run the computations At the end, once the macro is launched by using the command below, the ```bash root -b -q relauncherCJitFunctionThreadTest.C ``` ## Console {{ "```{literalinclude} " + parent_dir + "/roottest/build/uranie/doc/relauncher/use_cases/cpp/relauncherCJitFunctionThreadTest_clean.log" + "\n" + ":language: none\n" + ":lines: 4-\n" + "```" }}