Skip to content

Commit

Permalink
add sanity checks to nj and nk, <0 or >MAX_NU_PTS; new err code; matc…
Browse files Browse the repository at this point in the history
…hing test/dumbinputs; and docs
  • Loading branch information
ahbarnett committed Feb 7, 2024
1 parent 7087a94 commit 077dc0c
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 23 deletions.
7 changes: 6 additions & 1 deletion docs/error.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ has the following meanings (see ``include/finufft_errors.h``):
17 invalid spread/interp method for dim (attempt to blockgather in 1D, e.g.)
18 size of bins for subprob/blockgather invalid
19 GPU shmem too small for subprob/blockgather parameters
20 invalid number of nonuniform points, i.e., nj or nk negative, or too large

When ``ier=1`` (warning only) the transform(s) is/are still completed, at the smallest epsilon achievable, so, with that caveat, the answer should still be usable.

For any other nonzero values of ``ier`` the transform may not have been performed and the output should not be trusted. However, we hope that the value of ``ier`` will help to narrow down the problem.

FINUFFT sometimes also sends error text to ``stderr`` if it detects faulty input parameters.
FINUFFT sometimes also sends error text to ``stderr`` if it detects faulty input parameters. Please check your terminal output.

If you are getting error codes, please reread the documentation
for your language, then see our :ref:`troubleshooting advice <trouble>`.
Expand All @@ -53,3 +54,7 @@ Note that mallocs smaller than this, but which still exceed available RAM, may c
If you have a large-RAM machine and want to exceed the above hard-coded limit, you will need
to edit ``defs.h`` and recompile.

Similar sanity checks are done on the numbers of nonuniform points, and it is
(barely) conceivable that you could want to
increase ``MAX_NU_PTS`` beyond its current value
of ``1e14`` in ``defs.h``, and recompile.
5 changes: 4 additions & 1 deletion include/finufft/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@

// Internal (nf1 etc) array allocation size that immediately raises error.
// (Note: next235 takes 1s for this size, so it is also to prevent hang here.)
// Increase this if you need >1TB RAM... (used only in common.cpp)
// Increase this if you need >1TB RAM...
#define MAX_NF (BIGINT)1e11

// Maximum allowed number M of NU points; useful to catch incorrectly cast int32
// values for M = nj (also ns in type 3)
#define MAX_NU_PTS (BIGINT)1e14


// -------------- Math consts (not in math.h) and useful math macros ----------
Expand Down
3 changes: 2 additions & 1 deletion include/finufft_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
#define FINUFFT_ERR_METHOD_NOTVALID 17
#define FINUFFT_ERR_BINSIZE_NOTVALID 18
#define FINUFFT_ERR_INSUFFICIENT_SHMEM 19

