From 34af3b0b9aaca390c2c82cc775ce7fee71915311 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 15 Jul 2026 11:30:53 -0500 Subject: [PATCH 1/3] COMP: Guard compiler-specific pragmas behind feature macros Wrap the OpenMP work-sharing directives in #ifdef _OPENMP and the MSVC #pragma warning suppressions in #ifdef _MSC_VER so GCC/Clang builds without OpenMP no longer emit -Wunknown-pragmas. --- src/TV2DWopt.cpp | 12 ++++++++++-- src/TV2Dopt.cpp | 32 ++++++++++++++++++++++++++++++-- src/TVL1opt_tautstring.cpp | 12 ++++++++++-- src/TVNDopt.cpp | 28 ++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/TV2DWopt.cpp b/src/TV2DWopt.cpp index b860cfc..7362284 100644 --- a/src/TV2DWopt.cpp +++ b/src/TV2DWopt.cpp @@ -150,7 +150,9 @@ int DR2L1W_TV(size_t M, size_t N, double*unary, double*W1, double*W2, double*s, @param ws array of Workspaces to use for the computation */ void DR_columnsPass(size_t M, size_t N, double* input, double* output, double* W, Workspace **ws) { + #ifdef _OPENMP #pragma omp parallel shared(M,N,input,output,W,ws) default(none) + #endif { // Get thread number int id = omp_get_thread_num(); @@ -159,8 +161,10 @@ void DR_columnsPass(size_t M, size_t N, double* input, double* output, double* W wsi->warm = 0; // Run 1-d solvers in parallel on each column of the input + #ifdef _OPENMP #pragma omp for - for (int j=0; j < N; j++) { + #endif + for (size_t j=0; j < N; j++) { resetWorkspace(wsi); // Array for weights double* wline = getDoubleWorkspace(wsi); @@ -188,9 +192,11 @@ void DR_columnsPass(size_t M, size_t N, double* input, double* output, double* W @param ws array of Workspaces to use for the computation */ void DR_rowsPass(size_t M, size_t N, double* input, double* output, double* ref, double* W, Workspace **ws) { + #ifdef _OPENMP #pragma omp parallel shared(M,N,input,ref,output,W,ws) default(none) + #endif { - int i,j; + size_t i, j; // Get thread number int id = omp_get_thread_num(); // Get corresponding workspace @@ -198,7 +204,9 @@ void DR_rowsPass(size_t M, size_t N, double* input, double* output, double* ref, wsi->warm = 0; // Run 1-d solvers in parallel on each row of the input + #ifdef _OPENMP #pragma omp for + #endif for (j=0; j < M; j++) { resetWorkspace(wsi); // Array for weights diff --git a/src/TV2Dopt.cpp b/src/TV2Dopt.cpp index 0c5ccfb..d4f499d 100644 --- a/src/TV2Dopt.cpp +++ b/src/TV2Dopt.cpp @@ -129,7 +129,9 @@ int PD2_TV(double *y,double *lambdas,double *norms,double *dims,double *x,double #endif /* Initialization */ + #ifdef _OPENMP #pragma omp parallel for shared(x,y,p,q,n) private(i) default(none) + #endif for(i=0;iwarm = 0; int top=nSlices[d]; + #ifdef _OPENMP #pragma omp for + #endif for(j=0;jwarm = 0; int top=nSlices[d]; + #ifdef _OPENMP #pragma omp for + #endif for(j=0;jwarm = 0; // Run 1-d solvers in parallel on each column of the input + #ifdef _OPENMP #pragma omp for - for (int j=0; j < N; j++) { + #endif + for (size_t j=0; j < N; j++) { resetWorkspace(wsi); // Prepare inputs memcpy(wsi->in, input+(M*j), sizeof(double)*M); @@ -467,9 +491,11 @@ void DR_columnsPass(size_t M, size_t N, double* input, double* output, double W, @param ws array of Workspaces to use for the computation */ void DR_rowsPass(size_t M, size_t N, double* input, double* output, double* ref, double W, double norm, Workspace **ws) { + #ifdef _OPENMP #pragma omp parallel shared(M,N,input,ref,output,W,norm,ws) default(none) + #endif { - int i,j; + size_t i, j; // Get thread number int id = omp_get_thread_num(); // Get corresponding workspace @@ -477,7 +503,9 @@ void DR_rowsPass(size_t M, size_t N, double* input, double* output, double* ref, wsi->warm = 0; // Run 1-d solvers in parallel on each row of the input + #ifdef _OPENMP #pragma omp for + #endif for (j=0; j < M; j++) { resetWorkspace(wsi); // Prepare inputs, considering displacement from reference signal diff --git a/src/TVL1opt_tautstring.cpp b/src/TVL1opt_tautstring.cpp index 303ddc0..ddade9d 100644 --- a/src/TVL1opt_tautstring.cpp +++ b/src/TVL1opt_tautstring.cpp @@ -234,7 +234,7 @@ inline Segment* newknot(Buffer* majorant, Buffer* minorant, Point* origin, Point The new prox-TV segment is added to the prox array */ #define addproxsegment(prox, segment, j) \ - for ( j = 0 ; j < segment->incx ; j++ ) \ + for ( j = 0 ; j < (size_t) segment->incx ; j++ ) \ (prox)[j] = segment->slope; /* @@ -292,16 +292,20 @@ int classicTautString_TV1_offset(double *signal, int n, double lam, double *prox Segment *saux; size_t i, iaux; double *pwriter = prox; - for ( i = 1 ; i < n-1 ; i++ ) { + for ( i = 1 ; i < (size_t)(n-1) ; i++ ) { // Update majorant segment.incx = 1; segment.slope = segment.incy = signal[i]; +#ifdef _MSC_VER #pragma warning(suppress: 4244) +#endif concavemajorantadd(majorant, dirsegment, saux, iaux); // Update minorant segment.incx = 1; segment.slope = segment.incy = signal[i]; +#ifdef _MSC_VER #pragma warning(suppress: 4244) +#endif convexminorantadd(minorant, dirsegment, saux, iaux); // Update last explored point lastexplored.x++; @@ -319,12 +323,16 @@ int classicTautString_TV1_offset(double *signal, int n, double lam, double *prox // Update majorant with last segment segment.incx = 1; segment.slope = segment.incy = signal[n-1] + lam; +#ifdef _MSC_VER #pragma warning(suppress: 4244) +#endif concavemajorantadd(majorant, dirsegment, saux, iaux); // Update minorant with last segment segment.incx = 1; segment.slope = segment.incy = signal[n-1] - lam; +#ifdef _MSC_VER #pragma warning(suppress: 4244) +#endif convexminorantadd(minorant, dirsegment, saux, iaux); // At this point, because the endpoint of the tube is the same diff --git a/src/TVNDopt.cpp b/src/TVNDopt.cpp index bda1c66..6688621 100644 --- a/src/TVNDopt.cpp +++ b/src/TVNDopt.cpp @@ -122,7 +122,9 @@ int PD_TV(double *y,double *lambdas,double *norms,double *dims,double *x,double #endif /* Initialization */ + #ifdef _OPENMP #pragma omp parallel for shared(n,x,npen,z,y) private(i,j) default(none) + #endif for(i=0;iwarm = 0; /* Run 1-dimensional prox operator over each 1-dimensional slice along the specified dimension */ + #ifdef _OPENMP #pragma omp for nowait + #endif for(j=0;jwarm = 0; /* Run 1-dimensional prox operators over each 1-dimensional slice along the specified dimension */ + #ifdef _OPENMP #pragma omp for nowait + #endif for(j=0;j Date: Wed, 15 Jul 2026 11:30:53 -0500 Subject: [PATCH 2/3] COMP: Fix -Wsign-compare and -Wmisleading-indentation Use size_t loop counters against size_t bounds in the 2D Douglas-Rachford column/row passes, cast the segment/interior bounds in the taut-string solver, and split the NORM macro's trailing statement onto its own line. --- src/TVL2opt.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/TVL2opt.cpp b/src/TVL2opt.cpp index af36ee3..2c195c6 100644 --- a/src/TVL2opt.cpp +++ b/src/TVL2opt.cpp @@ -219,7 +219,8 @@ int morePG_TV2(double *y,double lambda,double *x,double *info,int n,Workspace *w #define NORM(x,n,i,tmp) \ tmp = 0; \ - for(i=0;i Date: Wed, 15 Jul 2026 11:48:57 -0500 Subject: [PATCH 3/3] COMP: Validate array length and penalty count in solver entry points Reject n < 2 in more_TV2/morePG_TV2 and npen < 1 in PD_TV/PDR_TV before the dependent memcpy/calloc sizes are computed, so the signed-to-size_t size arguments can no longer be a huge value (-Wstringop-overflow, -Walloc-size-larger-than). --- src/TVL2opt.cpp | 2 ++ src/TVNDopt.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/TVL2opt.cpp b/src/TVL2opt.cpp index 2c195c6..b066af9 100644 --- a/src/TVL2opt.cpp +++ b/src/TVL2opt.cpp @@ -33,6 +33,7 @@ - n: length of array y (and x). */ int more_TV2(double *y,double lambda,double *x,double *info,int n){ + if(n < 2) { info[INFO_RC] = RC_ERROR; return 0; } int nn=n-1,i; double stop,tmp,lam,pNorm,qNorm,pNormSq,dist; double *Dy,*alpha,*beta,*minus,*p,*aux; @@ -194,6 +195,7 @@ int more_TV2(double *y,double lambda,double *x,double *info,int n){ - ws: workspace of allocated memory to use. If NULL, any needed memory is locally managed. */ int morePG_TV2(double *y,double lambda,double *x,double *info,int n,Workspace *ws){ + if(n < 2) { if(info) info[INFO_RC] = RC_ERROR; return 0; } int nn=n-1,i,iters; double stop,tmp,lam,pNorm,qNorm,pNormSq,dist; double *Dy=NULL,*alpha=NULL,*beta=NULL,*minus=NULL,*p,*aux; diff --git a/src/TVNDopt.cpp b/src/TVNDopt.cpp index 6688621..5656a8a 100644 --- a/src/TVNDopt.cpp +++ b/src/TVNDopt.cpp @@ -69,6 +69,8 @@ int PD_TV(double *y,double *lambdas,double *norms,double *dims,double *x,double if(info) info[INFO_RC] = RC_ERROR;\ return 0; + if(npen < 1) { if(info) info[INFO_RC] = RC_ERROR; return 0; } + /* Set number of threads */ nThreads = (ncores > 1) ? ncores : 1; #ifdef DEBUG @@ -299,6 +301,8 @@ int PDR_TV(double *y,double *lambdas,double *norms,double *dims,double *x,double if(info) info[INFO_RC] = RC_ERROR;\ return 0; + if(npen < 1) { if(info) info[INFO_RC] = RC_ERROR; return 0; } + /* Set number of threads */ nThreads = (ncores > 1) ? ncores : 1; #ifdef DEBUG