Skip to content

Commit

Permalink
add -perTaskThreads and benchmark-based counts
Browse files Browse the repository at this point in the history
  • Loading branch information
bhaller committed Aug 8, 2023
1 parent f303627 commit f04c311
Show file tree
Hide file tree
Showing 9 changed files with 539 additions and 160 deletions.
2 changes: 1 addition & 1 deletion EidosScribe/EidosAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ - (void)applicationWillFinishLaunching:(NSNotification *)aNotification
// We always use 4 threads; we don't want to hog the whole machine, just run with a couple threads.
// We pass false for active_threads to let the worker threads sleep, otherwise the CPU is pegged
// the whole time EidosScribe is running, even when sitting idle.
Eidos_WarmUpOpenMP(&std::cout, true, 4, false);
Eidos_WarmUpOpenMP(&std::cout, true, 4, false, /* default per-task thread counts */ "");
#endif

Eidos_WarmUp();
Expand Down
2 changes: 1 addition & 1 deletion SLiMgui/AppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ - (void)applicationWillFinishLaunching:(NSNotification *)aNotification
// We always use 4 threads; we don't want to hog the whole machine, just run with a couple threads.
// We pass false for active_threads to let the worker threads sleep, otherwise the CPU is pegged
// the whole time SLiMgui is running, even when sitting idle.
Eidos_WarmUpOpenMP(&std::cout, true, 4, false);
Eidos_WarmUpOpenMP(&std::cout, true, 4, false, /* default per-task thread counts */ "");
#endif

Eidos_WarmUp();
Expand Down
3 changes: 2 additions & 1 deletion VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ PARALLEL changes (now in the master branch):
modify CMakeLists.txt to add /usr/local/include to all targets (through GSL_INCLUDES, which should maybe get cleaned up somehow)
modify CMakeLists.txt to build executables eidos_multi and slim_multi when PARALLEL is ON, and to link in libomp
disable parallel builds of EidosScribe, SLiMgui, and SLiMguiLegacy with #error directives; parallelization is for the command line only (active threads peg the CPU, passive threads are slower than single-threaded)
add a command-line option, -maxthreads <n>, to control the maximum number of threads used in OpenMP
add a command-line option, -maxThreads <n>, to control the maximum number of threads used in OpenMP
add a header eidos_openmp.h that should be used instead of #include "omp.h", providing various useful definitions etc.
add an initialization function for OpenMP, Eidos_WarmUpOpenMP(), that must be called when warming up; sets various options, logs diagnostic info
set default values for OMP_WAIT_POLICY (active) and OMP_PROC_BIND (false) and OMP_DYNAMIC (false) for slim and eidos
Expand Down Expand Up @@ -84,6 +84,7 @@ PARALLEL changes (now in the master branch):
add parallelSetTaskThreadCounts() function to set per-task thread counts, and parallelGetTaskThreadCounts() to get them
add recipe 22.7, Parallelizing nonWF reproduction and spatial interactions
add internal EidosBenchmark facility for timing of internal loops, for benchmarking of parallelization scaling
add a command-line option, -perTaskThreads, to let the user control how many threads to use for different tasks (if not overridden)

development head (in the master branch):
fix a minor bug with autofix when opening multiple .slim documents at once in SLiMgui
Expand Down
37 changes: 26 additions & 11 deletions core/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ static void PrintUsageAndDie(bool p_print_header, bool p_print_full_usage)
SLIM_OUTSTREAM << " [-l[ong] [<l>]] [-s[eed] <seed>] [-t[ime]] [-m[em]] [-M[emhist]] [-x]" << std::endl;
SLIM_OUTSTREAM << " [-d[efine] <def>] ";
#ifdef _OPENMP
// The -maxthreads flag is visible only for a parallel build
SLIM_OUTSTREAM << "[-maxthreads <n>] ";
// Some flags are visible only for a parallel build
SLIM_OUTSTREAM << "[-maxThreads <n>] [-perTaskThreads \"x\"] ";
#endif
#if (SLIMPROFILING == 1)
// Some flags are visible only for a profile build
Expand All @@ -130,8 +130,9 @@ static void PrintUsageAndDie(bool p_print_header, bool p_print_full_usage)
SLIM_OUTSTREAM << " -x : disable SLiM's runtime safety/consistency checks" << std::endl;
SLIM_OUTSTREAM << " -d[efine] <def> : define an Eidos constant, such as \"mu=1e-7\"" << std::endl;
#ifdef _OPENMP
// The -maxthreads flag is visible only for a parallel build
SLIM_OUTSTREAM << " -maxthreads <n> : set the maximum number of threads used" << std::endl;
// Some flags are visible only for a parallel build
SLIM_OUTSTREAM << " -maxThreads <n> : set the maximum number of threads used" << std::endl;
SLIM_OUTSTREAM << " -perTaskThreads \"x\": set per-task thread counts to named set \"x\"" << std::endl;
#endif
#if (SLIMPROFILING == 1)
SLIM_OUTSTREAM << " " << std::endl;
Expand Down Expand Up @@ -187,6 +188,7 @@ int main(int argc, char *argv[])
#ifdef _OPENMP
long max_thread_count = omp_get_max_threads();
bool changed_max_thread_count = false;
std::string per_task_thread_count_set_name = ""; // default per-task thread counts
#endif

