Bill-Gray / find_orb

Orbit determination from observations
https://www.projectpluto.com/find_orb.htm
GNU General Public License v2.0
97 stars 45 forks source link

ARM g++ unable to compile lsquare.cpp #37

Closed spenczar closed 1 year ago

spenczar commented 1 year ago

I'm working on an Apple Macbook M1 ("Apple Silicon") which is an ARM platform.

After resolving #36, g++ hits many errors in compiling lsquare.cpp:

g++ -c -Wall -pedantic -Wextra -Werror  -I ~/include -O3 lsquare.cpp

lsquare.cpp:48:20: error: '__float128' does not name a type; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:58:4: note: in expansion of macro 'ldouble'
   58 |    ldouble *wtw, *uw;
      |    ^~~~~~~
lsquare.cpp: In function 'void* lsquare_init(int)':
lsquare.cpp:69:10: error: 'struct lsquare' has no member named 'uw'
   69 |    rval->uw = (ldouble *)calloc( (n_params + 1) * n_params, sizeof( ldouble));
      |          ^~
lsquare.cpp:48:20: error: '__float128' was not declared in this scope; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:69:16: note: in expansion of macro 'ldouble'
   69 |    rval->uw = (ldouble *)calloc( (n_params + 1) * n_params, sizeof( ldouble));
      |                ^~~~~~~
lsquare.cpp:69:25: error: expected primary-expression before ')' token
   69 |    rval->uw = (ldouble *)calloc( (n_params + 1) * n_params, sizeof( ldouble));
      |                         ^
lsquare.cpp:70:10: error: 'struct lsquare' has no member named 'wtw'
   70 |    rval->wtw = rval->uw + n_params;
      |          ^~~
lsquare.cpp:70:22: error: 'struct lsquare' has no member named 'uw'
   70 |    rval->wtw = rval->uw + n_params;
      |                      ^~
lsquare.cpp: In function 'int lsquare_add_observation(void*, double, double, const double*)':
lsquare.cpp:48:20: error: '__float128' does not name a type; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:115:13: note: in expansion of macro 'ldouble'
  115 |       const ldouble w2_obs_i = (ldouble)( weight * weight * obs[i]);
      |             ^~~~~~~
lsquare.cpp:117:12: error: 'struct lsquare' has no member named 'uw'
  117 |       lsq->uw[i] += (ldouble)residual * w2_obs_i;
      |            ^~
lsquare.cpp:48:20: error: '__float128' was not declared in this scope; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:117:22: note: in expansion of macro 'ldouble'
  117 |       lsq->uw[i] += (ldouble)residual * w2_obs_i;
      |                      ^~~~~~~
lsquare.cpp:119:15: error: 'struct lsquare' has no member named 'wtw'
  119 |          lsq->wtw[i + j * n_params] += w2_obs_i * (ldouble)obs[j];
      |               ^~~
lsquare.cpp:119:40: error: 'w2_obs_i' was not declared in this scope
  119 |          lsq->wtw[i + j * n_params] += w2_obs_i * (ldouble)obs[j];
      |                                        ^~~~~~~~
lsquare.cpp:120:12: error: 'struct lsquare' has no member named 'wtw'
  120 |       lsq->wtw[i + i * n_params] +=
      |            ^~~
lsquare.cpp:121:19: error: 'w2_obs_i' was not declared in this scope
  121 |                   w2_obs_i * (ldouble)( obs[i] * levenberg_marquardt_lambda);
      |                   ^~~~~~~~
lsquare.cpp:106:58: error: unused parameter 'residual' [-Werror=unused-parameter]
  106 | int lsquare_add_observation( void *lsquare, const double residual,
      |                                             ~~~~~~~~~~~~~^~~~~~~~
lsquare.cpp:107:48: error: unused parameter 'weight' [-Werror=unused-parameter]
  107 |                                   const double weight, const double *obs)
      |                                   ~~~~~~~~~~~~~^~~~~~
lsquare.cpp: At global scope:
lsquare.cpp:48:20: error: '__float128' does not name a type; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:127:1: note: in expansion of macro 'ldouble'
  127 | ldouble lsquare_determinant;
      | ^~~~~~~
lsquare.cpp:48:20: error: '__float128' does not name a type; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:160:8: note: in expansion of macro 'ldouble'
  160 | static ldouble pivot_value( const ldouble *line, const unsigned line_size)
      |        ^~~~~~~
lsquare.cpp:48:20: error: '__float128' does not name a type; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:172:8: note: in expansion of macro 'ldouble'
  172 | static ldouble *calc_inverse( const ldouble *src, const int size)
      |        ^~~~~~~
