array-api-comparison
array-api-comparison copied to clipboard
ONNX
We at ONNX are working on the roadmap and I'm proposing that we adopt the numpy array API definition and eventually the array API standard from the outcome of this work group. ONNX is a model exchange standard for the deep learning frameworks. The array API comparison exercise here is very helpful and it would be great if we could include the ONNX in the comparison here.
The definition of array API functions can be found here.
@szha Thanks for the links! I'll look into the ONNX array API functions, and at a minimum add it to the "join" dataset, which compares across all libraries.
@kgryte did you get a chance to look at ONNX? Let me know if you need anything else.
I suspect part of the hold up here is that ONNX doesn't use Sphinx, so the tooling may not be as easily adjusted. Still would be good to include in the overview.
| A | B | C | D | E | F | G | H | I | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | numpy | cupy | dask.array | jax | mxnet | pytorch | tensorflow | onnx runtime | ONNX Extra Operator |
| 2 | numpy.absolute | absolute | absolute | absolute | abs | math.abs | Abs | AveragePool | |
| 3 | numpy.add | add | add | add | add | math.add | Add | BatchNormalization | |
| 4 | numpy.all | all | all | alltrue | reduce_all | Cast | |||
| 5 | numpy.allclose | allclose | allclose | allclose | allclose | Compress | |||
| 6 | numpy.amax | max | max | max | amax | math.reduce_max | Constant | ||
| 7 | numpy.amin | min | min | min | amin | math.reduce_min | ConstantOfShape | ||
| 8 | numpy.angle | angle | angle | angle | angle | angle | math.angle | Conv | |
| 9 | numpy.any | any | any | sometrue | math.reduce_any | ConvInteger | |||
| 10 | numpy.arange | arange | arange | arange | arange | range | range | ConvTranspose | |
| 11 | numpy.arccos | arccos | arccos | arccos | arccos | acos | math.acos | Acos | DepthToSpace |
| 12 | numpy.arccosh | arccosh | arccosh | arccosh | arccosh | math.acosh | Acosh | DequantizeLinear | |
| 13 | numpy.arcsin | arcsin | arcsin | arcsin | arcsin | asin | math.asin | Asin | Dropout |
| 14 | numpy.arcsinh | arcsinh | arcsinh | arcsinh | arcsinh | math.asinh | Asinh | Elu | |
| 15 | numpy.arctan | arctan | arctan | arctan | arctan | atan | math.atan | Atan | Erf |
| 16 | numpy.arctan2 | arctan2 | arctan2 | arctan2 | arctan2 | atan2 | math.atan2 | EyeLike | |
| 17 | numpy.arctanh | arctanh | arctanh | arctanh | arctanh | math.atanh | Atanh | Flatten | |
| 18 | numpy.argmax | argmax | argmax | argmax | argmax | argmax | math.argmax | ArgMax | GRU |
| 19 | numpy.argmin | argmin | argmin | argmin | argmin | argmin | math.argmin | ArgMin | Gather |
| 20 | numpy.argsort | argsort | argsort | argsort | argsort | argsort | GatherElements | ||
| 21 | numpy.around | around | round | around | around | GatherND | |||
| 22 | numpy.array | array | array | array | array | tensor | make_ndarray | Gemm | |
| 23 | numpy.asarray | asarray | asarray | asarray | asarray | convert_to_tensor | GlobalAveragePool | ||
| 24 | numpy.atleast_1d | atleast_1d | atleast_1d | atleast_1d | atleast_1d | GlobalLpPool | |||
| 25 | numpy.atleast_2d | atleast_2d | atleast_2d | atleast_2d | atleast_2d | GlobalMaxPool | |||
| 26 | numpy.atleast_3d | atleast_3d | atleast_3d | atleast_3d | atleast_3d | HardSigmoid | |||
| 27 | numpy.bincount | bincount | bincount | bincount | bincount | math.bincount | Hardmax | ||
| 28 | numpy.bitwise_and | bitwise_and | bitwise_and | bitwise_and | bitwise_and | bitwise.bitwise_and | |||
| 29 | numpy.bitwise_or | bitwise_or | bitwise_or | bitwise_or | bitwise_or | bitwise.bitwise_or | If | ||
| 30 | numpy.bitwise_xor | bitwise_xor | bitwise_xor | bitwise_xor | bitwise_xor | bitwise.bitwise_xor | InstanceNormalization | ||
| 31 | numpy.broadcast_arrays | broadcast_arrays | broadcast_arrays | broadcast_arrays | broadcast_arrays | broadcast_tensors | LRN | ||
| 32 | numpy.broadcast_to | broadcast_to | broadcast_to | broadcast_to | broadcast_to | broadcast_to | Expand | LSTM | |
| 33 | numpy.ceil | ceil | ceil | ceil | ceil | ceil | math.ceil | Ceil | LeakyRelu |
| 34 | numpy.clip | clip | clip | clip | clip | clip_by_value | Clip | LogSoftmax | |
| 35 | numpy.concatenate | concatenate | concatenate | concatenate | concatenate | cat | concat | Concat | Loop |
| 36 | numpy.conj | conj | conj | conj | conj | conj | math.conj | LpNormalization | |
| 37 | numpy.copysign | copysign | copysign | copysign | copysign | LpPool | |||
| 38 | numpy.corrcoef | corrcoef | corrcoef | corrcoef | corrcoef | MaxPool | |||
| 39 | numpy.cos | cos | cos | cos | cos | cos | math.cos | Cos | MaxRoiPool |
| 40 | numpy.cosh | cosh | cosh | cosh | cosh | cosh | math.cosh | Cosh | MaxUnpool |
| 41 | numpy.count_nonzero | count_nonzero | count_nonzero | count_nonzero | count_nonzero | math.count_nonzero | Multinomial | ||
| 42 | numpy.cov | cov | cov | cov | cov | NonMaxSuppression | |||
| 43 | numpy.cross | cross | cross | cross | cross | linalg.cross | NonZero | ||
| 44 | numpy.cumprod | cumprod | cumprod | cumproduct | cumprod | cumprod | math.cumprod | OneHot | |
| 45 | numpy.cumsum | cumsum | cumsum | cumsum | cumsum | cumsum | math.cumsum | CumSum | PRelu |
| 46 | numpy.deg2rad | deg2rad | deg2rad | deg2rad | deg2rad | QLinearConv | |||
| 47 | numpy.degrees | degrees | degrees | degrees | degrees | QLinearMatMul | |||
| 48 | numpy.diag | diag | diag | diag | diag | diag | linalg.diag | QuantizeLinear | |
| 49 | numpy.diagonal | diagonal | diagonal | diagonal | diagonal | diagonal | linalg.diag_part | RNN | |
| 50 | numpy.divide | divide | divide | divide | div | math.divide | Div | RandomNormal | |
| 51 | numpy.dot | dot | dot | dot | dot | RandomNormalLike | |||
| 52 | numpy.dstack | dstack | dstack | dstack | dstack | ConcatFromSequence | RandomUniform | ||
| 53 | numpy.einsum | einsum | einsum | einsum | einsum | einsum | einsum | Einsum | RandomUniformLike |
| 54 | numpy.empty | empty | empty | empty | empty | empty | Reciprocal | ||
| 55 | numpy.empty_like | empty_like | empty_like | empty_like | empty_like | empty_like | ReduceL1 | ||
| 56 | numpy.equal | equal | equal | eq | math.equal | Equal | ReduceL2 | ||
| 57 | numpy.exp | exp | exp | exp | exp | exp | math.exp | Exp | ReduceLogSum |
| 58 | numpy.expand_dims | expand_dims | expand_dims | expand_dims | unsqueeze | expand_dims | Unsqueeze | ReduceLogSumExp | |
| 59 | numpy.expm1 | expm1 | expm1 | expm1 | expm1 | expm1 | math.expm1 | ReduceMax | |
| 60 | numpy.eye | eye | eye | eye | eye | eye | eye | Identity | ReduceMean |
| 61 | numpy.fft.fft | fft.fft | fft.fft | fft | fft | signal.fft | ReduceMin | ||
| 62 | numpy.fft.fft2 | fft.fft2 | fft.fft2 | fft2 | signal.fft2d | ReduceProd | |||
| 63 | numpy.fft.fftn | fft.fftn | fft.fftn | fftn | signal.fft3d | ReduceSum | |||
| 64 | numpy.fft.fftshift | fft.fftshift | fft.fftshift | fftshift | signal.fftshift | BitShift | ReduceSumSquare | ||
| 65 | numpy.fft.ifft | fft.ifft | fft.ifft | ifft | ifft | signal.ifft | Relu | ||
| 66 | numpy.fft.ifft2 | fft.ifft2 | fft.ifft2 | ifft2 | signal.ifft2d | Resize | |||
| 67 | numpy.fft.ifftn | fft.ifftn | fft.ifftn | ifftn | signal.ifft3d | ReverseSequence | |||
| 68 | numpy.fft.ifftshift | fft.ifftshift | fft.ifftshift | ifftshift | signal.ifftshift | BitShift | RoiAlign | ||
| 69 | numpy.fft.irfft | fft.irfft | fft.irfft | irfft | irfft | signal.irfft | Scan | ||
| 70 | numpy.fft.irfft2 | fft.irfft2 | fft.irfft2 | irfft2 | signal.irfft2d | Scatter (deprecated) | |||
| 71 | numpy.fft.irfftn | fft.irfftn | fft.irfftn | irfftn | signal.irfft3d | ScatterElements | |||
| 72 | numpy.fft.rfft | fft.rfft | fft.rfft | rfft | rfft | signal.rfft | ScatterND | ||
| 73 | numpy.fft.rfft2 | fft.rfft2 | fft.rfft2 | rfft2 | signal.rfft2d | Selu | |||
| 74 | numpy.fft.rfftn | fft.rfftn | fft.rfftn | rfftn | signal.rfft3d | SequenceAt | |||
| 75 | numpy.fix | fix | fix | fix | fix | SequenceConstruct | |||
| 76 | numpy.flip | flip | flip | flip | flip | flip | reverse | SequenceEmpty | |
| 77 | numpy.fliplr | fliplr | fliplr | fliplr | fliplr | SequenceErase | |||
| 78 | numpy.flipud | flipud | flipud | flipud | flipud | SequenceInsert | |||
| 79 | numpy.floor | floor | floor | floor | floor | floor | math.floor | Floor | SequenceLength |
| 80 | numpy.floor_divide | floor_divide | floor_divide | floor_divide | floor_divide | math.floordiv | Shape | ||
| 81 | numpy.fmax | fmax | fmax | fmax | fmax | Shrink | |||
| 82 | numpy.fmin | fmin | fmin | fmin | fmin | Sigmoid | |||
| 83 | numpy.fmod | fmod | fmod | fmod | fmod | fmod | Size | ||
| 84 | numpy.frexp | frexp | frexp | frexp | frexp | Slice | |||
| 85 | numpy.full | full | full | full | full | full | fill | Softmax | |
| 86 | numpy.full_like | full_like | full_like | full_like | full_like | full_like | Softplus | ||
| 87 | numpy.greater | greater | greater | gt | math.greater | Greater | Softsign | ||
| 88 | numpy.greater_equal | greater_equal | greater_equal | ge | math.greater_equal | SpaceToDepth | |||
| 89 | numpy.histogram | histogram | histogram | histogram | histc | SplitToSequence | |||
| 90 | numpy.hstack | hstack | hstack | hstack | hstack | ConcatFromSequence | StringNormalizer | ||
| 91 | numpy.hypot | hypot | hypot | hypot | hypot | TfIdfVectorizer | |||
| 92 | numpy.imag | imag | imag | imag | imag | imag | math.imag | ThresholdedRelu | |
| 93 | numpy.inner | inner | inner | inner | dot | TopK | |||
| 94 | numpy.iscomplex | iscomplex | iscomplex | iscomplex | is_complex | Upsample (deprecated) | |||
| 95 | numpy.isfinite | isfinite | isfinite | isfinite | isfinite | math.is_finite | Xor | ||
| 96 | numpy.isinf | isinf | isinf | isinf | isinf | IsInf | Function | ||
| 97 | numpy.isnan | isnan | isnan | isnan | isnan | math.is_nan | IsNaN | Celu | |
| 98 | numpy.isreal | isreal | isreal | isreal | is_floating_point | DynamicQuantizeLinear | |||
| 99 | numpy.ldexp | ldexp | ldexp | ldexp | ldexp | GreaterOrEqual | |||
| 100 | numpy.less | less | less | lt | math.less | Less | LessOrEqual | ||
| 101 | numpy.less_equal | less_equal | less_equal | le | math.less_equal | MeanVarianceNormalization | |||
| 102 | numpy.linalg.cholesky | linalg.cholesky | linalg.cholesky | cholesky | linalg.cholesky | cholesky | linalg.cholesky | NegativeLogLikelihoodLoss | |
| 103 | numpy.linalg.det | linalg.det | det | linalg.det | det | linalg.det | Det | Range | |
| 104 | numpy.linalg.eig | eig | linalg.eig | eig | linalg.eigh | SoftmaxCrossEntropyLoss | |||
| 105 | numpy.linalg.eigvalsh | linalg.eigvalsh | eigvalsh | symeig | linalg.eigvalsh | ||||
| 106 | numpy.linalg.inv | linalg.inv | linalg.inv | inv | linalg.inv | inverse | linalg.inv | ||
| 107 | numpy.linalg.lstsq | linalg.lstsq | linalg.lstsq | linalg.lstsq | lstsq | linalg.lstsq | |||
| 108 | numpy.linalg.matrix_power | linalg.matrix_power | matrix_power | linalg.matrix_power | matrix_power | ||||
| 109 | numpy.linalg.matrix_rank | linalg.matrix_rank | matrix_rank | linalg.matrix_rank | matrix_rank | rank | |||
| 110 | numpy.linalg.norm | linalg.norm | linalg.norm | norm | linalg.norm | norm | norm | ||
| 111 | numpy.linalg.pinv | linalg.pinv | pinv | linalg.pinv | linalg.pinv | ||||
| 112 | numpy.linalg.qr | linalg.qr | linalg.qr | qr | linalg.qr | qr | linalg.qr | ||
| 113 | numpy.linalg.slogdet | linalg.slogdet | slogdet | linalg.slogdet | slogdet | linalg.slogdet | |||
| 114 | numpy.linalg.solve | linalg.solve | linalg.solve | solve | linalg.solve | solve | linalg.solve | ||
| 115 | numpy.linalg.svd | linalg.svd | linalg.svd | svd | linalg.svd | svd | linalg.svd | ||
| 116 | numpy.linspace | linspace | linspace | linspace | linspace | linspace | linspace | ||
| 117 | numpy.log | log | log | log | log | log | math.log | Log | |
| 118 | numpy.log10 | log10 | log10 | log10 | log10 | log10 | |||
| 119 | numpy.log1p | log1p | log1p | log1p | log1p | log1p | math.log1p | ||
| 120 | numpy.log2 | log2 | log2 | log2 | log2 | log2 | |||
| 121 | numpy.logaddexp | logaddexp | logaddexp | logaddexp | logaddexp | logsumexp | math.reduce_logsumexp | ||
| 122 | numpy.logaddexp2 | logaddexp2 | logaddexp2 | logaddexp2 | logaddexp2 | ||||
| 123 | numpy.logical_and | logical_and | logical_and | logical_and | logical_and | math.logical_and | And | ||
| 124 | numpy.logical_not | logical_not | logical_not | logical_not | logical_not | math.logical_not | Not | ||
| 125 | numpy.logical_or | logical_or | logical_or | logical_or | logical_or | math.logical_or | Or | ||
| 126 | numpy.logical_xor | logical_xor | logical_xor | logical_xor | logical_xor | math.logical_xor | |||
| 127 | numpy.logspace | logspace | logspace | logspace | logspace | ||||
| 128 | numpy.matmul | matmul | matmul | matmul | matmul | mm | linalg.matmul | MatMul, MatMulInteger | |
| 129 | numpy.maximum | maximum | maximum | maximum | maximum | max | math.maximum | Max | |
| 130 | numpy.mean | mean | mean | mean | mean | mean | math.reduce_mean | Mean | |
| 131 | numpy.median | median | median | median | median | ||||
| 132 | numpy.meshgrid | meshgrid | meshgrid | meshgrid | meshgrid | meshgrid | meshgrid | ||
| 133 | numpy.minimum | minimum | minimum | minimum | minimum | min | math.minimum | Min | |
| 134 | numpy.mod | mod | mod | mod | math.floormod | Mod | |||
| 135 | numpy.moveaxis | moveaxis | moveaxis | moveaxis | moveaxis | ||||
| 136 | numpy.multiply | multiply | multiply | multiply | mul | math.multiply | Mul | ||
| 137 | numpy.nan_to_num | nan_to_num | nan_to_num | nan_to_num | nan_to_num | ||||
| 138 | numpy.nanmax | nanmax | nanmax | nanmax | nanmax | ||||
| 139 | numpy.nanmin | nanmin | nanmin | nanmin | nanmin | ||||
| 140 | numpy.nanprod | nanprod | nanprod | nanprod | nanprod | ||||
| 141 | numpy.nansum | nansum | nansum | nansum | nansum | ||||
| 142 | numpy.negative | negative | negative | negative | neg | math.negative | Neg | ||
| 143 | numpy.nextafter | nextafter | nextafter | nextafter | nextafter | math.nextafter | |||
| 144 | numpy.nonzero | nonzero | nonzero | nonzero | nonzero | nonzero | |||
| 145 | numpy.not_equal | not_equal | not_equal | ne | math.not_equal | ||||
| 146 | numpy.ones | ones | ones | ones | ones | ones | ones | ||
| 147 | numpy.ones_like | ones_like | ones_like | ones_like | ones_like | ones_like | ones_like | ||
| 148 | numpy.outer | outer | outer | outer | outer | ger | |||
| 149 | numpy.pad | pad | pad | pad | pad | Pad | |||
| 150 | numpy.percentile | percentile | percentile | percentile | percentile | ||||
| 151 | numpy.power | power | power | power | pow | math.pow | Pow | ||
| 152 | numpy.prod | prod | prod | product | prod | prod | math.reduce_prod | ||
| 153 | numpy.rad2deg | rad2deg | rad2deg | rad2deg | rad2deg | ||||
| 154 | numpy.radians | radians | radians | radians | radians | ||||
| 155 | numpy.ravel | ravel | ravel | ravel | ravel | ||||
| 156 | numpy.real | real | real | real | real | real | math.real | ||
| 157 | numpy.reciprocal | reciprocal | reciprocal | reciprocal | math.reciprocal | ||||
| 158 | numpy.remainder | remainder | remainder | remainder | remainder | ||||
| 159 | numpy.repeat | repeat | repeat | repeat | repeat | repeat | |||
| 160 | numpy.reshape | reshape | reshape | reshape | reshape | reshape | reshape | Reshape | |
| 161 | numpy.result_type | result_type | result_type | result_type | result_type | ||||
| 162 | numpy.rint | rint | rint | rint | rint | math.rint | |||
| 163 | numpy.roll | roll | roll | roll | roll | roll | roll | ||
| 164 | numpy.rollaxis | rollaxis | rollaxis | rollaxis | rollaxis | ||||
| 165 | numpy.rot90 | rot90 | rot90 | rot90 | rot90 | ||||
| 166 | numpy.round_ | round_ | round | round_ | round | math.round | Round | ||
| 167 | numpy.sign | sign | sign | sign | sign | sign | math.sign | Sign | |
| 168 | numpy.signbit | signbit | signbit | signbit | signbit | ||||
| 169 | numpy.sin | sin | sin | sin | sin | sin | math.sin | Sin | |
| 170 | numpy.sinh | sinh | sinh | sinh | sinh | sinh | math.sinh | Sinh | |
| 171 | numpy.sort | sort | sort | sort | sort | sort | |||
| 172 | numpy.split | split | split | split | split | split | Split | ||
| 173 | numpy.sqrt | sqrt | sqrt | sqrt | sqrt | sqrt | math.sqrt | Sqrt | |
| 174 | numpy.square | square | square | square | square | square | math.square | ||
| 175 | numpy.squeeze | squeeze | squeeze | squeeze | squeeze | squeeze | squeeze | Squeeze | |
| 176 | numpy.stack | stack | stack | stack | stack | stack | stack | ConcatFromSequence | |
| 177 | numpy.std | std | std | std | std | std | math.reduce_std | ||
| 178 | numpy.subtract | subtract | subtract | subtract | math.subtract | Sub | |||
| 179 | numpy.sum | sum | sum | sum | sum | sum | math.reduce_sum | Sum | |
| 180 | numpy.take | take | take | take | take | ||||
| 181 | numpy.tan | tan | tan | tan | tan | tan | math.tan | Tan | |
| 182 | numpy.tanh | tanh | tanh | tanh | tanh | tanh | math.tanh | Tanh | |
| 183 | numpy.tensordot | tensordot | tensordot | tensordot | tensordot | tensordot | tensordot | ||
| 184 | numpy.tile | tile | tile | tile | tile | tile | Tile | ||
| 185 | numpy.trace | trace | trace | trace | trace | trace | linalg.trace | ||
| 186 | numpy.transpose | transpose | transpose | transpose | transpose | transpose | transpose | Transpose | |
| 187 | numpy.tril | tril | tril | tril | tril | tril | |||
| 188 | numpy.triu | triu | triu | triu | triu | triu | |||
| 189 | numpy.true_divide | true_divide | true_divide | true_divide | true_divide | math.truediv | |||
| 190 | numpy.trunc | trunc | trunc | trunc | trunc | trunc | truncatediv | ||
| 191 | numpy.unique | unique | unique | unique | unique | unique | Unique | ||
| 192 | numpy.var | var | var | var | var | var | math.reduce_variance | ||
| 193 | numpy.vdot | vdot | vdot | vdot | vdot | ||||
| 194 | numpy.vstack | vstack | vstack | vstack | vstack | ConcatFromSequence | |||
| 195 | numpy.where | where | where | where | where | where | where | Where | |
| 196 | numpy.zeros | zeros | zeros | zeros | zeros | zeros | zeros | ||
| 197 | numpy.zeros_like | zeros_like | zeros_like | zeros_like | zeros_like | zeros_like | zeros_like |
Thanks @szha! Question about scope: is ONNX in principle interested to add all the listed functions/operators, or are there sets of functionality that are out of scope?
Scrolling through the list one possible correction: ONNX's Identity probably maps to eye.
@rgommers good catch. thanks. In terms of scope, the ONNX steering committee and operator SIG lead are generally in favor of supporting the operators in the array library standard first. We haven't committed to implementing all the above operators yet, and the community will need to review the draft standard first to decide.