def define_MLP_ResiliNet_architecture_fog1(
        fog2_output,
        fog3_output,
        fog4_output,
        hidden_units,
        fog2_failure_lambda,
        multiply_hyperconnection_weight_layer=None):
    if multiply_hyperconnection_weight_layer == None or multiply_hyperconnection_weight_layer[
            "f2f1"] == None or multiply_hyperconnection_weight_layer[
                "f3f1"] == None or multiply_hyperconnection_weight_layer[
                    "f4f1"] == None:
        skip_hyperconnections = add([fog3_output, fog4_output])
        fog1_input = Lambda(InputMux(fog2_failure_lambda.has_failed),
                            name="node2_input")(
                                [skip_hyperconnections, fog2_output])
    else:
        skip_hyperconnections = add([
            multiply_hyperconnection_weight_layer["f3f1"](fog3_output),
            multiply_hyperconnection_weight_layer["f4f1"](fog4_output)
        ])
        fog1_input = Lambda(
            InputMux(fog2_failure_lambda.has_failed), name="node2_input")([
                skip_hyperconnections,
                multiply_hyperconnection_weight_layer["f2f1"](fog2_output)
            ])
    fog1_output = define_MLP_architecture_fog_with_two_layers(
        fog1_input, hidden_units, "fog1_output_layer", "fog1_input_layer")
    return fog1_output
def define_cnn_ResiliNet_architecture_fog(
    skip_iotfog,
    edge_output,
    alpha,
    depth_multiplier,
    edge_failure_lambda,
    multiply_hyperconnection_weight_layer_IoTf=None,
    multiply_hyperconnection_weight_layer_ef=None,
    strides=(2, 2)):
    if multiply_hyperconnection_weight_layer_IoTf == None or multiply_hyperconnection_weight_layer_ef == None:
        fog_input = Lambda(InputMux(edge_failure_lambda.has_failed),
                           name="node2_input")([skip_iotfog, edge_output])
    else:
        fog_input = Lambda(
            InputMux(edge_failure_lambda.has_failed), name="node2_input")([
                multiply_hyperconnection_weight_layer_IoTf(skip_iotfog),
                multiply_hyperconnection_weight_layer_ef(edge_output)
            ])
    fog = define_cnn_architecture_fog(fog_input, alpha, depth_multiplier)
    # cnn for imagenet does not need padding
    if strides == (2, 2):
        fog_output = fog
    elif strides == (1, 1):
        # pad from (7,7,256) to (8,8,256)
        fog_output = layers.ZeroPadding2D(
            padding=((0, 1), (0, 1)), name="fogcloud_connection_padding")(fog)
    else:
        raise ValueError("Incorrect stride value")

    return fog_output
def define_MLP_ResiliNet_architecture_fog2(
        edge1_output,
        edge2_output,
        edge3_output,
        edge4_output,
        fog3_output,
        fog4_output,
        hidden_units,
        fog3_failure_lambda,
        fog4_failure_lambda,
        multiply_hyperconnection_weight_layer=None):
    if multiply_hyperconnection_weight_layer == None or multiply_hyperconnection_weight_layer[
            "e1f2"] == None or multiply_hyperconnection_weight_layer[
                "e2f2"] == None or multiply_hyperconnection_weight_layer[
                    "e3f2"] == None or multiply_hyperconnection_weight_layer[
                        "e4f2"] == None or multiply_hyperconnection_weight_layer[
                            "f3f2"] == None or multiply_hyperconnection_weight_layer[
                                "f4f2"] == None:
        fog2_input_left = Lambda(InputMux(fog3_failure_lambda.has_failed),
                                 name="node3_input_left")(
                                     [edge1_output, fog3_output])
        skip_hyperconnections = add([edge2_output, edge3_output, edge4_output])
        fog2_input_right = Lambda(InputMux(fog4_failure_lambda.has_failed),
                                  name="node3_input_right")(
                                      [skip_hyperconnections, fog4_output])
    else:
        fog2_input_left = Lambda(
            InputMux(fog3_failure_lambda.has_failed),
            name="node3_input_left")([
                multiply_hyperconnection_weight_layer["e1f2"](edge1_output),
                multiply_hyperconnection_weight_layer["f3f2"](fog3_output)
            ])
        skip_hyperconnections = add([
            multiply_hyperconnection_weight_layer["e2f2"](edge2_output),
            multiply_hyperconnection_weight_layer["e3f2"](edge3_output),
            multiply_hyperconnection_weight_layer["e4f2"](edge4_output)
        ])
        fog2_input_right = Lambda(
            InputMux(fog4_failure_lambda.has_failed),
            name="node3_input_right")([
                skip_hyperconnections,
                multiply_hyperconnection_weight_layer["f4f2"](fog4_output)
            ])

    fog2_input = layers.add([fog2_input_left, fog2_input_right],
                            name="node3_input")
    fog2_output = define_MLP_architecture_fog_with_two_layers(
        fog2_input, hidden_units, "fog2_output_layer", "fog2_input_layer")
    return fog2_output
