mirror of
https://github.com/TREX-CoE/qmckl.git
synced 2024-10-02 14:31:07 +02:00
Precision adjusted for MOs
This commit is contained in:
parent
f150eb1610
commit
27b1134a4c
@ -5539,7 +5539,7 @@ end function qmckl_compute_ao_value_doc
|
|||||||
/* Don't compute polynomials when the radial part is zero. */
|
/* Don't compute polynomials when the radial part is zero. */
|
||||||
const int precision = ctx->numprec.precision;
|
const int precision = ctx->numprec.precision;
|
||||||
const double cutoff = log( (double) ( ((uint64_t) 1) << (precision-2) ) );
|
const double cutoff = log( (double) ( ((uint64_t) 1) << (precision-2) ) );
|
||||||
const bool double_precision = precision > 23;
|
const bool double_precision = precision > 22;
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
@ -5736,15 +5736,6 @@ IVDEP
|
|||||||
const int32_t n = lstart[l+1]-lstart[l];
|
const int32_t n = lstart[l+1]-lstart[l];
|
||||||
|
|
||||||
if (s1 == 0.0) {
|
if (s1 == 0.0) {
|
||||||
/*
|
|
||||||
IVDEP
|
|
||||||
#ifdef HAVE_OPENMP
|
|
||||||
#pragma omp simd
|
|
||||||
#endif
|
|
||||||
for (int64_t il=0 ; il<n ; ++il) {
|
|
||||||
ao_value_1[il] = 0.;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,7 +1324,6 @@ qmckl_compute_mo_basis_mo_value_hpc_sp (const qmckl_context context,
|
|||||||
double* restrict const vgl1 = &(mo_value[ipoint*mo_num]);
|
double* restrict const vgl1 = &(mo_value[ipoint*mo_num]);
|
||||||
const double* restrict avgl1 = &(ao_value[ipoint*ao_num]);
|
const double* restrict avgl1 = &(ao_value[ipoint*ao_num]);
|
||||||
|
|
||||||
// memset(vgl_sp, 0, mo_num*sizeof(float));
|
|
||||||
float* __attribute__((aligned(64))) vgl_sp = calloc((size_t) mo_num, sizeof(float));
|
float* __attribute__((aligned(64))) vgl_sp = calloc((size_t) mo_num, sizeof(float));
|
||||||
assert (vgl_sp != NULL);
|
assert (vgl_sp != NULL);
|
||||||
|
|
||||||
@ -1409,7 +1408,7 @@ qmckl_compute_mo_basis_mo_value_hpc (const qmckl_context context,
|
|||||||
|
|
||||||
/* Don't compute polynomials when the radial part is zero. */
|
/* Don't compute polynomials when the radial part is zero. */
|
||||||
const int precision = ctx->numprec.precision;
|
const int precision = ctx->numprec.precision;
|
||||||
const bool single_precision = precision <= 23;
|
const bool single_precision = precision <= 24;
|
||||||
|
|
||||||
if (single_precision) {
|
if (single_precision) {
|
||||||
return qmckl_compute_mo_basis_mo_value_hpc_sp (context,
|
return qmckl_compute_mo_basis_mo_value_hpc_sp (context,
|
||||||
@ -1442,6 +1441,7 @@ qmckl_compute_mo_basis_mo_value_hpc (const qmckl_context context,
|
|||||||
int64_t nidx=0;
|
int64_t nidx=0;
|
||||||
int64_t idx[ao_num];
|
int64_t idx[ao_num];
|
||||||
double av1[ao_num];
|
double av1[ao_num];
|
||||||
|
|
||||||
for (int64_t k=0 ; k<ao_num ; ++k) {
|
for (int64_t k=0 ; k<ao_num ; ++k) {
|
||||||
if (avgl1[k] != 0.) {
|
if (avgl1[k] != 0.) {
|
||||||
idx[nidx] = k;
|
idx[nidx] = k;
|
||||||
@ -1924,7 +1924,7 @@ qmckl_compute_mo_basis_mo_vgl_hpc (const qmckl_context context,
|
|||||||
|
|
||||||
/* Don't compute polynomials when the radial part is zero. */
|
/* Don't compute polynomials when the radial part is zero. */
|
||||||
const int precision = ctx->numprec.precision;
|
const int precision = ctx->numprec.precision;
|
||||||
const bool single_precision = precision <= 23;
|
const bool single_precision = precision <= 26;
|
||||||
|
|
||||||
if (single_precision) {
|
if (single_precision) {
|
||||||
return qmckl_compute_mo_basis_mo_vgl_hpc_sp (context,
|
return qmckl_compute_mo_basis_mo_vgl_hpc_sp (context,
|
||||||
@ -3384,7 +3384,7 @@ print ( "[4][1][15][14] : %25.15e"% lf(a,x,y))
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
/* Check single precision */
|
/* Check single precision */
|
||||||
rc = qmckl_set_numprec_precision(context,23);
|
rc = qmckl_set_numprec_precision(context,53);
|
||||||
rc = qmckl_context_touch(context);
|
rc = qmckl_context_touch(context);
|
||||||
assert (rc == QMCKL_SUCCESS);
|
assert (rc == QMCKL_SUCCESS);
|
||||||
|
|
||||||
@ -3394,7 +3394,7 @@ print ( "[4][1][15][14] : %25.15e"% lf(a,x,y))
|
|||||||
rc = qmckl_get_mo_basis_mo_vgl(context, &(mo_vgl[0][0][0]), point_num*5*chbrclf_mo_num);
|
rc = qmckl_get_mo_basis_mo_vgl(context, &(mo_vgl[0][0][0]), point_num*5*chbrclf_mo_num);
|
||||||
assert (rc == QMCKL_SUCCESS);
|
assert (rc == QMCKL_SUCCESS);
|
||||||
|
|
||||||
rc = qmckl_set_numprec_precision(context,24);
|
rc = qmckl_set_numprec_precision(context,23);
|
||||||
rc = qmckl_context_touch(context);
|
rc = qmckl_context_touch(context);
|
||||||
assert (rc == QMCKL_SUCCESS);
|
assert (rc == QMCKL_SUCCESS);
|
||||||
|
|
||||||
@ -3407,31 +3407,45 @@ print ( "[4][1][15][14] : %25.15e"% lf(a,x,y))
|
|||||||
assert (rc == QMCKL_SUCCESS);
|
assert (rc == QMCKL_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t average_prec = 0;
|
||||||
|
int32_t nbits;
|
||||||
for (int i=0 ; i< point_num; ++i) {
|
for (int i=0 ; i< point_num; ++i) {
|
||||||
for (int k=0 ; k< chbrclf_mo_num ; ++k) {
|
for (int k=0 ; k< chbrclf_mo_num ; ++k) {
|
||||||
printf("%d %d %e %e\n", i, k, mo_value_sp[i][k], mo_value[i][k]);
|
nbits = qmckl_test_precision_64(mo_value_sp[i][k], mo_value[i][k]);
|
||||||
assert(fabs((mo_value_sp[i][k] - mo_value[i][k])) < 1.e-4) ;
|
// printf("%d %d %25.15e %25.15e %d\n", i, k, mo_value_sp[i][k], mo_value[i][k], nbits);
|
||||||
|
average_prec += nbits;
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
}
|
}
|
||||||
|
printf("Average precision for %d: %d\n", qmckl_get_numprec_precision(context),
|
||||||
|
(int) (average_prec/(point_num*chbrclf_mo_num)));
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
average_prec = 0;
|
||||||
for (int i=0 ; i< point_num; ++i) {
|
for (int i=0 ; i< point_num; ++i) {
|
||||||
for (int k=0 ; k< chbrclf_mo_num ; ++k) {
|
for (int k=0 ; k< chbrclf_mo_num ; ++k) {
|
||||||
printf("%d %d\n", i, k);
|
// printf("%d %d\n", i, k);
|
||||||
printf("%e %e\n", mo_vgl_sp[i][0][k], mo_vgl[i][0][k]);
|
nbits = qmckl_test_precision_64(mo_vgl_sp[i][0][k], mo_vgl[i][0][k]);
|
||||||
printf("%e %e\n", mo_vgl_sp[i][1][k], mo_vgl[i][1][k]);
|
average_prec += nbits;
|
||||||
printf("%e %e\n", mo_vgl_sp[i][2][k], mo_vgl[i][2][k]);
|
// printf("%25.15e %25.15e %d\n", mo_vgl_sp[i][0][k], mo_vgl[i][0][k], nbits);
|
||||||
printf("%e %e\n", mo_vgl_sp[i][3][k], mo_vgl[i][3][k]);
|
nbits = qmckl_test_precision_64(mo_vgl_sp[i][1][k], mo_vgl[i][1][k]);
|
||||||
printf("%e %e\n", mo_vgl_sp[i][4][k], mo_vgl[i][4][k]);
|
average_prec += nbits;
|
||||||
assert(fabs((mo_vgl_sp[i][0][k] - mo_vgl[i][0][k])) < 1.e-4) ;
|
// printf("%25.15e %25.15e %d\n", mo_vgl_sp[i][1][k], mo_vgl[i][1][k], nbits);
|
||||||
assert(fabs((mo_vgl_sp[i][1][k] - mo_vgl[i][1][k])) < 1.e-3) ;
|
nbits = qmckl_test_precision_64(mo_vgl_sp[i][2][k], mo_vgl[i][2][k]);
|
||||||
assert(fabs((mo_vgl_sp[i][2][k] - mo_vgl[i][2][k])) < 1.e-3) ;
|
average_prec += nbits;
|
||||||
assert(fabs((mo_vgl_sp[i][3][k] - mo_vgl[i][3][k])) < 1.e-3) ;
|
// printf("%25.15e %25.15e %d\n", mo_vgl_sp[i][2][k], mo_vgl[i][2][k], nbits);
|
||||||
assert(fabs((mo_vgl_sp[i][4][k] - mo_vgl[i][4][k])) < 1.e-2) ;
|
nbits = qmckl_test_precision_64(mo_vgl_sp[i][3][k], mo_vgl[i][3][k]);
|
||||||
printf("\n");
|
average_prec += nbits;
|
||||||
|
// printf("%25.15e %25.15e %d\n", mo_vgl_sp[i][3][k], mo_vgl[i][3][k], nbits);
|
||||||
|
nbits = qmckl_test_precision_64(mo_vgl_sp[i][4][k], mo_vgl[i][4][k]);
|
||||||
|
average_prec += nbits;
|
||||||
|
// printf("%25.15e %25.15e %d\n", mo_vgl_sp[i][4][k], mo_vgl[i][4][k], nbits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nbits = (int) (average_prec/(point_num*chbrclf_mo_num*5));
|
||||||
|
printf("Average precision for %d: %d\n", qmckl_get_numprec_precision(context), nbits);
|
||||||
|
fflush(stdout);
|
||||||
rc = qmckl_set_numprec_precision(context,53);
|
rc = qmckl_set_numprec_precision(context,53);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
/* Check selection of MOs */
|
/* Check selection of MOs */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#+TITLE: Numerical precision
|
3+TITLE: Numerical precision
|
||||||
#+SETUPFILE: ../tools/theme.setup
|
#+SETUPFILE: ../tools/theme.setup
|
||||||
#+INCLUDE: ../tools/lib.org
|
#+INCLUDE: ../tools/lib.org
|
||||||
|
|
||||||
@ -366,13 +366,11 @@ double qmckl_get_numprec_epsilon(const qmckl_context context) {
|
|||||||
unchanged, we need a function that returns the number of unchanged
|
unchanged, we need a function that returns the number of unchanged
|
||||||
bits in the range, and in the precision.
|
bits in the range, and in the precision.
|
||||||
|
|
||||||
#+begin_src c :comments org :tangle (eval h_func) :exports none
|
For this, we first count by how many units in the last place (ulps) two
|
||||||
int32_t qmckl_test_precision_64(double a, double b);
|
numbers differ.
|
||||||
int32_t qmckl_test_precision_32(float a, float b);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src c :tangle (eval c)
|
#+begin_src c :tangle (eval c)
|
||||||
int32_t qmckl_test_precision_64(double a, double b) {
|
int64_t countUlpDifference_64(double a, double b) {
|
||||||
|
|
||||||
union int_or_float {
|
union int_or_float {
|
||||||
int64_t i;
|
int64_t i;
|
||||||
@ -382,15 +380,38 @@ int32_t qmckl_test_precision_64(double a, double b) {
|
|||||||
x.f = a;
|
x.f = a;
|
||||||
y.f = b;
|
y.f = b;
|
||||||
|
|
||||||
uint64_t diff = x.i > y.i ? x.i - y.i : y.i - x.i;
|
// Handle sign bit discontinuity: if the signs are different and either value is not zero
|
||||||
|
if ((x.i < 0) != (y.i < 0) && (x.f != 0.0) && (y.f != 0.0)) {
|
||||||
|
// Use the absolute values and add the distance to zero for both numbers
|
||||||
|
int64_t distanceToZeroForX = x.i < 0 ? INT64_MAX + x.i : INT64_MAX - x.i;
|
||||||
|
int64_t distanceToZeroForY = y.i < 0 ? INT64_MAX + y.i : INT64_MAX - y.i;
|
||||||
|
return distanceToZeroForX + distanceToZeroForY;
|
||||||
|
}
|
||||||
|
|
||||||
if (diff == 0) return 64;
|
// Calculate the difference in their binary representations
|
||||||
|
int64_t result = x.i - y.i;
|
||||||
|
result = result > 0 ? result : -result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
int32_t result = 0;
|
#+begin_src c :comments org :tangle (eval h_func) :exports none
|
||||||
|
int32_t qmckl_test_precision_64(double a, double b);
|
||||||
|
int32_t qmckl_test_precision_32(float a, float b);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
while (!(diff & 1)) {
|
#+begin_src c :tangle (eval c)
|
||||||
|
int32_t qmckl_test_precision_64(double a, double b) {
|
||||||
|
|
||||||
|
int64_t diff = countUlpDifference_64(a,b);
|
||||||
|
|
||||||
|
if (diff == 0) return 53;
|
||||||
|
|
||||||
|
int32_t result = 53;
|
||||||
|
|
||||||
|
for (int i=0 ; i<53 && diff != 0 ; ++i) {
|
||||||
diff >>= 1;
|
diff >>= 1;
|
||||||
result++;
|
result--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -400,27 +421,7 @@ int32_t qmckl_test_precision_64(double a, double b) {
|
|||||||
|
|
||||||
#+begin_src c :tangle (eval c)
|
#+begin_src c :tangle (eval c)
|
||||||
int32_t qmckl_test_precision_32(float a, float b) {
|
int32_t qmckl_test_precision_32(float a, float b) {
|
||||||
|
return qmckl_test_precision_64( (double) a, (double) b );
|
||||||
union int_or_float {
|
|
||||||
int32_t i;
|
|
||||||
float f;
|
|
||||||
} x, y;
|
|
||||||
|
|
||||||
x.f = a;
|
|
||||||
y.f = b;
|
|
||||||
|
|
||||||
uint32_t diff = x.i > y.i ? x.i - y.i : y.i - x.i;
|
|
||||||
|
|
||||||
if (diff == 0) return 32;
|
|
||||||
|
|
||||||
int32_t result = 0;
|
|
||||||
|
|
||||||
while (!(diff & 1)) {
|
|
||||||
diff >>= 1;
|
|
||||||
result++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user