onnxruntime 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddf24b881b18a6adf439e7d835baa3092222b3e7bfb87f15be0b1b6668cc0bbf
4
- data.tar.gz: f9a52098345b401b706d5675b1ca3e1e6b209a4e1f446ff8441e8d27a722ea25
3
+ metadata.gz: d6e2e19cb7a47b9fcf2adfeebb1606ef754e9a72497f3a75effa61b0bd20679b
4
+ data.tar.gz: 3f7d7ffd49dda192c7bc835912cdfbbe2726930cbe4615b75c84c6de41af9d8e
5
5
  SHA512:
6
- metadata.gz: 84b0e4d4c623f57689d25e1658fc3abba1ce0fffa41641b2474ad8ada83de7ef4f592dd28f4929e2cb388bee7408cc007d69fe8ea46a612803924cb90ce8e24f
7
- data.tar.gz: bf122bd7ba8048c7d5b6336ec33375632cbbe979db253d0b61c5f80e35097097a353f85ffd4f6a33f470266513b64f698cc21942375b67337be095325ffab4ce
6
+ metadata.gz: d60433135876cd75dfef93832ae691e4845b14197f980ec77a0e954ca5795271a51620beff55e44d65839313d613f80e64754058a753895f8bf48807120b081a
7
+ data.tar.gz: fa3d7e675b8e3401948391b8d61b48f03a8e2b3972d1257a91bfd23fb4bc67771b20fc3ac29bf4d10e641295ffcf2ef13c6d9923694ea428de7083fd29383bc9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.11.0 (2026-02-22)
2
+
3
+ - Updated ONNX Runtime to 1.24.2
4
+ - Dropped shared library for Mac x86-64 (no longer provided by upstream)
5
+
6
+ ## 0.10.2 (2026-02-19)
7
+
8
+ - Fixed uncaught exception with `CoreMLExecutionProvider`
9
+ - Fixed memory leak with `map` and `seq` outputs
10
+
1
11
  ## 0.10.1 (2025-09-30)
2
12
 
3
13
  - Updated ONNX Runtime to 1.23.0
data/LICENSE.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) Microsoft Corporation
4
- Copyright (c) 2019-2025 Andrew Kane
4
+ Copyright (c) 2019-2026 Andrew Kane
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -16,6 +16,8 @@ Add this line to your application’s Gemfile:
16
16
  gem "onnxruntime"