lsquare.cpp:353:13: error: variable or field 'mult_matrices' declared void
  353 | static void mult_matrices( ldouble *prod, const ldouble *a, const int awidth,
      |             ^~~~~~~~~~~~~
lsquare.cpp:48:20: error: '__float128' was not declared in this scope; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:353:28: note: in expansion of macro 'ldouble'
  353 | static void mult_matrices( ldouble *prod, const ldouble *a, const int awidth,
      |                            ^~~~~~~
lsquare.cpp:353:37: error: 'prod' was not declared in this scope
  353 | static void mult_matrices( ldouble *prod, const ldouble *a, const int awidth,
      |                                     ^~~~
lsquare.cpp:353:43: error: expected primary-expression before 'const'
  353 | static void mult_matrices( ldouble *prod, const ldouble *a, const int awidth,
      |                                           ^~~~~
lsquare.cpp:353:61: error: expected primary-expression before 'const'
  353 | static void mult_matrices( ldouble *prod, const ldouble *a, const int awidth,
      |                                                             ^~~~~
lsquare.cpp:354:19: error: expected primary-expression before 'const'
  354 |                   const int aheight, const ldouble *b, const int bwidth)
      |                   ^~~~~
lsquare.cpp:354:38: error: expected primary-expression before 'const'
  354 |                   const int aheight, const ldouble *b, const int bwidth)
      |                                      ^~~~~
lsquare.cpp:354:56: error: expected primary-expression before 'const'
  354 |                   const int aheight, const ldouble *b, const int bwidth)
      |                                                        ^~~~~
lsquare.cpp:48:20: error: '__float128' does not name a type; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:385:8: note: in expansion of macro 'ldouble'
  385 | static ldouble *calc_inverse_improved( const ldouble *src, const int size)
      |        ^~~~~~~
lsquare.cpp: In function 'int lsquare_solve(const void*, double*)':
lsquare.cpp:48:20: error: '__float128' was not declared in this scope; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:428:4: note: in expansion of macro 'ldouble'
  428 |    ldouble *inverse;
      |    ^~~~~~~
lsquare.cpp:428:13: error: 'inverse' was not declared in this scope
  428 |    ldouble *inverse;
      |             ^~~~~~~
lsquare.cpp:434:42: error: 'const struct lsquare' has no member named 'wtw'
  434 |    inverse = calc_inverse_improved( lsq->wtw, n_params);
      |                                          ^~~
lsquare.cpp:434:14: error: 'calc_inverse_improved' was not declared in this scope
  434 |    inverse = calc_inverse_improved( lsq->wtw, n_params);
      |              ^~~~~~~~~~~~~~~~~~~~~
lsquare.cpp:440:15: error: expected ';' before 'temp_result'
  440 |       ldouble temp_result = 0;
      |               ^~~~~~~~~~~
lsquare.cpp:443:10: error: 'temp_result' was not declared in this scope
  443 |          temp_result += inverse[i + j * n_params] * lsq->uw[j];
      |          ^~~~~~~~~~~
lsquare.cpp:443:58: error: 'const struct lsquare' has no member named 'uw'
  443 |          temp_result += inverse[i + j * n_params] * lsq->uw[j];
      |                                                          ^~
lsquare.cpp:444:27: error: 'temp_result' was not declared in this scope
  444 |       result[i] = (double)temp_result;
      |                           ^~~~~~~~~~~
lsquare.cpp: At global scope:
lsquare.cpp:48:20: error: '__float128' does not name a type; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:451:56: note: in expansion of macro 'ldouble'
  451 | static double *convert_ldouble_matrix_to_double( const ldouble *matrix,
      |                                                        ^~~~~~~
lsquare.cpp: In function 'double* lsquare_covariance_matrix(const void*)':
lsquare.cpp:48:20: error: '__float128' was not declared in this scope; did you mean '_Float128'?
   48 | #define ldouble    __float128
      |                    ^~~~~~~~~~
lsquare.cpp:465:4: note: in expansion of macro 'ldouble'
  465 |    ldouble *lrval = NULL;
      |    ^~~~~~~
lsquare.cpp:465:13: error: 'lrval' was not declared in this scope
  465 |    ldouble *lrval = NULL;
      |             ^~~~~
lsquare.cpp:468:43: error: 'const struct lsquare' has no member named 'wtw'
  468 |       lrval = calc_inverse_improved( lsq->wtw, lsq->n_params);
      |                                           ^~~
lsquare.cpp:468:15: error: 'calc_inverse_improved' was not declared in this scope
  468 |       lrval = calc_inverse_improved( lsq->wtw, lsq->n_params);
      |               ^~~~~~~~~~~~~~~~~~~~~
lsquare.cpp: In function 'double* lsquare_wtw_matrix(const void*)':
lsquare.cpp:485:51: error: 'const struct lsquare' has no member named 'wtw'
  485 |    return( convert_ldouble_matrix_to_double( lsq->wtw, lsq->n_params));
      |                                                   ^~~
lsquare.cpp: In function 'void lsquare_free(void*)':
lsquare.cpp:492:15: error: 'const struct lsquare' has no member named 'uw'
  492 |    free( lsq->uw);
      |               ^~
lsquare.cpp: In function 'double* lsquare_covariance_matrix(const void*)':
lsquare.cpp:467:30: error: control reaches end of non-void function [-Werror=return-type]
  467 |    if( lsq->n_params <= lsq->n_obs)       /* got enough observations */
      |                         ~~~~~^~~~~
lsquare.cpp: At global scope:
lsquare.cpp:451:16: error: 'double* convert_ldouble_matrix_to_double(const int*, int)' defined but not used [-Werror=unused-function]
  451 | static double *convert_ldouble_matrix_to_double( const ldouble *matrix,
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is after using same setup that I described in #36.

spenczar commented 1 year ago

If I naively change from __float128 to _Float128, everything Just Works, and I get no errors:

--- a/lsquare.cpp
+++ b/lsquare.cpp
@@ -45,7 +45,7 @@ idea for nearly-singular matrices.  */
       with a mere 52 bits of precision.   */

 #if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 && !defined( __arm__)
-#define ldouble    __float128
+#define ldouble    _Float128
 #else
 #define ldouble    long double
 #endif

I don't know anything about what this change really means, or whether this would break builds on other platforms (presumably yes?), but it resolves it for my particular machine.

Bill-Gray commented 1 year ago

I'm afraid _Float128 doesn't work on x64. And it sounds as if even though the M1 is an ARM device, __arm__ isn't being defined. Will look tomorrow for a suitable predefined constant so we can say

#if defined( __M1__)
   #define ldouble _Float128
#else
   (define ldouble to be _float128 or long double in the existing way)
#endif

As with issue #36, I expect you may find other issues of which I knew not (I lack a machine with an M1, sadly... not a Mac fan in general, but these do sound quite nice.) Please continue letting me know what you see.

spenczar commented 1 year ago

That makes sense. I suspect the right macro might be "aarch64", which is the label used for 64-bit ARM in quite a few places.

It's a nice machine, but I find that architecture compatibility issues come up about once a week for me. We all sure got used to that x86 monopoly!

Bill-Gray commented 1 year ago

Yes, I should probably at least get a Raspberry Pi for testing purposes.

This link suggests we should be using __aarch64__. If you find that revising lsquare.cpp to say

#if defined( __aarch64__)
   #define ldouble _Float128
#elif ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 && !defined( __arm__)
   #define ldouble    __float128
#else
   #define ldouble    long double
#endif

then I'll modify the code accordingly. Seems to be the only place in my code where I've resorted to quad float math.

Thanks for the report on this. I expect others are either already trying to run this code on M1 and M2 devices, or they will be trying to do so. So it'll be good to get these problems fixed.

Bill-Gray commented 1 year ago

Ping @spenczar : wondered if you'd found a fix, either the above or something else? I'm reasonably sure the above would work, but thought I'd ask you before just blindly committing a patch. Any other M1/M2 issues that I should know about? Thanks!

spenczar commented 1 year ago

Oh, thanks for the reminder, and sorry for the long silence!

I haven't looked at this much since about March, but I believe your recommendation worked. I didn't hit any other issues compiling the code. Of course, correctness issues may lurk in there, much trickier to discover, but I don't believe I found any other problems.

Bill-Gray commented 1 year ago

Excellent. I've committed the fix in question. Thanks!

nugent-lab commented 1 year ago

Hi Bill- unfortunately that fix is causing errors for me (M2 chip, Ventura 13) with lsquare.cpp. There's a string of errors, such as: lsquare.cpp:60:4: error: unknown type name '_Float128' I'm looking into it, will update if I find a fix.

Bill-Gray commented 1 year ago

Hi Carrie - well, that's interesting... guess this isn't as simple as it looked. Things rarely are, of course.

I'll guess that we'll have to add some sort of #ifdef __M2__ option that then gets ldouble properly #defined. If so, it shouldn't be too tricky.