#if (SLIMPROFILING == 1)
Expand Down Expand Up @@ -335,7 +337,7 @@ int main(int argc, char *argv[])
if (strcmp(arg, "--testEidos") == 0 || strcmp(arg, "-testEidos") == 0 || strcmp(arg, "-te") == 0)
{
#ifdef _OPENMP
Eidos_WarmUpOpenMP(&SLIM_ERRSTREAM, changed_max_thread_count, (int)max_thread_count, true);
Eidos_WarmUpOpenMP(&SLIM_ERRSTREAM, changed_max_thread_count, (int)max_thread_count, true, /* max per-task thread counts */ "maxThreads");
#endif
Eidos_WarmUp();

Expand All @@ -351,7 +353,7 @@ int main(int argc, char *argv[])
if (strcmp(arg, "--testSLiM") == 0 || strcmp(arg, "-testSLiM") == 0 || strcmp(arg, "-ts") == 0)
{
#ifdef _OPENMP
Eidos_WarmUpOpenMP(&SLIM_ERRSTREAM, changed_max_thread_count, (int)max_thread_count, true);
Eidos_WarmUpOpenMP(&SLIM_ERRSTREAM, changed_max_thread_count, (int)max_thread_count, true, /* max per-task thread counts */ "maxThreads");
#endif
Eidos_WarmUp();
SLiM_WarmUp();
Expand Down Expand Up @@ -383,8 +385,8 @@ int main(int argc, char *argv[])
continue;
}

// -maxthreads <x>: set the maximum number of OpenMP threads that will be used
if (strcmp(arg, "-maxthreads") == 0)
// -maxThreads <x>: set the maximum number of OpenMP threads that will be used
if (strcmp(arg, "-maxThreads") == 0)
{
if (++arg_index == argc)
PrintUsageAndDie(false, true);
Expand All @@ -397,20 +399,33 @@ int main(int argc, char *argv[])

if ((max_thread_count < 1) || (max_thread_count > EIDOS_OMP_MAX_THREADS))
{
SLIM_OUTSTREAM << "The -maxthreads command-line option enforces a range of [1, " << EIDOS_OMP_MAX_THREADS << "]." << std::endl;
SLIM_OUTSTREAM << "The -maxThreads command-line option enforces a range of [1, " << EIDOS_OMP_MAX_THREADS << "]." << std::endl;
exit(EXIT_FAILURE);
}

continue;
#else
if (count != 1)
{
SLIM_OUTSTREAM << "The -maxthreads command-line option only allows a value of 1 when not running a PARALLEL build." << std::endl;
SLIM_OUTSTREAM << "The -maxThreads command-line option only allows a value of 1 when not running a PARALLEL build." << std::endl;
exit(EXIT_FAILURE);
}
#endif
}

// -perTaskThreads "x": set the per-task thread counts to be used in OpenMP to a named set "x"
if (strcmp(arg, "-perTaskThreads") == 0)
{
if (++arg_index == argc)
PrintUsageAndDie(false, true);

#ifdef _OPENMP
// We just take the name as given; testing against known values will be done later
// This command-line argument is ignored completely when not parallel
per_task_thread_count_set_name = std::string(argv[arg_index]);
#endif
}

#if (SLIMPROFILING == 1)
if (strcmp(arg, "-profileStart") == 0)
{
Expand Down Expand Up @@ -500,7 +515,7 @@ int main(int argc, char *argv[])
#endif

#ifdef _OPENMP
Eidos_WarmUpOpenMP((SLiM_verbosity_level >= 1) ? &SLIM_ERRSTREAM : nullptr, changed_max_thread_count, (int)max_thread_count, true);
Eidos_WarmUpOpenMP((SLiM_verbosity_level >= 1) ? &SLIM_ERRSTREAM : nullptr, changed_max_thread_count, (int)max_thread_count, true, per_task_thread_count_set_name);
#endif

if (SLiM_verbosity_level >= 2)
Expand Down
8 changes: 6 additions & 2 deletions eidos/eidos_functions_other.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,9 +891,9 @@ EidosValue_SP Eidos_ExecuteFunction_parallelSetTaskThreadCounts(__attribute__((u

if (source_value->Type() == EidosValueType::kValueNULL)
{
// A dict value of NULL means "reset to default settings", which we have a function for
// A dict value of NULL means "reset to the command-line default settings"
#ifdef _OPENMP
_Eidos_SetDefaultOpenMPThreadCounts();
_Eidos_SetOpenMPThreadCounts(gEidosDefaultPerTaskThreadCounts);
#endif
}
else
Expand Down Expand Up @@ -1048,6 +1048,10 @@ EidosValue_SP Eidos_ExecuteFunction_parallelSetTaskThreadCounts(__attribute__((u
else if (key == "SURVIVAL") gEidos_OMP_threads_SURVIVAL = (int)value_int64;
else
EIDOS_TERMINATION << "ERROR (Eidos_ExecuteFunction_parallelSetTaskThreadCounts): parallelSetTaskThreadCounts() does not recognize the task name " << key << "." << EidosTerminate(nullptr);

// This assumes that any thread count set might push the maximum per-task thread count higher, but not lower
gEidosPerTaskThreadCountsSetName = "UserDefined";
gEidosPerTaskOriginalMaxThreadCount = std::max(gEidosPerTaskOriginalMaxThreadCount, (int)value_int64);
#endif
}
else
Expand Down
Loading

0 comments on commit f04c311

Please sign in to comment.