Skip to content

Commit

Permalink
CMAKE: add check for ZFP_CUDA
Browse files Browse the repository at this point in the history
  • Loading branch information
vicentebolea committed Oct 29, 2021
1 parent 35c3f19 commit a75d822
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 64 deletions.
24 changes: 24 additions & 0 deletions cmake/DetectOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,30 @@ elseif(ADIOS2_USE_ZFP)
endif()
if(ZFP_FOUND)
set(ADIOS2_HAVE_ZFP TRUE)
set(ADIOS2_HAVE_ZFP_CUDA ${ZFP_CUDA})

# Older versions of ZFP
if(NOT ADIOS2_HAVE_ZFP_CUDA)
get_target_property(ZFP_INCLUDE_DIRECTORIES zfp::zfp INTERFACE_INCLUDE_DIRECTORIES)
set(CMAKE_REQUIRED_INCLUDES ${ZFP_INCLUDE_DIRECTORIES})
set(CMAKE_REQUIRED_LIBRARIES zfp::zfp)
include(CheckCSourceRuns)
check_c_source_runs("
#include <zfp.h>
int main()
{
zfp_stream* stream = zfp_stream_open(NULL);
return !zfp_stream_set_execution(stream, zfp_exec_cuda);
}"
ADIOS2_HAVE_ZFP_CUDA)
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)
endif()

if(ADIOS2_HAVE_ZFP_CUDA)
add_compile_definitions(ADIOS2_HAVE_ZFP_CUDA)
endif()
endif()

# SZ
Expand Down
2 changes: 2 additions & 0 deletions source/adios2/common/ADIOSTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,9 @@ constexpr char precision[] = "precision";

namespace value
{
#ifdef ADIOS2_HAVE_ZFP_CUDA
constexpr char backend_cuda[] = "cuda";
#endif
constexpr char backend_omp[] = "omp";
constexpr char backend_serial[] = "serial";
}
Expand Down
129 changes: 92 additions & 37 deletions source/adios2/operator/compress/CompressZFP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@
#include "CompressZFP.h"
#include "adios2/helper/adiosFunctions.h"
#include <sstream>
#include <zfp.h>

/* CMake will make sure zfp >= 5.0.1 */
#if ZFP_VERSION_RELEASE > 1 && !defined(ZFP_DEFAULT_EXECUTION_POLICY)

/* ZFP will default to SERIAL if CUDA is not available */
#ifndef ZFP_DEFAULT_EXECUTION_POLICY
#ifdef ADIOS2_HAVE_ZFP_CUDA
#define ZFP_DEFAULT_EXECUTION_POLICY zfp_exec_cuda
#else
#define ZFP_DEFAULT_EXECUTION_POLICY zfp_exec_serial
#endif

#endif

