Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] Add option MUJOCO_USE_SINGLE_PRECISION to enable compilation of MuJoCo with single precision #2278

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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
18 changes: 18 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ jobs:
-DCMAKE_CXX_COMPILER:STRING=g++-12
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
tmpdir: "/tmp"
- os: ubuntu-22.04
additional_label: "-gcc-12-single-precision"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-12
-DCMAKE_CXX_COMPILER:STRING=g++-12
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
-DMUJOCO_USE_SINGLE_PRECISION:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-22.04
additional_label: "-gcc-11"
cmake_args: >-
Expand Down Expand Up @@ -64,6 +73,15 @@ jobs:
-DCMAKE_CXX_COMPILER:STRING=clang++-14
-DMUJOCO_HARDEN:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-22.04
additional_label: "-clang-14-single-precision"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-14
-DCMAKE_CXX_COMPILER:STRING=clang++-14
-DMUJOCO_HARDEN:BOOL=ON
-DMUJOCO_USE_SINGLE_PRECISION:BOOL=ON
tmpdir: "/tmp"
- os: ubuntu-22.04
additional_label: "-clang-13"
cmake_args: >-
Expand Down
37 changes: 36 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
option(MUJOCO_BUILD_EXAMPLES "Build samples for MuJoCo" ON)
option(MUJOCO_BUILD_SIMULATE "Build simulate library for MuJoCo" ON)
option(MUJOCO_BUILD_TESTS "Build tests for MuJoCo" ON)
option(MUJOCO_USE_SINGLE_PRECISION "Build MuJoCo using single precision scalars" OFF)
option(MUJOCO_TEST_PYTHON_UTIL "Build and test utility libraries for Python bindings" ON)

if(APPLE AND (MUJOCO_BUILD_EXAMPLES OR MUJOCO_BUILD_SIMULATE))
Expand All @@ -62,13 +63,44 @@ set(MUJOCO_HEADERS
include/mujoco/mjsan.h
include/mujoco/mjspec.h
include/mujoco/mjthread.h
include/mujoco/mjtnum.h
include/mujoco/mjui.h
include/mujoco/mjvisualize.h
include/mujoco/mjxmacro.h
include/mujoco/mujoco.h
)

# Depending on the value of MUJOCO_USE_SINGLE_PRECISION,
# we either install the regular include/mujoco/mjtnum.h,
# that defines mjtNum as double, or a patched version
# that defines mjUSESINGLE
if(NOT MUJOCO_USE_SINGLE_PRECISION)
list(APPEND MUJOCO_HEADERS "include/mujoco/mjtnum.h")
else()
# Otherwise, we create a new file ${CMAKE_CURRENT_BINARY_DIR}/include/mujoco/mjtnum.h
# that also contains the code snippet:
# #ifndef mjUSESINGLE
# #define mjUSESINGLE
# #endif

# Read original include/mujoco/mjtnum.h
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/include/mujoco/mjtnum.h" mjtnum_original_header)

# Define the point in which we insert the mjUSESINGLE definition, and the definition itself
set(insertion_point "#define MUJOCO_INCLUDE_MJTNUM_H_")
set(directive "\n#ifndef mjUSESINGLE\n#define mjUSESINGLE\n#endif\n")

# Define the insertion point and the directive to insert
set(insertion_point "#define MUJOCO_INCLUDE_MJTNUM_H_")
set(directive "\n\n// This definition is added by CMake as it was configured with MUJOCO_USE_SINGLE_PRECISION set to ON\n#ifndef mjUSESINGLE\n#define mjUSESINGLE\n#endif\n")

# Add the definition
string(REPLACE "${insertion_point}" "${insertion_point}${directive}" mjtnum_modified_header "${mjtnum_original_header}")

# Write the modified header and add to the headers to install
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/include/mujoco/mjtnum.h" "${mjtnum_modified_header}")
list(APPEND MUJOCO_HEADERS "${CMAKE_CURRENT_BINARY_DIR}/include/mujoco/mjtnum.h" )
endif()

