Appelez Rust de Python pour accélérer! Tutoriel PyO3: Emballage d'une partie de fonction simple

Aperçu

  1. Il n'est pas préférable en termes de vitesse d'écrire l'algorithme en Pyhton ~
  2. Très bien, recherchez quelque chose d'écrit autour de C, C ++ et appelez-le depuis Python pour l'accélérer.
  3. Je ne trouve pas de bonne bibliothèque,
  4. Oh, s'il a été écrit dans une langue appelée Rust
  5. Rust peut-il être appelé depuis Python? ??

But ultime

Donc, j'ai écrit un tutoriel "Cython" pour appeler des bibliothèques C ++ à partir de Python pour accélérer les choses.

A partir de ce moment, j'écrirai un tutoriel d'une bibliothèque appelée "PyO3" pour appeler Rust depuis Python et l'accélérer.

Le but ultime est Être capable d'appeler facilement des fonctions et des classes (comme des choses?) Écrit en rust à partir de python est.

Ce PyO3 (git est ici) est en cours de développement et est mis à jour (probablement) à un rythme effréné.

L'objectif de cette fois

En premier lieu, à partir de l'état du premier regard de Rust, J'ai touché PyO3 dans le but de pouvoir appeler des fonctions écrites en Rust depuis Python.

Il y a quelques articles de commentaires sur Kita et d'autres blogs.

Cette fois, Exécuter le module Rust depuis Python (PyO3) Je voudrais emprunter votre code, y ajouter setup.py et appeler une fonction écrite en Rust depuis Python.

procédure

Installer la rouille

Lorsque vous exécutez la première ligne, vous serez interrogé sur l'installation avec 3 choix, mais je pense qu'il n'y a aucun problème à sélectionner 1 de l'installation par défaut.

curl https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env

Installer la rouille tous les soirs

Vous en aurez besoin pour utiliser PyO3. Est-ce quelque chose comme une version bêta qui contient beaucoup de caisses en cours de développement?

Vérifiez la version J'utiliserai cette version cette fois.

$rustc --version
rustc 1.44.0-nightly (f509b26a7 2020-03-18)
$ rustup --version
rustup 1.21.1 (7832b2ebe 2019-12-20)
rustup install nightly
rustup default nightly

Créer un projet de rouille

Créez un projet pour la bibliothèque en ajoutant --lib. Cette fois, le nom du projet est «exemple».

cargo new --lib example

$ tree example/
├── Cargo.toml
├── setup.py
├── src
│   └── lib.rs

La structure des dossiers ressemble à ceci.

Définir Cargo.toml

L'une des choses que Rust est censée être meilleure que C ++ etc. est la facilité de gestion de la bibliothèque. J'écris les bibliothèques nécessaires dans Cargo.toml, mais c'est beaucoup plus facile et plus facile à lire que CMakeLists.txt.

Cargo.toml


[package]
name = "test"
version = "0.1.0"
edition = "2018"

[lib]
name = "test_library"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.9.1"
features = ["extension-module"]

Cette fois, j'ai utilisé pyo3 comme bibliothèque La bibliothèque cible à créer est test_library.

Autrement dit, en Python

test.py


import test_library

Je veux écrire comme ça.

Créer une fonction avec Rust

Essayez de copier pour le moment

Le code est Exécuter le module Rust depuis Python (PyO3) J'ai apporté toutes ses affaires. Cela semble être une mise en œuvre du tamisage d'Eratostène.


//lib.rs

use pyo3::prelude::*;


// This is the test function in Rust, getting prime number, which is called by python as get_prime_numbers
#[pyfunction]
fn get_prime_numbers(n: i32) -> PyResult<Vec<i32>> {
    let mut flags = Vec::new();
    for _ in 0..n+1 {
        flags.push(true);
    }

    let upper = (n as f32).sqrt().floor() as i32;
    for i in 2..upper+1 {
        if !flags[i as usize] {
            continue;
        }

        let prime = i;

        let mut j = prime * 2;
        while j <= n {
            flags[j as usize] = false;
            j += prime;
        }
    }

    let mut primes = Vec::new();
    for i in 2..n+1 {
        if flags[i as usize] {
            primes.push(i);
        }
    }

    Ok(primes)
}



Je n'ai pas la capacité d'expliquer la syntaxe de Rust en détail, donc Supposons que cette fonction est correcte et expliquons comment elle est enveloppée dans une forme qui peut être appelée depuis Python.

#[pyfunction]
fn get_prime_numbers(n: i32) -> PyResult<Vec<i32>>

Si vous regardez Tout d'abord, le décorateur de # [pyfunction] déclare que l'argument ou la valeur de retour de cette fonction contiendra un objet Python analysé par PyO3.

