Skip to content
This repository was archived by the owner on Apr 28, 2023. It is now read-only.

Commit 795b595

Browse files
Drop implicit Tuner and OptionsCache interaction
This PR removes the implicit load and store of OptionsCache during tuning. Now tuning requires explicitly loading the content of the cache and using it as a base mapping in order to perform reinforcement tuning. Tuning also stops storing to file automatically. As a consequence we expose the OptionsCache shared_ptr object in the Tuner as well as 2 convenience functions (loadTopKFromCache and storeTopKToCache). We also drop the makeCacheFilename function which ends up being more confusing than anything else. We explicitly append ".options" in tc.cc for legacy reasons but this will go away in the new bindings. Lastly, since a few python userland tests are relying on this implicit behavior we temporarily disable them. They will be reactivated once the new bindings land.
1 parent 964a438 commit 795b595

24 files changed

+180
-257
lines changed

tc/aten/aten_autotuner-inl.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ std::vector<typename Backend::MappingOptionsType>
5252
ATenAutotuner<Backend, Search>::tune(
5353
const std::string& tcName,
5454
const std::vector<at::Tensor>& inputs,
55-
const typename Backend::MappingOptionsType& baseMapping,
56-
const std::string& cacheFileName,
55+
const std::vector<typename Backend::MappingOptionsType>& baseMappings,
5756
const tc::autotune::TuningParameterFixer& fixedParams) {
5857
// TODO: some checks that inputs memory lives on the proper Backend device
5958

@@ -91,8 +90,7 @@ ATenAutotuner<Backend, Search>::tune(
9190
tcName,
9291
rawInputsPerDevice,
9392
rawOutputsPerDevice,
94-
baseMapping,
95-
cacheFileName,
93+
baseMappings,
9694
fixedParams);
9795
}
9896
} // namespace aten