namespace adios2
Expand All @@ -23,6 +31,27 @@ namespace core
namespace compress
{

/**
* Constructor Zfp zfp_field based on input information around the data
* pointer
* @param data
* @param shape
* @param type
* @return zfp_field*
*/
zfp_field *GetZFPField(const char *data, const Dims &shape, DataType type);

/**
* Returns Zfp supported zfp_type based on adios string type
* @param type adios type as string, see GetDataType<T> in
* helper/adiosType.inl
* @return zfp_type
*/
zfp_type GetZfpType(DataType type);

zfp_stream *GetZFPStream(const Dims &dimensions, DataType type,
const Params &parameters);

CompressZFP::CompressZFP(const Params &parameters) : Operator("zfp", parameters)
{
}
Expand Down Expand Up @@ -55,32 +84,43 @@ size_t CompressZFP::Operate(const char *dataIn, const Dims &blockStart,
PutParameter(bufferOut, bufferOutOffset,
static_cast<uint8_t>(ZFP_VERSION_MINOR));
PutParameter(bufferOut, bufferOutOffset,
static_cast<uint8_t>(ZFP_VERSION_PATCH));
static_cast<uint8_t>(ZFP_VERSION_RELEASE));
PutParameters(bufferOut, bufferOutOffset, parameters);
// zfp V1 metadata end

Dims convertedDims = ConvertDims(blockCount, type, 3);
zfp_field *field = GetZFPField(dataIn, convertedDims, type);
zfp_stream *stream = GetZFPStream(convertedDims, type, parameters);
size_t maxSize = zfp_stream_maximum_size(stream, field);
// associate bitstream
bitstream *bitstream = stream_open(bufferOut + bufferOutOffset, maxSize);
zfp_stream_set_bit_stream(stream, bitstream);
zfp_stream_rewind(stream);

size_t sizeOut = zfp_compress(stream, field);
try
{
zfp_field *field = GetZFPField(dataIn, convertedDims, type);
zfp_stream *stream = GetZFPStream(convertedDims, type, parameters);

size_t maxSize = zfp_stream_maximum_size(stream, field);
// associate bitstream
bitstream *bitstream =
stream_open(bufferOut + bufferOutOffset, maxSize);
zfp_stream_set_bit_stream(stream, bitstream);
zfp_stream_rewind(stream);

size_t sizeOut = zfp_compress(stream, field);

if (sizeOut == 0)
{
throw std::invalid_argument("ERROR: zfp failed, compressed buffer "
"size is 0, in call to Compress");
}

bufferOutOffset += sizeOut;

if (sizeOut == 0)
zfp_field_free(field);
zfp_stream_close(stream);
stream_close(bitstream);
}
catch (std::invalid_argument &e)
{
throw std::invalid_argument("ERROR: zfp failed, compressed buffer "
"size is 0, in call to Compress");
throw std::invalid_argument(e.what() + m_VersionInfo + "\n");
}

bufferOutOffset += sizeOut;

zfp_field_free(field);
zfp_stream_close(stream);
stream_close(bitstream);
return bufferOutOffset;
}

Expand Down Expand Up @@ -141,7 +181,7 @@ size_t CompressZFP::DecompressV1(const char *bufferIn, const size_t sizeIn,
blockCount[i] = GetParameter<size_t, size_t>(bufferIn, bufferInOffset);
}
const DataType type = GetParameter<DataType>(bufferIn, bufferInOffset);
m_VersionInfo =
this->m_VersionInfo =
" Data is compressed using ZFP Version " +
std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) + "." +
std::to_string(GetParameter<uint8_t>(bufferIn, bufferInOffset)) + "." +
Expand All @@ -151,8 +191,18 @@ size_t CompressZFP::DecompressV1(const char *bufferIn, const size_t sizeIn,

Dims convertedDims = ConvertDims(blockCount, type, 3);

zfp_field *field = GetZFPField(dataOut, convertedDims, type);
zfp_stream *stream = GetZFPStream(convertedDims, type, parameters);
zfp_field *field = nullptr;
zfp_stream *stream = nullptr;

try
{
field = GetZFPField(dataOut, convertedDims, type);
stream = GetZFPStream(convertedDims, type, parameters);
}
catch (std::invalid_argument &e)
{
throw std::invalid_argument(e.what() + m_VersionInfo + "\n");
}

// associate bitstream
bitstream *bitstream = stream_open(
Expand All @@ -176,7 +226,7 @@ size_t CompressZFP::DecompressV1(const char *bufferIn, const size_t sizeIn,
return helper::GetTotalSize(convertedDims, helper::GetDataTypeSize(type));
}

zfp_type CompressZFP::GetZfpType(DataType type) const
zfp_type GetZfpType(DataType type)
{
zfp_type zfpType = zfp_type_none;

Expand Down Expand Up @@ -217,8 +267,9 @@ zfp_type CompressZFP::GetZfpType(DataType type) const
return zfpType;
}

zfp_field *CompressZFP::GetZFPField(const char *data, const Dims &dimensions,
DataType type) const
// Free static functions

zfp_field *GetZFPField(const char *data, const Dims &dimensions, DataType type)
{
zfp_type zfpType = GetZfpType(type);
zfp_field *field = nullptr;
Expand All @@ -242,28 +293,25 @@ zfp_field *CompressZFP::GetZFPField(const char *data, const Dims &dimensions,
throw std::invalid_argument(
"ERROR: zfp_field* failed for data of type " + ToString(type) +
", only 1D, 2D and 3D dimensions are supported, from "
"class CompressZfp." +
m_VersionInfo + "\n");
"class CompressZfp.");
}

if (field == nullptr)
{
throw std::invalid_argument(
"ERROR: zfp_field_" + std::to_string(dimensions.size()) +
"d failed for data of type " + ToString(type) +
", data might be corrupted, from class CompressZfp." +
m_VersionInfo + "\n");
", data might be corrupted, from class CompressZfp.");
}

return field;
}

