Beispiel #1
0
def fixed_point_position_legalizer(optree,
                                   input_prec_solver=default_prec_solver):
    """ Legalize a FixedPointPosition node to a constant """
    assert isinstance(optree, FixedPointPosition)
    fixed_input = optree.get_input(0)
    fixed_precision = input_prec_solver(fixed_input)
    if not is_fixed_point(fixed_precision):
        Log.report(
            Log.Error,
            "in fixed_point_position_legalizer: precision of {} should be fixed-point but is {}"
            .format(fixed_input, fixed_precision))

    position = optree.get_input(1).get_value()

    align = optree.get_align()

    value_computation_map = {
        FixedPointPosition.FromLSBToLSB:
        position,
        FixedPointPosition.FromMSBToLSB:
        fixed_precision.get_bit_size() - 1 - position,
        FixedPointPosition.FromPointToLSB:
        fixed_precision.get_frac_size() + position,
        FixedPointPosition.FromPointToMSB:
        fixed_precision.get_integer_size() - position
    }
    cst_value = value_computation_map[align]
    # display value
    Log.report(
        Log.LogLevel("FixedPoint"),
        "fixed-point position {tag} has been resolved to {value}".format(
            tag=optree.get_tag(), value=cst_value))
    result = Constant(cst_value, precision=ML_Integer)
    forward_attributes(optree, result)
    return result
Beispiel #2
0
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
###############################################################################

import sys
from metalibm_core.utility.log_report import Log
""" custom warning log level for pass management """
LOG_PASS_INFO = Log.LogLevel("Info", "passes")


## Parent class for all pass dependency
class PassDependency:
    ## test if the  @p self dependency is resolved
    #  @p param pass_scheduler scheduler which requires dependency checking
    #  @return boolean True if dependency is resolved, False otherwise
    def is_dep_resolved(self, pass_scheduler):
        return True


class AfterPassByClass(PassDependency):
    def __init__(self, pass_class):
        self.pass_class = pass_class
Beispiel #3
0
from metalibm_core.core.legalizer import extract_placeholder

from metalibm_core.core.passes import FunctionPass, Pass, LOG_PASS_INFO

from metalibm_core.core.bb_operations import (
    BasicBlockList,
    ConditionalBranch, UnconditionalBranch, BasicBlock,
    SequentialBlock,
    PhiNode
)

from metalibm_core.utility.log_report import Log

# specific debug log levels for this file: (very) verbose and
# info(rmative)
LOG_LEVEL_GEN_BB_VERBOSE = Log.LogLevel("GenBBVerbose")
LOG_LEVEL_GEN_BB_INFO = Log.LogLevel("GenBBInfo")


def transform_cb_to_bb(bb_translator, optree, fct=None, fct_group=None, memoization_map=None):
    """ Transform a ConditionBlock node to a list of BasicBlock
        returning the entry block as result.

        @param bb_translator generic basic-block translator object
                             which can be called recursively on CB sub basic
                             blocks
        @param optree input operation tree
        @return entry BasicBlock to the ConditionBlock translation """
    # get current unfinished basic block (CB:) from top of stack
    #
    # When encoutering
Beispiel #4
0
        result_type = (None if node_format is None else node_format.get_match_format() ,)
        if not is_leaf_node(node):
            arg_type = tuple((arg.get_precision().get_match_format() if not arg.get_precision() is None else None) for arg in node.get_inputs())
            interface = result_type + arg_type
        else:
            interface = (result_type,)
        codegen_key = node.get_codegen_key()
        return op_class, interface, codegen_key

    @property
    def action_selection_table(self):
        """ semantic indirection between action_selection_table and
            code_generation_table """
        return self.lowering_table

LOG_LOWERING_INFO = Log.LogLevel("LoweringInfo")

@METALIBM_PASS_REGISTER
class Pass_GenericLowering(FunctionPass):
    """ implement generic lowering """
    pass_tag = "generic_lowering"
    def __init__(self, target, description="lower operation for target"):
        FunctionPass.__init__(self, description, target)

    def execute_on_optree(self, optree, fct=None, fct_group=None, memoization_map=None):
        raise NotImplementedError

    def execute_on_graph(self, op_graph):
        lowering_engine = LoweringEngine(self.target)
        lowered_graph = lowering_engine.lower_node(op_graph)
        return lowered_graph
