Converts an array into a TensorProto including Args: array: a numpy array. name: (optional) the name of the tensor. Returns: TensorProto: the converted tensor def.
(array: np.ndarray, /, name: str | None = None)
| 319 | |
| 320 | |
| 321 | def from_array(array: np.ndarray, /, name: str | None = None) -> onnx.TensorProto: |
| 322 | """Converts an array into a TensorProto including |
| 323 | |
| 324 | Args: |
| 325 | array: a numpy array. |
| 326 | name: (optional) the name of the tensor. |
| 327 | |
| 328 | Returns: |
| 329 | TensorProto: the converted tensor def. |
| 330 | """ |
| 331 | tensor = onnx.TensorProto() |
| 332 | tensor.dims.extend(array.shape) |
| 333 | if name: |
| 334 | tensor.name = name |
| 335 | if array.dtype == object or np.issubdtype(array.dtype, np.str_): |
| 336 | # Special care for strings. |
| 337 | tensor.data_type = onnx.TensorProto.STRING |
| 338 | # TODO: Introduce full string support. |
| 339 | # We flatten the array in case there are n-D arrays are specified |
| 340 | # If you want more complex shapes then follow the below instructions. |
| 341 | # Unlike other types where the shape is automatically inferred from |
| 342 | # nested arrays of values, the only reliable way now to feed strings |
| 343 | # is to put them into a flat array then specify type astype(object) |
| 344 | # (otherwise all strings may have different types depending on their length) |
| 345 | # and then specify shape .reshape([x, y, z]) |
| 346 | flat_array = array.flatten() |
| 347 | for e in flat_array: |
| 348 | if isinstance(e, str): |
| 349 | tensor.string_data.append(e.encode("utf-8")) |
| 350 | elif isinstance(e, bytes): |
| 351 | tensor.string_data.append(e) |
| 352 | else: |
| 353 | raise NotImplementedError( |
| 354 | f"Unrecognized object in the object array, expect a string, or array of bytes: {type(e)}" |
| 355 | ) |
| 356 | return tensor |
| 357 | |
| 358 | dtype = helper.np_dtype_to_tensor_dtype(array.dtype) |
| 359 | if dtype in { |
| 360 | onnx.TensorProto.INT4, |
| 361 | onnx.TensorProto.UINT4, |
| 362 | onnx.TensorProto.FLOAT4E2M1, |
| 363 | }: |
| 364 | # Pack the array into int4 |
| 365 | array = _pack_4bitx2(array) |
| 366 | |
| 367 | if dtype in { |
| 368 | onnx.TensorProto.UINT2, |
| 369 | onnx.TensorProto.INT2, |
| 370 | }: |
| 371 | # Pack the array into int2 |
| 372 | array = _pack_2bitx4(array) |
| 373 | |
| 374 | tensor.raw_data = tobytes_little_endian(array) |
| 375 | tensor.data_type = dtype # type: ignore[assignment] |
| 376 | return tensor |
| 377 | |
| 378 |
searching dependent graphs…