2013-02-08 3 views
0

У меня есть код C, который требует переадресации с помощью openMP. сам код работает нормально, но не при парализовании. код запускается с PBS, и я включил пакетный скрипт.OpenMP- no output

Код имеет две парализованные области, как в цикле времени, которые становятся последовательными в конце для печати выходных файлов. идеально для того, чтобы иметь один выход на шаг времени.

Последовательный i выводит файл каждый таймepep, но параллельно он выводит первый файл и продолжает бесконечно выводить вывод (включая файлы ошибок, как самодельные, так и системные ошибки).

Код

.#pragma omp parallel for default(none) private (dudx2, dudy2, dudz2, du, /*I_gap, I_gap2,*/ Ii, x, y, z) shared (V, Vnew, /*v_fibro,*/ hh) schedule(static) 
    for (z=1;z<Z;z++) { 
      for (y=1;y<Y;y++) 
       for (x=1;x<X;x++) 
        if (hh[x][y][z] > 0) { 


      dudx2 = (V[x - 1][y][z] + V[x + 1][y][z] - 2 * V[x][y][z]) ; 
      dudy2 = (V[x][y - 1][z] + V[x][y + 1][z] - 2 * V[x][y][z]) ; 
      dudz2 = (V[x][y][z - 1] + V[x][y][z + 1] - 2 * V[x][y][z]); 

      du = (D/(dx*dx))*((dudx2) + (dudy2) + (dudz2)) ; 


      Ii = MYO(x,y,z); //calls function with multiple multi-dimen' arrays 

         Vnew[x][y][z] = V[x][y][z] + dt * (du - Ii); 
     } 
    } 





.#pragma omp parallel for default(none) shared (V, Vnew, hh) private (x, y, z) schedule(static) 
      for (z=0;z<=Z;z++) { 
        for (y=0;y<=Y;y++) 
          for (x=0;x<=X;x++){ 
                  if (hh[x][y][z] > 0) 
           V[x][y][z]=Vnew[x][y][z]; 

          } 

      } 

         sprintf(str2,"V%d.vtk",tab); 
      fprintf(outp,"%s\n",str2); 
      userfile=fopen(str2,"wt"); 
      if(userfile==NULL) fprintf(outp,"Could not open%s\n.",str2); 

        tab++; 

        fprintf(userfile,"vtk header\n"); 




       for (z=0;z<Z;z++){ 
        for (y=0;y<Y;y++){ 
         for (x=0;x<X;x++){  
         fprintf(userfile,"%g ",Vnew[x][y][z]);      
          } 

Примечание

-The многомерные массивы 200x200x200 и есть 20+ из них, которые не могут быть уменьшены realisitcally (представляют собой биологические клеточные свойства в 3D ткани)

Это позволяет нам исследовать возможность ошибки памяти. поэтому мы изменили пакетный скрипт, чтобы разрешить 8gb на процессор

- код включает в себя и omp_set_num_threads (64), а строка компиляции;

gcc -lm -lgomp -fopenmp -03 filename.c -o test ("-mcmodel=medium" has been trialed) 

-The партия сценарий

mppwidth и aprun не работают

.#!/bin/bash 
.#PBS -l nodes=1:ppn=64 
.#PBS -l mem=512G 
.#PBS -M email [email protected] 
.#PBS -l walltime=20:00:00 
.#PBS -N test 
.#PBS -o ./ 
.#PBS -e ./ 

.#Modules! 
. /etc/profile.d/modules.sh 

module purge 

.#(Intel compilers) 
.# source /opt/intel/composer_xe_2011_sp1.7.256/bin/compilervars.sh intel64 
module load intel/composerxe/13.0.0 

cd $PBS_O_WORKDIR 

export OMP_NUM_THREADS=64 

./test 

Заранее спасибо, и извинения по поводу плачевной грамматики орфографии и форматирования и т.д.

+0

Кстати, вы используете printf, который буферизуется, поэтому вы получите «спагетти» в выходном файле. Замените printf на sprintf на строку и только на последней строке цикла printf, следующей за fflush. И даже в этом случае, если ваш буфер будет больше, чем буфер stdio, вы не получите атомную операцию. –

+0

Извините. Я плохо прочитал код. Может быть, вы попытаетесь определить в 'private' только z и в других циклах write' (для int y = ... '? –

ответ

0

Здесь представляет собой простой пример:

#include <stdio.h> 
#include <math.h> 
#include <sys/time.h> 

#define OMP_NUM_THREADS 4 
#define X 50 
#define Y 50 
#define Z 50 

double dtime(){ 
double t; 
struct timeval tv; 
gettimeofday(&tv, NULL); 
t = tv.tv_sec + ((double)tv.tv_usec)/1e6; 
return t; 
} 

int main(int argv, char **argc){ 
double V[X][Y][Z]; 
double Vnew[X][Y][Z]; 
int z; 

for (int z=0;z<Z;z++) 
    for (int y=0;y<Y;y++) 
    for (int x=0;x<X;x++) 
    V[x][y][z] = 3.*x+2.*y+z; 

double t0 = dtime(); 
#pragma omp parallel for shared(V, Vnew) 
for(z=1;z<Z;z++) 
    for(int y=1;y<Y;y++) 
    for(int x=1;x<X;x++) 
    Vnew[x][y][z] = sin(V[x][y][z])*cos(V[x][y][z])+log(V[x][y][z]); 
printf("time: %g\n", dtime() - t0); 
FILE *userfile=fopen("out" ,"w"); 
fprintf(userfile,"vtk header\n"); 
for (z=0;z<Z;z++) 
    for (int y=0;y<Y;y++) 
    for (int x=0;x<X;x++) 
    fprintf(userfile,"%g ",Vnew[x][y][z]); 
} 

Компиляция:

gcc -std=gnu99 -fopenmp -lm 1.c 

После запуска на моей машине (4-ядерный) это дает:

time: 0.0224061 

Когда я комментирую #pragma omp, я получаю:

time: 0.059217 
+0

Мне жаль, если я был полным noob. но означает ли это, что с моими парализованными петлями есть что-то неправомерно? и первый цикл является наиболее критичным, а MYO - это большая функция для вызова. – user2054764

+0

Возьмите эту функцию 'dtime' и сравните время с и без openmp. Иногда слишком много параметров только замедляют выполнение. –

0

Мы добились прогресса в получении parralleising для работы в openmp, но только для небольших файлов (будет запускаться для массивов 20x20x20, 50x50x50, но не для 100 ...) с 20x20x20 медленнее и 50x50x 50 значительно быстрее. но нам нужно, чтобы он работал с гораздо большими аранжировками в longrun

для больших файлов он записывает первый outfile для первого цикла и не записывает остальное (наблюдается с меньшими размерами массива), потому что он работает с меньшие размеры массивов, нам было интересно, может ли это быть проблемой памяти?