Beispiel #5
0
###############################################################################

from metalibm_core.core.ml_formats import (ML_Custom_FixedPoint_Format)
from metalibm_core.core.ml_hdl_format import (RTL_FixedPointFormat,
                                              ML_StdLogicVectorFormat)
import metalibm_core.core.ml_hdl_format as ml_hdl_format

from metalibm_core.core.ml_table import ML_TableFormat

from metalibm_core.core.ml_operations import (is_leaf_node)
from metalibm_core.core.passes import FunctionPass, METALIBM_PASS_REGISTER

from metalibm_core.utility.log_report import Log

# high verbosity log-level for expand_multi_precision pass module
LOG_LEVEL_LEGALIZE_RTL2SW = Log.LogLevel("LegalizeRTL2SWFormat")


class Pass_ExhaustiveSearch(FunctionPass):
    """ Check precision of every node appearing in the graph """
    pass_tag = "exhaustive_search"

    def __init__(self, tag, target):
        FunctionPass.__init__(self, tag, target)

    def execute_on_node(self, node):
        """ execute pass action on node without input traversal """
        raise NotImplementedError

    def execute_on_optree(self, optree, fct, fct_group, memoization_map):
        if optree in memoization_map:
    MP_FMA2211,
    MP_FMA2222,
    MP_Add323,
    MP_Add332,
    MP_Add333,
    MP_Mul322,
    MP_Mul332,
    MP_Mul323,
    subnormalize_multi,
    Normalize_33,
)

from metalibm_core.utility.log_report import Log

# high verbosity log-level for expand_multi_precision pass module
LOG_LEVEL_EXPAND_VERBOSE = Log.LogLevel("ExpandVerbose")


def is_subnormalize_op(node):
    """ test if @p node is a Subnormalize operation """
    return isinstance(
        node,
        SpecificOperation) and node.specifier is SpecificOperation.Subnormalize


def get_elementary_precision(multi_precision):
    """ return the elementary precision corresponding
        to multi_precision """
    multi_precision = multi_precision.get_match_format()
    if isinstance(multi_precision, ML_FP_MultiElementFormat):
        return multi_precision.field_format_list[0]
Beispiel #7
0
                                               FormatSolver)

from metalibm_core.core.legalizer import (subsignalsection_legalizer,
                                          fixed_point_position_legalizer,
                                          minmax_legalizer_wrapper)

from metalibm_core.opt.opt_utils import forward_attributes

###############################################################################
# PASS DESCRIPTION:
# The pass implemented in this file processes an optree and  legalize every
# supported node
# the output format
###############################################################################

LOG_LEVEL_LEGALIZE = Log.LogLevel("LegalizeVerbose")


def legalize_Select(optree):
    """ legalize Select operation node by converting if and else inputs to
        Select output format if the bit sizes do not match """
    cond = optree.get_input(0)
    op0 = optree.get_input(1)
    op1 = optree.get_input(2)
    precision = optree.get_precision()
    if precision is None:
        Log.report(Log.Error, "None precision for Select:\n{}", optree)
    if op0.get_precision().get_bit_size() != precision.get_bit_size():
        optree.set_input(1, Conversion(op0, precision=precision))
    if op1.get_precision().get_bit_size() != precision.get_bit_size():
        optree.set_input(2, Conversion(op1, precision=optree.get_precision()))
Beispiel #8
0
)

from metalibm_core.core.ml_operations import (
    VectorAssembling,
    Comparison,
    BooleanOperation,
    LogicalNot,
    LogicalOr,
    LogicalAnd,
    Test,
)

from metalibm_core.utility.log_report import Log
from metalibm_core.utility.debug_utils import debug_multi

LOG_VERBOSE_VBOOL_LEGALIZATION = Log.LogLevel("VirtualBoolLegalizeVerbose")

# List of tests which can be expanded by VirtualBoolVectorLegalizer
EXPANDABLE_TEST_LIST = [
    Test.IsInfOrNaN, Test.IsInfty, Test.IsNaN, Test.IsZero, Test.IsSubnormal,
    Test.IsQuietNaN, Test.IsSignalingNaN
]


