Skip to content
Snippets Groups Projects
Engine.h 13.2 KiB
Newer Older
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * Engine.h Base abstract class for the core Open, Write/Read, Advance, Close
 * functionality. Use toolkit components to build your own Engine extending this
 * class.
 * Examples of derived classes in: adios2/engine/*
 *
 *  Created on: Nov 7, 2016
 *      Author: William F Godoy godoywf@ornl.gov
#ifndef ADIOS2_CORE_ENGINE_H_
#define ADIOS2_CORE_ENGINE_H_

/// \cond EXCLUDE_FROM_DOXYGEN
#include <functional> //std::function
#include <map>
#include <memory> //std::shared_ptr
#include <string>
#include <vector>
/// \endcond

#include "adios2/ADIOSConfig.h"
#include "adios2/ADIOSMPICommOnly.h"
#include "adios2/ADIOSTypes.h"
#include "adios2/core/IO.h"
#include "adios2/core/Variable.h"
#include "adios2/core/VariableCompound.h"
/** Base Abstract class for IO operations:  Read/Write, Schedule, Advance and
 * Close */
class Engine
{

public:
     * Unique Base class constructor
     * @param io object that generates this Engine
     * @param name unique engine name within IO class object
     * @param openMode  open mode from ADIOSTypes.h OpenMode
     * @param mpiComm new communicator passed at Open or from ADIOS class
    Engine(const std::string engineType, IO &io, const std::string &name,
           const OpenMode openMode, MPI_Comm mpiComm);

    virtual ~Engine() = default;

    /**
     * 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
     */
    void Write(Variable<T> &variable, const T *values);

    /**
     * String version
     * @param variableName
     * @param values
     */
    template <class T>
    void Write(const std::string &variableName, const T *values);

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

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

    /// Read API
     * @param variableName
    template <class T>
    Variable<T> *InquireVariable(const std::string &variableName,
                                 const bool readIn = false);

    /**
     * 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
     */
    void Read(Variable<T> &variable, T *values);

    /**
     * String version
     * @param variableName
     * @param values
     */
    template <class T>
    void Read(const std::string &variableName, T *values);

    /**
     * Single value version
     * @param variable
     * @param values
     */
    void Read(Variable<T> &variable, T &values);

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

    /**
     * Unallocated version, ADIOS will allocate space for incoming data
     * @param variable
     */
    void Read(Variable<T> &variable);

    /**
     * Unallocated version, ADIOS will allocate space for incoming data
     * @param variableName
     */
    void Read(const std::string &variableName);

    /**
     * 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
     */
    void ScheduleRead(Variable<T> &variable, T *values);

    /**
     * String version
     * @param variableName
     * @param values
     */
    template <class T>
    void ScheduleRead(const std::string &variableName, T *values);

    /**
     * Single value version
     * @param variable
     * @param values
     */
    void ScheduleRead(Variable<T> &variable, T &values);

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

    /**
     * Unallocated version, ADIOS will allocate space for incoming data
     * @param variableName
     */
    // virtual void ScheduleRead(const std::string &variableName);

