Skip to content

Commit

Permalink
First stage of instrumentation point rewrite
Browse files Browse the repository at this point in the history
New classes added, but not yet hooked up to the instrumentor.
  • Loading branch information
nchaimov committed Jan 16, 2025
1 parent 66c4eaa commit de02a21
Show file tree
Hide file tree
Showing 5 changed files with 330 additions and 16 deletions.
9 changes: 6 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,7 @@ set(SALT_HEADER_FILES
dprint.hpp
ryml_all.hpp
selectfile.hpp
tau_datatypes.h
tooling.hpp
instrumentor.hpp
)

list(TRANSFORM SALT_HEADER_FILES PREPEND "${CMAKE_SOURCE_DIR}/include/")
Expand All @@ -230,6 +229,7 @@ list(TRANSFORM CPARSE_LLVM_SRCS PREPEND "${CMAKE_SOURCE_DIR}/src/")
# If we refactor into a library that executables link against it will simplify this and reduce repitition
add_executable(cparse-llvm)
target_sources(cparse-llvm PUBLIC ${CPARSE_LLVM_SRCS})
target_sources(cparse-llvm PUBLIC FILE_SET headers TYPE HEADERS FILES ${SALT_HEADER_FILES})
target_include_directories(cparse-llvm PUBLIC "${CMAKE_SOURCE_DIR}/include" "${CMAKE_BINARY_DIR}/include")
target_compile_features(cparse-llvm PUBLIC cxx_std_17)
target_link_libraries(cparse-llvm PUBLIC SALT_LLVM_TOOLING) # Inherit definitions, compile features, etc.
Expand Down Expand Up @@ -291,20 +291,23 @@ if(MLIR_FOUND AND Flang_FOUND)

set(SALT_FLANG_PLUGIN_HEADER_FILES
selectfile.hpp
tau_datatypes.h
flang_source_location.hpp
flang_instrumentation_constants.hpp
flang_instrumentation_point.hpp
)
list(TRANSFORM SALT_FLANG_PLUGIN_HEADER_FILES PREPEND "${CMAKE_SOURCE_DIR}/include/")

set(SALT_FLANG_PLUGIN_SRCS
selectfile.cpp
flang_source_location.cpp
flang_instrumentation_point.cpp
salt_instrument_flang_plugin.cpp
)
list(TRANSFORM SALT_FLANG_PLUGIN_SRCS PREPEND "${CMAKE_SOURCE_DIR}/src/")

add_library(salt-flang-plugin SHARED)
target_sources(salt-flang-plugin PUBLIC ${SALT_FLANG_PLUGIN_SRCS})
target_sources(salt-flang-plugin PUBLIC FILE_SET headers TYPE HEADERS FILES ${SALT_FLANG_PLUGIN_HEADER_FILES})
target_include_directories(salt-flang-plugin PUBLIC "${CMAKE_SOURCE_DIR}/include" "${CMAKE_BINARY_DIR}/include" )
target_compile_features(salt-flang-plugin PUBLIC cxx_std_17)
target_link_libraries(salt-flang-plugin PUBLIC SALT_FLANG_FRONTEND)
Expand Down
39 changes: 39 additions & 0 deletions include/flang_instrumentation_constants.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* 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.
*/

#ifndef FLANG_INSTRUMENTATION_CONSTANTS_HPP
#define FLANG_INSTRUMENTATION_CONSTANTS_HPP

// Configuration file environment variable
#define SALT_FORTRAN_CONFIG_FILE_VAR "SALT_FORTRAN_CONFIG_FILE"
#define SALT_FORTRAN_CONFIG_DEFAULT_PATH "config_files/tau_config.yaml"

// Selective instrumentation environment variable
#define SALT_FORTRAN_SELECT_FILE_VAR "SALT_FORTRAN_SELECT_FILE"

// Configuration file YAML keys
#define SALT_FORTRAN_KEY "Fortran"
#define SALT_FORTRAN_PROGRAM_BEGIN_KEY "program_insert"
#define SALT_FORTRAN_PROCEDURE_BEGIN_KEY "procedure_begin_insert"
#define SALT_FORTRAN_PROCEDURE_END_KEY "procedure_end_insert"

// Configuration file template replacement strings
#define SALT_FORTRAN_TIMER_NAME_TEMPLATE R"(\$\{full_timer_name\})"

// Fortran line splitting
#define SALT_FORTRAN_STRING_SPLITTER "&\n &"
#define SALT_F77_LINE_LENGTH 64

#endif //FLANG_INSTRUMENTATION_CONSTANTS_HPP
167 changes: 167 additions & 0 deletions include/flang_instrumentation_point.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/* 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.
*/

#ifndef FLANG_INSTRUMENTATION_POINT_HPP
#define FLANG_INSTRUMENTATION_POINT_HPP

