//  [python]
def create_tf_modelfile(
    create_savedmodel, models_dir, model_version, max_batch, dtype, shape
):
    if not tu.validate_for_tf_model(dtype, dtype, dtype, shape, shape, shape):
        return

    tf_input_dtype = np_to_tf_dtype(dtype)
    tf_dtype = tf_input_dtype

    # If the input is a string then use int32 for operation and just
    # cast to/from string for input and output.
    if tf_input_dtype == tf.string:
        tf_dtype = tf.int32

    # Create the model. If non-batching then don't include the batch
    # dimension.
    tf.compat.v1.reset_default_graph()
    if create_savedmodel and (max_batch == 0):
        input0 = tf.compat.v1.placeholder(
            tf_input_dtype,
            [
                1,
            ],
            "INPUT",
        )
        if tf_input_dtype == tf.string:
            input0 = tf.strings.to_number(tf.strings.join(["0", input0]), tf_dtype)
        start0 = tf.compat.v1.placeholder(
            tf_dtype,
            [
                1,
            ],
            "START",
        )
        end0 = tf.compat.v1.placeholder(
            tf_dtype,
            [
                1,
            ],
            "END",
        )
        ready0 = tf.compat.v1.placeholder(
            tf_dtype,
            [
                1,
            ],
            "READY",
        )
        corrid0 = tf.compat.v1.placeholder(
            tf.uint64,
            [
                1,
            ],
            "CORRID",
        )
        corrid_cast0 = tf.cast(corrid0, tf_dtype)
        acc = tf.compat.v1.get_variable(
            "ACC",
            [
                1,
            ],
            dtype=tf_dtype,
        )
        tmp0 = tf.compat.v1.where(tf.equal(start0, 1), input0, tf.add(acc, input0))
        tmp1 = tf.compat.v1.where(tf.equal(end0, 1), tf.add(tmp0, corrid_cast0), tmp0)
        newacc = tf.compat.v1.where(tf.equal(ready0, 1), tmp1, acc)
        assign = tf.compat.v1.assign(acc, newacc)
        if tf_input_dtype == tf.string:
            tf.strings.as_string(assign, name="OUTPUT")
        else:
            tf.identity(assign, name="OUTPUT")
    else:
        # For batching we can't use a tf.variable to hold the
        # accumulated values since that forces the size of the output
        # to the size of the variable (which must be a max-batch-size
        # vector since require one accumulator each), instead of the
        # output shape being [None, 1]. So instead we just return 0 if
        # not-ready and 'INPUT'+'START'+('END'*'CORRID')
        # otherwise... the tests know to expect this.
        input0 = tf.compat.v1.placeholder(
            tf_input_dtype,
            [
                None,
            ]
            + tu.shape_to_tf_shape(shape),
            "INPUT",
        )
        if tf_input_dtype == tf.string:
            input0 = tf.strings.to_number(tf.strings.join(["0", input0]), tf_dtype)
        start0 = tf.compat.v1.placeholder(tf_dtype, [None, 1], "START")
        end0 = tf.compat.v1.placeholder(tf_dtype, [None, 1], "END")
        ready0 = tf.compat.v1.placeholder(tf_dtype, [None, 1], "READY")
        corrid0 = tf.compat.v1.placeholder(tf.uint64, [None, 1], "CORRID")
        corrid_cast0 = tf.cast(corrid0, tf_dtype)
        tmp = tf.compat.v1.where(
            tf.equal(ready0, 1),
            tf.add(tf.add(start0, input0), tf.multiply(end0, corrid_cast0)),
            tf.zeros(tf.shape(input=input0), dtype=tf_dtype),
        )
        if tf_input_dtype == tf.string:
            tf.strings.as_string(tmp, name="OUTPUT")
        else:
            tf.identity(tmp, name="OUTPUT")

    # Use a different model name for the non-batching variant
    if create_savedmodel:
        model_name = tu.get_dyna_sequence_model_name(
            "savedmodel_nobatch" if max_batch == 0 else "savedmodel", dtype
        )
    else:
        model_name = tu.get_dyna_sequence_model_name(
            "graphdef_nobatch" if max_batch == 0 else "graphdef", dtype
        )

    model_version_dir = models_dir + "/" + model_name + "/" + str(model_version)

    try:
        os.makedirs(model_version_dir)
    except OSError as ex:
        pass  # ignore existing dir

    if create_savedmodel:
        with tf.compat.v1.Session() as sess:
            sess.run(tf.compat.v1.initializers.global_variables())
            input0_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name(
                "INPUT:0"
            )
            start0_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name(
                "START:0"
            )
            end0_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name("END:0")
            ready0_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name(
                "READY:0"
            )
            corrid0_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name(
                "CORRID:0"
            )
            output0_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name(
                "OUTPUT:0"
            )
            tf.compat.v1.saved_model.simple_save(
                sess,
                model_version_dir + "/model.savedmodel",
                inputs={
                    "INPUT": input0_tensor,
                    "START": start0_tensor,
                    "END": end0_tensor,
                    "READY": ready0_tensor,
                    "CORRID": corrid0_tensor,
                },
                outputs={"OUTPUT": output0_tensor},
            )
    else:
        with tf.compat.v1.Session() as sess:
            sess.run(tf.compat.v1.initializers.global_variables())
            graph_io.write_graph(
                sess.graph.as_graph_def(),
                model_version_dir,
                "model.graphdef",
                as_text=False,
            )