コード例 #1
0
bool Excn::ExodusFile::initialize(const SystemInterface& si, int start_part, int part_count)
{
  processorCount_ = si.processor_count(); // Total number processors
  partCount_      = part_count;      // Total parts we are processing
  startPart_      = start_part;      // Which one to start with
  SMART_ASSERT(partCount_ + startPart_ <= processorCount_)(partCount_)(startPart_)(processorCount_);
  
  // EPU always wants entity (block, set, map) ids as 64-bit quantities...
  mode64bit_ = EX_IDS_INT64_API;
  if (si.int64()) {
    mode64bit_ |= EX_ALL_INT64_API;

    // For output...
    mode64bit_ |= EX_ALL_INT64_DB;
  }

  // See if we can keep files open 
  int max_files = get_free_descriptor_count();
  if (partCount_ <= max_files) {
    keepOpen_ = true;
    if (si.debug() & 1)
      std::cout << "Files kept open... (Max open = " << max_files << ")\n\n";
  } else {
    keepOpen_ = false;
    std::cout << "Single file mode... (Max open = " << max_files << ")\n"
	      << "Consider using the -subcycle option for faster execution...\n\n";
  }

  fileids_.resize(processorCount_);
  filenames_.resize(processorCount_);

  std::string curdir = si.cwd();
  std::string file_prefix = si.basename();
  std::string exodus_suffix = si.exodus_suffix();
  
  std::string root_dir = si.root_dir();
  std::string sub_dir  = si.sub_dir();

  ParallelDisks disks;
  disks.Raid_Offset(si.raid_offset());
  disks.Number_of_Raids(si.raid_count());

  float version = 0.0;

  // create exo names
  for(int p = 0; p < partCount_; p++) {
    std::string name = file_prefix;
    if (!exodus_suffix.empty()) {
      name += "." + exodus_suffix;
    }

    int proc = p + startPart_;
    disks.rename_file_for_mp(root_dir, sub_dir, name, proc,
			     processorCount_); 
    filenames_[p] = name;

    if (p == 0) {
      int cpu_word_size  = sizeof(float);
      int io_word_size_var   = 0;
      int mode = EX_READ;
      mode |= mode64bit_;
      int exoid = ex_open(filenames_[p].c_str(),
			  mode, &cpu_word_size,
			  &io_word_size_var, &version);
      if (exoid < 0) {
	std::cerr << "Cannot open file '" << filenames_[p] << "'" << std::endl;
	return false;
      }

      int int64db = ex_int64_status(exoid) & EX_ALL_INT64_DB;
      if (int64db) {
	// If anything stored on input db as 64-bit int, then output db will have
	// everything stored as 64-bit ints and all API functions will use 64-bit
	mode64bit_ |= EX_ALL_INT64_API;
	mode64bit_ |= EX_ALL_INT64_DB;
      }
      
      int max_name_length = ex_inquire_int(exoid, EX_INQ_DB_MAX_USED_NAME_LENGTH);
      if (max_name_length > maximumNameLength_)
	maximumNameLength_ = max_name_length;

      ex_close(exoid);

      if (io_word_size_var < (int)sizeof(float))
	io_word_size_var = sizeof(float);

      ioWordSize_ = io_word_size_var;
      cpuWordSize_ = io_word_size_var;
    }

    if (keepOpen_ || p == 0) {
      int io_word_size_var   = 0;
      int mode = EX_READ;
      // All entity ids (block, sets) are read/written as 64-bit...
      mode |= mode64bit_;
      fileids_[p] = ex_open(filenames_[p].c_str(),
			    mode, &cpuWordSize_,
			    &io_word_size_var, &version);
      if (fileids_[p] < 0) {
	std::cerr << "Cannot open file '" << filenames_[p] << "'" << std::endl;
	return false;
      }
      ex_set_max_name_length(fileids_[p], maximumNameLength_);
      SMART_ASSERT(ioWordSize_ == io_word_size_var)(ioWordSize_)(io_word_size_var);
    }
    
    if (si.debug()&64 || p==0 || p==partCount_-1) {
      std::cout << "Input(" << p << "): '" << name.c_str() << "'" << std::endl;
      if (!(si.debug()&64) && p==0)
	std::cout << "..." << std::endl;
    }
  }

  if (mode64bit_ & EX_ALL_INT64_DB) {
    std::cout << "Input files contain 8-byte integers.\n";
    si.set_int64();
  }

  return true;
}
コード例 #2
0
ファイル: ps_restart.C プロジェクト: 00liujj/trilinos
void NemSpread<T,INT>::read_restart_data ()