tc/aten/aten_autotuner.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ class ATenAutotuner : public tc::autotune::Autotuner<Backend, SearchStrategy> {
7979
std::vector<MappingOptionsType> tune(
8080
const std::string& tcEntryPoint,
8181
const std::vector<at::Tensor>& inputs,
82-
const MappingOptionsType& baseMapping,
83-
const std::string& cacheFileName = "",
82+
const std::vector<MappingOptionsType>& baseMappings,
8483
const tc::autotune::TuningParameterFixer& fixedParams = {});
8584

8685
protected:

tc/autotuner/autotuner-inl.h

Lines changed: 8 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -321,45 +321,6 @@ namespace {
321321
volatile std::sig_atomic_t sigint_ = 0;
322322
volatile std::sig_atomic_t sigterm_ = 0;
323323

324-
template <typename Backend>
325-
std::vector<typename Backend::MappingOptionsType> loadThroughCache(
326-
lang::TreeRef tree,
327-
std::shared_ptr<OptionsCache<Backend>> optionsCache,
328-
const std::string& cacheFileName,
329-
const std::vector<const DLConstTensor*>& inputs,
330-
const size_t numCandidates) {
331-
LOG_IF(INFO, FLAGS_debug_tuner)
332-
<< "Loading proto from: " << tc::makeOptionsFilename(cacheFileName)
333-
<< std::endl;
334-
if (!cacheFileName.empty()) {
335-
optionsCache->loadCacheFromFile(tc::makeOptionsFilename(cacheFileName));
336-
}
337-
auto outputs = tc::detail::inferOutputTensorInfo(tree, inputs);
338-
return optionsCache->getTopKOptions(
339-
canonicalTc(tree),
340-
makeTensorInfoVector(inputs),
341-
outputs,
342-
Backend::backendString(),
343-
numCandidates);
344-
}
345-
346-
template <typename Backend>
347-
void storeTopKInCache(
348-
const std::shared_ptr<OptionsCache<Backend>>& optionsCache,
349-
const std::string& cacheFilename) {
350-
if (cacheFilename.empty()) {
351-
LOG_IF(INFO, FLAGS_debug_tuner)
352-
<< "No filepath provided, not saving cache" << std::endl;
353-
} else {
354-
LOG_IF(INFO, FLAGS_debug_tuner)
355-
<< "Dumping cache to " << tc::makeOptionsFilename(cacheFilename)
356-
<< std::endl;
357-
OptionsCache<Backend> cache(*optionsCache);
358-
cache.pruneKeepTopK(tc::FLAGS_tuner_save_best_candidates_count);
359-
cache.storeCacheToFile(tc::makeOptionsFilename(cacheFilename));
360-
}
361-
}
362-
363324
void removeDuplicates(std::vector<size_t>& v) {
364325
std::sort(v.begin(), v.end());
365326
v.erase(std::unique(v.begin(), v.end()), v.end());
@@ -416,7 +377,7 @@ void setupTuningParameters(
416377

417378
template <typename Backend, typename SearchStrategy>
418379
Autotuner<Backend, SearchStrategy>::Autotuner()
419-
: optionsCache_(new OptionsCache<Backend>()) {}
380+
: optionsCache(new OptionsCache<Backend>()) {}
420381

421382
template <typename Backend, typename SearchStrategy>
422383
std::vector<typename Backend::MappingOptionsType>
@@ -425,8 +386,7 @@ Autotuner<Backend, SearchStrategy>::tune(
425386
const std::string& tcEntryPoint,
426387
const std::unordered_map<size_t, std::vector<const DLConstTensor*>>& inputs,
427388
std::unordered_map<size_t, std::vector<const DLTensor*>>& outputs,
428-
const typename Backend::MappingOptionsType& baseMapping,
429-
const std::string& cacheFileName,
389+
const std::vector<typename Backend::MappingOptionsType>& baseMappings,
430390
const TuningParameterFixer& fixedParams) {
431391
std::map<std::string, lang::TreeRef> tcEntryPointMap(tc::detail::parse(tc));
432392
TC_CHECK_EQ(tcEntryPointMap.count(tcEntryPoint), 1u)
@@ -438,28 +398,13 @@ Autotuner<Backend, SearchStrategy>::tune(
438398
setupTuningParameters(inputs.begin()->second, modelConfiguration);
439399
modelConfiguration.fixParameters(fixedParams);
440400

441-
// Build starting points from baseMapping + whatever we recover from cache
442-
std::vector<typename Backend::MappingOptionsType> startingPoints{baseMapping};
443-
auto restoredCandidates = loadThroughCache<Backend>(
444-
tcEntryPointMap.at(tcEntryPoint),
445-
optionsCache_,
446-
cacheFileName,
447-
inputs.begin()->second,
448-
FLAGS_tuner_gen_restore_number);
449-
if (restoredCandidates.size() > 0) {
450-
startingPoints.reserve(1 + restoredCandidates.size());
451-
std::move(
452-
restoredCandidates.begin(),
453-
restoredCandidates.end(),
454-
std::back_inserter(startingPoints));
455-
}
456-
457401
// Create initial configs based on options + model configuration
402+
const std::vector<typename Backend::MappingOptionsType> options{baseMappings};
458403
std::vector<TuningConfiguration> configs;
459-
configs.reserve(startingPoints.size());
404+
configs.reserve(options.size());
460405
std::transform(
461-
startingPoints.begin(),
462-
startingPoints.end(),
406+
options.begin(),
407+
options.end(),
463408
std::back_inserter(configs),
464409
[this, &fixedParams, &modelConfiguration](
465410
const typename Backend::MappingOptionsType& options) {
@@ -484,9 +429,9 @@ Autotuner<Backend, SearchStrategy>::tune(
484429
tcEntryPointMap.at(tcEntryPoint),
485430
inputs,
486431
outputs,
487-
baseMapping,
432+
options[0],
488433
fixedParams,
489-
optionsCache_);
434+
optionsCache);
490435

491436
// Setup handlers
492437
sigterm_ = 0;
@@ -505,10 +450,6 @@ Autotuner<Backend, SearchStrategy>::tune(
505450
try {
506451
tuningHarness.run(searchStrategy);
507452
} catch (const std::exception& e) {
508-
std::cerr << "Exception during autotuning: " << e.what()
509-
<< "\n dumping cache to "
510-
<< tc::makeOptionsFilename(cacheFileName) << std::endl;
511-
storeTopKInCache<Backend>(optionsCache_, cacheFileName);
512453
tuningHarnessThreadEx = std::current_exception();
513454
}
514455
tuningHarnessFinished = true;
@@ -517,11 +458,9 @@ Autotuner<Backend, SearchStrategy>::tune(
517458
std::this_thread::sleep_for(std::chrono::milliseconds(100));
518459
if (sigint_) {
519460
tuningHarness.stopAfterCurrentIteration();
520-
storeTopKInCache<Backend>(optionsCache_, cacheFileName);
521461
}
522462
if (sigterm_) {
523463
std::cerr << "Autotuning aborted." << std::endl;
524-
storeTopKInCache<Backend>(optionsCache_, cacheFileName);
525464
std::abort();
526465
}
527466
}
@@ -532,8 +471,6 @@ Autotuner<Backend, SearchStrategy>::tune(
532471
std::rethrow_exception(tuningHarnessThreadEx);
533472
}
534473

535-
storeTopKInCache<Backend>(optionsCache_, cacheFileName);
536-
537474
return {tuningHarness.bestMappingOptions()};
538475
}
539476
} // namespace autotune

tc/autotuner/autotuner.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,14 @@ class Autotuner {
164164
const std::unordered_map<size_t, std::vector<const DLConstTensor*>>&
165165
inputs,
166166
std::unordered_map<size_t, std::vector<const DLTensor*>>& outputs,
167-
const MappingOptionsType& baseMapping,
168-
const std::string& cacheFileName = "",
167+
const std::vector<MappingOptionsType>& baseMapping,
169168
const TuningParameterFixer& fixedParams = TuningParameterFixer());
170169

171-
private:
172-
std::shared_ptr<OptionsCache<Backend>> optionsCache_;
170+
public:
171+
/// This is accessed by multiple threads in the tuning harness.
172+
/// Even though manipulations are threadsafe, you want to be sure tuning
173+
/// has finished before accessing the optionsCache.
174+
std::shared_ptr<OptionsCache<Backend>> optionsCache;
173175
};
174176

175177
/// Helper functions that need specializing for various backends.

tc/autotuner/options_cache-inl.h

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <llvm/ADT/Optional.h>
2828

2929
#include "tc/core/check.h"
30+
#include "tc/core/compiler.h"
3031
#include "tc/core/tensor.h"
3132
#include "tc/core/utils/math.h"
3233
#include "tc/core/utils/time.h"
@@ -163,12 +164,10 @@ void OptionsCache<Backend>::storeCacheToFile(
163164
std::lock_guard<std::mutex> lock(mutex);
164165
std::fstream serialized(
165166
filename, std::ios::binary | std::ios::trunc | std::ios::out);
166-
if (!serialized.is_open()) {
167-
LOG(ERROR) << "Failed to open the output stream for dumping protobuf: "
168-
<< filename;
169-
} else {
170-
proto.SerializePartialToOstream(&serialized);
171-
}
167+
TC_CHECK(serialized.is_open(), std::invalid_argument)
168+
<< "Failed to open the output stream for dumping protobuf: "
169+
<< filename;
170+
proto.SerializePartialToOstream(&serialized);
172171
}
173172
}
174173

@@ -317,9 +316,37 @@ void OptionsCache<Backend>::fromProtobuf(
317316
}
318317
}
319318

320-
} // namespace autotune
319+
template <typename Backend>
320+
std::vector<typename Backend::MappingOptionsType> loadTopKFromCacheFile(
321+
const std::string& tc,
322+
const std::string& entryPoint,
323+
const std::string& cacheFilename,
324+
const std::vector<const DLConstTensor*>& inputs,
325+
size_t count) {
326+
OptionsCache<Backend> optionsCache;
327+
optionsCache.loadCacheFromFile(cacheFilename);
328+
auto outputs = tc::inferOutputTensorInfo(tc, entryPoint, inputs);
329+
return optionsCache.getTopKOptions(
330+
lang::canonicalTc(tc::detail::parse(tc).at(entryPoint)),
331+
tc::makeTensorInfoVector(inputs),
332+
outputs,
333+
Backend::backendString(),
334+
count);
335+
}
321336

322-
inline std::string makeOptionsFilename(const std::string& fn) {
323-
return fn + ".options";
337+
template <typename Backend>
338+
void appendTopKToCacheFile(
339+
const std::shared_ptr<OptionsCache<Backend>>& cache,
340+
const std::string& cacheFilename,
341+
uint32_t count) {
342+
OptionsCache<Backend> copy(*cache);
343+
copy.pruneKeepTopK(count);
344+
auto proto = copy.toProtobuf();
345+
OptionsCache<Backend> optionsCache;
346+
optionsCache.loadCacheFromFile(cacheFilename);
347+
optionsCache.fromProtobuf(proto);
348+
optionsCache.storeCacheToFile(cacheFilename);
324349
}
350+
351+
} // namespace autotune
325352
} // namespace tc

tc/autotuner/options_cache.h

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ struct OptionsCache {
140140
const std::string& backendStr,
141141
size_t K) const;
142142

143-
/// Drops the (N - K) worst performing options
143+
/// Drops the (N - K) worst performing options for each key in the cache.
144+
/// That is, for each unique tuple(
145+
/// CanonicalTcString, input TensorInfo, output TensorInfo, backend string)
146+
/// this function keeps the best K.
144147
void pruneKeepTopK(size_t K);
145148

146149
protected:
@@ -162,10 +165,45 @@ struct OptionsCache {
162165
OptionsCacheValue<Backend>,
163166
OptionsCacheKeyHash>
164167
store_;
168+
169+
template <typename BackendType>
170+
friend void appendTopKToCacheFile(
171+
const std::shared_ptr<OptionsCache<BackendType>>& cache,
172+
const std::string& cacheFilename,
173+
uint32_t count);
165174
};
166-
} // namespace autotune
167175

