def get_gelu_pattern1():
    """
    y = x * (0.5 * (tanh(((.0447)x^3 + x ) * sqrt(2/pi)) + 1))


    [...] -----> pow (3) ----> mul (.044715) ---> add -----> mul (sqrt(2/pi)) ---> tanh ----> add (1) ----> mul (0.5) -----> mul ---> [...]
      |                                            ^                                                                          ^
      |                                            |                                                                          |
      |------------------------------------------------------------------------------------------------------------------------

    """
    @mb.program(input_specs=[mb.TensorSpec(shape=([get_new_symbol(), get_new_symbol(), get_new_symbol()])), ])
    def gelu_to_detect_1(x):
        # MIL operation takes named inputs (instead of positional inputs).
        # Here `name` argument is MANDATORY.
        pow = mb.pow(x=x, y=3.0, name="pow")
        mul_1 = mb.mul(x=0.044714998453855515, y=pow, name="mul_1")
        add = mb.add(x=x, y=mul_1, name="add")
        mul_2 = mb.mul(x=0.7978845834732056, y=add, name="mul_2")
        tanh = mb.tanh(x=mul_2, name="tanh")
        add_1 = mb.add(x=1.0, y=tanh, name="add_1")
        mul = mb.mul(x=0.5, y=add_1, name="mul")
        mul_3 = mb.mul(x=mul, y=x, name="mul_3")
        return mul_3

    return gelu_to_detect_1
def get_gelu_pattern2():
    """
    y = (0.5 * x) * (tanh(((.0447)x^3 + x ) * sqrt(2/pi)) + 1)

                    ---------------------------------------------------------------------------------------------------------
                    ^                                                                                                       |
                    |                                                                                                       V
     [...] -----> mul(0.5)    pow (3) ----> mul (.044715) ---> add -----> mul (sqrt(2/pi)) ---> tanh ----> add (1) -----> mul ---> [...]
      |                         ^                               ^
      |                         |                               |
      |------------------------------------------------------------
    """
    @mb.program(input_specs=[mb.TensorSpec(shape=([get_new_symbol(), get_new_symbol(), get_new_symbol()])), ])
    def gelu_to_detect_2(x):
        pow = mb.pow(x=x, y=3.0, name="pow")
        mul_1 = mb.mul(x=0.044714998453855515, y=pow, name="mul_1")
        add = mb.add(x=x, y=mul_1, name="add")
        mul_2 = mb.mul(x=0.7978845834732056, y=add, name="mul_2")
        tanh = mb.tanh(x=mul_2, name="tanh")
        add_1 = mb.add(x=1.0, y=tanh, name="add_1")
        mul = mb.mul(x=0.5, y=x, name="mul")
        mul_3 = mb.mul(x=mul, y=add_1, name="mul_3")
        return mul_3

    return gelu_to_detect_2
Ejemplo n.º 3
0
    def test_tutorial():
        from coremltools.converters.mil import Builder as mb

        @mb.program(
            input_specs=[mb.TensorSpec(shape=(1, 100, 100, 3)),]
        )
        def prog(x):
            x = mb.relu(x=x, name="relu")
            x = mb.transpose(x=x, perm=[0, 3, 1, 2], name="transpose")
            x = mb.reduce_mean(x=x, axes=[2, 3], keep_dims=False, name="reduce")
            x = mb.log(x=x, name="log")
            y = mb.add(x=1, y=2)
            return x

        print("prog:\n", prog)

        # Convert and verify
        from coremltools.converters.mil.converter import _convert
        from coremltools import models

        proto = _convert(prog, convert_from="mil")

        model = models.MLModel(proto)

        # running predict() is only supported on macOS
        if ct.utils._is_macos():
            prediction = model.predict(
                {"x": np.random.rand(1, 100, 100, 3).astype(np.float32),}
            )
            assert len(prediction) == 1
