Skip to content
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

Start to integrate LLVM bindings into Pyk #2844

Closed
wants to merge 13 commits into from
Closed

Start to integrate LLVM bindings into Pyk #2844

wants to merge 13 commits into from

Conversation

Baltoli
Copy link
Contributor

@Baltoli Baltoli commented Aug 31, 2022

This PR is a revised attempt (following runtimeverification/llvm-backend#551, which wasn't what we were looking for) to integrate the new Python bindings for the LLVM backend into Pyk.

The previous attempt aimed to build a wheel from the LLVM backend's build directory, then convince Poetry to track that wheel as a dependency locally. Unfortunately, this would require us to be able to build a wheel for every supported platform; this would be a lot of wrangling and cross-compilation.

This PR works by symlinking the shared library built during the LLVM backend's build phase into the src/kllvm package, which then transparently re-exports the symbols from that package. Poetry then packages this local package alongside pyk at build time.

I've also added a trivial test case for the bindings to make sure that all of these changes actually work.

I've spent quite a bit of time fiddling with this, but I'm open to suggestions on how to improve it - it's by no means guaranteed to be the best solution, but it's the neatest one I've found as yet.

Per @goodlyrottenapple's request, this PR also adds a line to the github action spec to ensure we're testing Pyk via nix.

@Baltoli Baltoli marked this pull request as ready for review August 31, 2022 15:30
@Baltoli Baltoli requested a review from a team as a code owner August 31, 2022 15:45
@ehildenb
Copy link
Member

It looks overall fine to me, but I suppose that the changes to the Makefile must be taken into account in the cookiecutter settings @tothtamas28 ?

Comment on lines +1 to +9
from unittest import TestCase

import kllvm


class KLLVMTest(TestCase):
def test_basic(self):
sort_int = kllvm.ast.CompositeSort('SortInt')
self.assertEqual(str(sort_int), "SortInt{}")
Copy link
Member

Choose a reason for hiding this comment

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

Did you confirm that this test is being run on CI correctly (shows up in the output)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From the CI log:

test_basic (tests.test_kllvm.KLLVMTest) ... ok

Comment on lines +1 to +2
from . import kllvm
from .kllvm import ast
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the suggested way for wrapping native pybind11 modules? Whe I try to import the module from an interpreter, I get the following error.

In [1]: import kllvm
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [1], in <cell line: 1>()
----> 1 import kllvm

File ~/.local/lib/python3.8/site-packages/kllvm/__init__.py:1, in <module>
----> 1 from . import kllvm
      2 from .kllvm import ast

ImportError: cannot import name 'kllvm' from partially initialized module 'kllvm' (most likely due to a circular import) (/home/ttoth/.local/lib/python3.8/site-packages/kllvm/__init__.py)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Did you run make deps in the pyk directory beforehand?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(i.e. is there a shared library kllvm.platform-os-etc.so beside src/kllvm/__init__.py?)

Copy link
Contributor

@tothtamas28 tothtamas28 Sep 1, 2022

Choose a reason for hiding this comment

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

There is, and the unit test passes accordingly.

But now I tried it with python, and it works, so the issue is only present with ipython.

Copy link
Contributor

Choose a reason for hiding this comment

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

Currently, both of the following work:

from kllvm.kllvm import ast
from kllvm import ast

Did you consider putting this in __init__.py instead?

from .kllvm import *

Copy link
Contributor

Choose a reason for hiding this comment

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

If that doesn't solve the circular import problem of ipython, an other solution to consider is to rename the native module to _kllvm. (That also communicates to users that the module is not supposed to be imported directly.)

Copy link
Contributor

@tothtamas28 tothtamas28 left a comment

Choose a reason for hiding this comment

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

The previous attempt aimed to build a wheel from the LLVM backend's build directory, then convince Poetry to track that wheel as a dependency locally. Unfortunately, this would require us to be able to build a wheel for every supported platform; this would be a lot of wrangling and cross-compilation.

I think that would be the right way to do it though. As I see it, the current solution just transfers the problem to pyk deployment.

What do you think about the following workaround?

Let's pull this module out from pyk to it's own package at the llvm-backend root. We then define a dev dependency in pyk to the corresponding path (we use the same hack downstreams). Once we have the capacity, we can set up the CI pipelines for proper deployment, and replace the dev dependency by a runtime dependency.

@Baltoli
Copy link
Contributor Author

Baltoli commented Sep 1, 2022

So to summarise - the LLVM backend should present a Python package that contains the shared library it compiled; this package can use a similar trick as above to re-export all the symbols from the shared library (module getting the imports / exports right - _kllvm seems like the right answer).

Pyk can then point its pyproject.toml file to the LLVM backend's installed package as a dev dependency.

@tothtamas28
Copy link
Contributor

So to summarise (...)

Yes, I think that would be the right approach for now.

@Baltoli
Copy link
Contributor Author

Baltoli commented Sep 1, 2022

Great, thanks for the pointers!

@Baltoli Baltoli closed this Sep 1, 2022
@Baltoli Baltoli mentioned this pull request Sep 1, 2022
3 tasks
h0nzZik pushed a commit to h0nzZik/k that referenced this pull request Nov 24, 2022
…untimeverification#2212)

* haskell-backend/src/main/native/haskell-backend: d0bfb78f - Update regression tests (runtimeverification#2844)

* haskell-backend/src/main/native/haskell-backend: 98e241ed - Update dependency: deps/k_release (runtimeverification#2843)
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.

3 participants