Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ cmake --build build -j
cmake --install build
```

Models are **not** built by default — pass `-DROSS_BUILD_MODELS=ON` to include `phold` and any symlinked-in models. Test discovery is gated by `ROSS_BUILD_TESTING` (defaults ON at top level, inherits from `BUILD_TESTING` if the parent set it; defaults OFF under `add_subdirectory()`/`FetchContent` — parent must opt in).
Models are **not** built by default — pass `-DROSS_BUILD_MODELS=ON` to build the bundled `phold`. External models should be standalone CMake projects that consume ROSS via `find_package(ROSS)`; see [models/README.md](models/README.md). The older symlink-into-`models/` workflow still works during a deprecation period but is no longer the documented path. Test discovery is gated by `ROSS_BUILD_TESTING` (defaults ON at top level, inherits from `BUILD_TESTING` if the parent set it; defaults OFF under `add_subdirectory()`/`FetchContent` — parent must opt in).

MPI is required and auto-discovered via `find_package(MPI)` — do not set `CC=mpicc` or `-DCMAKE_C_COMPILER=mpicc`. For non-standard installs, hint with `-DMPI_HOME=...` or `module load <mpi>` before configuring. The top-level `CMakeLists.txt` does per-arch detection via `CMAKE_SYSTEM_PROCESSOR` and falls back to a `gtod` clock if unrecognized. Set `-DROSS_CLOCK_OVERRIDE=YES` to force the gtod clock.

Expand Down
7 changes: 7 additions & 0 deletions Documentation/dev/deprecate-symlink-models.build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The "symlink your model into ROSS's `models/` directory and let the
in-tree build pick it up" workflow is now deprecated. Configuring with
a symlinked model present produces a CMake deprecation warning at
configure time. The workflow still works for this release; it will be
removed in a future release. New models should be standalone CMake
projects that consume ROSS via `find_package(ROSS)` — see
`models/README.md` for a worked example.
5 changes: 0 additions & 5 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
SET(ROSS_runtime_checks ON CACHE BOOL "Perform ID checks" FORCE)
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug)

# Set all options
#SET(OPTIONS "${OPTIONS} -DROSS_QUEUE_${QUEUE} -DROSS_RAND_${RAND} -DROSS_NETWORK_mpi -DROSS_CLOCK_${CLOCK} -DROSS_GVT_${GVT} -DARCH_${ARCH}")
#SET(OPTIONS "${OPTIONS} -DROSS_QUEUE_${QUEUE} -DROSS_RAND_${RAND} -DROSS_NETWORK_mpi -DROSS_CLOCK_${CLOCK} -DROSS_GVT_${GVT} -DARCH_${ARCH}" PARENT_SCOPE)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DROSS_OPTION_LIST='\"${OPTIONS}\"'")

# Generate Library
# ROSS_BUILD_SHARED_LIBS, which propagates here as BUILD_SHARED_LIBS.
add_library(ROSS ${ross_srcs})
Expand Down
142 changes: 116 additions & 26 deletions models/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# Launcher conventions for the test helpers below:
# - MPI tests use the find_package(MPI)-provided variables:
# ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
# <binary> <args> ${MPIEXEC_POSTFLAGS}
# This replaces the hardcoded "mpirun -np 2" form so tests run under
# whatever launcher CMake detected (e.g., mpiexec, srun, jsrun).
# - Single-rank tests (Sequential, OptDebug, RollbackCheck, _INST_Seq)
# intentionally do NOT use the launcher wrapper — --synch=1, --synch=4,
# and --synch=6 have a single-rank contract that would break if invoked
# under mpiexec.
# - Test binary path is the $<TARGET_FILE:${target_name}> generator
# expression so ctest invokes the binary by absolute path rather than
# the cwd-relative "./${target_name}" form.
# - ${MPIEXEC_PREFLAGS} / ${MPIEXEC_POSTFLAGS} are passed through as-is;
# we do not separate_arguments() them. ${MPIEXEC_EXECUTABLE} is treated
# as a single command (mpiexec/mpirun/srun/jsrun), not a full command
# line with embedded flags. Users on HPC sites with non-trivial launcher
# needs feed extra prefix args via MPIEXEC_PREFLAGS as a CMake list,
# which is the standard CMake MPI idiom.

## BASIC SCHEDULERS
FUNCTION(ROSS_TEST_SCHEDULERS target_name)
# if a parent superbuild has called
Expand All @@ -6,12 +26,24 @@ FUNCTION(ROSS_TEST_SCHEDULERS target_name)
if(NOT ROSS_BUILD_TESTING)
return()
endif()
ADD_TEST(${target_name}_SCHED_Sequential ${target_name} --synch=1)
ADD_TEST(${target_name}_SCHED_Conservative mpirun -np 2 ./${target_name} --synch=2)
ADD_TEST(${target_name}_SCHED_Optimistic mpirun -np 2 ./${target_name} --synch=3 --extramem=100000)
ADD_TEST(${target_name}_SCHED_Realtime mpirun -np 2 ./${target_name} --synch=5 --gvt-interval=1 --clock-rate=$ENV{CLOCK_SPEED} --extramem=100000)
ADD_TEST(${target_name}_SCHED_OptDebug ${target_name} --synch=4 --nkp=1 --extramem=1000000)
ADD_TEST(${target_name}_SCHED_RollbackCheck ${target_name} --synch=6 --nkp=1)
add_test(NAME ${target_name}_SCHED_Sequential
COMMAND $<TARGET_FILE:${target_name}> --synch=1)
add_test(NAME ${target_name}_SCHED_Conservative
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=2
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_SCHED_Optimistic
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --extramem=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_SCHED_Realtime
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=5 --gvt-interval=1 --clock-rate=$ENV{CLOCK_SPEED} --extramem=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_SCHED_OptDebug
COMMAND $<TARGET_FILE:${target_name}> --synch=4 --nkp=1 --extramem=1000000)
add_test(NAME ${target_name}_SCHED_RollbackCheck
COMMAND $<TARGET_FILE:${target_name}> --synch=6 --nkp=1)

SET(sched_tests
${target_name}_SCHED_Sequential
Expand All @@ -28,23 +60,57 @@ FUNCTION(ROSS_TEST_INSTRUMENTATION target_name)
if(NOT ROSS_BUILD_TESTING)
return()
endif()
ADD_TEST(${target_name}_INST_OptPE mpirun -np 2 ./${target_name} --synch=3 --engine-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
ADD_TEST(${target_name}_INST_OptLP mpirun -np 2 ./${target_name} --synch=3 --engine-stats=4 --event-trace=2 --kp-data=1 --lp-data=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
add_test(NAME ${target_name}_INST_OptPE
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --engine-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_INST_OptLP
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --engine-stats=4 --event-trace=2 --kp-data=1 --lp-data=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})

ADD_TEST(${target_name}_INST_RTOptPE mpirun -np 2 ./${target_name} --synch=5 --engine-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
ADD_TEST(${target_name}_INST_RTOptLP mpirun -np 2 ./${target_name} --synch=5 --engine-stats=4 --event-trace=2 --kp-data=1 --lp-data=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
add_test(NAME ${target_name}_INST_RTOptPE
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=5 --engine-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_INST_RTOptLP
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=5 --engine-stats=4 --event-trace=2 --kp-data=1 --lp-data=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})

ADD_TEST(${target_name}_INST_ConsPE mpirun -np 2 ./${target_name} --synch=2 --engine-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
ADD_TEST(${target_name}_INST_ConsLP mpirun -np 2 ./${target_name} --synch=2 --engine-stats=4 --event-trace=2 --kp-data=1 --lp-data=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
add_test(NAME ${target_name}_INST_ConsPE
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=2 --engine-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_INST_ConsLP
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=2 --engine-stats=4 --event-trace=2 --kp-data=1 --lp-data=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})

ADD_TEST(${target_name}_INST_Seq ./${target_name} --synch=1 --event-trace=1 --extramem=100000)
add_test(NAME ${target_name}_INST_Seq
COMMAND $<TARGET_FILE:${target_name}> --synch=1 --event-trace=1 --extramem=100000)

ADD_TEST(${target_name}_INST_Model mpirun -np 2 ./${target_name} --synch=3 --model-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
add_test(NAME ${target_name}_INST_Model
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --model-stats=4 --event-trace=2 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})

ADD_TEST(${target_name}_INST_DisableOutput mpirun -np 2 ./${target_name} --synch=3 --engine-stats=4 --disable-output=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000)
ADD_TEST(${target_name}_INST_ForceOverflow mpirun -np 2 ./${target_name} --synch=3 --event-trace=1 --buffer-free=0 --extramem=100000)
ADD_TEST(${target_name}_INST_FullEventTrace mpirun -np 2 ./${target_name} --synch=3 --event-trace=1 --extramem=100000)
ADD_TEST(${target_name}_INST_RBEventTrace mpirun -np 2 ./${target_name} --synch=3 --event-trace=2 --extramem=100000)
add_test(NAME ${target_name}_INST_DisableOutput
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --engine-stats=4 --disable-output=1 --extramem=100000 --vt-interval=10000 --vt-samp-end=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_INST_ForceOverflow
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --event-trace=1 --buffer-free=0 --extramem=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_INST_FullEventTrace
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --event-trace=1 --extramem=100000
${MPIEXEC_POSTFLAGS})
add_test(NAME ${target_name}_INST_RBEventTrace
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${target_name}> --synch=3 --event-trace=2 --extramem=100000
${MPIEXEC_POSTFLAGS})

SET(inst_tests
${target_name}_INST_OptPE
Expand All @@ -62,11 +128,35 @@ FUNCTION(ROSS_TEST_INSTRUMENTATION target_name)
ENDFUNCTION(ROSS_TEST_INSTRUMENTATION)


# Automatically search and add model subdirectories
CMAKE_POLICY(SET CMP0009 NEW) # follow sym-links
FILE(GLOB_RECURSE my_list . FOLLOW_SYMLINKS */CMakeLists.txt)
FOREACH(cmf ${my_list})
GET_FILENAME_COMPONENT(dir_path ${cmf} PATH)
ADD_SUBDIRECTORY(${dir_path})
# MESSAGE(${dir_path})
ENDFOREACH(cmf)
# Discover model subdirectories via a flat (non-recursive) glob: every
# top-level entry under models/ that is a directory and contains a
# CMakeLists.txt gets added. This skips build/install/test dirs (no
# CMakeLists.txt there) and avoids the GLOB_RECURSE + FOLLOW_SYMLINKS
# recursion the previous form risked. Symlinked-in models keep working
# as a side effect of IS_DIRECTORY / EXISTS following symlinks — see
# models/README.md, where that workflow is no longer the documented
# path. New models should be standalone CMake projects that consume
# ROSS via find_package(ROSS). When the symlink workflow is fully
# retired, the glob below collapses to an explicit add_subdirectory(phold).
file(GLOB model_dirs LIST_DIRECTORIES TRUE
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/*")
foreach(d ${model_dirs})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${d}"
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${d}/CMakeLists.txt")
# Catch users still on the deprecated symlink workflow at the
# moment they reconfigure. The README note only reaches new
# users discovering the path; this reaches existing users. The
# whole block goes away with the glob when the workflow is
# fully retired.
if(IS_SYMLINK "${CMAKE_CURRENT_SOURCE_DIR}/${d}")
message(DEPRECATION
"Model '${d}' was discovered via the deprecated "
"symlink-into-models/ workflow. This path still works "
"but will be removed in a future ROSS release. Please "
"migrate to a standalone CMake project consuming ROSS "
"via find_package(ROSS); see models/README.md.")
endif()
add_subdirectory(${d})
endif()
endforeach()
39 changes: 28 additions & 11 deletions models/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
# Welcome to Modeling!

ROSS comes loaded with one model Phold. This model is often used to test the speed of ROSS in new systems, specially HPC systems. To find out more ROSS example models, please check out the repos below:
ROSS ships with one bundled model, `phold`, used to benchmark ROSS performance on new systems. For other example models built against ROSS:

- [A Template Model](https://github.com/ROSS-org/template-model) that can be used as a starting point for any new model.
- [Bare-bones postal network of mailboxes](https://github.com/nmcglo/ROSS-Mail-Model) made with the intent on mind of teaching ROSS to beginners.
- [A Game of Life example](https://github.com/helq/highlife-ross). The goal of this example is to show case how to build a model where ROSS is linked as library (opposed to building the model inside of ROSS' space).
- [(Deprecated) A Suite of Stable Models](https://github.com/ROSS-org/ROSS-Models) which contains several completed models. These might need some tweaking before they can be run as they were written for legacy ROSS.
- [A Template Model](https://github.com/ROSS-org/template-model) — starting point for any new model
- [Bare-bones postal network of mailboxes](https://github.com/nmcglo/ROSS-Mail-Model) — written with the intent of teaching ROSS to beginners
- [A Game of Life example](https://github.com/helq/highlife-ross) — shows how to build a model where ROSS is linked as a library (opposed to building the model inside of ROSS' space)
- [(Deprecated) A Suite of Stable Models](https://github.com/ROSS-org/ROSS-Models) — older models that may need some tweaking before they can be run; they were written for legacy ROSS

## Creating Your Own Model
## Building your own model

As you develop your model, the best practice is to do it in a separate git repostroy.
Sym-link your model into this folder and CMake will automatically find it for building.
Develop your model as a standalone CMake project that consumes the installed ROSS package via `find_package`. A minimal `CMakeLists.txt` for a single-source-file model looks like this:

```cmake
cmake_minimum_required(VERSION 3.16)
project(my_model C)

find_package(ROSS REQUIRED)

add_executable(my_model my_model.c)
target_link_libraries(my_model PRIVATE ROSS::ROSS m)
```
cd ~/Projects/ROSS/models
ln -s ~/Projects/my-model ./

Build it after installing ROSS, pointing CMake at the install prefix:

```
For more details on creating a model please check out ROSS' documentation page.
cmake -S . -B build -DCMAKE_PREFIX_PATH=<ross-install-prefix>
cmake --build build -j
```

For more details on writing the model code itself please check out ROSS' documentation page.

### If you have a model symlinked into this directory

The older workflow — drop your model's source into a separate repo, symlink it into ROSS's `models/`, rely on ROSS's build to pick it up — still works for now, but is deprecated and will be removed in a future release. Please migrate to the standalone `find_package(ROSS)` setup shown above.
Loading