Ejemplo n.º 4
0
    def test_rename_feature_mlprogram(self):
        @mb.program(input_specs=[mb.TensorSpec(shape=(3, ))])
        def linear_prog(input):
            W = np.ones((10, 3), dtype=np.float)
            out = mb.linear(x=input, weight=W, name="output")
            return out

        model = coremltools.convert(linear_prog, convert_to='mlprogram')

        spec = model.get_spec()
        input_name = spec.description.input[0].name
        output_name = spec.description.output[0].name

        # rename input
        rename_feature(spec, input_name, "new_input_name")
        self.assertEqual(spec.description.input[0].name, "new_input_name")
        model = coremltools.models.MLModel(spec, weights_dir=model.weights_dir)
        out = model.predict({"new_input_name": np.array([1.0, 2.0,
                                                         3.0])})[output_name]
        self.assertEqual(out.shape, (10, ))
        self.assertEqual(out[0], 6.0)

        # rename output
        rename_feature(spec, output_name, "new_output_name")
        self.assertEqual(spec.description.output[0].name, "new_output_name")
        model = coremltools.models.MLModel(spec, weights_dir=model.weights_dir)
        out = model.predict({"new_input_name":
                             np.array([1.0, 2.0, 3.0])})["new_output_name"]
        self.assertEqual(out.shape, (10, ))
        self.assertEqual(out[1], 6.0)
Ejemplo n.º 5
0
def pattern_to_detect(conv_transpose, transpose, sub):
    """
    Wrapper to create 8 patterns to detect for conciseness.
    """
    @mb.program(input_specs=[mb.TensorSpec(shape=arbitrary_input)])
    def conv_bias_pattern(x):
        if not conv_transpose:
            conv = mb.conv(x=x,
                           weight=arbitrary_weight,
                           pad_type="valid",
                           name="conv")
        else:
            conv = mb.conv_transpose(x=x,
                                     weight=arbitrary_weight,
                                     pad_type="valid",
                                     name="conv")

        if transpose:
            transpose_layer = mb.transpose(x=conv,
                                           perm=arbitrary_perm,
                                           name="transpose")

        if sub:
            add_or_sub = mb.sub(x=transpose_layer if transpose else conv,
                                y=arbitrary_scalar,
                                name="add_or_sub")
        else:
            add_or_sub = mb.add(x=transpose_layer if transpose else conv,
                                y=arbitrary_scalar,
                                name="add_or_sub")
        return add_or_sub

    return conv_bias_pattern
Ejemplo n.º 6
0
    def setup_class(self):
        # define an mlprogram, which has weights
        @mb.program(input_specs=[mb.TensorSpec(shape=(4, 5000))])
        def linear_prog(input):
            W = mb.const(val=np.random.rand(100, 5000), name="const_W")
            out = mb.linear(x=input, weight=W, name="output")
            return out

        # define another mlprogram, which does not have weights
        @mb.program(input_specs=[mb.TensorSpec(shape=(4, 5, 2))])
        def relu_prog(input):
            out = mb.relu(x=input, name="output")
            return out

        # convert and save model on disk
        self.mlmodel = coremltools.convert(linear_prog, convert_to="mlprogram")
        self.mlpackage_path = tempfile.mkdtemp(suffix=utils._MLPACKAGE_EXTENSION)
        self.mlmodel.save(self.mlpackage_path)
        self.mlmodel_no_weights = coremltools.convert(relu_prog, convert_to="mlprogram")
Ejemplo n.º 7
0
    def get_prelu_pattern():
        """
        y = a * relu(-1 * x) + relu(x)

        when x is rank 4, and "a" is of shape (1, C, 1, 1) or (C, 1, 1),
        this is equivalent to prelu with alpha = -a.flatten(),
        """
        @mb.program(input_specs=[mb.TensorSpec(shape=([get_new_symbol(), get_new_symbol(),
                                                       get_new_symbol(), get_new_symbol()])), ])
        def prelu_pattern(x):
            return _prelu_pattern(x)

        return prelu_pattern
