Skip to content
Snippets Groups Projects
Engine.h 14.9 KiB
Newer Older
/*
 * Capsule.h
 *
 *  Created on: Nov 7, 2016
 *      Author: wfg
 */

#ifndef ENGINE_H_
#define ENGINE_H_


/// \cond EXCLUDE_FROM_DOXYGEN
#include <vector>
#include <string>
#include <memory> //std::shared_ptr
#include <map>
#include <utility> //std::pair
#include <complex> //std::complex
/// \endcond

#ifdef HAVE_MPI
  #include <mpi.h>
#else
  #include "mpidummy.h"
#endif

wfg's avatar
wfg committed
#include "ADIOS.h"
#include "core/Method.h"
#include "core/Variable.h"
#include "core/VariableCompound.h"
#include "core/Transform.h"
#include "core/Transport.h"
#include "core/Capsule.h"


namespace adios
{

typedef enum { NONBLOCKINGREAD = 0, BLOCKINGREAD = 1 } PerformReadMode;


typedef enum {
    APPEND = 0, UPDATE = 1,                    // writer advance modes
    NEXT_AVAILABLE = 2, LATEST_AVAILABLE = 3,  // reader advance modes
} AdvanceMode;

/**
 * Base class for Engine operations managing shared-memory, and buffer and variables transform and transport operations
 */
class Engine
{

public:

    /**
wfg's avatar
wfg committed
     * Unique constructor
wfg's avatar
wfg committed
     * @param engineType
     * @param name
     * @param accessMode
     * @param mpiComm
wfg's avatar
wfg committed
     * @param method
wfg's avatar
wfg committed
     * @param debugMode
     * @param cores
     * @param endMessage
wfg's avatar
wfg committed
    Engine( ADIOS& adios, const std::string engineType, const std::string name, const std::string accessMode,
            MPI_Comm mpiComm, const Method& method, const bool debugMode, const unsigned int cores,
            const std::string endMessage );

    virtual ~Engine( );

    /** @brief Let ADIOS allocate memory for a variable, which can be used by the user.
     *
     * To decrease the cost of copying memory, a user may let ADIOS allocate the memory for a user-variable,
     * according to the definition of an ADIOS-variable. The memory will be part of the ADIOS buffer used
     * by the engine and it lives until the engine (file, stream) is closed.
     * A variable that has been allocated this way (cannot have its local dimensions changed, and AdvanceAsync() should be
     * used instead of Advance() and the user-variable must not be modified by the application until the notification arrives.
     * This is required so that any reader can access the written data before the application overwrites it.
     * @param var Variable with defined local dimensions and offsets in global space
     * @param fillValue Fill the allocated array with this value
     * @return A constant pointer to the non-constant allocated array. User should not deallocate this pointer.
     */
    template<class T> inline
    T * const AllocateVariable( Variable<T>& var, T fillValue = 0 )
    {
        throw std::invalid_argument( "ERROR: type not supported for variable " + var->name + " in call to GetVariable\n" );
    }

    /*
     * Needed for DataMan Engine
     * @param callback
     */
    //virtual void SetCallBack( std::function<void( const void*, std::string, std::string, std::string, Dims )> callback );
    /**
     * Write function that adds static checking on the variable to be passed by values
     * It then calls its corresponding derived class virtual function
     * This version uses m_Group to look for the variableName.
     * @param variable name of variable to the written
     * @param values pointer passed from the application
     */
wfg's avatar
wfg committed
    void Write( Variable<T>& variable, const T* values )
wfg's avatar
wfg committed
        Write( variable, values );
    /**
     * String version
     * @param variableName
     * @param values
     */
    template< class T >
    void Write( const std::string variableName, const T* values )
    {
        Write( variableName, values );
    }

    /**
     * Single value version
     * @param variable
     * @param values
     */
    template< class T >
    void Write( Variable<T>& variable, const T& values )
    {
        Write( variable, &values );
    }

    /**
     * Single value version using string as variable handlers
     * @param variableName
     * @param values
     */
    template< class T >
    void Write( const std::string variableName, const T& values )
    {
        Write( variableName, &values );
    }

