LCOV - code coverage report
Current view: top level - src/tensor_buffers - LBMTensorBuffer.C (source / functions) Hit Total Coverage
Test: idaholab/swift: #92 (25e020) with base b3cd84 Lines: 0 97 0.0 %
Date: 2025-09-10 17:10:32 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /**********************************************************************/
       2             : /*                    DO NOT MODIFY THIS HEADER                       */
       3             : /*             Swift, a Fourier spectral solver for MOOSE             */
       4             : /*                                                                    */
       5             : /*            Copyright 2024 Battelle Energy Alliance, LLC            */
       6             : /*                        ALL RIGHTS RESERVED                         */
       7             : /**********************************************************************/
       8             : 
       9             : #include "LBMTensorBuffer.h"
      10             : #include "DomainAction.h"
      11             : #include "LatticeBoltzmannStencilBase.h"
      12             : #include "LatticeBoltzmannProblem.h"
      13             : 
      14             : #ifdef LIBMESH_HAVE_HDF5
      15             : #include "hdf5.h"
      16             : #endif
      17             : 
      18             : registerMooseObject("SwiftApp", LBMTensorBuffer);
      19             : 
      20             : InputParameters
      21           0 : LBMTensorBuffer::validParams()
      22             : {
      23             :   InputParameters params = TensorBuffer<torch::Tensor>::validParams();
      24           0 :   params.addRequiredParam<std::string>("buffer_type",
      25             :                                        "The buffer type can be either distribution function (df), "
      26             :                                        "macroscopic scalar (ms) or macroscopic vectorial (mv)");
      27             : 
      28           0 :   params.addParam<FileName>("file", "Optional path of the file to read tensor form.");
      29             : 
      30           0 :   params.addParam<bool>("is_integer", false, "Whether to specify integer dtype");
      31           0 :   params.addPrivateParam<TensorProblem *>("_tensor_problem", nullptr);
      32           0 :   params.addClassDescription("Tensor wrapper form LBM tensors");
      33             : 
      34           0 :   return params;
      35           0 : }
      36             : 
      37           0 : LBMTensorBuffer::LBMTensorBuffer(const InputParameters & parameters)
      38             :   : TensorBuffer<torch::Tensor>(parameters),
      39           0 :     _buffer_type(getParam<std::string>("buffer_type")),
      40           0 :     _lb_problem(dynamic_cast<LatticeBoltzmannProblem &>(
      41           0 :         *getCheckedPointerParam<TensorProblem *>("_tensor_problem"))),
      42           0 :     _stencil(_lb_problem.getStencil())
      43             : {
      44           0 : }
      45             : 
      46             : void
      47           0 : LBMTensorBuffer::init()
      48             : {
      49             :   int64_t dimension = 0;
      50           0 :   if (_buffer_type == "df")
      51           0 :     dimension = _stencil._q;
      52           0 :   else if (_buffer_type == "mv")
      53           0 :     dimension = _domain.getDim();
      54           0 :   else if (_buffer_type == "ms")
      55             :     dimension = 0;
      56             :   else
      57           0 :     mooseError("Buffer type ", _buffer_type, " is not recognized");
      58             : 
      59           0 :   std::vector<int64_t> shape(_domain.getShape().begin(), _domain.getShape().end());
      60             : 
      61           0 :   if (_domain.getDim() < 3)
      62           0 :     shape.push_back(1);
      63           0 :   if (dimension > 0)
      64           0 :     shape.push_back(static_cast<int64_t>(dimension));
      65             : 
      66           0 :   if (getParam<bool>("is_integer"))
      67           0 :     _u = torch::zeros(shape, MooseTensor::intTensorOptions());
      68             :   else
      69           0 :     _u = torch::zeros(shape, MooseTensor::floatTensorOptions());
      70             : 
      71           0 :   if (isParamValid("file"))
      72           0 :     readTensorFromHdf5();
      73           0 : }
      74             : 
      75             : void
      76           0 : LBMTensorBuffer::readTensorFromFile(const std::vector<int64_t> & shape)
      77             : {
      78           0 :   mooseDeprecated("readTensorFromFile is deprecated, use h5 reader readTensorFromHdf5 instead!");
      79             : 
      80           0 :   const FileName tensor_file = getParam<FileName>("file");
      81           0 :   mooseInfo("Loading tensor(s) from file \n" + tensor_file);
      82           0 :   std::ifstream file(tensor_file);
      83           0 :   if (!file.is_open())
      84           0 :     mooseError("Cannot open file " + tensor_file);
      85             : 
      86             :   // read file into standart vector
      87           0 :   std::vector<Real> fileData(shape[0] * shape[1] * shape[2]);
      88             : 
      89           0 :   for (unsigned int i = 0; i < fileData.size(); i++)
      90           0 :     if (!(file >> fileData[i]))
      91           0 :       mooseError("Insufficient data in the file");
      92             : 
      93           0 :   file.close();
      94             : 
      95             :   // reshape and write into torch tensor
      96           0 :   for (int64_t k = 0; k < shape[2]; k++)
      97           0 :     for (int64_t j = 0; j < shape[1]; j++)
      98           0 :       for (int64_t i = 0; i < shape[0]; i++)
      99             :       {
     100           0 :         if (getParam<bool>("is_integer"))
     101           0 :           _u.index_put_({i, j, k},
     102           0 :                         static_cast<int>(fileData[k * shape[1] * shape[0] + j * shape[0] + i]));
     103             :         else
     104           0 :           _u.index_put_({i, j, k}, fileData[k * shape[1] * shape[0] + j * shape[0] + i]);
     105             :       }
     106           0 : }
     107             : 
     108             : void
     109           0 : LBMTensorBuffer::readTensorFromHdf5()
     110             : {
     111             : #ifdef LIBMESH_HAVE_HDF5
     112           0 :   const FileName tensor_file_name = getParam<FileName>("file");
     113             : 
     114             :   auto tensor_file_char = tensor_file_name.c_str();
     115             : 
     116             :   // open file
     117           0 :   hid_t file_id = H5Fopen(tensor_file_char, H5F_ACC_RDONLY, H5P_DEFAULT);
     118           0 :   if (file_id < 0)
     119           0 :     mooseError("Failed to open h5 file");
     120             : 
     121           0 :   std::string dataset_name = tensor_file_name.substr(0, tensor_file_name.size() - 3);
     122           0 :   auto last_slash = dataset_name.find_last_of("/\\");
     123           0 :   if (last_slash != std::string::npos)
     124           0 :     dataset_name = dataset_name.substr(last_slash + 1);
     125             :   auto dataset_name_char = dataset_name.c_str();
     126             : 
     127             :   // open dataset
     128           0 :   hid_t dataset_id = H5Dopen2(file_id, dataset_name_char, H5P_DEFAULT);
     129           0 :   if (dataset_id < 0)
     130           0 :     mooseError("Failed to obtain dataset from h5 file");
     131             : 
     132             :   // get dataspace
     133           0 :   hid_t dataspace_id = H5Dget_space(dataset_id);
     134           0 :   if (dataspace_id < 0)
     135           0 :     mooseError("Failed to obtain dataspace from h5 dataset");
     136             : 
     137             :   // get the dimensions of the dataspace
     138           0 :   const hsize_t rank = H5Sget_simple_extent_ndims(dataspace_id);
     139           0 :   std::vector<hsize_t> dims(rank);
     140           0 :   H5Sget_simple_extent_dims(dataspace_id, dims.data(), NULL);
     141             : 
     142             :   // get memory type id
     143           0 :   hid_t datatype_id = H5Dget_type(dataset_id);
     144             : 
     145             :   // total number of elements in the buffer
     146             :   int64_t total_number_of_elements = 1;
     147           0 :   for (auto i : index_range(dims))
     148             :   {
     149           0 :     total_number_of_elements *= dims[i];
     150             :   }
     151             : 
     152             :   // make tensor
     153           0 :   std::vector<int64_t> torch_dims(dims.begin(), dims.end());
     154             : 
     155           0 :   if (getParam<bool>("is_integer"))
     156             :   {
     157             :     // create read buffer
     158           0 :     std::vector<int64_t> buffer(total_number_of_elements);
     159             :     // read data
     160           0 :     H5Dread(dataset_id, datatype_id, H5S_ALL, dataspace_id, H5P_DEFAULT, buffer.data());
     161             : 
     162           0 :     auto cpu_tensor = torch::from_blob(buffer.data(), torch_dims, torch::kInt64).clone();
     163           0 :     _u = cpu_tensor.to(MooseTensor::intTensorOptions());
     164           0 :   }
     165             :   else
     166             :   {
     167             :     // create read buffer
     168           0 :     std::vector<double> buffer(total_number_of_elements);
     169             :     // read data
     170           0 :     H5Dread(dataset_id, datatype_id, H5S_ALL, dataspace_id, H5P_DEFAULT, buffer.data());
     171             : 
     172           0 :     auto cpu_tensor = torch::from_blob(buffer.data(), torch_dims, torch::kFloat64).clone();
     173           0 :     _u = cpu_tensor.to(MooseTensor::floatTensorOptions());
     174           0 :   }
     175           0 :   while (_u.dim() < 3)
     176           0 :     _u.unsqueeze_(-1);
     177             : 
     178             :   // close everything
     179           0 :   H5Fclose(file_id);
     180           0 :   H5Dclose(dataset_id);
     181           0 :   H5Sclose(dataspace_id);
     182             : #else
     183             :   mooseError("MOOSE was built without HDF5 support.");
     184             : #endif
     185           0 : }
     186             : 
     187             : void
     188           0 : LBMTensorBuffer::makeCPUCopy()
     189             : {
     190           0 :   if (!_u.defined())
     191             :     return;
     192             : 
     193           0 :   if (_cpu_copy_requested)
     194             :   {
     195           0 :     if (_u.is_cpu())
     196           0 :       _u_cpu = _u.clone().contiguous();
     197             :     else
     198           0 :       _u_cpu = _u.cpu().contiguous();
     199             :   }
     200             : }

Generated by: LCOV version 1.14