JeffersonLab / qphix

QCD for Intel Xeon Phi and Xeon processors
http://jeffersonlab.github.io/qphix/
Other
13 stars 11 forks source link

RAII Container for Spinors (and Clover) #35

Closed martin-ueding closed 7 years ago

martin-ueding commented 7 years ago

In the QPhiX testing code, there a lot of manually managed resources, like this:

Spinor* psi_even=(Spinor*)geom.allocCBFourSpinor();
Spinor* psi_odd=(Spinor*)geom.allocCBFourSpinor();
Spinor* chi_even=(Spinor*)geom.allocCBFourSpinor();
Spinor* chi_odd=(Spinor*)geom.allocCBFourSpinor();

At the end of the function, there are cleanup calls:

geom.free(psi_even);
geom.free(psi_odd);
geom.free(chi_even);
geom.free(chi_odd);

I believe that we should leverage RAII for those objects in order to make programming easier and safer. Basically one needs some sort of unique_ptr<FourSpinorBlock[]> with a custom deleter, namely geom.free(). The following is a simple implementation:

/**
  RAII container for checkerboarded four spinors.

  The four spinors are C-style arrays with no length information and most
  importantly no cleanup. This wrapper enables automatic cleanup using the
  QPhiX::Geometry object.

  Perhaps it would be even better to use `std::vector` with a custom allocator
  for this structure.
  */
template <typename FT, int veclen, int soalen, bool compress12>
class FourSpinorCBWrapper {
 public:
  typedef
      typename ::QPhiX::Geometry<FT, veclen, soalen, compress12>::FourSpinorBlock FourSpinorBlock;

  FourSpinorCBWrapper(::QPhiX::Geometry<FT, veclen, soalen, compress12> &geom_)
      : geom(geom_), spinor(geom.allocCBFourSpinor()) {}

  ~FourSpinorCBWrapper() { geom.free(spinor); }

  FourSpinorBlock const *data() const { return spinor; }
  FourSpinorBlock *data() { return spinor; }

  size_t num_blocks() const { return geom.get_num_blocks(); }

 private:
  ::QPhiX::Geometry<FT, veclen, soalen, compress12> &geom;
  FourSpinorBlock *const spinor;
};

There are a couple of types that could need such a RAII wrapper:

Perhaps one wants to implement the operator*() and operator[] in order to use it just like a raw pointer. Perhaps the factory functions in the Geometry class could return such a handle instead of a raw owning pointer?

martin-ueding commented 7 years ago

Those are now implemented by adding them, one does not have to use them. I will use them in my new test cases.