zfp_stream *CompressZFP::GetZFPStream(const Dims &dimensions, DataType type,
const Params &parameters) const
zfp_stream *GetZFPStream(const Dims &dimensions, DataType type,
const Params &parameters)
{
zfp_stream *stream = zfp_stream_open(NULL);
zfp_stream_set_execution(stream, ZFP_DEFAULT_EXECUTION_POLICY);
bool isSerial = ZFP_DEFAULT_EXECUTION_POLICY == zfp_exec_serial;
bool isSerial = true;

auto itAccuracy = parameters.find("accuracy");
const bool hasAccuracy = itAccuracy != parameters.end();
Expand All @@ -274,30 +322,37 @@ zfp_stream *CompressZFP::GetZFPStream(const Dims &dimensions, DataType type,
auto itPrecision = parameters.find("precision");
const bool hasPrecision = itPrecision != parameters.end();

#if ZFP_VERSION_RELEASE > 1
auto itBackend = parameters.find("backend");
const bool hasBackend = itBackend != parameters.end();

zfp_stream_set_execution(stream, ZFP_DEFAULT_EXECUTION_POLICY);
isSerial = ZFP_DEFAULT_EXECUTION_POLICY == zfp_exec_serial;

if (hasBackend)
{
auto policy = ZFP_DEFAULT_EXECUTION_POLICY;
const auto backend = itBackend->second;

if (backend == "cuda")
if (backend == "serial")
{
policy = zfp_exec_cuda;
policy = zfp_exec_serial;
isSerial = true;
}
else if (backend == "omp")
{
policy = zfp_exec_omp;
}
else if (backend == "serial")
#ifdef ADIOS2_HAVE_ZFP_CUDA
else if (backend == "cuda")
{
policy = zfp_exec_serial;
isSerial = true;
policy = zfp_exec_cuda;
}
#endif

zfp_stream_set_execution(stream, policy);
}
#endif

if ((hasAccuracy && hasPrecision) || (hasAccuracy && hasRate) ||
(hasPrecision && hasRate) ||
Expand Down
26 changes: 0 additions & 26 deletions source/adios2/operator/compress/CompressZFP.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
#ifndef ADIOS2_TRANSFORM_COMPRESS_COMPRESSZFP_H_
#define ADIOS2_TRANSFORM_COMPRESS_COMPRESSZFP_H_

extern "C" {
#include <zfp.h>
}

#include "adios2/core/Operator.h"

namespace adios2
Expand Down Expand Up @@ -61,28 +57,6 @@ class CompressZFP : public Operator
bool IsDataTypeValid(const DataType type) const final;

private:
/**
* Returns Zfp supported zfp_type based on adios string type
* @param type adios type as string, see GetDataType<T> in
* helper/adiosType.inl
* @return zfp_type
*/
zfp_type GetZfpType(DataType type) const;

/**
* Constructor Zfp zfp_field based on input information around the data
* pointer
* @param data
* @param shape
* @param type
* @return zfp_field*
*/
zfp_field *GetZFPField(const char *data, const Dims &shape,
DataType type) const;

zfp_stream *GetZFPStream(const Dims &dimensions, DataType type,
const Params &parameters) const;

/**
* Decompress function for V1 buffer. Do NOT remove even if the buffer
* version is updated. Data might be still in lagacy formats. This function
Expand Down
2 changes: 1 addition & 1 deletion testing/adios2/engine/bp/operations/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ if(ADIOS2_HAVE_ZFP)
)
endforeach()

if(ADIOS2_HAVE_CUDA)
if(ADIOS2_HAVE_CUDA AND ADIOS2_HAVE_ZFP_CUDA)
enable_language(CUDA)

gtest_add_tests_helper(WriteReadZfpCuda MPI_ALLOW BP Engine.BP. .BP4
Expand Down

0 comments on commit a75d822

Please sign in to comment.