/* Function which reads the restart variable data from the EXODUS II
 * database which contains the results information. Then distribute
 * it to the processors, and write it to the parallel exodus files.
 *
 *----------------------------------------------------------------------------
 *
 * Functions called:
 *
 * read_vars -- function which reads the variable values from the restart
 *              file, and then distributes them to the processors
 *
 * write_var_timestep -- function which writes out the variables for a
 *                       to a parallel ExodusII file.
 *
 *----------------------------------------------------------------------------
 */

{
    const char  *yo="read_restart_data";

    /* need to get the element block ids and counts */
    std::vector<INT> eb_ids_global(globals.Num_Elem_Blk);
    std::vector<INT> eb_cnts_global(globals.Num_Elem_Blk);
    std::vector<INT> ss_ids_global(globals.Num_Side_Set);
    std::vector<INT> ss_cnts_global(globals.Num_Side_Set);
    std::vector<INT> ns_ids_global(globals.Num_Node_Set);
    std::vector<INT> ns_cnts_global(globals.Num_Node_Set);

    INT ***eb_map_ptr = NULL, **eb_cnts_local = NULL;
    int    exoid=0, *par_exoid = NULL;

    float  vers;
    char   cTemp[512];

    /* computing precision should be the same as the database precision
     *
     * EXCEPTION: if the io_ws is smaller than the machine precision,
     * ie - database with io_ws == 4 on a Cray (sizeof(float) == 8),
     * then the cpu_ws must be the machine precision.
     */
    int cpu_ws;
    if (io_ws < (int)sizeof(float)) cpu_ws = sizeof(float);
    else                            cpu_ws = io_ws;

    /* Open the ExodusII file */
    {
        cpu_ws = io_ws;
        int mode = EX_READ | int64api;
        if ((exoid=ex_open(Exo_Res_File, mode, &cpu_ws, &io_ws, &vers)) < 0) {
            fprintf(stderr, "%s: Could not open file %s for restart info\n",
                    yo, Exo_Res_File);
            exit(1);
        }
    }

    /* allocate space for the global variables */
    Restart_Info.Glob_Vals.resize(Restart_Info.NVar_Glob);

    if (Restart_Info.NVar_Elem > 0 ) {

        /* allocate storage space */
        Restart_Info.Elem_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Elem *
                                (globals.Num_Internal_Elems[iproc] + globals.Num_Border_Elems[iproc]);
            Restart_Info.Elem_Vals[iproc].resize(array_size);
        }

        /*
         * at this point, I need to broadcast the global element block ids
         * and counts to the processors. I know that this is redundant data
         * since they will all receive this information in read_mesh, but
         * the variables which contain that information are static in
         * el_exoII_io.c, and cannot be used here. So, take a second and
         * broadcast all of this out.
         *
         * I want to do this here so that it is done only once no matter
         * how many time steps are retrieved
         */

        /* Get the Element Block IDs from the input file */
        if (ex_get_ids (exoid, EX_ELEM_BLOCK, TOPTR(eb_ids_global)) < 0)
        {
            fprintf(stderr, "%s: unable to get element block IDs", yo);
            exit(1);
        }

        /* Get the count of elements in each element block */
        for (int cnt = 0; cnt < globals.Num_Elem_Blk; cnt++) {
            if (ex_get_block(exoid, EX_ELEM_BLOCK, eb_ids_global[cnt], cTemp,
                             &(eb_cnts_global[cnt]), NULL, NULL, NULL, NULL) < 0) {
                fprintf(stderr, "%s: unable to get element count for block id "ST_ZU"",
                        yo, (size_t)eb_ids_global[cnt]);
                exit(1);
            }
        }

        /*
         * in order to speed up finding matches in the global element
         * number map, set up an array of pointers to the start of
         * each element block's global element number map. That way
         * only entries for the current element block have to be searched
         */
        eb_map_ptr = (INT ***) array_alloc (__FILE__, __LINE__, 2,Proc_Info[2],
                                            globals.Num_Elem_Blk, sizeof(INT *));
        if (!eb_map_ptr) {
            fprintf(stderr, "[%s]: ERROR, insufficient memory!\n", yo);
            exit(1);
        }
        eb_cnts_local = (INT **) array_alloc (__FILE__, __LINE__, 2,Proc_Info[2],
                                              globals.Num_Elem_Blk, sizeof(INT));
        if (!eb_cnts_local) {
            fprintf(stderr, "[%s]: ERROR, insufficient memory!\n", yo);
            exit(1);
        }

        /*
         * for now, assume that element blocks have been
         * stored in the same order as the global blocks
         */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            int    ifound = 0;
            size_t offset = 0;
            int    ilocal;
            for (int cnt = 0; cnt < globals.Num_Elem_Blk; cnt++) {
                for (ilocal = ifound; ilocal < globals.Proc_Num_Elem_Blk[iproc]; ilocal++) {
                    if (globals.Proc_Elem_Blk_Ids[iproc][ilocal] == eb_ids_global[cnt])
                        break;
                }

                if (ilocal < globals.Proc_Num_Elem_Blk[iproc]) {
                    eb_map_ptr[iproc][cnt] = &globals.GElems[iproc][offset];
                    eb_cnts_local[iproc][cnt] = globals.Proc_Num_Elem_In_Blk[iproc][ilocal];
                    offset += globals.Proc_Num_Elem_In_Blk[iproc][ilocal];
                    ifound = ilocal; /* don't search the same part of the list over */
                }
                else {
                    eb_map_ptr[iproc][cnt] = NULL;
                    eb_cnts_local[iproc][cnt] = 0;
                }
            }
        }

    } /* End: "if (Restart_Info.NVar_Elem > 0 )" */

    if (Restart_Info.NVar_Node > 0 ) {
        /* allocate storage space */
        Restart_Info.Node_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Node * (globals.Num_Internal_Nodes[iproc] +
                                globals.Num_Border_Nodes[iproc] + globals.Num_External_Nodes[iproc]);
            Restart_Info.Node_Vals[iproc].resize(array_size);
        }
    }

    if (Restart_Info.NVar_Sset > 0 ) {

        /* allocate storage space */
        Restart_Info.Sset_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Sset * globals.Proc_SS_Elem_List_Length[iproc];

            Restart_Info.Sset_Vals[iproc].resize(array_size);
        }

        /*
         * at this point, I need to broadcast the ids and counts to the
         * processors. I know that this is redundant data since they will
         * all receive this information in read_mesh, but the variables
         * which contain that information are static in el_exoII_io.c, and
         * cannot be used here. So, take a second and broadcast all of
         * this out.
         *
         * I want to do this here so that it is done only once no matter
         * how many time steps are retrieved
         */

        /* Get the Sideset IDs from the input file */
        if (ex_get_ids (exoid, EX_SIDE_SET, TOPTR(ss_ids_global)) < 0) {
            fprintf(stderr, "%s: unable to get sideset IDs", yo);
            exit(1);
        }

        /* Get the count of elements in each sideset */
        for (int cnt = 0; cnt < globals.Num_Side_Set; cnt++) {
            if (ex_get_set_param(exoid, EX_SIDE_SET,
                                 ss_ids_global[cnt],
                                 &(ss_cnts_global[cnt]), NULL) < 0) {
                fprintf(stderr, "%s: unable to get element count for sideset id "ST_ZU"",
                        yo, (size_t)ss_ids_global[cnt]);
                exit(1);
            }
        }
    } /* End: "if (Restart_Info.NVar_Sset > 0 )" */


    if (Restart_Info.NVar_Nset > 0 ) {

        /* allocate storage space */
        Restart_Info.Nset_Vals.resize(Proc_Info[2]);

        /* now allocate storage for the values */
        for (int iproc = 0; iproc <Proc_Info[2]; iproc++) {
            size_t array_size = Restart_Info.NVar_Nset * globals.Proc_NS_List_Length[iproc];
            Restart_Info.Nset_Vals[iproc].resize(array_size);
        }

        /*
         * at this point, I need to broadcast the ids and counts to the
         * processors. I know that this is redundant data since they will
         * all receive this information in read_mesh, but the variables
         * which contain that information are static in el_exoII_io.c, and
         * cannot be used here. So, take a second and broadcast all of
         * this out.
         *
         * I want to do this here so that it is done only once no matter
         * how many time steps are retrieved
         */

        /* Get the Nodeset IDs from the input file */
        if (ex_get_ids (exoid, EX_NODE_SET, TOPTR(ns_ids_global)) < 0) {
            fprintf(stderr, "%s: unable to get nodeset IDs", yo);
            exit(1);
        }

        /* Get the count of elements in each nodeset */
        for (int cnt = 0; cnt < globals.Num_Node_Set; cnt++) {
            if (ex_get_set_param(exoid, EX_NODE_SET,
                                 ns_ids_global[cnt],
                                 &(ns_cnts_global[cnt]), NULL) < 0) {
                fprintf(stderr, "%s: unable to get element count for nodeset id "ST_ZU"",
                        yo, (size_t)ns_ids_global[cnt]);
                exit(1);
            }
        }
    } /* End: "if (Restart_Info.NVar_Nset > 0 )" */


    /*
     * NOTE: A possible place to speed this up would be to
     * get the global node and element lists here, and broadcast
     * them out only once.
     */

    par_exoid = (int*)malloc(Proc_Info[2] * sizeof(int));
    if(!par_exoid) {
        fprintf(stderr, "[%s]: ERROR, insufficient memory!\n",
                yo);
        exit(1);
    }

    /* See if any '/' in the name.  IF present, isolate the basename of the file */
    if (strrchr(PIO_Info.Scalar_LB_File_Name, '/') != NULL) {
        /* There is a path separator.  Get the portion after the
         * separator
         */
        strcpy(cTemp, strrchr(PIO_Info.Scalar_LB_File_Name, '/')+1);
    } else {
        /* No separator; this is already just the basename... */
        strcpy(cTemp, PIO_Info.Scalar_LB_File_Name);
    }

    if (strlen(PIO_Info.Exo_Extension) == 0)
        add_fname_ext(cTemp, ".par");
    else
        add_fname_ext(cTemp, PIO_Info.Exo_Extension);

    int open_file_count = get_free_descriptor_count();
    if (open_file_count >Proc_Info[5]) {
        printf("All output files opened simultaneously.\n");
        for (int iproc=Proc_Info[4]; iproc <Proc_Info[4]+Proc_Info[5]; iproc++) {

            gen_par_filename(cTemp, Par_Nem_File_Name, Proc_Ids[iproc],
                             Proc_Info[0]);

            /* Open the parallel Exodus II file for writing */
            cpu_ws = io_ws;
            int mode = EX_WRITE | int64api | int64db;
            if ((par_exoid[iproc]=ex_open(Par_Nem_File_Name, mode, &cpu_ws,
                                          &io_ws, &vers)) < 0) {
                fprintf(stderr,"[%d] %s Could not open parallel Exodus II file: %s\n",
                        iproc, yo, Par_Nem_File_Name);
                exit(1);
            }
        }
    } else {
        printf("All output files opened one-at-a-time.\n");
    }

    /* Now loop over the number of time steps */
    for (int time_idx = 0; time_idx < Restart_Info.Num_Times; time_idx++) {

        double start_t = second ();

        /* read and distribute the variables for this time step */
        if (read_vars(exoid, Restart_Info.Time_Idx[time_idx],
                      TOPTR(eb_ids_global), TOPTR(eb_cnts_global), eb_map_ptr,
                      eb_cnts_local,
                      TOPTR(ss_ids_global), TOPTR(ss_cnts_global),
                      TOPTR(ns_ids_global), TOPTR(ns_cnts_global)) < 0) {
            fprintf(stderr, "%s: Error occured while reading variables\n",
                    yo);
            exit(1);
        }
        double end_t   = second () - start_t;
        printf ("\tTime to read  vars for timestep %d: %f (sec.)\n", (time_idx+1), end_t);

        start_t = second ();
        for (int iproc=Proc_Info[4]; iproc <Proc_Info[4]+Proc_Info[5]; iproc++) {

            if (open_file_count <Proc_Info[5]) {
                gen_par_filename(cTemp, Par_Nem_File_Name, Proc_Ids[iproc],
                                 Proc_Info[0]);

                /* Open the parallel Exodus II file for writing */
                cpu_ws = io_ws;
                int mode = EX_WRITE | int64api | int64db;
                if ((par_exoid[iproc]=ex_open(Par_Nem_File_Name, mode, &cpu_ws,
                                              &io_ws, &vers)) < 0) {
                    fprintf(stderr,"[%d] %s Could not open parallel Exodus II file: %s\n",
                            iproc, yo, Par_Nem_File_Name);
                    exit(1);
                }
            }

            /*
             * Write out the variable data for the time steps in this
             * block to each parallel file.
             */
            write_var_timestep(par_exoid[iproc], iproc, (time_idx+1),
                               TOPTR(eb_ids_global), TOPTR(ss_ids_global), TOPTR(ns_ids_global));

            if (iproc%10 == 0 || iproc ==Proc_Info[2]-1)
                printf("%d", iproc);
            else
                printf(".");

            if (open_file_count <Proc_Info[5]) {
                if (ex_close(par_exoid[iproc]) == -1) {
                    fprintf(stderr, "[%d] %s Could not close the parallel Exodus II file.\n",
                            iproc, yo);
                    exit(1);
                }
            }
        } /* End "for (iproc=0; iproc <Proc_Info[2]; iproc++)" */

        end_t   = second () - start_t;
        printf ("\n\tTime to write vars for timestep %d: %f (sec.)\n", (time_idx+1), end_t);

    }
    if (Restart_Info.NVar_Elem > 0 ) {
        safe_free((void **) &eb_map_ptr);
        safe_free((void **) &eb_cnts_local);
    }

    /* Close the restart exodus II file */
    if (ex_close(exoid) == -1) {
        fprintf(stderr, "%sCould not close the restart Exodus II file\n",
                yo);
        exit(1);
    }

    if (open_file_count >Proc_Info[5]) {
        for (int iproc=Proc_Info[4]; iproc <Proc_Info[4]+Proc_Info[5]; iproc++) {
            /* Close the parallel exodus II file */
            if (ex_close(par_exoid[iproc]) == -1) {
                fprintf(stderr, "[%d] %s Could not close the parallel Exodus II file.\n",
                        iproc, yo);
                exit(1);
            }
        }
    }
    if (par_exoid != NULL) {
        free(par_exoid);
        par_exoid = NULL;
    }
}
コード例 #3
0
bool Excn::ExodusFile::initialize(const SystemInterface& si)
{
  // See if we can keep files open 
  size_t max_files = get_free_descriptor_count();
  if (si.inputFiles_.size() <= max_files) {
    keepOpen_ = true;
    if (si.debug() & 1)
      std::cout << "Files kept open... (Max open = " << max_files << ")\n\n";
  } else {
    keepOpen_ = false;
    std::cout << "Single file mode... (Max open = " << max_files << ")\n"
	      << "Consider using the -subcycle option for faster execution...\n\n";
  }

  float version = 0.0;

  // create exo names
  filenames_.resize(si.inputFiles_.size());
  fileids_.resize(si.inputFiles_.size());
  
  int int_byte_size_api = 4;
  if (si.ints_64_bit())
    int_byte_size_api = 8;
  
  int overall_max_name_length = 0;
  for(size_t p = 0; p < si.inputFiles_.size(); p++) {
    std::string name = si.inputFiles_[p];

    filenames_[p] = name;

    if (p == 0) {
      int cpu_word_size  = sizeof(float);
      int io_wrd_size   = 0;
      int exoid = ex_open(filenames_[p].c_str(),
			  EX_READ, &cpu_word_size,
			  &io_wrd_size, &version);
      if (exoid < 0) {
	std::cerr << "Cannot open file '" << filenames_[p] << "'" << std::endl;
	return false;
      }

      int max_name_length = ex_inquire_int(exoid, EX_INQ_DB_MAX_USED_NAME_LENGTH);
      if (max_name_length > overall_max_name_length)
	overall_max_name_length = max_name_length;

      ex_close(exoid);

      if (io_wrd_size < (int)sizeof(float))
	io_wrd_size = sizeof(float);

      ioWordSize_ = io_wrd_size;
      cpuWordSize_ = io_wrd_size;

      if (ex_int64_status(exoid & EX_ALL_INT64_DB) || si.ints_64_bit()) {
	exodusMode_ = EX_ALL_INT64_API;
      }
    }

    if (keepOpen_ || p == 0) {
      int io_wrd_size   = 0;
      int mode = EX_READ | exodusMode_;

      fileids_[p] = ex_open(filenames_[p].c_str(),
			    mode, &cpuWordSize_,
			    &io_wrd_size, &version);
      if (fileids_[p] < 0) {
	std::cerr << "Cannot open file '" << filenames_[p] << "'" << std::endl;
	return false;
      }

      SMART_ASSERT(ioWordSize_ == io_wrd_size)(ioWordSize_)(io_wrd_size);
    }
    
    std::cout << "Part " << p+1 << ": '" << name.c_str() << "'" << std::endl;
  }

  maximumNameLength_ = overall_max_name_length;
  for(size_t p = 0; p < si.inputFiles_.size(); p++) {
    ex_set_max_name_length(fileids_[p], maximumNameLength_);
  }

  return true;
}