#include <string>
#include <map>
#include <utility>

namespace salt::fortran {
enum class InstrumentationPointType {
PROGRAM_BEGIN, // Declare profiler, initialize TAU, set node, start timer
PROCEDURE_BEGIN, // Declare profiler, start timer
PROCEDURE_END, // Stop timer on the line after
RETURN_STMT, // Stop timer on the line before
IF_RETURN // Transform if to if-then-endif, stop timer before return
};

enum class InstrumentationLocation {
BEFORE,
AFTER,
REPLACE
};

using InstrumentationMap = std::map<InstrumentationPointType, const std::string>;

class InstrumentationPoint {
public:
InstrumentationPoint(const InstrumentationPointType type, const int line,
const InstrumentationLocation location) : instrumentationType_(type), line_(line),
location_(location) {
}

virtual ~InstrumentationPoint() = default;

[[nodiscard]] InstrumentationPointType instrumentationType() const {
return instrumentationType_;
}

[[nodiscard]] int line() const {
return line_;
}

[[nodiscard]] InstrumentationLocation location() const {
return location_;
}

[[nodiscard]] bool instrumentBefore() const {
return location() == InstrumentationLocation::BEFORE;
}

bool operator<(const InstrumentationPoint &other) const {
if (line() == other.line()) {
if (instrumentBefore() && !other.instrumentBefore()) {
return true;
}
return false;
}
return line() < other.line();
}

[[nodiscard]] std::string typeString() const;

[[nodiscard]] std::string locationString() const;

[[nodiscard]] virtual std::string toString() const;

[[nodiscard]] virtual std::string instrumentationString(const InstrumentationMap &instMap,
const std::string &lineText) const;

private:
const InstrumentationPointType instrumentationType_;
const int line_;
const InstrumentationLocation location_;
};

class ProgramBeginInstrumentationPoint final : public InstrumentationPoint {
public:
ProgramBeginInstrumentationPoint(const int line, std::string timerName) : InstrumentationPoint(
InstrumentationPointType::PROGRAM_BEGIN, line, InstrumentationLocation::BEFORE),
timerName_(std::move(timerName)) {
}

[[nodiscard]] std::string timerName() const {
return timerName_;
}

[[nodiscard]] std::string toString() const override;

[[nodiscard]] std::string instrumentationString(const InstrumentationMap &instMap,
const std::string &lineText) const override;

private:
const std::string timerName_;
};

class ProcedureBeginInstrumentationPoint final : public InstrumentationPoint {
public:
ProcedureBeginInstrumentationPoint(const int line, std::string timerName) : InstrumentationPoint(
InstrumentationPointType::PROCEDURE_BEGIN,
line,
InstrumentationLocation::BEFORE),
timerName_(std::move(timerName)) {
}

[[nodiscard]] std::string timerName() const {
return timerName_;
}

[[nodiscard]] std::string toString() const override;

[[nodiscard]] std::string instrumentationString(const InstrumentationMap &instMap,
const std::string &lineText) const override;

private:
const std::string timerName_;
};

class ProcedureEndInstrumentationPoint final : public InstrumentationPoint {
public:
explicit ProcedureEndInstrumentationPoint(const int line) : InstrumentationPoint(
InstrumentationPointType::PROCEDURE_END, line, InstrumentationLocation::AFTER) {
}
};

class ReturnStmtInstrumentationPoint final : public InstrumentationPoint {
public:
explicit ReturnStmtInstrumentationPoint(const int line) : InstrumentationPoint(
InstrumentationPointType::RETURN_STMT, line, InstrumentationLocation::BEFORE) {
}
};

class IfReturnStmtInstrumentationPoint final : public InstrumentationPoint {
public:
explicit IfReturnStmtInstrumentationPoint(const int line, const int conditionalColumn) : InstrumentationPoint(
InstrumentationPointType::IF_RETURN, line, InstrumentationLocation::REPLACE),
conditionalColumn_(conditionalColumn) {
}

[[nodiscard]] int conditionalColumn() const {
return conditionalColumn_;
}

[[nodiscard]] std::string toString() const override;

[[nodiscard]] std::string instrumentationString(const InstrumentationMap &instMap,
const std::string &lineText) const override;

private:
const int conditionalColumn_;
};
}

#endif //FLANG_INSTRUMENTATION_POINT_HPP
116 changes: 116 additions & 0 deletions src/flang_instrumentation_point.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* 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.
*/


#include <string>
#include <sstream>
#include <regex>

#include "flang/Common/idioms.h"

#include "flang_instrumentation_point.hpp"
#include "flang_instrumentation_constants.hpp"


using namespace std::string_literals;