def is_virtual_bool_node(node):
    return (isinstance(node, BooleanOperation) or isinstance(node, VectorAssembling)) and \
        node.get_precision().is_vector_format() and \
        node.get_precision().get_scalar_format() is ML_Bool


class VirtualBoolVectorLegalizer(object):
from metalibm_core.core.ml_formats import (ml_infty, is_fixed_format)
from metalibm_core.core.ml_operations import (
    is_leaf_node,
    Min, Max, Constant, Test, Comparison, ConditionBlock,
    LogicOperation, LogicalAnd, LogicalOr, LogicalNot,
    Statement,
    Multiplication, Addition,
)
from metalibm_core.core.legalizer import is_constant
from metalibm_core.core.meta_interval import MetaInterval, MetaIntervalList, inf, sup

from metalibm_core.utility.log_report import Log
from metalibm_core.utility.debug_utils import debug_multi

LOG_VERBOSE_NUMERICAL_SIMPLIFICATION = Log.LogLevel("NumericalSimplificationVerbose")

from metalibm_core.opt.opt_utils import is_false, is_true

def is_simplifiable_to_cst(node):
    """ node can be simplified to a constant """
    node_interval = node.get_interval()
    if node_interval is None or isinstance(node, Constant):
        return False
    elif isinstance(node_interval, SollyaObject) and node_interval.is_range():
        return sollya.inf(node_interval) == sollya.sup(node_interval)
    elif isinstance(node_interval, (MetaInterval, MetaIntervalList)):
        return not node_interval.is_empty and (node_interval.inf == node_interval.sup)
    else:
        return False
Beispiel #10
0
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
###############################################################################
# Description: evaluating node range accross the graph
###############################################################################

from metalibm_core.core.ml_operations import is_leaf_node
from metalibm_core.utility.log_report import Log
from metalibm_core.core.passes import FunctionPass, LOG_PASS_INFO, Pass
from metalibm_core.opt.opt_utils import evaluate_range

LOG_VERBOSE_EVALUATE_RANGE = Log.LogLevel("EvaluateRangeVerbose")

class Pass_EvaluateRange(FunctionPass):
    """ Verify that each node has a precision assigned to it """
    pass_tag = "evaluate_range"

    def __init__(self, target):
        super().__init__("evaluate_range", target)

    def evaluate_set_range(self, optree, memoization_map=None):
        """ check if all precision-instantiated operation are supported by the processor """
        # memoization map is used to store node's range/interval
        memoization_map = {} if memoization_map is None else memoization_map
        if  optree in memoization_map:
            return optree
        else:
Beispiel #11
0
###############################################################################

from metalibm_core.core.ml_operations import (
    is_leaf_node, FunctionObject,
    Conversion, is_conversion,
    TypeCast, is_typecast,
    Constant, Abs, Subtraction)
from metalibm_core.core.legalizer import is_constant
from metalibm_core.core.ml_formats import ML_Void

from metalibm_core.code_generation.code_constant import C_Code
from metalibm_core.code_generation.generator_utility import TemplateOperatorFormat

from metalibm_core.utility.log_report import Log

LOG_RUNTIME_EVAL_ERROR = Log.LogLevel("LogRuntimeEvalError")


def evaluate_typecast_value(optree, value):
    assert isinstance(optree, TypeCast)
    input_format = optree.get_input(0).get_precision()
    output_format = optree.get_precision() 
    input_value = input_format.get_integer_coding(value)
    output_value = output_format.get_value_from_integer_coding(input_value, base=None)
    Log.report(LOG_RUNTIME_EVAL_ERROR, "value={}, input_value= {}, output_value={}", value, input_value, output_value) 
    return output_value

def evaluate_conversion_value(optree, value):
    return optree.get_precision().round_sollya_object(value)

Beispiel #12
0
# Description: optimization pass to expand multi-precision node to simple
#              precision implementation
###############################################################################

from metalibm_core.core.passes import OptreeOptimization, Pass, LOG_PASS_INFO
from metalibm_core.core.ml_operations import (VectorElementSelection)
from metalibm_core.core.ml_hdl_operations import (BitSelection,
                                                  SubSignalSelection)
