binary_archive.hpp 6.16 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//| Copyright Inria May 2015
//| This project has received funding from the European Research Council (ERC) under
//| the European Union's Horizon 2020 research and innovation programme (grant
//| agreement No 637972) - see http://www.resibots.eu
//|
//| Contributor(s):
//|   - Jean-Baptiste Mouret (jean-baptiste.mouret@inria.fr)
//|   - Antoine Cully (antoinecully@gmail.com)
//|   - Konstantinos Chatzilygeroudis (konstantinos.chatzilygeroudis@inria.fr)
//|   - Federico Allocati (fede.allocati@gmail.com)
//|   - Vaios Papaspyros (b.papaspyros@gmail.com)
//|   - Roberto Rama (bertoski@gmail.com)
//|
//| This software is a computer library whose purpose is to optimize continuous,
//| black-box functions. It mainly implements Gaussian processes and Bayesian
//| optimization.
//| Main repository: http://github.com/resibots/limbo
//| Documentation: http://www.resibots.eu/limbo
//|
//| This software is governed by the CeCILL-C license under French law and
//| abiding by the rules of distribution of free software.  You can  use,
//| modify and/ or redistribute the software under the terms of the CeCILL-C
//| license as circulated by CEA, CNRS and INRIA at the following URL
//| "http://www.cecill.info".
//|
//| As a counterpart to the access to the source code and  rights to copy,
//| modify and redistribute granted by the license, users are provided only
//| with a limited warranty  and the software's author,  the holder of the
//| economic rights,  and the successive licensors  have only  limited
//| liability.
//|
//| In this respect, the user's attention is drawn to the risks associated
//| with loading,  using,  modifying and/or developing or reproducing the
//| software by the user in light of its specific status of free software,
//| that may mean  that it is complicated to manipulate,  and  that  also
//| therefore means  that it is reserved for developers  and  experienced
//| professionals having in-depth computer knowledge. Users are therefore
//| encouraged to load and test the software's suitability as regards their
//| requirements in conditions enabling the security of their systems and/or
//| data to be ensured and,  more generally, to use and operate it in the
//| same conditions as regards security.
//|
//| The fact that you are presently reading this means that you have had
//| knowledge of the CeCILL-C license and that you accept its terms.
//|
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>

// Quick hack for definition of 'I' in <complex.h>
#undef I
#include <boost/filesystem.hpp>

#include <Eigen/Core>

namespace limbo {
    namespace serialize {

        class BinaryArchive {
        public:
            BinaryArchive(const std::string& dir_name) : _dir_name(dir_name) {}

            /// write an Eigen::Matrix*
65
            void save(const Eigen::MatrixXd& v, const std::string& object_name) const
66
67
68
69
70
71
72
73
74
75
            {
                _create_directory();

                std::ofstream out(fname(object_name).c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
                _write_binary(out, v);
                out.close();
            }

            /// write a vector of Eigen::Vector*
            template <typename T>
76
            void save(const std::vector<T>& v, const std::string& object_name) const
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
            {
                _create_directory();

                std::stringstream s;

                int size = v.size();
                s.write((char*)(&size), sizeof(int));
                for (auto& x : v) {
                    _write_binary(s, x);
                }

                std::ofstream out(fname(object_name).c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
                out << s.rdbuf();
                out.close();
            }

            /// load an Eigen matrix (or vector)
            template <typename M>
95
            void load(M& m, const std::string& object_name) const
96
97
98
99
100
101
102
103
            {
                std::ifstream in(fname(object_name).c_str(), std::ios::in | std::ios::binary);
                _read_binary(in, m);
                in.close();
            }

            /// load a vector of Eigen::Vector*
            template <typename V>
104
            void load(std::vector<V>& m_list, const std::string& object_name) const
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
            {
                m_list.clear();

                std::ifstream in(fname(object_name).c_str(), std::ios::in | std::ios::binary);

                int size;
                in.read((char*)(&size), sizeof(int));

                for (int i = 0; i < size; i++) {
                    V v;
                    _read_binary(in, v);
                    m_list.push_back(v);
                }
                in.close();
                assert(!m_list.empty());
            }

            std::string fname(const std::string& object_name) const
            {
                return _dir_name + "/" + object_name + ".bin";
            }

127
            const std::string& directory() const
128
129
130
131
            {
                return _dir_name;
            }

132
133
134
        protected:
            std::string _dir_name;

135
            void _create_directory() const
136
137
138
139
140
141
            {
                boost::filesystem::path my_path(_dir_name);
                boost::filesystem::create_directory(my_path);
            }

            template <class Matrix, class Stream>
142
            void _write_binary(Stream& out, const Matrix& matrix) const
143
144
145
146
147
148
149
150
            {
                typename Matrix::Index rows = matrix.rows(), cols = matrix.cols();
                out.write((char*)(&rows), sizeof(typename Matrix::Index));
                out.write((char*)(&cols), sizeof(typename Matrix::Index));
                out.write((char*)matrix.data(), rows * cols * sizeof(typename Matrix::Scalar));
            }

            template <class Matrix, class Stream>
151
            void _read_binary(Stream& in, Matrix& matrix) const
152
153
154
155
156
157
158
159
160
161
            {
                typename Matrix::Index rows = 0, cols = 0;
                in.read((char*)(&rows), sizeof(typename Matrix::Index));
                in.read((char*)(&cols), sizeof(typename Matrix::Index));
                matrix.resize(rows, cols);
                in.read((char*)matrix.data(), rows * cols * sizeof(typename Matrix::Scalar));
            }
        };
    } // namespace serialize
} // namespace limbo