How developed is C++ interoperability?

I am rather new to Swift, but from what I have read about it and the little experience I have had with it so far I can tell that I like it a lot. I am a machine learning researcher and I think I would be interested in getting a project started to develop a Swift frontend for the popular ML library PyTorch (SwifTorch?), but it seems like this would be a lot easier if/when Swift C++ interoperability is relatively advanced (since the PyTorch internals are written mostly in C++).

I'm aware that it's possible to wrap C++ libraries in pure C and then work with them from Swift, but honestly I'm not sure I or others would be willing to put the time or energy in to do that. If it's possible to simply declare Swift structs and classes that contain C++ objects as properties, and call C++ methods on those objects, then developing the frontend would be a lot more straightforward.

So all that is to say, what is the state of C++ interoperability in Swift? Is it currently usable for a project like the one I'm describing?

Thanks,
Nora

PS: I am well aware that Swift for TensorFlow is a thing, but for better or worse the ML community has been tending to shift away from TensorFlow and toward PyTorch, so I think it would be quite valuable to have a version of PyTorch for Swift— potentially a lot more people could be brought over to using Swift that way.

8 Likes

Hi Nora,

I'm not sure "current state" is well-documented, especially since C++ interoperability is still being designed and implemented.

You can check out the C++ Interoperability Manifesto and the C++ interoperability test suite to get a sense.

You can also find out by downloading a development snapshot from swift.org/download and trying to import PyTorch C++ headers (with swiftc -enable-cxx-interop) to see what works and what doesn't yet.

Thanks for the suggestion, I am downloading the most recent development snapshot now.

1 Like

Nice. If you want to create a SwiftPM package importing C++ headers, I believe you'll need swift build -Xswiftc -enable-cxx-interop.

1 Like

I know that @zoecarver and @hlopko were actively working on C++ interop recently, maybe they could give an update?

The short answer is: it's not yet ready. Depending on your library, you might be OK, but there's no guarantee, and I wouldn't be surprised if you run into some crashes, or linker errors. (In fact, I would be surprised if you don't.) Not to mention, many things may (and probably will) change in the next few months, so I wouldn't sink a bunch of work into a project just yet.

Here's a few important things that we do/don't support:

  • We have very rudimentary support for function templates.
  • Class templates should land in the next few days/weeks.
  • Fully specialized class templates are supported.
  • C++ constructors are supported.
  • C++ copy constructors/destructors should land in the next few days/weeks.
  • Move constructors are not supported (and won't be for some time, probably).
  • We don't yet support dependent types (those may be coming soon, though).
  • We can't yet import the C++ standard library.
  • Namespaces and other nested nominal types are mostly supported, some bug fixes for these should land in the next few days.
  • System C headers / Glibc support is finicky on Linux (I think C++ support will work best on macOS at this stage).

If you want to continue anyway... here are some suggestions:

  • Make sure to use a ToT build. Every few days we're submitting new fixes and improvements.
  • Write plain code; don't use templates; if possible create "C-like" bridge functions.
  • As Dan said, you can use -Xswiftc -enable-cxx-interop to enable C++, but this will implicitly disable C/Objective-C interop. So be careful that you're not using any of those libraries (such as Foundation).

Hope this helps.

10 Likes

Thank you for the information and your work on this. I will keep my eye on the C++ interoperability progress on the forums and on GitHub and probably wait a few months before trying to start SwifTorch in earnest.

1 Like

Of course. When you do start the project, let me know. The more C++ interop projects we can monitor, the more bugs / areas for improvement we can find. And once the project starts, maybe we can try to maintain source compatibility with it (as an extra level of testing).

2 Likes

Will do!

This is a really great summary @zoecarver great work!

2 Likes

Is this just a temporary thing to simplify the initial development, or is a limitation that might make it into a stable release?

Hopefully we'll remedy this soon. I can't say what it will look like in the future, but I expect there to be a way to use Objective-C/C and C++ libraries all together.

2 Likes

Until swiftc cxx-interop is ready, you can use Scapix to automatically generate ObjectiveC/Swift C++ bindings during build.

Disclaimer: I am the author of Scapix Language Bridge.

3 Likes

Hey guys I've tried to do simple libtorch testing using modified GitHub - plotfi/cxx-interop-test: Small test app for C++ Interop with Swift.
But im stuck on

error: missing '#include "__hash_table"'; partial specialization of '__is_hash_value_type<_One>' must be declared before it is used

#include <cstdint>

Is this limitation of actual c++ compiler in 5.5 branch or im missing something?

My build config (I tried cxx11 standard and other libtorch builds)

import PackageDescription
import Foundation



let package = Package(
    name: "cxx-interop-test",
    platforms: [.macOS(.v10_15)],
    products: [
        .executable(
            name: "cxx-interop-test",
            targets: ["cxx-interop-test"]),
    ],
    dependencies: [
    ],
    targets: [
        .target(name: "CXX", dependencies: []),
        .target(
            name: "cxx-interop-test",
            dependencies: ["CXX"],
            path: "./Sources/Swift",
            sources: [ "main.swift" ],
            swiftSettings: [.unsafeFlags([
                                          // TODO: we shouldn't have to do this. See SRXXXX.
                                          "-Xfrontend", "-validate-tbd-against-ir=none",
                                          "-Xfrontend", "-enable-cxx-interop",
                                          "-I", "Sources/CXX/include",
                                          "-I", "/opt/swift/bin/swift/usr/include",
                                          "-I", "/opt/swift/include/c++/v1/",
                                          "-I", "/opt/libtorch/include",
                                          "-I", "/opt/libtorch/include/torch/csrc/api/include",
                "-L", "/opt/libtorch/lib", "-ltorch", "-lc10",
                                          "-Xfrontend", "-disable-implicit-concurrency-module-import",
                                          "-Xcc", "-nostdinc++"])]),
    ],
    cxxLanguageStandard: CXXLanguageStandard.cxx14
)
3 Likes
Terms of Service

Privacy Policy

Cookie Policy