esiaccel 0.1.0__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of esiaccel might be problematic. Click here for more details.

Files changed (41) hide show
  1. esiaccel/__init__.py +13 -0
  2. esiaccel/accelerator.py +95 -0
  3. esiaccel/bin/esi-cosim.py +405 -0
  4. esiaccel/bin/esiquery +0 -0
  5. esiaccel/cmake/esiaccelConfig.cmake +15 -0
  6. esiaccel/codegen.py +197 -0
  7. esiaccel/cosim/Cosim_DpiPkg.sv +85 -0
  8. esiaccel/cosim/Cosim_Endpoint.sv +189 -0
  9. esiaccel/cosim/Cosim_Manifest.sv +32 -0
  10. esiaccel/cosim/driver.cpp +131 -0
  11. esiaccel/cosim/driver.sv +60 -0
  12. esiaccel/esiCppAccel.cpython-313-x86_64-linux-gnu.so +0 -0
  13. esiaccel/include/esi/Accelerator.h +232 -0
  14. esiaccel/include/esi/CLI.h +77 -0
  15. esiaccel/include/esi/Common.h +154 -0
  16. esiaccel/include/esi/Context.h +74 -0
  17. esiaccel/include/esi/Design.h +127 -0
  18. esiaccel/include/esi/Engines.h +124 -0
  19. esiaccel/include/esi/Logging.h +231 -0
  20. esiaccel/include/esi/Manifest.h +72 -0
  21. esiaccel/include/esi/Ports.h +275 -0
  22. esiaccel/include/esi/Services.h +404 -0
  23. esiaccel/include/esi/Types.h +182 -0
  24. esiaccel/include/esi/Utils.h +102 -0
  25. esiaccel/include/esi/backends/Cosim.h +85 -0
  26. esiaccel/include/esi/backends/RpcServer.h +55 -0
  27. esiaccel/include/esi/backends/Trace.h +87 -0
  28. esiaccel/lib/libCosimBackend.so +0 -0
  29. esiaccel/lib/libESICppRuntime.so +0 -0
  30. esiaccel/lib/libEsiCosimDpiServer.so +0 -0
  31. esiaccel/lib/libMtiPli.so +0 -0
  32. esiaccel/lib/libz.so.1 +0 -0
  33. esiaccel/lib/libz.so.1.2.13 +0 -0
  34. esiaccel/types.py +512 -0
  35. esiaccel/utils.py +36 -0
  36. esiaccel-0.1.0.dist-info/METADATA +254 -0
  37. esiaccel-0.1.0.dist-info/RECORD +41 -0
  38. esiaccel-0.1.0.dist-info/WHEEL +6 -0
  39. esiaccel-0.1.0.dist-info/entry_points.txt +4 -0
  40. esiaccel-0.1.0.dist-info/licenses/LICENSE +234 -0
  41. esiaccel-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,182 @@
