Skip to content

Commit

Permalink
[aie] Remove boost dependency by implementing Dijkstra using ADT (#706)
Browse files Browse the repository at this point in the history
  • Loading branch information
makslevental authored Nov 5, 2023
1 parent 7ae85ed commit dd2bf48
Show file tree
Hide file tree
Showing 16 changed files with 619 additions and 608 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/buildAndTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ defaults:
env:
# Run apt package manager in the CI in non-interactive mode.
# Otherwise, on Ubuntu 20.04 the installation of tzdata asking question
# freezes libboost installation.
DEBIAN_FRONTEND: noninteractive

jobs:
Expand Down Expand Up @@ -120,9 +119,6 @@ jobs:
fetch-depth: 2
submodules: "true"

- name: Install libboost
run: apt-get install -y libboost-all-dev

- name: Install Python and other packages
# Install cmake here to get the latest version to compile
# LLVM. The Ubuntu 20.04 cmake version is only 3.16.3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/generateDocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
submodules: "true"

- name: Install packages
run: sudo apt-get install -y libboost-all-dev graphviz lld
run: sudo apt-get install -y graphviz lld

- name: Install Python packages
run: sudo pip install psutil rich numpy pybind11
Expand Down
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ option(AIE_INCLUDE_INTEGRATION_TESTS
"Generate build targets for the mlir-aie integration tests." OFF)

find_package(MLIR REQUIRED CONFIG)
find_package(Boost REQUIRED)

message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
Expand Down Expand Up @@ -131,7 +130,6 @@ include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${MLIR_INCLUDE_DIRS})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_BINARY_DIR}/include)
include_directories(${Boost_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})

# Silence a false positive GCC -Wunused-but-set-parameter warning in constexpr
Expand Down
2 changes: 1 addition & 1 deletion aie_runtime_lib/AIE/aiesim/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ all: sim

CC_ENV := (export LD_LIBRARY_PATH=${XILINX_VITIS_AIETOOLS}/lib/lnx64.o:$(LD_LIBRARY_PATH))
CC := "${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/bin/g++"
CC_ARGS := -fPIC -fpermissive -c -std=c++17 -D__AIEARCH__=10 -DAIE_OPTION_SCALAR_FLOAT_ON_VECTOR -Wno-deprecated-declarations -DSC_INCLUDE_DYNAMIC_PROCESSES -D__AIESIM__ -D__PS_INIT_AIE__ -DXAIE_DEBUG -Og -flto -D main\(...\)=ps_main\(...\) -I${XILINX_VITIS_AIETOOLS}/include -I${XILINX_VITIS_AIETOOLS}/include/drivers/aiengine -I${XILINX_HLS}/include -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0 -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/backward -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/x86_64-pc-linux-gnu -I${XILINX_VITIS_AIETOOLS}/data/osci_systemc/include -I${XILINX_VITIS_AIETOOLS}/tps/boost_1_72_0 -I. -I$(MLIR_AIE_SRC_DIR) -I${XILINX_VITIS_AIETOOLS}/include/xtlm/include -I${XILINX_VITIS_AIETOOLS}/include/common_cpp/common_cpp_v1_0/include -I${MLIR_AIE_INSTALL}/runtime_lib/x86_64/test_lib/include -I../../ -I../
CC_ARGS := -fPIC -fpermissive -c -std=c++17 -D__AIEARCH__=10 -DAIE_OPTION_SCALAR_FLOAT_ON_VECTOR -Wno-deprecated-declarations -DSC_INCLUDE_DYNAMIC_PROCESSES -D__AIESIM__ -D__PS_INIT_AIE__ -DXAIE_DEBUG -Og -flto -D main\(...\)=ps_main\(...\) -I${XILINX_VITIS_AIETOOLS}/include -I${XILINX_VITIS_AIETOOLS}/include/drivers/aiengine -I${XILINX_HLS}/include -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0 -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/backward -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/x86_64-pc-linux-gnu -I${XILINX_VITIS_AIETOOLS}/data/osci_systemc/include -I. -I$(MLIR_AIE_SRC_DIR) -I${XILINX_VITIS_AIETOOLS}/include/xtlm/include -I${XILINX_VITIS_AIETOOLS}/include/common_cpp/common_cpp_v1_0/include -I${MLIR_AIE_INSTALL}/runtime_lib/x86_64/test_lib/include -I../../ -I../

