LCOV - code coverage report
Current view: top level - core - DataContainer.cpp (source / functions) Hit Total Coverage
Test: test_coverage.info.cleaned Lines: 0 321 0.0 %
Date: 2022-08-04 03:43:28 Functions: 0 316 0.0 %

          Line data    Source code
       1             : #include "DataContainer.h"
       2             : #include "DataContainerFormatter.hpp"
       3             : #include "FormatConfig.h"
       4             : #include "DataHandlerCPU.h"
       5             : #include "DataHandlerMapCPU.h"
       6             : #include "BlockDescriptor.h"
       7             : #include "RandomBlocksDescriptor.h"
       8             : #include "PartitionDescriptor.h"
       9             : #include "Error.h"
      10             : #include "TypeCasts.hpp"
      11             : #include "Assertions.h"
      12             : 
      13             : #include <utility>
      14             : #include <algorithm>
      15             : 
      16             : namespace elsa
      17             : {
      18             : 
      19             :     template <typename data_t>
      20           0 :     DataContainer<data_t>::DataContainer(const DataDescriptor& dataDescriptor,
      21             :                                          DataHandlerType handlerType)
      22           0 :         : _dataDescriptor{dataDescriptor.clone()},
      23           0 :           _dataHandler{createDataHandler(handlerType, _dataDescriptor->getNumberOfCoefficients())},
      24           0 :           _dataHandlerType{handlerType}
      25             :     {
      26           0 :     }
      27             : 
      28             :     template <typename data_t>
      29           0 :     DataContainer<data_t>::DataContainer(const DataDescriptor& dataDescriptor,
      30             :                                          const Eigen::Matrix<data_t, Eigen::Dynamic, 1>& data,
      31             :                                          DataHandlerType handlerType)
      32           0 :         : _dataDescriptor{dataDescriptor.clone()},
      33           0 :           _dataHandler{createDataHandler(handlerType, _dataDescriptor->getNumberOfCoefficients())},
      34           0 :           _dataHandlerType{handlerType}
      35             :     {
      36           0 :         if (_dataHandler->getSize() != data.size())
      37           0 :             throw InvalidArgumentError("DataContainer: initialization vector has invalid size");
      38             : 
      39           0 :         for (index_t i = 0; i < _dataHandler->getSize(); ++i)
      40           0 :             (*_dataHandler)[i] = data[i];
      41           0 :     }
      42             : 
      43             :     template <typename data_t>
      44           0 :     DataContainer<data_t>::DataContainer(const DataContainer<data_t>& other)
      45           0 :         : _dataDescriptor{other._dataDescriptor->clone()},
      46           0 :           _dataHandler{other._dataHandler->clone()},
      47           0 :           _dataHandlerType{other._dataHandlerType}
      48             :     {
      49           0 :     }
      50             : 
      51             :     template <typename data_t>
      52           0 :     DataContainer<data_t>& DataContainer<data_t>::operator=(const DataContainer<data_t>& other)
      53             :     {
      54           0 :         if (this != &other) {
      55           0 :             _dataDescriptor = other._dataDescriptor->clone();
      56             : 
      57           0 :             if (_dataHandler && canAssign(other._dataHandlerType)) {
      58           0 :                 *_dataHandler = *other._dataHandler;
      59             :             } else {
      60           0 :                 _dataHandler = other._dataHandler->clone();
      61           0 :                 _dataHandlerType = other._dataHandlerType;
      62             :             }
      63             :         }
      64             : 
      65           0 :         return *this;
      66             :     }
      67             : 
      68             :     template <typename data_t>
      69           0 :     DataContainer<data_t>::DataContainer(DataContainer<data_t>&& other) noexcept
      70           0 :         : _dataDescriptor{std::move(other._dataDescriptor)},
      71           0 :           _dataHandler{std::move(other._dataHandler)},
      72           0 :           _dataHandlerType{std::move(other._dataHandlerType)}
      73             :     {
      74             :         // leave other in a valid state
      75           0 :         other._dataDescriptor = nullptr;
      76           0 :         other._dataHandler = nullptr;
      77           0 :     }
      78             : 
      79             :     template <typename data_t>
      80           0 :     DataContainer<data_t>& DataContainer<data_t>::operator=(DataContainer<data_t>&& other)
      81             :     {
      82           0 :         _dataDescriptor = std::move(other._dataDescriptor);
      83             : 
      84           0 :         if (_dataHandler && canAssign(other._dataHandlerType)) {
      85           0 :             *_dataHandler = std::move(*other._dataHandler);
      86             :         } else {
      87           0 :             _dataHandler = std::move(other._dataHandler);
      88           0 :             _dataHandlerType = std::move(other._dataHandlerType);
      89             :         }
      90             : 
      91             :         // leave other in a valid state
      92           0 :         other._dataDescriptor = nullptr;
      93           0 :         other._dataHandler = nullptr;
      94             : 
      95           0 :         return *this;
      96             :     }
      97             : 
      98             :     template <typename data_t>
      99           0 :     const DataDescriptor& DataContainer<data_t>::getDataDescriptor() const
     100             :     {
     101           0 :         return *_dataDescriptor;
     102             :     }
     103             : 
     104             :     template <typename data_t>
     105           0 :     index_t DataContainer<data_t>::getSize() const
     106             :     {
     107           0 :         return _dataHandler->getSize();
     108             :     }
     109             : 
     110             :     template <typename data_t>
     111           0 :     data_t& DataContainer<data_t>::operator[](index_t index)
     112             :     {
     113           0 :         ELSA_VERIFY(index >= 0);
     114           0 :         ELSA_VERIFY(index < getSize());
     115             : 
     116           0 :         return (*_dataHandler)[index];
     117             :     }
     118             : 
     119             :     template <typename data_t>
     120           0 :     const data_t& DataContainer<data_t>::operator[](index_t index) const
     121             :     {
     122           0 :         ELSA_VERIFY(index >= 0);
     123           0 :         ELSA_VERIFY(index < getSize());
     124             : 
     125           0 :         return static_cast<const DataHandler<data_t>&>(*_dataHandler)[index];
     126             :     }
     127             : 
     128             :     template <typename data_t>
     129           0 :     data_t DataContainer<data_t>::at(const IndexVector_t& coordinate) const
     130             :     {
     131           0 :         const auto arr = coordinate.array();
     132           0 :         if ((arr < 0).any()
     133           0 :             || (arr >= _dataDescriptor->getNumberOfCoefficientsPerDimension().array()).any()) {
     134           0 :             return 0;
     135             :         }
     136             : 
     137           0 :         return (*this)[_dataDescriptor->getIndexFromCoordinate(coordinate)];
     138             :     }
     139             : 
     140             :     template <typename data_t>
     141           0 :     data_t& DataContainer<data_t>::operator()(const IndexVector_t& coordinate)
     142             :     {
     143             :         // const auto arr = coordinate.array();
     144             :         // const auto shape = _dataDescriptor->getNumberOfCoefficientsPerDimension().array();
     145             :         // ELSA_VERIFY((arr >= 0).all());
     146             :         // ELSA_VERIFY((arr < shape).all());
     147             : 
     148           0 :         return (*this)[_dataDescriptor->getIndexFromCoordinate(coordinate)];
     149             :     }
     150             : 
     151             :     template <typename data_t>
     152           0 :     const data_t& DataContainer<data_t>::operator()(const IndexVector_t& coordinate) const
     153             :     {
     154             :         // const auto arr = coordinate.array();
     155             :         // const auto shape = _dataDescriptor->getNumberOfCoefficientsPerDimension().array();
     156             :         // ELSA_VERIFY((arr >= 0).all());
     157             :         // ELSA_VERIFY((arr < shape).all());
     158             : 
     159           0 :         return (*this)[_dataDescriptor->getIndexFromCoordinate(coordinate)];
     160             :     }
     161             : 
     162             :     template <typename data_t>
     163           0 :     data_t DataContainer<data_t>::dot(const DataContainer<data_t>& other) const
     164             :     {
     165           0 :         return _dataHandler->dot(*other._dataHandler);
     166             :     }
     167             : 
     168             :     template <typename data_t>
     169           0 :     GetFloatingPointType_t<data_t> DataContainer<data_t>::squaredL2Norm() const
     170             :     {
     171           0 :         return _dataHandler->squaredL2Norm();
     172             :     }
     173             : 
     174             :     template <typename data_t>
     175           0 :     GetFloatingPointType_t<data_t> DataContainer<data_t>::l2Norm() const
     176             :     {
     177           0 :         return _dataHandler->l2Norm();
     178             :     }
     179             : 
     180             :     template <typename data_t>
     181           0 :     index_t DataContainer<data_t>::l0PseudoNorm() const
     182             :     {
     183           0 :         return _dataHandler->l0PseudoNorm();
     184             :     }
     185             : 
     186             :     template <typename data_t>
     187           0 :     GetFloatingPointType_t<data_t> DataContainer<data_t>::l1Norm() const
     188             :     {
     189           0 :         return _dataHandler->l1Norm();
     190             :     }
     191             : 
     192             :     template <typename data_t>
     193           0 :     GetFloatingPointType_t<data_t> DataContainer<data_t>::lInfNorm() const
     194             :     {
     195           0 :         return _dataHandler->lInfNorm();
     196             :     }
     197             : 
     198             :     template <typename data_t>
     199           0 :     data_t DataContainer<data_t>::sum() const
     200             :     {
     201           0 :         return _dataHandler->sum();
     202             :     }
     203             : 
     204             :     template <typename data_t>
     205           0 :     data_t DataContainer<data_t>::minElement() const
     206             :     {
     207           0 :         return _dataHandler->minElement();
     208             :     }
     209             : 
     210             :     template <typename data_t>
     211           0 :     data_t DataContainer<data_t>::maxElement() const
     212             :     {
     213           0 :         return _dataHandler->maxElement();
     214             :     }
     215             : 
     216             :     template <typename data_t>
     217           0 :     void DataContainer<data_t>::fft(FFTNorm norm) const
     218             :     {
     219           0 :         this->_dataHandler->fft(*this->_dataDescriptor, norm);
     220           0 :     }
     221             : 
     222             :     template <typename data_t>
     223           0 :     void DataContainer<data_t>::ifft(FFTNorm norm) const
     224             :     {
     225           0 :         this->_dataHandler->ifft(*this->_dataDescriptor, norm);
     226           0 :     }
     227             : 
     228             :     template <typename data_t>
     229           0 :     DataContainer<data_t>& DataContainer<data_t>::operator+=(const DataContainer<data_t>& dc)
     230             :     {
     231           0 :         *_dataHandler += *dc._dataHandler;
     232           0 :         return *this;
     233             :     }
     234             : 
     235             :     template <typename data_t>
     236           0 :     DataContainer<data_t>& DataContainer<data_t>::operator-=(const DataContainer<data_t>& dc)
     237             :     {
     238           0 :         *_dataHandler -= *dc._dataHandler;
     239           0 :         return *this;
     240             :     }
     241             : 
     242             :     template <typename data_t>
     243           0 :     DataContainer<data_t>& DataContainer<data_t>::operator*=(const DataContainer<data_t>& dc)
     244             :     {
     245           0 :         *_dataHandler *= *dc._dataHandler;
     246           0 :         return *this;
     247             :     }
     248             : 
     249             :     template <typename data_t>
     250           0 :     DataContainer<data_t>& DataContainer<data_t>::operator/=(const DataContainer<data_t>& dc)
     251             :     {
     252           0 :         *_dataHandler /= *dc._dataHandler;
     253           0 :         return *this;
     254             :     }
     255             : 
     256             :     template <typename data_t>
     257           0 :     DataContainer<data_t>& DataContainer<data_t>::operator+=(data_t scalar)
     258             :     {
     259           0 :         *_dataHandler += scalar;
     260           0 :         return *this;
     261             :     }
     262             : 
     263             :     template <typename data_t>
     264           0 :     DataContainer<data_t>& DataContainer<data_t>::operator-=(data_t scalar)
     265             :     {
     266           0 :         *_dataHandler -= scalar;
     267           0 :         return *this;
     268             :     }
     269             : 
     270             :     template <typename data_t>
     271           0 :     DataContainer<data_t>& DataContainer<data_t>::operator*=(data_t scalar)
     272             :     {
     273           0 :         *_dataHandler *= scalar;
     274           0 :         return *this;
     275             :     }
     276             : 
     277             :     template <typename data_t>
     278           0 :     DataContainer<data_t>& DataContainer<data_t>::operator/=(data_t scalar)
     279             :     {
     280           0 :         *_dataHandler /= scalar;
     281           0 :         return *this;
     282             :     }
     283             : 
     284             :     template <typename data_t>
     285           0 :     DataContainer<data_t>& DataContainer<data_t>::operator=(data_t scalar)
     286             :     {
     287           0 :         *_dataHandler = scalar;
     288           0 :         return *this;
     289             :     }
     290             : 
     291             :     template <typename data_t>
     292             :     template <typename... Args>
     293             :     std::unique_ptr<DataHandler<data_t>>
     294           0 :         DataContainer<data_t>::createDataHandler(DataHandlerType handlerType, Args&&... args)
     295             :     {
     296           0 :         switch (handlerType) {
     297           0 :             case DataHandlerType::CPU:
     298           0 :                 return std::make_unique<DataHandlerCPU<data_t>>(std::forward<Args>(args)...);
     299           0 :             case DataHandlerType::MAP_CPU:
     300           0 :                 return std::make_unique<DataHandlerCPU<data_t>>(std::forward<Args>(args)...);
     301             : #ifdef ELSA_CUDA_VECTOR
     302             :             case DataHandlerType::GPU:
     303             :                 return std::make_unique<DataHandlerGPU<data_t>>(std::forward<Args>(args)...);
     304             :             case DataHandlerType::MAP_GPU:
     305             :                 return std::make_unique<DataHandlerGPU<data_t>>(std::forward<Args>(args)...);
     306             : #endif
     307           0 :             default:
     308           0 :                 throw InvalidArgumentError("DataContainer: unknown handler type");
     309             :         }
     310             :     }
     311             : 
     312             :     template <typename data_t>
     313           0 :     DataContainer<data_t>::DataContainer(const DataDescriptor& dataDescriptor,
     314             :                                          std::unique_ptr<DataHandler<data_t>> dataHandler,
     315             :                                          DataHandlerType dataType)
     316           0 :         : _dataDescriptor{dataDescriptor.clone()},
     317           0 :           _dataHandler{std::move(dataHandler)},
     318           0 :           _dataHandlerType{dataType}
     319             :     {
     320           0 :     }
     321             : 
     322             :     template <typename data_t>
     323           0 :     bool DataContainer<data_t>::operator==(const DataContainer<data_t>& other) const
     324             :     {
     325           0 :         if (*_dataDescriptor != *other._dataDescriptor)
     326           0 :             return false;
     327             : 
     328           0 :         if (*_dataHandler != *other._dataHandler)
     329           0 :             return false;
     330             : 
     331           0 :         return true;
     332             :     }
     333             : 
     334             :     template <typename data_t>
     335           0 :     bool DataContainer<data_t>::operator!=(const DataContainer<data_t>& other) const
     336             :     {
     337           0 :         return !(*this == other);
     338             :     }
     339             : 
     340             :     template <typename data_t>
     341           0 :     DataContainer<data_t> DataContainer<data_t>::getBlock(index_t i)
     342             :     {
     343           0 :         const auto blockDesc = downcast_safe<BlockDescriptor>(_dataDescriptor.get());
     344           0 :         if (!blockDesc)
     345           0 :             throw LogicError("DataContainer: cannot get block from not-blocked container");
     346             : 
     347           0 :         if (i >= blockDesc->getNumberOfBlocks() || i < 0)
     348           0 :             throw InvalidArgumentError("DataContainer: block index out of bounds");
     349             : 
     350           0 :         index_t startIndex = blockDesc->getOffsetOfBlock(i);
     351           0 :         const auto& ithDesc = blockDesc->getDescriptorOfBlock(i);
     352           0 :         index_t blockSize = ithDesc.getNumberOfCoefficients();
     353             : 
     354           0 :         DataHandlerType newHandlerType = (_dataHandlerType == DataHandlerType::CPU
     355           0 :                                           || _dataHandlerType == DataHandlerType::MAP_CPU)
     356           0 :                                              ? DataHandlerType::MAP_CPU
     357             :                                              : DataHandlerType::MAP_GPU;
     358             : 
     359           0 :         return DataContainer<data_t>{ithDesc, _dataHandler->getBlock(startIndex, blockSize),
     360           0 :                                      newHandlerType};
     361             :     }
     362             : 
     363             :     template <typename data_t>
     364           0 :     const DataContainer<data_t> DataContainer<data_t>::getBlock(index_t i) const
     365             :     {
     366           0 :         const auto blockDesc = downcast_safe<BlockDescriptor>(_dataDescriptor.get());
     367           0 :         if (!blockDesc)
     368           0 :             throw LogicError("DataContainer: cannot get block from not-blocked container");
     369             : 
     370           0 :         if (i >= blockDesc->getNumberOfBlocks() || i < 0)
     371           0 :             throw InvalidArgumentError("DataContainer: block index out of bounds");
     372             : 
     373           0 :         index_t startIndex = blockDesc->getOffsetOfBlock(i);
     374           0 :         const auto& ithDesc = blockDesc->getDescriptorOfBlock(i);
     375           0 :         index_t blockSize = ithDesc.getNumberOfCoefficients();
     376             : 
     377           0 :         DataHandlerType newHandlerType = (_dataHandlerType == DataHandlerType::CPU
     378           0 :                                           || _dataHandlerType == DataHandlerType::MAP_CPU)
     379           0 :                                              ? DataHandlerType::MAP_CPU
     380             :                                              : DataHandlerType::MAP_GPU;
     381             : 
     382             :         // getBlock() returns a pointer to non-const DH, but that's fine as it gets wrapped in a
     383             :         // constant container
     384           0 :         return DataContainer<data_t>{ithDesc, _dataHandler->getBlock(startIndex, blockSize),
     385           0 :                                      newHandlerType};
     386             :     }
     387             : 
     388             :     template <typename data_t>
     389           0 :     DataContainer<data_t> DataContainer<data_t>::viewAs(const DataDescriptor& dataDescriptor)
     390             :     {
     391           0 :         if (dataDescriptor.getNumberOfCoefficients() != getSize())
     392           0 :             throw InvalidArgumentError("DataContainer: view must have same size as container");
     393             : 
     394           0 :         DataHandlerType newHandlerType = (_dataHandlerType == DataHandlerType::CPU
     395           0 :                                           || _dataHandlerType == DataHandlerType::MAP_CPU)
     396           0 :                                              ? DataHandlerType::MAP_CPU
     397             :                                              : DataHandlerType::MAP_GPU;
     398             : 
     399           0 :         return DataContainer<data_t>{dataDescriptor, _dataHandler->getBlock(0, getSize()),
     400           0 :                                      newHandlerType};
     401             :     }
     402             : 
     403             :     template <typename data_t>
     404             :     const DataContainer<data_t>
     405           0 :         DataContainer<data_t>::viewAs(const DataDescriptor& dataDescriptor) const
     406             :     {
     407           0 :         if (dataDescriptor.getNumberOfCoefficients() != getSize())
     408           0 :             throw InvalidArgumentError("DataContainer: view must have same size as container");
     409             : 
     410           0 :         DataHandlerType newHandlerType = (_dataHandlerType == DataHandlerType::CPU
     411           0 :                                           || _dataHandlerType == DataHandlerType::MAP_CPU)
     412           0 :                                              ? DataHandlerType::MAP_CPU
     413             :                                              : DataHandlerType::MAP_GPU;
     414             : 
     415             :         // getBlock() returns a pointer to non-const DH, but that's fine as it gets wrapped in a
     416             :         // constant container
     417           0 :         return DataContainer<data_t>{dataDescriptor, _dataHandler->getBlock(0, getSize()),
     418           0 :                                      newHandlerType};
     419             :     }
     420             : 
     421             :     template <typename data_t>
     422           0 :     const DataContainer<data_t> DataContainer<data_t>::slice(index_t i) const
     423             :     {
     424           0 :         auto& desc = getDataDescriptor();
     425           0 :         auto dim = desc.getNumberOfDimensions();
     426           0 :         auto sizeOfLastDim = desc.getNumberOfCoefficientsPerDimension()[dim - 1];
     427             : 
     428           0 :         if (i >= sizeOfLastDim) {
     429           0 :             throw LogicError("Trying to access out of bound slice");
     430             :         }
     431             : 
     432           0 :         if (sizeOfLastDim == 1) {
     433           0 :             return *this;
     434             :         }
     435             : 
     436           0 :         auto sliceDesc = PartitionDescriptor(desc, sizeOfLastDim);
     437             : 
     438             :         // Now set the slice
     439           0 :         return viewAs(sliceDesc).getBlock(i);
     440           0 :     }
     441             : 
     442             :     template <typename data_t>
     443           0 :     DataContainer<data_t> DataContainer<data_t>::slice(index_t i)
     444             :     {
     445           0 :         auto& desc = getDataDescriptor();
     446           0 :         auto dim = desc.getNumberOfDimensions();
     447           0 :         auto sizeOfLastDim = desc.getNumberOfCoefficientsPerDimension()[dim - 1];
     448             : 
     449           0 :         if (i >= sizeOfLastDim) {
     450           0 :             throw LogicError("Trying to access out of bound slice");
     451             :         }
     452             : 
     453           0 :         if (sizeOfLastDim == 1) {
     454           0 :             return *this;
     455             :         }
     456             : 
     457           0 :         auto sliceDesc = PartitionDescriptor(desc, sizeOfLastDim);
     458             : 
     459             :         // Now set the slice
     460           0 :         return viewAs(sliceDesc).getBlock(i);
     461           0 :     }
     462             : 
     463             :     template <typename data_t>
     464           0 :     typename DataContainer<data_t>::iterator DataContainer<data_t>::begin()
     465             :     {
     466           0 :         return iterator(&(*this)[0]);
     467             :     }
     468             : 
     469             :     template <typename data_t>
     470           0 :     typename DataContainer<data_t>::const_iterator DataContainer<data_t>::begin() const
     471             :     {
     472           0 :         return cbegin();
     473             :     }
     474             : 
     475             :     template <typename data_t>
     476           0 :     typename DataContainer<data_t>::const_iterator DataContainer<data_t>::cbegin() const
     477             :     {
     478           0 :         return const_iterator(&(*this)[0]);
     479             :     }
     480             : 
     481             :     template <typename data_t>
     482           0 :     typename DataContainer<data_t>::iterator DataContainer<data_t>::end()
     483             :     {
     484           0 :         return iterator(&(*this)[0] + getSize());
     485             :     }
     486             : 
     487             :     template <typename data_t>
     488           0 :     typename DataContainer<data_t>::const_iterator DataContainer<data_t>::end() const
     489             :     {
     490           0 :         return cend();
     491             :     }
     492             : 
     493             :     template <typename data_t>
     494           0 :     typename DataContainer<data_t>::const_iterator DataContainer<data_t>::cend() const
     495             :     {
     496           0 :         return const_iterator(&(*this)[0] + getSize());
     497             :     }
     498             : 
     499             :     template <typename data_t>
     500           0 :     typename DataContainer<data_t>::reverse_iterator DataContainer<data_t>::rbegin()
     501             :     {
     502           0 :         return reverse_iterator(end());
     503             :     }
     504             : 
     505             :     template <typename data_t>
     506           0 :     typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::rbegin() const
     507             :     {
     508           0 :         return crbegin();
     509             :     }
     510             : 
     511             :     template <typename data_t>
     512           0 :     typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::crbegin() const
     513             :     {
     514           0 :         return const_reverse_iterator(cend());
     515             :     }
     516             : 
     517             :     template <typename data_t>
     518           0 :     typename DataContainer<data_t>::reverse_iterator DataContainer<data_t>::rend()
     519             :     {
     520           0 :         return reverse_iterator(begin());
     521             :     }
     522             : 
     523             :     template <typename data_t>
     524           0 :     typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::rend() const
     525             :     {
     526           0 :         return crend();
     527             :     }
     528             : 
     529             :     template <typename data_t>
     530           0 :     typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::crend() const
     531             :     {
     532           0 :         return const_reverse_iterator(cbegin());
     533             :     }
     534             : 
     535             :     template <typename data_t>
     536           0 :     DataHandlerType DataContainer<data_t>::getDataHandlerType() const
     537             :     {
     538           0 :         return _dataHandlerType;
     539             :     }
     540             : 
     541             :     template <typename data_t>
     542           0 :     void DataContainer<data_t>::format(std::ostream& os, format_config cfg) const
     543             :     {
     544           0 :         DataContainerFormatter<data_t> fmt{cfg};
     545           0 :         fmt.format(os, *this);
     546           0 :     }
     547             : 
     548             :     template <typename data_t>
     549           0 :     DataContainer<data_t> DataContainer<data_t>::loadToCPU()
     550             :     {
     551           0 :         if (_dataHandlerType == DataHandlerType::CPU
     552           0 :             || _dataHandlerType == DataHandlerType::MAP_CPU) {
     553           0 :             throw LogicError(
     554             :                 "DataContainer: cannot load data to CPU with already CPU based container");
     555             :         }
     556             : 
     557           0 :         DataContainer<data_t> dcCPU(*_dataDescriptor, DataHandlerType::CPU);
     558             : 
     559           0 :         for (index_t i = 0; i < getSize(); i++) {
     560           0 :             dcCPU[i] = this->operator[](i);
     561             :         }
     562             : 
     563           0 :         return dcCPU;
     564           0 :     }
     565             : 
     566             :     template <typename data_t>
     567           0 :     DataContainer<data_t> DataContainer<data_t>::loadToGPU()
     568             :     {
     569           0 :         if (_dataHandlerType == DataHandlerType::GPU
     570           0 :             || _dataHandlerType == DataHandlerType::MAP_GPU) {
     571           0 :             throw LogicError(
     572             :                 "DataContainer: cannot load data to GPU with already GPU based container");
     573             :         }
     574             : 
     575           0 :         DataContainer<data_t> dcGPU(*_dataDescriptor, DataHandlerType::GPU);
     576             : 
     577           0 :         for (index_t i = 0; i < getSize(); i++) {
     578           0 :             dcGPU[i] = this->operator[](i);
     579             :         }
     580             : 
     581           0 :         return dcGPU;
     582           0 :     }
     583             : 
     584             :     template <typename data_t>
     585           0 :     bool DataContainer<data_t>::canAssign(DataHandlerType handlerType)
     586             :     {
     587           0 :         if (_dataHandlerType == DataHandlerType::CPU
     588           0 :             || _dataHandlerType == DataHandlerType::MAP_CPU) {
     589           0 :             switch (handlerType) {
     590           0 :                 case DataHandlerType::CPU:
     591           0 :                     return true;
     592             :                     break;
     593           0 :                 case DataHandlerType::MAP_CPU:
     594           0 :                     return true;
     595             :                     break;
     596           0 :                 default:
     597           0 :                     return false;
     598             :             }
     599             :         } else {
     600           0 :             switch (handlerType) {
     601           0 :                 case DataHandlerType::GPU:
     602           0 :                     return true;
     603             :                     break;
     604           0 :                 case DataHandlerType::MAP_GPU:
     605           0 :                     return true;
     606             :                     break;
     607           0 :                 default:
     608           0 :                     return false;
     609             :             }
     610             :         }
     611             :     }
     612             : 
     613             :     template <typename data_t>
     614           0 :     DataContainer<data_t> clip(DataContainer<data_t> dc, data_t min, data_t max)
     615             :     {
     616           0 :         std::transform(dc.begin(), dc.end(), dc.begin(), [&](auto x) {
     617           0 :             if (x < min) {
     618           0 :                 return min;
     619           0 :             } else if (x > max) {
     620           0 :                 return max;
     621             :             } else {
     622           0 :                 return x;
     623             :             }
     624             :         });
     625             : 
     626           0 :         return dc;
     627             :     }
     628             : 
     629             :     template <typename data_t>
     630           0 :     DataContainer<data_t> concatenate(const DataContainer<data_t>& dc1,
     631             :                                       const DataContainer<data_t>& dc2)
     632             :     {
     633           0 :         auto desc1 = dc1.getDataDescriptor().clone();
     634           0 :         auto desc2 = dc2.getDataDescriptor().clone();
     635             : 
     636           0 :         if (desc1->getNumberOfDimensions() != desc2->getNumberOfDimensions()) {
     637           0 :             throw LogicError("Can't concatenate two DataContainers with different dimension");
     638             :         }
     639             : 
     640           0 :         std::vector<std::unique_ptr<DataDescriptor>> descriptors;
     641           0 :         descriptors.reserve(2);
     642           0 :         descriptors.push_back(std::move(desc1));
     643           0 :         descriptors.push_back(std::move(desc2));
     644             : 
     645           0 :         auto blockDesc = RandomBlocksDescriptor(descriptors);
     646           0 :         auto concatenated = DataContainer<data_t>(blockDesc);
     647             : 
     648           0 :         concatenated.getBlock(0) = dc1;
     649           0 :         concatenated.getBlock(1) = dc2;
     650           0 :         return concatenated;
     651           0 :     }
     652             : 
     653             :     template <typename data_t>
     654           0 :     DataContainer<data_t> fftShift2D(DataContainer<data_t> dc)
     655             :     {
     656           0 :         assert(dc.getDataDescriptor().getNumberOfDimensions() == 2
     657             :                && "DataContainer::fftShift2D: currently only supporting 2D signals");
     658             : 
     659           0 :         const DataDescriptor& dataDescriptor = dc.getDataDescriptor();
     660           0 :         IndexVector_t numOfCoeffsPerDim = dataDescriptor.getNumberOfCoefficientsPerDimension();
     661           0 :         index_t m = numOfCoeffsPerDim[0];
     662           0 :         index_t n = numOfCoeffsPerDim[1];
     663             : 
     664           0 :         index_t firstShift = m / 2;
     665           0 :         index_t secondShift = n / 2;
     666             : 
     667           0 :         DataContainer<data_t> copyDC(dataDescriptor);
     668             : 
     669           0 :         for (index_t i = 0; i < m; ++i) {
     670           0 :             for (index_t j = 0; j < n; ++j) {
     671           0 :                 copyDC((i + firstShift) % m, (j + secondShift) % n) = dc(i, j);
     672             :             }
     673             :         }
     674             : 
     675           0 :         return copyDC;
     676           0 :     }
     677             : 
     678             :     template <typename data_t>
     679           0 :     DataContainer<data_t> ifftShift2D(DataContainer<data_t> dc)
     680             :     {
     681           0 :         assert(dc.getDataDescriptor().getNumberOfDimensions() == 2
     682             :                && "DataContainer::ifftShift2D: currently only supporting 2D signals");
     683             : 
     684           0 :         const DataDescriptor& dataDescriptor = dc.getDataDescriptor();
     685           0 :         IndexVector_t numOfCoeffsPerDim = dataDescriptor.getNumberOfCoefficientsPerDimension();
     686           0 :         index_t m = numOfCoeffsPerDim[0];
     687           0 :         index_t n = numOfCoeffsPerDim[1];
     688             : 
     689           0 :         index_t firstShift = -m / 2;
     690           0 :         index_t secondShift = -n / 2;
     691             : 
     692           0 :         DataContainer<data_t> copyDC(dataDescriptor);
     693             : 
     694           0 :         for (index_t i = 0; i < m; ++i) {
     695           0 :             for (index_t j = 0; j < n; ++j) {
     696           0 :                 index_t leftIndex = (((i + firstShift) % m) + m) % m;
     697           0 :                 index_t rightIndex = (((j + secondShift) % n) + n) % n;
     698           0 :                 copyDC(leftIndex, rightIndex) = dc(i, j);
     699             :             }
     700             :         }
     701             : 
     702           0 :         return copyDC;
     703           0 :     }
     704             : 
     705             :     // ------------------------------------------
     706             :     // explicit template instantiation
     707             :     template class DataContainer<float>;
     708             :     template class DataContainer<complex<float>>;
     709             :     template class DataContainer<double>;
     710             :     template class DataContainer<complex<double>>;
     711             :     template class DataContainer<index_t>;
     712             : 
     713             :     template DataContainer<float> clip<float>(DataContainer<float> dc, float min, float max);
     714             :     template DataContainer<double> clip<double>(DataContainer<double> dc, double min, double max);
     715             : 
     716             :     template DataContainer<float> concatenate<float>(const DataContainer<float>&,
     717             :                                                      const DataContainer<float>&);
     718             :     template DataContainer<double> concatenate<double>(const DataContainer<double>&,
     719             :                                                        const DataContainer<double>&);
     720             :     template DataContainer<complex<float>>
     721             :         concatenate<complex<float>>(const DataContainer<complex<float>>&,
     722             :                                     const DataContainer<complex<float>>&);
     723             :     template DataContainer<complex<double>>
     724             :         concatenate<complex<double>>(const DataContainer<complex<double>>&,
     725             :                                      const DataContainer<complex<double>>&);
     726             : 
     727             :     template DataContainer<float> fftShift2D<float>(DataContainer<float>);
     728             :     template DataContainer<complex<float>>
     729             :         fftShift2D<complex<float>>(DataContainer<complex<float>>);
     730             :     template DataContainer<double> fftShift2D<double>(DataContainer<double>);
     731             :     template DataContainer<complex<double>>
     732             :         fftShift2D<complex<double>>(DataContainer<complex<double>>);
     733             : 
     734             :     template DataContainer<float> ifftShift2D<float>(DataContainer<float>);
     735             :     template DataContainer<complex<float>>
     736             :         ifftShift2D<complex<float>>(DataContainer<complex<float>>);
     737             :     template DataContainer<double> ifftShift2D<double>(DataContainer<double>);
     738             :     template DataContainer<complex<double>>
     739             :         ifftShift2D<complex<double>>(DataContainer<complex<double>>);
     740             : 
     741             : } // namespace elsa

Generated by: LCOV version 1.14