1
+ //===- Types.h - ESI type system -------------------------------*- C++ -*-===//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+ //
9
+ // DO NOT EDIT!
10
+ // This file is distributed as part of an ESI package. The source for this file
11
+ // should always be modified within CIRCT.
12
+ //
13
+ //===----------------------------------------------------------------------===//
14
+
15
+ // NOLINTNEXTLINE(llvm-header-guard)
16
+ #ifndef ESI_TYPES_H
17
+ #define ESI_TYPES_H
18
+
19
+ #include <cstdint>
20
+ #include <map>
21
+ #include <string>
22
+ #include <vector>
23
+
24
+ namespace esi {
25
+
26
+ /// Root class of the ESI type system.
27
+ class Type {
28
+ public:
29
+ using ID = std::string;
30
+ Type(const ID &id) : id(id) {}
31
+ virtual ~Type() = default;
32
+
33
+ ID getID() const { return id; }
34
+ virtual std::ptrdiff_t getBitWidth() const { return -1; }
35
+
36
+ protected:
37
+ ID id;
38
+ };
39
+
40
+ /// Bundles represent a collection of channels. Services exclusively expose
41
+ /// bundles (sometimes of just one channel). As such, they are the type of
42
+ /// accessible ports on an accelerator, from a host API perspective.
43
+ /// TODO: Add a good description of direction?
44
+ class BundleType : public Type {
45
+ public:
46
+ enum Direction { To, From };
47
+
48
+ using ChannelVector =
49
+ std::vector<std::tuple<std::string, Direction, const Type *>>;
50
+
51
+ BundleType(const ID &id, const ChannelVector &channels)
52
+ : Type(id), channels(channels) {}
53
+
54
+ const ChannelVector &getChannels() const { return channels; }
55
+ std::ptrdiff_t getBitWidth() const override { return -1; };
56
+
57
+ std::pair<const Type *, Direction> findChannel(std::string name) const {
58
+ for (auto [channelName, dir, type] : channels)
59
+ if (channelName == name)
60
+ return std::make_pair(type, dir);
61
+ throw std::runtime_error("Channel '" + name + "' not found in bundle");
62
+ }
63
+
64
+ protected:
65
+ ChannelVector channels;
66
+ };
67
+
68
+ /// Channels are the basic communication primitives. They are unidirectional and
69
+ /// carry one values of one type.
70
+ class ChannelType : public Type {
71
+ public:
72
+ ChannelType(const ID &id, const Type *inner) : Type(id), inner(inner) {}
73
+ const Type *getInner() const { return inner; }
74
+ std::ptrdiff_t getBitWidth() const override { return inner->getBitWidth(); };
75
+
76
+ private:
77
+ const Type *inner;
78
+ };
79
+
80
+ /// The "void" type is a special type which can be used to represent no type.
81
+ class VoidType : public Type {
82
+ public:
83
+ VoidType(const ID &id) : Type(id) {}
84
+ // 'void' is 1 bit by convention.
85
+ std::ptrdiff_t getBitWidth() const override { return 1; };
86
+ };
87
+
88
+ /// The "any" type is a special type which can be used to represent any type, as
89
+ /// identified by the type id. Said type id is guaranteed to be present in the
90
+ /// manifest. Importantly, the "any" type id over the wire may not be a string
91
+ /// as it is in software.
92
+ class AnyType : public Type {
93
+ public:
94
+ AnyType(const ID &id) : Type(id) {}
95
+ std::ptrdiff_t getBitWidth() const override { return -1; };
96
+ };
97
+
98
+ /// Bit vectors include signed, unsigned, and signless integers.
99
+ class BitVectorType : public Type {
100
+ public:
101
+ BitVectorType(const ID &id, uint64_t width) : Type(id), width(width) {}
102
+
103
+ uint64_t getWidth() const { return width; }
104
+ std::ptrdiff_t getBitWidth() const override { return getWidth(); };
105
+
106
+ private:
107
+ uint64_t width;
108
+ };
109
+
110
+ /// Bits are just an array of bits. They are not interpreted as a number but are
111
+ /// identified in the manifest as "signless" ints.
112
+ class BitsType : public BitVectorType {
113
+ public:
114
+ using BitVectorType::BitVectorType;
115
+ };
116
+
117
+ /// Integers are bit vectors which may be signed or unsigned and are interpreted
118
+ /// as numbers.
119
+ class IntegerType : public BitVectorType {
120
+ public:
121
+ using BitVectorType::BitVectorType;
122
+ };
123
+
124
+ /// Signed integer.
125
+ class SIntType : public IntegerType {
126
+ public:
127
+ using IntegerType::IntegerType;
128
+ };
129
+
130
+ /// Unsigned integer.
131
+ class UIntType : public IntegerType {
132
+ public:
133
+ using IntegerType::IntegerType;
134
+ };
135
+
136
+ /// Structs are an ordered collection of fields, each with a name and a type.
137
+ class StructType : public Type {
138
+ public:
139
+ using FieldVector = std::vector<std::pair<std::string, const Type *>>;
140
+
141
+ StructType(const ID &id, const FieldVector &fields)
142
+ : Type(id), fields(fields) {}
143
+
144
+ const FieldVector &getFields() const { return fields; }
145
+ std::ptrdiff_t getBitWidth() const override {
146
+ std::ptrdiff_t size = 0;
147
+ for (auto [name, ty] : getFields()) {
148
+ std::ptrdiff_t fieldSize = ty->getBitWidth();
149
+ if (fieldSize < 0)
150
+ return -1;
151
+ size += fieldSize;
152
+ }
153
+ return size;
154
+ }
155
+
156
+ private:
157
+ FieldVector fields;
158
+ };
159
+
160
+ /// Arrays have a compile time specified (static) size and an element type.
161
+ class ArrayType : public Type {
162
+ public:
163
+ ArrayType(const ID &id, const Type *elementType, uint64_t size)
164
+ : Type(id), elementType(elementType), size(size) {}
165
+
166
+ const Type *getElementType() const { return elementType; }
167
+ uint64_t getSize() const { return size; }
168
+ std::ptrdiff_t getBitWidth() const override {
169
+ std::ptrdiff_t elementSize = elementType->getBitWidth();
170
+ if (elementSize < 0)
171
+ return -1;
172
+ return elementSize * size;
173
+ }
174
+
175
+ private:
176
+ const Type *elementType;
177
+ uint64_t size;
178
+ };
179
+
180
+ } // namespace esi
181
+
182
+ #endif // ESI_TYPES_H
@@ -0,0 +1,102 @@
1
+ //===- Utils.h - ESI runtime utility code -----------------------*- C++ -*-===//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+ //
9
+ // DO NOT EDIT!
10
+ // This file is distributed as part of an ESI package. The source for this file
11
+ // should always be modified within CIRCT.
12
+ //
13
+ //===----------------------------------------------------------------------===//
14
+
15
+ // NOLINTNEXTLINE(llvm-header-guard)
16
+ #ifndef ESI_UTILS_H
17
+ #define ESI_UTILS_H
18
+
19
+ #include <cstdint>
20
+ #include <functional>
21
+ #include <mutex>
22
+ #include <optional>
23
+ #include <queue>
24
+ #include <string>
25
+
26
+ namespace esi {
27
+ namespace utils {
28
+ // Very basic base64 encoding.
29
+ void encodeBase64(const void *data, size_t size, std::string &out);
30
+
31
+ /// C++'s stdlib doesn't have a hash_combine function. This is a simple one.
32
+ inline size_t hash_combine(size_t h1, size_t h2) {
33
+ return h1 + 0x9e3779b9 + (h2 << 6) + (h2 >> 2);
34
+ }
35
+
36
+ /// Thread safe queue. Just wraps std::queue protected with a lock. Long term,
37
+ /// we need to avoid copying data. It has a lot of data copies currently.
38
+ template <typename T>
39
+ class TSQueue {
40
+ using Lock = std::lock_guard<std::mutex>;
41
+
42
+ /// The queue and its mutex.
43
+ mutable std::mutex qM;
44
+ std::queue<T> q;
45
+
46
+ /// A mutex to ensure that only one 'pop' operation is happening at a time. It
47
+ /// is critical that locks be obtained on this and `qM` same order in both pop
48
+ /// methods. This lock should be obtained first since one of the pop methods
49
+ /// must unlock `qM` then relock it.
50
+ std::mutex popM;
51
+
52
+ public:
53
+ /// Push onto the queue.
54
+ template <typename... E>
55
+ void push(E... t) {
56
+ Lock l(qM);
57
+ q.emplace(t...);
58
+ }
59
+
60
+ /// Pop something off the queue but return nullopt if the queue is empty. Why
61
+ /// doesn't std::queue have anything like this?
62
+ std::optional<T> pop() {
63
+ Lock pl(popM);
64
+ Lock ql(qM);
65
+ if (q.size() == 0)
66
+ return std::nullopt;
67
+ auto t = q.front();
68
+ q.pop();
69
+ return t;
70
+ }
71
+
72
+ /// Call the callback for the front of the queue (if anything is there). Only
73
+ /// pop it off the queue if the callback returns true.
74
+ void pop(std::function<bool(const T &)> callback) {
75
+ // Since we need to unlock the mutex to call the callback, the queue
76
+ // could be pushed on to and its memory layout could thusly change,
77
+ // invalidating the reference returned by `.front()`. The easy solution here
78
+ // is to copy the data. TODO: Avoid copying the data.
79
+ Lock pl(popM);
80
+ T t;
81
+ {
82
+ Lock l(qM);
83
+ if (q.size() == 0)
84
+ return;
85
+ t = q.front();
86
+ }
87
+ if (callback(t)) {
88
+ Lock l(qM);
89
+ q.pop();
90
+ }
91
+ }
92
+
93
+ /// Is the queue empty?
94
+ bool empty() const {
95
+ Lock l(qM);
96
+ return q.empty();
97
+ }
98
+ };
99
+ } // namespace utils
100
+ } // namespace esi
101
+
102
+ #endif // ESI_UTILS_H
@@ -0,0 +1,85 @@
1
+ //===- Cosim.h - ESI C++ cosimulation backend -------------------*- C++ -*-===//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+ //
9
+ // This is a specialization of the ESI C++ API (backend) for connection into a
10
+ // simulation of an ESI system. Currently uses Cap'nProto RPC, but that could
11
+ // change. Requires Cap'nProto C++ library.
12
+ //
13
+ // DO NOT EDIT!
14
+ // This file is distributed as part of an ESI package. The source for this file
15
+ // should always be modified within CIRCT (lib/dialect/ESI/runtime/cpp).
16
+ //
17
+ //===----------------------------------------------------------------------===//
18
+
19
+ // NOLINTNEXTLINE(llvm-header-guard)
20
+ #ifndef ESI_BACKENDS_COSIM_H
21
+ #define ESI_BACKENDS_COSIM_H
22
+
23
+ #include "esi/Accelerator.h"
24
+
25
+ #include <memory>
26
+ #include <set>
27
+
28
+ namespace esi {
29
+ namespace cosim {
30
+ class ChannelDesc;
31
+ }
32
+
33
+ namespace backends {
34
+ namespace cosim {
35
+ class CosimEngine;
36
+
37
+ /// Connect to an ESI simulation.
38
+ class CosimAccelerator : public esi::AcceleratorConnection {
39
+ friend class CosimEngine;
40
+
41
+ public:
42
+ CosimAccelerator(Context &, std::string hostname, uint16_t port);
43
+ ~CosimAccelerator();
44
+
45
+ static std::unique_ptr<AcceleratorConnection>
46
+ connect(Context &, std::string connectionString);
47
+
48
+ // Different ways to retrieve the manifest in Cosimulation.
49
+ enum ManifestMethod {
50
+ Cosim, // Use the backdoor cosim interface. Default.
51
+ MMIO, // Use MMIO emulation.
52
+ };
53
+ // Set the way this connection will retrieve the manifest.
54
+ void setManifestMethod(ManifestMethod method);
55
+
56
+ // C++ doesn't have a mechanism to forward declare a nested class and we don't
57
+ // want to include the generated header here. So we have to wrap it in a
58
+ // forward-declared struct we write ourselves.
59
+ struct StubContainer;
60
+
61
+ void createEngine(const std::string &engineTypeName, AppIDPath idPath,
62
+ const ServiceImplDetails &details,
63
+ const HWClientDetails &clients) override;
64
+
65
+ protected:
66
+ virtual Service *createService(Service::Type service, AppIDPath path,
67
+ std::string implName,
68
+ const ServiceImplDetails &details,
69
+ const HWClientDetails &clients) override;
70
+
71
+ private:
72
+ StubContainer *rpcClient;
73
+
74
+ // We own all channels connected to rpcClient since their lifetime is tied to
75
+ // rpcClient.
76
+ std::set<std::unique_ptr<ChannelPort>> channels;
77
+
78
+ ManifestMethod manifestMethod = Cosim;
79
+ };
80
+
81
+ } // namespace cosim
82
+ } // namespace backends
83
+ } // namespace esi
84
+
85
+ #endif // ESI_BACKENDS_COSIM_H
@@ -0,0 +1,55 @@
1
+ //===- RpcServer.h - Run a cosim server -------------------------*- C++ -*-===//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+ //
9
+ // Setup and run a server accepting connections via the 'cosim' RPC protocol.
10
+ // Then, one can request ports to and from the clients.
11
+ //
12
+ // Abstract this out to support multi-party communication in the future.
13
+ //
14
+ //===----------------------------------------------------------------------===//
15
+
16
+ #ifndef ESI_COSIM_RPCSERVER_H
17
+ #define ESI_COSIM_RPCSERVER_H
18
+
19
+ #include "esi/Ports.h"
20
+
21
+ namespace esi {
22
+ namespace cosim {
23
+
24
+ /// TODO: make this a proper backend (as much as possible).
25
+ class RpcServer {
26
+ public:
27
+ ~RpcServer();
28
+
29
+ /// Set the manifest and version. There is a race condition here in that the
30
+ /// RPC server can be started and a connection from the client could happen
31
+ /// before the manifest is set. TODO: rework the DPI API to require that the
32
+ /// manifest gets set first.
33
+ void setManifest(int esiVersion,
34
+ const std::vector<uint8_t> &compressedManifest);
35
+
36
+ /// Register a read or write port which communicates over RPC.
37
+ ReadChannelPort &registerReadPort(const std::string &name,
38
+ const std::string &type);
39
+ WriteChannelPort &registerWritePort(const std::string &name,
40
+ const std::string &type);
41
+
42
+ void stop();
43
+ void run(int port);
44
+
45
+ /// Hide the implementation details from this header file.
46
+ class Impl;
47
+
48
+ private:
49
+ Impl *impl = nullptr;
50
+ };
51
+
52
+ } // namespace cosim
53
+ } // namespace esi
54
+
55
+ #endif // ESI_COSIM_RPCSERVER_H
@@ -0,0 +1,87 @@
1
+ //===- Trace.h - ESI trace backend ------------------------------*- C++ -*-===//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+ //
9
+ // This is a specialization of the ESI C++ API (backend) for trace-based
10
+ // Accelerator interactions. This means that it will have the capability to read
11
+ // trace files recorded from interactions with an actual connection. It also has
12
+ // a mode wherein it will write to a file (for sends) and produce random data
13
+ // (for receives). Both modes are intended for debugging without a simulation.
14
+ //
15
+ // DO NOT EDIT!
16
+ // This file is distributed as part of an ESI package. The source for this file
17
+ // should always be modified within CIRCT (lib/dialect/ESI/runtime/cpp/).
18
+ //
19
+ //===----------------------------------------------------------------------===//
20
+
21
+ // NOLINTNEXTLINE(llvm-header-guard)
22
+ #ifndef ESI_BACKENDS_COSIM_H
23
+ #define ESI_BACKENDS_COSIM_H
24
+
25
+ #include "esi/Accelerator.h"
26
+
27
+ #include <filesystem>
28
+ #include <memory>
29
+
30
+ namespace esi {
31
+ namespace backends {
32
+ namespace trace {
33
+
34
+ /// Connect to an ESI simulation.
35
+ class TraceAccelerator : public esi::AcceleratorConnection {
36
+ public:
37
+ enum Mode {
38
+ // Write data sent to the accelerator to the trace file. Produce random
39
+ // garbage data for reads from the accelerator.
40
+ Write,
41
+
42
+ // Sent data to the accelerator is compared against the trace file's record.
43
+ // Data read from the accelerator is read from the trace file.
44
+ // TODO: Full trace mode not yet supported.
45
+ // Read
46
+
47
+ // Discard all data sent to the accelerator. Disable trace file generation.
48
+ Discard,
49
+ };
50
+
51
+ /// Create a trace-based accelerator backend.
52
+ /// \param mode The mode of operation. See Mode.
53
+ /// \param manifestJson The path to the manifest JSON file.
54
+ /// \param traceFile The path to the trace file. For 'Write' mode, this file
55
+ /// is opened for writing. For 'Read' mode, this file is opened for reading.
56
+ TraceAccelerator(Context &, Mode mode, std::filesystem::path manifestJson,
57
+ std::filesystem::path traceFile);
58
+ ~TraceAccelerator() override;
59
+
60
+ /// Parse the connection string and instantiate the accelerator. Format is:
61
+ /// "<mode>:<manifest path>[:<traceFile>]".
62
+ static std::unique_ptr<AcceleratorConnection>
63
+ connect(Context &, std::string connectionString);
64
+
65
+ /// Internal implementation.
66
+ struct Impl;
67
+ Impl &getImpl();
68
+
69
+ protected:
70
+ void createEngine(const std::string &engineTypeName, AppIDPath idPath,
71
+ const ServiceImplDetails &details,
72
+ const HWClientDetails &clients) override;
73
+
74
+ virtual Service *createService(Service::Type service, AppIDPath idPath,
75
+ std::string implName,
76
+ const ServiceImplDetails &details,
77
+ const HWClientDetails &clients) override;
78
+
79
+ private:
80
+ std::unique_ptr<Impl> impl;
81
+ };
82
+
83
+ } // namespace trace
84
+ } // namespace backends
85
+ } // namespace esi
86
+
87
+ #endif // ESI_BACKENDS_COSIM_H
Binary file
Binary file
Binary file
Binary file
esiaccel/lib/libz.so.1 ADDED
Binary file
Binary file