Mod#

Mod - 13#

Version

  • name: Mod (GitHub)

  • domain: main

  • since_version: 13

  • function: False

  • support_level: SupportType.COMMON

  • shape inference: True

This version of the operator has been available since version 13.

Summary

Performs element-wise binary modulus (with Numpy-style broadcasting support).

The sign of the remainder is the same as that of the Divisor.

Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend (in contrast to integer mod). To force a behavior like numpy.fmod() an ‘fmod’ Attribute is provided. This attribute is set to 0 by default causing the behavior to be like integer mod. Setting this attribute to 1 causes the remainder to be calculated similar to that of numpy.fmod().

If the input type is floating point, then fmod attribute must be set to 1.

In case of dividend being zero, the results will be platform dependent.

This operator supports multidirectional (i.e., Numpy-style) broadcasting; for more details please check Broadcasting in ONNX.

Attributes

  • fmod: Whether the operator should behave like fmod (default=0 meaning it will do integer mods); Set this to 1 to force fmod treatment

Inputs

  • A (heterogeneous) - T: Dividend tensor

  • B (heterogeneous) - T: Divisor tensor

Outputs

  • C (heterogeneous) - T: Remainder tensor

Type Constraints

  • T in ( tensor(bfloat16), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input and output types to high-precision numeric tensors.

Examples

_mod_mixed_sign_float64

import numpy as np
import onnx

node = onnx.helper.make_node("Mod", inputs=["x", "y"], outputs=["z"], fmod=1)

x = np.array([-4.3, 7.2, 5.0, 4.3, -7.2, 8.0]).astype(np.float64)
y = np.array([2.1, -3.4, 8.0, -2.1, 3.4, 5.0]).astype(np.float64)
z = np.fmod(x, y)  # expected output [-0.1,  0.4,  5. ,  0.1, -0.4,  3.]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_mixed_sign_float64")

_mod_mixed_sign_float32

import numpy as np
import onnx

node = onnx.helper.make_node("Mod", inputs=["x", "y"], outputs=["z"], fmod=1)

x = np.array([-4.3, 7.2, 5.0, 4.3, -7.2, 8.0]).astype(np.float32)
y = np.array([2.1, -3.4, 8.0, -2.1, 3.4, 5.0]).astype(np.float32)
z = np.fmod(
    x, y
)  # expected output [-0.10000038, 0.39999962, 5. , 0.10000038, -0.39999962, 3.]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_mixed_sign_float32")

_mod_mixed_sign_float16

import numpy as np
import onnx

node = onnx.helper.make_node("Mod", inputs=["x", "y"], outputs=["z"], fmod=1)

x = np.array([-4.3, 7.2, 5.0, 4.3, -7.2, 8.0]).astype(np.float16)
y = np.array([2.1, -3.4, 8.0, -2.1, 3.4, 5.0]).astype(np.float16)
z = np.fmod(
    x, y
)  # expected output [-0.10156, 0.3984 , 5. , 0.10156, -0.3984 ,  3.]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_mixed_sign_float16")

_mod_mixed_sign_int64

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([-4, 7, 5, 4, -7, 8]).astype(np.int64)
y = np.array([2, -3, 8, -2, 3, 5]).astype(np.int64)
z = np.mod(x, y)  # expected output [ 0, -2,  5,  0,  2,  3]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_mixed_sign_int64")

_mod_mixed_sign_int32

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([-4, 7, 5, 4, -7, 8]).astype(np.int32)
y = np.array([2, -3, 8, -2, 3, 5]).astype(np.int32)
z = np.mod(x, y)  # expected output [ 0, -2,  5,  0,  2,  3]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_mixed_sign_int32")

_mod_mixed_sign_int16

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([-4, 7, 5, 4, -7, 8]).astype(np.int16)
y = np.array([2, -3, 8, -2, 3, 5]).astype(np.int16)
z = np.mod(x, y)  # expected output [ 0, -2,  5,  0,  2,  3]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_mixed_sign_int16")

_mod_mixed_sign_int8

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([-4, 7, 5, 4, -7, 8]).astype(np.int8)
y = np.array([2, -3, 8, -2, 3, 5]).astype(np.int8)
z = np.mod(x, y)  # expected output [ 0, -2,  5,  0,  2,  3]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_mixed_sign_int8")

_mod_uint8

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([4, 7, 5]).astype(np.uint8)
y = np.array([2, 3, 8]).astype(np.uint8)
z = np.mod(x, y)  # expected output [0, 1, 5]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_uint8")

_mod_uint16

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([4, 7, 5]).astype(np.uint16)
y = np.array([2, 3, 8]).astype(np.uint16)
z = np.mod(x, y)  # expected output [0, 1, 5]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_uint16")

_mod_uint32

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([4, 7, 5]).astype(np.uint32)
y = np.array([2, 3, 8]).astype(np.uint32)
z = np.mod(x, y)  # expected output [0, 1, 5]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_uint32")

_mod_uint64

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.array([4, 7, 5]).astype(np.uint64)
y = np.array([2, 3, 8]).astype(np.uint64)
z = np.mod(x, y)  # expected output [0, 1, 5]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_uint64")

_mod_int64_fmod

import numpy as np
import onnx

node = onnx.helper.make_node("Mod", inputs=["x", "y"], outputs=["z"], fmod=1)

x = np.array([-4, 7, 5, 4, -7, 8]).astype(np.int64)
y = np.array([2, -3, 8, -2, 3, 5]).astype(np.int64)
z = np.fmod(x, y)  # expected output [ 0,  1,  5,  0, -1,  3]
expect(node, inputs=[x, y], outputs=[z], name="test_mod_int64_fmod")

_mod_broadcast

import numpy as np
import onnx

node = onnx.helper.make_node(
    "Mod",
    inputs=["x", "y"],
    outputs=["z"],
)

x = np.arange(0, 30).reshape([3, 2, 5]).astype(np.int32)
y = np.array([7]).astype(np.int32)
z = np.mod(x, y)
#   array([[[0, 1, 2, 3, 4],
#     [5, 6, 0, 1, 2]],

#    [[3, 4, 5, 6, 0],
#     [1, 2, 3, 4, 5]],

#    [[6, 0, 1, 2, 3],
#     [4, 5, 6, 0, 1]]], dtype=int32)
expect(node, inputs=[x, y], outputs=[z], name="test_mod_broadcast")

Mod - 10#

Version

  • name: Mod (GitHub)

  • domain: main

  • since_version: 10

  • function: False

  • support_level: SupportType.COMMON

  • shape inference: True

This version of the operator has been available since version 10.

Summary

Performs element-wise binary modulus (with Numpy-style broadcasting support).

The sign of the remainder is the same as that of the Divisor.

Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend (in contrast to integer mod). To force a behavior like numpy.fmod() an ‘fmod’ Attribute is provided. This attribute is set to 0 by default causing the behavior to be like integer mod. Setting this attribute to 1 causes the remainder to be calculated similar to that of numpy.fmod().

If the input type is floating point, then fmod attribute must be set to 1.

In case of dividend being zero, the results will be platform dependent.

This operator supports multidirectional (i.e., Numpy-style) broadcasting; for more details please check Broadcasting in ONNX.

Attributes

  • fmod: Whether the operator should behave like fmod (default=0 meaning it will do integer mods); Set this to 1 to force fmod treatment

Inputs

  • A (heterogeneous) - T: Dividend tensor

  • B (heterogeneous) - T: Divisor tensor

Outputs

  • C (heterogeneous) - T: Remainder tensor

Type Constraints

  • T in ( tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input and output types to high-precision numeric tensors.