gcc - Internal compiler error with nested functions in OpenMP parallel regions -


i tried call monte carlo integration subroutine of gsl library numerical calculation. because loop rather simple, meaning results of different runs independent, expect should straightforward parallelize using openmp. when compiled it, said "internal compiler error: segmentation fault", , generated nothing. here code:

#include <stdlib.h> #include <omp.h> #include <gsl/gsl_math.h> #include <gsl/gsl_monte.h> #include <gsl/gsl_monte_vegas.h> #include <math.h>        double  reg1 (double *x, double t, size_t dim, void *params)  {      return sin(x[1])*cos(t*t)*x[0]*x[0]*cos(x[0])*cos(3*x[0]);  }    void  display_results (char *title, double result, double error)  {    printf ("%s ==================\n", title);    printf ("result = % .10f\n", result);    printf ("sigma  = % .10f\n\n", error);  }    void  vegas_integration_routine (double (*function)(double *, size_t, void *),                              double xl[], double xu[], size_t calls, gsl_rng * r)  {  double res, err;      gsl_monte_function function = { function, 2, 0 };          gsl_monte_vegas_state *s = gsl_monte_vegas_alloc (2);       gsl_monte_vegas_integrate (&function, xl, xu, 2, 20000, r, s, &res, &err);       display_results ("vegas warm-up", res, err);       printf ("converging...\n");              {          gsl_monte_vegas_integrate (&function, xl, xu, 2, calls, r, s, &res, &err);           printf ("result = % .10f; sigma = % .10f; "                  "chisq/dof = %.2f\n", res, err, gsl_monte_vegas_chisq (s));        }      while (fabs (gsl_monte_vegas_chisq (s) - 1.0) > 0.05);       display_results ("vegas final", res, err);       gsl_monte_vegas_free (s);  }    int  main (void)  {       int seg = 200;     double xl[2] = { 195.0, -1000.0 };    double xu[2] = { 205.0, 1000.0 };     const gsl_rng_type *t;    gsl_rng *r;     size_t calls = 1000000;     gsl_rng_env_setup ();     t = gsl_rng_default;    r = gsl_rng_alloc (t);     /* calculate g1 */    int i;    double j=0;    #pragma omp parallel shared(xl,xu,calls,r,seg) private(i,j)    for(i=0; i<=seg; i=i+1)    {     j=(double)i * 0.05;     printf("now it's t = %.2f \n", j);     printf("compute re(g1)...\n");     double g(double * x, size_t dim, void *params)     {         return reg1(x, j, dim, &params);         }         vegas_integration_routine (&g, xl, xu, calls, r);    }    gsl_rng_free (r);     return 0;  } 

this code modified sample code on gsl webpage. without using openmp, works perfectly. when used gcc compile following commands (with -fopenmp added) , works on our server,

gcc -c -wall -ansi -i/usr/include -l/usr/lib/gcc/x86_64-redhat-linux/4.4.4/ -lgomp -fopenmp test2.c -o test2.o gcc -l/usr/lib64/  test2.o -l/usr/lib/gcc/x86_64-redhat-linux/4.4.4/ -lgomp -fopenmp -lgsl -lgslcblas -lm -o test2.out 

i got following error message:

test2.c: in function 'main': test2.c:85: internal compiler error: segmentation fault please submit full bug report, preprocessed source if appropriate. see <http://bugzilla.redhat.com/bugzilla> instructions. preprocessed source stored /tmp/ccagfe3v.out file, please attach bugreport. make: *** [test2.o] error 1 

since couldn't compile , error message shown above limited, i'd know what's wrong, decompose subroutine vegas_integration_routine called , run line line. found compilation stopped @ second line

gsl_monte_function function = { function, 2, 0 }; 

which made me confused. can't declare gsl function in loop when using openmp flatten loop? there internal conflict between gsl , openmp? did search on stack overflow google, seems no related post exists (so odd!).i appreciate if either explain what's going on here, or point out alternative way parallel computing. i'm sure way wrote loop wasn't best , neatest...

there a regression bug in way implementation of lexical closures in gcc interacts openmp code transformation engine. bug appears fixed in later versions of gcc 4.7 branch. if cannot replace gcc 4.4.4 gcc 4.7.1 or later, should rewrite code not use nested functions in gsl example refer in post. besides, nested functions non-standard gcc c extension , should refrain using them wherever possible.

the monte carlo integration interface in gsl supports passing additional arguments integrand via void *params argument explained here. have change reg1 follows:

double reg1 (double *x, size_t dim, void *params) {     double t = *(double *)params;     return sin(x[1])*cos(t*t)*x[0]*x[0]*cos(x[0])*cos(3*x[0]); } 

and update second line of vegas_integration_routine read:

gsl_monte_function function = { function, 2, &t }; 

you have add t list of dummy arguments of vegas_integration_routine , pass value main. relevant parts therefore become:

void vegas_integration_routine (double (*function)(double *, size_t, void *),                            double t,                            double xl[], double xu[], size_t calls, gsl_rng * r) {    double res, err;    gsl_monte_function function = { function, 2, &t };    ... }  #pragma omp parallel for(i=0; <= seg; i++) {    double t = (double)i * 0.05;    ...    vegas_integration_routine (reg1, t, xl, xu, calls, r); } 

Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

CSS3 Transition to highlight new elements created in JQuery -