Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
d3027cf
Preliminary implementation of subsample features in PotAccel and Cube…
Nov 29, 2025
5d6ea21
Additional implementation errors fixed and added some documentation
Dec 1, 2025
56fb55c
Typo in call name
Dec 1, 2025
1cd694b
Merge branch 'devel' into OutSample
Dec 1, 2025
322ab22
Refactoring into a single covariance class for simplicity
Dec 1, 2025
3799ed2
Added writeCoefCovariance for Cylindrical
Dec 2, 2025
825ece2
Comment changes only
Dec 2, 2025
8bac118
Comment changes only
Dec 2, 2025
411947c
Merge branch 'devel' into OutSample
Dec 2, 2025
1e5dcc1
Update src/Cube.cc
The9Cat Dec 2, 2025
311c70d
Initial plan
Copilot Dec 2, 2025
1ab52bc
Initial plan
Copilot Dec 2, 2025
43f4d72
Update expui/Covariance.cc
The9Cat Dec 2, 2025
e0f66bd
Initial plan
Copilot Dec 2, 2025
ed77d7b
Fix error message class name from CovarianceReader to SubsampleCovari…
Copilot Dec 2, 2025
539a19a
Fix class name in error messages: CovarianceReader -> SubsampleCovari…
Copilot Dec 2, 2025
1c17c87
Fix additional class name references for consistency
Copilot Dec 2, 2025
ac06b30
Complete review checks
Copilot Dec 2, 2025
0d46fd6
Complete class name consistency fixes
Copilot Dec 2, 2025
f06cdb2
Merge pull request #178 from EXP-code/copilot/sub-pr-177
The9Cat Dec 2, 2025
3cf02b9
Fix class name in error messages to SubsampleCovariance
Copilot Dec 2, 2025
8b976c8
Merge pull request #179 from EXP-code/copilot/sub-pr-177-again
The9Cat Dec 2, 2025
8ea07a7
Complete feedback implementation
Copilot Dec 2, 2025
8f1cd58
Merge pull request #180 from EXP-code/copilot/sub-pr-177-another-one
The9Cat Dec 2, 2025
0e1f720
Name stopping with OutCoef
Dec 2, 2025
b30b991
Implemented CUDA version of subsampling but not tested
Dec 3, 2025
e580b21
Reuse intermediate reduction variables
Dec 3, 2025
cb19486
Add base-class overrides
Dec 3, 2025
095aed8
Fix memory allocation for subsampling; allow user to set Cuda reducti…
Dec 3, 2025
8840d32
Add signature for updated coefficient storage; add base-class overrides
Dec 3, 2025
7b3e9f0
Save a small bit of time to zero rather than resize previously sized …
Dec 3, 2025
c09d8fe
Make GPU indexing scheme consistent with CPU
Dec 3, 2025
e3030f5
Comment addition only [no CI]
Dec 3, 2025
53c51ae
Refactoring fix
Dec 4, 2025
df26050
Preliminary implementation of subsample support for Spherical and Cyl…
Dec 4, 2025
8521af7
Remove debug output line
Dec 4, 2025
a662ac9
Fix debug routine for EL3's use of Eigen rather than Vector
Dec 4, 2025
a0f3f58
Add missing methods needed for Covariance
Dec 4, 2025
92b1e8f
Add a constructor from an explicit path+filename
Dec 5, 2025
d913617
Use the explicit path+filename constructor for Covariance
Dec 5, 2025
f29c04d
Fix OutSample logic
Dec 5, 2025
3522ba6
Merge branch 'devel' into OutSample
Dec 10, 2025
2ced206
Should be a project not system include here
Dec 10, 2025
c9d36b9
Merge branch 'devel' into OutSample to get the latest changes from 'm…
Dec 11, 2025
d8f9c75
Implemented coefficient parameter checking on reading and writing
Dec 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _codeql_detected_source_root
226 changes: 78 additions & 148 deletions expui/BiorthBasis.H
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "BiorthBess.H"
#include "BasisFactory.H"
#include "BiorthCube.H"
#include "Covariance.H"
#include "sltableMP2.H"
#include "SLGridMP2.H"
#include "YamlCheck.H"
Expand Down Expand Up @@ -106,22 +107,14 @@ namespace BasisClasses
//! Coefficient variance computation enabled
bool pcavar = false;

