-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#17754: Lower Indestructible to Metal, add guidance on using static v…
…ars with non-trivial destructors (#17899) ### Ticket #17754, #17607 ### Problem description Variables with static storage duration should have trivial destructors. Add guidance on why this so, and lower `Indestructible` utility to Metal, as the suggested alternative. ### What's changed * Lower `Indestructible` from tt-train to Metal. * Add guidance to best practices doc. * Add comments and a test for `Indestructible`. ### Checklist - [X] [All post commit](https://github.com/tenstorrent/tt-metal/actions/runs/13350667483) - [X] New/Existing tests provide coverage for changes - [X] Checked that standalone tt-train compiles.
- Loading branch information
1 parent
bdb0bfc
commit 42cf08b
Showing
8 changed files
with
134 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-FileCopyrightText: © 2024 Tenstorrent Inc. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <gtest/gtest.h> | ||
#include <gmock/gmock.h> | ||
|
||
#include "tt_metal/tt_stl/indestructible.hpp" | ||
|
||
namespace tt::stl { | ||
namespace { | ||
|
||
TEST(IndestructibleTest, Basic) { | ||
struct DangerouslyDestructible { | ||
~DangerouslyDestructible() { | ||
// Wrapping in a lambda, as `FAIL()` returns `void`. | ||
[]() { FAIL(); }(); | ||
} | ||
}; | ||
|
||
Indestructible<DangerouslyDestructible> obj; | ||
} | ||
|
||
} // namespace | ||
} // namespace tt::stl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// SPDX-FileCopyrightText: (c) 2024 Tenstorrent AI ULC | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include <cstddef> | ||
#include <new> | ||
#include <utility> | ||
|
||
namespace tt::stl { | ||
|
||
// `Indestructible` is a wrapper around `T` that behaves like `T` but does not call the destructor of `T`. | ||
// This is useful for creating objects with static storage duration: `Indestructible` avoids heap allocation, provides | ||
// thread-safe construction, and ensures the destructor is no-op, so does not depend on any other objects. | ||
// | ||
// | ||
// Example usage: | ||
// | ||
// const auto& get_object() { | ||
// static Indestructible<MyObject> object; | ||
// return object.get(); | ||
// } | ||
// | ||
template <typename T> | ||
class Indestructible { | ||
public: | ||
template <typename... Args> | ||
explicit Indestructible(Args&&... args) { | ||
// Construct T in our aligned storage | ||
new (&storage_) T(std::forward<Args>(args)...); | ||
} | ||
|
||
T& get() { return *std::launder(reinterpret_cast<T*>(&storage_)); } | ||
|
||
const T& get() const { return *std::launder(reinterpret_cast<const T*>(&storage_)); } | ||
|
||
// Disable copy and assignment | ||
Indestructible(const Indestructible&) = delete; | ||
Indestructible& operator=(const Indestructible&) = delete; | ||
|
||
// Destructor does NOT call T's destructor. | ||
// This leaves the object "indestructible." | ||
~Indestructible() = default; | ||
|
||
private: | ||
// A buffer of std::byte with alignment of T and size of T | ||
alignas(T) std::byte storage_[sizeof(T)]; | ||
}; | ||
|
||
} // namespace tt::stl |