@@ -109,9 +109,78 @@ std::string get_full_path(const std::string& dir, const std::string& filename) {
109109 }
110110}
111111
112+ class MmapWrapperImpl : public MmapWrapper {
113+ public:
114+ MmapWrapperImpl (void * data, size_t size, HANDLE hfile, HANDLE hmapping)
115+ : MmapWrapper(data, size), hfile_(hfile), hmapping_(hmapping) {}
116+
117+ ~WindowsMmapWrapper () override {
118+ if (data_) {
119+ UnmapViewOfFile (data_);
120+ }
121+ if (hmapping_ != NULL ) {
122+ CloseHandle (mapping_handle_);
123+ }
124+ if (hfile_ != INVALID_HANDLE_VALUE) {
125+ CloseHandle (file_handle_);
126+ }
127+ }
128+
129+ private:
130+ HANDLE hfile_;
131+ HANDLE hmapping_;
132+ };
133+
134+ std::shared_ptr<MmapWrapper> MmapWrapper::create (const std::string& filename) {
135+ void * mapped_data = nullptr ;
136+ size_t file_size = 0 ;
137+
138+ HANDLE file_handle = CreateFileA (
139+ filename.c_str (),
140+ GENERIC_READ,
141+ FILE_SHARE_READ,
142+ NULL ,
143+ OPEN_EXISTING,
144+ FILE_ATTRIBUTE_NORMAL,
145+ NULL
146+ );
147+
148+ if (file_handle == INVALID_HANDLE_VALUE) {
149+ return nullptr ;
150+ }
151+
152+ LARGE_INTEGER size;
153+ if (!GetFileSizeEx (file_handle, &size)) {
154+ CloseHandle (file_handle);
155+ return nullptr ;
156+ }
157+
158+ file_size = static_cast <size_t >(size.QuadPart );
159+
160+ HANDLE mapping_handle = CreateFileMapping (file_handle, NULL , PAGE_READONLY, 0 , 0 , NULL );
161+
162+ if (mapping_handle == NULL ) {
163+ CloseHandle (file_handle);
164+ return nullptr ;
165+ }
166+
167+ mapped_data = MapViewOfFile (mapping_handle, FILE_MAP_READ, 0 , 0 , file_size);
168+
169+ if (mapped_data == NULL ) {
170+ CloseHandle (mapping_handle);
171+ CloseHandle (file_handle);
172+ return nullptr ;
173+ }
174+
175+ return std::make_shared<MmapWrapperImpl>(mapped_data, file_size, file_handle, mapping_handle);
176+ }
177+
112178#else // Unix
113179#include < dirent.h>
180+ #include < fcntl.h>
181+ #include < sys/mman.h>
114182#include < sys/stat.h>
183+ #include < unistd.h>
115184
116185bool file_exists (const std::string& filename) {
117186 struct stat buffer;
@@ -143,8 +212,66 @@ std::string get_full_path(const std::string& dir, const std::string& filename) {
143212 return " " ;
144213}
145214
215+ class MmapWrapperImpl : public MmapWrapper {
216+ public:
217+ MmapWrapperImpl (void * data, size_t size) : MmapWrapper(data, size) {}
218+
219+ ~MmapWrapperImpl () override {
220+ if (data_) {
221+ munmap (data_, size_);
222+ }
223+ }
224+ };
225+
226+ std::shared_ptr<MmapWrapper> MmapWrapper::create (const std::string& filename) {
227+
228+ int file_descriptor = open (filename.c_str (), O_RDONLY);
229+ if (file_descriptor == -1 ) {
230+ return nullptr ;
231+ }
232+
233+ int mmap_flags = MAP_PRIVATE;
234+
235+ #ifdef __linux__
236+ // performance flags used by llama.cpp
237+ // posix_fadvise(file_descriptor, 0, 0, POSIX_FADV_SEQUENTIAL);
238+ // mmap_flags |= MAP_POPULATE;
239+ #endif
240+
241+ struct stat sb;
242+ if (fstat (file_descriptor, &sb) == -1 ) {
243+ close (file_descriptor);
244+ return nullptr ;
245+ }
246+
247+ size_t file_size = sb.st_size ;
248+
249+ void * mapped_data = mmap (NULL , file_size, PROT_READ, mmap_flags, file_descriptor, 0 );
250+
251+ close (file_descriptor);
252+
253+ if (mapped_data == MAP_FAILED) {
254+ return nullptr ;
255+ }
256+
257+ #ifdef __linux__
258+ // performance flags used by llama.cpp
259+ // posix_madvise(mapped_data, file_size, POSIX_MADV_WILLNEED);
260+ #endif
261+
262+ return std::make_shared<MmapWrapperImpl>(mapped_data, file_size);
263+ }
264+
146265#endif
147266
267+ bool MmapWrapper::copy_data (void * buf, size_t n, size_t offset) const {
268+ if (offset >= size_ || n > (size_ - offset)) {
269+ return false ;
270+ }
271+ std::memcpy (buf, data () + offset, n);
272+ return true ;
273+ }
274+
148275// get_num_physical_cores is copy from
149276// https://github.com/ggerganov/llama.cpp/blob/master/examples/common.cpp
150277// LICENSE: https://github.com/ggerganov/llama.cpp/blob/master/LICENSE
0 commit comments