Skip to content

Commit

Permalink
Merge pull request #1171 from LLNL/feature/kweiss/aws-tutorial
Browse files Browse the repository at this point in the history
AWS tutorial
  • Loading branch information
kennyweiss authored Aug 7, 2024
2 parents b5fa221 + 2c9dfcd commit 58f9958
Show file tree
Hide file tree
Showing 24 changed files with 3,403 additions and 24 deletions.
29 changes: 29 additions & 0 deletions scripts/llnl_scripts/llnl_lc_build_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ def build_and_test_host_config(test_root, host_config,
should_test_installed_cmake_example = True
should_test_installed_blt_example = True
should_test_installed_make_example = False
should_test_installed_tutorial = True

if should_test_installed_cmake_example:
install_example_dir = pjoin(install_dir, "examples", "axom", "using-with-cmake")
Expand Down Expand Up @@ -378,6 +379,34 @@ def build_and_test_host_config(test_root, host_config,
print("[ERROR: Installed 'using-with-blt' example for host-config: %s failed]\n\n" % host_config)
return res

if should_test_installed_tutorial:
# Notes: Might require loading module for more recent cmake than the system default for some platforms
install_example_dir = pjoin(install_dir, "examples", "axom", "radiuss_tutorial")
install_example_output_file = pjoin(build_dir,"output.log.install_example.radiuss_tutorial.txt")
print("[testing installed 'radiuss_tutorial' example]")
print("[log file: %s]" % install_example_output_file)

example_commands = [
"cd {0}".format(install_example_dir),
"rm -rf build",
"mkdir build",
"cd build",
"""echo "[Configuring 'radiuss_tutorial']" """,
"cmake -C ../host-config.cmake -DCMAKE_BUILD_TYPE={0} ..".format(build_type),
"""echo "[Building 'radiuss_tutorial']" """,
"make -j16",
"""echo "[Running lessons for radiuss_tutorial]" """,
"ctest -j16",
"""echo "[Done]" """
]

res = sexe(" && ".join(example_commands),
output_file = install_example_output_file,
echo=True)

if res != 0:
print("[ERROR: Installed 'radiuss_tutorial' for host-config: %s failed]\n\n" % host_config)
return res

print("[SUCCESS: Build, test, and install for host-config: %s complete]\n" % host_config)

Expand Down
2 changes: 1 addition & 1 deletion src/axom/core/RangeAdapter.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2017-2023, Lawrence Livermore National Security, LLC and
// Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
// other Axom Project Developers. See the top-level LICENSE file for details.
//
// SPDX-License-Identifier: (BSD-3-Clause)
Expand Down
2 changes: 1 addition & 1 deletion src/axom/core/examples/core_array_perf.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2017-2023, Lawrence Livermore National Security, LLC and
// Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
// other Axom Project Developers. See the top-level LICENSE file for details.
//
// SPDX-License-Identifier: (BSD-3-Clause)
Expand Down
17 changes: 9 additions & 8 deletions src/axom/primal/geometry/BoundingBox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,18 +450,19 @@ template <typename OtherType>
AXOM_HOST_DEVICE bool BoundingBox<T, NDIMS>::intersectsWith(
const BoundingBox<OtherType, NDIMS>& otherBB) const
{
bool status = true;

// AABBs cannot intersect if they are separated along any dimension
for(int i = 0; i < NDIMS; ++i)
{
status &= detail::intersect_bbox_bbox(m_min[i],
m_max[i],
otherBB.m_min[i],
otherBB.m_max[i]);
} // END for all dimensions
if(!detail::intersect_bbox_bbox(m_min[i],
m_max[i],
otherBB.m_min[i],
otherBB.m_max[i]))
{
return false;
}
}

return status;
return true;
}

//------------------------------------------------------------------------------
Expand Down
11 changes: 5 additions & 6 deletions src/axom/primal/operators/detail/intersect_bounding_box_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ namespace detail
/*!
* \brief Helper routine for AABB / AABB intersection test.
*
* \param [in] min1 the 1st AABB min coordinate along a direction.
* \param [in] max1 the 1st AABB max coordinate along a drection.
* \param [in] min2 the 2nd AABB min coordinate along a direction.
* \param [in] max2 the 2nd AABB max coordinate along a drection.
* \param [in] min1 the 1st AABB min coordinate along a direction
* \param [in] max1 the 1st AABB max coordinate along a direction
* \param [in] min2 the 2nd AABB min coordinate along a direction
* \param [in] max2 the 2nd AABB max coordinate along a direction
*
* \return status true if the AABB's intersect, otherwise false.
*
Expand All @@ -37,8 +37,7 @@ AXOM_HOST_DEVICE inline bool intersect_bbox_bbox(const T& min1,
const T& min2,
const T& max2)
{
bool status = ((max1 < min2 || min1 > max2) ? false : true);
return status;
return max1 >= min2 && min1 <= max2;
}

/*!
Expand Down
12 changes: 6 additions & 6 deletions src/axom/primal/operators/detail/intersect_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ AXOM_HOST_DEVICE bool intersect_tri3D_tri3D(const Triangle<T, 3>& t1,
// Vector3 t2Normal = Vector3::cross_product(Vector3(t2[2], t2[0]),
// Vector3(t2[2], t2[1]));
Vector3 t2Normal = t2.normal().unitVector();
double dp1 = (Vector3(t2[2], t1[0])).dot(t2Normal);
double dq1 = (Vector3(t2[2], t1[1])).dot(t2Normal);
double dr1 = (Vector3(t2[2], t1[2])).dot(t2Normal);
const double dp1 = (t1[0] - t2[2]).dot(t2Normal);
const double dq1 = (t1[1] - t2[2]).dot(t2Normal);
const double dr1 = (t1[2] - t2[2]).dot(t2Normal);

if(nonzeroSignMatch(dp1, dq1, dr1, EPS))
{
Expand All @@ -192,9 +192,9 @@ AXOM_HOST_DEVICE bool intersect_tri3D_tri3D(const Triangle<T, 3>& t1,
// Vector3 t1Normal = Vector3::cross_product(Vector3(t1[0], t1[1]),
// Vector3(t1[0], t1[2]));
Vector3 t1Normal = t1.normal().unitVector();
double dp2 = (Vector3(t1[2], t2[0])).dot(t1Normal);
double dq2 = (Vector3(t1[2], t2[1])).dot(t1Normal);
double dr2 = (Vector3(t1[2], t2[2])).dot(t1Normal);
const double dp2 = (t2[0] - t1[2]).dot(t1Normal);
const double dq2 = (t2[1] - t1[2]).dot(t1Normal);
const double dr2 = (t2[2] - t1[2]).dot(t1Normal);

if(nonzeroSignMatch(dp2, dq2, dr2, EPS))
{
Expand Down
2 changes: 1 addition & 1 deletion src/axom/slic/docs/sphinx/sections/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ The :ref:`GenericOutputStream`, takes two arguments in its constructor:
will deallocate them when ``slic::finalize()`` is called.

Step 5.1: Tagged Log Streams
^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Slic has limited support for tags, where users can bind streams
to user-defined tags. The bound streams only output messages with the
Expand Down
21 changes: 21 additions & 0 deletions src/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,24 @@ install(
examples/axom/using-with-blt
)


#------------------------------------------------------------------------------
# configure and install 'radiuss_tutorial' example
#------------------------------------------------------------------------------
configure_file(
radiuss_tutorial/host-config.cmake.in
${PROJECT_BINARY_DIR}/examples/radiuss_tutorial/host-config.cmake)

install(
FILES
radiuss_tutorial/CMakeLists.txt
${PROJECT_BINARY_DIR}/examples/radiuss_tutorial/host-config.cmake
DESTINATION
examples/axom/radiuss_tutorial
)

foreach(_lesson lesson_00 lesson_01 lesson_02 lesson_03 lesson_04 patch figs)
install(DIRECTORY radiuss_tutorial/${_lesson}
DESTINATION examples/axom/radiuss_tutorial)
endforeach()

141 changes: 141 additions & 0 deletions src/examples/radiuss_tutorial/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
# other Axom Project Developers. See the top-level LICENSE file for details.
#
# SPDX-License-Identifier: (BSD-3-Clause)
#------------------------------------------------------------------------------
# Tutorial that demonstrates the usage of several Axom components
# in a BLT-based build system.
#
# Configuration variables are stored in a CMake cache file 'host-config.cmake'
# which defines paths to blt, axom and possibly other TPLs.
# It also contains information about the compiler used to build axom.
#------------------------------------------------------------------------------
#
# To build:
# mkdir build
# cd build
# cmake -C ../host-config.cmake ..
# make
# ./bin/lesson_*
#
#------------------------------------------------------------------------------

cmake_minimum_required(VERSION 3.14)

project(radiuss_tutorial)

#------------------------------------------------------------------------------
# Set up BLT with validity checks
#------------------------------------------------------------------------------

# Check that path to BLT is provided and valid
if(NOT DEFINED BLT_SOURCE_DIR OR NOT EXISTS ${BLT_SOURCE_DIR}/SetupBLT.cmake)
message(FATAL_ERROR "Missing required 'BLT_SOURCE_DIR' variable pointing to a valid blt")
endif()
include(${BLT_SOURCE_DIR}/SetupBLT.cmake)


#------------------------------------------------------------------------------
# Check for AXOM_DIR and use CMake's find_package to import axom's targets
#------------------------------------------------------------------------------
if(NOT DEFINED AXOM_DIR OR NOT EXISTS ${AXOM_DIR}/lib/cmake/axom-config.cmake)
message(FATAL_ERROR "Missing required 'AXOM_DIR' variable pointing to an installed axom")
endif()

include(CMakeFindDependencyMacro)

find_dependency(axom REQUIRED
NO_DEFAULT_PATH
PATHS ${AXOM_DIR}/lib/cmake)

#------------------------------------------------------------------------------
# Set up target executables for the tutorial
#------------------------------------------------------------------------------
set(tutorial_deps axom axom::fmt axom::cli11)
blt_list_append(TO tutorial_deps ELEMENTS blt::openmp IF ENABLE_OPENMP)
blt_list_append(TO tutorial_deps ELEMENTS blt::cuda IF ENABLE_CUDA)
blt_list_append(TO tutorial_deps ELEMENTS blt::hip IF ENABLE_HIP)

blt_add_executable(NAME lesson_00_check_axom_configuration
SOURCES lesson_00/check_axom_configuration.cpp
DEPENDS_ON ${tutorial_deps})

blt_add_executable(NAME lesson_01_load_stl_mesh
SOURCES lesson_01/load_stl_mesh.cpp
DEPENDS_ON ${tutorial_deps})

blt_add_executable(NAME lesson_02_naive_self_intersections
SOURCES lesson_02/naive_self_intersections.cpp
DEPENDS_ON ${tutorial_deps})

if(umpire_FOUND AND RAJA_FOUND)
blt_list_append(TO tutorial_deps ELEMENTS RAJA IF RAJA_FOUND)
blt_list_append(TO tutorial_deps ELEMENTS umpire IF umpire_FOUND)

blt_add_executable(NAME lesson_03_device_self_intersections
SOURCES lesson_03/device_self_intersections.cpp
DEPENDS_ON ${tutorial_deps})

blt_add_executable(NAME lesson_04_device_spatial_indexes
SOURCES lesson_04/device_spatial_indexes.cpp
DEPENDS_ON ${tutorial_deps})
endif()

#------------------------------------------------------------------------------
# Optionally, add tests to run the tutorial lessons
#------------------------------------------------------------------------------
if(ENABLE_TESTS)
blt_add_test(NAME lesson_00_check_axom_configuration
COMMAND lesson_00_check_axom_configuration)

set(_sphere_mesh "${AXOM_DATA_DIR}/quest/sphere_binary.stl")
set(_plane_problem_mesh "${AXOM_DATA_DIR}/quest/plane_simp_problems.stl")

if(EXISTS ${_sphere_mesh})
blt_add_test(
NAME lesson_01_load_stl_mesh_sphere
COMMAND lesson_01_load_stl_mesh -i ${_sphere_mesh})

blt_add_test(
NAME lesson_02_naive_self_intersections_sphere
COMMAND lesson_02_naive_self_intersections -i ${_sphere_mesh} --use-bounding-boxes)
endif()

set (_policies "seq")
blt_list_append(TO _policies ELEMENTS "omp" IF ENABLE_OPENMP)
blt_list_append(TO _policies ELEMENTS "cuda" IF ENABLE_CUDA)
blt_list_append(TO _policies ELEMENTS "hip" IF ENABLE_HIP)

# the plane_mesh can take too long on lesson 3 in Debug configs, so only use it in Release configs
set(_lesson_03_mesh_name "sphere")
set(_lesson_03_mesh_path ${_sphere_mesh})
if(${CMAKE_BUILD_TYPE} MATCHES "^[Rr]elease")
set(_lesson_03_mesh_name "plane")
set(_lesson_03_mesh_path ${_plane_problem_mesh})
endif()
if(TARGET lesson_03_device_self_intersections AND EXISTS ${_lesson_03_mesh_path})
foreach(_pol ${_policies})
blt_add_test(
NAME lesson_03_device_self_intersections_${_lesson_03_mesh_name}_${_pol}
COMMAND lesson_03_device_self_intersections -i ${_lesson_03_mesh_path} --use-bounding-boxes -p ${_pol})
endforeach()
endif()

if(TARGET lesson_04_device_spatial_indexes AND EXISTS ${_plane_problem_mesh})
foreach(_pol ${_policies})
blt_add_test(
NAME lesson_04_device_spatial_indexes_plane_${_pol}
COMMAND lesson_04_device_spatial_indexes -i ${_plane_problem_mesh} -p ${_pol})
endforeach()
endif()

endif()


#------------------------------------------------------------------------------
# Optionally, print out information about imported targets
#------------------------------------------------------------------------------
if(EXAMPLE_VERBOSE_OUTPUT)
blt_print_target_properties(TARGET axom CHILDREN TRUE)
endif()

16 changes: 16 additions & 0 deletions src/examples/radiuss_tutorial/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Axom tutorial

This tutorial showcases several features of Axom by incrementally building up an application that checks for self-intersections and degeneracies among the triangles in a triangle mesh. The resulting application matches functionality from Axom's [mesh_tester utility](https://github.com/LLNL/axom/blob/develop/src/tools/mesh_tester.cpp).


![Mesh with self-intersections](figs/porsche.png)
<div style="text-align: center; font-style: italic;">
A triangle mesh of a car with intersecting triangles highlighted in red
</div>
<br />

* [Lesson 00](lesson_00/README.md) provides a brief overview of Axom and develops a simple application against an installed version of Axom
* [Lesson 01](lesson_01/README.md) uses Axom to load an [STL triangle mesh](https://en.wikipedia.org/wiki/STL_(file_format)) and print out the number of triangles in the mesh. It uses Axom's logging component `slic` as well as functionality from its spatial querying component, `quest`.
* [Lesson 02](lesson_02/README.md) adds a naive algorithm that checks every pair of triangles in the mesh for self-intersections, showcasing computational geometry primitives and operations from Axom's `primal` component.
* [Lesson 03](lesson_03/README.md) ports this naive algorithm to [RAJA](https://github.com/llnl/raja) for performance-portable execution on available computing resources, using sequential (CPU), threaded (OpenMP) and GPU devices using `cuda` and `hip` backends.
* [Lesson 04](lesson_04/README.md) uses a spatial index from Axom's `spin` component to further accelerate our self-intersection algorithm.
Binary file added src/examples/radiuss_tutorial/figs/porsche.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 58f9958

Please sign in to comment.