@@ -95,9 +95,72 @@ bool is_directory(const std::string& path) {
9595 return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY));
9696}
9797
98+ class MmapWrapperImpl : public MmapWrapper {
99+ public:
100+ MmapWrapperImpl (void * data, size_t size, HANDLE hfile, HANDLE hmapping)
101+ : MmapWrapper(data, size), hfile_(hfile), hmapping_(hmapping) {}
102+
103+ ~MmapWrapperImpl () override {
104+ UnmapViewOfFile (data_);
105+ CloseHandle (hmapping_);
106+ CloseHandle (hfile_);
107+ }
108+
109+ private:
110+ HANDLE hfile_;
111+ HANDLE hmapping_;
112+ };
113+
114+ std::shared_ptr<MmapWrapper> MmapWrapper::create (const std::string& filename) {
115+ void * mapped_data = nullptr ;
116+ size_t file_size = 0 ;
117+
118+ HANDLE file_handle = CreateFileA (
119+ filename.c_str (),
120+ GENERIC_READ,
121+ FILE_SHARE_READ,
122+ NULL ,
123+ OPEN_EXISTING,
124+ FILE_ATTRIBUTE_NORMAL,
125+ NULL
126+ );
127+
128+ if (file_handle == INVALID_HANDLE_VALUE) {
129+ return nullptr ;
130+ }
131+
132+ LARGE_INTEGER size;
133+ if (!GetFileSizeEx (file_handle, &size)) {
134+ CloseHandle (file_handle);
135+ return nullptr ;
136+ }
137+
138+ file_size = static_cast <size_t >(size.QuadPart );
139+
140+ HANDLE mapping_handle = CreateFileMapping (file_handle, NULL , PAGE_READONLY, 0 , 0 , NULL );
141+
142+ if (mapping_handle == NULL ) {
143+ CloseHandle (file_handle);
144+ return nullptr ;
145+ }
146+
147+ mapped_data = MapViewOfFile (mapping_handle, FILE_MAP_READ, 0 , 0 , file_size);
148+
149+ if (mapped_data == NULL ) {
150+ CloseHandle (mapping_handle);
151+ CloseHandle (file_handle);
152+ return nullptr ;
153+ }
154+
155+ return std::make_shared<MmapWrapperImpl>(mapped_data, file_size, file_handle, mapping_handle);
156+ }
157+
98158#else // Unix
99159#include < dirent.h>
160+ #include < fcntl.h>
161+ #include < sys/mman.h>
100162#include < sys/stat.h>
163+ #include < unistd.h>
101164
102165bool file_exists (const std::string& filename) {
103166 struct stat buffer;
@@ -109,8 +172,64 @@ bool is_directory(const std::string& path) {
109172 return (stat (path.c_str (), &buffer) == 0 && S_ISDIR (buffer.st_mode ));
110173}
111174
175+ class MmapWrapperImpl : public MmapWrapper {
176+ public:
177+ MmapWrapperImpl (void * data, size_t size) : MmapWrapper(data, size) {}
178+
179+ ~MmapWrapperImpl () override {
180+ munmap (data_, size_);
181+ }
182+ };
183+
184+ std::shared_ptr<MmapWrapper> MmapWrapper::create (const std::string& filename) {
185+
186+ int file_descriptor = open (filename.c_str (), O_RDONLY);
187+ if (file_descriptor == -1 ) {
188+ return nullptr ;
189+ }
190+
191+ int mmap_flags = MAP_PRIVATE;
192+
193+ #ifdef __linux__
194+ // performance flags used by llama.cpp
195+ // posix_fadvise(file_descriptor, 0, 0, POSIX_FADV_SEQUENTIAL);
196+ // mmap_flags |= MAP_POPULATE;
197+ #endif
198+
199+ struct stat sb;
200+ if (fstat (file_descriptor, &sb) == -1 ) {
201+ close (file_descriptor);
202+ return nullptr ;
203+ }
204+
205+ size_t file_size = sb.st_size ;
206+
207+ void * mapped_data = mmap (NULL , file_size, PROT_READ, mmap_flags, file_descriptor, 0 );
208+
209+ close (file_descriptor);
210+
211+ if (mapped_data == MAP_FAILED) {
212+ return nullptr ;
213+ }
214+
215+ #ifdef __linux__
216+ // performance flags used by llama.cpp
217+ // posix_madvise(mapped_data, file_size, POSIX_MADV_WILLNEED);
218+ #endif
219+
220+ return std::make_shared<MmapWrapperImpl>(mapped_data, file_size);
221+ }
222+
112223#endif
113224
225+ bool MmapWrapper::copy_data (void * buf, size_t n, size_t offset) const {
226+ if (offset >= size_ || n > (size_ - offset)) {
227+ return false ;
228+ }
229+ std::memcpy (buf, data () + offset, n);
230+ return true ;
231+ }
232+
114233// get_num_physical_cores is copy from
115234// https://github.com/ggerganov/llama.cpp/blob/master/examples/common.cpp
116235// LICENSE: https://github.com/ggerganov/llama.cpp/blob/master/LICENSE
0 commit comments