From 4a927f33384e667c1381ca2e6ea51ddea7d0976f Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Mon, 27 Jan 2025 15:36:03 -0500 Subject: [PATCH] Add wrapper script to delegate to instrumentor based on language Saltfm now will decide whether to call cparse-llvm or fparse-llvm to instrument the code. --- CMakeLists.txt | 12 ++-- src/fparse-llvm.in | 14 +++-- src/saltfm.in | 150 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 9 deletions(-) create mode 100755 src/saltfm.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a3b61c..71cb91e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -328,6 +328,10 @@ else() message(STATUS "Flang not found -- skipping Flang frontend plugin") endif() +configure_file(${CMAKE_SOURCE_DIR}/src/saltfm.in ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/saltfm @ONLY) +install(PROGRAMS ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/saltfm + TYPE BIN) # TYPE BIN installs into CMAKE_INSTALL_BINDIR + #--------------------- # Find TAU locations for testing #--------------------- @@ -473,7 +477,7 @@ function(add_instrumentor_test test_src) set(TEST_NAME ${ARGV1}) endif() add_test(NAME ${TEST_NAME} - COMMAND $ ${CMAKE_SOURCE_DIR}/tests/${test_src}) + COMMAND ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/saltfm ${CMAKE_SOURCE_DIR}/tests/${test_src}) set_tests_properties(${TEST_NAME} PROPERTIES REQUIRED_FILES "${CMAKE_SOURCE_DIR}/tests/${test_src}" @@ -536,7 +540,7 @@ function(compile_instrumented test_src) endif() set(test_path ${CMAKE_SOURCE_DIR}/tests/${TEST_BASE_NAME}.${TEST_LANG}) - set(TAUC_OPTS -optVerbose -optSaltInst -optSaltParser=$ -optSaltConfigFile=${CMAKE_SOURCE_DIR}/config_files/tau_config.yaml) + set(TAUC_OPTS -optVerbose -optSaltInst -optSaltParser=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/saltfm -optSaltConfigFile=${CMAKE_SOURCE_DIR}/config_files/tau_config.yaml) set(compile_opts ${TAU_COMPILE_OPTIONS}) foreach(comp IN LISTS compilers_to_test) set(lower_comp ${comp}) @@ -640,11 +644,11 @@ set_tests_properties(fparse_llvm_smoke_test foreach(test_source IN LISTS FORTRAN_TESTS_SOURCES_LIST) add_test(NAME instrument_${test_source} - COMMAND ./${CMAKE_INSTALL_BINDIR}/fparse-llvm ${CMAKE_SOURCE_DIR}/tests/fortran/${test_source} + COMMAND ./${CMAKE_INSTALL_BINDIR}/saltfm ${CMAKE_SOURCE_DIR}/tests/fortran/${test_source} ) set_tests_properties(instrument_${test_source} PROPERTIES - REQUIRED_FILES "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/fparse-llvm" + REQUIRED_FILES "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/fparse-llvm;${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/saltfm" ENVIRONMENT "SALT_FORTRAN_CONFIG_FILE=${CMAKE_SOURCE_DIR}/config_files/tau_config.yaml;SALT_FORTRAN_VERBOSE=1" PASS_REGULAR_EXPRESSION "SALT Instrumentor Plugin finished" ) diff --git a/src/fparse-llvm.in b/src/fparse-llvm.in index 27f5274..231eebc 100755 --- a/src/fparse-llvm.in +++ b/src/fparse-llvm.in @@ -164,7 +164,7 @@ for arg in "$@"; do exit 0 elif [[ $arg == --version ]]; then echo "SALT FM Version: ${_VERSION}" - flang-new -version + flang-new --version exit 0 elif $expecting_arg_to_forward; then args+=("$arg") @@ -221,20 +221,24 @@ done #echo "args: \"${args[*]}\"" # print the argument list if [[ -z "${input_file:-}" ]]; then - input_file="${args[0]}" - args=("${args[@]:1}") + if [[ ${#args[@]} -gt 0 ]]; then + # An input file has not been recognized. + # Try to take the first argument as the input file + input_file="${args[0]}" + args=("${args[@]:1}") + fi fi echo "input file: ${input_file:-\"\" }" # If no output file is given, emit the output file in the current working directory if [[ -z "${output_file:-}" ]]; then - if [[ ${input_file} == *.* ]]; then + if [[ ${input_file:-none} == *.* ]]; then file_ext=".${input_file##*.}" else file_ext="" fi - if [[ "${input_file}" == */* ]]; then + if [[ "${input_file:-none}" == */* ]]; then output_file="${input_file%.*}.inst${file_ext//f/F}" output_file="$(pwd)/${output_file##*/}" else diff --git a/src/saltfm.in b/src/saltfm.in new file mode 100755 index 0000000..6f62b57 --- /dev/null +++ b/src/saltfm.in @@ -0,0 +1,150 @@ +#!/usr/bin/env bash +# Copyright (C) 2025, ParaTools, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script determines whether to call the SALTFM C/C++ or Fortran instrumentor +# based on the file extension of the input source file or the --lang option. + +set -o errexit +set -o nounset +set -o pipefail +#set -o verbose +set -o xtrace + +readonly _VERSION=@SALT_VERSION_MAJOR@.@SALT_VERSION_MINOR@ +# get the absolute path of this script +_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly _SCRIPT_DIR + +read -r -d '' _USAGE < [... ] + +OPTIONS: + +Generic SALTFM Options: + + -h - Alias for --help + --help - Display available options (--help-hidden for more) + --help-fortran - Display Fortran instrumentor options and usage information + --help-c - Display C/C++ instrumentor options and usage information + --help-cxx - Display C/C++ instrumentor options and usage information + --version - Display the version of this program + --lang= - Specify the language of the input source file (default: auto-detect) + --show - Print the command line that would be executed by the outter wrapper script + +TAU instrumentor options: + + --config_file= - Specify path to SALT configuration YAML file + --tau_instrument_inline - Instrument inlined functions (default: false) + --tau_output= - Specify name of output instrumented file + --tau_select_file= - Provide a selective instrumentation specification file + --tau_use_cxx_api - Use TAU's C++ instrumentation API +EOF + +# Add a help/usage message function +function usage { + echo "$_USAGE" +} + +if [[ $# -eq 0 ]]; then + usage + exit 1 +fi + +# Reconstruct argument list to forward to tool +args=() +for arg in "$@"; do + #echo "working on arg: $arg" + if [[ $arg == --lang=* ]]; then + lang="${arg#--lang=}" + case "${lang}" in + fortran|Fortran) + force_lang=fortran + tool=fparse-llvm + ;; + c|C|cxx|CXX|c++|C++) + force_lang=c + tool=cparse-llvm + ;; + *) + echo "Invalid language specified: $lang" + exit 1 + ;; + esac + elif [[ $arg == --help || $arg == -h ]]; then + if [[ -n "${force_lang:-}" ]]; then + "${_SCRIPT_DIR}/${tool}" --help + else + usage + fi + exit 0 + elif [[ $arg == --help-fortran ]]; then + "${_SCRIPT_DIR}/fparse-llvm" --help + exit 0 + elif [[ $arg == --help-c || $arg == --help-cxx ]]; then + "${_SCRIPT_DIR}/cparse-llvm" --help + exit 0 + elif [[ $arg == --version ]]; then + echo "SALT FM Version: ${_VERSION}" + if [[ -n "${tool:-}" ]]; then + "${_SCRIPT_DIR}/${tool}" --version + fi + exit 0 + elif [[ $arg == *.[Ff]90 || $arg == *.[Ff] || $arg == *.[Ff]03 ]]; then + args+=("$arg") + if [[ -z "${tool:-}" ]]; then + tool=fparse-llvm + fi + elif [[ $arg == *.[cC] || $arg == *.[cC][cC] || $arg == *.cpp || $arg == *.CPP ]]; then + args+=("$arg") + if [[ -z "${tool:-}" ]]; then + tool=cparse-llvm + fi + elif [[ $arg == --show ]]; then + show=true + else + args+=("$arg") + fi +done + +if [[ -z "${tool:-}" ]]; then + echo "No source files provided, language not detected." + exit 1 +fi + +# Check if the tool exists +if [[ ! -f "${_SCRIPT_DIR}/${tool}" ]]; then + echo "Tool not found: ${_SCRIPT_DIR}/${tool}" + exit 1 +fi + +# Print the command line that would be executed by the outter wrapper script +# if the --show flag is set +if [[ "${show:-false}" == "true" ]]; then + if [[ "${tool}" == "fparse-llvm" ]]; then + echo "$tool --show ${args[*]}" + # fparse-llvm is also a wrapper script with a --show flag + # so print the command line that would be executed by the inner wrapper script + # if the language is Fortran + "${_SCRIPT_DIR}/fparse-llvm" --show "${args[@]}" + else + echo "$tool ${args[*]}" + fi + exit 0 +fi + +# Execute the tool with the arguments +"${_SCRIPT_DIR}/${tool}" "${args[@]}"