ps/test.o: $(host)
$(CC_ENV);$(CC) $(CC_ARGS) -o $@ $<
Expand Down
2 changes: 1 addition & 1 deletion aie_runtime_lib/AIE2/aiesim/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ all: sim

CC_ENV := (export LD_LIBRARY_PATH=${XILINX_VITIS_AIETOOLS}/lib/lnx64.o:$(LD_LIBRARY_PATH))
CC := "${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/bin/g++"
CC_ARGS := -fPIC -fpermissive -c -std=c++17 -D__AIEARCH__=20 -DAIE_OPTION_SCALAR_FLOAT_ON_VECTOR -DAIE2_FP32_EMULATION_ACCURACY_FAST -Wno-deprecated-declarations -DSC_INCLUDE_DYNAMIC_PROCESSES -D__AIESIM__ -D__PS_INIT_AIE__ -DXAIE_DEBUG -Og -flto -D main\(...\)=ps_main\(...\) -I${XILINX_VITIS_AIETOOLS}/include -I${XILINX_VITIS_AIETOOLS}/include/drivers/aiengine -I${XILINX_HLS}/include -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0 -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/backward -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/x86_64-pc-linux-gnu -I${XILINX_VITIS_AIETOOLS}/data/osci_systemc/include -I${XILINX_VITIS_AIETOOLS}/tps/boost_1_72_0 -I. -I$(MLIR_AIE_SRC_DIR) -I${XILINX_VITIS_AIETOOLS}/include/xtlm/include -I${XILINX_VITIS_AIETOOLS}/include/common_cpp/common_cpp_v1_0/include -I${MLIR_AIE_INSTALL}/runtime_lib/x86_64/test_lib/include -I../../ -I../
CC_ARGS := -fPIC -fpermissive -c -std=c++17 -D__AIEARCH__=20 -DAIE_OPTION_SCALAR_FLOAT_ON_VECTOR -DAIE2_FP32_EMULATION_ACCURACY_FAST -Wno-deprecated-declarations -DSC_INCLUDE_DYNAMIC_PROCESSES -D__AIESIM__ -D__PS_INIT_AIE__ -DXAIE_DEBUG -Og -flto -D main\(...\)=ps_main\(...\) -I${XILINX_VITIS_AIETOOLS}/include -I${XILINX_VITIS_AIETOOLS}/include/drivers/aiengine -I${XILINX_HLS}/include -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0 -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/backward -I${XILINX_VITIS_AIETOOLS}/tps/lnx64/gcc/include/c++/8.3.0/x86_64-pc-linux-gnu -I${XILINX_VITIS_AIETOOLS}/data/osci_systemc/include -I. -I$(MLIR_AIE_SRC_DIR) -I${XILINX_VITIS_AIETOOLS}/include/xtlm/include -I${XILINX_VITIS_AIETOOLS}/include/common_cpp/common_cpp_v1_0/include -I${MLIR_AIE_INSTALL}/runtime_lib/x86_64/test_lib/include -I../../ -I../

ps/test.o: $(host)
$(CC_ENV);$(CC) $(CC_ARGS) -o $@ $<
Expand Down
2 changes: 1 addition & 1 deletion docs/Building.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ clang/llvm 14+ from source https://github.com/llvm/llvm-project

Xilinx Vitis can be downloaded and installed from the [Xilinx Downloads](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vitis.html) site.