//! Data type for covariance
bool floatType = false;

//@{
//! Sample counts and masses for covariance computation
Eigen::VectorXi sampleCounts;
Eigen::VectorXd sampleMasses;
//@}

//@{
//! HDF5 compression settings
unsigned H5compress = 5;
unsigned H5chunk = 1024*1024; // (1 MB)
bool H5shuffle = true;
bool H5szip = false;
//@}
//! Covariance storage instance
std::shared_ptr<SubsampleCovariance> covarStore;

//! Round time key to emulated fixed-point arithmetic
double roundTime(double time)
Expand All @@ -131,19 +124,6 @@ namespace BasisClasses
return std::floor(time * multiplier + 0.5) / multiplier;
}

//! Write H5 covariance; returns updated group count
virtual unsigned writeCovarH5(HighFive::Group& group, unsigned count, double time);

//! Write H5 parameters for coefficient covariance
virtual void writeCovarH5Params(HighFive::File& file) {}

//! Add coefficient covariance data to an HDF5 file
virtual void extendCoefCovariance(const std::string& filename, double time);

//! Variance file versioning (Version 1.0 has more granularity and
//! poor compression)
inline static const std::string CovarianceFileVersion = "1.1";

//! Store full coavariance matrix?
bool covar = true;

Expand Down Expand Up @@ -290,51 +270,36 @@ namespace BasisClasses
return varray;
}

//! Return a vector of tuples of basis functions and the
//! covariance matrix for subsamples of particles
using CoefCovarType = std::tuple<Eigen::VectorXcd, Eigen::MatrixXcd>;
virtual std::vector<std::vector<CoefCovarType>>
getCoefCovariance()
{
// Must be overriden; base implementation throws error
throw std::runtime_error("BiorthBasis::getCoefCovariance: Not implemented for this basis");
}

//! Get sample counts for the covariance computation
virtual std::tuple<Eigen::VectorXi, Eigen::VectorXd>
getCovarSamples()
{
return std::make_tuple(sampleCounts, sampleMasses);
}

//! Write coefficient covariance data to an HDF5 file
void writeCoefCovariance(const std::string& compname,
const std::string& runtag,
double time=0.0);

//! Choose between float and double storage for covariance
void setCovarFloatType(bool flt) { floatType = flt; }

//! HDF5 compression settings
void setCovarH5Compress(unsigned level, unsigned chunksize, bool shuffle, bool szip=false)
virtual void writeCoefCovariance(const std::string& compname, const std::string& runtag,
double time=0.0)
{
H5compress = level;
H5chunk = chunksize;
H5shuffle = shuffle;
H5szip = szip;
// Must be overriden; base implementation throws error
throw std::runtime_error("BiorthBasis::writeCoefCovariance: "
"Not implemented for this basis");
}

//! Make covariance after accumulation
virtual void makeCoefCovariance(void) {}

//! Enable covariance computation with optional sample time
virtual void enableCoefCovariance(bool pcavar, int sampT_in, bool covar_in)
virtual void enableCoefCovariance(bool pcavar, int sampT_in, bool ftype, bool covar_in)
{
// Must be overriden; base implementation throws error
throw std::runtime_error("BiorthBasis::enableCoefCovariance: "
"Not implemented for this basis");
}

//! HDF5 compression settings
void setCovarH5Compress(unsigned level, unsigned chunksize, bool shuffle, bool szip=false)
{
if (covarStore) {
covarStore->setCovarH5Compress(level, chunksize, shuffle, szip);
} else {
throw std::runtime_error("BiorthBasis::setCovarH5Compress: covariance storage not initialized");
}
}

