onnxruntime 0.2.2 → 0.3.3

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: fa019e016dea45f795caba9b06e972edc6ae705d1599826fb17adf10af572851
4
- data.tar.gz: e0704039d0c8a94bf523dce7f707636493696ee92aa3f741d5b49ea62561e6d5
3
+ metadata.gz: b7d22851572b35128d1e2bbcc041b4989851e02354cace5389afc25855674b11
4
+ data.tar.gz: f1eee285e5dbff1fbf6de4e350560e3e386e1f4d26d53810f154cd16117e38e6
5
5
  SHA512:
6
- metadata.gz: 07dbde3621a15379bceb5b0fe7bfbb2bb581cb54a1b78d0f104f432396bac9086ab3c6186798fab52026515c8331074b35a68f6cce6748d3315e10bc375c3a9a
7
- data.tar.gz: ccc9ee30c55d0c8ae611b70adeab1b8707bc15bce42281ce05ca6bb9d4d6ff4953c2795a3931f4ff325401a3caea95d62e08243732d125cebda9dfb4587bdbc8
6
+ metadata.gz: f89ba13181bfcc8cdf35356efae175d0e2c7a0787a13af8d46788645046f057bce466e28566c0f2982f52893dbb7cc1553a741b1ca4923066e90c0a5fb230edf
7
+ data.tar.gz: 3843b9c1e5a9432d3b72ebb33498aaef0fb6edf8942a9f0b6794bed36fb95df67290e6c4385e19927e5404510d89ad8965b15de0a96246b7f1770c4fb01216f6
@@ -1,3 +1,29 @@
1
+ ## 0.3.3 (2020-06-17)
2
+
3
+ - Fixed segmentation fault on exit on Linux
4
+
5
+ ## 0.3.2 (2020-06-16)
6
+
7
+ - Fixed error with FFI 1.13.0+
8
+ - Added friendly graph optimization levels
9
+
10
+ ## 0.3.1 (2020-05-18)
11
+
12
+ - Updated ONNX Runtime to 1.3.0
13
+ - Added `custom_metadata_map` to model metadata
14
+
15
+ ## 0.3.0 (2020-03-11)
16
+
17
+ - Updated ONNX Runtime to 1.2.0
18
+ - Added model metadata
19
+ - Added `end_profiling` method
20
+ - Added support for loading from IO objects
21
+ - Improved `input` and `output` for `seq` and `map` types
22
+
23
+ ## 0.2.3 (2020-01-23)
24
+
25
+ - Updated ONNX Runtime to 1.1.1
26
+
1
27
  ## 0.2.2 (2019-12-24)
2
28
 
3
29
  - Added support for session options
@@ -1,4 +1,4 @@
1
- Copyright (c) 2019 Andrew Kane
1
+ Copyright (c) 2019-2020 Andrew Kane
2
2
  Datasets Copyright (c) Microsoft Corporation
3
3
 
4
4
  MIT License
data/README.md CHANGED
@@ -20,7 +20,7 @@ Load a model and make predictions
20
20
 
21
21
  ```ruby
22
22
  model = OnnxRuntime::Model.new("model.onnx")
23
- model.predict(x: [1, 2, 3])
23
+ model.predict({x: [1, 2, 3]})
24
24
  ```
25
25
 