    /**
     * Unallocated unspecified version, ADIOS will receive any variable and will
     * allocate space for incoming data
     */
    // virtual void ScheduleRead();
    /**
     * Perform all scheduled reads, either blocking until all reads completed,
     * or
     * return immediately.
     * @param mode Blocking or non-blocking modes
     */
    virtual 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(const float timeoutSeconds = 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(const AdvanceMode mode,
                         const float timeoutSeconds = 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(const AdvanceMode mode,
                 std::function<void(std::shared_ptr<adios::Engine>)> callback);

    AdvanceStatus GetAdvanceStatus();
     * @brief Let ADIOS allocate memory for a variable in the buffer (bp),
     * to be populated by the user. Variable dimensions are fixed.
     * 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 reference to the allocated array.
    template <class T>
    T *AllocateVariable(Variable<T> &var, T fillValue = 0);
    /**
     * Needed for DataMan Engine
     * @param callback function passed from the user
     */
    virtual void
    SetCallBack(std::function<void(const void *, std::string, std::string,
                                   std::string, std::vector<size_t>)>
                    callback);
    /** Return the names of all variables present in a stream/file opened for
     * reading
     * @return a vector of strings
     */
    std::vector<std::string> VariableNames();
    /**
     * Closes a particular transport, or all if -1
     * @param transportIndex order from IO AddTransport
     */
    virtual void Close(const int transportIndex = -1) = 0;
    /** from derived class */
    const std::string m_EngineType;

    /** IO class object that creates this Engine at Open */
    IO &m_IO;

    /** Unique name for this Engine within m_IO */
    const std::string &m_Name;

    /** open mode from ADIOSTypes.h OpenMode */
    const OpenMode m_OpenMode;

    /** from ADIOS class passed to Engine created with Open
     *  if no new communicator is passed */
    MPI_Comm m_MPIComm = MPI_COMM_SELF;

    /** true: additional exceptions */
    const bool m_DebugMode = false;

    /** added to exceptions to improve debugging */
    std::string m_EndMessage;

    /** Tracks written variables */
    std::set<std::string> m_WrittenVariables;
    AdvanceStatus m_AdvanceStatus = AdvanceStatus::OK;
    /** Called from constructors */
    virtual void Init();
    /** From IO SetParameters */
    virtual void InitParameters();

    /** From IO AddTransport */
    virtual void InitTransports();

// Known-type
#define declare_type(T)                                                        \
    virtual void DoWrite(Variable<T> &variable, const T *values);
    ADIOS2_FOREACH_TYPE_1ARG(declare_type)
#undef declare_type
    virtual void DoWrite(VariableCompound &variable, const void *values);
     * Finds the variable and call the corresponding DoWrite by
     * type
     * @param variableName
     * @param values application values
    void DoWrite(const std::string &variableName, const void *values);

    // READ
    virtual VariableBase *InquireVariableUnknown(const std::string &name,
                                                 const bool readIn);
    virtual Variable<char> *InquireVariableChar(const std::string &name,
                                                const bool readIn);
    virtual Variable<unsigned char> *
    InquireVariableUChar(const std::string &name, const bool readIn);
    virtual Variable<short> *InquireVariableShort(const std::string &name,
                                                  const bool readIn);
    virtual Variable<unsigned short> *
    InquireVariableUShort(const std::string &name, const bool readIn);
    virtual Variable<int> *InquireVariableInt(const std::string &name,
                                              const bool readIn);
    virtual Variable<unsigned int> *InquireVariableUInt(const std::string &name,
                                                        const bool readIn);
    virtual Variable<long int> *InquireVariableLInt(const std::string &name,
                                                    const bool readIn);
    virtual Variable<unsigned long int> *
    InquireVariableULInt(const std::string &name, const bool readIn);
    virtual Variable<long long int> *
    InquireVariableLLInt(const std::string &name, const bool readIn);
    virtual Variable<unsigned long long int> *
    InquireVariableULLInt(const std::string &name, const bool readIn);

    virtual Variable<float> *InquireVariableFloat(const std::string &name,
                                                  const bool readIn);
    virtual Variable<double> *InquireVariableDouble(const std::string &name,
                                                    const bool readIn);
    virtual Variable<long double> *
    InquireVariableLDouble(const std::string &name, const bool readIn);

    virtual Variable<cfloat> *InquireVariableCFloat(const std::string &name,
                                                    const bool readIn);
    virtual Variable<cdouble> *InquireVariableCDouble(const std::string &name,
                                                      const bool readIn);
    virtual Variable<cldouble> *InquireVariableCLDouble(const std::string &name,
                                                        const bool readIn);

// Known-type
#define declare_type(T)                                                        \
    virtual void DoScheduleRead(Variable<T> &variable, const T *values);       \
    virtual void DoScheduleRead(const std::string &variableName,               \
                                const T *values);
    ADIOS2_FOREACH_TYPE_1ARG(declare_type)
#undef declare_type

    void DoScheduleRead(const std::string &variableName, void *values);

private:
    /** Checks that start and count are not empty for global variables */
    void CheckVariableDims(const Dims start, const Dims count);
    /** Throw exception by Engine virtual functions not implemented by a derived
     * class */
    void ThrowUp(const std::string function);
} // end namespace adios

#include "Engine.inl"
#endif /* ADIOS2_CORE_ENGINE_H_ */