// back to CPU errors
#define FINUFFT_ERR_NUM_NU_PTS_INVALID 20
#endif
16 changes: 15 additions & 1 deletion src/finufft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,14 @@ int FINUFFT_SETPTS(FINUFFT_PLAN p, BIGINT nj, FLT* xj, FLT* yj, FLT* zj,
int d = p->dim; // abbrev for spatial dim
CNTime timer; timer.start();
p->nj = nj; // the user only now chooses how many NU (x,y,z) pts

if (nj<0) {
fprintf(stderr,"[%s] nj (%lld) cannot be negative!\n",__func__,(long long)nj);
return FINUFFT_ERR_NUM_NU_PTS_INVALID;
} else if (nj>MAX_NU_PTS) {
fprintf(stderr,"[%s] nj (%lld) exceeds MAX_NU_PTS\n",__func__,(long long)nj);
return FINUFFT_ERR_NUM_NU_PTS_INVALID;
}

if (p->type!=3) { // ------------------ TYPE 1,2 SETPTS -------------------
// (all we can do is check and maybe bin-sort the NU pts)
p->X = xj; // plan must keep pointers to user's fixed NU pts
Expand All @@ -789,6 +796,13 @@ int FINUFFT_SETPTS(FINUFFT_PLAN p, BIGINT nj, FLT* xj, FLT* yj, FLT* zj,
} else { // ------------------------- TYPE 3 SETPTS -----------------------
// (here we can precompute pre/post-phase factors and plan the t2)

if (nk<0) {
fprintf(stderr,"[%s] nk (%lld) cannot be negative!\n",__func__,(long long)nk);
return FINUFFT_ERR_NUM_NU_PTS_INVALID;
} else if (nk>MAX_NU_PTS) {
fprintf(stderr,"[%s] nk (%lld) exceeds MAX_NU_PTS\n",__func__,(long long)nk);
return FINUFFT_ERR_NUM_NU_PTS_INVALID;
}
p->nk = nk; // user set # targ freq pts
p->S = s; // keep pointers to user's input target pts
p->T = t;
Expand Down
59 changes: 40 additions & 19 deletions test/dumbinputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,24 @@ int main(int argc, char* argv[])
}
ier = FINUFFT1D1(M,x,c,+1,acc,0,F,&opts);
if (ier) {
printf("1d1 N=0:\tier=%d",ier);
printf("1d1 N=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT1D1(-1,x,c,+1,acc,0,F,&opts);
if (ier != FINUFFT_ERR_NUM_NU_PTS_INVALID) {
printf("1d1 M<0:\twrong err code %d\n",ier);
return 1;
}
int64_t Mhuge = (int64_t)(1e16); // see defs.h MAX_NU_PTS
ier = FINUFFT1D1(Mhuge,x,c,+1,acc,0,F,&opts);
if (ier != FINUFFT_ERR_NUM_NU_PTS_INVALID) {
printf("1d1 M huge:\twrong err code %d\n",ier);
return 1;
}
ier = FINUFFT1D1(0,x,c,+1,acc,N,F,&opts);
FLT t = twonorm(N,F);
if (ier || t!=0.0) {
printf("1d1 M=0:\tier=%d nrm(F)=%.3g",ier,t);
printf("1d1 M=0:\tier=%d nrm(F)=%.3g\n",ier,t);
return 1;
}
FLT xsave = x[0];
Expand Down Expand Up @@ -131,12 +142,12 @@ int main(int argc, char* argv[])
ier = FINUFFT1D2(M,x,c,+1,acc,0,F,&opts);
t = twonorm(M,c);
if (ier || t!=0.0) {
printf("1d2 N=0:\tier=%d nrm(c)=%.3g",ier,t);
printf("1d2 N=0:\tier=%d nrm(c)=%.3g\n",ier,t);
return 1;
}
ier = FINUFFT1D2(0,x,c,+1,acc,N,F,&opts);
if (ier) {
printf("1d2 M=0:\tier=%d",ier);
printf("1d2 M=0:\tier=%d\n",ier);
return ier;
}
for (int j=0; j<M; ++j) c[j] = sin((FLT)1.3*j) + IMA*cos((FLT)0.9*j); // reset c for t3
Expand All @@ -147,28 +158,38 @@ int main(int argc, char* argv[])
}
ier = FINUFFT1D3(M,x,c,+1,acc,0,s,F,&opts);
if (ier) {
printf("1d3 nk=0:\tier=%d",ier);
printf("1d3 nk=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT1D3(M,x,c,+1,acc,-1,s,F,&opts);
if (ier != FINUFFT_ERR_NUM_NU_PTS_INVALID) {
printf("1d3 nk=-1:\twrong err code %d\n",ier);
return 1;
}
ier = FINUFFT1D3(M,x,c,+1,acc,Mhuge,s,F,&opts);
if (ier != FINUFFT_ERR_NUM_NU_PTS_INVALID) {
printf("1d3 nk huge:\twrong err code %d\n",ier);
return 1;
}
ier = FINUFFT1D3(0,x,c,+1,acc,N,s,F,&opts);
t = twonorm(N,F);
if (ier || t!=0.0) {
printf("1d3 M=0:\tier=%d nrm(F)=%.3g",ier,t);
printf("1d3 M=0:\tier=%d nrm(F)=%.3g\n",ier,t);
return 1;
}
// for type 3 only we include crude accuracy check for 1-NUpt (I/O) cases...
ier = FINUFFT1D3(1,x,c,+1,acc,N,s,F,&opts); // XK prod formally 0
dirft1d3(1,x,c,+1,N,s,Fe); for (int k=0; k<N; ++k) F[k] -= Fe[k]; // acc chk
FLT err = twonorm(N,F)/sqrt((FLT)N);
if (ier || err>100*acc) {
printf("1d3 M=1:\tier=%d nrm(err)=%.3g",ier,err);
printf("1d3 M=1:\tier=%d nrm(err)=%.3g\n",ier,err);
return 1;
}
ier = FINUFFT1D3(M,x,c,+1,acc,1,s,F,&opts);
dirft1d3(M,x,c,+1,1,s,Fe);
err = abs(F[0]-Fe[0]);
if (ier || err>10*acc) {
printf("1d3 N=1:\tier=%d err=%.3g\n",ier,err);
printf("1d3 nk=1:\tier=%d err=%.3g\n",ier,err);
return 1;
}
ier = FINUFFT1D3(1,x,c,+1,acc,1,s,F,&opts);
Expand Down Expand Up @@ -199,7 +220,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT1D1MANY(ndata,M,x,cm,+1,acc,0,Fm,&opts);
if (ier) {
printf("1d1many N=0:\tier=%d",ier);
printf("1d1many N=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT1D1MANY(ndata,0,x,cm,+1,acc,N,Fm,&opts);
Expand Down Expand Up @@ -227,7 +248,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT1D2MANY(ndata,0,x,cm,+1,acc,N,Fm,&opts);
if (ier) {
printf("1d2many M=0:\tier=%d",ier);
printf("1d2many M=0:\tier=%d\n",ier);
return ier;
}
for (int j=0; j<M*ndata; ++j) cm[j] = sin((FLT)1.3*j) + IMA*cos((FLT)0.9*j); // reset cm for 1d3many
Expand All @@ -243,7 +264,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT1D3MANY(ndata, M,x,cm,+1,acc,0,s,Fm,&opts);
if (ier) {
printf("1d3many nk=0:\tier=%d",ier);
printf("1d3many nk=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT1D3MANY(ndata, 0,x,cm,+1,acc,N,s,Fm,&opts);
Expand All @@ -260,14 +281,14 @@ int main(int argc, char* argv[])
dirft1d3(M,x,c,+1,1,s,Fe);
err = abs(Fm[0]-Fe[0]);
if (ier || err>10*acc) {
printf("1d3many N=1:\tier=%d err=%.3g\n",ier,err);
printf("1d3many nk=1:\tier=%d err=%.3g\n",ier,err);
return 1;
}
ier = FINUFFT1D3MANY(ndata,1,x,cm,+1,acc,1,s,Fm,&opts);
dirft1d3(1,x,c,+1,1,s,Fe);
err = abs(Fm[0]-Fe[0]);
if (ier || err>10*acc) {
printf("1d3many M=N=1:\tier=%d err=%.3g\n",ier,err);
printf("1d3many M=nk=1:\tier=%d err=%.3g\n",ier,err);
return 1;
}
ier = FINUFFT1D3MANY(ndata,M,x,cm,+1,acc,N,shuge,Fm,&opts);
Expand Down Expand Up @@ -341,7 +362,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT2D3(M,x,x,c,+1,acc,0,s,s,F,&opts);
if (ier) {
printf("2d3 nk=0:\tier=%d",ier);
printf("2d3 nk=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT2D3(0,x,x,c,+1,acc,N,s,s,F,&opts);
Expand Down Expand Up @@ -425,7 +446,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT2D2MANY(ndata,0,x,x,cm,+1,acc,N,N,Fm,&opts);
if (ier) {
printf("2d2many M=0:\tier=%d",ier);
printf("2d2many M=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT2D3MANY(0,M,x,x,cm,+1,0,N,s,s,Fm,&opts);
Expand All @@ -440,7 +461,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT2D3MANY(ndata,M,x,x,cm,+1,acc,0,s,s,Fm,&opts);
if (ier) {
printf("2d3many nk=0:\tier=%d",ier);
printf("2d3many nk=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT2D3MANY(ndata,0,x,x,cm,+1,acc,N,s,s,Fm,&opts);
Expand Down Expand Up @@ -532,7 +553,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT3D3(M,x,x,x,c,+1,acc,0,s,s,s,F,&opts);
if (ier) {
printf("3d3 nk=0:\tier=%d",ier);
printf("3d3 nk=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT3D3(0,x,x,x,c,+1,acc,N,s,s,s,F,&opts);
Expand Down Expand Up @@ -627,7 +648,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT3D2MANY(ndata,0,x,x,x,cm,+1,acc,N,N,N,Fm,&opts);
if (ier) {
printf("3d2many M=0:\tier=%d",ier);
printf("3d2many M=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT3D3MANY(0,M,x,x,x,cm,+1,0,N,s,s,s,Fm,&opts);
Expand All @@ -642,7 +663,7 @@ int main(int argc, char* argv[])
}
ier = FINUFFT3D3MANY(ndata,M,x,x,x,cm,+1,acc,0,s,s,s,Fm,&opts);
if (ier) {
printf("3d3many nk=0:\tier=%d",ier);
printf("3d3many nk=0:\tier=%d\n",ier);
return ier;
}
ier = FINUFFT3D3MANY(ndata,0,x,x,x,cm,+1,acc,N,s,s,s,Fm,&opts);
Expand Down

0 comments on commit 077dc0c

Please sign in to comment.