added rust support (#50)
* added rust support * move binding files to their respective directories * updated README.md * updated pypi ci package-dir * add ruapu::rua() for rust
This commit is contained in:
parent
8d3ffb0e60
commit
550a9caa0f
32
.github/workflows/ci.yml
vendored
32
.github/workflows/ci.yml
vendored
@ -35,8 +35,16 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python3 -m pip install pip -U
|
python3 -m pip install pip -U
|
||||||
python3 -m pip install setuptools -U
|
python3 -m pip install setuptools -U
|
||||||
|
cd python
|
||||||
pip3 install .
|
pip3 install .
|
||||||
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
||||||
|
- name: build-test-rust
|
||||||
|
run: |
|
||||||
|
rustup update stable
|
||||||
|
rustup default stable
|
||||||
|
cd rust
|
||||||
|
cargo build --verbose
|
||||||
|
cargo test --verbose
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
@ -50,8 +58,16 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python3 -m pip install pip -U
|
python3 -m pip install pip -U
|
||||||
python3 -m pip install setuptools -U
|
python3 -m pip install setuptools -U
|
||||||
|
cd python
|
||||||
pip3 install .
|
pip3 install .
|
||||||
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
||||||
|
- name: build-test-rust
|
||||||
|
run: |
|
||||||
|
rustup update stable
|
||||||
|
rustup default stable
|
||||||
|
cd rust
|
||||||
|
cargo build --verbose
|
||||||
|
cargo test --verbose
|
||||||
|
|
||||||
macos-arm64:
|
macos-arm64:
|
||||||
runs-on: macos-14
|
runs-on: macos-14
|
||||||
@ -65,8 +81,16 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python3 -m pip install pip -U
|
python3 -m pip install pip -U
|
||||||
python3 -m pip install setuptools -U
|
python3 -m pip install setuptools -U
|
||||||
|
cd python
|
||||||
pip3 install .
|
pip3 install .
|
||||||
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
||||||
|
- name: build-test-rust
|
||||||
|
run: |
|
||||||
|
rustup update stable
|
||||||
|
rustup default stable
|
||||||
|
cd rust
|
||||||
|
cargo build --verbose
|
||||||
|
cargo test --verbose
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
@ -86,8 +110,16 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python3 -m pip install pip -U
|
python3 -m pip install pip -U
|
||||||
python3 -m pip install setuptools -U
|
python3 -m pip install setuptools -U
|
||||||
|
cd python
|
||||||
pip3 install .
|
pip3 install .
|
||||||
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
python3 -c 'import ruapu; print(ruapu.supports("neon")); print(ruapu.supports(isa="avx"))'
|
||||||
|
- name: build-test-rust
|
||||||
|
run: |
|
||||||
|
rustup update stable
|
||||||
|
rustup default stable
|
||||||
|
cd rust
|
||||||
|
cargo build --verbose
|
||||||
|
cargo test --verbose
|
||||||
|
|
||||||
qemu:
|
qemu:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
1
.github/workflows/pypi.yml
vendored
1
.github/workflows/pypi.yml
vendored
@ -31,6 +31,7 @@ jobs:
|
|||||||
CIBW_BUILD: "cp311*"
|
CIBW_BUILD: "cp311*"
|
||||||
CIBW_BUILD_VERBOSITY: 1
|
CIBW_BUILD_VERBOSITY: 1
|
||||||
with:
|
with:
|
||||||
|
package-dir: python
|
||||||
output-dir: wheelhouse
|
output-dir: wheelhouse
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,3 +3,6 @@ build/
|
|||||||
dist/
|
dist/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
|
# Rust files
|
||||||
|
target
|
||||||
|
32
README.md
32
README.md
@ -102,7 +102,7 @@ pip3 install ruapu
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
# from source code
|
# from source code
|
||||||
pip3 install .
|
pip3 install ./python
|
||||||
```
|
```
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -121,6 +121,36 @@ ruapu.supports(isa="avx2")
|
|||||||
</td></tr>
|
</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
### ruapu with Rust
|
||||||
|
|
||||||
|
<table>
|
||||||
|
|
||||||
|
<tr><td>
|
||||||
|
|
||||||
|
Compile ruapu library
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# from source code
|
||||||
|
cd rust
|
||||||
|
cargo build --release
|
||||||
|
```
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
Use ruapu in Rust
|
||||||
|
|
||||||
|
```rust
|
||||||
|
extern crate ruapu;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("supports neon: {}", ruapu::supports("neon").unwrap());
|
||||||
|
println!("supports avx2: {}", ruapu::supports("avx2").unwrap());
|
||||||
|
println!("rua: {:?}", ruapu::rua());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Github-hosted runner result (Linux)</summary>
|
<summary>Github-hosted runner result (Linux)</summary>
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
#define RUAPU_IMPLEMENTATION
|
||||||
|
#include "../ruapu.h"
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
|
||||||
#define RUAPU_IMPLEMENTATION
|
|
||||||
#include "ruapu.h"
|
|
||||||
|
|
||||||
static PyObject *ruapu_supports_py(PyObject *self, PyObject *args, PyObject *kwargs)
|
static PyObject *ruapu_supports_py(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
static char *kwlist[] = {"isa", NULL};
|
static char *kwlist[] = {"isa", NULL};
|
@ -16,7 +16,7 @@ class bdist_wheel_abi3(bdist_wheel):
|
|||||||
|
|
||||||
ext = Extension(
|
ext = Extension(
|
||||||
name = 'ruapu',
|
name = 'ruapu',
|
||||||
sources = ['ruapu-py.c'],
|
sources = ['ruapu-binding.c'],
|
||||||
py_limited_api = True
|
py_limited_api = True
|
||||||
)
|
)
|
||||||
|
|
39
rust/Cargo.lock
generated
Normal file
39
rust/Cargo.lock
generated
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.88"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "claim"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f81099d6bb72e1df6d50bb2347224b666a670912bb7f06dbe867a4a070ab3ce8"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruapu"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"claim",
|
||||||
|
"lazy_static",
|
||||||
|
]
|
13
rust/Cargo.toml
Normal file
13
rust/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "ruapu"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cc = "1.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
claim = "0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
lazy_static = "1"
|
6
rust/build.rs
Normal file
6
rust/build.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
fn main() {
|
||||||
|
cc::Build::new()
|
||||||
|
.file("src/ruapu-binding.c")
|
||||||
|
.compile("ruapu-rs");
|
||||||
|
println!("cargo:rerun-if-changed=ruapu-binding.c");
|
||||||
|
}
|
7
rust/examples/ruapu.rs
Normal file
7
rust/examples/ruapu.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
extern crate ruapu;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("supports neon: {}", ruapu::supports("neon").unwrap());
|
||||||
|
println!("supports avx2: {}", ruapu::supports("avx2").unwrap());
|
||||||
|
println!("rua: {:?}", ruapu::rua());
|
||||||
|
}
|
76
rust/src/lib.rs
Normal file
76
rust/src/lib.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
use std::ffi::{CString, CStr, NulError};
|
||||||
|
use std::os::raw::c_char;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::result::Result;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref RUAPU_INITILIASED: Mutex<bool> = Mutex::new(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn ruapu_init();
|
||||||
|
fn ruapu_supports(isa: *const c_char) -> i32;
|
||||||
|
fn ruapu_rua() -> *const *const c_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_ruapu() {
|
||||||
|
if !*(RUAPU_INITILIASED.lock().unwrap()) {
|
||||||
|
unsafe {
|
||||||
|
ruapu_init();
|
||||||
|
}
|
||||||
|
*(RUAPU_INITILIASED.lock().unwrap()) = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn supports(isa: &str) -> Result<bool, NulError> {
|
||||||
|
init_ruapu();
|
||||||
|
let isa = CString::new(isa)?;
|
||||||
|
let isa_ptr = isa.as_ptr();
|
||||||
|
unsafe {
|
||||||
|
Ok(ruapu_supports(isa_ptr) != 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rua() -> Vec<String> {
|
||||||
|
init_ruapu();
|
||||||
|
let mut result = Vec::new();
|
||||||
|
unsafe {
|
||||||
|
let mut i = 0;
|
||||||
|
let ptr = ruapu_rua();
|
||||||
|
loop {
|
||||||
|
let ptr = ptr.offset(i);
|
||||||
|
if *ptr == std::ptr::null() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let c_str = CStr::from_ptr(*ptr);
|
||||||
|
let str = c_str.to_str().unwrap();
|
||||||
|
result.push(str.to_string());
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use claim::assert_ok;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_supports() {
|
||||||
|
assert_ok!(supports("avx2"));
|
||||||
|
assert_ok!(supports("non_exists_feature"));
|
||||||
|
assert_eq!(supports("non_exists_feature").unwrap(), false);
|
||||||
|
|
||||||
|
let supported_features = rua();
|
||||||
|
for feature in supported_features {
|
||||||
|
assert_eq!(supports(&feature).unwrap(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let nul_error = supports("neon\0avx2").unwrap_err();
|
||||||
|
assert_eq!(nul_error.into_vec(), b"neon\0avx2");
|
||||||
|
}
|
||||||
|
}
|
2
rust/src/ruapu-binding.c
Normal file
2
rust/src/ruapu-binding.c
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define RUAPU_IMPLEMENTATION
|
||||||
|
#include "../../ruapu.h"
|
Loading…
Reference in New Issue
Block a user