    virtual void Write( Variable<char>& variable,                      const char* values );
    virtual void Write( Variable<unsigned char>& variable,             const unsigned char* values );
    virtual void Write( Variable<short>& variable,                     const short* values );
    virtual void Write( Variable<unsigned short>& variable,            const unsigned short* values );
    virtual void Write( Variable<int>& variable,                       const int* values );
    virtual void Write( Variable<unsigned int>& variable,              const unsigned int* values );
    virtual void Write( Variable<long int>& variable,                  const long int* values );
    virtual void Write( Variable<unsigned long int>& variable,         const unsigned long int* values );
    virtual void Write( Variable<long long int>& variable,             const long long int* values );
    virtual void Write( Variable<unsigned long long int>& variable,    const unsigned long long int* values );
    virtual void Write( Variable<float>& variable,                     const float* values );
    virtual void Write( Variable<double>& variable,                    const double* values );
    virtual void Write( Variable<long double>& variable,               const long double* values );
    virtual void Write( Variable<std::complex<float>>& variable,       const std::complex<float>* values );
    virtual void Write( Variable<std::complex<double>>& variable,      const std::complex<double>* values );
    virtual void Write( Variable<std::complex<long double>>& variable, const std::complex<long double>* values );
    virtual void Write( VariableCompound& variable,                    const void* values );

wfg's avatar
wfg committed
    /**
     * @brief Write functions can be overridden by derived classes. Base class behavior is to:
     * 1) Write to Variable values (m_Values) using the pointer to default group *m_Group set with SetDefaultGroup function
     * 2) Transform the data
     * 3) Write to all capsules -> data and metadata
     * @param variableName
     * @param values coming from user app
     */
    virtual void Write( const std::string variableName, const char* values );
    virtual void Write( const std::string variableName, const unsigned char* values );
    virtual void Write( const std::string variableName, const short* values );
    virtual void Write( const std::string variableName, const unsigned short* values );
    virtual void Write( const std::string variableName, const int* values );
    virtual void Write( const std::string variableName, const unsigned int* values );
    virtual void Write( const std::string variableName, const long int* values );
    virtual void Write( const std::string variableName, const unsigned long int* values );
    virtual void Write( const std::string variableName, const long long int* values );
    virtual void Write( const std::string variableName, const unsigned long long int* values );
    virtual void Write( const std::string variableName, const float* values );
    virtual void Write( const std::string variableName, const double* values );
    virtual void Write( const std::string variableName, const long double* values );
    virtual void Write( const std::string variableName, const std::complex<float>* values );
    virtual void Write( const std::string variableName, const std::complex<double>* values );
    virtual void Write( const std::string variableName, const std::complex<long double>* values );
    virtual void Write( const std::string variableName, const void* values );

     * Read function that adds static checking on the variable to be passed by values
     * It then calls its corresponding derived class virtual function
     * This version uses m_Group to look for the variableName.
     * @param variable name of variable to the written
     * @param values pointer passed from the application, nullptr not allowed, must use Read(variable) instead intentionally
    template< class T >
    void Read( Variable<T>& variable, const T* values )
    {
        Read( variable, values );
    }
    /**
     * String version
     * @param variableName
     * @param values
     */
    template< class T >
    void Read( const std::string variableName, const T* values )
    {
        Read( variableName, values );
    }
     * Single value version
     * @param variable
     * @param values
    template< class T >
    void Read( Variable<T>& variable, const T& values)
    {
        Read( variable, &values );
    }
    /**
     * Single value version using string as variable handlers
     * @param variableName
     * @param values
     */
    template< class T >
    void Read( const std::string variableName, const T& values )
    {
        Read( variableName, &values );
    }
wfg's avatar
wfg committed

    /**
      * Unallocated version, ADIOS will allocate space for incoming data
      * @param variable
      */
     template< class T >
     void Read( Variable<T>& variable )
     {
         Read( variable, nullptr );
     }
wfg's avatar
wfg committed

     /**
       * Unallocated version, ADIOS will allocate space for incoming data
       * @param variableName
       */
      template< class T >
      void Read( const std::string variableName )
      {
          Read( variableName, nullptr );
      }
    virtual void Read( Variable<double>& variable,                    const double* values );
     * Read function that adds static checking on the variable to be passed by values
     * It then calls its corresponding derived class virtual function
     * This version uses m_Group to look for the variableName.
     * @param variable name of variable to the written
     * @param values pointer passed from the application
    template< class T >
    void ScheduleRead( Variable<T>& variable, const T* values )
    {
        ScheduleRead( variable, values );
    }
    /**
     * String version
     * @param variableName
     * @param values
     */
    template< class T >
    void ScheduleRead( const std::string variableName, const T* values )
    {
        ScheduleRead( variableName, values );
    }
    /**
     * Single value version
     * @param variable
     * @param values
     */
    template< class T >
    void ScheduleRead( Variable<T>& variable, const T& values )
    {
        ScheduleRead( variable, &values );
    }
     * Single value version using string as variable handlers
     * @param variableName
     * @param values
     */
    template< class T >
    void ScheduleRead( const std::string variableName, const T& values )
    {
        ScheduleRead( variableName, &values );
    }

