Skip to content

Stack the created interpreters. #607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 30, 2025

Conversation

vgvassilev
Copy link
Contributor

This patch offers an API to switch back and forth different interpreters which can come at handy in several occasions including research into implementing threading.

Fixes #302.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 10 out of 14. Check the log or trigger a new build to see more.

struct InterpDeleter {
~InterpDeleter() = default;
} Deleter;
struct InterpreterInfo {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: class 'InterpreterInfo' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]

struct InterpreterInfo {
       ^

// FIXME: For now we just leak the Interpreter.
~InterpreterInfo() {}
};
static llvm::SmallVector<InterpreterInfo, 8> sInterpreters;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'sInterpreters' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

static llvm::SmallVector<InterpreterInfo, 8> sInterpreters;
                                             ^

// assert(!sInterpreter && "Interpreter already set.");
sInterpreter = I;
// assert(sInterpreters.empty() && "Interpreter already set.");
sInterpreters.push_back({I, /*isOwned=*/true});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not declare C-style arrays, use std::array<> instead [cppcoreguidelines-avoid-c-arrays]

    auto Args = std::make_unique<const char*[]>(NumArgs + 2);
                                       ^

return I;
}

TInterp_t GetInterpreter() { return sInterpreter; }
bool DeleteInterpreter(TInterp_t I /*=nullptr*/) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]

    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
                                      ^

@vgvassilev vgvassilev force-pushed the interpreter-stack branch from 9c4439e to 4eeafdf Compare May 29, 2025 10:36
Copy link

codecov bot commented May 29, 2025

Codecov Report

Attention: Patch coverage is 83.87097% with 5 lines in your changes missing coverage. Please review.

Project coverage is 77.48%. Comparing base (de1e51b) to head (c2d62be).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
lib/CppInterOp/CppInterOp.cpp 83.87% 5 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #607      +/-   ##
==========================================
+ Coverage   77.31%   77.48%   +0.17%     
==========================================
  Files           9        9              
  Lines        3685     3713      +28     
==========================================
+ Hits         2849     2877      +28     
  Misses        836      836              
Files with missing lines Coverage Δ
include/CppInterOp/CppInterOp.h 100.00% <ø> (ø)
lib/CppInterOp/CppInterOp.cpp 84.87% <83.87%> (+0.21%) ⬆️
Files with missing lines Coverage Δ
include/CppInterOp/CppInterOp.h 100.00% <ø> (ø)
lib/CppInterOp/CppInterOp.cpp 84.87% <83.87%> (+0.21%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vgvassilev
Copy link
Contributor Author

@aaronj0 and @Vipul-Cariappa, do you understand the cppyy assertion for this PR?

@vgvassilev vgvassilev force-pushed the interpreter-stack branch 3 times, most recently from e01c641 to 3cb4164 Compare May 29, 2025 11:36
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

};

// std::deque avoids relocations and calling the dtor of InterpreterInfo.
static llvm::ManagedStatic<std::deque<InterpreterInfo>> sInterpreters;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: variable 'sInterpreters' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables]

static llvm::ManagedStatic<std::deque<InterpreterInfo>> sInterpreters;
                                                        ^

TInterp_t GetInterpreter() { return sInterpreter; }
bool DeleteInterpreter(TInterp_t I /*=nullptr*/) {
if (!I) {
sInterpreters->pop_back();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]

    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
                                      ^

EXPECT_TRUE(Cpp::DeleteInterpreter(nullptr));
EXPECT_EQ(I2, Cpp::GetInterpreter());

auto* I4 = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]

  auto* I4 = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
             ^

EXPECT_TRUE(Cpp::DeleteInterpreter(nullptr));
EXPECT_EQ(I2, Cpp::GetInterpreter());

auto* I4 = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: integer to pointer cast pessimizes optimization opportunities [performance-no-int-to-ptr]

  auto* I4 = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
             ^

EXPECT_TRUE(Cpp::DeleteInterpreter(nullptr));
EXPECT_EQ(I2, Cpp::GetInterpreter());

auto* I4 = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::uintptr_t" is directly included [misc-include-cleaner]

  auto* I4 = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
                                                      ^

EXPECT_TRUE(Cpp::Evaluate("__cplusplus") == 201703L)
<< "Failed to activate C++17";

auto* UntrackedI = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]

  auto* UntrackedI = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
                     ^

EXPECT_TRUE(Cpp::Evaluate("__cplusplus") == 201703L)
<< "Failed to activate C++17";

auto* UntrackedI = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: integer to pointer cast pessimizes optimization opportunities [performance-no-int-to-ptr]

  auto* UntrackedI = reinterpret_cast<void*>(static_cast<std::uintptr_t>(~0U));
                     ^

@Vipul-Cariappa
Copy link
Collaborator

Vipul-Cariappa commented May 30, 2025

@aaronj0 and @Vipul-Cariappa, do you understand the cppyy assertion for this PR?

@vgvassilev, you want to look at https://github.com/compiler-research/cppyy-backend/blob/e1068109110344b63b1546c853862db9632ec737/clingwrapper/src/clingwrapper.cxx#L182C1-L212C10

We first check if an interpreter already exists; if so, we just continue using it. Otherwise, create a new interpreter.
This is required for Xeus-CPP Cppyy integration. Because xeus-cpp would create the interpreter at the start of the kernel, then when a cell with %%python is executed, cppyy is loaded. It can not create a new interpreter at that point in time, because doing so will lose all the definitions declared so far.

EDITED
I have not compiled this locally and tested it. I am suspecting this to be the cause of the assertion failure, based on the cppyy's initialization code and error message.

@vgvassilev vgvassilev force-pushed the interpreter-stack branch 2 times, most recently from 258c884 to 5179760 Compare May 30, 2025 13:30
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

struct InterpDeleter {
~InterpDeleter() = default;
} Deleter;
struct InterpreterInfo {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: class 'InterpreterInfo' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]

struct InterpreterInfo {
       ^

TInterp_t GetInterpreter() { return sInterpreter; }
bool DeleteInterpreter(TInterp_t I /*=nullptr*/) {
if (!I) {
sInterpreters.pop_back();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]

    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
                                      ^

@vgvassilev vgvassilev force-pushed the interpreter-stack branch from 5179760 to e1c2c04 Compare May 30, 2025 13:42
This patch offers an API to switch back and forth different interpreters which
can come at handy in several occasions including research into implementing
threading.

Fixes compiler-research#302.
@vgvassilev vgvassilev force-pushed the interpreter-stack branch from e1c2c04 to c2d62be Compare May 30, 2025 14:35
Copy link
Collaborator

@Vipul-Cariappa Vipul-Cariappa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@vgvassilev vgvassilev merged commit 27d762d into compiler-research:main May 30, 2025
78 checks passed
@vgvassilev vgvassilev deleted the interpreter-stack branch May 30, 2025 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support multiple interpreter instance?
2 participants