//! Evaluate acceleration in Cartesian coordinates in centered
//! coordinate system for a collections of points
virtual RowMatrixXd& getAccel(Eigen::Ref<const RowMatrixXd> pos)
Expand Down Expand Up @@ -518,19 +483,39 @@ namespace BasisClasses
return ret;
}

//! Return a vector of tuples of basis functions and the
//! covariance matrix for subsamples of particles
std::vector<std::vector<CoefCovarType>>
getCoefCovariance();
//! Write coefficient covariance data to an HDF5 file
virtual void writeCoefCovariance(const std::string& compname, const std::string& runtag, double time=0.0)
{
if (covarStore) {
std::vector<std::vector<SubsampleCovariance::CoefCovarType>> covarData(meanV.size());
for (int T=0; T<meanV.size(); ++T) {
covarData[T].resize(meanV[T].size());
for (int lm=0; lm<meanV[T].size(); ++lm) {
covarData[T][lm] = std::make_tuple(meanV[T][lm], covrV[T][lm]);
}
}

SubsampleCovariance::CovarData elements = std::make_tuple(sampleCounts, sampleMasses, covarData);
covarStore->writeCoefCovariance(compname, runtag, elements, time);
} else {
throw std::runtime_error("Spherical::writeCoefCovariance: covariance storage not initialized");
}
}

//! Request and initialize covariance computation
virtual void enableCoefCovariance(bool pcavar_in, int sampT_in=100,
bool covar_in=true)
bool ftype=false, bool covar_in=true)
{
pcavar = pcavar_in;
sampT = sampT_in;
covar = covar_in;
if (pcavar) init_covariance();
if (pcavar) {
init_covariance();
covarStore = std::make_shared<SubsampleCovariance>
([this](HighFive::File& file){this->writeCovarH5Params(file);}, BasisID, ftype, covar);
}
}

//! Create and the coefficients from a function callback with the
//! provided time value. Set potential=true if function is a
//! potential field. Density is assumed if false (default).
Expand Down Expand Up @@ -990,7 +975,6 @@ namespace BasisClasses
//! For coefficient writing
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>
EigenColMajor;


//@{
//! Basis construction parameters
Expand Down Expand Up @@ -1103,31 +1087,30 @@ namespace BasisClasses
return ret;
}

//! Return a vector of tuples of basis functions and the
//! covariance matrix for subsamples of particles
std::vector<std::vector<CoefCovarType>>
getCoefCovariance()
{
return sl->getCoefCovariance();
}

std::tuple<Eigen::VectorXi, Eigen::VectorXd>
getCovarSamples()
//! Write coefficient covariance data to an HDF5 file
virtual void writeCoefCovariance(const std::string& compname, const std::string& runtag, double time=0.0)
{
// Copy to base class members
std::tie(sampleCounts, sampleMasses) = sl->getCovarSamples();
return {sampleCounts, sampleMasses};
if (covarStore) {
auto covarData = sl->getCoefCovariance();
std::tie(sampleCounts, sampleMasses) = sl->getCovarSamples();
SubsampleCovariance::CovarData elements = std::make_tuple(sampleCounts, sampleMasses, covarData);
covarStore->writeCoefCovariance(compname, runtag, elements, time);
} else {
throw std::runtime_error("Spherical::writeCoefCovariance: covariance storage not initialized");
}
}

virtual void enableCoefCovariance(bool pcavar_in, int sampT_in=100,
bool covar_in=true)
bool ftype=false, bool covar_in=true)
{
pcavar = pcavar_in;
sampT = sampT_in;
covar = covar_in;
if (pcavar) {
sl->setSampT(std::max(1, sampT));
sl->set_covar(true);
covarStore = std::make_shared<SubsampleCovariance>
([this](HighFive::File& file){this->writeCovarH5Params(file);}, BasisID, ftype, covar);
}
}
//! Create and the coefficients from a function callback with the
Expand Down Expand Up @@ -1443,25 +1426,35 @@ namespace BasisClasses
return true;
}

