Skip to content

Commit f924215

Browse files
committed
Add comments for public functions and classes
ghstack-source-id: 050d4344c02534efc7c2b7ccb74f2682fb13fc29 Pull Request resolved: #222
1 parent 8cea05b commit f924215

11 files changed

+144
-14
lines changed

.gitignore

-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
.git/**
33
**/__pycache__/**
44
**.coverage
5-
.coverage
6-
multipy/runtime/interpreter/cpython
7-
multipy/runtime/interpreter/cpython/**
85
**/build/**
96
**/CMakeFiles/**
10-
multipy/runtime/interpreter/frozen/**
117
multipy/runtime/example/generated/
128
*.egg-info

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ cmake --build . --config Release
163163

164164
### Running unit tests for `multipy::runtime`
165165

166-
We first need to generate the neccessary examples. First make sure your python enviroment has [torch](https://pytorch.org). Afterwards, once `multipy::runtime` is built, run the following (executed automatically for `docker` and `pip` above):
166+
We first need to generate the neccessary examples. First make sure your python environment has [torch](https://pytorch.org). Afterwards, once `multipy::runtime` is built, run the following (executed automatically for `docker` and `pip` above):
167167

168168
```
169169
cd multipy/multipy/runtime

multipy/runtime/deploy.h

+83-8
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ struct TORCH_API InterpreterSession {
5757
// InterpreterSession* I)' instead. We will have no backwards compatibility
5858
// guarentees for this function.
5959
ReplicatedObj createMovable(Obj obj);
60+
61+
// Converts a `ReplicatedObj` to an `Obj` on this InterpreterSession.
6062
Obj fromMovable(const ReplicatedObj& obj);
6163

6264
protected:
@@ -73,6 +75,9 @@ struct TORCH_API InterpreterSession {
7375
std::function<void()> deconstruction_callback_ = nullptr;
7476
};
7577

78+
// An `Interpreter` represents an invidual subinterpreter created by
79+
// `torch::deploy`. It allows for the creation of `InterpreterSession` objects
80+
// which allow users to interact with python objects.
7681
class TORCH_API Interpreter {
7782
private:
7883
void* handle_;
@@ -84,17 +89,24 @@ class TORCH_API Interpreter {
8489
multipy::optional<EmbeddedFile> torchPluginFile_;
8590

8691
public:
92+
// Creates an Interpreter which is managed by `manager` and using the
93+
// environment `env`
8794
Interpreter(InterpreterManager* manager, std::shared_ptr<Environment> env);
95+
96+
// Creates an Interpreter manager using environment `env` which is not tied to
97+
// an Interpreter Manager.
8898
explicit Interpreter(std::shared_ptr<Environment> env)
8999
: Interpreter(nullptr, env) {}
90100

101+
// Gets a new `InterpreterSession` from this Interpreter.
91102
InterpreterSession acquireSession() const {
92103
if (manager_) {
93104
return InterpreterSession(pImpl_->acquireSession(), manager_);
94105
} else {
95106
return InterpreterSession(pImpl_->acquireSession());
96107
}
97108
}
109+
98110
~Interpreter();
99111
Interpreter(Interpreter&& rhs) noexcept
100112
: handle_(rhs.handle_),
@@ -113,17 +125,28 @@ class TORCH_API Interpreter {
113125

114126
struct Package;
115127

128+
// The default LoadBalancer for torch::deploy which handles allocating and
129+
// freeing subinterpreters.
116130
struct TORCH_API LoadBalancer {
131+
// Creates a Loadbalancer which handles `n` interpreters.
117132
explicit LoadBalancer(size_t n)
118133
: uses_(new uint64_t[8 * n]), allocated_(n), n_(n) {
119134
// 8*... to avoid false sharing of atomics on the same cache line
120135
memset(uses_.get(), 0, 8 * n_ * sizeof(uint64_t));
121136
}
137+
138+
// Changes the amount of subinterpreters which is handled by the load
139+
// balancer.
122140
void setResourceLimit(size_t n) {
123141
MULTIPY_INTERNAL_ASSERT(n <= allocated_);
124142
n_ = n;
125143
}
144+
145+
// Allocates an subinterpreter, and return its ID which is used to free it.
126146
int acquire();
147+
148+
// Frees the subinterpreter with ID `where`. This ID is returned by
149+
// `LoadBalancer::acquire()`
127150
void free(int where);
128151

129152
private:
@@ -134,13 +157,21 @@ struct TORCH_API LoadBalancer {
134157
size_t n_;
135158
};
136159

160+
// An `InterpreterManager` handles the interaction of multiple subinterpreters
161+
// such as allocating subinterpreters, or load balancing the subinterpreters.
137162
struct TORCH_API InterpreterManager {
163+
// constructor for `InterpreterManager` which takes the number of interpreters
164+
// (usually correlates to number of cores on your cpu), and a pointer to an
165+
// `Environment`. The default uses the local python env.
138166
explicit InterpreterManager(
139167
size_t nInterp = 2,
140168
std::shared_ptr<Environment> env = std::make_shared<NoopEnvironment>());
141169

142-
// get a free model, guarenteed that no other user of acquireOne has the same
143-
// model. It _is_ possible that other users will be using the interpreter.
170+
// get a free InterpreterSession, guarenteed that no other user of acquireOne
171+
// has the same InterpreterSession. It _is_ possible that other users will be
172+
// using the interpreter if there are no free InterpreterSessions. Unless you
173+
// are very careful to only use free interpreters, then do not assume that the
174+
// `Obj`s are isolated from each other.
144175
InterpreterSession acquireOne() {
145176
int where = resources_.acquire();
146177
InterpreterSession I = instances_[where].acquireSession();
@@ -154,11 +185,19 @@ struct TORCH_API InterpreterManager {
154185
at::ArrayRef<Interpreter> allInstances() {
155186
return instances_;
156187
}
188+
189+
// debugging tool to control the size of the loadBalancer
190+
// and change the number of interpreters on the fly
157191
void debugLimitInterpreters(size_t N) {
158192
AT_ASSERT(N <= instances_.size());
159193
resources_.setResourceLimit(N);
160194
}
195+
196+
// loads a package from a file with name `uri`
161197
Package loadPackage(const std::string& uri);
198+
199+
// loads a package from a `PyTorchStreamReader` or any class other which uses
200+
// `ReadAdapterInterface`
162201
Package loadPackage(
163202
std::shared_ptr<caffe2::serialize::ReadAdapterInterface> reader);
164203

@@ -171,10 +210,12 @@ struct TORCH_API InterpreterManager {
171210
registeredModuleSource_[std::move(name)] = std::move(src);
172211
}
173212

174-
// Util function for debugging.
213+
// Util function for debugging which outputs the number of registered modules.
175214
size_t countRegisteredModuleSources() {
176215
return registeredModuleSource_.size();
177216
}
217+
218+
// Converts `obj` from on `InterpreterSession` I into a `ReplicatedObj`.
178219
ReplicatedObj createMovable(Obj obj, InterpreterSession* I);
179220
InterpreterManager(const InterpreterManager&) = delete;
180221
InterpreterManager& operator=(const InterpreterManager&) = delete;
@@ -204,33 +245,58 @@ struct TORCH_API ReplicatedObjImpl {
204245
InterpreterManager* manager_;
205246
};
206247

248+
//ReplicatedObj represents a python object that can be used on multiple interpreters. Calling
249+
// methods on this will pick an arbitrary interpreter to run on, transfer it there if not already
250+
// and run the method. A replicated object can be converted to an interpreter specific `Obj` using
251+
// `InterpreterSession::fromMovable(ReplicatedObj)`
207252
struct TORCH_API ReplicatedObj {
253+
// Default constructor for `ReplicatedObj`
208254
ReplicatedObj() : pImpl_(nullptr) {}
255+
256+
// Creates an `InterpreterSession` using `onThisInterpreter`. If
257+
// `onThisInterpreter` is a `nullptr', then the associated
258+
// `InterpreterManager` allocates it.
209259
InterpreterSession acquireSession(
210260
const Interpreter* onThisInterpreter = nullptr) const;
211261
at::IValue operator()(at::ArrayRef<at::IValue> args) const {
212262
auto I = acquireSession();
213263
return I.self(args).toIValue();
214264
}
215265

266+
// Calls an `ReplicatedObj` callable, with arguments given by the tuple args
267+
// and named arguments given by the dictionary kwargs (equivalent to python's `__call__`). This is done on an
268+
// arbitrary `InterpreterSession` which belongs to the `ReplicatedObj`'s
269+
// manager.
216270
[[nodiscard]] at::IValue callKwargs(
217271
std::vector<at::IValue> args,
218272
std::unordered_map<std::string, c10::IValue> kwargs) const {
219273
auto I = acquireSession();
220274
return I.self.callKwargs(std::move(args), std::move(kwargs)).toIValue();
221275
}
222276

277+
// Calls an `ReplicatedObj` callable, with named arguments given by the
278+
// dictionary kwargs (equivalent to python's `__call__`). This is done on an arbitrary `InterpreterSession` which
279+
// belongs to the `ReplicatedObj`'s manager.
223280
[[nodiscard]] at::IValue callKwargs(
224281
std::unordered_map<std::string, c10::IValue> kwargs) const {
225282
auto I = acquireSession();
226283
return I.self.callKwargs(std::move(kwargs)).toIValue();
227284
}
228285

229-
[[nodiscard]] bool hasattr(const char* name) const {
286+
// Returns true if `ReplicatedObj` has attribute with name `attr` and false
287+
// otherwise. This is done on an arbitrary `InterpreterSession` which belongs
288+
// to the `ReplicatedObj`'s manager.
289+
[[nodiscard]] bool hasattr(const char* attr) const {
230290
auto I = acquireSession();
231-
return I.self.hasattr(name);
291+
return I.self.hasattr(attr);
232292
}
293+
294+
// Deletes `ReplicatedObj` from onThisInterpreter, if onThisInterpreter is
295+
// `nullptr`, unload is called on all interpreters belonging to the
296+
// ReplicatedObject's InterpreterManager
233297
void unload(const Interpreter* onThisInterpreter = nullptr);
298+
299+
// Converts `ReplicatedObj` to `Obj` on `InterpreterSession` `I`
234300
Obj toObj(InterpreterSession* I);
235301

236302
private:
@@ -242,21 +308,24 @@ struct TORCH_API ReplicatedObj {
242308
friend struct InterpreterManager;
243309
};
244310

311+
// PythonMethodWrapper is a more specific instance of a
312+
// ReplicatedObj which represents a python method, and
313+
// is therefore callable and has argument names accessible.
245314
class PythonMethodWrapper : public torch::IMethod {
246-
// PythonMethodWrapper is a more specific instance of a
247-
// ReplicatedObj which represents a python method, and
248-
// is therefore callable and has argument names accessible.
249315
public:
250316
// TODO(whc) make bound method pickleable, then directly construct from that
317+
251318
PythonMethodWrapper(
252319
torch::deploy::ReplicatedObj model,
253320
std::string methodName)
254321
: model_(std::move(model)), methodName_(std::move(methodName)) {}
255322

323+
// return the name of the python method.
256324
const std::string& name() const override {
257325
return methodName_;
258326
}
259327

328+
// overrides the `()` operater to call the underlying python method.
260329
c10::IValue operator()(
261330
std::vector<c10::IValue> args,
262331
const IValueMap& kwargs = IValueMap()) const override {
@@ -274,6 +343,8 @@ class PythonMethodWrapper : public torch::IMethod {
274343
std::string methodName_;
275344
};
276345

346+
// An object to encapsulate a `torch::package` which can act as part (or entire)
347+
// environment for subinterpreters.
277348
struct TORCH_API Package {
278349
// shorthand for getting the object as a pickle resource in the package
279350
ReplicatedObj loadPickle(const std::string& module, const std::string& file) {
@@ -308,12 +379,16 @@ struct TORCH_API Package {
308379
}
309380
#endif
310381

382+
// Allocates an `InterpreterSession` and load the appropriate torch.package
383+
// with it.
311384
InterpreterSession acquireSession() {
312385
auto I = manager_->acquireOne();
313386
I.self =
314387
I.impl_->createOrGetPackageImporterFromContainerFile(containerFile_);
315388
return I;
316389
}
390+
391+
// Converts an `Obj` from `InterpreterSession` `I` into a `ReplicatedObj`.
317392
ReplicatedObj createMovable(Obj obj, InterpreterSession* I) {
318393
return manager_->createMovable(obj, I);
319394
}

multipy/runtime/elf_file.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
namespace torch {
1717
namespace deploy {
1818

19+
// A representation of a section of an ElfFile.
1920
struct Section {
2021
Section() {}
2122
explicit Section(
@@ -35,13 +36,18 @@ struct Section {
3536
}
3637
};
3738

39+
// TODO: consolidate other ELF file related functions in loader.cpp to this file
40+
3841
/*
3942
* This class provie utilities to handle ELF file. Only support 64bit ELF file.
4043
*/
41-
// TODO: consolidate other ELF file related functions in loader.cpp to this file
4244
class ElfFile {
4345
public:
46+
// Constructs an Elffile with the corresponding `filename`
4447
explicit ElfFile(const char* filename);
48+
49+
// Finds and return a `Section` with the corresponding `name`. If nothing is
50+
// found, then a `multipy::nullopt` is returned.
4551
multipy::optional<Section> findSection(const char* name) const;
4652

4753
private:

multipy/runtime/embedded_file.h

+4
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@
1111
namespace torch {
1212
namespace deploy {
1313

14+
// Represents an ExeSection of an EmbeddedFile.
1415
struct ExeSection {
1516
const char* sectionName;
1617
bool customLoader;
1718
};
1819

20+
// These are symbols used by the subinterpreters.
1921
struct InterpreterSymbol {
2022
const char* startSym;
2123
const char* endSym;
2224
bool customLoader;
2325
};
2426

27+
// Represents an EmbeddedFile which is a file which contains a binary for a
28+
// subinterprerter.
2529
struct EmbeddedFile {
2630
std::string libraryName{""};
2731
bool customLoader{false};

multipy/runtime/environment.h

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Environment {
4242
fclose(zippedFile);
4343
return zipArchive;
4444
}
45+
4546
void setupZippedPythonModules(const std::string& pythonAppDir) {
4647
#ifdef FBCODE_CAFFE2
4748
extraPythonPaths_.push_back(getZippedArchive(
@@ -56,14 +57,19 @@ class Environment {
5657
}
5758

5859
public:
60+
// Environment constructor which creates a random temporary directory as
61+
// a directory for the zipped python modules.
5962
explicit Environment() {
6063
char tempDirName[] = "/tmp/torch_deploy_zipXXXXXX";
6164
char* tempDirectory = mkdtemp(tempDirName);
6265
setupZippedPythonModules(tempDirectory);
6366
}
67+
// Environment constructor which takes a file name for the
68+
// directory for the zipped python modules.
6469
explicit Environment(const std::string& pythonAppDir) {
6570
setupZippedPythonModules(pythonAppDir);
6671
}
72+
// Deconstructor for Environment.
6773
virtual ~Environment() {
6874
auto rmCmd = "rm -rf " + extraPythonLibrariesDir_;
6975
(void)system(rmCmd.c_str());

0 commit comments

Comments
 (0)