168-
std::string makeOptionsFilename(const std::string& fn);
176+
/// Loads at most `count' bets entries from the file `cacheFilename', for the
177+
/// TC definition corresponding to the entryPoint.
178+
///
179+
/// Note that the file manipulation is threadsafe but not IPC-safe.
180+
/// TODO: implement using a filesystem lock (e.g. flock) if more safety is
181+
/// needed.
182+
template <typename Backend>
183+
std::vector<typename Backend::MappingOptionsType> loadTopKFromCacheFile(
184+
const std::string& tc,
185+
const std::string& entryPoint,
186+
const std::string& cacheFilename,
187+
const std::vector<const DLConstTensor*>& inputs,
188+
size_t count);
189+
190+
/// Stores at most `count' best entries from the cache into the file
191+
/// `cacheFilename', if that filename can be written to; otherwise throws.
192+
/// To avoid spuriously overwriting previous results, this ***appends*** the
193+
/// at most `count' best entries from cache to the cache loaded from
194+
/// cacheFilename. If the file is empty or does not exist then this function
195+
/// just writes instead of appending.
196+
///
197+
/// Note that the file manipulation is threadsafe but not IPC-safe.
198+
/// TODO: implement using a filesystem lock (e.g. flock) if more safety is
199+
/// needed.
200+
template <typename Backend>
201+
void appendTopKToCacheFile(
202+
const std::shared_ptr<OptionsCache<Backend>>& cache,
203+
const std::string& cacheFilename,
204+
uint32_t count);
205+
206+
} // namespace autotune
169207
} // namespace tc
170208

