blob: 545ce66b7db72afd28893d21425aaf7eea34ff52 [file] [log] [blame]
Ben Vanik11ced0c2023-11-03 14:24:08 -07001// Copyright 2023 The IREE Authors
2//
3// Licensed under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
7// Dumps parsed parameter file information.
8// We intentionally use the same flags and parsing behavior as the rest of the
9// runtime tools so that users can pass their parameter flags and see exactly
10// what the runtime tools would see post-indexing. We don't try to dump original
11// file metadata as we only support parsing enough information for what we need.
12//
13// We also support basic extraction of individual parameters in cases where
14// users want to dump them out. Since we don't parse or preserve metadata we
15// can't easily dump them to
16//
17// # List all available parameters and their index information:
18// $ iree-dump-parameters --parameters=my_scope=my_file.gguf [--parameters=...]
19// # Extract parameter binary contents from a file:
20// $ iree-dump-parameters ... --extract=scope::key0=file0.bin [--extract=...]
21
22#include <ctype.h>
23#include <stdio.h>
24
25#include "iree/base/api.h"
26#include "iree/base/internal/file_io.h"
27#include "iree/base/internal/flags.h"
28#include "iree/io/parameter_index.h"
29#include "iree/io/scope_map.h"
30#include "iree/tooling/parameter_util.h"
31
32//===----------------------------------------------------------------------===//
Ben Vanik11ced0c2023-11-03 14:24:08 -070033// Parameter extraction
34//===----------------------------------------------------------------------===//
35
36IREE_FLAG_LIST(string, extract,
37 "Extracts a parameter to a file as `[scope::]key=file.bin`.");
38
39static iree_status_t iree_tooling_extract_parameter(
40 iree_io_scope_map_t* scope_map, iree_string_view_t scope,
41 iree_string_view_t key, iree_string_view_t path,
42 iree_allocator_t host_allocator) {
43 // Lookup the index for the given scope.
44 iree_io_parameter_index_t* index = NULL; // unowned
45 IREE_RETURN_IF_ERROR(iree_io_scope_map_lookup(scope_map, scope, &index));
46
47 // Lookup the entry within the index.
48 const iree_io_parameter_index_entry_t* entry = NULL; // unowned
49 IREE_RETURN_IF_ERROR(iree_io_parameter_index_lookup(index, key, &entry));
50
51 fprintf(stdout, "Extracting parameter `");
52 if (!iree_string_view_is_empty(scope)) {
53 fprintf(stdout, "%.*s::", (int)scope.size, scope.data);
54 }
55 fprintf(stdout, "%.*s` (%" PRIu64 "b) to `%.*s`...\n", (int)key.size,
56 key.data, entry->length, (int)path.size, path.data);
57
Ben Vanika306a282023-11-05 14:53:57 -080058 if (entry->type != IREE_IO_PARAMETER_INDEX_ENTRY_STORAGE_TYPE_FILE) {
59 return iree_make_status(IREE_STATUS_FAILED_PRECONDITION,
60 "cannot extract parameters of type %d",
61 (int)entry->type);
62 }
63
Ben Vanik11ced0c2023-11-03 14:24:08 -070064 // TODO(benvanik): support generic file handle IO instead of memory-only.
Ben Vanika306a282023-11-05 14:53:57 -080065 if (iree_io_file_handle_type(entry->storage.file.handle) !=
Ben Vanik11ced0c2023-11-03 14:24:08 -070066 IREE_IO_FILE_HANDLE_TYPE_HOST_ALLOCATION) {
67 return iree_make_status(
68 IREE_STATUS_UNIMPLEMENTED,
69 "only host allocation file handles are supported today");
70 }
71 iree_byte_span_t file_contents =
Ben Vanika306a282023-11-05 14:53:57 -080072 iree_io_file_handle_value(entry->storage.file.handle).host_allocation;
Ben Vanik11ced0c2023-11-03 14:24:08 -070073 iree_const_byte_span_t entry_contents = iree_make_const_byte_span(
Ben Vanika306a282023-11-05 14:53:57 -080074 file_contents.data + entry->storage.file.offset, entry->length);
Ben Vanik11ced0c2023-11-03 14:24:08 -070075 char* path_str = (char*)iree_alloca(path.size + 1);
76 memcpy(path_str, path.data, path.size);
77 path_str[path.size] = 0;
78 return iree_file_write_contents(path_str, entry_contents);
79}
80
81static iree_status_t iree_tooling_extract_parameters(
82 iree_io_scope_map_t* scope_map, iree_allocator_t host_allocator) {
83 for (iree_host_size_t i = 0; i < FLAG_extract_list().count; ++i) {
84 iree_string_view_t flag = FLAG_extract_list().values[i];
85 iree_string_view_t identifier, path;
86 iree_string_view_split(flag, '=', &identifier, &path);
87
88 iree_host_size_t separator_pos =
89 iree_string_view_find_first_of(identifier, IREE_SV("::"), 0);
90 iree_string_view_t scope = iree_string_view_empty();
91 iree_string_view_t key = iree_string_view_empty();
92 if (separator_pos != IREE_STRING_VIEW_NPOS) {
93 scope = iree_string_view_substr(identifier, 0, separator_pos);
94 key = iree_string_view_substr(identifier, separator_pos + 2,
95 IREE_HOST_SIZE_MAX);
96 } else {
97 key = identifier;
98 }
99
100 IREE_RETURN_IF_ERROR(iree_tooling_extract_parameter(scope_map, scope, key,
101 path, host_allocator),
102 "extracting parameter with flag `%.*s`",
103 (int)flag.size, flag.data);
104 }
105 return iree_ok_status();
106}
107
108//===----------------------------------------------------------------------===//
109// main
110//===----------------------------------------------------------------------===//
111
112int main(int argc, char** argv) {
113 IREE_TRACE_ZONE_BEGIN(z0);
114
115 iree_allocator_t host_allocator = iree_allocator_system();
116 int exit_code = EXIT_SUCCESS;
117
118 // Parse command line flags.
119 iree_flags_set_usage("iree-dump-parameters",
120 "Dumps information about parsed parameter files.\n");
121 iree_flags_parse_checked(IREE_FLAGS_PARSE_MODE_DEFAULT, &argc, &argv);
122
Ilija Kalinić193bc272023-12-21 01:10:37 +0100123 if (argc > 1) {
124 fprintf(stderr, "Error: no positional arguments expected.\n");
125 fprintf(stderr,
126 "Use one or more --parameters=file.ext flags to specify parameter "
127 "files.\n");
128 IREE_TRACE_ZONE_END(z0);
129 return EXIT_FAILURE;
130 }
131
Ben Vanik11ced0c2023-11-03 14:24:08 -0700132 iree_io_scope_map_t scope_map = {0};
133 iree_io_scope_map_initialize(host_allocator, &scope_map);
134
135 // Parse parameters using the common tooling flags.
136 iree_status_t status =
137 iree_tooling_build_parameter_indices_from_flags(&scope_map);
138
139 // Dump parameter information.
140 if (iree_status_is_ok(status)) {
Ben Vanikfce839f2023-11-28 17:12:58 -0800141 iree_string_builder_t sb;
142 iree_string_builder_initialize(host_allocator, &sb);
143 status = iree_io_scope_map_dump(&scope_map, &sb);
144 if (iree_status_is_ok(status)) {
145 fprintf(stdout, "%.*s", (int)iree_string_builder_size(&sb),
146 iree_string_builder_buffer(&sb));
147 }
148 iree_string_builder_deinitialize(&sb);
Ben Vanik11ced0c2023-11-03 14:24:08 -0700149 }
150
151 // Extract parameters as requested, if any.
152 if (iree_status_is_ok(status)) {
153 status = iree_tooling_extract_parameters(&scope_map, host_allocator);
154 }
155
156 iree_io_scope_map_deinitialize(&scope_map);
157
158 fflush(stdout);
159 if (!iree_status_is_ok(status)) {
160 iree_status_fprint(stderr, status);
161 iree_status_free(status);
162 exit_code = EXIT_FAILURE;
163 }
164 fflush(stderr);
165
166 IREE_TRACE_ZONE_END(z0);
167 return exit_code;
168}