352 lines
8.3 KiB
C++
352 lines
8.3 KiB
C++
/* ----------------------------------------------------------------------
|
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
|
https://lammps.sandia.gov/, Sandia National Laboratories
|
|
Steve Plimpton, sjplimp@sandia.gov
|
|
|
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
|
certain rights in this software. This software is distributed under
|
|
the GNU General Public License.
|
|
|
|
See the README file in the top-level LAMMPS directory.
|
|
------------------------------------------------------------------------- */
|
|
|
|
#include "lmptype.h"
|
|
#include "my_page.h"
|
|
#include "my_pool_chunk.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace LAMMPS_NS;
|
|
|
|
TEST(MyPage, int)
|
|
{
|
|
MyPage<int> p;
|
|
|
|
// default init. maxchunk=1, pagesize=1024
|
|
int rv = p.init();
|
|
ASSERT_EQ(rv, 0);
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
int *iptr = p.vget();
|
|
// second call to vget() should give same pointer without vgot()
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(1);
|
|
++iptr;
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 1);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
ASSERT_EQ(iptr, p.vget());
|
|
// use too large chunk size
|
|
p.vgot(2);
|
|
ASSERT_EQ(1, p.status());
|
|
|
|
p.reset();
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
p.vgot(1);
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get());
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get(1));
|
|
ASSERT_EQ(p.ndatum, 3);
|
|
ASSERT_EQ(p.nchunk, 3);
|
|
|
|
// restart with custom init. maxchunk=16, pagesize=256
|
|
rv = p.init(16, 64, 2);
|
|
ASSERT_EQ(rv, 0);
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
// second call to vget() should give same pointer without vgot()
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(16);
|
|
iptr += 16;
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 16);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
|
|
// use too large chunk size
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(32);
|
|
ASSERT_EQ(1, p.status());
|
|
|
|
p.reset();
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
p.vgot(16);
|
|
iptr = p.vget();
|
|
p.vgot(4);
|
|
iptr += 4;
|
|
ASSERT_EQ(iptr, p.get());
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get(16));
|
|
ASSERT_DOUBLE_EQ(p.size(), (double)sizeof(int) * 128.0);
|
|
ASSERT_EQ(p.ndatum, 37);
|
|
ASSERT_EQ(p.nchunk, 4);
|
|
p.get(16);
|
|
p.get(16);
|
|
// allocation on the same page
|
|
iptr = p.get(16);
|
|
iptr += 16;
|
|
ASSERT_EQ(iptr, p.get(16));
|
|
// allocation on different pages
|
|
p.get(16);
|
|
iptr += 16;
|
|
ASSERT_NE(iptr, p.get(16));
|
|
ASSERT_DOUBLE_EQ(p.size(), (double)sizeof(int) * 256.0);
|
|
ASSERT_EQ(p.ndatum, 133);
|
|
ASSERT_EQ(p.nchunk, 10);
|
|
}
|
|
|
|
TEST(MyPage, double)
|
|
{
|
|
MyPage<double> p;
|
|
|
|
// default init. maxchunk=1, pagesize=1024
|
|
int rv = p.init();
|
|
ASSERT_EQ(rv, 0);
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
double *iptr = p.vget();
|
|
// second call to vget() should give same pointer without vgot()
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(1);
|
|
++iptr;
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 1);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
ASSERT_EQ(iptr, p.vget());
|
|
// use too large chunk size
|
|
p.vgot(2);
|
|
ASSERT_EQ(1, p.status());
|
|
|
|
p.reset();
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
p.vgot(1);
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get());
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get(1));
|
|
ASSERT_EQ(p.ndatum, 3);
|
|
ASSERT_EQ(p.nchunk, 3);
|
|
|
|
// restart with custom init. maxchunk=16, pagesize=256
|
|
rv = p.init(16, 64, 2);
|
|
ASSERT_EQ(rv, 0);
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
// second call to vget() should give same pointer without vgot()
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(16);
|
|
iptr += 16;
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 16);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
|
|
// use too large chunk size
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(32);
|
|
ASSERT_EQ(1, p.status());
|
|
|
|
p.reset();
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
p.vgot(16);
|
|
iptr = p.vget();
|
|
p.vgot(4);
|
|
iptr += 4;
|
|
ASSERT_EQ(iptr, p.get());
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get(16));
|
|
ASSERT_DOUBLE_EQ(p.size(), (double)sizeof(double) * 128.0);
|
|
ASSERT_EQ(p.ndatum, 37);
|
|
ASSERT_EQ(p.nchunk, 4);
|
|
p.get(16);
|
|
p.get(16);
|
|
// allocation on the same page
|
|
iptr = p.get(16);
|
|
iptr += 16;
|
|
ASSERT_EQ(iptr, p.get(16));
|
|
// allocation on different pages
|
|
p.get(16);
|
|
iptr += 16;
|
|
ASSERT_NE(iptr, p.get(16));
|
|
ASSERT_DOUBLE_EQ(p.size(), (double)sizeof(double) * 256.0);
|
|
ASSERT_EQ(p.ndatum, 133);
|
|
ASSERT_EQ(p.nchunk, 10);
|
|
}
|
|
|
|
TEST(MyPage, bigint)
|
|
{
|
|
MyPage<bigint> p;
|
|
|
|
// default init. maxchunk=1, pagesize=1024
|
|
int rv = p.init();
|
|
ASSERT_EQ(rv, 0);
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
bigint *iptr = p.vget();
|
|
// second call to vget() should give same pointer without vgot()
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(1);
|
|
++iptr;
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 1);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
ASSERT_EQ(iptr, p.vget());
|
|
// use too large chunk size
|
|
p.vgot(2);
|
|
ASSERT_EQ(1, p.status());
|
|
|
|
p.reset();
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
p.vgot(1);
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get());
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get(1));
|
|
ASSERT_EQ(p.ndatum, 3);
|
|
ASSERT_EQ(p.nchunk, 3);
|
|
|
|
// restart with custom init. maxchunk=16, pagesize=256
|
|
rv = p.init(16, 64, 2);
|
|
ASSERT_EQ(rv, 0);
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
// second call to vget() should give same pointer without vgot()
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(16);
|
|
iptr += 16;
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 16);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
|
|
// use too large chunk size
|
|
ASSERT_EQ(iptr, p.vget());
|
|
p.vgot(32);
|
|
ASSERT_EQ(1, p.status());
|
|
|
|
p.reset();
|
|
ASSERT_EQ(0, p.status());
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
|
|
iptr = p.vget();
|
|
p.vgot(16);
|
|
iptr = p.vget();
|
|
p.vgot(4);
|
|
iptr += 4;
|
|
ASSERT_EQ(iptr, p.get());
|
|
++iptr;
|
|
ASSERT_EQ(iptr, p.get(16));
|
|
ASSERT_DOUBLE_EQ(p.size(), (double)sizeof(bigint) * 128.0);
|
|
ASSERT_EQ(p.ndatum, 37);
|
|
ASSERT_EQ(p.nchunk, 4);
|
|
p.get(16);
|
|
p.get(16);
|
|
// allocation on the same page
|
|
iptr = p.get(16);
|
|
iptr += 16;
|
|
ASSERT_EQ(iptr, p.get(16));
|
|
// allocation on different pages
|
|
p.get(16);
|
|
iptr += 16;
|
|
ASSERT_NE(iptr, p.get(16));
|
|
ASSERT_DOUBLE_EQ(p.size(), (double)sizeof(bigint) * 256.0);
|
|
ASSERT_EQ(p.ndatum, 133);
|
|
ASSERT_EQ(p.nchunk, 10);
|
|
}
|
|
|
|
TEST(MyPoolChunk, int)
|
|
{
|
|
// defaults to minchunk=1, maxchunk=1, nbin=1, chunksperpage=1024, pagedelta=1
|
|
MyPoolChunk<int> p;
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
ASSERT_EQ(p.size(), 0.0);
|
|
|
|
int idx = ~0x0000;
|
|
int *iptr = p.get(idx);
|
|
ASSERT_NE(iptr, nullptr);
|
|
ASSERT_EQ(idx, 0);
|
|
|
|
iptr = p.get(1, idx);
|
|
ASSERT_NE(iptr, nullptr);
|
|
ASSERT_EQ(idx, 1);
|
|
// we have only one page allocated
|
|
ASSERT_EQ(p.size(), 1024 * sizeof(int) + 1024 * sizeof(int) + sizeof(void *) + sizeof(int));
|
|
ASSERT_EQ(p.ndatum, 2);
|
|
ASSERT_EQ(p.nchunk, 2);
|
|
|
|
p.put(0);
|
|
ASSERT_EQ(p.ndatum, 1);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
|
|
iptr = p.get(2, idx);
|
|
ASSERT_EQ(iptr, nullptr);
|
|
ASSERT_EQ(p.status(), 3);
|
|
ASSERT_EQ(p.ndatum, 1);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
}
|
|
|
|
TEST(MyPoolChunk, double)
|
|
{
|
|
// defaults to minchunk=1, maxchunk=1, nbin=1, chunksperpage=1024, pagedelta=1
|
|
MyPoolChunk<double> p;
|
|
|
|
ASSERT_EQ(p.ndatum, 0);
|
|
ASSERT_EQ(p.nchunk, 0);
|
|
ASSERT_EQ(p.size(), 0.0);
|
|
|
|
int idx = ~0x0000;
|
|
double *dptr = p.get(idx);
|
|
ASSERT_NE(dptr, nullptr);
|
|
ASSERT_EQ(idx, 0);
|
|
|
|
dptr = p.get(1, idx);
|
|
ASSERT_NE(dptr, nullptr);
|
|
ASSERT_EQ(idx, 1);
|
|
// we have only one page allocated
|
|
ASSERT_EQ(p.size(), 1024 * sizeof(int) + 1024 * sizeof(double) + sizeof(void *) + sizeof(int));
|
|
|
|
p.put(0);
|
|
ASSERT_EQ(p.ndatum, 1);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
|
|
dptr = p.get(2, idx);
|
|
ASSERT_EQ(dptr, nullptr);
|
|
ASSERT_EQ(p.status(), 3);
|
|
ASSERT_EQ(p.ndatum, 1);
|
|
ASSERT_EQ(p.nchunk, 1);
|
|
}
|