8#ifndef UTILS_CONCATENATEDALIGNEDARRAYRMM_H_ 
    9#define UTILS_CONCATENATEDALIGNEDARRAYRMM_H_ 
   15template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
   18    enum class Quantity_t { RX = 0, RY = 1, RZ = 2, VX = 3, VY = 4, VZ = 5, UID = 6};
 
   21        mardyn_assert(
sizeof(real_calc_t) <= 
sizeof(uid_t));
 
   25    void prefetchForForce() 
const;
 
   27    real_calc_t* begin_calc(Quantity_t coord);
 
   28    real_accum_t* begin_accum(Quantity_t coord);
 
   29    uid_t* begin_uid(Quantity_t coord);
 
   30    real_calc_t& get_calc(Quantity_t coord, 
size_t i);
 
   31    real_accum_t& get_accum(Quantity_t coord, 
size_t i);
 
   32    uid_t& get_uid(Quantity_t coord, 
size_t i);
 
   34    const real_calc_t* begin_calc(Quantity_t coord) 
const;
 
   35    const real_accum_t* begin_accum(Quantity_t coord) 
const;
 
   36    const uid_t* begin_uid(Quantity_t coord) 
const;
 
   37    const real_calc_t& get_calc(Quantity_t coord, 
size_t i) 
const;
 
   38    const real_accum_t& get_accum(Quantity_t coord, 
size_t i) 
const;
 
   39    const uid_t& get_uid(Quantity_t coord, 
size_t i) 
const;
 
   41    void zero(
size_t start_idx = 0);
 
   46    void resize(
size_t nEntriesPerArray);
 
   48    void increaseStorage(
size_t oldNumElements, 
size_t additionalElements);
 
   50    void appendValues(std::array<real_calc_t, 3> calcs, std::array<real_accum_t, 3> accums, uid_t uid, 
size_t oldNumElements);
 
   52    size_t get_dynamic_memory()
 const {
 
   53        return _byteBuffer.get_dynamic_memory();
 
   57    typedef unsigned char byte_t;
 
   58    byte_t* begin(Quantity_t coord);
 
   59    const byte_t* begin(Quantity_t coord) 
const;
 
   64    size_t _numEntriesPerArray;
 
   67template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
   69    byte_t * rx = _byteBuffer;
 
   70    byte_t * ry = rx + _numEntriesPerArray * 
sizeof(real_calc_t);
 
   71    byte_t * rz = ry + _numEntriesPerArray * 
sizeof(real_calc_t);
 
   72    byte_t * vx = rz + _numEntriesPerArray * 
sizeof(real_calc_t);
 
   73    byte_t * vy = vx + _numEntriesPerArray * 
sizeof(real_accum_t);
 
   74    byte_t * vz = vy + _numEntriesPerArray * 
sizeof(real_accum_t);
 
   75    byte_t * uid = vz + _numEntriesPerArray * 
sizeof(real_accum_t);
 
   76    byte_t * starts[7] = {rx, ry, rz, vx, vy, vz, uid};
 
   77    return _numEntriesPerArray > 0 ? starts[size_t(coord)] : 
nullptr;
 
   80template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
   82    const byte_t * rx = _byteBuffer;
 
   83    const byte_t * ry = rx + _numEntriesPerArray * 
sizeof(real_calc_t);
 
   84    const byte_t * rz = ry + _numEntriesPerArray * 
sizeof(real_calc_t);
 
   85    const byte_t * vx = rz + _numEntriesPerArray * 
sizeof(real_calc_t);
 
   86    const byte_t * vy = vx + _numEntriesPerArray * 
sizeof(real_accum_t);
 
   87    const byte_t * vz = vy + _numEntriesPerArray * 
sizeof(real_accum_t);
 
   88    const byte_t * uid = vz + _numEntriesPerArray * 
sizeof(real_accum_t);
 
   89    const byte_t * starts[7] = {rx, ry, rz, vx, vy, vz, uid};
 
   90    return _numEntriesPerArray > 0 ? starts[size_t(coord)] : 
nullptr;
 
   93template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
   95    mardyn_assert(coord < Quantity_t::VX);
 
   96    byte_t * ret = begin(coord);
 
   97    return reinterpret_cast<real_calc_t*
>(ret);
 
  100template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  102    mardyn_assert(coord >= Quantity_t::VX and coord < Quantity_t::UID);
 
  103    byte_t * ret = begin(coord);
 
  104    return reinterpret_cast<real_accum_t*
>(ret);
 
  107template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  109    mardyn_assert(coord == Quantity_t::UID);
 
  110    byte_t * ret = begin(coord);
 
  111    return reinterpret_cast<uid_t*
>(ret);
 
  114template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  116    mardyn_assert(coord < Quantity_t::VX);
 
  117    mardyn_assert(i < _numEntriesPerArray);
 
  118    byte_t * startByte = begin(coord);
 
  119    real_calc_t * startReal = 
reinterpret_cast<real_calc_t*
>(startByte);
 
  120    real_calc_t & ret = startReal[i];
 
  124template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  126    mardyn_assert(coord >= Quantity_t::VX and coord < Quantity_t::UID);
 
  127    mardyn_assert(i < _numEntriesPerArray);
 
  128    byte_t * startByte = begin(coord);
 
  129    real_accum_t * startReal = 
reinterpret_cast<real_accum_t*
>(startByte);
 
  130    real_accum_t & ret = startReal[i];
 
  134template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  136    mardyn_assert(coord == Quantity_t::UID);
 
  137    mardyn_assert(i < _numEntriesPerArray);
 
  138    byte_t * startByte = begin(coord);
 
  139    uid_t * startUID = 
reinterpret_cast<uid_t*
>(startByte);
 
  140    uid_t & ret = startUID[i];
 
  144template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  146    mardyn_assert(coord < Quantity_t::VX);
 
  147    const byte_t * ret = begin(coord);
 
  148    return reinterpret_cast<const real_calc_t*
>(ret);
 
  151template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  153    mardyn_assert(coord >= Quantity_t::VX and coord < Quantity_t::UID);
 
  154    const byte_t * ret = begin(coord);
 
  155    return reinterpret_cast<const real_accum_t*
>(ret);
 
  158template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  160    mardyn_assert(coord == Quantity_t::UID);
 
  161    const byte_t * ret = begin(coord);
 
  162    return reinterpret_cast<const uid_t*
>(ret);
 
  165template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  167    mardyn_assert(coord < Quantity_t::VX);
 
  168    mardyn_assert(i < _numEntriesPerArray);
 
  169    const byte_t * startByte = begin(coord);
 
  170    const real_calc_t * startReal = 
reinterpret_cast<const real_calc_t*
>(startByte);
 
  171    const real_calc_t & ret = startReal[i];
 
  175template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  177    mardyn_assert(coord >= Quantity_t::VX and coord < Quantity_t::UID);
 
  178    mardyn_assert(i < _numEntriesPerArray);
 
  179    const byte_t * startByte = begin(coord);
 
  180    const real_accum_t * startReal = 
reinterpret_cast<const real_accum_t*
>(startByte);
 
  181    const real_accum_t & ret = startReal[i];
 
  185template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  187    mardyn_assert(coord == Quantity_t::UID);
 
  188    mardyn_assert(i < _numEntriesPerArray);
 
  189    const byte_t * startByte = begin(coord);
 
  190    const uid_t * startUID = 
reinterpret_cast<const uid_t*
>(startByte);
 
  191    const uid_t & ret = startUID[i];
 
  195template <
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  198    if (nEntriesPerArray == 0 and _numEntriesPerArray == 0)
 
  202    size_t numBytesForReals = 3 * _numEntriesPerArray * (
sizeof(real_calc_t) + 
sizeof(real_accum_t));
 
  203    size_t numBytesForUID = _numEntriesPerArray * 
sizeof(uid_t);
 
  204    size_t totalNumBytes = numBytesForReals + numBytesForUID;
 
  206    _byteBuffer.resize(totalNumBytes);
 
  208    if (_numEntriesPerArray > nEntriesPerArray) {
 
  209        zero(nEntriesPerArray);
 
  213template<
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  215    if (start_idx == 0) {
 
  216        _byteBuffer.zero(start_idx);
 
  219    size_t num_to_zero = _numEntriesPerArray - start_idx;
 
  220    if (_numEntriesPerArray > 0 and num_to_zero > 0) {
 
  221        const int qbegin = 
static_cast<int>(Quantity_t::RX);
 
  222        const int qmid = 
static_cast<int>(Quantity_t::VX);
 
  223        const int qend = 
static_cast<int>(Quantity_t::UID);
 
  224        for (
int i = qbegin; i < qmid; ++i) {
 
  225            Quantity_t q = 
static_cast<Quantity_t
>(i);
 
  226            std::memset(&(get_calc(q,start_idx)), 0, num_to_zero * 
sizeof(real_calc_t));
 
  228        for (
int i = qmid; i < qend; ++i) {
 
  229            Quantity_t q = 
static_cast<Quantity_t
>(i);
 
  230            std::memset(&(get_accum(q,start_idx)), 0, num_to_zero * 
sizeof(real_accum_t));
 
  233        size_t startIndex = begin(Quantity_t::UID) - begin(Quantity_t::RX) + start_idx * 
sizeof(uid_t);
 
  234        _byteBuffer.zero(startIndex);
 
  238template<
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  240    mardyn_assert(oldNumElements <= _numEntriesPerArray);
 
  242    size_t newNumElements = oldNumElements + additionalElements;
 
  244    if (newNumElements <= _numEntriesPerArray) {
 
  250    if (oldNumElements > 0) {
 
  254        size_t oldNumEntriesPerArray = _numEntriesPerArray;
 
  255        resize(newNumElements);
 
  257        const int qbegin = 
static_cast<int>(Quantity_t::RX);
 
  258        const int qend = 
static_cast<int>(Quantity_t::UID);
 
  259        for (
int i = qbegin; i < qend; ++i) {
 
  260            Quantity_t q = 
static_cast<Quantity_t
>(i);
 
  261            std::memcpy(begin(q), &(backupCopy[i*oldNumEntriesPerArray*
sizeof(real_calc_t)]), oldNumElements * 
sizeof(real_calc_t));
 
  263        std::memcpy(begin(Quantity_t::UID), &(backupCopy[6*oldNumEntriesPerArray*
sizeof(real_calc_t)]), oldNumElements * 
sizeof(uid_t));
 
  266        resize(newNumElements);
 
  270template<
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  272        std::array<real_calc_t, 3> calcs, std::array<real_accum_t, 3> accums, uid_t uid, 
size_t oldNumElements) {
 
  273    mardyn_assert(oldNumElements <= _numEntriesPerArray);
 
  274    if (oldNumElements < _numEntriesPerArray) {
 
  277        increaseStorage(oldNumElements, 1);
 
  279    get_calc(Quantity_t::RX, oldNumElements) = calcs[0];
 
  280    get_calc(Quantity_t::RY, oldNumElements) = calcs[1];
 
  281    get_calc(Quantity_t::RZ, oldNumElements) = calcs[2];
 
  282    get_accum(Quantity_t::VX, oldNumElements) = accums[0];
 
  283    get_accum(Quantity_t::VY, oldNumElements) = accums[1];
 
  284    get_accum(Quantity_t::VZ, oldNumElements) = accums[2];
 
  285    get_uid(Quantity_t::UID, oldNumElements) = uid;
 
  288template<
typename real_calc_t, 
typename real_accum_t, 
typename u
id_t>
 
  291    const byte_t * b = begin(Quantity_t::RX);
 
  292    const byte_t * e = begin(Quantity_t::UID);
 
  293    const size_t stride = CACHE_LINE_SIZE / 
sizeof(byte_t);
 
  295    for (
const byte_t * p = b; p < e; p += stride) {
 
  297        _mm_prefetch(
reinterpret_cast<const char*
>(p), _MM_HINT_T1);
 
Defines the length of the vectors and the corresponding functions.
 
An aligned array.
Definition: AlignedArray.h:75
 
Definition: ConcatenatedAlignedArrayRMM.h:16
 
void resize(size_t nEntriesPerArray)
Reallocate the array. All content may be lost.
Definition: ConcatenatedAlignedArrayRMM.h:196