std::string salt::fortran::InstrumentationPoint::typeString() const {
switch (instrumentationType()) {
case InstrumentationPointType::PROGRAM_BEGIN:
return "PROGRAM_BEGIN"s;
case InstrumentationPointType::PROCEDURE_BEGIN:
return "PROCEDURE_BEGIN"s;
case InstrumentationPointType::PROCEDURE_END:
return "PROCEDURE_END"s;
case InstrumentationPointType::RETURN_STMT:
return "RETURN_STMT"s;
case InstrumentationPointType::IF_RETURN:
return "IF_RETURN"s;
default:
CRASH_NO_CASE;
}
}

std::string salt::fortran::InstrumentationPoint::locationString() const {
switch (location()) {
case InstrumentationLocation::BEFORE:
return "BEFORE"s;
case InstrumentationLocation::AFTER:
return "AFTER"s;
case InstrumentationLocation::REPLACE:
return "REPLACE"s;
default:
CRASH_NO_CASE;
}
}

std::string salt::fortran::InstrumentationPoint::toString() const {
std::stringstream ss;
ss << line() << "\t";
ss << locationString() << "\t";
ss << typeString() << "\t";
return ss.str();
}

std::string salt::fortran::InstrumentationPoint::instrumentationString(const InstrumentationMap &instMap,
[[maybe_unused]] const std::string &lineText)
const {
return instMap.at(instrumentationType());
}

std::string salt::fortran::ProgramBeginInstrumentationPoint::toString() const {
std::stringstream ss;
ss << InstrumentationPoint::toString();
ss << "\"" << timerName() << "\"\t";
return ss.str();
}

std::string salt::fortran::ProgramBeginInstrumentationPoint::instrumentationString(
const InstrumentationMap &instMap, [[maybe_unused]] const std::string &lineText) const {
static std::regex timerNameRegex{SALT_FORTRAN_TIMER_NAME_TEMPLATE};
const std::string instTemplate{InstrumentationPoint::instrumentationString(instMap, lineText)};
return std::regex_replace(instTemplate, timerNameRegex, timerName());
}

std::string salt::fortran::ProcedureBeginInstrumentationPoint::toString() const {
std::stringstream ss;
ss << InstrumentationPoint::toString();
ss << timerName() << "\t";
return ss.str();
}

std::string salt::fortran::ProcedureBeginInstrumentationPoint::instrumentationString(
const InstrumentationMap &instMap, [[maybe_unused]] const std::string &lineText) const {
static std::regex timerNameRegex{SALT_FORTRAN_TIMER_NAME_TEMPLATE};
const std::string instTemplate{InstrumentationPoint::instrumentationString(instMap, lineText)};
return std::regex_replace(instTemplate, timerNameRegex, timerName());
}

std::string salt::fortran::IfReturnStmtInstrumentationPoint::toString() const {
std::stringstream ss;
ss << InstrumentationPoint::toString();
ss << conditionalColumn() << "\t";
return ss.str();
}

std::string salt::fortran::IfReturnStmtInstrumentationPoint::instrumentationString(
const InstrumentationMap &instMap, const std::string &lineText) const {
std::stringstream ss;
ss << lineText.substr(0, conditionalColumn()) << " then\n";
ss << InstrumentationPoint::instrumentationString(instMap, lineText) << "\n";
ss << " return\n";
ss << " endif\n";
return ss.str();
}
15 changes: 2 additions & 13 deletions src/salt_instrument_flang_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,14 @@ limitations under the License.
#include "flang/Parser/source.h"
#include "flang/Common/indirection.h"

#include "flang_instrumentation_constants.hpp"
#include "selectfile.hpp"
#include "flang_source_location.hpp"
#include "flang_instrumentation_point.hpp"

// TODO Split declarations into a separate header file.
// TODO Put debug output behind verbose flag

#define SALT_FORTRAN_CONFIG_FILE_VAR "SALT_FORTRAN_CONFIG_FILE"
#define SALT_FORTRAN_CONFIG_DEFAULT_PATH "config_files/tau_config.yaml"

#define SALT_FORTRAN_SELECT_FILE_VAR "SALT_FORTRAN_SELECT_FILE"

#define SALT_FORTRAN_KEY "Fortran"
#define SALT_FORTRAN_PROGRAM_BEGIN_KEY "program_insert"
#define SALT_FORTRAN_PROCEDURE_BEGIN_KEY "procedure_begin_insert"
#define SALT_FORTRAN_PROCEDURE_END_KEY "procedure_end_insert"

#define SALT_FORTRAN_TIMER_NAME_TEMPLATE R"(\$\{full_timer_name\})"
#define SALT_FORTRAN_STRING_SPLITTER "&\n &"
#define SALT_F77_LINE_LENGTH 64

using namespace Fortran::frontend;
using namespace salt::fortran;
Expand Down

0 comments on commit de02a21

Please sign in to comment.