예제 #1
0
void ompi_file_set_view_f(MPI_Fint *fh, MPI_Offset *disp,
			 MPI_Fint *etype, MPI_Fint *filetype,
			 char *datarep, MPI_Fint *info, MPI_Fint *ierr,
                         int datarep_len)
{
   MPI_File c_fh = PMPI_File_f2c(*fh);
   MPI_Datatype c_etype = PMPI_Type_f2c(*etype);
   MPI_Datatype c_filetype = PMPI_Type_f2c(*filetype);
   MPI_Info c_info = PMPI_Info_f2c(*info);
   char *c_datarep;
   int c_ierr, ret;

    /* Convert the fortran string */
   if (OMPI_SUCCESS != (ret = ompi_fortran_string_f2c(datarep, datarep_len,
                                                       &c_datarep))) {
        c_ierr = OMPI_ERRHANDLER_INVOKE(c_fh, ret, "MPI_FILE_SET_VIEW");
        if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);
        return;
   }

   c_ierr = PMPI_File_set_view(c_fh, (MPI_Offset) *disp,
                              c_etype, c_filetype,
                              c_datarep, c_info);
   if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr);

   free(c_datarep);
}
예제 #2
0
int MPI_File_set_view(MPI_File fh, MPI_Offset disp, MPI_Datatype etype, 
                      MPI_Datatype filetype, char *datarep, MPI_Info info)
{
    int g2g = 1;
    char call[COLLCHK_SM_STRLEN];
    MPI_Comm comm;

    sprintf(call, "FILE_SET_VIEW");

    /* Check if init has been called */
    g2g = CollChk_is_init();

    if(g2g) {
        /* get the comm */
        if (!CollChk_get_fh(fh, &comm)) {
            return CollChk_err_han("File has not been Opened",
                                   COLLCHK_ERR_FILE_NOT_OPEN, 
                                   call, MPI_COMM_WORLD);
        }

        /* check for call consistancy */
        CollChk_same_call(comm, call);
        /* check type consistancy */
        CollChk_dtype_bcast(comm, etype, 1, 0, call);
        /* check datarep consistancy */
        CollChk_same_datarep(comm, datarep, call);

        /* make the call */
        return PMPI_File_set_view(fh, disp, etype, filetype, datarep, info);
    }
    else {
        /* init not called */
        return CollChk_err_han("MPI_Init() has not been called!", 
                               COLLCHK_ERR_NOT_INIT, call, MPI_COMM_WORLD);
    }
}
예제 #3
0
void ipm_log(void) { /* called by all tasks (or as many as possible) */
    int i,ii,rv,icall,ibytes,irank,ireg,kreg;
    int ipm_log_fd=-1, fan_out=0;
    int log_rank=-1, search_offset=0, token=1;
    FILE *ipm_mpi_log_fh;
    MPI_File ipm_mpiio_log_fh;
    DIR  *ipm_mpi_log_dp;
    struct dirent *de;
    struct stat file_stat;
    IPM_KEY_TYPE key,ikey;
    char *cp, txt[MAXSIZE_TXTLINE];
    char tmp_fname[MAXSIZE_FILENAME];
    char tmp_pref[MAXSIZE_FILENAME];
    char tmp_cmd[MAXSIZE_FILENAME];
    double b_flops;
    double stamp1, stamp2, stamp3, stamp4;
    MPI_Status s[4];
    MPI_Info outinfo;


    if(task.flags & IPM_WROTELOG) return;
    memset((void *)txt,0,(size_t)(MAXSIZE_TXTLINE*sizeof(char)));
    task.flags |= IPM_WROTELOG;

    /* only one chance, even if we fail at this point we should not return  */

    if(task.flags & DEBUG) {
        printf("IPM: %d log enter job.cookie=%s username=%s \n",
               task.mpi_rank,
               job.cookie,
               job.username);
        fflush(stdout);
    }

    /*
    ** bail
    */


    if(strcmp(job.log_dir, "/dev/null") == 0 ) {
        if(task.flags & DEBUG) {
            printf("IPM: %d log exit due to LOGDIR=/dev/null", task.mpi_rank);
        }
        return;
    }

    if(stat(job.log_dir,&file_stat)) {
        if(!task.mpi_rank) {
            printf("IPM: %d log IPMLOG_DIR %s not available using $CWD \n",
                   task.mpi_rank,  job.log_dir);
        }
        sprintf(job.log_dir, "./");
    }


    /*
    ** Aggregation method #1 : Multiple Files - No Aggregation
    IPM_LOG_USEMULTI
    ** Aggregation method #2 : Single File    - Locks
    IPM_LOG_USELOCKS
    ** Aggregation method #3 : Single File    - SMP & /tmp
    IPM_LOG_USETMPFS
    ** Aggregation method #4 : Single File    - MPI  - default
    IPM_LOG_USEMPI
    */

#ifndef IPM_LOG_USEMULTI
#ifndef IPM_LOG_USELOCKS
#ifndef IPM_LOG_USETMPFS
#ifndef IPM_LOG_USEMPI
#endif
#endif
#endif
#endif


#ifdef IPM_LOG_USEMULTI
    sprintf(job.log_fname,"%s/%s.%s.%d",
            job.log_dir,
            job.username,
            job.cookie,
            task.mpi_rank);
#else
    if (!strcmp(job.log_fname,"unset")) {
        sprintf(job.log_fname,"%s/%s.%s.%d",
                job.log_dir,
                job.username,
                job.cookie,0);
    }
    else
    {
        sprintf(tmp_fname,"%s/%s",job.log_dir,job.log_fname);
        sprintf(job.log_fname,"%s",tmp_fname);
    }
#endif

    if(task.flags & DEBUG) {
        printf("IPM: %d log IPMLOG_DIR=%s FNAME=%s \n",
               task.mpi_rank,
               job.log_dir,
               job.log_fname);
    }
    /*
    ** Aggregation method #1 : Multiple Files - No Aggregation  {
    */

#ifdef IPM_LOG_USEMULTI
    /* simplest case no locking just write each file. Parallel FS may
       have metadata storm for N file creates */

    ipm_mpi_log_fh = fopen(job.log_fname,"w");
    if(ipm_mpi_log_fh == NULL) {
        printf("IPM: %d log fopen failed fname=%s \n",
               task.mpi_rank,
               job.log_fname);
        fflush(stdout);
    }
    rv = fprintf(ipm_mpi_log_fh,
                 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<ipm>\n");
    ipm_log_write_task(&job, &task, txt, ipm_mpi_log_fh);
    rv = fprintf(ipm_mpi_log_fh,
                 "</ipm>\n");
    fclose(ipm_mpi_log_fh);
    chmod(job.log_fname, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);

    return;
#endif
    /* } */

    /*
    ** Aggregation methods #2 : Single File    - Locks {
    */
#ifdef IPM_LOG_USELOCKS
    signal(SIGALRM, ipm_alarm_log_block);
    alarm(30);
    IPM_TIME_GTOD(stamp1);
    if(task.flags & DEBUG) {
        printf("IPM: %d log block_lock fname=%s fd=%d stamp=%f \n",
               task.mpi_rank,
               job.log_fname,
               ipm_log_fd,
               stamp1
              );
        fflush(stdout);
    }

    IPM_FILE_LOCK(job.log_fname,ipm_log_fd);

    IPM_TIME_GTOD(stamp2);
    if(task.flags & DEBUG) {
        printf("IPM: %d log block_lock fname=%s fd=%d stamp=%12.6f delta=%.3e \n",
               task.mpi_rank,
               job.log_fname,
               ipm_log_fd,
               stamp2, stamp2-stamp1
              );
        fflush(stdout);
    }


    alarm(0);
    signal(SIGALRM, SIG_DFL);

    ipm_mpi_log_fh = fdopen(ipm_log_fd,"w+");

    if(!ipm_mpi_log_fh || !ipm_log_fd) {
        /* fail silently */
        return;
    }

    /* got log fh */
    fseek(ipm_mpi_log_fh,0,SEEK_END);
    ipm_log_write_task(&job, &task, txt, ipm_mpi_log_fh);

    IPM_TIME_GTOD(stamp3);
    if(task.flags & DEBUG) {
        printf("IPM: %d log write fname=%s fd=%d stamp=%12.6f delta=%.3e \n",
               task.mpi_rank,
               job.log_fname,
               ipm_log_fd,
               stamp3, stamp3-stamp2
              );
        fflush(stdout);
    }


    fflush(ipm_mpi_log_fh);
    IPM_FILE_UNLOCK(job.log_fname,ipm_log_fd);

    IPM_TIME_GTOD(stamp4);
    if(task.flags & DEBUG) {
        printf("IPM: %d log unlock fname=%s fd=%d stamp=%12.6f delta=%.3e \n",
               task.mpi_rank,
               job.log_fname,
               ipm_log_fd,
               stamp4, stamp4-stamp3
              );
        fflush(stdout);
    }

#endif
    /* } */

    /*
    ** Aggregation method #3 : Single File    - SMP & /tmp {
    */
#ifdef IPM_LOG_USETMPFS

    if(task.flags & IPM_MPI_FINALIZING) {
        if(task.mpi_size == 1) { /* special easy case  now uneeded */
        }

        sprintf(tmp_fname,"/tmp/%s.%s.%d",
                job.username,
                job.cookie,
                task.mpi_rank);
        ipm_mpi_log_fh = fopen(tmp_fname,"w");
        if(ipm_mpi_log_fh == NULL) {
            printf("IPM: %d log fopen failed fname=%s \n",
                   task.mpi_rank,
                   tmp_fname);
            fflush(stdout);
        }
        chmod(tmp_fname, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
        ipm_log_write_task(&job, &task, txt, ipm_mpi_log_fh);
        fclose(ipm_mpi_log_fh);


        /* host local ring barrier so that /tmp is all good */

        if(task.intra_size > 1) {
            if(task.intra_root == task.mpi_rank) {
                PMPI_Send(&i,1,MPI_INT,task.intra_right,0,MPI_COMM_WORLD);
                PMPI_Recv(&i,1,MPI_INT,task.intra_left,0,MPI_COMM_WORLD,s);
            } else {
                PMPI_Recv(&i,1,MPI_INT,task.intra_left,0,MPI_COMM_WORLD,s);
                PMPI_Send(&i,1,MPI_INT,task.intra_right,0,MPI_COMM_WORLD);
            }
        }

        if(task.intra_root == task.mpi_rank) {
            if(job.nhosts > 1 && task.mpi_rank) {
                PMPI_Recv(&i,1,MPI_INT,task.inter_left,0,MPI_COMM_WORLD,s);
            }
            /* sh -c lacks PATH on some system so remove popen&system where possible */

            sprintf(tmp_cmd, "/usr/bin/cat /tmp/%s.%s.* >> %s",
                    job.username,
                    job.cookie,
                    job.syslog_fname);
            system(tmp_cmd);

            chmod(job.syslog_fname, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
            sprintf(tmp_cmd, "/usr/bin/rm -f /tmp/%s.%s.* ",
                    job.username,
                    job.cookie);
            system(tmp_cmd);

            /* ugh! duplicating cat and rm is yucky
               sprintf(tmp_pref,"%s.%s", job.username, job.cookie);
               dp=opendir("/tmp");
               if(dp) {
               while(de=readdir(dp))!=NULL){
               if(!strncmp(de->d_name,tmp_pref, strlen(tmp_fname))) {
               sprintf(tmp_fname,"/tmp/%s", de->d_name);
               fopen(tmp_fname,"r"
               read in pieces and write them to the intra-node file
               delete the .rank file
               }
               }
               }
            */

            if(job.nhosts > 1 && task.inter_right != 0) {
                PMPI_Send(&i,1,MPI_INT,task.inter_right,0,MPI_COMM_WORLD);
            }


        }
        return;
    }
#endif
    /* } */

    /*
    ** Aggregation method #4 : Single File    - MPI  {
    */
#ifdef IPM_LOG_USEMPI

    if (task.flags & PARALLEL_IO_LOG ) {
        int buff_size=0;
        MPI_Offset file_offset=0;
        int64_t buff_sum=0;
        int malloc_flag,malloc_sum;
        char* buffer=NULL;
        MPI_Info info;


        /* measure size of buff required */
        buff_size=ipm_log_write(&job, &task, txt, buffer,0,1);

        malloc_flag=1;
        buffer = (char*)malloc(buff_size+1);
        if (buffer == NULL) {
            malloc_flag=0;
        } else {
            rv=ipm_log_write(&job, &task, txt, buffer,buff_size,1);
        }

        /*see whether malloc suceeded across all mpi tasks */
        PMPI_Allreduce(&malloc_flag,&malloc_sum,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD);
        if (malloc_sum == task.mpi_size)  {/* use parallel IO */

            if(task.flags & DEBUG && !task.mpi_rank) {
                printf("IPM: %d IPM report parallel IO used\n", task.mpi_rank);
            }

            PMPI_Info_create(&info);
#ifndef CRAY_GPFS_BUG
            PMPI_Info_set(info,"access_style","write_once");
            PMPI_Info_set(info,"collective_buffering","true");
            PMPI_Info_set(info,"file_perm","0644");
            PMPI_Info_set(info,"romio_cb_read","true");
            PMPI_Info_set(info,"cb_align","2");
            PMPI_Info_set(info,"romio_cb_write","true");
            PMPI_Info_set(info,"cb_config_list","*:1");
            PMPI_Info_set(info,"striping_factor","80");

            PMPI_Info_set(info,"IBM_largeblock_io","true");
#endif

            /* with allowing the user to choose the filename - can overwrite an old */
            /* file - which would be fine if MPI-IO allowed TRUNC - but it doesn't */
            /* so we just delete so that we don't end up with trailing garbage  */
            if (!task.mpi_rank) rv=PMPI_File_delete ( job.log_fname,MPI_INFO_NULL);
            rv=PMPI_Barrier(MPI_COMM_WORLD);

            rv = PMPI_File_open( MPI_COMM_WORLD, job.log_fname, MPI_MODE_WRONLY | MPI_MODE_CREATE,info,  &ipm_mpiio_log_fh );
            if (rv)
            {
                printf("IPM: %d syslog fopen failed fname=%s \n",
                       task.mpi_rank,
                       job.log_fname);
                fflush(stdout);
                return;
            }
            /* workaround for cases when MPI_INTEGER8 is not defined */
#ifndef MPI_INTEGER8
#define MPI_INTEGER8 MPI_LONG_LONG_INT
#endif

            if (task.mpi_size > 1) {
                if (task.mpi_rank == 0) {
                    buff_sum+=(int64_t)buff_size;
                    PMPI_Send (&buff_sum,1,MPI_INTEGER8,1,0,MPI_COMM_WORLD);
                    file_offset=0;
                } else if (task.mpi_rank == (task.mpi_size-1)) {
                    PMPI_Recv (&buff_sum,1,MPI_INTEGER8,task.mpi_rank-1,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
                    file_offset=(MPI_Offset)buff_sum;
                } else {
                    PMPI_Recv (&buff_sum,1,MPI_INTEGER8,task.mpi_rank-1,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
                    file_offset=(MPI_Offset)buff_sum;
                    buff_sum+=(int64_t)buff_size;
                    PMPI_Send (&buff_sum,1,MPI_INTEGER8,task.mpi_rank+1,0,MPI_COMM_WORLD);
                }
            }

            rv=PMPI_File_set_view(ipm_mpiio_log_fh,file_offset,MPI_CHAR, MPI_CHAR,"native",info);

            /*write info*/
            rv=PMPI_File_write_all(ipm_mpiio_log_fh,buffer,buff_size,MPI_CHAR,MPI_STATUS_IGNORE);


            rv = PMPI_File_close( &ipm_mpiio_log_fh );
            PMPI_Barrier(MPI_COMM_WORLD);
            /* Some MPI-IO implimentations (cray) permissions are not setable with hints */
            if (task.mpi_rank == 0) chmod (job.log_fname,0744);
            free (buffer);
            return;
        } else {
            if (! task.mpi_rank) printf("IPM: %d Allocation of IO Buffer failed on one or more tasks\n",task.mpi_rank);
        }
    }
    /*parallel IO failed */
    if (! task.mpi_rank) printf("IPM: %d Using serial IO\n",task.mpi_rank);

    /*************************************/
    /* write log from rank zero using MPI*/
    /*************************************/
    if(task.mpi_rank==0) {
        ipm_mpi_log_fh = fopen(job.log_fname,"w+");
        if(ipm_mpi_log_fh == NULL) {
            printf("IPM: %d syslog fopen failed fname=%s \n",
                   task.mpi_rank,
                   job.log_fname);
            fflush(stdout);
        }
        chmod(job.log_fname, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);

        ipm_log_write(&job, &task, txt,ipm_mpi_log_fh ,0,0);
        /* we now pollute the local profile state irrevocably in the interest
           of keeping a memory footprint  which is a constant independent of
           concurrency */

        /* task 0 initiates a volley of Sends via a handshake */
        for(i=1; i<job.ntasks; i++) {
            PMPI_Send(&token,1,MPI_INT,i,0,MPI_COMM_WORLD);
            PMPI_Recv(&job,sizeof(struct ipm_jobdata),MPI_BYTE,i,0,MPI_COMM_WORLD,s+0);
            PMPI_Recv(&task,sizeof(struct ipm_taskdata),MPI_BYTE,i,1,MPI_COMM_WORLD,s+1);
            PMPI_Recv(&(txt[0]),MAXSIZE_TXTLINE,MPI_CHAR,i,1,MPI_COMM_WORLD,s+1);

            ipm_log_write(&job, &task, txt,ipm_mpi_log_fh ,0,0);
        }
        fclose(ipm_mpi_log_fh);
    } else {
        PMPI_Recv(&token,1,MPI_INT,0,0,MPI_COMM_WORLD,s+0);
        PMPI_Send(&job,sizeof(struct ipm_jobdata),MPI_BYTE,0,0,MPI_COMM_WORLD);
        PMPI_Send(&task,sizeof(struct ipm_taskdata),MPI_BYTE,0,1,MPI_COMM_WORLD);
        PMPI_Send(&(txt[0]),MAXSIZE_TXTLINE,MPI_CHAR,0,1,MPI_COMM_WORLD);
    }
    PMPI_Barrier(MPI_COMM_WORLD);

    return;
#endif

    return;
}