def define_MLP_ResiliNet_architecture_cloud(
        fog2_output, fog1_output, hidden_units, num_classes,
        fog1_failure_lambda, multiply_hyperconnection_weight_layer):
    if multiply_hyperconnection_weight_layer == None or multiply_hyperconnection_weight_layer[
            "f1c"] == None or multiply_hyperconnection_weight_layer[
                "f2c"] == None:
        cloud_input = Lambda(InputMux(fog1_failure_lambda.has_failed),
                             name="node1_input")([fog2_output, fog1_output])
    else:
        cloud_input = Lambda(
            InputMux(fog1_failure_lambda.has_failed), name="node1_input")([
                multiply_hyperconnection_weight_layer["f2c"](fog2_output),
                multiply_hyperconnection_weight_layer["f1c"](fog1_output)
            ])
    cloud_output = define_MLP_architecture_cloud(cloud_input, hidden_units,
                                                 num_classes)
    return cloud_output
def define_MLP_ResiliNet_architecture_fog2(
        iot_skip_output,
        edge_output,
        hidden_units,
        edge_failure_lambda,
        multiply_hyperconnection_weight_layer_IoTf2=None,
        multiply_hyperconnection_weight_layer_ef2=None):
    if multiply_hyperconnection_weight_layer_IoTf2 == None or multiply_hyperconnection_weight_layer_ef2 == None:
        fog2_input = Lambda(InputMux(edge_failure_lambda.has_failed),
                            name="node3_input")([iot_skip_output, edge_output])
    else:
        fog2_input = Lambda(
            InputMux(edge_failure_lambda.has_failed), name="node3_input")([
                multiply_hyperconnection_weight_layer_IoTf2(iot_skip_output),
                multiply_hyperconnection_weight_layer_ef2(edge_output)
            ])
    fog2_output = define_MLP_architecture_fog2(fog2_input, hidden_units)
    return fog2_output
def define_MLP_ResiliNet_architecture_fog1(
        edge_skip_output,
        fog2_output,
        hidden_units,
        fog2_failure_lambda,
        multiply_hyperconnection_weight_layer_ef1=None,
        multiply_hyperconnection_weight_layer_f2f1=None):
    if multiply_hyperconnection_weight_layer_ef1 == None or multiply_hyperconnection_weight_layer_f2f1 == None:
        fog1_input = Lambda(InputMux(fog2_failure_lambda.has_failed),
                            name="node2_input")(
                                [edge_skip_output, fog2_output])
    else:
        fog1_input = Lambda(
            InputMux(fog2_failure_lambda.has_failed), name="node2_input")([
                multiply_hyperconnection_weight_layer_ef1(edge_skip_output),
                multiply_hyperconnection_weight_layer_f2f1(fog2_output)
            ])
    fog1_output = define_MLP_architecture_fog1(fog1_input, hidden_units)
    return fog1_output
def define_cnn_ResiliNet_architecture_cloud(
        fog_output,
        skip_edgecloud,
        alpha,
        depth_multiplier,
        classes,
        include_top,
        pooling,
        fog_failure_lambda,
        multiply_hyperconnection_weight_layer_fc=None,
        multiply_hyperconnection_weight_layer_ec=None):
    if multiply_hyperconnection_weight_layer_fc == None or multiply_hyperconnection_weight_layer_ec == None:
        cloud_input = Lambda(InputMux(fog_failure_lambda.has_failed),
                             name="node1_input")([skip_edgecloud, fog_output])
    else:
        cloud_input = Lambda(
            InputMux(fog_failure_lambda.has_failed), name="node1_input")([
                multiply_hyperconnection_weight_layer_ec(skip_edgecloud),
                multiply_hyperconnection_weight_layer_fc(fog_output)
            ])
    cloud_output = define_cnn_architecture_cloud(cloud_input, alpha,
                                                 depth_multiplier, classes,
                                                 include_top, pooling)
    return cloud_output