# Add metadata to mujoco.dll when building on Windows.
if(WIN32)
set(MUJOCO_RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/dist/mujoco.rc)
Expand Down Expand Up @@ -99,6 +131,9 @@ target_compile_definitions(mujoco PRIVATE _GNU_SOURCE CCD_STATIC_DEFINE MUJOCO_D
if(MUJOCO_ENABLE_AVX_INTRINSICS)
target_compile_definitions(mujoco PUBLIC mjUSEPLATFORMSIMD)
endif()
if(MUJOCO_USE_SINGLE_PRECISION)
target_compile_definitions(mujoco PUBLIC mjUSESINGLE)
endif()

target_compile_options(
mujoco
Expand Down
7 changes: 6 additions & 1 deletion cmake/MujocoDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ findorfetch(
target_compile_options(SdfLib PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
target_link_options(SdfLib PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})

set(ENABLE_DOUBLE_PRECISION ON)
if(MUJOCO_USE_SINGLE_PRECISION)
set(ENABLE_DOUBLE_PRECISION OFF)
else()
set(ENABLE_DOUBLE_PRECISION ON)
endif()
message(STATUS "======> ENABLE_DOUBLE_PRECISION: ${ENABLE_DOUBLE_PRECISION}")
set(CCD_HIDE_ALL_SYMBOLS ON)
findorfetch(
USE_SYSTEM_PACKAGE
Expand Down
15 changes: 15 additions & 0 deletions cmake/ShellTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
# limitations under the License.

function(add_mujoco_shell_test TEST_NAME TARGET_BINARY)
set(options)
set(oneValueArgs)
set(multiValueArgs TAGS)
cmake_parse_arguments(
_ARGS
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
# If TAGS include nofloat32 and MUJOCO_USE_SINGLE_PRECISION is enabled,
# we do not compile or add the tests
if("nofloat32" IN_LIST _ARGS_TAGS AND MUJOCO_USE_SINGLE_PRECISION)
return()
endif()
find_program(BASH_PROGRAM bash)
if(BASH_PROGRAM)
# Set up the test directory
Expand Down
46 changes: 37 additions & 9 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,26 @@ set(MUJOCO_TEST_WORKING_DIR ${CMAKE_CURRENT_SOURCE_DIR})

include(GoogleTest)

macro(mujoco_test name)
# This function is used to add a C++ test to MuJoCo CMake build system
#
# The CMake targets linked by default with target_link_libraries are:
# mujoco fixture gmock
#
# This function supports the following parameters:
# * PROPERTIES: multiple value parameter, its value is set as test properties
# via the set_tests_properties(<test> PROPERTIES <argument>) function
# * ADDITIONAL_LINK_LIBRARIES: multiple value parameter, additional libraries linked
# to the test via target_link_libraries
# * MAIN_TARGET: single value parameter, used to specify the target linked to the tests
# that define the main entry poiny. If not indicated, gest_main is used
# * TAGS: multiple value parameter, used to annotate the test if it belongs to a given
# category. The macro supports the following tags:
# * nofloat32: Used to annotate the tests should be skipped if
# MUJOCO_USE_SINGLE_PRECISION option is enabled
function(mujoco_test name)
set(options)
set(oneValueArgs)
set(multiValueArgs PROPERTIES)
set(oneValueArgs MAIN_TARGET)
set(multiValueArgs PROPERTIES ADDITIONAL_LINK_LIBRARIES TAGS)
cmake_parse_arguments(
_ARGS
"${options}"
Expand All @@ -29,8 +45,22 @@ macro(mujoco_test name)
${ARGN}
)

# If TAGS include nofloat32 and MUJOCO_USE_SINGLE_PRECISION is enabled,
# we do not compile or add the tests
if("nofloat32" IN_LIST _ARGS_TAGS AND MUJOCO_USE_SINGLE_PRECISION)
return()
endif()

add_executable(${name} ${name}.cc)
target_link_libraries(${name} gtest_main mujoco)
target_link_libraries(${name} mujoco fixture gmock)
if(_ARGS_MAIN_TARGET)
target_link_libraries(${name} ${_ARGS_MAIN_TARGET})
else()
target_link_libraries(${name} gtest_main)
endif()
if(_ARGS_ADDITIONAL_LINK_LIBRARIES)
target_link_libraries(${name} ${_ARGS_ADDITIONAL_LINK_LIBRARIES})
endif()
target_include_directories(${name} PRIVATE ${MUJOCO_TEST_INCLUDE})
set_target_properties(${name} PROPERTIES BUILD_RPATH ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
# gtest_discover_tests is recommended over gtest_add_tests, but has some issues in Windows.
Expand All @@ -48,7 +78,8 @@ macro(mujoco_test name)
if(_ARGS_PROPERTIES)
set_tests_properties(${testList} PROPERTIES ${_ARGS_PROPERTIES})
endif()
endmacro()

endfunction()

add_library(fixture STATIC fixture.h fixture.cc)
target_include_directories(fixture PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
Expand All @@ -67,13 +98,10 @@ target_link_libraries(
target_include_directories(fixture PRIVATE ${mujoco_SOURCE_DIR}/include gmock)

mujoco_test(fixture_test)
target_link_libraries(fixture_test fixture gmock)

mujoco_test(header_test)
target_link_libraries(header_test fixture gmock)

mujoco_test(pipeline_test)
target_link_libraries(pipeline_test fixture gmock)
mujoco_test(pipeline_test TAGS nofloat32)

add_subdirectory(benchmark)
add_subdirectory(engine)
Expand Down
83 changes: 21 additions & 62 deletions test/benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,86 +12,45 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Macro for benchmarks that don't use GL (same as mujoco_api_test, but uses
# benchmark::benchmark_main).

macro(mujoco_benchmark_test name)
add_executable(${name} ${name}.cc)
target_link_libraries(
${name}
benchmark::benchmark_main
mujoco
absl::core_headers
)
target_include_directories(${name} PRIVATE ${MUJOCO_TEST_INCLUDE})
# TODO(fraromano) Check RPATH settings
set_target_properties(${name} PROPERTIES BUILD_RPATH ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
# gtest_discover_tests is recommended over gtest_add_tests, but has some issues in Windows.
gtest_add_tests(
TARGET ${name}
SOURCES ${name}.cc
WORKING_DIRECTORY ${MUJOCO_TEST_WORKING_DIR}
TEST_LIST testList
)
if(WIN32)
set_tests_properties(
${testList} PROPERTIES ENVIRONMENT "PATH=$<TARGET_FILE_DIR:mujoco>;$ENV{PATH}"
)
endif()
endmacro()

mujoco_benchmark_test(ccd_benchmark_test)
target_link_libraries(
mujoco_test(
ccd_benchmark_test
fixture
gmock
benchmark::benchmark
MAIN_TARGET benchmark::benchmark_main
ADDITIONAL_LINK_LIBRARIES benchmark::benchmark absl::core_headers
)

mujoco_benchmark_test(step_benchmark_test)
target_link_libraries(
mujoco_test(
step_benchmark_test
fixture
gmock
benchmark::benchmark
MAIN_TARGET benchmark::benchmark_main
ADDITIONAL_LINK_LIBRARIES benchmark::benchmark absl::core_headers
)

mujoco_benchmark_test(thread_performance_test)
target_link_libraries(
mujoco_test(
thread_performance_test
fixture
gmock
benchmark::benchmark
MAIN_TARGET benchmark::benchmark_main
ADDITIONAL_LINK_LIBRARIES benchmark::benchmark absl::core_headers
)

mujoco_benchmark_test(parse_benchmark_test)
target_link_libraries(
mujoco_test(
parse_benchmark_test
fixture
gmock
benchmark::benchmark
MAIN_TARGET benchmark::benchmark_main
ADDITIONAL_LINK_LIBRARIES benchmark::benchmark absl::core_headers
)

mujoco_benchmark_test(engine_util_spatial_benchmark_test)
target_link_libraries(
mujoco_test(
engine_util_spatial_benchmark_test
fixture
gmock
benchmark::benchmark
MAIN_TARGET benchmark::benchmark_main
ADDITIONAL_LINK_LIBRARIES benchmark::benchmark absl::core_headers
)

mujoco_benchmark_test(engine_core_smooth_benchmark_test)
target_link_libraries(
mujoco_test(
engine_core_smooth_benchmark_test
fixture
gmock
benchmark::benchmark
MAIN_TARGET benchmark::benchmark_main
ADDITIONAL_LINK_LIBRARIES benchmark::benchmark absl::core_headers
)

mujoco_benchmark_test(engine_util_sparse_benchmark_test)
target_link_libraries(
mujoco_test(
engine_util_sparse_benchmark_test
fixture
gmock
benchmark::benchmark
MAIN_TARGET benchmark::benchmark_main
ADDITIONAL_LINK_LIBRARIES benchmark::benchmark absl::core_headers
)
Loading