Add command line option to select pre split files at runtime.

This commit is contained in:
Gunther H. Weber 2020-10-01 11:45:19 -07:00
parent 9dda1cc661
commit 8b00e8ec48
2 changed files with 449 additions and 445 deletions

@ -99,10 +99,7 @@ VTKM_THIRDPARTY_POST_INCLUDE
#include <utility> #include <utility>
#include <vector> #include <vector>
#define SINGLE_FILE_STDOUT_STDERR
#define PRESPLIT_FILE
namespace ctaug_ns = vtkm::worklet::contourtree_augmented;
// Simple helper class for parsing the command line options // Simple helper class for parsing the command line options
class ParseCL class ParseCL
@ -234,6 +231,11 @@ int main(int argc, char* argv[])
{ {
useMarchingCubes = true; useMarchingCubes = true;
} }
bool preSplitFiles = false;
if (parser.hasOption("--preSplitFiles"))
{
preSplitFiles = true;
}
bool saveDotFiles = false; bool saveDotFiles = false;
if (parser.hasOption("--saveDot")) if (parser.hasOption("--saveDot"))
{ {
@ -297,19 +299,16 @@ int main(int argc, char* argv[])
<< std::endl; << std::endl;
std::cout << "Options: (Bool options are give via int, i.e. =0 for False and =1 for True)" std::cout << "Options: (Bool options are give via int, i.e. =0 for False and =1 for True)"
<< std::endl; << std::endl;
std::cout std::cout << "--mc Use marching cubes connectivity (Default=False)." << std::endl;
<< "--mc Use marching cubes interpolation for contour tree calculation. " std::cout << "--preSplitFiles Input data is already pre-split into blocks." << std::endl;
"(Default=False)" std::cout << "--saveDot Save DOT files of the distributed contour tree "
<< std::endl; << "computation (Default=False). " << std::endl;
std::cout << "--saveDot Save dot files of the distributed contour tree computations."
<< std::endl;
#ifdef ENABLE_SET_NUM_THREADS #ifdef ENABLE_SET_NUM_THREADS
std::cout std::cout << "--numThreads Specifiy the number of threads to use. "
<< "--numThreads Specifiy the number of threads to use. Available only with TBB." << "Available only with TBB." << std::endl;
<< std::endl;
#endif #endif
std::cout << "--numBlocks Number of blocks to load. (Default=number of MPI ranks.)" std::cout << "--numBlocks Number of blocks to use during computation "
<< std::endl; << "(Default=number of MPI ranks.)" << std::endl;
std::cout << std::endl; std::cout << std::endl;
} }
MPI_Finalize(); MPI_Finalize();
@ -322,8 +321,10 @@ int main(int argc, char* argv[])
std::endl std::endl
<< " ------------ Settings -----------" << std::endl << " ------------ Settings -----------" << std::endl
<< " filename=" << filename << std::endl << " filename=" << filename << std::endl
<< " preSplitFiles=" << preSplitFiles << std::endl
<< " device=" << device.GetName() << std::endl << " device=" << device.GetName() << std::endl
<< " mc=" << useMarchingCubes << std::endl << " mc=" << useMarchingCubes << std::endl
<< " saveDot=" << saveDotFiles << std::endl
#ifdef ENABLE_SET_NUM_THREADS #ifdef ENABLE_SET_NUM_THREADS
<< " numThreads=" << numThreads << std::endl << " numThreads=" << numThreads << std::endl
#endif #endif
@ -345,7 +346,7 @@ int main(int argc, char* argv[])
return 255; return 255;
} }
/* #ifndef SINGLE_FILE_STDOUT_STDERR
std::snprintf(cstr_filename, sizeof(cstr_filename), "cerr_%d.log", rank); std::snprintf(cstr_filename, sizeof(cstr_filename), "cerr_%d.log", rank);
int err = open(cstr_filename, O_RDWR | O_CREAT | O_APPEND, 0600); int err = open(cstr_filename, O_RDWR | O_CREAT | O_APPEND, 0600);
if (-1 == err) if (-1 == err)
@ -353,7 +354,7 @@ int main(int argc, char* argv[])
perror("opening cerr.log"); perror("opening cerr.log");
return 255; return 255;
} }
*/ #endif
int save_out = dup(fileno(stdout)); int save_out = dup(fileno(stdout));
int save_err = dup(fileno(stderr)); int save_err = dup(fileno(stderr));
@ -363,8 +364,11 @@ int main(int argc, char* argv[])
perror("cannot redirect stdout"); perror("cannot redirect stdout");
return 255; return 255;
} }
//if (-1 == dup2(err, fileno(stderr))) #ifdef SINGLE_FILE_STDOUT_STDERR
if (-1 == dup2(out, fileno(stderr))) if (-1 == dup2(out, fileno(stderr)))
#else
if (-1 == dup2(err, fileno(stderr)))
#endif
{ {
perror("cannot redirect stderr"); perror("cannot redirect stderr");
return 255; return 255;
@ -379,7 +383,6 @@ int main(int argc, char* argv[])
vtkm::Float64 buildDatasetTime = 0; vtkm::Float64 buildDatasetTime = 0;
std::vector<vtkm::Float32>::size_type nDims = 0; std::vector<vtkm::Float32>::size_type nDims = 0;
#ifdef PRESPLIT_FILE
// Multi-block dataset for multi-block DIY-paralle processing // Multi-block dataset for multi-block DIY-paralle processing
vtkm::cont::PartitionedDataSet useDataSet; vtkm::cont::PartitionedDataSet useDataSet;
@ -396,6 +399,8 @@ int main(int argc, char* argv[])
auto localBlockOriginsPortal = localBlockOrigins.WritePortal(); auto localBlockOriginsPortal = localBlockOrigins.WritePortal();
auto localBlockSizesPortal = localBlockSizes.WritePortal(); auto localBlockSizesPortal = localBlockSizes.WritePortal();
if (preSplitFiles)
{
for (int blockNo = 0; blockNo < blocksPerRank; ++blockNo) for (int blockNo = 0; blockNo < blocksPerRank; ++blockNo)
{ {
// Translate pattern into filename for this block // Translate pattern into filename for this block
@ -592,7 +597,8 @@ int main(int argc, char* argv[])
// and add to partition // and add to partition
useDataSet.AppendPartition(ds); useDataSet.AppendPartition(ds);
localBlockIndicesPortal.Set(blockNo, localBlockIndicesPortal.Set(
blockNo,
vtkm::Id3{ static_cast<vtkm::Id>(blockIndex[0]), vtkm::Id3{ static_cast<vtkm::Id>(blockIndex[0]),
static_cast<vtkm::Id>(blockIndex[1]), static_cast<vtkm::Id>(blockIndex[1]),
static_cast<vtkm::Id>(nDims == 3 ? blockIndex[2] : 0) }); static_cast<vtkm::Id>(nDims == 3 ? blockIndex[2] : 0) });
@ -650,9 +656,11 @@ int main(int argc, char* argv[])
<< " ---------------- Input Mesh Properties --------------" << std::endl << " ---------------- Input Mesh Properties --------------" << std::endl
<< " Number of dimensions: " << nDims << std::endl); << " Number of dimensions: " << nDims << std::endl);
} }
}
#else else
{
vtkm::cont::DataSet inDataSet; vtkm::cont::DataSet inDataSet;
using ValueType = vtkm::FloatDefault;
std::vector<ValueType> values; std::vector<ValueType> values;
std::vector<vtkm::Id> dims; std::vector<vtkm::Id> dims;
@ -668,12 +676,12 @@ int main(int argc, char* argv[])
// Copy the data into the values array so we can construct a multiblock dataset // Copy the data into the values array so we can construct a multiblock dataset
// TODO All we should need to do to implement BOV support is to copy the values // TODO All we should need to do to implement BOV support is to copy the values
// in the values vector and copy the dimensions in the dims vector // in the values vector and copy the dimensions in the dims vector
vtkm::Id nRows, nCols, nSlices; vtkm::Id3 pointDimensions;
vtkm::worklet::contourtree_augmented::GetRowsColsSlices temp; vtkm::worklet::contourtree_augmented::GetPointDimensions temp;
temp(inDataSet.GetCellSet(), nRows, nCols, nSlices); temp(inDataSet.GetCellSet(), pointDimensions);
dims[0] = nRows; dims[0] = pointDimensions[0];
dims[1] = nCols; dims[1] = pointDimensions[1];
dims[2] = nSlices; dims[2] = pointDimensions[2];
auto tempField = inDataSet.GetField("values").GetData(); auto tempField = inDataSet.GetField("values").GetData();
values.resize(static_cast<std::size_t>(tempField.GetNumberOfValues())); values.resize(static_cast<std::size_t>(tempField.GetNumberOfValues()));
auto tempFieldHandle = tempField.AsVirtual<ValueType>().ReadPortal(); auto tempFieldHandle = tempField.AsVirtual<ValueType>().ReadPortal();
@ -702,6 +710,9 @@ int main(int argc, char* argv[])
{ {
dims.push_back(dimVertices); dims.push_back(dimVertices);
} }
// Swap dimensions so that they are from fastest to slowest growing
// dims[0] -> col; dims[1] -> row, dims[2] ->slice
std::swap(dims[0], dims[1]);
// Compute the number of vertices, i.e., xdim * ydim * zdim // Compute the number of vertices, i.e., xdim * ydim * zdim
nDims = static_cast<unsigned short>(dims.size()); nDims = static_cast<unsigned short>(dims.size());
@ -747,25 +758,15 @@ int main(int argc, char* argv[])
} }
// Create a multi-block dataset for multi-block DIY-paralle processing // Create a multi-block dataset for multi-block DIY-paralle processing
vtkm::cont::PartitionedDataSet useDataSet; // Partitioned variant of the input dataset blocksPerDim = nDims == 3 ? vtkm::Id3(1, 1, numBlocks)
vtkm::Id3 blocksPerDim = : vtkm::Id3(1, numBlocks, 1); // Decompose the data into
nDims == 3 ? vtkm::Id3(1, 1, numBlocks) : vtkm::Id3(1, numBlocks, 1); // Decompose the data into globalSize = nDims == 3 ? vtkm::Id3(static_cast<vtkm::Id>(dims[0]),
vtkm::Id3 globalSize = nDims == 3 ? vtkm::Id3(static_cast<vtkm::Id>(dims[0]),
static_cast<vtkm::Id>(dims[1]), static_cast<vtkm::Id>(dims[1]),
static_cast<vtkm::Id>(dims[2])) static_cast<vtkm::Id>(dims[2]))
: vtkm::Id3(static_cast<vtkm::Id>(dims[0]), : vtkm::Id3(static_cast<vtkm::Id>(dims[0]),
static_cast<vtkm::Id>(dims[1]), static_cast<vtkm::Id>(dims[1]),
static_cast<vtkm::Id>(0)); static_cast<vtkm::Id>(1));
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockIndices; std::cout << blocksPerDim << " " << globalSize << std::endl;
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockOrigins;
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockSizes;
localBlockIndices.Allocate(blocksPerRank);
localBlockOrigins.Allocate(blocksPerRank);
localBlockSizes.Allocate(blocksPerRank);
auto localBlockIndicesPortal = localBlockIndices.WritePortal();
auto localBlockOriginsPortal = localBlockOrigins.WritePortal();
auto localBlockSizesPortal = localBlockSizes.WritePortal();
{ {
vtkm::Id lastDimSize = vtkm::Id lastDimSize =
(nDims == 2) ? static_cast<vtkm::Id>(dims[1]) : static_cast<vtkm::Id>(dims[2]); (nDims == 2) ? static_cast<vtkm::Id>(dims[1]) : static_cast<vtkm::Id>(dims[2]);
@ -808,17 +809,17 @@ int main(int argc, char* argv[])
if (nDims == 2) if (nDims == 2)
{ {
vtkm::Id2 vdims; vtkm::Id2 vdims;
vdims[0] = static_cast<vtkm::Id>(currBlockSize); vdims[0] = static_cast<vtkm::Id>(dims[0]);
vdims[1] = static_cast<vtkm::Id>(dims[0]); vdims[1] = static_cast<vtkm::Id>(currBlockSize);
vtkm::Vec<ValueType, 2> origin(0, blockIndex * blockSize); vtkm::Vec<ValueType, 2> origin(0, blockIndex * blockSize);
vtkm::Vec<ValueType, 2> spacing(1, 1); vtkm::Vec<ValueType, 2> spacing(1, 1);
ds = dsb.Create(vdims, origin, spacing); ds = dsb.Create(vdims, origin, spacing);
localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(blockIndex, 0, 0)); localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(0, blockIndex, 0));
localBlockOriginsPortal.Set(localBlockIndex, localBlockOriginsPortal.Set(localBlockIndex,
vtkm::Id3((blockStart / blockSliceSize), 0, 0)); vtkm::Id3(0, (blockStart / blockSliceSize), 0));
localBlockSizesPortal.Set(localBlockIndex, localBlockSizesPortal.Set(localBlockIndex,
vtkm::Id3(currBlockSize, static_cast<vtkm::Id>(dims[0]), 0)); vtkm::Id3(static_cast<vtkm::Id>(dims[0]), currBlockSize, 0));
} }
// 3D data // 3D data
else else
@ -834,9 +835,10 @@ int main(int argc, char* argv[])
localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(0, 0, blockIndex)); localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(0, 0, blockIndex));
localBlockOriginsPortal.Set(localBlockIndex, localBlockOriginsPortal.Set(localBlockIndex,
vtkm::Id3(0, 0, (blockStart / blockSliceSize))); vtkm::Id3(0, 0, (blockStart / blockSliceSize)));
localBlockSizesPortal.Set( localBlockSizesPortal.Set(localBlockIndex,
localBlockIndex, vtkm::Id3(static_cast<vtkm::Id>(dims[0]),
vtkm::Id3(static_cast<vtkm::Id>(dims[0]), static_cast<vtkm::Id>(dims[1]), currBlockSize)); static_cast<vtkm::Id>(dims[1]),
currBlockSize));
} }
std::vector<vtkm::Float32> subValues((values.begin() + blockStart), std::vector<vtkm::Float32> subValues((values.begin() + blockStart),
@ -846,7 +848,8 @@ int main(int argc, char* argv[])
useDataSet.AppendPartition(ds); useDataSet.AppendPartition(ds);
} }
} }
#endif }
// Check if marching cubes is enabled for non 3D data // Check if marching cubes is enabled for non 3D data
bool invalidMCOption = (useMarchingCubes && nDims != 3); bool invalidMCOption = (useMarchingCubes && nDims != 3);
VTKM_LOG_IF_S(vtkm::cont::LogLevel::Error, VTKM_LOG_IF_S(vtkm::cont::LogLevel::Error,
@ -911,11 +914,12 @@ int main(int argc, char* argv[])
vtkm::Float64 computeContourTreeTime = currTime - prevTime; vtkm::Float64 computeContourTreeTime = currTime - prevTime;
prevTime = currTime; prevTime = currTime;
//std::cout << std::flush; close(out);
//std::cerr << std::flush; close(err);
std::cout << std::flush; std::cout << std::flush;
std::cerr << std::flush; std::cerr << std::flush;
close(out); close(out);
#ifndef SINGLE_FILE_STDOUT_STDERR
close(err);
#endif
dup2(save_out, fileno(stdout)); dup2(save_out, fileno(stdout));
dup2(save_err, fileno(stderr)); dup2(save_err, fileno(stderr));

@ -25,7 +25,7 @@ rm ${filename}
echo "Running HACT" echo "Running HACT"
n_parts=$(($2*$2)) n_parts=$(($2*$2))
echo mpirun -np 4 ./ContourTree_Distributed -d Any --numBlocks=${n_parts} ${fileroot}_part_%d_of_${n_parts}.txt echo mpirun -np 4 ./ContourTree_Distributed -d Any --numBlocks=${n_parts} ${fileroot}_part_%d_of_${n_parts}.txt
mpirun -np 4 ./ContourTree_Distributed -d Any --numBlocks=${n_parts} ${fileroot}_part_%d_of_${n_parts}.txt mpirun -np 4 ./ContourTree_Distributed -d Any --preSplitFiles=1 --numBlocks=${n_parts} ${fileroot}_part_%d_of_${n_parts}.txt
rm ${fileroot}_part_*_of_${n_parts}.txt rm ${fileroot}_part_*_of_${n_parts}.txt
echo "Compiling Outputs" echo "Compiling Outputs"