QDataStream serialize/deserialize eigen SparseMatrix (cpp)

61 Views Asked by At

My final goal is to save/load eigen sparse matrix on disk and compress it using QDatastream. My code for deserializing doesn't compile and i don't know the reason. my code :


// this overload compile
template <typename TempDI_, int whatever, typename IND>
inline QDataStream& operator <<(QDataStream &out, const Eigen::SparseMatrix<TempDI_, whatever, IND>& m)
{
    m.makeCompressed();
    IND rows, cols, nnzs, outS, innS;
    rows = m.rows()     ;
    cols = m.cols()     ;
    nnzs = m.nonZeros() ;
    outS = m.outerSize();
    innS = m.innerSize();

    out.writeBytes((const char *)&(rows), sizeof(IND));
    out.writeBytes((const char *)&(cols), sizeof(IND));
    out.writeBytes((const char *)&(nnzs), sizeof(IND));
    out.writeBytes((const char *)&(innS), sizeof(IND));
    out.writeBytes((const char *)&(outS), sizeof(IND));

    out.writeBytes((const char *)(m.valuePtr()),       sizeof(TempDI_  ) * m.nonZeros());
    out.writeBytes((const char *)(m.outerIndexPtr()),  sizeof(IND) * m.outerSize());
    out.writeBytes((const char *)(m.innerIndexPtr()),  sizeof(IND) * m.nonZeros());

    return out;
}

// doesn't compile
template <typename TempDI_, int whatever, typename IND>
inline QDataStream &operator>>(QDataStream &in, Eigen::SparseMatrix<TempDI_, whatever, IND>& m)
{
    IND rows, cols, nnz, inSz, outSz;
    uint len;

    len= sizeof(IND);
    char* ind;
    in.readBytes(ind, len);
    rows = (IND)*ind;

    in.readBytes(ind, len);
    cols = (IND)*ind;

    in.readBytes(ind, len);
    nnz = (IND)*ind;

    in.readBytes(ind, len);
    inSz = (IND)*ind;

    in.readBytes(ind, len);
    outSz = (IND)*ind;

    m.resize(rows, cols);
    m.makeCompressed();
    m.resizeNonZeros(nnz);

    // compiling error :  error: cannot bind non-const lvalue reference of type 'char*&' to an rvalue of type 'char*'
    in.readBytes((char*)(m.valuePtr())     , sizeof(TempDI_  ) * nnz  );
    
    // compiling error :  error: invalid cast of an rvalue expression of type 'Eigen::SparseMatrix<int, 0, int>::StorageIndex*' {aka 'int*'} to type 'char*&'
    in.readBytes((char*&)(m.outerIndexPtr()), sizeof(IND) * outSz);

    // compiling error : error: cannot bind non-const lvalue reference of type 'char*&' to an rvalue of type 'char*'
    in.readBytes((char*)(m.innerIndexPtr()), sizeof(IND) * nnz );


    m.finalize();
}

I have another code to serialize/deserialize to file using stdlib that works perfectly :

template <typename TempDI, int whatever, typename IND>
    static void Serialize(QString path, Eigen::SparseMatrix<TempDI, whatever, IND>& m)
    {
        m.makeCompressed();

        std::fstream writeFile;
        writeFile.open(path.toStdString(), std::ios::binary | std::ios::out);

        if(writeFile.is_open())
        {
            IND rows, cols, nnzs, outS, innS;
            rows = m.rows()     ;
            cols = m.cols()     ;
            nnzs = m.nonZeros() ;
            outS = m.outerSize();
            innS = m.innerSize();

            writeFile.write((const char *)&(rows), sizeof(IND));
            writeFile.write((const char *)&(cols), sizeof(IND));
            writeFile.write((const char *)&(nnzs), sizeof(IND));
            writeFile.write((const char *)&(innS), sizeof(IND));
            writeFile.write((const char *)&(outS), sizeof(IND));

            writeFile.write((const char *)(m.valuePtr()),       sizeof(TempDI  ) * m.nonZeros());
            writeFile.write((const char *)(m.outerIndexPtr()),  sizeof(IND) * m.outerSize());
            writeFile.write((const char *)(m.innerIndexPtr()),  sizeof(IND) * m.nonZeros());

            writeFile.close();
        }

    };

    template <typename TempDI, int whatever, typename IND>
    static void Deserialize(QString path, Eigen::SparseMatrix<TempDI, whatever, IND>& m)
    {
        std::fstream readFile;
        readFile.open(path.toStdString(), std::ios::binary | std::ios::in);
        if(readFile.is_open())
        {
            IND rows, cols, nnz, inSz, outSz;
            readFile.read((char*)&rows , sizeof(IND));
            readFile.read((char*)&cols , sizeof(IND));
            readFile.read((char*)&nnz  , sizeof(IND));
            readFile.read((char*)&inSz , sizeof(IND));
            readFile.read((char*)&outSz, sizeof(IND));

            m.resize(rows, cols);
            m.makeCompressed();
            m.resizeNonZeros(nnz);

            readFile.read((char*)(m.valuePtr())     , sizeof(TempDI  ) * nnz  );
            readFile.read((char*)(m.outerIndexPtr()), sizeof(IND) * outSz);
            readFile.read((char*)(m.innerIndexPtr()), sizeof(IND) * nnz );

            m.finalize();

            readFile.close();
        }

         //qDebug()<<"Deserialize OK";
    };

I don't understand why i have compiling errors. Could someone please explain me? and eventually solve my problem Thank you for you help

I've also tried a lot of different casting without success.

0

There are 0 best solutions below