171209
#include "tc/autotuner/options_cache-inl.h"

tc/benchmarks/MLP_model.cc

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,7 @@ def _1LUT(float(E1, D) LUT1, int32(B, L1) I1) -> (O1) {
257257
std::to_string(FLAGS_E1);
258258
std::vector<tc::CudaMappingOptions> bestOptions{options};
259259
if (FLAGS_autotune) {
260-
bestOptions = autotune(
261-
FLAGS_save_tuner_proto_prefix + std::string("/1LUT_cache") + suffix,
262-
FLAGS_save_tuner_proto_prefix + std::string("/1LUT_best") + suffix,
263-
tc,
264-
"_1LUT",
265-
inputs,
266-
options,
267-
check_fun);
260+
bestOptions = autotune(tc, "_1LUT", inputs, options, check_fun);
268261
TC_CHECK_GE(bestOptions.size(), 1u);
269262
}
270263
Check(tc, "_1LUT", options, inputs, check_fun);
@@ -375,14 +368,7 @@ def _2LUT(float(E1, D) LUT1, int32(B, L1) I1, float(E2, D) LUT2, int32(B, L2) I2
375368
std::to_string(FLAGS_E2);
376369
std::vector<tc::CudaMappingOptions> bestOptions{options};
377370
if (FLAGS_autotune) {
378-
bestOptions = autotune(
379-
FLAGS_save_tuner_proto_prefix + std::string("/2LUT_cache") + suffix,
380-
FLAGS_save_tuner_proto_prefix + std::string("/2LUT_best") + suffix,
381-
tc,
382-
"_2LUT",
383-
inputs,
384-
options,
385-
check_fun);
371+
bestOptions = autotune(tc, "_2LUT", inputs, options, check_fun);
386372
TC_CHECK_GE(bestOptions.size(), 1u);
387373
}
388374
Check(tc, "_2LUT", bestOptions[0], inputs, check_fun);
@@ -444,14 +430,7 @@ def _C3(float(B,WX) I, float(WY, WX) W) -> (C3) {
444430
std::to_string(FLAGS_WY);
445431
std::vector<tc::CudaMappingOptions> bestOptions{options};
446432
if (FLAGS_autotune) {
447-
bestOptions = autotune(
448-
FLAGS_save_tuner_proto_prefix + std::string("/_C3_cache") + suffix,
449-
FLAGS_save_tuner_proto_prefix + std::string("/_C3_best") + suffix,
450-
tc,
451-
"_C3",
452-
inputs,
453-
options,
454-
check_fun);
433+
bestOptions = autotune(tc, "_C3", inputs, options, check_fun);
455434
TC_CHECK_GE(bestOptions.size(), 1u);
456435
}
457436
Check(tc, "_C3", bestOptions[0], inputs, check_fun);
@@ -509,14 +488,7 @@ def mlp1(float(B,M) I, float(M, N) W1, float(N) B1) -> (O1) {
509488
std::to_string(FLAGS_N);
510489
std::vector<tc::CudaMappingOptions> bestOptions{options};
511490
if (FLAGS_autotune) {
512-
bestOptions = autotune(
513-
FLAGS_save_tuner_proto_prefix + std::string("/mlp1_cache") + suffix,
514-
FLAGS_save_tuner_proto_prefix + std::string("/mlp1_best") + suffix,
515-
tc,
516-
"mlp1",
517-
inputs,
518-
options,
519-
check_fun);
491+
bestOptions = autotune(tc, "mlp1", inputs, options, check_fun);
520492
TC_CHECK_GE(bestOptions.size(), 1u);
521493
}
522494
Check(tc, "mlp1", bestOptions[0], inputs, check_fun);
@@ -592,14 +564,7 @@ def mlp3(float(B,N) I, float(O,N) W2, float(O) B2, float(P,O) W3, float(P) B3,
592564
std::to_string(FLAGS_N);
593565
std::vector<tc::CudaMappingOptions> bestOptions{options};
594566
if (FLAGS_autotune) {
595-
bestOptions = autotune(
596-
FLAGS_save_tuner_proto_prefix + std::string("/mlp3_cache") + suffix,
597-
FLAGS_save_tuner_proto_prefix + std::string("/mlp3_best") + suffix,
598-
tc,
599-
"mlp3",
600-
inputs,
601-
options,
602-
check_fun);
567+
bestOptions = autotune(tc, "mlp3", inputs, options, check_fun);
603568
TC_CHECK_GE(bestOptions.size(), 1u);
604569
}
605570
Check(tc, "mlp3", bestOptions[0], inputs, check_fun);

0 commit comments

Comments
 (0)