일부 수치 계산을 위해 GSL 라이브러리의 Monte Carlo 통합 서브 루틴을 호출하려고했습니다. my for 루프는 다소 단순하기 때문에 다른 실행 결과가 독립적이라는 것을 의미하므로 OpenMP를 사용하여 병렬 처리하는 것이 매우 간단해야합니다. 그러나 내가 컴파일 할 때 항상 "내부 컴파일러 오류 : 분할 오류"라고 말하며 아무것도 생성하지 않았습니다.OpenMP 병렬 영역에서 중첩 함수의 내부 컴파일러 오류
#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");
do
{
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 for 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, ¶ms);
}
VEGAS_integration_routine (&g, xl, xu, calls, r);
}
gsl_rng_free (r);
return 0;
}
이 코드는 것은 기본적으로 GSL webpage에 샘플 코드에서 수정 : 여기 내 코드입니다. OpenMP를 사용하지 않으면 완벽하게 작동합니다. 내가 컴파일 할 수 있기 때문에
test2.c: In function 'main':
test2.c:85: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
Preprocessed source stored into /tmp/ccAGFe3v.out file, please attach this to your bugreport.
make: *** [test2.o] Error 1
: 나는 우리의 서버에서 작동, (추가 -fopenmp
로) 다음 명령을 사용하여 컴파일 GCC를 사용하지만
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
나는 다음과 같은 오류 메시지를 받았습니다 그것과 위의 오류 메시지가 너무 제한되어있어 무엇이 잘못되었는지 정말 알고 싶습니다. 따라서 서브 루틴을 분해하여
VEGAS_integration_routine
을 호출 한 다음 한 줄씩 실행하십시오. 내가 찾은 것은 두 번째 줄에서 컴파일이 중단되었다는 것입니다.
gsl_monte_function Function = { function, 2, 0 };
이렇게 혼란 스러웠습니다. 루프를 평탄화하기 위해 OpenMP를 사용할 때 루프에서 GSL 기능을 선언 할 수 있습니까? GSL과 OpenMP간에 내부 충돌이 있습니까? 나는 Stack Overflow와 Google에서 검색을했는데 관련 포스트가 존재하지 않는 것 같습니다 (너무 이상합니다!) 누군가가 여기에서 무슨 일이 일어나고 있는지 설명하거나 병렬 컴퓨팅을 수행하는 다른 방법을 지적 할 수 있다면 정말 고맙겠습니다. 나는 for 루프를 작성하는 방법이 가장 좋고 가장 깨끗한 것이 아님을 확신한다 ...
와우 감사합니다. @Hristo! 중첩 된 함수가 C에서 비표준임을 알지 못했습니다 ... 저는 중첩 함수를 지원하는 Mathematica를 사용하여 계산을했습니다. 어쨌든, 적어도 나는 뭔가를 배웁니다! 그러나이 경우에는 GSL 통합 서브 루틴 (즉,'Reg1'을 사용하여'gsl_monte_function' 객체를 선언 한 후'gsl_monte_vegas_integrate'에 전달)에 대한 적분 함수'Reg1'의 참조를 전달해야하므로 다른 t 값으로 계산하고 싶기 때문에 (for 루프가 필요한 이유입니다.) 중첩 된 함수를 사용하지 않고 다시 작성할 수 있습니까? –
그것은 가능하며 GSL은이를 수행 할 수있는 특정 인터페이스를 제공합니다. 그에 따라 내 대답을 업데이트했습니다. –
코드가 올바르게 작동하는 것보다 더 흥미로운 것은 없습니다! 나는 당신의 상세한 답변을 주셔서 감사합니다! (솔직히 말하면, 왜 무효 포인터'params'가 있는지 이해하지 못했습니다 (예 : [here] (http://www.gnu.org/software/gsl/manual/html_node/Monte-Carlo-Interface.html 참조).)) 내가 수정 된 코드를 읽을 때까지 ...) –