26
26
  > Download pre-trained models from the [ONNX Model Zoo](https://github.com/onnx/models)
@@ -37,10 +37,16 @@ Get outputs
37
37
  model.outputs
38
38
  ```
39
39
 
40
+ Get metadata
41
+
42
+ ```ruby
43
+ model.metadata
44
+ ```
45
+
40
46
  Load a model from a string
41
47
 
42
48
  ```ruby
43
- byte_str = File.binread("model.onnx")
49
+ byte_str = StringIO.new("...")
44
50
  model = OnnxRuntime::Model.new(byte_str)
45
51
  ```
46
52
 
@@ -57,8 +63,8 @@ OnnxRuntime::Model.new(path_or_bytes, {
57
63
  enable_cpu_mem_arena: true,
58
64
  enable_mem_pattern: true,
59
65
  enable_profiling: false,
60
- execution_mode: :sequential,
61
- graph_optimization_level: nil,
66
+ execution_mode: :sequential, # :sequential or :parallel
67
+ graph_optimization_level: nil, # :none, :basic, :extended, or :all
62
68
  inter_op_num_threads: nil,
63
69
  intra_op_num_threads: nil,
64
70
  log_severity_level: 2,
@@ -19,7 +19,7 @@ module OnnxRuntime
19
19
  self.ffi_lib = [vendor_lib]
20
20
 
21
21
  def self.lib_version
22
- FFI.OrtGetApiBase[:GetVersionString].call
22
+ FFI.OrtGetApiBase[:GetVersionString].call.read_string
23
23
  end
24
24
 
25
25
  # friendlier error message
@@ -20,7 +20,7 @@ module OnnxRuntime
20
20
  layout \
21
21
  :CreateStatus, callback(%i[int string], :pointer),
22
22
  :GetErrorCode, callback(%i[pointer], :pointer),
23
- :GetErrorMessage, callback(%i[pointer], :string),
23
+ :GetErrorMessage, callback(%i[pointer], :pointer),
24
24
  :CreateEnv, callback(%i[int string pointer], :pointer),
25
25
  :CreateEnvWithCustomLogger, callback(%i[], :pointer),
26
26
  :EnableTelemetryEvents, callback(%i[pointer], :pointer),
@@ -119,7 +119,30 @@ module OnnxRuntime
119
119
  :ReleaseTypeInfo, callback(%i[pointer], :void),
120
120
  :ReleaseTensorTypeAndShapeInfo, callback(%i[pointer], :void),
121
121
  :ReleaseSessionOptions, callback(%i[pointer], :void),
122
- :ReleaseCustomOpDomain, callback(%i[pointer], :void)
122
+ :ReleaseCustomOpDomain, callback(%i[pointer], :void),
123
+ :GetDenotationFromTypeInfo, callback(%i[], :pointer),
124
+ :CastTypeInfoToMapTypeInfo, callback(%i[pointer pointer], :pointer),
125
+ :CastTypeInfoToSequenceTypeInfo, callback(%i[pointer pointer], :pointer),
126
+ :GetMapKeyType, callback(%i[pointer pointer], :pointer),
127
+ :GetMapValueType, callback(%i[pointer pointer], :pointer),
128
+ :GetSequenceElementType, callback(%i[pointer pointer], :pointer),
129
+ :ReleaseMapTypeInfo, callback(%i[pointer], :void),
130
+ :ReleaseSequenceTypeInfo, callback(%i[pointer], :void),
131
+ :SessionEndProfiling, callback(%i[pointer pointer pointer], :pointer),
132
+ :SessionGetModelMetadata, callback(%i[pointer pointer], :pointer),
133
+ :ModelMetadataGetProducerName, callback(%i[pointer pointer pointer], :pointer),
134
+ :ModelMetadataGetGraphName, callback(%i[pointer pointer pointer], :pointer),
135
+ :ModelMetadataGetDomain, callback(%i[pointer pointer pointer], :pointer),
136
+ :ModelMetadataGetDescription, callback(%i[pointer pointer pointer], :pointer),
137
+ :ModelMetadataLookupCustomMetadataMap, callback(%i[pointer pointer pointer pointer], :pointer),
138
+ :ModelMetadataGetVersion, callback(%i[pointer pointer], :pointer),
139
+ :ReleaseModelMetadata, callback(%i[pointer], :void),
140
+ :CreateEnvWithGlobalThreadPools, callback(%i[], :pointer),
141
+ :DisablePerSessionThreads, callback(%i[], :pointer),
142
+ :CreateThreadingOptions, callback(%i[], :pointer),
143
+ :ReleaseThreadingOptions, callback(%i[], :pointer),
144
+ :ModelMetadataGetCustomMetadataMapKeys, callback(%i[pointer pointer pointer pointer], :pointer),
145
+ :AddFreeDimensionOverrideByName, callback(%i[], :pointer)
123
146
  end
124
147
 
125
148
  class ApiBase < ::FFI::Struct
@@ -127,7 +150,7 @@ module OnnxRuntime
127
150
  # to prevent "unable to resolve type" error on Ubuntu
128
151
  layout \
129
152
  :GetApi, callback(%i[uint32], Api.by_ref),
130
- :GetVersionString, callback(%i[], :string)
153
+ :GetVersionString, callback(%i[], :pointer)
131
154
  end
132
155
 
133
156
  attach_function :OrtGetApiBase, %i[], ApiBase.by_ref
@@ -10,18 +10,17 @@ module OnnxRuntime
10
10
  check_status api[:EnableMemPattern].call(session_options.read_pointer) if enable_mem_pattern
11
11
  check_status api[:EnableProfiling].call(session_options.read_pointer, "onnxruntime_profile_") if enable_profiling
12
12
  if execution_mode
13
- mode =
14
- case execution_mode
15
- when :sequential
16
- 0
17
- when :parallel
18
- 1
19
- else
20
- raise ArgumentError, "Invalid execution mode"
21
- end
13
+ execution_modes = {sequential: 0, parallel: 1}
14
+ mode = execution_modes[execution_mode]
15
+ raise ArgumentError, "Invalid execution mode" unless mode
22
16
  check_status api[:SetSessionExecutionMode].call(session_options.read_pointer, mode)
23
17
  end
24
- check_status api[:SetSessionGraphOptimizationLevel].call(session_options.read_pointer, graph_optimization_level) if graph_optimization_level
18
+ if graph_optimization_level
19
+ optimization_levels = {none: 0, basic: 1, extended: 2, all: 99}
20
+ # TODO raise error in 0.4.0
21
+ level = optimization_levels[graph_optimization_level] || graph_optimization_level
22
+ check_status api[:SetSessionGraphOptimizationLevel].call(session_options.read_pointer, level)
23
+ end
25
24
  check_status api[:SetInterOpNumThreads].call(session_options.read_pointer, inter_op_num_threads) if inter_op_num_threads
26
25
  check_status api[:SetIntraOpNumThreads].call(session_options.read_pointer, intra_op_num_threads) if intra_op_num_threads
27
26
  check_status api[:SetSessionLogSeverityLevel].call(session_options.read_pointer, log_severity_level) if log_severity_level
@@ -31,18 +30,27 @@ module OnnxRuntime
31
30
 
32
31
  # session
33
32
  @session = ::FFI::MemoryPointer.new(:pointer)
34
- path_or_bytes = path_or_bytes.to_str
33
+ from_memory =
34
+ if path_or_bytes.respond_to?(:read)
35
+ path_or_bytes = path_or_bytes.read
36
+ true
37
+ else
38
+ path_or_bytes = path_or_bytes.to_str
39
+ path_or_bytes.encoding == Encoding::BINARY
40
+ end
35
41
 
36
42
  # fix for Windows "File doesn't exist"
37
- if Gem.win_platform? && path_or_bytes.encoding != Encoding::BINARY
43
+ if Gem.win_platform? && !from_memory
38
44
  path_or_bytes = File.binread(path_or_bytes)
45
+ from_memory = true
39
46
  end
40
47
 
41
- if path_or_bytes.encoding == Encoding::BINARY
48
+ if from_memory
42
49
  check_status api[:CreateSessionFromArray].call(env.read_pointer, path_or_bytes, path_or_bytes.bytesize, session_options.read_pointer, @session)
43
50
  else
44
51
  check_status api[:CreateSession].call(env.read_pointer, path_or_bytes, session_options.read_pointer, @session)
45
52
  end
53
+ ObjectSpace.define_finalizer(self, self.class.finalize(@session))
46
54
 
47
55
  # input info
48
56
  allocator = ::FFI::MemoryPointer.new(:pointer)
@@ -73,6 +81,8 @@ module OnnxRuntime
73
81
  check_status api[:SessionGetOutputTypeInfo].call(read_pointer, i, typeinfo)
74
82
  @outputs << {name: name_ptr.read_pointer.read_string}.merge(node_info(typeinfo))
75
83
  end
84
+ ensure
85
+ # release :SessionOptions, session_options
76
86
  end
77
87
 
78
88
  # TODO support logid
@@ -98,6 +108,58 @@ module OnnxRuntime
98
108
  output_names.size.times.map do |i|
99
109
  create_from_onnx_value(output_tensor[i].read_pointer)
100
110
  end
111
+ ensure
112
+ release :RunOptions, run_options
113
+ if input_tensor
114
+ input_feed.size.times do |i|
115
+ release :Value, input_tensor[i]
116
+ end
117
+ end
118
+ end
119
+
120
+ def modelmeta
121
+ keys = ::FFI::MemoryPointer.new(:pointer)
122
+ num_keys = ::FFI::MemoryPointer.new(:int64_t)
123
+ description = ::FFI::MemoryPointer.new(:string)
124
+ domain = ::FFI::MemoryPointer.new(:string)
125
+ graph_name = ::FFI::MemoryPointer.new(:string)
126
+ producer_name = ::FFI::MemoryPointer.new(:string)
127
+ version = ::FFI::MemoryPointer.new(:int64_t)
128
+
129
+ metadata = ::FFI::MemoryPointer.new(:pointer)
130
+ check_status api[:SessionGetModelMetadata].call(read_pointer, metadata)
131
+
132
+ custom_metadata_map = {}
133
+ check_status = api[:ModelMetadataGetCustomMetadataMapKeys].call(metadata.read_pointer, @allocator.read_pointer, keys, num_keys)
134
+ num_keys.read(:int64_t).times do |i|
135
+ key = keys.read_pointer[i * ::FFI::Pointer.size].read_pointer.read_string
136
+ value = ::FFI::MemoryPointer.new(:string)
137
+ check_status api[:ModelMetadataLookupCustomMetadataMap].call(metadata.read_pointer, @allocator.read_pointer, key, value)
138
+ custom_metadata_map[key] = value.read_pointer.read_string
139
+ end
140
+
141
+ check_status api[:ModelMetadataGetDescription].call(metadata.read_pointer, @allocator.read_pointer, description)
142
+ check_status api[:ModelMetadataGetDomain].call(metadata.read_pointer, @allocator.read_pointer, domain)
143
+ check_status api[:ModelMetadataGetGraphName].call(metadata.read_pointer, @allocator.read_pointer, graph_name)
144
+ check_status api[:ModelMetadataGetProducerName].call(metadata.read_pointer, @allocator.read_pointer, producer_name)
145
+ check_status api[:ModelMetadataGetVersion].call(metadata.read_pointer, version)
146
+
147
+ {
148
+ custom_metadata_map: custom_metadata_map,
149
+ description: description.read_pointer.read_string,
150
+ domain: domain.read_pointer.read_string,
151
+ graph_name: graph_name.read_pointer.read_string,
152
+ producer_name: producer_name.read_pointer.read_string,
153
+ version: version.read(:int64_t)
154
+ }
155
+ ensure
156
+ release :ModelMetadata, metadata
157
+ end
158
+
159
+ def end_profiling
160
+ out = ::FFI::MemoryPointer.new(:string)
161
+ check_status api[:SessionEndProfiling].call(read_pointer, @allocator.read_pointer, out)
162
+ out.read_pointer.read_string
101
163
  end
102
164
 
103
165
  private
@@ -181,6 +243,8 @@ module OnnxRuntime
181
243
  output_tensor_size = api[:GetTensorShapeElementCount].call(typeinfo.read_pointer, out_size)
182
244
  output_tensor_size = read_size_t(out_size)
183
245
 
246
+ release :TensorTypeAndShapeInfo, typeinfo
247
+
184
248
  # TODO support more types
185
249
  type = FFI::TensorElementDataType[type]
186
250
  arr =
@@ -213,6 +277,7 @@ module OnnxRuntime
213
277
  check_status api[:GetValue].call(out_ptr, 1, @allocator.read_pointer, map_values)
214
278
  check_status api[:GetTensorTypeAndShape].call(map_keys.read_pointer, type_shape)
215
279
  check_status api[:GetTensorElementType].call(type_shape.read_pointer, elem_type)
280
+ release :TensorTypeAndShapeInfo, type_shape
216
281
 
217
282
  # TODO support more types
218
283
  elem_type = FFI::TensorElementDataType[elem_type.read_int]
@@ -239,7 +304,7 @@ module OnnxRuntime
239
304
 
240
305
  def check_status(status)
241
306
  unless status.null?
242
- message = api[:GetErrorMessage].call(status)
307
+ message = api[:GetErrorMessage].call(status).read_string
243
308
  api[:ReleaseStatus].call(status)
244
309
  raise OnnxRuntime::Error, message
245
310
  end
@@ -253,6 +318,7 @@ module OnnxRuntime
253
318
  case type
254
319
  when :tensor
255
320
  tensor_info = ::FFI::MemoryPointer.new(:pointer)
321
+ # don't free tensor_info
256
322
  check_status api[:CastTypeInfoToTensorInfo].call(typeinfo.read_pointer, tensor_info)
257
323
 
258
324
  type, shape = tensor_type_and_shape(tensor_info)
@@ -261,22 +327,39 @@ module OnnxRuntime
261
327
  shape: shape
262
328
  }
263
329
  when :sequence
264
- # TODO show nested
330
+ sequence_type_info = ::FFI::MemoryPointer.new(:pointer)
331
+ check_status api[:CastTypeInfoToSequenceTypeInfo].call(typeinfo.read_pointer, sequence_type_info)
332
+ nested_type_info = ::FFI::MemoryPointer.new(:pointer)
333
+ check_status api[:GetSequenceElementType].call(sequence_type_info.read_pointer, nested_type_info)
334
+ v = node_info(nested_type_info)[:type]
335
+
265
336
  {
266
- type: "seq",
337
+ type: "seq(#{v})",
267
338
  shape: []
268
339
  }
269
340
  when :map
270
- # TODO show nested
341
+ map_type_info = ::FFI::MemoryPointer.new(:pointer)
342
+ check_status api[:CastTypeInfoToMapTypeInfo].call(typeinfo.read_pointer, map_type_info)
343
+
344
+ # key
345
+ key_type = ::FFI::MemoryPointer.new(:int)
346
+ check_status api[:GetMapKeyType].call(map_type_info.read_pointer, key_type)
347
+ k = FFI::TensorElementDataType[key_type.read_int]
348
+
349
+ # value
350
+ value_type_info = ::FFI::MemoryPointer.new(:pointer)
351
+ check_status api[:GetMapValueType].call(map_type_info.read_pointer, value_type_info)
352
+ v = node_info(value_type_info)[:type]
353
+
271
354
  {
272
- type: "map",
355
+ type: "map(#{k},#{v})",
273
356
  shape: []
274
357
  }
275
358
  else
276
359
  unsupported_type("ONNX", type)
277
360
  end
278
361
  ensure
279
- api[:ReleaseTypeInfo].call(typeinfo.read_pointer)
362
+ release :TypeInfo, typeinfo
280
363
  end
281
364
 
282
365
  def tensor_type_and_shape(tensor_info)
@@ -307,7 +390,24 @@ module OnnxRuntime
307
390
  end
308
391
 
309
392
  def api
310
- @api ||= FFI.OrtGetApiBase[:GetApi].call(1)
393
+ self.class.api
394
+ end
395
+
396
+ def release(*args)
397
+ self.class.release(*args)
398
+ end
399
+
400
+ def self.api
401
+ @api ||= FFI.OrtGetApiBase[:GetApi].call(3)
402
+ end
403
+
404
+ def self.release(type, pointer)
405
+ api[:"Release#{type}"].call(pointer.read_pointer) if pointer && !pointer.null?
406
+ end
407
+
408
+ def self.finalize(session)
409
+ # must use proc instead of stabby lambda
410
+ proc { release :Session, session }
311
411
  end
312
412
 
313
413
  def env
@@ -316,7 +416,7 @@ module OnnxRuntime
316
416
  @@env ||= begin
317
417
  env = ::FFI::MemoryPointer.new(:pointer)
318
418
  check_status api[:CreateEnv].call(3, "Default", env)
319
- at_exit { api[:ReleaseEnv].call(env.read_pointer) }
419
+ at_exit { release :Env, env }
320
420
  # disable telemetry
321
421
  # https://github.com/microsoft/onnxruntime/blob/master/docs/Privacy.md
322
422
  check_status api[:DisableTelemetryEvents].call(env)
@@ -22,5 +22,9 @@ module OnnxRuntime
22
22
  def outputs
23
23
  @session.outputs
24
24
  end
25
+
26
+ def metadata
27
+ @session.modelmeta
28
+ end
25
29
  end
26
30
  end
@@ -1,3 +1,3 @@
1
1
  module OnnxRuntime
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.3"
3
3
  end
Binary file
Binary file
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: onnxruntime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-24 00:00:00.000000000 Z
11
+ date: 2020-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
108
  requirements: []
109
- rubygems_version: 3.0.3
109
+ rubygems_version: 3.1.2
110
110
  signing_key:
111
111
  specification_version: 4
112
112
  summary: High performance scoring engine for ML models