Cette fonction get_prime_numbers '' prend int32 comme argument et renvoie une liste de nombres premiers inférieurs à cela. À ce stade, la valeur de retour est PyResult <Vec > , Ce `PyResult``` vient de` `ʻuse pyo3 :: prelude :: *;`.

De plus, `` Vec '' est comme indiqué dans le tableau de correspondance des types ci-dessous, et est converti en type Liste Python par PyResut.

Rust Python
i32, usizeetc int
f32, f64 float
bool bool
Vec<T> list
String str
HashMap dict

Extrait de [Rust] Create Python Package with PyO3

Aussi le dernier

Ok(primes)

Convertit Vec '' en liste ''.

Résumé

Je suis désolé que si vous arrivez ici, vous vous retrouverez avec une copie de la plupart des références. Je vais le séparer ici une fois.

En résumé,

C'est tout.

Ensuite, ajoutez lib.rs, ajoutez setup.py, et compilez-le comme un fichier objet de la bibliothèque.

Cette fois par ici.

fin.

Recommended Posts

Appelez Rust de Python pour accélérer! Tutoriel PyO3: Emballage d'une partie de fonction simple
Appelez Rust de Python pour accélérer! Tutoriel PyO3: Emballage d'une partie de fonction simple ➁
Appelez Rust de Python pour accélérer! Tutoriel PyO3: Partie des classes d'habillage ➀
Appelez Rust de Python pour accélérer! Tutoriel PyO3: partie des classes d'emballage ➁
[Python] Comment appeler une fonction de c depuis python (édition ctypes)
Langage C pour voir et se souvenir de la partie 3 Appelez le langage C depuis Python (argument) c = a + b
Envisagez la conversion de Python récursif en non récursif
Comment appeler une fonction
[Python Kivy] Comment créer une simple fenêtre pop-up
De la configuration de l'environnement Rust à l'exécution de Hello World
Aller au langage pour voir et se souvenir de la partie 8 Appeler le langage GO à partir de Python
N'écrivez pas Python si vous voulez l'accélérer avec Python
[Python] Hit Keras depuis TensorFlow et TensorFlow depuis c ++ pour accélérer l'exécution.
[Road to Intermediate Python] Appelez une instance de classe comme une fonction avec __call__
Appelez dlm depuis python pour exécuter un modèle de régression à coefficient variable dans le temps
[Python] Une fonction simple pour trouver les coordonnées du centre d'un cercle
Tout, de la création d'un environnement Python à son exécution sous Windows
Appelez Matlab depuis Python pour optimiser
Numba pour accélérer en Python
Python --Fonction d'appel dynamique à partir d'une chaîne
Comment accélérer les calculs Python
Introduction et utilisation de la bouteille Python ・ Essayez de configurer un serveur Web simple avec une fonction de connexion
Langage C pour voir et se souvenir de la partie 2 Appeler le langage C à partir de la chaîne Python (argument)
Langage C pour voir et se souvenir de la partie 1 Appeler le langage C depuis Python (bonjour le monde)
Langage C pour voir et se souvenir de la partie 4 Appelez le langage C depuis Python (argument) double
Langage C pour voir et se souvenir de la partie 5 Appel du langage C à partir du tableau Python (argument)
Un simple script IDAPython pour nommer une fonction
Appeler des commandes depuis Python (édition Windows)
[Python] J'ai essayé d'obtenir le nom du type sous forme de chaîne de caractères à partir de la fonction type
Le programme Python est lent! Je veux accélérer! Dans ce cas ...
Envoyer un message de Slack à un serveur Python
Configurer un serveur HTTPS simple avec Python 3
Modifier Excel à partir de Python pour créer un tableau croisé dynamique
Comment ouvrir un navigateur Web à partir de python
Comment créer un objet fonction à partir d'une chaîne
Comment générer un objet Python à partir de JSON
Appel de scripts Python à partir de Python intégré en C ++ / C ++
Configurer un serveur SMTP simple en Python
[Go] Comment écrire ou appeler une fonction
[Python] Faites de votre mieux pour accélérer SQL Alchemy
Un moyen simple d'appeler Java depuis Python
Sur un PC qui ne peut pas démarrer à partir de NVMe, déplacez / usr etc. vers NVMe pour accélérer
Comprendre le rendement Python Si vous mettez le rendement dans une fonction, elle se transforme en générateur
[Il n'est pas trop tard pour apprendre Python à partir de 2020] Partie 2 Créons un environnement de développement Python
Un mécanisme pour appeler des méthodes Ruby à partir de Python qui peut être fait en 200 lignes