Fix type-related issues in dependent code. Remove hardcoded mjUSEDOUBLE. Add mjUSESINGLE compiler flag.
This CL does not change the default build behavior of MuJoCo. To use single-precision floating-point, build MuJoCo with `-DmjUSESINGLE`. PiperOrigin-RevId: 644782648 Change-Id: Ie815df9916798ca8054306437b39a33f84ce9e08
This commit is contained in:
committed by
Copybara-Service
parent
7bd7065e0e
commit
3f3b39bbb1
@@ -534,6 +534,14 @@ shown in the table below. Their names are in the format ``mjKEY_XXX``. They corr
|
|||||||
Macros
|
Macros
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
.. _mjUSESINGLE:
|
||||||
|
|
||||||
|
mjUSESINGLE
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
Compile-time flag, see :ref:`mjtNum`.
|
||||||
|
|
||||||
.. _mjDISABLED:
|
.. _mjDISABLED:
|
||||||
|
|
||||||
mjDISABLED
|
mjDISABLED
|
||||||
|
|||||||
@@ -54,24 +54,28 @@ The two types below are defined in `mjtnum.h <https://github.com/google-deepmind
|
|||||||
mjtNum
|
mjtNum
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
This is the floating-point type used throughout the simulator. If the symbol ``mjUSEDOUBLE`` is defined in
|
This is the floating-point type used throughout the simulator. When using the default build configuration, ``mjtNum`` is
|
||||||
``mjmodel.h``, this type is defined as ``double``, otherwise it is defined as ``float``. Currently only the
|
defined as ``double``. If the symbol ``mjUSESINGLE`` is defined, ``mjtNum`` is defined as ``float``.
|
||||||
double-precision version of MuJoCo is distributed, although the entire code base works with single-precision as well.
|
|
||||||
We may release the single-precision version in the future for efficiency reasons, but the double-precision version
|
|
||||||
will always be available. Thus it is safe to write user code assuming double precision. However, our preference is to
|
|
||||||
write code that works with either single or double precision. To this end we provide math utility functions that are
|
|
||||||
always defined with the correct floating-point type.
|
|
||||||
|
|
||||||
Note that changing ``mjUSEDOUBLE`` in ``mjtnum.h`` will not change how the library was compiled, and instead will
|
Currently only the double-precision version of MuJoCo is distributed, although the entire code base works with
|
||||||
|
single-precision as well. We may release the single-precision version in the future, but the
|
||||||
|
double-precision version will always be available. Thus it is safe to write user code assuming double precision.
|
||||||
|
However, our preference is to write code that works with either single or double precision. To this end we provide math
|
||||||
|
utility functions that are always defined with the correct floating-point type.
|
||||||
|
|
||||||
|
Note that changing ``mjUSESINGLE`` in ``mjtnum.h`` will not change how the library was compiled, and instead will
|
||||||
result in numerous link errors. In general, the header files distributed with precompiled MuJoCo should never be
|
result in numerous link errors. In general, the header files distributed with precompiled MuJoCo should never be
|
||||||
changed by the user.
|
changed by the user.
|
||||||
|
|
||||||
.. code-block:: C
|
.. code-block:: C
|
||||||
|
|
||||||
#ifdef mjUSEDOUBLE
|
// floating point data type and minval
|
||||||
typedef double mjtNum;
|
#ifndef mjUSESINGLE
|
||||||
|
typedef double mjtNum;
|
||||||
|
#define mjMINVAL 1E-15 // minimum value in any denominator
|
||||||
#else
|
#else
|
||||||
typedef float mjtNum;
|
typedef float mjtNum;
|
||||||
|
#define mjMINVAL 1E-15f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -25,12 +25,18 @@ General
|
|||||||
5. Added support for ``ball`` joints in the URDF parser ("spherical" in URDF).
|
5. Added support for ``ball`` joints in the URDF parser ("spherical" in URDF).
|
||||||
6. Deprecated :ref:`mju_rotVecMat` and :ref:`mju_rotVecMatT` in favor of :ref:`mju_mulMatVec3` and
|
6. Deprecated :ref:`mju_rotVecMat` and :ref:`mju_rotVecMatT` in favor of :ref:`mju_mulMatVec3` and
|
||||||
:ref:`mju_mulMatTVec3`. These functions names and argument ordering are more consistent with the rest of the API.
|
:ref:`mju_mulMatTVec3`. These functions names and argument ordering are more consistent with the rest of the API.
|
||||||
|
7. Replaced ``mjUSEDOUBLE`` which was previously hard-coded in
|
||||||
|
`mjtnum.h <https://github.com/google-deepmind/mujoco/blob/main/include/mujoco/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
|
MJX
|
||||||
~~~
|
~~~
|
||||||
7. Added support for :ref:`elliptic friction cones<option-cone>`.
|
8. Added support for :ref:`elliptic friction cones<option-cone>`.
|
||||||
8. Fixed a bug that resulted in less-optimal linesearch solutions for some difficult constraint settings.
|
9. 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.
|
10. Fixed a bug in the Newton solver that sometimes resulted in less-optimal gradients.
|
||||||
|
|
||||||
|
|
||||||
.. youtube:: P83tKA1iz2Y
|
.. youtube:: P83tKA1iz2Y
|
||||||
@@ -39,8 +45,8 @@ MJX
|
|||||||
|
|
||||||
Simulate
|
Simulate
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
10. Added improved tutorial video.
|
11. Added improved tutorial video.
|
||||||
11. Improved the Brownian noise generator.
|
12. Improved the Brownian noise generator.
|
||||||
|
|
||||||
|br| |br| |br| |br|
|
|br| |br| |br| |br|
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,8 @@
|
|||||||
|
|
||||||
//---------------------------------- floating-point definition -------------------------------------
|
//---------------------------------- floating-point definition -------------------------------------
|
||||||
|
|
||||||
// compile-time configuration options
|
|
||||||
#define mjUSEDOUBLE // single or double precision for mjtNum
|
|
||||||
|
|
||||||
|
|
||||||
// floating point data type and minval
|
// floating point data type and minval
|
||||||
#ifdef mjUSEDOUBLE
|
#ifndef mjUSESINGLE
|
||||||
typedef double mjtNum;
|
typedef double mjtNum;
|
||||||
#define mjMINVAL 1E-15 // minimum value in any denominator
|
#define mjMINVAL 1E-15 // minimum value in any denominator
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -893,7 +893,7 @@ MJAPI int mjs_isWarning(mjSpec* s);
|
|||||||
|
|
||||||
//---------------------------------- Standard math -------------------------------------------------
|
//---------------------------------- Standard math -------------------------------------------------
|
||||||
|
|
||||||
#ifdef mjUSEDOUBLE
|
#if !defined(mjUSESINGLE)
|
||||||
#define mju_sqrt sqrt
|
#define mju_sqrt sqrt
|
||||||
#define mju_exp exp
|
#define mju_exp exp
|
||||||
#define mju_sin sin
|
#define mju_sin sin
|
||||||
|
|||||||
+12
-10
@@ -34,18 +34,17 @@ mjData* d[maxthread];
|
|||||||
// per-thread statistics
|
// per-thread statistics
|
||||||
int contacts[maxthread];
|
int contacts[maxthread];
|
||||||
int constraints[maxthread];
|
int constraints[maxthread];
|
||||||
double simtime[maxthread];
|
mjtNum simtime[maxthread];
|
||||||
|
|
||||||
|
|
||||||
// timer
|
// timer
|
||||||
std::chrono::steady_clock::time_point tm_start;
|
|
||||||
mjtNum gettm(void) {
|
mjtNum gettm(void) {
|
||||||
std::chrono::duration<double, std::micro> elapsed;
|
using std::chrono::steady_clock;
|
||||||
elapsed = std::chrono::steady_clock::now() - tm_start;
|
using Microseconds = std::chrono::duration<double, std::micro>;
|
||||||
|
static steady_clock::time_point tm_start = steady_clock::now();
|
||||||
|
auto elapsed = Microseconds(steady_clock::now() - tm_start);
|
||||||
return elapsed.count();
|
return elapsed.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// deallocate and print message
|
// deallocate and print message
|
||||||
int finish(const char* msg = NULL, mjModel* m = NULL) {
|
int finish(const char* msg = NULL, mjModel* m = NULL) {
|
||||||
// deallocate model
|
// deallocate model
|
||||||
@@ -87,7 +86,7 @@ void simulate(int id, int nstep, mjtNum* ctrl) {
|
|||||||
constraints[id] = 0;
|
constraints[id] = 0;
|
||||||
|
|
||||||
// run and time
|
// run and time
|
||||||
double start = gettm();
|
mjtNum start = gettm();
|
||||||
for (int i=0; i < nstep; i++) {
|
for (int i=0; i < nstep; i++) {
|
||||||
// inject pseudo-random control noise
|
// inject pseudo-random control noise
|
||||||
mju_copy(d[id]->ctrl, ctrl + i*m->nu, m->nu);
|
mju_copy(d[id]->ctrl, ctrl + i*m->nu, m->nu);
|
||||||
@@ -126,7 +125,7 @@ int main(int argc, char** argv) {
|
|||||||
// read arguments
|
// read arguments
|
||||||
int nstep = 10000, nthread = 0, npoolthread = 0;
|
int nstep = 10000, nthread = 0, npoolthread = 0;
|
||||||
// inject small noise by default, to avoid fixed contact state
|
// 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)) {
|
if (argc > 2 && (std::sscanf(argv[2], "%d", &nstep) != 1 || nstep <= 0)) {
|
||||||
return finish("Invalid nstep argument");
|
return finish("Invalid nstep argument");
|
||||||
}
|
}
|
||||||
@@ -149,7 +148,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
// get filename, determine file type
|
// get filename, determine file type
|
||||||
std::string filename(argv[1]);
|
std::string filename(argv[1]);
|
||||||
bool binary = (filename.find(".mjb") != std::string::npos);
|
bool binary = (filename.find(".mjb") != std::string::npos); // NOLINT
|
||||||
|
|
||||||
// load model
|
// load model
|
||||||
char error[1000] = "Could not load binary model";
|
char error[1000] = "Could not load binary model";
|
||||||
@@ -191,8 +190,11 @@ int main(int argc, char** argv) {
|
|||||||
nstep,
|
nstep,
|
||||||
nthread > 1 ? " per thread" : "",
|
nthread > 1 ? " per thread" : "",
|
||||||
m->opt.timestep);
|
m->opt.timestep);
|
||||||
|
if (sizeof(mjtNum) == 4) {
|
||||||
|
std::printf(", using single-precision");
|
||||||
|
}
|
||||||
if (npoolthread > 1) {
|
if (npoolthread > 1) {
|
||||||
std::printf(", using %d threads for engine-internal threadpool", npoolthread);
|
std::printf(", using %d threads", npoolthread);
|
||||||
}
|
}
|
||||||
std::printf("...\n\n");
|
std::printf("...\n\n");
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -12,6 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@@ -334,7 +335,7 @@ void PhysicsLoop(mj::Simulate& sim) {
|
|||||||
|
|
||||||
// misalignment condition: distance from target sim time is bigger than syncmisalign
|
// misalignment condition: distance from target sim time is bigger than syncmisalign
|
||||||
bool misaligned =
|
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
|
// out-of-sync (for any reason): reset sync times, step
|
||||||
if (elapsedSim < 0 || elapsedCPU.count() < 0 || syncCPU.time_since_epoch().count() == 0 ||
|
if (elapsedSim < 0 || elapsedCPU.count() < 0 || syncCPU.time_since_epoch().count() == 0 ||
|
||||||
|
|||||||
@@ -1165,7 +1165,9 @@ void CopyPose(mj::Simulate* sim, const mjModel* m, const mjData* d) {
|
|||||||
|
|
||||||
// millisecond timer, for MuJoCo built-in profiler
|
// millisecond timer, for MuJoCo built-in profiler
|
||||||
mjtNum Timer() {
|
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
|
// clear all times
|
||||||
|
|||||||
@@ -35,9 +35,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#define mjUSEAVX
|
#define mjUSEAVX
|
||||||
#endif // defined(__AVX__) && defined(mjUSEDOUBLE)
|
#endif // defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#endif // mjUSEPLATFORMSIMD
|
#endif // mjUSEPLATFORMSIMD
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include "engine/engine_util_spatial.h"
|
#include "engine/engine_util_spatial.h"
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#define mjUSEAVX
|
#define mjUSEAVX
|
||||||
#include "immintrin.h"
|
#include "immintrin.h"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include <mujoco/mjtnum.h>
|
#include <mujoco/mjtnum.h>
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
#define mjUSEAVX
|
#define mjUSEAVX
|
||||||
#include "immintrin.h"
|
#include "immintrin.h"
|
||||||
#endif
|
#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) {
|
void mju_addScl(mjtNum* res, const mjtNum* vec1, const mjtNum* vec2, mjtNum scl, int n) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
#if defined(__AVX__) && defined(mjUSEAVX) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && defined(mjUSEAVX) && !defined(mjUSESINGLE)
|
||||||
int n_4 = n - 4;
|
int n_4 = n - 4;
|
||||||
|
|
||||||
// vector part
|
// vector part
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ extern "C" {
|
|||||||
|
|
||||||
//------------------------------ standard library functions ----------------------------------------
|
//------------------------------ standard library functions ----------------------------------------
|
||||||
|
|
||||||
#ifdef mjUSEDOUBLE
|
#if !defined(mjUSESINGLE)
|
||||||
#define mju_sqrt sqrt
|
#define mju_sqrt sqrt
|
||||||
#define mju_exp exp
|
#define mju_exp exp
|
||||||
#define mju_sin sin
|
#define mju_sin sin
|
||||||
@@ -59,7 +59,7 @@ extern "C" {
|
|||||||
#define mju_log10 log10f
|
#define mju_log10 log10f
|
||||||
#define mju_floor floorf
|
#define mju_floor floorf
|
||||||
#define mju_ceil ceilf
|
#define mju_ceil ceilf
|
||||||
#endif
|
#endif // !defined(mjUSESINGLE)
|
||||||
|
|
||||||
|
|
||||||
//------------------------------ 3D vector and matrix-vector operations ----------------------------
|
//------------------------------ 3D vector and matrix-vector operations ----------------------------
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#define MUJOCO_SRC_ENGINE_ENGINE_UTIL_SPARSE_AVX_H_
|
#define MUJOCO_SRC_ENGINE_ENGINE_UTIL_SPARSE_AVX_H_
|
||||||
|
|
||||||
#ifdef mjUSEPLATFORMSIMD
|
#ifdef mjUSEPLATFORMSIMD
|
||||||
#if defined(__AVX__) && defined(mjUSEDOUBLE)
|
#if defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
|
|
||||||
#define mjUSEAVX
|
#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));
|
return !memcmp(vec1+i, vec2+i, (n-i)*sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(__AVX__) && defined(mjUSEDOUBLE)
|
#endif // defined(__AVX__) && !defined(mjUSESINGLE)
|
||||||
|
|
||||||
#endif // mjUSEPLATFORMSIMD
|
#endif // mjUSEPLATFORMSIMD
|
||||||
|
|
||||||
|
|||||||
@@ -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 bool THIRD_PARTY_MUJOCO_INCLUDE_MJTHREAD_H_ = true;
|
||||||
public const int mjMAXTHREAD = 128;
|
public const int mjMAXTHREAD = 128;
|
||||||
public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTNUM_H_ = true;
|
public const bool THIRD_PARTY_MUJOCO_INCLUDE_MJTNUM_H_ = true;
|
||||||
public const bool mjUSEDOUBLE = true;
|
|
||||||
public const double mjMINVAL = 1e-15;
|
public const double mjMINVAL = 1e-15;
|
||||||
public const bool THIRD_PARTY_MUJOCO_MJUI_H_ = true;
|
public const bool THIRD_PARTY_MUJOCO_MJUI_H_ = true;
|
||||||
public const int mjMAXUISECT = 10;
|
public const int mjMAXUISECT = 10;
|
||||||
|
|||||||
Reference in New Issue
Block a user