Ejemplo n.º 8
0
    def get_prelu_pattern():
        """
        x1 = transpose(perm=(0,2,3,1))(x)
        y = a * relu(-1 * x1) + relu(x1)

        when x is rank 4, and "a" is of shape (C,) or (1, C) or (1,1,C) or (1,1,1,C),
        this is equivalent to prelu with alpha = -a.flatten(), followed by a transpose
        with perm (0,2,3,1)
        """
        @mb.program(input_specs=[mb.TensorSpec(shape=([get_new_symbol(), get_new_symbol(),
                                                       get_new_symbol(), get_new_symbol()])), ])
        def prelu_pattern(x):
            # perm value can be anything, it will be checked in "is_var_constraint_satisifed" method
            x = mb.transpose(x=x, perm=[0,1,2,3], name="transpose")
            return _prelu_pattern(x)

        return prelu_pattern
Ejemplo n.º 9
0
    ...

Result:
    %3 = conv(%1)
    ...
"""

arbitrary_cin = 5
arbitrary_cout = 8
arbitrary_scalar = 5
np.random.seed()
arbitrary_input = (3, arbitrary_cin, 224, 224)
arbitrary_weight = np.random.rand(arbitrary_cout, arbitrary_cin, 10, 10)


@mb.program(input_specs=[mb.TensorSpec(shape=arbitrary_input)])
def conv_scale_mul(x):
    conv = mb.conv(x=x, weight=arbitrary_weight, pad_type="valid", name="conv")
    mul = mb.mul(x=conv, y=arbitrary_scalar, name="scale")
    return mul


@mb.program(input_specs=[mb.TensorSpec(shape=arbitrary_input)])
def conv_transpose_scale_mul(x):
    conv = mb.conv_transpose(x=x,
                             weight=arbitrary_weight,
                             pad_type="valid",
                             name="conv")
    mul = mb.mul(x=conv, y=arbitrary_scalar, name="scale")
    return mul
    :param mode: reduce mode
    """
    if reduce_op is None:
        return False
    if reduce_op.op_type != mode:
        return False
    if reduce_op.keep_dims.val is False:
        return False
    if reduce_op.axes is None or reduce_op.axes.val is None:
        return False
    return True


if os.getenv("ENABLE_EXPERIMENTAL_PASSES") == "1":

    @mb.program(input_specs=[mb.TensorSpec(shape=shape)])
    def instancenorm_or_layernorm(x):
        """
        Identify the pattern:

        y = gamma * (x - mean) / sqrt(variance + epsilon) + beta

        y = x * [gamma * rsqrt(variance + eps)] + (beta - mean * [gamma * rsqrt(variance + eps)])

        x --> main_reduce --> sub --> square --> reduce_mean_2 --> add(epsilon) --> rsqrt
        |             |        ^                                                      |
        |             |        |                                                      V
        |-----------------------                                                mul (gamma)
        |             |                                                             |
        |             |                                                     --------|---------
        |             |                                                     |                |
# -*- coding: utf-8 -*-

#  Copyright (c) 2020, Apple Inc. All rights reserved.
#
#  Use of this source code is governed by a BSD-3-clause license that can be
#  found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause

import os

from coremltools.converters.mil import Builder as mb
from coremltools.converters.mil.mil.passes.helper import _check_var_scalar_value
from coremltools.converters.mil.experimental.passes.generic_pass_infrastructure import register_generic_pass


@mb.program(input_specs=[
    mb.TensorSpec(shape=([1, 1024, 4096])),
])
def gelu_to_detect_1(x):
    # MIL operation takes named inputs (instead of positional inputs).
    # Here `name` argument is MANDATORY.
    pow = mb.pow(x=x, y=3.0, name="pow")
    mul_1 = mb.mul(x=0.044714998453855515, y=pow, name="mul_1")
    add = mb.add(x=x, y=mul_1, name="add")
    mul_2 = mb.mul(x=0.7978845834732056, y=add, name="mul_2")
    tanh = mb.tanh(x=mul_2, name="tanh")
    add_1 = mb.add(x=1.0, y=tanh, name="add_1")
    mul = mb.mul(x=0.5, y=add_1, name="mul")
    mul_3 = mb.mul(x=mul, y=x, name="mul_3")
    return mul_3