Skip to content

Commit 2aafb29

Browse files
committed
Added a signal handler for the kernels. All routines now exit cleanly from a Ctrl-C. Fixes issue #12 and #58
1 parent bea42fd commit 2aafb29

16 files changed

+226
-74
lines changed

xi_mocks/DDrppi/countpairs_rp_pi_mocks_impl.c.src

+23-10
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
#include <omp.h>
2929
#endif
3030

31+
int interrupt_status_DDrppi_mocks_DOUBLE=EXIT_SUCCESS;
32+
33+
void interrupt_handler_countpairs_rp_pi_mocks_DOUBLE(int signo)
34+
{
35+
fprintf(stderr,"Received signal = `%s' (signo = %d). Aborting \n",strsignal(signo), signo);
36+
interrupt_status_DDrppi_mocks_DOUBLE = EXIT_FAILURE;
37+
}
38+
3139

3240
int check_ra_dec_cz_DOUBLE(const int64_t N, DOUBLE *phi, DOUBLE *theta, DOUBLE *cz)
3341
{
@@ -207,6 +215,16 @@ int countpairs_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1, DOUBLE
207215
int zbin_refine_factor=2;
208216
const int npibin = (int) pimax;
209217

218+
/* setup interrupt handler -> mostly useful during the python execution.
219+
Let's Ctrl-C abort the extension */
220+
int interrupt_signals[] = {SIGTERM, SIGINT, SIGHUP};
221+
for(size_t i=0;i<sizeof(interrupt_signals)/sizeof(interrupt_signals[0]);i++) {
222+
int signo = interrupt_signals[i];
223+
if (signal(signo, interrupt_handler_countpairs_rp_pi_mocks_DOUBLE) == SIG_ERR) {
224+
fprintf(stderr,"Can not handle signal = %d\n", signo);
225+
}
226+
}
227+
210228
//Try to initialize cosmology - code will exit if comoslogy is not implemented.
211229
//Putting in a different scope so I can call the variable status
212230
{
@@ -424,7 +442,7 @@ int countpairs_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1, DOUBLE
424442

425443

426444
#if defined(_OPENMP)
427-
#pragma omp parallel shared(numdone, abort_status)
445+
#pragma omp parallel shared(numdone, abort_status, interrupt_status_DDrppi_mocks_DOUBLE)
428446
{
429447
const int tid = omp_get_thread_num();
430448
uint64_t npairs[totnbins];
@@ -441,10 +459,10 @@ int countpairs_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1, DOUBLE
441459
for(int64_t index1=0;index1<totncells;index1++) {
442460

443461
#if defined(_OPENMP)
444-
#pragma omp flush (abort_status)
462+
#pragma omp flush (abort_status, interrupt_status_DDrppi_mocks_DOUBLE)
445463
#endif
446-
if(abort_status == EXIT_SUCCESS) { //omp cancel was introduced in omp 4.0 - so this is my way of checking if loop needs to be cancelled
447-
464+
if(abort_status == EXIT_SUCCESS && interrupt_status_DDrppi_mocks_DOUBLE == EXIT_SUCCESS) {
465+
//omp cancel was introduced in omp 4.0 - so this is my way of checking if loop needs to be cancelled
448466
/* If the verbose option is not enabled, avoid outputting anything unnecessary*/
449467
if(options.verbose) {
450468
#if defined(_OPENMP)
@@ -524,13 +542,8 @@ int countpairs_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1, DOUBLE
524542
if(autocorr == 0) {
525543
free_cellarray_mocks_index_particles_DOUBLE(lattice2,totncells);
526544
}
527-
528-
if(options.verbose) {
529-
finish_myprogressbar(&interrupted);
530-
}
531-
532545

533-
if(abort_status != EXIT_SUCCESS) {
546+
if(abort_status != EXIT_SUCCESS || interrupt_status_DDrppi_mocks_DOUBLE != EXIT_SUCCESS) {
534547
/* Cleanup memory here if aborting */
535548
free(rupp);
536549
#if defined(_OPENMP)

xi_mocks/DDrppi/countpairs_rp_pi_mocks_impl.h.src

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ extern "C" {
1414

1515
#include "countpairs_rp_pi_mocks.h" //for definition of results_countpairs_mocks
1616

17+
extern void interrupt_handler_countpairs_rp_pi_mocks_DOUBLE(int signo);
18+
1719
typedef int (*countpairs_mocks_func_ptr_DOUBLE)(const int64_t N0, DOUBLE *x0, DOUBLE *y0, DOUBLE *z0, DOUBLE *d0,
1820
const int64_t N1, DOUBLE *x1, DOUBLE *y1, DOUBLE *z1, DOUBLE *d1,
1921
const int same_cell,

xi_mocks/vpf/countspheres_mocks_impl.c.src

+32-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424

2525
#include "vpf_mocks_kernels_DOUBLE.c"
2626

27+
int interrupt_status_vpf_mocks_DOUBLE=EXIT_SUCCESS;
28+
29+
void interrupt_handler_vpf_mocks_DOUBLE(int signo)
30+
{
31+
fprintf(stderr,"Received signal = `%s' (signo = %d). Aborting \n",strsignal(signo), signo);
32+
interrupt_status_vpf_mocks_DOUBLE = EXIT_FAILURE;
33+
}
34+
35+
2736
int count_neighbors_DOUBLE(const DOUBLE xcen,const DOUBLE ycen,const DOUBLE zcen,const DOUBLE smin,const DOUBLE inv_rcube,const DOUBLE rmax,
2837
const int ngrid,const cellarray_DOUBLE *lattice, const int nthreshold, const int bin_refine_factor);
2938

@@ -178,11 +187,27 @@ int countspheres_mocks_DOUBLE(const int64_t Ngal, DOUBLE *xgal, DOUBLE *ygal, DO
178187
XRETURN(num_pN >= 1, EXIT_FAILURE,"Number of pN's=%d requested must be at least 1", num_pN);
179188

180189
/* Start cosmology */
181-
init_cosmology(cosmology);
190+
{
191+
// Declared in separate scope so I can call the variable status;
192+
int status = init_cosmology(cosmology);
193+
if(status != EXIT_SUCCESS) {
194+
return status;
195+
}
196+
}
182197

183198
struct config_options options = *input_options;
184199
options.periodic=0;
185200

201+
/* setup interrupt handler -> mostly useful during the python execution.
202+
Let's Ctrl-C abort the extension */
203+
int interrupt_signals[] = {SIGTERM, SIGINT, SIGHUP};
204+
for(size_t i=0;i<sizeof(interrupt_signals)/sizeof(interrupt_signals[0]);i++) {
205+
int signo = interrupt_signals[i];
206+
if (signal(signo, interrupt_handler_vpf_mocks_DOUBLE) == SIG_ERR) {
207+
fprintf(stderr,"Can not handle signal = %d\n", signo);
208+
}
209+
}
210+
186211
int need_randoms=0;
187212
int64_t num_centers_in_file=0;
188213
FILE *fpcen = fopen(centers_file,"r");
@@ -337,13 +362,12 @@ int countspheres_mocks_DOUBLE(const int64_t Ngal, DOUBLE *xgal, DOUBLE *ygal, DO
337362
itry=0 ;
338363
isucceed=0 ;
339364
int ncenters_written=0;
340-
341365
int interrupted=0;
342366
if(options.verbose) {
343367
init_my_progressbar(nc, &interrupted);
344368
}
345369

346-
while(isucceed < nc && itry < Nran) {
370+
while(isucceed < nc && itry < Nran && interrupt_status_vpf_mocks_DOUBLE == EXIT_SUCCESS) {
347371

348372
if(options.verbose){
349373
my_progressbar(isucceed,&interrupted);
@@ -453,7 +477,11 @@ int countspheres_mocks_DOUBLE(const int64_t Ngal, DOUBLE *xgal, DOUBLE *ygal, DO
453477
if(need_randoms == 1) {
454478
free_cellarray_DOUBLE(randoms_lattice, totncells);
455479
}
456-
480+
if(interrupt_status_vpf_mocks_DOUBLE != EXIT_SUCCESS) {
481+
matrix_free((void **) pN, nbin);
482+
return EXIT_FAILURE;
483+
}
484+
457485
if(options.verbose) {
458486
finish_myprogressbar(&interrupted);
459487
fprintf(stderr,"%s> Placed %d centers out of %d trials.\n",__FUNCTION__,isucceed,itry);

xi_mocks/vpf/countspheres_mocks_impl.h.src

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ extern "C" {
1515
#include "defs.h" //for definition of struct config_options
1616
#include "countspheres_mocks.h"//for definition of struct results_countspheres_mocks
1717

18-
18+
extern void interrupt_handler_vpf_mocks_DOUBLE(int signo);
19+
1920
typedef int (*vpf_mocks_func_ptr_DOUBLE)(const int64_t np, DOUBLE * restrict X, DOUBLE * restrict Y, DOUBLE * restrict Z,
2021
const DOUBLE xc, const DOUBLE yc, const DOUBLE zc,
2122
const DOUBLE rmax, const int nbin,

xi_mocks/wtheta/countpairs_theta_mocks_impl.c.src

+23-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@
2323
#include <omp.h>
2424
#endif
2525

26+
int interrupt_status_wtheta_mocks_DOUBLE=EXIT_SUCCESS;
27+
28+
void interrupt_handler_wtheta_mocks_DOUBLE(int signo)
29+
{
30+
fprintf(stderr,"Received signal = `%s' (signo = %d). Aborting \n",strsignal(signo), signo);
31+
interrupt_status_wtheta_mocks_DOUBLE = EXIT_FAILURE;
32+
}
33+
34+
35+
2636
int check_ra_dec_DOUBLE(const int64_t N, DOUBLE *ra, DOUBLE *theta)
2737
{
2838
if(N==0) {
@@ -291,6 +301,15 @@ int countpairs_theta_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1,
291301
int ra_refine_factor = 2;
292302
int dec_refine_factor = 2;
293303

304+
/* setup interrupt handler -> mostly useful during the python execution.
305+
Let's Ctrl-C abort the extension */
306+
int interrupt_signals[] = {SIGTERM, SIGINT, SIGHUP};
307+
for(size_t i=0;i<sizeof(interrupt_signals)/sizeof(interrupt_signals[0]);i++) {
308+
int signo = interrupt_signals[i];
309+
if (signal(signo, interrupt_handler_wtheta_mocks_DOUBLE) == SIG_ERR) {
310+
fprintf(stderr,"Can not handle signal = %d\n", signo);
311+
}
312+
}
294313

295314
#if defined(_OPENMP)
296315
if((options.link_in_ra == 0) && (dec_refine_factor < numthreads)) {
@@ -577,7 +596,7 @@ int countpairs_theta_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1,
577596

578597

579598
#if defined(_OPENMP)
580-
#pragma omp parallel shared(numdone, abort_status)
599+
#pragma omp parallel shared(numdone, abort_status, interrupt_status_wtheta_mocks_DOUBLE)
581600
{
582601
int tid = omp_get_thread_num();
583602
uint64_t npairs[nthetabin];
@@ -598,7 +617,8 @@ int countpairs_theta_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1,
598617
#if defined(_OPENMP)
599618
#pragma omp flush (abort_status)
600619
#endif
601-
if(abort_status == EXIT_SUCCESS) { //omp cancel was introduced in omp 4.0 - so this is my way of checking if loop needs to be cancelled
620+
if(abort_status == EXIT_SUCCESS && interrupt_status_wtheta_mocks_DOUBLE == EXIT_SUCCESS) {
621+
//omp cancel was introduced in omp 4.0 - so this is my way of checking if loop needs to be cancelled
602622

603623
/* If the verbose option is not enabled, avoid outputting anything unnecessary*/
604624
if(options.verbose) {
@@ -687,7 +707,7 @@ int countpairs_theta_mocks_DOUBLE(const int64_t ND1, DOUBLE *ra1, DOUBLE *dec1,
687707
free_cellarray_mocks_index_wtheta_DOUBLE(lattice2,totncells);
688708
}
689709

690-
if(abort_status != EXIT_SUCCESS) {
710+
if(abort_status != EXIT_SUCCESS || interrupt_status_wtheta_mocks_DOUBLE != EXIT_SUCCESS) {
691711
/* Cleanup memory here if aborting */
692712
free(theta_upp);
693713
#if defined(_OPENMP)

xi_mocks/wtheta/countpairs_theta_mocks_impl.h.src

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C" {
1414

1515
#include "countpairs_theta_mocks.h"
1616

17+
extern void interrupt_handler_wtheta_mocks_DOUBLE(int signo);
1718

1819
typedef int (*countpairs_theta_mocks_func_ptr_DOUBLE)(const int64_t N0, DOUBLE *x0, DOUBLE *y0, DOUBLE *z0,
1920
const int64_t N1, DOUBLE *x1, DOUBLE *y1, DOUBLE *z1,

xi_theory/vpf/countspheres_impl.c.src

+23-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@
2222

2323
#include "vpf_kernels_DOUBLE.c"
2424

25+
int interrupt_status_vpf_DOUBLE=EXIT_SUCCESS;
26+
27+
void interrupt_handler_vpf_DOUBLE(int signo)
28+
{
29+
fprintf(stderr,"Received signal = `%s' (signo = %d). Aborting \n",strsignal(signo), signo);
30+
interrupt_status_vpf_DOUBLE = EXIT_FAILURE;
31+
}
2532

2633
vpf_func_ptr_DOUBLE vpf_driver_DOUBLE(const struct config_options *options)
2734
{
@@ -119,6 +126,17 @@ int countspheres_DOUBLE(const int64_t np, DOUBLE * restrict X, DOUBLE * restrict
119126
gsl_rng * rng;
120127
int bin_refine_factor=1;
121128

129+
/* setup interrupt handler -> mostly useful during the python execution.
130+
Let's Ctrl-C abort the extension */
131+
int interrupt_signals[] = {SIGTERM, SIGINT, SIGHUP};
132+
for(size_t i=0;i<sizeof(interrupt_signals)/sizeof(interrupt_signals[0]);i++) {
133+
int signo = interrupt_signals[i];
134+
if (signal(signo, interrupt_handler_vpf_DOUBLE) == SIG_ERR) {
135+
fprintf(stderr,"Can not handle signal = %d\n", signo);
136+
}
137+
}
138+
139+
122140
rng = gsl_rng_alloc (T);
123141
gsl_rng_set(rng, seed);
124142

@@ -165,7 +183,7 @@ int countspheres_DOUBLE(const int64_t np, DOUBLE * restrict X, DOUBLE * restrict
165183

166184
/* loop through centers, placing each randomly */
167185
int ic=0;
168-
while(ic < nc) {
186+
while(ic < nc && interrupt_status_vpf_DOUBLE == EXIT_SUCCESS) {
169187
if(options->verbose) {
170188
my_progressbar(ic,&interrupted);
171189
}
@@ -307,6 +325,10 @@ int countspheres_DOUBLE(const int64_t np, DOUBLE * restrict X, DOUBLE * restrict
307325

308326
gsl_rng_free (rng);
309327
free_cellarray_DOUBLE(lattice, totncells);
328+
if(interrupt_status_vpf_DOUBLE != EXIT_SUCCESS) {
329+
matrix_free((void **) pN, nbin);
330+
return interrupt_status_vpf_DOUBLE;
331+
}
310332

311333
if(options->verbose) {
312334
finish_myprogressbar(&interrupted);

xi_theory/vpf/countspheres_impl.h.src

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ extern "C" {
1313
#endif
1414

1515
#include "countspheres.h" //for definition of DOUBLE
16+
17+
extern void interrupt_handler_vpf_DOUBLE(int signo);
1618

1719
typedef int (*vpf_func_ptr_DOUBLE)(const int64_t np, DOUBLE * restrict X, DOUBLE * restrict Y, DOUBLE * restrict Z,
1820
const DOUBLE xc, const DOUBLE yc, const DOUBLE zc,

xi_theory/wp/countpairs_wp_impl.c.src

+25-11
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
#include <stdio.h>
1010
#include <stdlib.h>
1111
#include <math.h>
12-
#include <assert.h>
1312
#include <stdint.h>
1413
#include <inttypes.h>
14+
#include <signal.h>
15+
#include <unistd.h>
1516

1617
#include "countpairs_wp_impl_DOUBLE.h" //function proto-type
1718
#include "wp_kernels_DOUBLE.c"
@@ -27,6 +28,15 @@
2728
#include <omp.h>
2829
#endif
2930

31+
int interrupt_status_wp_DOUBLE=EXIT_SUCCESS;
32+
33+
void interrupt_handler_countpairs_wp_DOUBLE(int signo)
34+
{
35+
fprintf(stderr,"Received signal = `%s' (signo = %d). Aborting \n",strsignal(signo), signo);
36+
interrupt_status_wp_DOUBLE = EXIT_FAILURE;
37+
}
38+
39+
3040
wp_func_ptr_DOUBLE wp_driver_DOUBLE(const struct config_options *options)
3141
{
3242
static int initialized = 0;
@@ -121,6 +131,16 @@ int countpairs_wp_DOUBLE(const int64_t ND, DOUBLE * restrict X, DOUBLE * restric
121131

122132
int bin_refine_factor=2,zbin_refine_factor=1;
123133
int nmesh_x, nmesh_y, nmesh_z;
134+
135+
/* setup interrupt handler -> mostly useful during the python execution.
136+
Let's Ctrl-C abort the extension */
137+
int interrupt_signals[] = {SIGTERM, SIGINT, SIGHUP};
138+
for(size_t i=0;i<sizeof(interrupt_signals)/sizeof(interrupt_signals[0]);i++) {
139+
int signo = interrupt_signals[i];
140+
if (signal(signo, interrupt_handler_countpairs_wp_DOUBLE) == SIG_ERR) {
141+
fprintf(stderr,"Can not handle signal = %d\n", signo);
142+
}
143+
}
124144

125145
/***********************
126146
*initializing the bins
@@ -219,7 +239,7 @@ int countpairs_wp_DOUBLE(const int64_t ND, DOUBLE * restrict X, DOUBLE * restric
219239

220240

221241
#if defined(_OPENMP)
222-
#pragma omp parallel shared(numdone, abort_status)
242+
#pragma omp parallel shared(numdone, abort_status, interrupt_status_wp_DOUBLE)
223243
{
224244
const int tid = omp_get_thread_num();
225245
uint64_t npair[nrpbins];
@@ -239,9 +259,9 @@ int countpairs_wp_DOUBLE(const int64_t ND, DOUBLE * restrict X, DOUBLE * restric
239259
for(int index1=0;index1<totncells;index1++) {
240260

241261
#if defined(_OPENMP)
242-
#pragma omp flush (abort_status)
262+
#pragma omp flush (abort_status, interrupt_status_wp_DOUBLE)
243263
#endif
244-
if(abort_status == EXIT_SUCCESS) {
264+
if(abort_status == EXIT_SUCCESS && interrupt_status_wp_DOUBLE == EXIT_SUCCESS) {
245265

246266
if(options.verbose) {
247267
#if defined(_OPENMP)
@@ -331,14 +351,8 @@ int countpairs_wp_DOUBLE(const int64_t ND, DOUBLE * restrict X, DOUBLE * restric
331351
}
332352
}//omp parallel
333353
#endif
334-
335-
if(options.verbose) {
336-
finish_myprogressbar(&interrupted);
337-
fprintf(stderr, "Freeing memory associated with 3-D lattices\n");
338-
}
339354
free_cellarray_index_particles_DOUBLE(lattice, totncells);
340-
341-
if(abort_status != EXIT_SUCCESS) {
355+
if(abort_status != EXIT_SUCCESS || interrupt_status_wp_DOUBLE != EXIT_SUCCESS) {
342356
/* Cleanup memory here if aborting */
343357
free(rupp);
344358
#if defined(_OPENMP)

0 commit comments

Comments
 (0)