diff --git a/runtime/src/iree/base/config.h b/runtime/src/iree/base/config.h index 1c87930baade..105ad1766a3c 100644 --- a/runtime/src/iree/base/config.h +++ b/runtime/src/iree/base/config.h @@ -128,6 +128,8 @@ typedef IREE_DEVICE_SIZE_T iree_device_size_t; //===----------------------------------------------------------------------===// // Synchronization and threading //===----------------------------------------------------------------------===// + +#if !defined(IREE_SYNCHRONIZATION_DISABLE_UNSAFE) // On ultra-tiny systems where there may only be a single core - or a single // core that is guaranteed to ever call an IREE API - all synchronization // primitives used throughout IREE can be turned into no-ops. Note that behavior @@ -135,31 +137,46 @@ typedef IREE_DEVICE_SIZE_T iree_device_size_t; // owned by IREE from multiple threads concurrently or across threads without // proper barriers in place. Unless your target system is in a similar class to // an Arduino this is definitely not what you want. - -#if !defined(IREE_SYNCHRONIZATION_DISABLE_UNSAFE) #define IREE_SYNCHRONIZATION_DISABLE_UNSAFE 0 #endif // !IREE_SYNCHRONIZATION_DISABLE_UNSAFE //===----------------------------------------------------------------------===// // File I/O //===----------------------------------------------------------------------===// + +#if !defined(IREE_FILE_IO_ENABLE) // On platforms without file systems or in applications where no file I/O // utilities are used, all file I/O operations can be stripped out. Functions // relying on file I/O will still be defined, but they will return errors. - -#if !defined(IREE_FILE_IO_ENABLE) #define IREE_FILE_IO_ENABLE 1 #endif // !IREE_FILE_IO_ENABLE +#if !defined(IREE_MAX_PATH) +// Maximum path C string length in characters excluding the NUL terminator. +// We stack allocate the path and want to keep it small enough to reasonably +// fit on any particular thread's stack (which may be as small as 64KB and we +// don't know who may be in the call stack above us). +// +// PATH_MAX is linux-only but _sometimes_ available on other platforms we use +// this code path for. Only when it's available it may indicate the PATH_MAX +// with _or_ without the NUL terminator. If we guess too large here the platform +// will fail as it scans the path and if we guess too small then users may want +// to re-evaluate their usage of the filesystem. +// +// MAX_PATH is 260 but most systems nowadays have long paths enabled and we +// don't want to limit ourselves to that. +#define IREE_MAX_PATH 2047 +#endif // !IREE_MAX_PATH + //===----------------------------------------------------------------------===// // Statistics/reporting //===----------------------------------------------------------------------===// + +#if !defined(IREE_STATISTICS_ENABLE) // Conditionally enables programmatic access to aggregate statistics. When // enabled statistics requires additional per-operation logic and per-resource // state that can bloat otherwise minimal structures. Shared resources may also // require synchronization where there otherwise would not be any. - -#if !defined(IREE_STATISTICS_ENABLE) #define IREE_STATISTICS_ENABLE 1 #endif // !IREE_STATISTICS_ENABLE @@ -173,6 +190,7 @@ typedef IREE_DEVICE_SIZE_T iree_device_size_t; // Specify a custom header with `-DIREE_TRACING_PROVIDER_H="my_provider.h"`. // Specify a dependency with `-DIREE_TRACING_PROVIDER=my_provider_target`. +#if !defined(IREE_TRACING_MODE) // Set IREE_TRACING_FEATURES based on IREE_TRACING_MODE if the user hasn't // overridden it with more specific settings. // @@ -181,7 +199,6 @@ typedef IREE_DEVICE_SIZE_T iree_device_size_t; // IREE_TRACING_MODE = 2: same as 1 with added allocation tracking // IREE_TRACING_MODE = 3: same as 2 with callstacks for allocations // IREE_TRACING_MODE = 4: same as 3 with callstacks for all instrumentation -#if !defined(IREE_TRACING_MODE) #define IREE_TRACING_MODE 0 #endif // !IREE_TRACING_MODE diff --git a/runtime/src/iree/base/internal/file_io.h b/runtime/src/iree/base/internal/file_io.h index 7f64b583061c..85b55c699e59 100644 --- a/runtime/src/iree/base/internal/file_io.h +++ b/runtime/src/iree/base/internal/file_io.h @@ -48,6 +48,8 @@ void iree_file_contents_free(iree_file_contents_t* contents); typedef enum iree_file_read_flag_bits_t { IREE_FILE_READ_FLAG_PRELOAD = (1u << 0), + // TODO(benvanik): drop this (and possibly all file utilities) in favor of + // iree_io_file_handle_t + iree_io_file_map_view. IREE_FILE_READ_FLAG_MMAP = (1u << 1), IREE_FILE_READ_FLAG_DEFAULT = IREE_FILE_READ_FLAG_PRELOAD, } iree_file_read_flags_t; diff --git a/runtime/src/iree/io/file_handle.c b/runtime/src/iree/io/file_handle.c index 40d5f8562b2d..9a6727bcf31c 100644 --- a/runtime/src/iree/io/file_handle.c +++ b/runtime/src/iree/io/file_handle.c @@ -12,11 +12,13 @@ #if IREE_FILE_IO_ENABLE #if defined(IREE_PLATFORM_WINDOWS) +#include // _open_osfhandle constants #include // _commit #include // WerRegisterExcludedMemoryBlock #else +#include // open #include // mmap #include // fstat #include // fsync @@ -160,6 +162,287 @@ iree_io_file_handle_flush(iree_io_file_handle_t* handle) { return status; } +//===----------------------------------------------------------------------===// +// iree_io_file_handle_t utilities +//===----------------------------------------------------------------------===// + +#if IREE_FILE_IO_ENABLE + +#if defined(IREE_PLATFORM_WINDOWS) + +static iree_status_t iree_io_file_handle_platform_open( + iree_io_file_mode_t mode, iree_string_view_t path, bool open_existing, + uint64_t initial_size, + iree_io_file_handle_primitive_t* out_handle_primitive) { + IREE_ASSERT_ARGUMENT(out_handle_primitive); + memset(out_handle_primitive, 0, sizeof(*out_handle_primitive)); + + // Convert path from a string view to a NUL-terminated C string. + if (path.size >= IREE_MAX_PATH) { + return iree_make_status(IREE_STATUS_OUT_OF_RANGE, + "path length %" PRIhsz + " exceeds maximum character length of %d", + path.size, IREE_MAX_PATH); + } + char* path_str = iree_alloca(path.size + 1); + iree_string_view_to_cstring(path, path_str, path.size + 1); + + DWORD desired_access = 0; + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_READ)) { + desired_access |= GENERIC_READ; + } + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_WRITE)) { + desired_access |= GENERIC_WRITE; + } + + DWORD share_mode = 0; + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_SHARE_READ)) { + share_mode |= FILE_SHARE_READ; + } + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_SHARE_WRITE)) { + share_mode |= FILE_SHARE_WRITE; + } + + DWORD creation_disposition = open_existing ? OPEN_EXISTING : CREATE_ALWAYS; + + DWORD flags = FILE_ATTRIBUTE_NORMAL; + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_RANDOM_ACCESS)) { + flags |= FILE_FLAG_RANDOM_ACCESS; + } else if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_SEQUENTIAL_SCAN)) { + flags |= FILE_FLAG_SEQUENTIAL_SCAN; + } + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_TEMPORARY)) { + flags |= FILE_FLAG_DELETE_ON_CLOSE; + } + + // Create or open the file. + HANDLE handle = CreateFileA(path_str, desired_access, share_mode, NULL, + creation_disposition, flags, NULL); + if (handle == INVALID_HANDLE_VALUE) { + return iree_make_status(iree_status_code_from_win32_error(GetLastError()), + "failed to open file '%.*s'", (int)path.size, + path.data); + } + + // If we were provided an initialize size and are creating the file then + // adjust the file length. + if (!open_existing) { + // Zeroish-extend the file up to the total file size specified by the + // caller. This may be larger than the virtual address space can handle but + // so long as the length requested for mapping is under the size_t limit + // this will succeed. + LARGE_INTEGER file_size = {0}; + file_size.QuadPart = initial_size; + if (!SetFilePointerEx(handle, file_size, NULL, FILE_BEGIN) || + !SetEndOfFile(handle)) { + CloseHandle(handle); + return iree_make_status(iree_status_code_from_win32_error(GetLastError()), + "failed to extend file '%.*s' to %" PRIu64 + " bytes (out of disk space or permission denied)", + (int)path.size, path.data, initial_size); + } + } + + // Transfer ownership of the handle to a CRT file descriptor. + // After this succeeds we cannot call CloseHandle as the CRT owns it. + int open_flags = 0; + if (!iree_all_bits_set(mode, IREE_IO_FILE_MODE_WRITE)) { + open_flags |= _O_RDONLY; + } + int fd = _open_osfhandle((intptr_t)handle, open_flags); + if (fd == -1) { + CloseHandle(handle); // must close since we didn't transfer + return iree_make_status( + IREE_STATUS_INTERNAL, + "unable to transfer Win32 HANDLE to a CRT file descriptor"); + } + + out_handle_primitive->type = IREE_IO_FILE_HANDLE_TYPE_FD; + out_handle_primitive->value.fd = fd; + return iree_ok_status(); +} + +static void iree_io_file_handle_platform_close( + void* user_data, iree_io_file_handle_primitive_t handle_primitive) { + // NOTE: we opened the file using Win32 APIs but it's safe to _close since we + // transferred ownership to the CRT with _open_osfhandle. If we used + // IREE_IO_FILE_HANDLE_TYPE_WIN32_HANDLE we'd want to switch on that instead. + IREE_ASSERT_EQ(handle_primitive.type, IREE_IO_FILE_HANDLE_TYPE_FD); + _close(handle_primitive.value.fd); +} + +#else + +static iree_status_t iree_io_file_handle_platform_open( + iree_io_file_mode_t mode, iree_string_view_t path, bool open_existing, + uint64_t initial_size, + iree_io_file_handle_primitive_t* out_handle_primitive) { + IREE_ASSERT_ARGUMENT(out_handle_primitive); + memset(out_handle_primitive, 0, sizeof(*out_handle_primitive)); + + // Convert path from a string view to a NUL-terminated C string. + if (path.size >= IREE_MAX_PATH) { + return iree_make_status(IREE_STATUS_OUT_OF_RANGE, + "path length %" PRIhsz + " exceeds maximum character length of %d", + path.size, IREE_MAX_PATH); + } + char* path_str = iree_alloca(path.size + 1); + iree_string_view_to_cstring(path, path_str, path.size + 1); + + int flags = 0; + // TODO(benvanik): add a flag for forking behavior. + flags |= O_CLOEXEC; + if (!open_existing) { + // If the file exists open anyway and truncate as if it had been recreated. + // This matches Win32 CREATE_ALWAYS behavior. + flags |= O_CREAT | O_TRUNC; + } + if (iree_all_bits_set(mode, + IREE_IO_FILE_MODE_READ | IREE_IO_FILE_MODE_WRITE)) { + // NOTE: O_RDWR != O_RDONLY | O_WRONLY! + flags |= O_RDWR; + } else if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_READ)) { + flags |= O_RDONLY; + } else if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_WRITE)) { + flags |= O_WRONLY; + } +#if defined(O_DIRECT) + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_DIRECT)) { + flags |= O_DIRECT; + } +#endif // O_DIRECT +#if defined(O_TMPFILE) + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_TEMPORARY)) { + flags |= O_TMPFILE; + } +#endif // O_TMPFILE + + // I don't know, unix file permissions are dumb. User and group seems fine? + const mode_t open_mode = (S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP); + + int fd = open(path_str, flags, open_mode); + if (fd == -1) { + return iree_make_status(iree_status_code_from_errno(errno), + "failed to open file '%.*s'", (int)path.size, + path.data); + } + + // If we were provided an initialize size and are creating the file then + // adjust the file length. + if (!open_existing) { + // Zero-extend the file up to the total file size specified by the + // caller. Note that `ftruncate` extends too. + if (ftruncate(fd, (off_t)initial_size) == -1) { + return iree_make_status(iree_status_code_from_errno(errno), + "failed to extend file '%.*s' to %" PRIu64 + " bytes (out of disk space or permission denied)", + (int)path.size, path.data, initial_size); + } + } + + out_handle_primitive->type = IREE_IO_FILE_HANDLE_TYPE_FD; + out_handle_primitive->value.fd = fd; + return iree_ok_status(); +} + +static void iree_io_file_handle_platform_close( + void* user_data, iree_io_file_handle_primitive_t handle_primitive) { + IREE_ASSERT_EQ(handle_primitive.type, IREE_IO_FILE_HANDLE_TYPE_FD); + close(handle_primitive.value.fd); +} + +#endif // IREE_PLATFORM_WINDOWS + +static iree_status_t iree_io_file_handle_create_or_open( + iree_io_file_mode_t mode, iree_string_view_t path, bool open_existing, + uint64_t initial_size, iree_allocator_t host_allocator, + iree_io_file_handle_t** out_handle) { + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_RANDOM_ACCESS | + IREE_IO_FILE_MODE_SEQUENTIAL_SCAN)) { + return iree_make_status(IREE_STATUS_INVALID_ARGUMENT, + "at most one access pattern hint may be specified"); + } + + iree_io_file_handle_primitive_t handle_primitive = {0}; + IREE_RETURN_IF_ERROR(iree_io_file_handle_platform_open( + mode, path, open_existing, initial_size, &handle_primitive)); + + iree_io_file_access_t allowed_access = 0; + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_READ)) { + allowed_access |= IREE_IO_FILE_ACCESS_READ; + } + if (iree_all_bits_set(mode, IREE_IO_FILE_MODE_WRITE)) { + allowed_access |= IREE_IO_FILE_ACCESS_WRITE; + } + iree_io_file_handle_release_callback_t release_callback = { + .fn = iree_io_file_handle_platform_close, + .user_data = NULL, + }; + iree_io_file_handle_t* handle = NULL; + iree_status_t status = + iree_io_file_handle_wrap(allowed_access, handle_primitive, + release_callback, host_allocator, &handle); + + if (iree_status_is_ok(status)) { + *out_handle = handle; + } else { + release_callback.fn(release_callback.user_data, handle_primitive); + } + return status; +} + +IREE_API_EXPORT iree_status_t iree_io_file_handle_create( + iree_io_file_mode_t mode, iree_string_view_t path, uint64_t initial_size, + iree_allocator_t host_allocator, iree_io_file_handle_t** out_handle) { + IREE_ASSERT_ARGUMENT(out_handle); + *out_handle = NULL; + IREE_TRACE_ZONE_BEGIN(z0); + IREE_TRACE_ZONE_APPEND_TEXT(z0, path.data, path.size); + iree_status_t status = iree_io_file_handle_create_or_open( + mode, path, /*open_existing=*/false, initial_size, host_allocator, + out_handle); + IREE_TRACE_ZONE_END(z0); + return status; +} + +IREE_API_EXPORT iree_status_t iree_io_file_handle_open( + iree_io_file_mode_t mode, iree_string_view_t path, + iree_allocator_t host_allocator, iree_io_file_handle_t** out_handle) { + IREE_ASSERT_ARGUMENT(out_handle); + *out_handle = NULL; + IREE_TRACE_ZONE_BEGIN(z0); + IREE_TRACE_ZONE_APPEND_TEXT(z0, path.data, path.size); + iree_status_t status = iree_io_file_handle_create_or_open( + mode, path, /*open_existing=*/true, 0ull, host_allocator, out_handle); + IREE_TRACE_ZONE_END(z0); + return status; +} + +#else + +IREE_API_EXPORT iree_status_t iree_io_file_handle_create( + iree_io_file_mode_t mode, iree_string_view_t path, uint64_t initial_size, + iree_allocator_t host_allocator, iree_io_file_handle_t** out_handle) { + IREE_ASSERT_ARGUMENT(out_handle); + *out_handle = NULL; + return iree_make_status(IREE_STATUS_UNAVAILABLE, + "file support has been compiled out of this binary; " + "set IREE_FILE_IO_ENABLE=1 to include it"); +} + +IREE_API_EXPORT iree_status_t iree_io_file_handle_open( + iree_io_file_mode_t mode, iree_string_view_t path, + iree_allocator_t host_allocator, iree_io_file_handle_t** out_handle) { + IREE_ASSERT_ARGUMENT(out_handle); + *out_handle = NULL; + return iree_make_status(IREE_STATUS_UNAVAILABLE, + "file support has been compiled out of this binary; " + "set IREE_FILE_IO_ENABLE=1 to include it"); +} + +#endif // IREE_FILE_IO_ENABLE + //===----------------------------------------------------------------------===// // iree_io_file_mapping_t support //===----------------------------------------------------------------------===// diff --git a/runtime/src/iree/io/file_handle.h b/runtime/src/iree/io/file_handle.h index 53e5a37594cc..908f1e7ae81a 100644 --- a/runtime/src/iree/io/file_handle.h +++ b/runtime/src/iree/io/file_handle.h @@ -156,6 +156,57 @@ static inline iree_io_file_handle_primitive_value_t iree_io_file_handle_value( IREE_API_EXPORT iree_status_t iree_io_file_handle_flush(iree_io_file_handle_t* handle); +//===----------------------------------------------------------------------===// +// iree_io_file_handle_t platform files +//===----------------------------------------------------------------------===// + +// Bits indicating how a file is opened. +typedef uint64_t iree_io_file_mode_t; +enum iree_io_file_mode_bits_t { + // Allow reads of both existing and new content. + IREE_IO_FILE_MODE_READ = 1ull << 0, + // Allow writes. + IREE_IO_FILE_MODE_WRITE = 1ull << 1, + // Hints that the file will be accessed at random (more-so than not). + // Mutually exclusive with IREE_IO_FILE_MODE_SEQUENTIAL_SCAN. If no access + // hint is specified the platform will use its default behavior. + IREE_IO_FILE_MODE_RANDOM_ACCESS = 1ull << 2, + // Hints that the file will be accessed sequentially (contiguous reads/writes + // or small skips forward only). + // Mutually exclusive with IREE_IO_FILE_MODE_RANDOM_ACCESS. If no access + // hint is specified the platform will use its default behavior. + IREE_IO_FILE_MODE_SEQUENTIAL_SCAN = 1ull << 3, + // Hints that the library and system caching are not required. May hurt + // performance more than it helps unless the file is very large and + // exclusively accessed as part of bulk transfer operations that are + // page-aligned. + IREE_IO_FILE_MODE_DIRECT = 1ull << 4, + // Ensures the file is deleted when it is closed. Platforms may use this as a + // hint to avoid writing the file contents when cache is available. + IREE_IO_FILE_MODE_TEMPORARY = 1ull << 5, + // Allows subsequent operations to open the file for read access while the + // file is open by the creator. + IREE_IO_FILE_MODE_SHARE_READ = 1ull << 6, + // Allows subsequent operations to open the file for write access while the + // file is open by the creator. + IREE_IO_FILE_MODE_SHARE_WRITE = 1ull << 7, +}; + +// Creates a new platform file at |path| for usage as defined by |mode|. +// The file will be extended to |initial_size| upon creation. +// Returns IREE_STATUS_ALREADY_EXISTS if the file already exists. +// Returns IREE_STATUS_PERMISSION_DENIED if the file cannot be created. +IREE_API_EXPORT iree_status_t iree_io_file_handle_create( + iree_io_file_mode_t mode, iree_string_view_t path, uint64_t initial_size, + iree_allocator_t host_allocator, iree_io_file_handle_t** out_handle); + +// Opens an existing platform file at |path| for usage as defined by |mode|. +// Returns IREE_STATUS_NOT_FOUND if the file does not exist. +// Returns IREE_STATUS_PERMISSION_DENIED if the specified |mode| is disallowed. +IREE_API_EXPORT iree_status_t iree_io_file_handle_open( + iree_io_file_mode_t mode, iree_string_view_t path, + iree_allocator_t host_allocator, iree_io_file_handle_t** out_handle); + //===----------------------------------------------------------------------===// // iree_io_file_mapping_t //===----------------------------------------------------------------------===// diff --git a/runtime/src/iree/io/stdio_stream.c b/runtime/src/iree/io/stdio_stream.c index 3f0fea8bd75e..b190585e5b1b 100644 --- a/runtime/src/iree/io/stdio_stream.c +++ b/runtime/src/iree/io/stdio_stream.c @@ -53,8 +53,6 @@ // iree_io_stdio_stream_t //===----------------------------------------------------------------------===// -#define IREE_MAX_PATH ((size_t)2048) - typedef struct iree_io_stdio_stream_t { iree_io_stream_t base; iree_allocator_t host_allocator; @@ -148,13 +146,15 @@ IREE_API_EXPORT iree_status_t iree_io_stdio_stream_open( // We could heap allocate instead but a few thousand chars is quite long and // since Windows doesn't support more than ~256 we generally keep them short // anyway. - if (path.size > IREE_MAX_PATH) { + if (path.size >= IREE_MAX_PATH) { IREE_TRACE_ZONE_END(z0); - return iree_make_status(IREE_STATUS_RESOURCE_EXHAUSTED, - "path exceeds reasonable maximum (%" PRIhsz - " > %" PRIhsz ")", + return iree_make_status(IREE_STATUS_OUT_OF_RANGE, + "path length %" PRIhsz + " exceeds maximum character length of %d", path.size, IREE_MAX_PATH); } + char* path_str = iree_alloca(path.size + 1); + iree_string_view_to_cstring(path, path_str, path.size + 1); char* fopen_path = (char*)iree_alloca(path.size + 1); memcpy(fopen_path, path.data, path.size); fopen_path[path.size] = 0; // NUL diff --git a/runtime/src/iree/tooling/parameter_util.c b/runtime/src/iree/tooling/parameter_util.c index e311f4ff664a..bd748ad02f17 100644 --- a/runtime/src/iree/tooling/parameter_util.c +++ b/runtime/src/iree/tooling/parameter_util.c @@ -18,13 +18,20 @@ // Parameter file I/O //===----------------------------------------------------------------------===// +#if IREE_FILE_IO_ENABLE +#define FLAG_PARAMETER_MODE_DEFAULT "file" +#else +#define FLAG_PARAMETER_MODE_DEFAULT "mmap" +#endif // IREE_FILE_IO_ENABLE + IREE_FLAG( - string, parameter_mode, "mmap", - "A parameter I/O mode of ['preload', 'mmap'].\n" + string, parameter_mode, FLAG_PARAMETER_MODE_DEFAULT, + "A parameter I/O mode of ['preload', 'mmap', 'file'].\n" " preload: read entire parameter files into wired memory on startup.\n" " mmap: maps the parameter files into discardable memory - can increase\n" " warm-up time and variance as mapped pages are swapped\n" - " by the OS."); + " by the OS.\n" + " file: uses platform file APIs to read/write the file as needed."); static void iree_file_contents_release_callback( void* user_data, iree_io_file_handle_primitive_t handle_primitive) { @@ -32,6 +39,36 @@ static void iree_file_contents_release_callback( iree_file_contents_free(file_contents); } +// Legacy parameter file open path. We should be able to replace this usage with +// iree_io_file_handle_t-based logic. +static iree_status_t iree_io_open_parameter_file_legacy( + iree_string_view_t path, iree_file_read_flags_t read_flags, + iree_allocator_t host_allocator, iree_io_file_handle_t** out_file_handle) { + IREE_ASSERT_ARGUMENT(out_file_handle); + *out_file_handle = NULL; + + char path_str[2048] = {0}; + iree_string_view_to_cstring(path, path_str, sizeof(path_str)); + + // Read (or map) the entire file into host memory. + iree_file_contents_t* file_contents = NULL; + IREE_RETURN_IF_ERROR(iree_file_read_contents(path_str, read_flags, + host_allocator, &file_contents)); + + // Wrap the loaded memory file in a file handle. + const iree_io_file_handle_release_callback_t release_callback = { + .fn = iree_file_contents_release_callback, + .user_data = file_contents, + }; + iree_status_t status = iree_io_file_handle_wrap_host_allocation( + IREE_IO_FILE_ACCESS_READ, file_contents->buffer, release_callback, + host_allocator, out_file_handle); + if (!iree_status_is_ok(status)) { + iree_file_contents_free(file_contents); + } + return status; +} + // Opens the parameter file at |path| with the mode specified by the // --parameter_mode flag and returns its handle. static iree_status_t iree_io_open_parameter_file( @@ -42,37 +79,25 @@ static iree_status_t iree_io_open_parameter_file( IREE_TRACE_ZONE_BEGIN(z0); IREE_TRACE_ZONE_APPEND_TEXT(z0, path.data, path.size); - char path_str[2048] = {0}; - iree_string_view_to_cstring(path, path_str, sizeof(path_str)); - iree_file_read_flags_t read_flags = 0; + iree_status_t status = iree_ok_status(); + iree_io_file_handle_t* file_handle = NULL; if (strcmp(FLAG_parameter_mode, "mmap") == 0) { - read_flags |= IREE_FILE_READ_FLAG_MMAP; + status = iree_io_open_parameter_file_legacy(path, IREE_FILE_READ_FLAG_MMAP, + host_allocator, &file_handle); } else if (strcmp(FLAG_parameter_mode, "preload") == 0) { - read_flags |= IREE_FILE_READ_FLAG_PRELOAD; + status = iree_io_open_parameter_file_legacy( + path, IREE_FILE_READ_FLAG_PRELOAD, host_allocator, &file_handle); + } else if (strcmp(FLAG_parameter_mode, "file") == 0) { + status = iree_io_file_handle_open(IREE_IO_FILE_MODE_READ, path, + host_allocator, &file_handle); } else { - IREE_TRACE_ZONE_END(z0); - return iree_make_status(IREE_STATUS_INVALID_ARGUMENT, - "unrecognized --parameter_mode= value '%s'", - FLAG_parameter_mode); + status = iree_make_status(IREE_STATUS_INVALID_ARGUMENT, + "unrecognized --parameter_mode= value '%s'", + FLAG_parameter_mode); } - iree_file_contents_t* file_contents = NULL; - IREE_RETURN_AND_END_ZONE_IF_ERROR( - z0, iree_file_read_contents(path_str, read_flags, host_allocator, - &file_contents)); - - iree_io_file_handle_release_callback_t release_callback = { - .fn = iree_file_contents_release_callback, - .user_data = file_contents, - }; - iree_io_file_handle_t* file_handle = NULL; - iree_status_t status = iree_io_file_handle_wrap_host_allocation( - IREE_IO_FILE_ACCESS_READ, file_contents->buffer, release_callback, - host_allocator, &file_handle); if (iree_status_is_ok(status)) { *out_file_handle = file_handle; - } else { - iree_file_contents_free(file_contents); } IREE_TRACE_ZONE_END(z0); return status;