blob: f6b023f845c2a555c485c993232d35f89ba43834 [file] [log] [blame]
#include <gtest/gtest.h>
#include <c10/util/Exception.h>
#include <torch/csrc/lazy/core/cache.h>
#include <torch/csrc/lazy/core/hash.h>
#include <torch/csrc/lazy/core/ir.h>
#include <torch/csrc/lazy/core/shape.h>
#include <torch/csrc/lazy/ts_backend/ts_node.h>
namespace torch {
namespace lazy {
class CacheNode : public Node {
public:
explicit CacheNode(const std::string& str)
: Node(OpKind(), /* num_outputs */ 1), hash_(Hash(str)), str_(str) {}
~CacheNode() override = default;
const std::vector<Output>& operands() const override {
TORCH_INTERNAL_ASSERT(false, "Can't access operands of test node");
}
const Output& operand(size_t i) const override {
TORCH_INTERNAL_ASSERT(false, "Can't access operand[i] of test node");
}
hash_t hash() const override {
return hash_;
}
hash_t shapeHash() const override {
return hash_;
}
private:
hash_t hash_;
std::string str_;
};
TEST(CacheTest, BasicTest) {
std::shared_ptr<CacheNode> a = std::make_shared<CacheNode>("a");
std::shared_ptr<CacheNode> b = std::make_shared<CacheNode>("b");
std::shared_ptr<CacheNode> c = std::make_shared<CacheNode>("c");
Cache<hash_t, CacheNode, HashReducer> cache(2);
cache.Add(a->hash(), a);
EXPECT_EQ(cache.Get(a->hash()), a);
EXPECT_EQ(cache.Get(b->hash()), nullptr);
EXPECT_EQ(cache.Get(c->hash()), nullptr);
cache.Add(b->hash(), b);
EXPECT_EQ(cache.Get(a->hash()), a);
EXPECT_EQ(cache.Get(b->hash()), b);
EXPECT_EQ(cache.Get(c->hash()), nullptr);
cache.Add(c->hash(), c);
EXPECT_EQ(cache.Get(a->hash()), nullptr); // a has been evicted
EXPECT_EQ(cache.Get(b->hash()), b);
EXPECT_EQ(cache.Get(c->hash()), c);
cache.Erase(c->hash());
EXPECT_EQ(cache.Get(a->hash()), nullptr);
EXPECT_EQ(cache.Get(b->hash()), b);
EXPECT_EQ(cache.Get(c->hash()), nullptr); // c has been removed
cache.Clear();
EXPECT_EQ(cache.Get(a->hash()), nullptr);
EXPECT_EQ(cache.Get(b->hash()), nullptr);
EXPECT_EQ(cache.Get(c->hash()), nullptr);
}
class CacheNodeWithShape : public TsNode {
public:
explicit CacheNodeWithShape(const Shape& shape)
: TsNode(OpKind(), shape, /* num_outputs */ 1, /* seed */ 0) {}
};
TEST(CacheTest, ShapeCacheTestForDynamicShape) {
// enable dynamic shape
FLAGS_ltc_enable_dynamic_shapes = true;
CacheNodeWithShape nodes[] = {
CacheNodeWithShape(Shape(c10::kFloat, {2, 4})),
CacheNodeWithShape(Shape(c10::kFloat, {4, 2}))};
/*
* Make sure the cached shape for node (2, 4) is not used for node (4, 2)
*/
for (auto& node : nodes) {
EXPECT_EQ(node.shape(), node.computeShape([&]() { return node.shape(); }));
}
// reset the flag
FLAGS_ltc_enable_dynamic_shapes = false;
}
} // namespace lazy
} // namespace torch