diff --git a/doc/APIreference/APIglobals.rst b/doc/APIreference/APIglobals.rst index f1ad2c5b..2d08ce08 100644 --- a/doc/APIreference/APIglobals.rst +++ b/doc/APIreference/APIglobals.rst @@ -534,6 +534,14 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr Macros ^^^^^^ + +.. _mjUSESINGLE: + +mjUSESINGLE +~~~~~~~~~~~ + +Compile-time flag, see :ref:`mjtNum`. + .. _mjDISABLED: mjDISABLED diff --git a/doc/APIreference/APItypes.rst b/doc/APIreference/APItypes.rst index 5ee07e6a..e5ff73ff 100644 --- a/doc/APIreference/APItypes.rst +++ b/doc/APIreference/APItypes.rst @@ -54,24 +54,28 @@ The two types below are defined in `mjtnum.h `__ + with the build-time flag ``mjUSESINGLE``. If this symbol is not defined, MuJoCo will use double-precision floating + point, as usual. If ``mjUSESINGLE`` is defined, MuJoCo will use single-precision floating point. See :ref:`mjtNum`. + + Relatedly, fixed various type errors that prevented building with single-precision. MJX ~~~ -7. Added support for :ref:`elliptic friction cones`. -8. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings. -9. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients. +8. Added support for :ref:`elliptic friction cones`. +9. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings. +10. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients. .. youtube:: P83tKA1iz2Y @@ -39,8 +45,8 @@ MJX Simulate ^^^^^^^^ -10. Added improved tutorial video. -11. Improved the Brownian noise generator. +11. Added improved tutorial video. +12. Improved the Brownian noise generator. |br| |br| |br| |br| diff --git a/include/mujoco/mjtnum.h b/include/mujoco/mjtnum.h index b9d78ea1..e50b5ff5 100644 --- a/include/mujoco/mjtnum.h +++ b/include/mujoco/mjtnum.h @@ -17,12 +17,8 @@ //---------------------------------- floating-point definition ------------------------------------- -// compile-time configuration options -#define mjUSEDOUBLE // single or double precision for mjtNum - - // floating point data type and minval -#ifdef mjUSEDOUBLE +#ifndef mjUSESINGLE typedef double mjtNum; #define mjMINVAL 1E-15 // minimum value in any denominator #else diff --git a/include/mujoco/mujoco.h b/include/mujoco/mujoco.h index 95893542..1c85099f 100644 --- a/include/mujoco/mujoco.h +++ b/include/mujoco/mujoco.h @@ -893,7 +893,7 @@ MJAPI int mjs_isWarning(mjSpec* s); //---------------------------------- Standard math ------------------------------------------------- -#ifdef mjUSEDOUBLE +#if !defined(mjUSESINGLE) #define mju_sqrt sqrt #define mju_exp exp #define mju_sin sin diff --git a/sample/testspeed.cc b/sample/testspeed.cc index 66dabf3a..09757888 100644 --- a/sample/testspeed.cc +++ b/sample/testspeed.cc @@ -34,18 +34,17 @@ mjData* d[maxthread]; // per-thread statistics int contacts[maxthread]; int constraints[maxthread]; -double simtime[maxthread]; - +mjtNum simtime[maxthread]; // timer -std::chrono::steady_clock::time_point tm_start; mjtNum gettm(void) { - std::chrono::duration elapsed; - elapsed = std::chrono::steady_clock::now() - tm_start; + using std::chrono::steady_clock; + using Microseconds = std::chrono::duration; + static steady_clock::time_point tm_start = steady_clock::now(); + auto elapsed = Microseconds(steady_clock::now() - tm_start); return elapsed.count(); } - // deallocate and print message int finish(const char* msg = NULL, mjModel* m = NULL) { // deallocate model @@ -87,7 +86,7 @@ void simulate(int id, int nstep, mjtNum* ctrl) { constraints[id] = 0; // run and time - double start = gettm(); + mjtNum start = gettm(); for (int i=0; i < nstep; i++) { // inject pseudo-random control noise mju_copy(d[id]->ctrl, ctrl + i*m->nu, m->nu); @@ -126,7 +125,7 @@ int main(int argc, char** argv) { // read arguments int nstep = 10000, nthread = 0, npoolthread = 0; // inject small noise by default, to avoid fixed contact state - mjtNum ctrlnoise = 0.01; + double ctrlnoise = 0.01; if (argc > 2 && (std::sscanf(argv[2], "%d", &nstep) != 1 || nstep <= 0)) { return finish("Invalid nstep argument"); } @@ -149,7 +148,7 @@ int main(int argc, char** argv) { // get filename, determine file type std::string filename(argv[1]); - bool binary = (filename.find(".mjb") != std::string::npos); + bool binary = (filename.find(".mjb") != std::string::npos); // NOLINT // load model char error[1000] = "Could not load binary model"; @@ -191,8 +190,11 @@ int main(int argc, char** argv) { nstep, nthread > 1 ? " per thread" : "", m->opt.timestep); + if (sizeof(mjtNum) == 4) { + std::printf(", using single-precision"); + } if (npoolthread > 1) { - std::printf(", using %d threads for engine-internal threadpool", npoolthread); + std::printf(", using %d threads", npoolthread); } std::printf("...\n\n"); diff --git a/simulate/main.cc b/simulate/main.cc index 30139f8f..397a83c9 100644 --- a/simulate/main.cc +++ b/simulate/main.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include #include #include @@ -334,7 +335,7 @@ void PhysicsLoop(mj::Simulate& sim) { // misalignment condition: distance from target sim time is bigger than syncmisalign bool misaligned = - mju_abs(Seconds(elapsedCPU).count()/slowdown - elapsedSim) > syncMisalign; + std::abs(Seconds(elapsedCPU).count()/slowdown - elapsedSim) > syncMisalign; // out-of-sync (for any reason): reset sync times, step if (elapsedSim < 0 || elapsedCPU.count() < 0 || syncCPU.time_since_epoch().count() == 0 || diff --git a/simulate/simulate.cc b/simulate/simulate.cc index a86c7343..a424e310 100644 --- a/simulate/simulate.cc +++ b/simulate/simulate.cc @@ -1165,7 +1165,9 @@ void CopyPose(mj::Simulate* sim, const mjModel* m, const mjData* d) { // millisecond timer, for MuJoCo built-in profiler mjtNum Timer() { - return Milliseconds(mj::Simulate::Clock::now().time_since_epoch()).count(); + static auto start = mj::Simulate::Clock::now(); + auto elapsed = Milliseconds(mj::Simulate::Clock::now() - start); + return elapsed.count(); } // clear all times diff --git a/src/engine/engine_core_constraint.c b/src/engine/engine_core_constraint.c index 6e47d384..e17c2bad 100644 --- a/src/engine/engine_core_constraint.c +++ b/src/engine/engine_core_constraint.c @@ -35,9 +35,9 @@ #endif #ifdef mjUSEPLATFORMSIMD - #if defined(__AVX__) && defined(mjUSEDOUBLE) + #if defined(__AVX__) && !defined(mjUSESINGLE) #define mjUSEAVX - #endif // defined(__AVX__) && defined(mjUSEDOUBLE) + #endif // defined(__AVX__) && !defined(mjUSESINGLE) #endif // mjUSEPLATFORMSIMD diff --git a/src/engine/engine_support.c b/src/engine/engine_support.c index 526a1334..6740f2ae 100644 --- a/src/engine/engine_support.c +++ b/src/engine/engine_support.c @@ -31,7 +31,7 @@ #include "engine/engine_util_spatial.h" #ifdef mjUSEPLATFORMSIMD - #if defined(__AVX__) && defined(mjUSEDOUBLE) + #if defined(__AVX__) && !defined(mjUSESINGLE) #define mjUSEAVX #include "immintrin.h" #endif diff --git a/src/engine/engine_util_blas.c b/src/engine/engine_util_blas.c index bb920b86..77ed4194 100644 --- a/src/engine/engine_util_blas.c +++ b/src/engine/engine_util_blas.c @@ -19,7 +19,7 @@ #include #ifdef mjUSEPLATFORMSIMD - #if defined(__AVX__) && defined(mjUSEDOUBLE) + #if defined(__AVX__) && !defined(mjUSESINGLE) #define mjUSEAVX #include "immintrin.h" #endif @@ -609,7 +609,7 @@ void mju_addToScl(mjtNum* res, const mjtNum* vec, mjtNum scl, int n) { void mju_addScl(mjtNum* res, const mjtNum* vec1, const mjtNum* vec2, mjtNum scl, int n) { int i = 0; -#if defined(__AVX__) && defined(mjUSEAVX) && defined(mjUSEDOUBLE) +#if defined(__AVX__) && defined(mjUSEAVX) && !defined(mjUSESINGLE) int n_4 = n - 4; // vector part diff --git a/src/engine/engine_util_blas.h b/src/engine/engine_util_blas.h index eaac6360..882c9783 100644 --- a/src/engine/engine_util_blas.h +++ b/src/engine/engine_util_blas.h @@ -26,7 +26,7 @@ extern "C" { //------------------------------ standard library functions ---------------------------------------- -#ifdef mjUSEDOUBLE +#if !defined(mjUSESINGLE) #define mju_sqrt sqrt #define mju_exp exp #define mju_sin sin @@ -59,7 +59,7 @@ extern "C" { #define mju_log10 log10f #define mju_floor floorf #define mju_ceil ceilf -#endif +#endif // !defined(mjUSESINGLE) //------------------------------ 3D vector and matrix-vector operations ---------------------------- diff --git a/src/engine/engine_util_sparse_avx.h b/src/engine/engine_util_sparse_avx.h index f962975c..c7f2f219 100644 --- a/src/engine/engine_util_sparse_avx.h +++ b/src/engine/engine_util_sparse_avx.h @@ -16,7 +16,7 @@ #define MUJOCO_SRC_ENGINE_ENGINE_UTIL_SPARSE_AVX_H_ #ifdef mjUSEPLATFORMSIMD -#if defined(__AVX__) && defined(mjUSEDOUBLE) +#if defined(__AVX__) && !defined(mjUSESINGLE) #define mjUSEAVX @@ -315,7 +315,7 @@ int mju_compare_avx(const int* vec1, const int* vec2, int n) { return !memcmp(vec1+i, vec2+i, (n-i)*sizeof(int)); } -#endif // defined(__AVX__) && defined(mjUSEDOUBLE) +#endif // defined(__AVX__) && !defined(mjUSESINGLE) #endif // mjUSEPLATFORMSIMD diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 2e791f25..0d551cdd 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -61,7 +61,6 @@ public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJSPEC_H_ = true; public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTHREAD_H_ = true; public const int mjMAXTHREAD = 128; public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTNUM_H_ = true; -public const bool mjUSEDOUBLE = true; public const double mjMINVAL = 1e-15; public const bool THIRD_PARTY_MUJOCO_MJUI_H_ = true; public const int mjMAXUISECT = 10;