1f86d1f99SJacob Hegnafunction(tf_get_absolute_path path base final_path) 2f86d1f99SJacob Hegna if (IS_ABSOLUTE ${path}) 3f86d1f99SJacob Hegna set(${final_path} ${path} PARENT_SCOPE) 433481c99SMircea Trofin else() 5f86d1f99SJacob Hegna set(${final_path} ${base}/${path} PARENT_SCOPE) 633481c99SMircea Trofin endif() 733481c99SMircea Trofinendfunction() 833481c99SMircea Trofin 9f86d1f99SJacob Hegnafunction(tf_get_model model final_path) 10f86d1f99SJacob Hegna string(FIND ${model} "http:" pos_http) 11f86d1f99SJacob Hegna string(FIND ${model} "https:" pos_https) 12f86d1f99SJacob Hegna if (${pos_http} EQUAL 0 OR ${pos_https} EQUAL 0) 13f86d1f99SJacob Hegna message("Downloading model " ${model}) 14f86d1f99SJacob Hegna string(FIND ${model} "/" fname_start REVERSE) 15f86d1f99SJacob Hegna math(EXPR fname_start "${fname_start}+1") 16f86d1f99SJacob Hegna string(SUBSTRING ${model} ${fname_start}+1 -1 fname) 17f86d1f99SJacob Hegna message("Model archive: " ${fname}) 18f86d1f99SJacob Hegna file(DOWNLOAD ${model} ${CMAKE_CURRENT_BINARY_DIR}/${fname}) 19f86d1f99SJacob Hegna file(ARCHIVE_EXTRACT INPUT 20f86d1f99SJacob Hegna ${CMAKE_CURRENT_BINARY_DIR}/${fname} 21f86d1f99SJacob Hegna DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/${fname}_model) 22f86d1f99SJacob Hegna set(${final_path} ${CMAKE_CURRENT_BINARY_DIR}/${fname}_model/model PARENT_SCOPE) 23f86d1f99SJacob Hegna else() 24f86d1f99SJacob Hegna tf_get_absolute_path(${model} ${CMAKE_CURRENT_BINARY_DIR} model_path) 25f86d1f99SJacob Hegna set(${final_path} ${model_path} PARENT_SCOPE) 26f86d1f99SJacob Hegna endif() 27f86d1f99SJacob Hegnaendfunction() 28f86d1f99SJacob Hegna 29f86d1f99SJacob Hegna# Generate a mock model for tests. 30edf8e3eaSMircea Trofinfunction(generate_mock_model generator output) 31edf8e3eaSMircea Trofin tf_get_absolute_path(${generator} ${CMAKE_CURRENT_SOURCE_DIR} generator_absolute_path) 32edf8e3eaSMircea Trofin tf_get_absolute_path(${output} ${CMAKE_CURRENT_BINARY_DIR} output_absolute_path) 33f86d1f99SJacob Hegna message(WARNING "Autogenerated mock models should not be used in production builds.") 34e267df8cSMatthias Braun execute_process(COMMAND ${Python3_EXECUTABLE} 35edf8e3eaSMircea Trofin ${generator_absolute_path} 36edf8e3eaSMircea Trofin ${output_absolute_path} 37f86d1f99SJacob Hegna WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 38f86d1f99SJacob Hegna ) 39f86d1f99SJacob Hegnaendfunction() 40f86d1f99SJacob Hegna 41bdceefe9SMircea Trofin# Run the tensorflow compiler (saved_model_cli) on the saved model in the 42bdceefe9SMircea Trofin# ${model} directory, looking for the ${tag_set} tag set, and the SignatureDef 43bdceefe9SMircea Trofin# ${signature_def_key}. 44bdceefe9SMircea Trofin# Produce a pair of files called ${fname}.h and ${fname}.o in the 45bdceefe9SMircea Trofin# ${CMAKE_CURRENT_BINARY_DIR}. The generated header will define a C++ class 46bdceefe9SMircea Trofin# called ${cpp_class} - which may be a namespace-qualified class name. 47f29256a6SMircea Trofinfunction(tf_compile model tag_set signature_def_key fname cpp_class hdr_file obj_file) 48f86d1f99SJacob Hegna tf_get_absolute_path(${model} ${CMAKE_CURRENT_BINARY_DIR} LLVM_ML_MODELS_ABSOLUTE) 49f34ef248SMircea Trofin message("Using model at " ${LLVM_ML_MODELS_ABSOLUTE}) 50bdceefe9SMircea Trofin add_custom_command(OUTPUT ${obj_file} ${hdr_file} 516c848c28SJacob Hegna COMMAND ${TENSORFLOW_AOT_COMPILER} aot_compile_cpu 526c848c28SJacob Hegna --multithreading false 53bdceefe9SMircea Trofin --dir ${LLVM_ML_MODELS_ABSOLUTE} 54bdceefe9SMircea Trofin --tag_set ${tag_set} 55bdceefe9SMircea Trofin --signature_def_key ${signature_def_key} 56bdceefe9SMircea Trofin --output_prefix ${prefix} 57bdceefe9SMircea Trofin --cpp_class ${cpp_class} 58bdceefe9SMircea Trofin --target_triple ${LLVM_HOST_TRIPLE} 59bdceefe9SMircea Trofin ) 60bdceefe9SMircea Trofin 61f29256a6SMircea Trofin # Aggregate the objects so that results of different tf_compile calls may be 62bdceefe9SMircea Trofin # grouped into one target. 63bdceefe9SMircea Trofin set(GENERATED_OBJS ${GENERATED_OBJS} ${obj_file} PARENT_SCOPE) 64bdceefe9SMircea Trofin set_source_files_properties(${obj_file} PROPERTIES 65bdceefe9SMircea Trofin GENERATED 1 EXTERNAL_OBJECT 1) 66bdceefe9SMircea Trofin 67bdceefe9SMircea Trofin set(GENERATED_HEADERS ${GENERATED_HEADERS} ${hdr_file} PARENT_SCOPE) 68bdceefe9SMircea Trofin set_source_files_properties(${hdr_file} PROPERTIES 69bdceefe9SMircea Trofin GENERATED 1) 70bdceefe9SMircea Trofin 71bdceefe9SMircea Trofin endfunction() 72f86d1f99SJacob Hegna 73edf8e3eaSMircea Trofinfunction(tf_find_and_compile model default_url default_path test_model_generator tag_set signature_def_key fname cpp_class) 74f29256a6SMircea Trofin set(prefix ${CMAKE_CURRENT_BINARY_DIR}/${fname}) 75f29256a6SMircea Trofin set(obj_file ${prefix}.o) 76f29256a6SMircea Trofin set(hdr_file ${prefix}.h) 77f29256a6SMircea Trofin string(TOUPPER ${fname} fname_allcaps) 78f29256a6SMircea Trofin set(override_header ${LLVM_OVERRIDE_MODEL_HEADER_${fname_allcaps}}) 79f29256a6SMircea Trofin set(override_object ${LLVM_OVERRIDE_MODEL_OBJECT_${fname_allcaps}}) 80f29256a6SMircea Trofin # If the user specified overrides, that indicates intent to use AOT and we 81f29256a6SMircea Trofin # don't care what the model path is 82f29256a6SMircea Trofin if (EXISTS "${override_header}" AND EXISTS "${override_object}") 83f29256a6SMircea Trofin configure_file(${override_header} ${hdr_file} COPYONLY) 84f29256a6SMircea Trofin configure_file(${override_object} ${obj_file} COPYONLY) 85f29256a6SMircea Trofin message(STATUS "Using provided header " ${hdr_file} " and object " ${obj_file} " 86f29256a6SMircea Trofin files for model " ${fname}) 87f29256a6SMircea Trofin set(GENERATED_OBJS ${GENERATED_OBJS} ${obj_file}) 88f29256a6SMircea Trofin set(GENERATED_HEADERS ${GENERATED_HEADERS} ${hdr_file}) 89f29256a6SMircea Trofin elseif("${model}" STREQUAL "none") 90f29256a6SMircea Trofin message(STATUS "Will skip enabling mlgo for ${fname}") 91f29256a6SMircea Trofin return() 92f29256a6SMircea Trofin else() 93f86d1f99SJacob Hegna if ("${model}" STREQUAL "download") 9496f15aa5SJacob Hegna # Crash if the user wants to download a model but a URL is set to "TO_BE_UPDATED" 9524c6c352SMircea Trofin if ("${default_url}" STREQUAL "<UNSPECIFIED>") 9624c6c352SMircea Trofin message(FATAL_ERROR "Model path was set to 'download' but there is no" 9724c6c352SMircea Trofin " model url currently specified in cmake. You can generate a model" 9824c6c352SMircea Trofin " using, for example, the tools at http://github.com/google/ml-compiler-opt." 9924c6c352SMircea Trofin " Some reference models are also periodically released there.") 10096f15aa5SJacob Hegna endif() 10196f15aa5SJacob Hegna 102f86d1f99SJacob Hegna set(model ${default_url}) 103f86d1f99SJacob Hegna endif() 104f86d1f99SJacob Hegna 105f86d1f99SJacob Hegna if ("${model}" STREQUAL "autogenerate") 106f86d1f99SJacob Hegna set(model ${default_path}-autogenerated) 107edf8e3eaSMircea Trofin generate_mock_model(${test_model_generator} ${model}) 108f86d1f99SJacob Hegna endif() 109f86d1f99SJacob Hegna 110f86d1f99SJacob Hegna tf_get_model(${model} LLVM_ML_MODELS_ABSOLUTE) 111f29256a6SMircea Trofin tf_compile(${LLVM_ML_MODELS_ABSOLUTE} ${tag_set} ${signature_def_key} ${fname} ${cpp_class} ${hdr_file} ${obj_file}) 112f29256a6SMircea Trofin endif() 113f86d1f99SJacob Hegna 11453753531SMatthias Braun set(GeneratedMLSources ${GeneratedMLSources} ${GENERATED_OBJS} ${GENERATED_HEADERS} PARENT_SCOPE) 115f86d1f99SJacob Hegna set(MLDeps ${MLDeps} tf_xla_runtime PARENT_SCOPE) 11653753531SMatthias Braun set(MLLinkDeps ${MLLinkDeps} tf_xla_runtime PARENT_SCOPE) 117*26300934SJay Foad add_compile_definitions(LLVM_HAVE_TF_AOT_${fname_allcaps}) 118f86d1f99SJacob Hegnaendfunction() 119