Skip to content

Commit 277424c

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

10 files changed

+121
-10
lines changed

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

+69-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 `torch::deploy`.
79+
// It allows for the creation of `InterpreterSession` objects which allow users to interact with
80+
// python objects.
7681
class TORCH_API Interpreter {
7782
private:
7883
void* handle_;
@@ -84,17 +89,22 @@ class TORCH_API Interpreter {
8489
multipy::optional<EmbeddedFile> torchPluginFile_;
8590

8691
public:
92+
// Creates an Interpreter which is managed by `manager` and using the environment `env`
8793
Interpreter(InterpreterManager* manager, std::shared_ptr<Environment> env);
94+
95+
// Creates an Interpreter manager using environment `env` which is not tied to an Interpreter Manager.
8896
explicit Interpreter(std::shared_ptr<Environment> env)
8997
: Interpreter(nullptr, env) {}
9098

99+
// Gets a new `InterpreterSession` from this Interpreter.
91100
InterpreterSession acquireSession() const {
92101
if (manager_) {
93102
return InterpreterSession(pImpl_->acquireSession(), manager_);
94103
} else {
95104
return InterpreterSession(pImpl_->acquireSession());
96105
}
97106
}
107+
98108
~Interpreter();
99109
Interpreter(Interpreter&& rhs) noexcept
100110
: handle_(rhs.handle_),
@@ -113,17 +123,26 @@ class TORCH_API Interpreter {
113123

114124
struct Package;
115125

126+
// The default LoadBalancer for torch::deploy which handles allocating and freeing subinterpreters.
116127
struct TORCH_API LoadBalancer {
128+
129+
// Creates a Loadbalancer which handles `n` interpreters.
117130
explicit LoadBalancer(size_t n)
118131
: uses_(new uint64_t[8 * n]), allocated_(n), n_(n) {
119132
// 8*... to avoid false sharing of atomics on the same cache line
120133
memset(uses_.get(), 0, 8 * n_ * sizeof(uint64_t));
121134
}
135+
136+
// Changes the amount of subinterpreters which is handled by the load balancer.
122137
void setResourceLimit(size_t n) {
123138
MULTIPY_INTERNAL_ASSERT(n <= allocated_);
124139
n_ = n;
125140
}
141+
142+
// Allocates an subinterpreter, and return its ID which is used to free it.
126143
int acquire();
144+
145+
// Frees the subinterpreter with ID `where`. This ID is returned by `LoadBalancer::acquire()`
127146
void free(int where);
128147

129148
private:
@@ -134,13 +153,21 @@ struct TORCH_API LoadBalancer {
134153
size_t n_;
135154
};
136155

156+
// An `InterpreterManager` handles the interaction of multiple subinterpreters such as allocating
157+
// subinterpreters, or load balancing the subinterpreters.
137158
struct TORCH_API InterpreterManager {
159+
160+
// constructor for `InterpreterManager` which takes the number of interpreters
161+
// (usually correlates to number of cores on your cpu), and a pointer to an `Environment`.
162+
// The defualt uses the local python env.
138163
explicit InterpreterManager(
139164
size_t nInterp = 2,
140165
std::shared_ptr<Environment> env = std::make_shared<NoopEnvironment>());
141166

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.
167+
// get a free InterpreterSession, guarenteed that no other user of acquireOne has the same
168+
// InterpreterSession. It _is_ possible that other users will be using the interpreter if there are
169+
// no free InterpreterSessions. Unless you are very careful to only use free interpreters, then do not assume
170+
// that the `Obj`s are isolated from each other.
144171
InterpreterSession acquireOne() {
145172
int where = resources_.acquire();
146173
InterpreterSession I = instances_[where].acquireSession();
@@ -154,11 +181,18 @@ struct TORCH_API InterpreterManager {
154181
at::ArrayRef<Interpreter> allInstances() {
155182
return instances_;
156183
}
184+
185+
// debugging tool to control the size of the loadBalancer
186+
// and change the number of interpreters on the fly
157187
void debugLimitInterpreters(size_t N) {
158188
AT_ASSERT(N <= instances_.size());
159189
resources_.setResourceLimit(N);
160190
}
191+
192+
// loads a package from a file with name `uri`
161193
Package loadPackage(const std::string& uri);
194+
195+
// loads a package from a `PyTorchStreamReader` or any class other which uses `ReadAdapterInterface`
162196
Package loadPackage(
163197
std::shared_ptr<caffe2::serialize::ReadAdapterInterface> reader);
164198

@@ -171,10 +205,12 @@ struct TORCH_API InterpreterManager {
171205
registeredModuleSource_[std::move(name)] = std::move(src);
172206
}
173207

174-
// Util function for debugging.
208+
// Util function for debugging which outputs the number of registered modules.
175209
size_t countRegisteredModuleSources() {
176210
return registeredModuleSource_.size();
177211
}
212+
213+
// Converts `obj` from on `InterpreterSession` I into a `ReplicatedObj`.
178214
ReplicatedObj createMovable(Obj obj, InterpreterSession* I);
179215
InterpreterManager(const InterpreterManager&) = delete;
180216
InterpreterManager& operator=(const InterpreterManager&) = delete;
@@ -204,33 +240,51 @@ struct TORCH_API ReplicatedObjImpl {
204240
InterpreterManager* manager_;
205241
};
206242

243+
// A python object which is Replicated from an `Obj` such that it is able to move around to different `InterpreterSessions`
244+
// by using `InterpreterSession::fromMovable(ReplicatedObj)`
207245
struct TORCH_API ReplicatedObj {
246+
247+
// Default constructor for `ReplicatedObj`
208248
ReplicatedObj() : pImpl_(nullptr) {}
249+
250+
// Creates an `InterpreterSession` using `onThisInterpreter`. If `onThisInterpreter` is
251+
// a `nullptr', then the associated `InterpreterManager` allocates it.
209252
InterpreterSession acquireSession(
210253
const Interpreter* onThisInterpreter = nullptr) const;
211254
at::IValue operator()(at::ArrayRef<at::IValue> args) const {
212255
auto I = acquireSession();
213256
return I.self(args).toIValue();
214257
}
215258

259+
// Calls an `ReplicatedObj` callable, with arguments given by the tuple args and named arguments given by the dictionary
260+
// kwargs. This is done on an arbitrary `InterpreterSession` which belongs to the `ReplicatedObj`'s manager.
216261
[[nodiscard]] at::IValue callKwargs(
217262
std::vector<at::IValue> args,
218263
std::unordered_map<std::string, c10::IValue> kwargs) const {
219264
auto I = acquireSession();
220265
return I.self.callKwargs(std::move(args), std::move(kwargs)).toIValue();
221266
}
222267

268+
// Calls an `ReplicatedObj` callable, with named arguments given by the dictionary kwargs.
269+
// This is done on an arbitrary `InterpreterSession` which belongs to the `ReplicatedObj`'s manager.
223270
[[nodiscard]] at::IValue callKwargs(
224271
std::unordered_map<std::string, c10::IValue> kwargs) const {
225272
auto I = acquireSession();
226273
return I.self.callKwargs(std::move(kwargs)).toIValue();
227274
}
228275

229-
[[nodiscard]] bool hasattr(const char* name) const {
276+
// Returns true if `ReplicatedObj` has attribute with name `attr` and false otherwise.
277+
// This is done on an arbitrary `InterpreterSession` which belongs to the `ReplicatedObj`'s manager.
278+
[[nodiscard]] bool hasattr(const char* attr) const {
230279
auto I = acquireSession();
231-
return I.self.hasattr(name);
280+
return I.self.hasattr(attr);
232281
}
282+
283+
// Deletes `ReplicatedObj` from onThisInterpreter, if onThisInterpreter is `nullptr`,
284+
// unload is called on all interpreters belonging to the ReplicatedObject's InterpreterManager
233285
void unload(const Interpreter* onThisInterpreter = nullptr);
286+
287+
// Converts `ReplicatedObj` to `Obj` on `InterpreterSession` `I`
234288
Obj toObj(InterpreterSession* I);
235289

236290
private:
@@ -242,21 +296,24 @@ struct TORCH_API ReplicatedObj {
242296
friend struct InterpreterManager;
243297
};
244298

299+
// PythonMethodWrapper is a more specific instance of a
300+
// ReplicatedObj which represents a python method, and
301+
// is therefore callable and has argument names accessible.
245302
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.
249303
public:
250304
// TODO(whc) make bound method pickleable, then directly construct from that
305+
251306
PythonMethodWrapper(
252307
torch::deploy::ReplicatedObj model,
253308
std::string methodName)
254309
: model_(std::move(model)), methodName_(std::move(methodName)) {}
255310

311+
// return the name of the python method.
256312
const std::string& name() const override {
257313
return methodName_;
258314
}
259315

316+
// overrides the `()` operater to call the underlying python method.
260317
c10::IValue operator()(
261318
std::vector<c10::IValue> args,
262319
const IValueMap& kwargs = IValueMap()) const override {
@@ -274,6 +331,7 @@ class PythonMethodWrapper : public torch::IMethod {
274331
std::string methodName_;
275332
};
276333

334+
// An object to encapsulate a `torch::package` which can act as part (or entire) environment for subinterpreters.
277335
struct TORCH_API Package {
278336
// shorthand for getting the object as a pickle resource in the package
279337
ReplicatedObj loadPickle(const std::string& module, const std::string& file) {
@@ -308,12 +366,15 @@ struct TORCH_API Package {
308366
}
309367
#endif
310368

369+
// Allocates an `InterpreterSession` and load the appropriate torch.package with it.
311370
InterpreterSession acquireSession() {
312371
auto I = manager_->acquireOne();
313372
I.self =
314373
I.impl_->createOrGetPackageImporterFromContainerFile(containerFile_);
315374
return I;
316375
}
376+
377+
// Converts an `Obj` from `InterpreterSession` `I` into a `ReplicatedObj`.
317378
ReplicatedObj createMovable(Obj obj, InterpreterSession* I) {
318379
return manager_->createMovable(obj, I);
319380
}

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+
47+
// Constructs an Elffile with the corresponding `filename`
4448
explicit ElfFile(const char* filename);
49+
50+
// Finds and return a `Section` with the corresponding `name`. If nothing is found, then a `multipy::nullopt` is returned.
4551
multipy::optional<Section> findSection(const char* name) const;
4652

4753
private:

multipy/runtime/embedded_file.h

+3
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@
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 subinterprerter.
2528
struct EmbeddedFile {
2629
std::string libraryName{""};
2730
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());

multipy/runtime/interpreter/interpreter_impl.h

+14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace deploy {
1919
struct InterpreterSessionImpl;
2020
struct Obj;
2121

22+
// Representation a Pickled Object
2223
struct PickledObject {
2324
std::string data_;
2425
std::vector<at::Storage> storages_;
@@ -28,6 +29,7 @@ struct PickledObject {
2829
std::shared_ptr<caffe2::serialize::PyTorchStreamReader> containerFile_;
2930
};
3031

32+
// The underlying implementation of `Obj` which holds the underlying `py::object`.
3133
struct InterpreterObj {
3234
friend struct Obj;
3335
friend struct ReplicatedObjImpl;
@@ -72,21 +74,32 @@ struct Obj {
7274
: isDefault_(false), baseObj_(baseObj) {}
7375
Obj() : isDefault_(true), baseObj_(nullptr) {}
7476

77+
// return `IValue` representation.
7578
at::IValue toIValue() const;
79+
80+
// Call an `Obj` callable, with arguments given by the tuple args.
7681
Obj operator()(at::ArrayRef<Obj> args);
82+
83+
// Call an `Obj` callable, with arguments given by the tuple args.
7784
Obj operator()(at::ArrayRef<at::IValue> args);
85+
86+
// Call an `Obj` callable, with arguments given by the tuple args, and named arguments given by the dictionary kwargs.
7887
Obj callKwargs(
7988
std::vector<at::IValue> args,
8089
std::unordered_map<std::string, c10::IValue> kwargs);
90+
// Call an `Obj` callable, with named arguments given by the dictionary kwargs.
8191
Obj callKwargs(std::unordered_map<std::string, c10::IValue> kwargs);
92+
// Returns true if `Obj` has attribute with name `attr` and false otherwise.
8293
bool hasattr(const char* attr);
94+
// Returns attribute `attr` from `Obj`. This is equivalent to calling `getattr(Obj, attr)` in python.
8395
Obj attr(const char* attr);
8496

8597
private:
8698
bool isDefault_;
8799
std::shared_ptr<InterpreterObj> baseObj_;
88100
};
89101

102+
// The underlying implementation of `InterpreterSession`
90103
struct InterpreterSessionImpl {
91104
friend struct Package;
92105
friend struct ReplicatedObj;
@@ -132,6 +145,7 @@ struct InterpreterSessionImpl {
132145
}
133146
};
134147

148+
// The underlying implementation of `Interpreter`
135149
struct InterpreterImpl {
136150
virtual InterpreterSessionImpl* acquireSession() = 0;
137151
virtual void setFindModule(

0 commit comments

Comments
 (0)