In order to successfully install Vitis on a fresh bare-bones Ubuntu install, some additional prerequisites are required, [documented here](https://support.xilinx.com/s/article/63794?language=en_US). For Ubuntu 20.04, the installation should succeed if you additionally install the following packages: `libncurses5 libtinfo5 libncurses5-dev libncursesw5-dev ncurses-compat-libs libstdc++6:i386 libgtk2.0-0:i386 dpkg-dev:i386 python3-pip libboost-all-dev` Further note that the above mentioned cmake prerequisite is _not_ satisfied by the package provided by Ubuntu; you will need to obtain a more current version.
In order to successfully install Vitis on a fresh bare-bones Ubuntu install, some additional prerequisites are required, [documented here](https://support.xilinx.com/s/article/63794?language=en_US). For Ubuntu 20.04, the installation should succeed if you additionally install the following packages: `libncurses5 libtinfo5 libncurses5-dev libncursesw5-dev ncurses-compat-libs libstdc++6:i386 libgtk2.0-0:i386 dpkg-dev:i386 python3-pip` Further note that the above mentioned cmake prerequisite is _not_ satisfied by the package provided by Ubuntu; you will need to obtain a more current version.

NOTE: Using the Vitis recommended `settings64.sh` script to set up your environement can cause tool conflicts. Setup your environment in the following order for aietools and Vitis:

Expand Down
19 changes: 4 additions & 15 deletions include/aie/Dialect/AIE/IR/AIEDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
#ifndef MLIR_AIE_DIALECT_H
#define MLIR_AIE_DIALECT_H

#include "AIEEnums.h"

#include "aie/Dialect/AIE/IR/AIETargetModel.h"

#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlow.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
Expand All @@ -30,13 +33,12 @@
#include "mlir/Pass/Pass.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Debug.h"

#include <map>
#include <set>

using namespace mlir;

#include "AIEEnums.h"

namespace xilinx {
namespace AIE {
// template <typename ConcreteType>
Expand Down Expand Up @@ -149,23 +151,10 @@ class AIEObjectFifoSubviewType
namespace xilinx {
namespace AIE {

// #include "AIEOpInterfaces.h.inc"

typedef std::pair<WireBundle, int> Port;
typedef std::pair<Port, Port> Connect;
typedef std::pair<DMAChannelDir, int> DMAChannel;

struct AIEArchDesc {
bool checkerboard;
};

// xcve2302 17x2, xcvc1902 50x8
struct AIEDevDesc {
unsigned int rows;
unsigned int cols;
AIEArchDesc arch;
};

const xilinx::AIE::AIETargetModel &getTargetModel(Operation *op);

mlir::ParseResult
Expand Down
180 changes: 180 additions & 0 deletions include/aie/Dialect/AIE/Transforms/AIEPathFinder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
//===- AIEPathfinder.h ------------------------------------------*- C++ -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// (c) Copyright 2021 Xilinx Inc.
//
//===----------------------------------------------------------------------===//

#ifndef AIE_PATHFINDER_H
#define AIE_PATHFINDER_H

#include "aie/Dialect/AIE/IR/AIEDialect.h" // for WireBundle and Port

#include "llvm/ADT/DirectedGraph.h"
#include "llvm/ADT/GraphTraits.h"

#include <algorithm>
#include <list>

namespace xilinx::AIE {

class Switchbox;
class Channel;
using SwitchboxBase = llvm::DGNode<Switchbox, Channel>;
using ChannelBase = llvm::DGEdge<Switchbox, Channel>;
using SwitchboxGraphBase = llvm::DirectedGraph<Switchbox, Channel>;

class Switchbox : public SwitchboxBase {
public:
Switchbox() = delete;
Switchbox(const int col, const int row) : col(col), row(row) {}

int col, row;
};

class Channel : public ChannelBase {
public:
explicit Channel(Switchbox &target) = delete;
Channel(Switchbox &src, Switchbox &target, WireBundle bundle,
uint32_t maxCapacity)
: ChannelBase(target), src(src), bundle(bundle),
maxCapacity(maxCapacity) {}

// Default deleted because of &src and &ChannelBase::TargetNode.
Channel(const Channel &E)
: ChannelBase(E), src(E.src), bundle(E.bundle),
maxCapacity(E.maxCapacity), demand(E.demand),
usedCapacity(E.usedCapacity), fixedCapacity(E.fixedCapacity),
overCapacityCount(E.overCapacityCount) {}

// Default deleted because of &src and &ChannelBase::TargetNode.
Channel &operator=(Channel &&E) {
ChannelBase::operator=(std::move(E));
src = std::move(E.src);
bundle = E.bundle;
maxCapacity = E.maxCapacity;
demand = E.demand;
usedCapacity = E.usedCapacity;
fixedCapacity = E.fixedCapacity;
overCapacityCount = E.overCapacityCount;
return *this;
}

Switchbox &src;
WireBundle bundle;
uint32_t maxCapacity = 0; // maximum number of routing resources
double demand = 0.0; // indicates how many flows want to use this Channel
uint32_t usedCapacity = 0; // how many flows are actually using this Channel
std::set<uint32_t> fixedCapacity; // channels not available to the algorithm
uint32_t overCapacityCount = 0; // history of Channel being over capacity
};

class SwitchboxGraph : public SwitchboxGraphBase {
public:
SwitchboxGraph() = default;
~SwitchboxGraph() = default;
};

// A SwitchSetting defines the required settings for a Switchbox for a flow
// SwitchSetting.first is the incoming signal
// SwitchSetting.second is the fanout
typedef std::pair<Port, std::set<Port>> SwitchSetting;
typedef std::map<Switchbox *, SwitchSetting> SwitchSettings;

// A Flow defines source and destination vertices
// Only one source, but any number of destinations (fanout)
typedef std::pair<Switchbox *, Port> PathEndPoint;
typedef std::pair<PathEndPoint, std::vector<PathEndPoint>> Flow;

class Pathfinder {
SwitchboxGraph graph;
std::vector<Flow> flows;
bool maxIterReached{};
std::map<TileID, Switchbox> grid;
// Use a list instead of a vector because nodes have an edge list of raw
// pointers to edges (so growing a vector would invalidate the pointers).
std::list<Channel> edges;

public:
Pathfinder() = default;
Pathfinder(int maxCol, int maxRow, DeviceOp &d);
void addFlow(TileID srcCoords, Port srcPort, TileID dstCoords, Port dstPort);
bool addFixedConnection(TileID coord, Port port);
bool isLegal();
std::map<PathEndPoint, SwitchSettings> findPaths(int maxIterations = 1000);

Switchbox *getSwitchbox(TileID coords) {
auto sb = std::find_if(graph.begin(), graph.end(), [&](Switchbox *sb) {
return sb->col == coords.first && sb->row == coords.second;
});
assert(sb != graph.end() && "couldn't find sb");
return *sb;
}
};

} // namespace xilinx::AIE

namespace llvm {
using namespace xilinx::AIE;

template <> struct GraphTraits<Switchbox *> {
using NodeRef = Switchbox *;

static Switchbox *SwitchboxGraphGetSwitchbox(DGEdge<Switchbox, Channel> *P) {
return &P->getTargetNode();
}

// Provide a mapped iterator so that the GraphTrait-based implementations can
// find the target nodes without having to explicitly go through the edges.
using ChildIteratorType =
mapped_iterator<Switchbox::iterator,
decltype(&SwitchboxGraphGetSwitchbox)>;
using ChildEdgeIteratorType = Switchbox::iterator;

static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) {
return ChildIteratorType(N->begin(), &SwitchboxGraphGetSwitchbox);
}
static ChildIteratorType child_end(NodeRef N) {
return ChildIteratorType(N->end(), &SwitchboxGraphGetSwitchbox);
}

static ChildEdgeIteratorType child_edge_begin(NodeRef N) {
return N->begin();
}
static ChildEdgeIteratorType child_edge_end(NodeRef N) { return N->end(); }
};

template <>
struct GraphTraits<SwitchboxGraph *> : public GraphTraits<Switchbox *> {
using nodes_iterator = SwitchboxGraph::iterator;
static NodeRef getEntryNode(SwitchboxGraph *DG) { return *DG->begin(); }
static nodes_iterator nodes_begin(SwitchboxGraph *DG) { return DG->begin(); }
static nodes_iterator nodes_end(SwitchboxGraph *DG) { return DG->end(); }
};

inline raw_ostream &operator<<(raw_ostream &OS, const Switchbox &S) {
OS << "Switchbox(" << S.col << ", " << S.row << ")";
return OS;
}

inline raw_ostream &operator<<(raw_ostream &OS, const Channel &C) {
OS << "Channel(src=" << C.src << ", dst=" << C.getTargetNode() << ")";
return OS;
}

} // namespace llvm

namespace std {
using namespace xilinx::AIE;
template <> struct less<Switchbox *> {
bool operator()(const Switchbox *a, const Switchbox *b) const {
return a->col == b->col ? a->row < b->row : a->col < b->col;
}
};
} // namespace std

#endif
Loading

0 comments on commit dd2bf48

Please sign in to comment.