17
17
  ```
18
18
 
19
+ On Mac x86-64, also run `brew install onnxruntime` to install the shared library
20
+
19
21
  ## Getting Started
20
22
 
21
23
  Load a model and make predictions
@@ -2,12 +2,20 @@ module OnnxRuntime
2
2
  module FFI
3
3
  extend ::FFI::Library
4
4
 
5
- ffi_lib OnnxRuntime.ffi_lib
5
+ begin
6
+ ffi_lib OnnxRuntime.ffi_lib
7
+ rescue LoadError => e
8
+ if e.message.include?("Could not open library '/usr/local/opt/onnxruntime/lib/libonnxruntime.dylib'")
9
+ raise LoadError, "ONNX Runtime not found. Run `brew install onnxruntime`"
10
+ else
11
+ raise e
12
+ end
13
+ end
6
14
 
7
15
  # https://github.com/microsoft/onnxruntime/blob/master/include/onnxruntime/core/session/onnxruntime_c_api.h
8
16
  # keep same order
9
17
 
10
- ORT_API_VERSION = 16
18
+ ORT_API_VERSION = 24
11
19
 
12
20
  # enums
13
21
  TensorElementDataType = enum(:undefined, :float, :uint8, :int8, :uint16, :int16, :int32, :int64, :string, :bool, :float16, :double, :uint32, :uint64, :complex64, :complex128, :bfloat16)
@@ -3,10 +3,12 @@ module OnnxRuntime
3
3
  attr_reader :inputs, :outputs
4
4
 
5
5
  def initialize(path_or_bytes, enable_cpu_mem_arena: true, enable_mem_pattern: true, enable_profiling: false, execution_mode: nil, free_dimension_overrides_by_denotation: nil, free_dimension_overrides_by_name: nil, graph_optimization_level: nil, inter_op_num_threads: nil, intra_op_num_threads: nil, log_severity_level: nil, log_verbosity_level: nil, logid: nil, optimized_model_filepath: nil, profile_file_prefix: nil, session_config_entries: nil, providers: [])
6
+ # create environment first to prevent uncaught exception with CoreMLExecutionProvider
7
+ env
8
+
6
9
  # session options
7
- session_options = ::FFI::MemoryPointer.new(:pointer)
8
- check_status api[:CreateSessionOptions].call(session_options)
9
- session_options = ::FFI::AutoPointer.new(session_options.read_pointer, api[:ReleaseSessionOptions])
10
+ session_options = Pointer.new(api[:ReleaseSessionOptions])
11
+ check_status api[:CreateSessionOptions].call(session_options.ref)
10
12
 
11
13
  if enable_cpu_mem_arena
12
14
  check_status api[:EnableCpuMemArena].call(session_options)
@@ -64,9 +66,8 @@ module OnnxRuntime
64
66
 
65
67
  case provider
66
68
  when "CUDAExecutionProvider"
67
- cuda_options = ::FFI::MemoryPointer.new(:pointer)
68
- check_status api[:CreateCUDAProviderOptions].call(cuda_options)
69
- cuda_options = ::FFI::AutoPointer.new(cuda_options.read_pointer, api[:ReleaseCUDAProviderOptions])
69
+ cuda_options = Pointer.new(api[:ReleaseCUDAProviderOptions])
70
+ check_status api[:CreateCUDAProviderOptions].call(cuda_options.ref)
70
71
  check_status api[:SessionOptionsAppendExecutionProvider_CUDA_V2].call(session_options, cuda_options)
71
72
  when "CoreMLExecutionProvider"
72
73
  unless FFI.respond_to?(:OrtSessionOptionsAppendExecutionProvider_CoreML)
@@ -103,9 +104,7 @@ module OnnxRuntime
103
104
  # TODO support logid
104
105
  def run_with_ort_values(output_names, input_feed, log_severity_level: nil, log_verbosity_level: nil, logid: nil, terminate: nil)
105
106
  input_tensor = ::FFI::MemoryPointer.new(:pointer, input_feed.size)
106
- input_feed.each_with_index do |(_, input), i|
107
- input_tensor[i].write_pointer(input.to_ptr)
108
- end
107
+ input_tensor.write_array_of_pointer(input_feed.values)
109
108
 
110
109
  output_names ||= @outputs.map { |v| v[:name] }
111
110
 
@@ -115,9 +114,8 @@ module OnnxRuntime
115
114
  output_node_names = create_node_names(output_names.map(&:to_s), refs)
116
115
 
117
116
  # run options
118
- run_options = ::FFI::MemoryPointer.new(:pointer)
119
- check_status api[:CreateRunOptions].call(run_options)
120
- run_options = ::FFI::AutoPointer.new(run_options.read_pointer, api[:ReleaseRunOptions])
117
+ run_options = Pointer.new(api[:ReleaseRunOptions])
118
+ check_status api[:CreateRunOptions].call(run_options.ref)
121
119
 
122
120
  check_status api[:RunOptionsSetRunLogSeverityLevel].call(run_options, log_severity_level) if log_severity_level
123
121
  check_status api[:RunOptionsSetRunLogVerbosityLevel].call(run_options, log_verbosity_level) if log_verbosity_level
@@ -126,88 +124,76 @@ module OnnxRuntime
126
124
 
127
125
  check_status api[:Run].call(@session, run_options, input_node_names, input_tensor, input_feed.size, output_node_names, output_names.size, output_tensor)
128
126
 
129
- output_names.size.times.map { |i| OrtValue.new(output_tensor[i].read_pointer) }
127
+ output_tensor.read_array_of_pointer(output_names.size).map { |v| OrtValue.new(v) }
130
128
  end
131
129
 
132
130
  def modelmeta
133
- metadata = ::FFI::MemoryPointer.new(:pointer)
134
- check_status api[:SessionGetModelMetadata].call(@session, metadata)
135
- metadata = ::FFI::AutoPointer.new(metadata.read_pointer, api[:ReleaseModelMetadata])
131
+ metadata = Pointer.new(api[:ReleaseModelMetadata])
132
+ check_status api[:SessionGetModelMetadata].call(@session, metadata.ref)
136
133
 
137
- keys = ::FFI::MemoryPointer.new(:pointer)
134
+ keys = Pointer.new(method(:allocator_free))
138
135
  num_keys = ::FFI::MemoryPointer.new(:int64_t)
139
- check_status api[:ModelMetadataGetCustomMetadataMapKeys].call(metadata, @allocator, keys, num_keys)
140
- keys = keys.read_pointer
141
-
142
- custom_metadata_map = {}
143
- num_keys.read(:int64_t).times do |i|
144
- key_ptr = keys.get_pointer(i * ::FFI::Pointer.size)
145
- key = key_ptr.read_string
146
- value = ::FFI::MemoryPointer.new(:pointer)
147
- check_status api[:ModelMetadataLookupCustomMetadataMap].call(metadata, @allocator, key, value)
148
- custom_metadata_map[key] = value.read_pointer.read_string
149
-
150
- allocator_free key_ptr
151
- allocator_free value.read_pointer
152
- end
136
+ check_status api[:ModelMetadataGetCustomMetadataMapKeys].call(metadata, @allocator, keys.ref, num_keys)
137
+ key_ptrs =
138
+ keys.read_array_of_pointer(num_keys.read(:int64_t)).map do |ptr|
139
+ ::FFI::AutoPointer.new(ptr, method(:allocator_free))
140
+ end
141
+
142
+ custom_metadata_map =
143
+ key_ptrs.to_h do |key|
144
+ value = Pointer.new(method(:allocator_free))
145
+ check_status api[:ModelMetadataLookupCustomMetadataMap].call(metadata, @allocator, key, value.ref)
146
+ [key.read_string, value.read_string]
147
+ end
153
148
 
154
- description = ::FFI::MemoryPointer.new(:pointer)
155
- check_status api[:ModelMetadataGetDescription].call(metadata, @allocator, description)
149
+ description = Pointer.new(method(:allocator_free))
150
+ check_status api[:ModelMetadataGetDescription].call(metadata, @allocator, description.ref)
156
151
 
157
- domain = ::FFI::MemoryPointer.new(:pointer)
158
- check_status api[:ModelMetadataGetDomain].call(metadata, @allocator, domain)
152
+ domain = Pointer.new(method(:allocator_free))
153
+ check_status api[:ModelMetadataGetDomain].call(metadata, @allocator, domain.ref)
159
154
 
160
- graph_name = ::FFI::MemoryPointer.new(:pointer)
161
- check_status api[:ModelMetadataGetGraphName].call(metadata, @allocator, graph_name)
155
+ graph_name = Pointer.new(method(:allocator_free))
156
+ check_status api[:ModelMetadataGetGraphName].call(metadata, @allocator, graph_name.ref)
162
157
 
163
- graph_description = ::FFI::MemoryPointer.new(:pointer)
164
- check_status api[:ModelMetadataGetGraphDescription].call(metadata, @allocator, graph_description)
158
+ graph_description = Pointer.new(method(:allocator_free))
159
+ check_status api[:ModelMetadataGetGraphDescription].call(metadata, @allocator, graph_description.ref)
165
160
 
166
- producer_name = ::FFI::MemoryPointer.new(:pointer)
167
- check_status api[:ModelMetadataGetProducerName].call(metadata, @allocator, producer_name)
161
+ producer_name = Pointer.new(method(:allocator_free))
162
+ check_status api[:ModelMetadataGetProducerName].call(metadata, @allocator, producer_name.ref)
168
163
 
169
164
  version = ::FFI::MemoryPointer.new(:int64_t)
170
165
  check_status api[:ModelMetadataGetVersion].call(metadata, version)
171
166
 
172
167
  {
173
168
  custom_metadata_map: custom_metadata_map,
174
- description: description.read_pointer.read_string,
175
- domain: domain.read_pointer.read_string,
176
- graph_name: graph_name.read_pointer.read_string,
177
- graph_description: graph_description.read_pointer.read_string,
178
- producer_name: producer_name.read_pointer.read_string,
169
+ description: description.read_string,
170
+ domain: domain.read_string,
171
+ graph_name: graph_name.read_string,
172
+ graph_description: graph_description.read_string,
173
+ producer_name: producer_name.read_string,
179
174
  version: version.read(:int64_t)
180
175
  }
181
- ensure
182
- allocator_free keys
183
- allocator_free description.read_pointer
184
- allocator_free domain.read_pointer
185
- allocator_free graph_name.read_pointer
186
- allocator_free graph_description.read_pointer
187
- allocator_free producer_name.read_pointer
188
176
  end
189
177
 
190
178
  # return value has double underscore like Python
191
179
  def end_profiling
192
- out = ::FFI::MemoryPointer.new(:pointer)
193
- check_status api[:SessionEndProfiling].call(@session, @allocator, out)
194
- begin
195
- out.read_pointer.read_string
196
- ensure
197
- allocator_free out.read_pointer
198
- end
180
+ out = Pointer.new(method(:allocator_free))
181
+ check_status api[:SessionEndProfiling].call(@session, @allocator, out.ref)
182
+ out.read_string
199
183
  end
200
184
 
201
185
  # no way to set providers with C API yet
202
186
  # so we can return all available providers
203
187
  def providers
204
- out_ptr = ::FFI::MemoryPointer.new(:pointer)
188
+ out_ptr = Pointer.new
205
189
  length_ptr = ::FFI::MemoryPointer.new(:int)
206
- check_status api[:GetAvailableProviders].call(out_ptr, length_ptr)
190
+ check_status api[:GetAvailableProviders].call(out_ptr.ref, length_ptr)
207
191
  length = length_ptr.read_int
208
- providers = out_ptr.read_pointer.read_array_of_pointer(length).map(&:read_string)
209
- api[:ReleaseAvailableProviders].call(out_ptr.read_pointer, length)
210
- providers
192
+ begin
193
+ out_ptr.read_array_of_pointer(length).map(&:read_string)
194
+ ensure
195
+ api[:ReleaseAvailableProviders].call(out_ptr, length)
196
+ end
211
197
  end
212
198
 
213
199
  private
@@ -222,13 +208,13 @@ module OnnxRuntime
222
208
  false
223
209
  end
224
210
 
225
- session = ::FFI::MemoryPointer.new(:pointer)
211
+ session = Pointer.new(api[:ReleaseSession])
226
212
  if from_memory
227
- check_status api[:CreateSessionFromArray].call(env, path_or_bytes, path_or_bytes.bytesize, session_options, session)
213
+ check_status api[:CreateSessionFromArray].call(env, path_or_bytes, path_or_bytes.bytesize, session_options, session.ref)
228
214
  else
229
- check_status api[:CreateSession].call(env, ort_string(path_or_bytes), session_options, session)
215
+ check_status api[:CreateSession].call(env, ort_string(path_or_bytes), session_options, session.ref)
230
216
  end
231
- ::FFI::AutoPointer.new(session.read_pointer, api[:ReleaseSession])
217
+ session
232
218
  end
233
219
 
234
220
  def load_inputs
@@ -236,16 +222,13 @@ module OnnxRuntime
236
222
  check_status api[:SessionGetInputCount].call(@session, num_input_nodes)
237
223
 
238
224
  num_input_nodes.read(:size_t).times.map do |i|
239
- name_ptr = ::FFI::MemoryPointer.new(:pointer)
240
- check_status api[:SessionGetInputName].call(@session, i, @allocator, name_ptr)
241
- name_str = name_ptr.read_pointer.read_string
242
- allocator_free name_ptr.read_pointer
225
+ name_ptr = Pointer.new(method(:allocator_free))
226
+ check_status api[:SessionGetInputName].call(@session, i, @allocator, name_ptr.ref)
243
227
 
244
- typeinfo = ::FFI::MemoryPointer.new(:pointer)
245
- check_status api[:SessionGetInputTypeInfo].call(@session, i, typeinfo)
246
- typeinfo = ::FFI::AutoPointer.new(typeinfo.read_pointer, api[:ReleaseTypeInfo])
228
+ typeinfo = Pointer.new(api[:ReleaseTypeInfo])
229
+ check_status api[:SessionGetInputTypeInfo].call(@session, i, typeinfo.ref)
247
230
 
248
- {name: name_str}.merge(Utils.node_info(typeinfo))
231
+ {name: name_ptr.read_string}.merge(Utils.node_info(typeinfo))
249
232
  end
250
233
  end
251
234
 
@@ -254,16 +237,13 @@ module OnnxRuntime
254
237
  check_status api[:SessionGetOutputCount].call(@session, num_output_nodes)
255
238
 
256
239
  num_output_nodes.read(:size_t).times.map do |i|
257
- name_ptr = ::FFI::MemoryPointer.new(:pointer)
258
- check_status api[:SessionGetOutputName].call(@session, i, @allocator, name_ptr)
259
- name_str = name_ptr.read_pointer.read_string
260
- allocator_free name_ptr.read_pointer
240
+ name_ptr = Pointer.new(method(:allocator_free))
241
+ check_status api[:SessionGetOutputName].call(@session, i, @allocator, name_ptr.ref)
261
242
 
262
- typeinfo = ::FFI::MemoryPointer.new(:pointer)
263
- check_status api[:SessionGetOutputTypeInfo].call(@session, i, typeinfo)
264
- typeinfo = ::FFI::AutoPointer.new(typeinfo.read_pointer, api[:ReleaseTypeInfo])
243
+ typeinfo = Pointer.new(api[:ReleaseTypeInfo])
244
+ check_status api[:SessionGetOutputTypeInfo].call(@session, i, typeinfo.ref)
265
245
 
266
- {name: name_str}.merge(Utils.node_info(typeinfo))
246
+ {name: name_ptr.read_string}.merge(Utils.node_info(typeinfo))
267
247
  end
268
248
  end
269
249
 
@@ -334,9 +314,8 @@ module OnnxRuntime
334
314
  # use mutex for thread-safety
335
315
  Utils.mutex.synchronize do
336
316
  @@env ||= begin
337
- env = ::FFI::MemoryPointer.new(:pointer)
338
- check_status api[:CreateEnv].call(3, "Default", env)
339
- env = ::FFI::AutoPointer.new(env.read_pointer, api[:ReleaseEnv])
317
+ env = Pointer.new(api[:ReleaseEnv])
318
+ check_status api[:CreateEnv].call(3, "Default", env.ref)
340
319
  # disable telemetry
341
320
  # https://github.com/microsoft/onnxruntime/blob/master/docs/Privacy.md
342
321
  check_status api[:DisableTelemetryEvents].call(env)
@@ -7,12 +7,7 @@ module OnnxRuntime
7
7
  def predict(input_feed, output_names: nil, **run_options)
8
8
  predictions = @session.run(output_names, input_feed, **run_options)
9
9
  output_names ||= outputs.map { |o| o[:name] }
10
-
11
- result = {}
12
- output_names.zip(predictions).each do |k, v|
13
- result[k.to_s] = v
14
- end
15
- result
10
+ output_names.zip(predictions).to_h { |k, v| [k.to_s, v] }
16
11
  end
17
12
 
18
13
  def inputs
@@ -22,18 +22,18 @@ module OnnxRuntime
22
22
  input_node_dims = ::FFI::MemoryPointer.new(:int64, shape.size)
23
23
  input_node_dims.write_array_of_int64(shape)
24
24
 
25
- ptr = ::FFI::MemoryPointer.new(:pointer)
25
+ ptr = Pointer.new
26
26
  if element_type == :string
27
27
  # keep reference to _str_ptrs until FillStringTensor call
28
28
  input_tensor_values, _str_ptrs = create_input_strings(input)
29
- Utils.check_status FFI.api[:CreateTensorAsOrtValue].call(Utils.allocator, input_node_dims, shape.size, type_enum, ptr)
30
- Utils.check_status FFI.api[:FillStringTensor].call(ptr.read_pointer, input_tensor_values, input_tensor_values.size / input_tensor_values.type_size)
29
+ Utils.check_status FFI.api[:CreateTensorAsOrtValue].call(Utils.allocator, input_node_dims, shape.size, type_enum, ptr.ref)
30
+ Utils.check_status FFI.api[:FillStringTensor].call(ptr, input_tensor_values, input_tensor_values.size / input_tensor_values.type_size)
31
31
  else
32
32
  input_tensor_values = create_input_data(input, element_type)
33
- Utils.check_status FFI.api[:CreateTensorWithDataAsOrtValue].call(allocator_info, input_tensor_values, input_tensor_values.size, input_node_dims, shape.size, type_enum, ptr)
33
+ Utils.check_status FFI.api[:CreateTensorWithDataAsOrtValue].call(allocator_info, input_tensor_values, input_tensor_values.size, input_node_dims, shape.size, type_enum, ptr.ref)
34
34
  end
35
35
 
36
- new(ptr.read_pointer, input_tensor_values)
36
+ new(ptr.to_ptr, input_tensor_values)
37
37
  end
38
38
 
39
39
  def self.from_shape_and_type(shape, element_type)
@@ -43,10 +43,10 @@ module OnnxRuntime
43
43
  input_node_dims = ::FFI::MemoryPointer.new(:int64, shape.size)
44
44
  input_node_dims.write_array_of_int64(shape)
45
45
 
46
- ptr = ::FFI::MemoryPointer.new(:pointer)
47
- Utils.check_status FFI.api[:CreateTensorAsOrtValue].call(Utils.allocator, input_node_dims, shape.size, type_enum, ptr)
46
+ ptr = Pointer.new
47
+ Utils.check_status FFI.api[:CreateTensorAsOrtValue].call(Utils.allocator, input_node_dims, shape.size, type_enum, ptr.ref)
48
48
 
49
- new(ptr.read_pointer)
49
+ new(ptr.to_ptr)
50
50
  end
51
51
 
52
52
  def self.create_input_data(input, tensor_type)
@@ -85,9 +85,8 @@ module OnnxRuntime
85
85
 
86
86
  def data_type
87
87
  @data_type ||= begin
88
- typeinfo = ::FFI::MemoryPointer.new(:pointer)
89
- Utils.check_status FFI.api[:GetTypeInfo].call(@ptr, typeinfo)
90
- typeinfo = ::FFI::AutoPointer.new(typeinfo.read_pointer, FFI.api[:ReleaseTypeInfo])
88
+ typeinfo = Pointer.new(FFI.api[:ReleaseTypeInfo])
89
+ Utils.check_status FFI.api[:GetTypeInfo].call(@ptr, typeinfo.ref)
91
90
  Utils.node_info(typeinfo)[:type]
92
91
  end
93
92
  end
@@ -117,9 +116,9 @@ module OnnxRuntime
117
116
  end
118
117
 
119
118
  def data_ptr
120
- tensor_data = ::FFI::MemoryPointer.new(:pointer)
121
- FFI.api[:GetTensorMutableData].call(@ptr, tensor_data)
122
- tensor_data.read_pointer
119
+ tensor_data = Pointer.new
120
+ FFI.api[:GetTensorMutableData].call(@ptr, tensor_data.ref)
121
+ tensor_data.to_ptr
123
122
  end
124
123
 
125
124
  private
@@ -134,9 +133,8 @@ module OnnxRuntime
134
133
 
135
134
  def type_and_shape_info
136
135
  @type_and_shape_info ||= begin
137
- typeinfo = ::FFI::MemoryPointer.new(:pointer)
138
- Utils.check_status FFI.api[:GetTensorTypeAndShape].call(@ptr, typeinfo)
139
- typeinfo = ::FFI::AutoPointer.new(typeinfo.read_pointer, FFI.api[:ReleaseTensorTypeAndShapeInfo])
136
+ typeinfo = Pointer.new(FFI.api[:ReleaseTensorTypeAndShapeInfo])
137
+ Utils.check_status FFI.api[:GetTensorTypeAndShape].call(@ptr, typeinfo.ref)
140
138
  Utils.tensor_type_and_shape(typeinfo)
141
139
  end
142
140
  end
@@ -148,14 +146,13 @@ module OnnxRuntime
148
146
 
149
147
  case type
150
148
  when :tensor
151
- typeinfo = ::FFI::MemoryPointer.new(:pointer)
152
- Utils.check_status FFI.api[:GetTensorTypeAndShape].call(out_ptr, typeinfo)
153
- typeinfo = ::FFI::AutoPointer.new(typeinfo.read_pointer, FFI.api[:ReleaseTensorTypeAndShapeInfo])
149
+ typeinfo = Pointer.new(FFI.api[:ReleaseTensorTypeAndShapeInfo])
150
+ Utils.check_status FFI.api[:GetTensorTypeAndShape].call(out_ptr, typeinfo.ref)
154
151
 
155
152
  type, shape = Utils.tensor_type_and_shape(typeinfo)
156
153
 
157
- tensor_data = ::FFI::MemoryPointer.new(:pointer)
158
- Utils.check_status FFI.api[:GetTensorMutableData].call(out_ptr, tensor_data)
154
+ tensor_data = Pointer.new
155
+ Utils.check_status FFI.api[:GetTensorMutableData].call(out_ptr, tensor_data.ref)
159
156
 
160
157
  out_size = ::FFI::MemoryPointer.new(:size_t)
161
158
  Utils.check_status FFI.api[:GetTensorShapeElementCount].call(typeinfo, out_size)
@@ -174,15 +171,15 @@ module OnnxRuntime
174
171
  else
175
172
  numo_type = Utils.numo_types[type]
176
173
  Utils.unsupported_type("element", type) unless numo_type
177
- numo_type.from_binary(tensor_data.read_pointer.read_bytes(output_tensor_size * numo_type::ELEMENT_BYTE_SIZE), shape)
174
+ numo_type.from_binary(tensor_data.to_ptr.read_bytes(output_tensor_size * numo_type::ELEMENT_BYTE_SIZE), shape)
178
175
  end
179
176
  when :ruby
180
177
  arr =
181
178
  case type
182
179
  when :float, :uint8, :int8, :uint16, :int16, :int32, :int64, :double, :uint32, :uint64
183
- tensor_data.read_pointer.send("read_array_of_#{type}", output_tensor_size)
180
+ tensor_data.to_ptr.send("read_array_of_#{type}", output_tensor_size)
184
181
  when :bool
185
- tensor_data.read_pointer.read_array_of_uint8(output_tensor_size).map { |v| v == 1 }
182
+ tensor_data.to_ptr.read_array_of_uint8(output_tensor_size).map { |v| v == 1 }
186
183
  when :string
187
184
  create_strings_from_onnx_value(out_ptr, output_tensor_size, [])
188
185
  else
@@ -198,20 +195,19 @@ module OnnxRuntime
198
195
  Utils.check_status FFI.api[:GetValueCount].call(out_ptr, out)
199
196
 
200
197
  out.read(:size_t).times.map do |i|
201
- seq = ::FFI::MemoryPointer.new(:pointer)
202
- Utils.check_status FFI.api[:GetValue].call(out_ptr, i, Utils.allocator, seq)
203
- create_from_onnx_value(seq.read_pointer, output_type)
198
+ seq = Pointer.new(FFI.api[:ReleaseValue])
199
+ Utils.check_status FFI.api[:GetValue].call(out_ptr, i, Utils.allocator, seq.ref)
200
+ create_from_onnx_value(seq, output_type)
204
201
  end
205
202
  when :map
206
- map_keys = ::FFI::MemoryPointer.new(:pointer)
207
- Utils.check_status FFI.api[:GetValue].call(out_ptr, 0, Utils.allocator, map_keys)
203
+ map_keys = Pointer.new(FFI.api[:ReleaseValue])
204
+ Utils.check_status FFI.api[:GetValue].call(out_ptr, 0, Utils.allocator, map_keys.ref)
208
205
 
209
- map_values = ::FFI::MemoryPointer.new(:pointer)
210
- Utils.check_status FFI.api[:GetValue].call(out_ptr, 1, Utils.allocator, map_values)
206
+ map_values = Pointer.new(FFI.api[:ReleaseValue])
207
+ Utils.check_status FFI.api[:GetValue].call(out_ptr, 1, Utils.allocator, map_values.ref)
211
208
 
212
- type_shape = ::FFI::MemoryPointer.new(:pointer)
213
- Utils.check_status FFI.api[:GetTensorTypeAndShape].call(map_keys.read_pointer, type_shape)
214
- type_shape = ::FFI::AutoPointer.new(type_shape.read_pointer, FFI.api[:ReleaseTensorTypeAndShapeInfo])
209
+ type_shape = Pointer.new(FFI.api[:ReleaseTensorTypeAndShapeInfo])
210
+ Utils.check_status FFI.api[:GetTensorTypeAndShape].call(map_keys, type_shape.ref)
215
211
 
216
212
  elem_type = ::FFI::MemoryPointer.new(:int)
217
213
  Utils.check_status FFI.api[:GetTensorElementType].call(type_shape, elem_type)
@@ -220,13 +216,9 @@ module OnnxRuntime
220
216
  elem_type = FFI::TensorElementDataType[elem_type.read_int]
221
217
  case elem_type
222
218
  when :int64
223
- ret = {}
224
- keys = create_from_onnx_value(map_keys.read_pointer, output_type)
225
- values = create_from_onnx_value(map_values.read_pointer, output_type)
226
- keys.zip(values).each do |k, v|
227
- ret[k] = v
228
- end
229
- ret
219
+ keys = create_from_onnx_value(map_keys, output_type)
220
+ values = create_from_onnx_value(map_values, output_type)
221
+ keys.zip(values).to_h
230
222
  else
231
223
  Utils.unsupported_type("element", elem_type)
232
224
  end
@@ -261,9 +253,9 @@ module OnnxRuntime
261
253
 
262
254
  def self.allocator_info
263
255
  @allocator_info ||= begin
264
- allocator_info = ::FFI::MemoryPointer.new(:pointer)
265
- Utils.check_status FFI.api[:CreateCpuMemoryInfo].call(1, 0, allocator_info)
266
- ::FFI::AutoPointer.new(allocator_info.read_pointer, FFI.api[:ReleaseMemoryInfo])
256
+ allocator_info = Pointer.new(FFI.api[:ReleaseMemoryInfo])
257
+ Utils.check_status FFI.api[:CreateCpuMemoryInfo].call(1, 0, allocator_info.ref)
258
+ allocator_info
267
259
  end
268
260
  end
269
261
  end
@@ -0,0 +1,29 @@
1
+ module OnnxRuntime
2
+ class Pointer
3
+ attr_reader :ref
4
+
5
+ def initialize(free = nil)
6
+ @ref = ::FFI::MemoryPointer.new(:pointer)
7
+ ObjectSpace.define_finalizer(self, self.class.finalize(@ref, free)) if free
8
+ end
9
+
10
+ def self.finalize(ref, free)
11
+ proc do
12
+ ptr = ref.read_pointer
13
+ free.(ptr) unless ptr.null?
14
+ end
15
+ end
16
+
17
+ def to_ptr
18
+ @ref.read_pointer
19
+ end
20
+
21
+ def read_string(...)
22
+ to_ptr.read_string(...)
23
+ end
24
+
25
+ def read_array_of_pointer(...)
26
+ to_ptr.read_array_of_pointer(...)
27
+ end
28
+ end
29
+ end
@@ -49,9 +49,9 @@ module OnnxRuntime
49
49
  case type
50
50
  when :tensor
51
51
  # don't free tensor_info
52
- tensor_info = ::FFI::MemoryPointer.new(:pointer)
53
- check_status api[:CastTypeInfoToTensorInfo].call(typeinfo, tensor_info)
54
- type, shape = Utils.tensor_type_and_shape(tensor_info.read_pointer)
52
+ tensor_info = Pointer.new
53
+ check_status api[:CastTypeInfoToTensorInfo].call(typeinfo, tensor_info.ref)
54
+ type, shape = Utils.tensor_type_and_shape(tensor_info)
55
55
 
56
56
  {
57
57
  type: "tensor(#{FFI::TensorElementDataType[type]})",
@@ -59,12 +59,11 @@ module OnnxRuntime
59
59
  }
60
60
  when :sequence
61
61
  # don't free sequence_info
62
- sequence_type_info = ::FFI::MemoryPointer.new(:pointer)
63
- check_status api[:CastTypeInfoToSequenceTypeInfo].call(typeinfo, sequence_type_info)
62
+ sequence_type_info = Pointer.new
63
+ check_status api[:CastTypeInfoToSequenceTypeInfo].call(typeinfo, sequence_type_info.ref)
64
64
 
65
- nested_type_info = ::FFI::MemoryPointer.new(:pointer)
66
- check_status api[:GetSequenceElementType].call(sequence_type_info.read_pointer, nested_type_info)
67
- nested_type_info = ::FFI::AutoPointer.new(nested_type_info.read_pointer, api[:ReleaseTypeInfo])
65
+ nested_type_info = Pointer.new(api[:ReleaseTypeInfo])
66
+ check_status api[:GetSequenceElementType].call(sequence_type_info, nested_type_info.ref)
68
67
  v = node_info(nested_type_info)[:type]
69
68
 
70
69
  {
@@ -73,18 +72,17 @@ module OnnxRuntime
73
72
  }
74
73
  when :map
75
74
  # don't free map_type_info
76
- map_type_info = ::FFI::MemoryPointer.new(:pointer)
77
- check_status api[:CastTypeInfoToMapTypeInfo].call(typeinfo, map_type_info)
75
+ map_type_info = Pointer.new
76
+ check_status api[:CastTypeInfoToMapTypeInfo].call(typeinfo, map_type_info.ref)
78
77
 
79
78
  # key
80
79
  key_type = ::FFI::MemoryPointer.new(:int)
81
- check_status api[:GetMapKeyType].call(map_type_info.read_pointer, key_type)
80
+ check_status api[:GetMapKeyType].call(map_type_info, key_type)
82
81
  k = FFI::TensorElementDataType[key_type.read_int]
83
82
 
84
83
  # value
85
- value_type_info = ::FFI::MemoryPointer.new(:pointer)
86
- check_status api[:GetMapValueType].call(map_type_info.read_pointer, value_type_info)
87
- value_type_info = ::FFI::AutoPointer.new(value_type_info.read_pointer, api[:ReleaseTypeInfo])
84
+ value_type_info = Pointer.new(api[:ReleaseTypeInfo])
85
+ check_status api[:GetMapValueType].call(map_type_info, value_type_info.ref)
88
86
  v = node_info(value_type_info)[:type]
89
87
 
90
88
  {
@@ -132,9 +130,10 @@ module OnnxRuntime
132
130
 
133
131
  def self.allocator
134
132
  @allocator ||= begin
135
- allocator = ::FFI::MemoryPointer.new(:pointer)
136
- check_status api[:GetAllocatorWithDefaultOptions].call(allocator)
137
- allocator.read_pointer # do not free default allocator
133
+ # do not free default allocator
134
+ allocator = Pointer.new
135
+ check_status api[:GetAllocatorWithDefaultOptions].call(allocator.ref)
136
+ allocator
138
137
  end
139
138
  end
140
139
  end
@@ -1,3 +1,3 @@
1
1
  module OnnxRuntime
2
- VERSION = "0.10.1"
2
+ VERSION = "0.11.0"
3
3
  end
data/lib/onnxruntime.rb CHANGED
@@ -6,6 +6,7 @@ require_relative "onnxruntime/datasets"
6
6
  require_relative "onnxruntime/inference_session"
7
7
  require_relative "onnxruntime/model"
8
8
  require_relative "onnxruntime/ort_value"
9
+ require_relative "onnxruntime/pointer"
9
10
  require_relative "onnxruntime/utils"
10
11
  require_relative "onnxruntime/version"
11
12
 
@@ -15,24 +16,24 @@ module OnnxRuntime
15
16
  class << self
16
17
  attr_accessor :ffi_lib
17
18
  end
19
+ vendor = File.expand_path("../vendor", __dir__)
18
20
  lib_name =
19
21
  if Gem.win_platform?
20
- "onnxruntime.dll"
22
+ "#{vendor}/onnxruntime.dll"
21
23
  elsif RbConfig::CONFIG["host_os"] =~ /darwin/i
22
24
  if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
23
- "libonnxruntime.arm64.dylib"
25
+ "#{vendor}/libonnxruntime.arm64.dylib"
24
26
  else
25
- "libonnxruntime.dylib"
27
+ "/usr/local/opt/onnxruntime/lib/libonnxruntime.dylib"
26
28
  end
27
29
  else
28
30
  if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
29
- "libonnxruntime.arm64.so"
31
+ "#{vendor}/libonnxruntime.arm64.so"
30
32
  else
31
- "libonnxruntime.so"
33
+ "#{vendor}/libonnxruntime.so"
32
34
  end
33
35
  end
34
- vendor_lib = File.expand_path("../vendor/#{lib_name}", __dir__)
35
- self.ffi_lib = [vendor_lib]
36
+ self.ffi_lib = [lib_name]
36
37
 
37
38
  def self.lib_version
38
39
  FFI.OrtGetApiBase[:GetVersionString].call.read_string
@@ -5806,41 +5806,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5806
5806
 
5807
5807
  _____
5808
5808
 
5809
- composable_kernel
5810
-
5811
- https://github.com/ROCmSoftwarePlatform/composable_kernel
5812
-
5813
- Copyright (c) 2018- , Advanced Micro Devices, Inc. (Chao Liu, Jing Zhang)
5814
- Copyright (c) 2019- , Advanced Micro Devices, Inc. (Letao Qin, Qianfeng Zhang, Liang Huang, Shaojie Wang)
5815
- Copyright (c) 2022- , Advanced Micro Devices, Inc. (Anthony Chang, Chunyu Lai, Illia Silin, Adam Osewski, Poyen Chen, Jehandad Khan)
5816
- Copyright (c) 2019-2021, Advanced Micro Devices, Inc. (Hanwen Chang)
5817
- Copyright (c) 2019-2020, Advanced Micro Devices, Inc. (Tejash Shah)
5818
- Copyright (c) 2020 , Advanced Micro Devices, Inc. (Xiaoyan Zhou)
5819
- Copyright (c) 2021-2022, Advanced Micro Devices, Inc. (Jianfeng Yan)
5820
-
5821
- SPDX-License-Identifier: MIT
5822
- Copyright (c) 2018-2023, Advanced Micro Devices, Inc. All rights reserved.
5823
-
5824
- Permission is hereby granted, free of charge, to any person obtaining a copy
5825
- of this software and associated documentation files (the "Software"), to deal
5826
- in the Software without restriction, including without limitation the rights
5827
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5828
- copies of the Software, and to permit persons to whom the Software is
5829
- furnished to do so, subject to the following conditions:
5830
-
5831
- The above copyright notice and this permission notice shall be included in all
5832
- copies or substantial portions of the Software.
5833
-
5834
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5835
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5836
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5837
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5838
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5839
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5840
- SOFTWARE.
5841
-
5842
- _____
5843
-
5844
5809
  neural-speed
5845
5810
 
5846
5811
  https://github.com/intel/neural-speed
Binary file
Binary file
Binary file
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onnxruntime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -37,13 +37,13 @@ files:
37
37
  - lib/onnxruntime/inference_session.rb
38
38
  - lib/onnxruntime/model.rb
39
39
  - lib/onnxruntime/ort_value.rb
40
+ - lib/onnxruntime/pointer.rb
40
41
  - lib/onnxruntime/utils.rb
41
42
  - lib/onnxruntime/version.rb
42
43
  - vendor/LICENSE
43
44
  - vendor/ThirdPartyNotices.txt
44
45
  - vendor/libonnxruntime.arm64.dylib
45
46
  - vendor/libonnxruntime.arm64.so
46
- - vendor/libonnxruntime.dylib
47
47
  - vendor/libonnxruntime.so
48
48
  - vendor/onnxruntime.dll
49
49
  homepage: https://github.com/ankane/onnxruntime-ruby
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
64
  - !ruby/object:Gem::Version
65
65
  version: '0'
66
66
  requirements: []
67
- rubygems_version: 3.6.9
67
+ rubygems_version: 4.0.3
68
68
  specification_version: 4
69
69
  summary: High performance scoring engine for ML models
70
70
  test_files: []
Binary file