from metalibm_core.core.legalizer import evaluate_cst_graph

from metalibm_core.opt.node_transformation import Pass_NodeTransformation
from metalibm_core.opt.opt_utils import forward_attributes

from metalibm_core.utility.log_report import Log

LOG_VERBOSE_SIMPLIFY_RTL = Log.LogLevel("SimplifyRTLVerbose")


def is_simplifiable(node):
    return (isinstance(node, VectorElementSelection) and isinstance(node.get_input(0), (Constant, SubSignalSelection))) or \
        (isinstance(node, SubSignalSelection) and isinstance(node.get_input(0), SubSignalSelection))


class BasicSimplifier(object):
    """ Basic expansion engine """
    def __init__(self, target):
        self.target = target
        self.memoization_map = {}

    def simplify_node(self, node):
        """ return the simplified version of @p node when possible
Beispiel #13
0
from metalibm_core.opt.opt_utils import (
    forward_attributes,
    logical_reduce,
)

from metalibm_core.core.ml_operations import (
    is_leaf_node,
    LogicalAnd,
    LogicalOr,
    LogicalNot,
)
from metalibm_core.core.legalizer import is_constant

from metalibm_core.utility.log_report import Log

LOG_LOGICAL_SIMPLIFICATION = Log.LogLevel("LogicalSimplification")

from metalibm_core.opt.opt_utils import is_false, is_true


def is_logical_and_not(node):
    """ test if node is a tree of And(Not(), And(..)) """
    if not isinstance(node, LogicalAnd):
        return False
    lhs = node.get_input(0)
    rhs = node.get_input(0)

    def input_predicate(op):
        return isinstance(op, LogicalNot) or is_logical_and_not(op)

    return input_predicate(lhs) and input_predicate(rhs)
Beispiel #14
0
    Equal,
    NotEqual,
    Constant,
    VectorElementSelection,
    Comparison,
    BooleanOperation,
    LogicalNot,
    LogicalOr,
    LogicalAnd,
    Test,
)

from metalibm_core.utility.log_report import Log
from metalibm_core.utility.debug_utils import debug_multi

LOG_VERBOSE_VECTOR_MASK_TEST = Log.LogLevel("VectorMaskTestVerbose")

# List of tests which can be expanded by VectorMaskTestExpander
EXPANDABLE_TEST_LIST = [
    Test.IsMaskAllZero, Test.IsMaskNotAllZero, Test.IsMaskNotAnyZero,
    Test.IsMaskAnyZero
]


def is_vector_mask_test(node):
    return isinstance(node, Test) and node.specifier in EXPANDABLE_TEST_LIST


class VectorMaskTestExpander(object):
    """ Basic expansion engine """
    def __init__(self, target):
Beispiel #15
0
                                              Division, is_leaf_node)
from metalibm_core.core.ml_formats import ML_Binary32, ML_Float
from metalibm_core.core.legalizer import evaluate_graph
from metalibm_core.core.precisions import ML_Faithful

from metalibm_core.opt.p_function_inlining import generate_inline_fct_scheme
from metalibm_core.opt.opt_utils import evaluate_range

from metalibm_core.code_generation.generic_processor import GenericProcessor

from metalibm_core.utility.ml_template import DefaultArgTemplate, ML_NewArgTemplate
from metalibm_core.utility.log_report import Log

from metalibm_functions.function_map import FUNCTION_MAP

LOG_VERBOSE_FUNCTION_EXPR = Log.LogLevel("FunctionExprVerbose")

FUNCTION_OBJECT_MAPPING = {
    name: FunctionObject(name, [ML_Float] * FUNCTION_MAP[name][0].arity,
                         ML_Float,
                         None,
                         range_function=FUNCTION_MAP[name][2])
    for name in FUNCTION_MAP
}

FCT_DESC_PATTERN = r"([-+/* ().,]|\d+|{}|[xyzt])*".format("|".join(
    FUNCTION_OBJECT_MAPPING.keys()))


def check_fct_expr(str_desc):
    """ check if function expression string is potentially valid """