Commit 050c06de authored by Burlen Loring's avatar Burlen Loring Committed by Mario Melara

remove ArrayIO utility

parent 2b4a7d11
...@@ -63,7 +63,6 @@ include(mpi) ...@@ -63,7 +63,6 @@ include(mpi)
include(vtk) include(vtk)
include(timer) include(timer)
include(pugixml) include(pugixml)
include(ArrayIO)
include(timer) include(timer)
include(diy) include(diy)
include(grid) include(grid)
......
...@@ -8,7 +8,7 @@ if (ENABLE_SENSEI) ...@@ -8,7 +8,7 @@ if (ENABLE_SENSEI)
ProgrammableDataAdaptor.cxx VTKHistogram.cxx VTKDataAdaptor.cxx ProgrammableDataAdaptor.cxx VTKHistogram.cxx VTKDataAdaptor.cxx
VTKUtils.cxx) VTKUtils.cxx)
set(senseiCore_libs mpi pugixml vtk thread ArrayIO timer diy grid) set(senseiCore_libs mpi pugixml vtk thread timer diy grid)
if (ENABLE_CONDUIT) if (ENABLE_CONDUIT)
list(APPEND senseiCore_sources ConduitDataAdaptor.cxx) list(APPEND senseiCore_sources ConduitDataAdaptor.cxx)
......
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include <fstream> #include <fstream>
#include <cassert> #include <cassert>
#include <ArrayIO.h>
#if defined(ENABLE_VTK_IO) #if defined(ENABLE_VTK_IO)
#include <vtkAlgorithm.h> #include <vtkAlgorithm.h>
#include <vtkCompositeDataPipeline.h> #include <vtkCompositeDataPipeline.h>
......
#include "ArrayIO.h"
#include <sstream>
using std::ostringstream;
namespace arrayIO
{
// ****************************************************************************
int open(
MPI_Comm comm, // MPI communicator handle
const char *fileName, // file name to write.
MPI_Info hints, // MPI file hints
MPI_File &file) // file handle
{
int iErr = 0;
#ifndef NDEBUG
int mpiOk = 0;
MPI_Initialized(&mpiOk);
if (!mpiOk)
{
std::cerr << "This class requires the MPI runtime" << std::endl;
return -1;
}
#endif
const int eStrLen = 2048;
char eStr[eStrLen] = {'\0'};
// Open the file
if ((iErr = MPI_File_open(comm, const_cast<char *>(fileName),
MPI_MODE_WRONLY|MPI_MODE_CREATE, hints, &file)))
{
MPI_Error_string(iErr, eStr, const_cast<int *>(&eStrLen));
std::cerr << "Error opeing file: " << fileName << std::endl
<< eStr << std::endl;
return -1;
}
return 0;
}
// ****************************************************************************
MPI_Info createHints(
int useCollectiveIO,
int numberOfIONodes,
int collectBufferSize,
int useDirectIO,
int useDeferredOpen,
int useDataSieving,
int sieveBufferSize,
int stripeCount,
int stripeSize)
{
MPI_Info hints = MPI_INFO_NULL;
int mpiOk;
MPI_Initialized(&mpiOk);
if (!mpiOk)
{
std::cerr << "This class requires the MPI runtime" << std::endl;
return hints;
}
MPI_Info_create(&hints);
switch (useCollectiveIO)
{
case HINT_AUTOMATIC:
// do nothing, it's up to implementation.
break;
case HINT_DISABLED:
MPI_Info_set(hints,"romio_cb_write","disable");
break;
case HINT_ENABLED:
MPI_Info_set(hints,"romio_cb_write","enable");
break;
default:
std::cerr << "Invalid value for UseCollectiveIO." << std::endl;
break;
}
if (numberOfIONodes > 0)
{
std::ostringstream os;
os << numberOfIONodes;
MPI_Info_set(hints,"cb_nodes",const_cast<char *>(os.str().c_str()));
}
if (collectBufferSize > 0)
{
std::ostringstream os;
os << collectBufferSize;
MPI_Info_set(hints,"cb_buffer_size",const_cast<char *>(os.str().c_str()));
//MPI_Info_set(hints,"striping_unit", const_cast<char *>(os.str().c_str()));
}
switch (useDirectIO)
{
case HINT_DEFAULT:
// do nothing, it's up to implementation.
break;
case HINT_DISABLED:
MPI_Info_set(hints,"direct_write","false");
break;
case HINT_ENABLED:
MPI_Info_set(hints,"direct_write","true");
break;
default:
std::cerr << "Invalid value for UseDirectIO." << std::endl;
break;
}
switch (useDeferredOpen)
{
case HINT_DEFAULT:
// do nothing, it's up to implementation.
break;
case HINT_DISABLED:
MPI_Info_set(hints,"romio_no_indep_rw","false");
break;
case HINT_ENABLED:
MPI_Info_set(hints,"romio_no_indep_rw","true");
break;
default:
std::cerr << "Invalid value for UseDeferredOpen." << std::endl;
break;
}
switch (useDataSieving)
{
case HINT_AUTOMATIC:
// do nothing, it's up to implementation.
break;
case HINT_DISABLED:
MPI_Info_set(hints,"romio_ds_write","disable");
break;
case HINT_ENABLED:
MPI_Info_set(hints,"romio_ds_write","enable");
break;
default:
std::cerr << "Invalid value for UseDataSieving." << std::endl;
break;
}
if (sieveBufferSize > 0)
{
std::ostringstream os;
os << sieveBufferSize;
MPI_Info_set(hints,"ind_rd_buffer_size", const_cast<char *>(os.str().c_str()));
}
if (stripeCount > 0)
{
std::ostringstream os;
os << stripeCount;
MPI_Info_set(hints,"striping_count", const_cast<char *>(os.str().c_str()));
}
if (stripeSize > 0)
{
std::ostringstream os;
os << stripeSize;
MPI_Info_set(hints,"striping_unit", const_cast<char *>(os.str().c_str()));
}
return hints;
}
}
#ifndef ArrayIO_h
#define ArrayIO_h
#include <iostream>
#include <mpi.h>
#define arrayIO_error(_arg) \
std::cerr << "ERROR: " << __FILE__ " : " << __LINE__ << std::endl \
<< "" _arg << std::endl;
namespace {
// *****************************************************************************
template <typename T>
size_t size(const T &ext)
{
size_t n = 1;
for (int i = 0; i < 3; ++i)
n *= ext[2*i+1] - ext[2*i] + 1;
return n;
}
// *****************************************************************************
template <typename T>
void size(const T &ext, int *n)
{
for (int i = 0; i < 3; ++i)
n[i] = ext[2*i+1] - ext[2*i] + 1;
}
// *****************************************************************************
template <typename T>
void start(const T &ext, int *id)
{
for (int i = 0; i < 3; ++i)
id[i] = ext[2*i];
}
// *****************************************************************************
template <typename T>
void offset(const T &dom, const T &subdom, int *id)
{
for (int i = 0; i < 3; ++i)
id[i] = dom[2*i] - subdom[2*i];
}
// *****************************************************************************
template <typename T>
bool equal(const T &l, const T &r)
{
for (int i = 0; i < 6; ++i)
{
if (l[i] != r[i])
return false;
}
return true;
}
// *****************************************************************************
template < typename T> struct mpi_tt;
template <> struct mpi_tt <float> { static MPI_Datatype Type(){ return MPI_FLOAT; } };
template <> struct mpi_tt <double> { static MPI_Datatype Type(){ return MPI_DOUBLE; } };
template <> struct mpi_tt <short int> { static MPI_Datatype Type(){ return MPI_SHORT; } };
template <> struct mpi_tt <unsigned short int> { static MPI_Datatype Type(){ return MPI_UNSIGNED_SHORT; } };
template <> struct mpi_tt <int> { static MPI_Datatype Type(){ return MPI_INT; } };
template <> struct mpi_tt <unsigned int> { static MPI_Datatype Type(){ return MPI_UNSIGNED; } };
template <> struct mpi_tt <long> { static MPI_Datatype Type(){ return MPI_LONG; } };
template <> struct mpi_tt <unsigned long> { static MPI_Datatype Type(){ return MPI_UNSIGNED_LONG; } };
template <> struct mpi_tt <long long> { static MPI_Datatype Type(){ return MPI_LONG_LONG; } };
template <> struct mpi_tt <unsigned long long> { static MPI_Datatype Type(){ return MPI_UNSIGNED_LONG_LONG; } };
template <> struct mpi_tt <signed char> { static MPI_Datatype Type(){ return MPI_CHAR; } };
template <> struct mpi_tt <char> { static MPI_Datatype Type(){ return MPI_CHAR; } };
template <> struct mpi_tt <unsigned char> { static MPI_Datatype Type(){ return MPI_UNSIGNED_CHAR; } };
}
namespace arrayIO
{
// ****************************************************************************
int open(
MPI_Comm comm, // MPI communicator handle
const char *fileName, // file name to open
MPI_Info hints, // MPI file hints
MPI_File &file); // file handle
// ****************************************************************************
inline
int close(MPI_File file)
{
MPI_File_close(&file);
return 0;
}
// ****************************************************************************
template < typename T>
int write(
MPI_File file, // File to write to.
MPI_Info hints, // MPI file hints
int domain[6], // entire region, dataset extents
int decomp[6], // local memory region, block extents with ghost zones
int valid[6], // region to write to disk
T *data) // pointer to a buffer to write to disk.
{
int iErr = 0;
// calculate block offsets and lengths
int domainDims[3];
::size(domain, domainDims);
int decompDims[3];
::size(decomp, decompDims);
int validDims[3];
::size(valid, validDims);
int validStart[3];
::start(valid, validStart);
int validOffset[3];
::offset(decomp, valid, validOffset);
// file view
MPI_Datatype nativeType = ::mpi_tt<T>::Type();
MPI_Datatype fileView;
if (MPI_Type_create_subarray(3, domainDims,
validDims, validStart, MPI_ORDER_FORTRAN,
nativeType, &fileView))
{
arrayIO_error(<< "MPI_Type_create_subarray failed.")
return -1;
}
if (MPI_Type_commit(&fileView))
{
arrayIO_error(<< "MPI_Type_commit failed.")
return -1;
}
if (MPI_File_set_view(file, 0,
nativeType, fileView, "native", hints))
{
arrayIO_error(<< "MPI_File_set_view failed.")
return -1;
}
// memory view
MPI_Datatype memView;
if (MPI_Type_create_subarray(3, decompDims,
validDims, validOffset, MPI_ORDER_FORTRAN,
nativeType, &memView))
{
arrayIO_error(<< "MPI_Type_create_subarray failed.")
return -1;
}
if (MPI_Type_commit(&memView))
{
arrayIO_error(<< "MPI_Type_commit failed.")
return -1;
}
// write
const int eStrLen = 2048;
char eStr[eStrLen] = {'\0'};
MPI_Status status;
if ((iErr = MPI_File_write(file, data, 1, memView, &status)))
{
MPI_Error_string(iErr, eStr, const_cast<int *>(&eStrLen));
arrayIO_error(<< "write error: " << eStr)
return -1;
}
MPI_Type_free(&fileView);
MPI_Type_free(&memView);
return 0;
}
// ****************************************************************************
template < typename T>
int write_all(
MPI_File file, // File to write to.
MPI_Info hints, // MPI file hints
int domain[6], // entire region, dataset extents
int decomp[6], // local memory region, block extents with ghost zones
int valid[6], // region to write to disk
T *data) // pointer to a buffer to write to disk.
{
int iErr = 0;
// calculate block offsets and lengths
int domainDims[3];
size(domain, domainDims);
int decompDims[3];
size(decomp, decompDims);
int validDims[3];
size(valid, validDims);
int validStart[3];
start(valid, validStart);
int validOffset[3];
offset(decomp, valid, validOffset);
// file view
MPI_Datatype nativeType = ::mpi_tt<T>::Type();
MPI_Datatype fileView;
if (MPI_Type_create_subarray(3, domainDims,
validDims, validStart, MPI_ORDER_FORTRAN,
nativeType, &fileView))
{
arrayIO_error(<< "MPI_Type_create_subarray failed.")
return -1;
}
if (MPI_Type_commit(&fileView))
{
arrayIO_error(<< "MPI_Type_commit failed.")
return -1;
}
if (MPI_File_set_view(file, 0,
nativeType, fileView, "native", hints))
{
arrayIO_error(<< "MPI_File_set_view failed.")
return -1;
}
// memory view
MPI_Datatype memView;
if (MPI_Type_create_subarray(3, decompDims,
validDims, validOffset, MPI_ORDER_FORTRAN,
nativeType, &memView))
{
arrayIO_error(<< "MPI_Type_create_subarray failed.")
return -1;
}
if (MPI_Type_commit(&memView))
{
arrayIO_error(<< "MPI_Type_commit failed.")
return -1;
}
// write
const int eStrLen = 2048;
char eStr[eStrLen] = {'\0'};
MPI_Status status;
if ((iErr = MPI_File_write_all(file, data, 1, memView, &status)))
{
MPI_Error_string(iErr, eStr, const_cast<int *>(&eStrLen));
arrayIO_error(<< "write error : " << eStr)
return -1;
}
MPI_Type_free(&fileView);
MPI_Type_free(&memView);
return iErr ? -1 : 0;
}
// ****************************************************************************
enum
{
HINT_DEFAULT = 0,
HINT_AUTOMATIC = 0,
HINT_DISABLED = 1,
HINT_ENABLED = 2
};
// ****************************************************************************
MPI_Info createHints(
int useCollectiveIO = HINT_ENABLED,
int numberOfIONodes = -1,
int collectiveBufferSize = -1,
int useDirectIO = HINT_AUTOMATIC,
int useDefferedOpen = HINT_AUTOMATIC,
int useDataSeive = HINT_AUTOMATIC,
int sieveBufferSize = -1,
int stripeCount = -1,
int stripeSize = -1);
};
#endif
add_library(ArrayIO STATIC ArrayIO.cxx)
target_link_libraries(ArrayIO mpi)
target_include_directories(ArrayIO
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include/ArrayIO>)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/"
DESTINATION include/ArrayIO FILES_MATCHING PATTERN "*.h")
install(TARGETS ArrayIO EXPORT ArrayIO INCLUDES DESTINATION
include/ArrayIO ARCHIVE DESTINATION lib LIBRARY DESTINATION lib)
install(EXPORT ArrayIO DESTINATION lib/cmake
EXPORT_LINK_INTERFACE_LIBRARIES)
%define MDOC
"Mesh and particle I/O using MPI-I/O with collective buffering
int writeArray(
const char *fileName,
int domain[6],
int decomp[6],
PyArrayObject *adata)
"
%enddef
%module (docstring=MDOC) WarpIVArrayIO
%{
#define SWIG_FILE_WITH_INIT
#include <stdio.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API_arrayIO
#include <numpy/arrayobject.h>
#include "WarpIVArrayIO.h"
#include "WarpIVGlue.h"
static
int asIntArray(PyObject *obj, int len, int *array)
{
if (!PySequence_Check(obj) || !(PySequence_Size(obj) == len))
return -1;
for (int i = 0; i < len; ++i)
array[i] = PyInt_AsLong(PySequence_GetItem(obj, i));
return 0;
}
%}
%init %{
import_array();
%}
%include "WarpIVTypemaps.i"
%inline %{
// **************************************************************************
int writeArray(
const char *fileName,
PyObject *aDomain,
PyObject *aDecomp,
PyObject *aValid,
PyArrayObject *adata)
{
// create the hints using the defaults
MPI_Info hints = createWriterHints();
int domain[6] = {0};
if (asIntArray(aDomain, 6, domain))
{
PyErr_Format(PyExc_TypeError, "aDomain is not a 6 element sequence");
return -1;
}
int decomp[6] = {0};
if (asIntArray(aDecomp, 6, decomp))
{
PyErr_Format(PyExc_TypeError, "aDecomp is not a 6 element sequence");
return -1;
}
int valid[6] = {0};
if (asIntArray(aValid, 6, valid))
{
PyErr_Format(PyExc_TypeError, "aValid is not a 6 element sequence");
return -1;
}
// dispatch based on data type
switch (getType(adata))
{
numpyDispatch(
// get a pointer to the numpy array
CPP_TT::Type *data = NULL;
if (getCPointer(adata, data))
{
PyErr_Format(PyExc_ValueError,
"failed to get pointer to array");
return -1;
}
return writeArray<CPP_TT::Type>(fileName,
MPI_COMM_WORLD, hints, domain, decomp, valid, data);
)
default:
PyErr_Format(PyExc_ValueError, "failed dispatch unsupported type");
return -1;
}
return -1;
}
%}
...@@ -24,5 +24,4 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/opts" ...@@ -24,5 +24,4 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/opts"
add_subdirectory(pugixml) add_subdirectory(pugixml)
add_subdirectory(timer) add_subdirectory(timer)
add_subdirectory(ArrayIO)
#add_subdirectory(ImageTester) #add_subdirectory(ImageTester)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment