multiplicationSparse
C++ Function Reference
1 Signature
BigDataStatMeth::hdf5Dataset * BigDataStatMeth::multiplicationSparse(BigDataStatMeth::hdf5Dataset *dsA, BigDataStatMeth::hdf5Dataset *dsB, BigDataStatMeth::hdf5Dataset *dsC, hsize_t hdf5_block, hsize_t mem_block_size, bool bparal, bool browmajor, Rcpp::Nullable< int > threads=R_NilValue)2 Description
Sparse matrix multiplication for HDF5 matrices.
3 Parameters
dsA(BigDataStatMeth::hdf5Dataset *): First input matrix datasetdsB(BigDataStatMeth::hdf5Dataset *): Second input matrix datasetdsC(BigDataStatMeth::hdf5Dataset *): Output matrix datasethdf5_block(hsize_t): Block size for HDF5 I/O operationsmem_block_size(hsize_t): Block size for in-memory operationsbparal(bool): Whether to use parallel processingbrowmajor(bool): Whether matrices are stored in row-major orderthreads(Rcpp::Nullable< int >): Number of threads for parallel processing
4 Returns
Type: BigDataStatMeth::hdf5Dataset *
5 Details
Performs sparse matrix multiplication C = A * B where A, B, and C are HDF5 datasets, with optimizations for sparse data structures.
6 Call Graph
7 Source Code
NoteImplementation
File: inst/include/hdf5Algebra/multiplicationSparse.hpp • Lines 68-182
inline BigDataStatMeth::hdf5Dataset* multiplicationSparse( BigDataStatMeth::hdf5Dataset* dsA, BigDataStatMeth::hdf5Dataset* dsB, BigDataStatMeth::hdf5Dataset* dsC,
hsize_t hdf5_block, hsize_t mem_block_size, bool bparal, bool browmajor, Rcpp::Nullable<int> threads = R_NilValue)
{
try {
hsize_t K = dsA->nrows();
hsize_t N = dsA->ncols();
hsize_t M = dsB->nrows();
// hsize_t L = dsB->ncols();
if( dsA->nrows() == dsB->ncols())
{
hsize_t isize = hdf5_block + 1,
ksize = hdf5_block + 1,
jsize = hdf5_block + 1;
std::vector<hsize_t> stride = {1, 1};
std::vector<hsize_t> block = {1, 1};
dsC->inheritCompressionLevel(dsA->getCompressionLevel());
//.. 20260408 ..// dsC->createDataset( M, N, "real");
dsC->createDataset( N, M, "real");
for (hsize_t ii = 0; ii < N; ii += hdf5_block)
{
if( ii + hdf5_block > N ) isize = N - ii;
// Això haurien de ser files i no per columnes
for (hsize_t jj = 0; jj < M; jj += hdf5_block)
{
if( jj + hdf5_block > M) jsize = M - jj;
for(hsize_t kk = 0; kk < K; kk += hdf5_block)
{
if( kk + hdf5_block > K ) ksize = K - kk;
hsize_t iRowsA = std::min(hdf5_block,ksize),
iColsA = std::min(hdf5_block,isize),
iRowsB = std::min(hdf5_block,jsize),
iColsB = std::min(hdf5_block,ksize);
std::vector<double> vdA( iRowsA * iColsA );
dsA->readDatasetBlock( {kk, ii}, {iRowsA, iColsA}, stride, block, vdA.data() );
Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> A (vdA.data(), iRowsA, iColsA );
std::vector<double> vdB( iRowsB * iColsB );
dsB->readDatasetBlock( {jj, kk}, {iRowsB, iColsB}, stride, block, vdB.data() );
Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> B (vdB.data(), iRowsB, iColsB );
//.. 20260408 ..// std::vector<double> vdC( iRowsB * iColsA );
//.. 20260408 ..// dsC->readDatasetBlock( {jj, ii}, {iRowsB, iColsA}, stride, block, vdC.data() );
//.. 20260408 ..// Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> C (vdC.data(), iRowsB, iColsA );
//.. 20260408 ..//
//.. 20260408 ..// // if( bparal == false) {
//.. 20260408 ..// // C = C + B * A;
//.. 20260408 ..// // } else {
//.. 20260408 ..// // C = C + Bblock_matrix_mul_parallel(B, A, mem_block_size, threads);
//.. 20260408 ..// // }
//.. 20260408 ..//
//.. 20260408 ..// C = C + (B.sparseView() * A.sparseView()).toDense() ;
//.. 20260408 ..//
//.. 20260408 ..// std::vector<hsize_t> offset = {jj,ii};
//.. 20260408 ..// std::vector<hsize_t> count = {iRowsB, iColsA};
//.. 20260408 ..//
//.. 20260408 ..// dsC->writeDatasetBlock(Rcpp::wrap(C), offset, count, stride, block, false);
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> C_accumulator =
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>::Zero(iRowsB, iColsA);
if (kk == 0) {
C_accumulator = (B.sparseView() * A.sparseView()).toDense();
} else {
std::vector<double> vdC(iRowsB * iColsA);
dsC->readDatasetBlock({jj, ii}, {iRowsB, iColsA}, stride, block, vdC.data());
Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> C_prev(vdC.data(), iRowsB, iColsA);
C_accumulator = C_prev + (B.sparseView() * A.sparseView()).toDense();
}
// Write using vector overload — same pattern as multiplication.hpp
std::vector<double> vdC_final(iRowsB * iColsA);
Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> C_final_map(vdC_final.data(), iRowsB, iColsA);
C_final_map = C_accumulator;
std::vector<hsize_t> offset = {jj, ii};
std::vector<hsize_t> count = {iRowsB, iColsA};
dsC->writeDatasetBlock(vdC_final, offset, count, stride, block);
if( kk + hdf5_block > K ) ksize = hdf5_block + 1;
}
if( jj + hdf5_block > M ) jsize = hdf5_block + 1;
}
if( ii + hdf5_block > N ) isize = hdf5_block + 1;
}
}else {
throw std::range_error("multiplicationSparse error: non-conformable arguments");
}
} catch(std::exception& ex) {
throw std::runtime_error(std::string("c++ exception multiplicationSparse: ") + ex.what());
}
return(dsC);
}8 Usage Example
#include "BigDataStatMeth.hpp"
// Example usage
auto result = multiplicationSparse(...);