//! Return a vector of tuples of basis functions and the
//! covariance matrix for subsamples of particles
std::vector<std::vector<CoefCovarType>> getCoefCovariance();

//! Get sample count and mass arrays
std::tuple<Eigen::VectorXi, Eigen::VectorXd>
getCovarSamples()
//! Write coefficient covariance data to an HDF5 file
virtual void writeCoefCovariance(const std::string& compname, const std::string& runtag, double time=0.0)
{
return {sampleCounts, sampleMasses};
if (covarStore) {
std::vector<std::vector<SubsampleCovariance::CoefCovarType>> covarData(meanV.size());
for (int T=0; T<meanV.size(); ++T) {
covarData[T].resize(1);
covarData[T][0] = std::make_tuple(meanV[T], covrV[T]);
}
SubsampleCovariance::CovarData elements = std::make_tuple(sampleCounts, sampleMasses, covarData);
covarStore->writeCoefCovariance(compname, runtag, elements, time);
} else {
throw std::runtime_error("Spherical::writeCoefCovariance: covariance storage not initialized");
}
}


//! Enable coefficient covariance computation
virtual void enableCoefCovariance(bool pcavar_in, int sampT_in=100,
bool covar_in=false)
bool ftype=false, bool covar_in=false)
{
pcavar = pcavar_in;
sampT = sampT_in;
covar = covar_in;
if (pcavar) { init_covariance(); }
if (pcavar) {
init_covariance();
covarStore = std::make_shared<SubsampleCovariance>
([this](HighFive::File& file){this->writeCovarH5Params(file);}, BasisID, ftype, covar);
}
}

//! Return wave-number indices from flattened index
Expand All @@ -1471,69 +1464,6 @@ namespace BasisClasses
unsigned index1D(int kx, int ky, int kz);
};

class CovarianceReader
{
public:

using CoefCovarType = std::tuple<Eigen::VectorXcd, Eigen::MatrixXcd>;

protected:

std::vector<double> times;
std::vector<Eigen::VectorXi> sampleCounts;
std::vector<Eigen::VectorXd> sampleMasses;
std::vector<std::vector<std::vector<CoefCovarType>>> covarData;

const double fixedPointPrecision = 1.0e08;
std::map<int, unsigned> timeMap;
unsigned timeIndex(double time)
{
int itime = static_cast<int>(time * fixedPointPrecision + 0.5);
auto it = timeMap.find(itime);
if (it == timeMap.end())
throw std::runtime_error("CovarianceReader: time not found");
return it->second;
}

std::string basisID;

public:

//! Constructor from HDF5 file
CovarianceReader(const std::string& filename, int stride=1);

//! Get time list
std::vector<double> Times() { return times; }

//@{
//! Return a vector of tuples of basis functions and the
//! covariance matrix for subsamples of particles
std::vector<std::vector<CoefCovarType>>
getCoefCovariance(unsigned index) { return covarData[index]; }

std::vector<std::vector<CoefCovarType>>
getCoefCovariance(double time) { return covarData[timeIndex(time)]; }
//@}


//@{
//! Get sample counts for the covariance computation
std::tuple<Eigen::VectorXi, Eigen::VectorXd>
getCovarSamples(unsigned index)
{
return {sampleCounts[index], sampleMasses[index]};
}

std::tuple<Eigen::VectorXi, Eigen::VectorXd>
getCovarSamples(double time)
{
unsigned index = timeIndex(time);
return {sampleCounts[index], sampleMasses[index]};
}
//@}

std::string basisIDname() { return basisID; }
};

//! Time-dependent potential-density model
using BasisCoef = std::tuple<std::shared_ptr<Basis>, std::shared_ptr<CoefClasses::Coefs>>;
Expand Down
Loading
Loading