    /**
     * Single value version using string as variable handlers
    void ScheduleRead();


    virtual void ScheduleRead( Variable<double>& variable,                    const double* values );

    /**
     * Perform all scheduled reads, either blocking until all reads completed, or return immediately.
     * @param mode Blocking or non-blocking modes
     */
    void PerformReads( PerformReadMode mode );


    /**
     * Reader application indicates that no more data will be read from the current stream before advancing.
     * This is necessary to allow writers to advance as soon as possible.
     */
    virtual void Release( );

    /**
     * Indicates that a new step is going to be written as new variables come in.
     */
    virtual void Advance( float timeout_sec=0.0 );

    /**
     * Indicates that a new step is going to be written as new variables come in.
     * @param mode Advance mode, there are different options for writers and readers
     */
    virtual void Advance( AdvanceMode mode, float timeout_sec=0.0 );

    /** @brief Advance asynchronously and get a callback when readers release access to the buffered step.
     *
     * User variables that were allocated through AllocateVariable()
     * must not be modified until advance is completed.
     * @param mode Advance mode, there are different options for writers and readers
     * @param callback Will be called when advance is completed.
     */
    virtual void AdvanceAsync ( AdvanceMode mode, std::function<void( std::shared_ptr<adios::Engine> )> callback );


    //Read API
    /**
     * Inquires and (optionally) allocates and copies the contents of a variable
     * If success: it returns a pointer to the internal stored variable object in ADIOS class.
     * If failure: it returns nullptr
     * @param name variable name to look for
     * @param readIn if true: reads the full variable and payload, allocating values in memory, if false: internal payload is nullptr
     * @return success: it returns a pointer to the internal stored variable object in ADIOS class, failure: nullptr
     */
    virtual Variable<void> InquireVariable( const std::string name, const bool readIn = true );
    virtual Variable<char> InquireVariableChar( const std::string name, const bool readIn = true );
    virtual Variable<unsigned char> InquireVariableUChar( const std::string name, const bool readIn = true );
    virtual Variable<short> InquireVariableShort( const std::string name, const bool readIn = true );
    virtual Variable<unsigned short> InquireVariableUShort( const std::string name, const bool readIn = true );
    virtual Variable<int> InquireVariableInt( const std::string name, const bool readIn = true );
    virtual Variable<unsigned int> InquireVariableUInt( const std::string name, const bool readIn = true );
    virtual Variable<long int> InquireVariableLInt( const std::string name, const bool readIn = true );
    virtual Variable<unsigned long int> InquireVariableULInt( const std::string name, const bool readIn = true );
    virtual Variable<long long int> InquireVariableLLInt( const std::string name, const bool readIn = true );
    virtual Variable<unsigned long long int> InquireVariableULLInt( const std::string name, const bool readIn = true );
    virtual Variable<float> InquireVariableFloat( const std::string name, const bool readIn = true );
    virtual Variable<double> InquireVariableDouble( const std::string name, const bool readIn = true );
    virtual Variable<long double> InquireVariableLDouble( const std::string name, const bool readIn = true );
    virtual Variable<std::complex<float>> InquireVariableCFloat( const std::string name, const bool readIn = true );
    virtual Variable<std::complex<double>> InquireVariableCDouble( const std::string name, const bool readIn = true );
    virtual Variable<std::complex<long double>> InquireVariableCLDouble( const std::string name, const bool readIn = true );
    virtual VariableCompound InquireVariableCompound( const std::string name, const bool readIn = true );


    /** Return the names of all variables present in a stream/file opened for reading
     *
     * @return a vector of strings
     */
    std::vector<std::string> VariableNames();

    virtual void Close( const int transportIndex = -1  ) = 0; ///< Closes a particular transport, or all if -1
};


} //end namespace

#endif /* ENGINE_H_ */