-
Notifications
You must be signed in to change notification settings - Fork 0
C99 Complex Special Files
This page is intended as a nexus for the checking of the C99 complex number transition. We need as many eyes on this as we can get, to get things over with fast and to reduce the amount of effort for each individual involved. Since we're here anyway, this may actually be a good time to do a small code review and clean up some of those pet peeves we all have.
Since we're talking about a large number of changes, we want to minimize the amount of redundancy in the process. While it is possible to suggest corrections through comments, this is a slow process that requires thinking, writing and reading by both the spotter of a problem and the person to correct it. This is not only extra tedious, it also introduces a serious risk of suggestions getting lost.
Instead, we can leverage git for this, through the following work flow. To start, check out the c99_complex
branch from deuzeman/tmLQCD
. Pick one ore more files you want to audit and remove them from this page. Now make any corrections that you believe are needed or just aesthetically pleasing and commit them to your fork. Send a pull request to the deuzeman/tmLQCD/c99_complex
branch, where they'll be picked up. Don't worry about sending pull requests for small numbers of files, or even single ones. Small requests are easier to manage and we're not going to round out of integers to number them any time soon.
As those of you who have been looking at the branch will have noticed, there are a number of not-so-serious issues that one may encounter. These are usually related to the fact that a sed script was used to do many of the replacements. Common 'problems' are the replacing of complex
by _Complex double
in comments, or the removal of parentheses around assignment operations that reduce readability even if things remain syntactically correct.
Tangentially related are missing (or weird) replacements of (*x).
by x->
. This is a change that was included in the script because many of the macros for SU(3) algebra, for example, contained loads of these. Note that this shouldn't cause problems with parentheses missing in macros, because the dereference was already inside the parentheses and the potential (*(x)).
is still replaced correctly by (x)->
. Otherwise, there are points where code starts to look ugly when macros are removed. Feel free to rewrite such sections, of course. Finally, the removal of the SVN $Id
comment lines may have gone bad at points. These are just comments, but we should probably remove those whenever we find them.
Within the branch deuzeman/tmLQCD/c99_complex
, the code compiles for a subset of possible configurations. That suggests that you shouldn't find many syntactically invalid statements anymore, but the worry is about changes in meaning. Files that are particularly likely to have this type of problem are marked specially below and should be gone over carefully. The other straightforward test is running the compiled code and checking the results versus etmc/tmLQCD/master
. That test, ideally, also includes some performance comparison. If you feel like running such a test, please indicate below -- just to minimize duplication of effort.
Finally, don't hesitate to ask if something seems weird! Or, of course, if you disagree with anything said here... :)
-
When assigning a variable of type
_Complex double
to adouble
, the imaginary part is simply truncated. That is, we don't need to callcreal()
when we, for example, want to calculate the norm squared of a complex number. -
A special function
cabs
exists to calculate the norm of a complex number without loss of precision. Use this instead ofsqrt(conj(x) * x)
, which is actually numerically dubious. -
This is perhaps superfluous, but
cimag
andcreal
return rvalues and cannot be assigned to! If you want to assign just to the real part, simply assign the real number to the complex variable! Similarly, use the predefined constantI
to create purely imaginary numbers in an assignment. -
It doesn't make much sense to write things like
double x = 1.0; float y = (double)x;
. The compiler will pretty much figure out what it needs to do when assigning doubles and floats to each other. Few of the special purpose macros for different precisions actually did anything. -
The operator
->
was provided specifically to be completely equivalent to(*x).
, but more readable. There is no reason not to use it. -
Support for APENext was removed.
When checking the files below, pay special attention to those that...
-
... are in the
solver
directory! These routines contain many 'loose' occurrences of complex numbers. Minus signs may have mysteriously appeared or vanished. -
... are in the
linalg
directory! The old versions of the routines were often kind of hard to read and the naming scheme not always equally clarifying. Convince yourself that they actually do as they're supposed to. -
... implement SU(3) algebra! Just because of the large number of changes here. But easy to check, because it's often clear enough what any function/macro is supposed to do.
-
... use operator assignment! There was an oversight in the sed script that may not have been cleaned up everywhere. Sometimes code like
x.re *= y; x.im *= y;
was replaced byx *= y + cimag(x); x *= I * y + creal(x);
. This is not so good... Note that any use ofx.re *= y
without the corresponding imaginary operation is highly dubious at any rate. It occurred once, where a complex number was used to store real numbers once in a while. Here we could simply writex *= y
, but it would probably be better to just use an additionaldouble
.
- hmc_tm
- invert
- ???
- block.c
- eigenvalues_bi.c
- hopping_test.c
- invert_eo.c
- invert_overlap.c
- little_D.c
- monomial.c
- operator/halfspinor_dbl.c
- overrelaxation.c
- polyakov_loop.c
- polyakov_loop.h
- reweighting_factor_nd.c
- sf_calc_action.c
- solver/bicgstab_complex.c
- solver/bicgstab_complex_bi.c
- solver/chrono_guess.c
- solver/dfl_projector.c
- solver/dfl_projector.h
- solver/diagonalise_general_matrix.c
- solver/diagonalise_general_matrix.h
- solver/dirac_operator_eigenvectors.c
- solver/dirac_operator_eigenvectors.h
- solver/eigenvalues.c
- solver/fgmres.c
- solver/fgmres.h
- solver/generate_dfl_subspace.c
- solver/generate_dfl_subspace.h
- solver/gmres.c
- solver/gmres.h
- solver/gmres_dr.c
- solver/gmres_dr.h
- solver/gmres_precon.h
- solver/gram-schmidt.c
- solver/gram-schmidt.h
- solver/gram-schmidt_bi.c
- solver/gram-schmidt_bi.h
- solver/index_jd.c
- solver/jdher.c
- solver/jdher.h
- solver/jdher_bi.c
- solver/jdher_bi.h
- solver/jdher_su3vect.h
- solver/lu_solve.c
- solver/lu_solve.h
- solver/matrix_mult_typedef.h
- solver/matrix_mult_typedef_bi.h
- solver/matrix_mult_typedef_nd.h
- solver/mr.c
- solver/pcg_her.c
- solver/pjdher_bi.h
- solver/sub_low_ev.c
- solver/sumr.c
- source_generation.c
- sse.h
- sse3.h
- su3adj.h
- temporalgauge.c
- test/check_nan.c
- test/overlaptests.c
- test/overlaptests.h
- test/scalar_prod_r_test.c
- test/test_eigenvalues.c
- D_psi.c (Bartek)
- Dov_psi.c (Albert)
- Hopping_Matrix.c (Albert)
- Makefile.in (Albert)
- Nondegenerate_Matrix.c (Albert)
- Nondegenerate_Matrix.h (Albert)
- benchmark.c (Albert)
- block.h (Albert)
- boundary.c (Albert)
- boundary.h (Albert)
- check_locallity.c (Albert)
- clover_leaf.c (Siebren/Albert)
- complex.h (Albert)
- configure.in (Albert)
- deriv_Sb.c (Albert)
- expo.c (Albert)
- init_jacobi_field.c (Albert)
- io/utils.c (Albert)
- jacobi.c (Albert)
- linalg/add.c (Albert)
- linalg/assign.c (Albert)
- linalg/assign_add_mul.c (Albert)
- linalg/assign_add_mul.h (Albert)
- linalg/assign_add_mul_add_mul_bi.c (Albert)
- linalg/assign_add_mul_add_mul_r.c (Albert)
- linalg/assign_add_mul_r_add_mul.c (Albert)
- linalg/assign_add_mul_r_bi.c (Albert)
- linalg/assign_add_mul_add_mul.c (Albert)
- linalg/assign_add_mul_add_mul.h (Albert)
- linalg/assign_add_mul_add_mul_bi.h (Albert)
- linalg/assign_add_mul_r.c (Albert)
- linalg/assign_bi.c (Albert)
- linalg/assign_diff_mul.h (Albert)
- linalg/assign_diff_mul.c (Albert)
- linalg/assign_diff_mul_bi.c (Albert)
- linalg/assign_diff_mul_bi.h (Albert)
- linalg/assign_mul_add_mul_add_mul_add_mul_r.c (Albert)
- linalg/assign_mul_add_mul_add_mul_r.c (Albert)
- linalg/assign_mul_add_mul_r.c (Albert)
- linalg/assign_mul_add_r.c (Albert)
- linalg/assign_mul_add_r_bi.c (Albert)
- linalg/assign_mul_bra_add_mul_ket_add_bi.c (Albert)
- linalg/assign_mul_bra_add_mul_ket_add_bi.h (Albert)
- linalg/assign_mul_bra_add_mul_ket_add_r.c (Albert)
- linalg/assign_mul_bra_add_mul_r.c (Albert)
- linalg/assign_mul_bra_add_mul_ket_add.c (Albert)
- linalg/assign_mul_bra_add_mul_ket_add.h (Albert)
- linalg/diff.c (Albert)
- linalg/diff_and_square_norm.c (Albert)
- linalg/diff_bi.c (Albert)
- linalg/mul.c (Albert)
- linalg/mul.h (Albert)
- linalg/mul_add_mul.c (Albert)
- linalg/mul_add_mul.h (Albert)
- linalg/mul_add_mul_r.c (Albert)
- linalg/mul_diff_mul.c (Albert)
- linalg/mul_diff_mul.h (Albert)
- linalg/mul_diff_mul_r.c (Albert)
- linalg/mul_diff_mul_r.h (Albert)
- linalg/mul_diff_r.c (Albert)
- linalg/mul_r.c (Albert)
- linalg/mul_r_bi.c (Albert)
- linalg/blas.h (Albert)
- linalg/comp_decomp.c (Albert)
- linalg/convert_eo_to_lexic.c (Albert)
- linalg/lapack.h (Albert)
- linalg/map_to_blas.h (Albert)
- linalg/mattimesvec.c (Albert)
- linalg/mattimesvec.h (Albert)
- linalg/square_and_prod_r.c (Albert)
- linalg/square_norm.c (Albert)
- linalg/square_norm_bi.c (Albert)
- linalg/scalar_prod.c (Albert)
- linalg/scalar_prod.h (Albert)
- linalg/scalar_prod_bi.c (Albert)
- linalg/scalar_prod_bi.h (Albert)
- linalg/scalar_prod_i.c (Albert)
- linalg/scalar_prod_r.c (Albert)
- linalg/scalar_prod_r_bi.c (Albert)
- linalg/scalar_prod_su3spinor.c (Albert)
- linsolve.c (Albert)
- little_D.h (Albert)
- monomial.h (Albert)
- operator.h (Albert)
- phmc.c (Albert)
- phmc.h (Albert)
- solver/gcr.c (Albert)
- solver/gcr4complex.c (Albert)
- solver/gcr4complex.h (Albert)
- start.c (Albert)
- su3.h (Albert)
- su3spinor.h (Albert)
- tm_operators.c (Bartek)
- update_tm.c (Albert)
- xchange_field.c (Albert)