Взаимодействие Chapel-Python — экспорт записей (или интерфейс с классами данных Python)Python

Программы на Python
Ответить
Anonymous
 Взаимодействие Chapel-Python — экспорт записей (или интерфейс с классами данных Python)

Сообщение Anonymous »

У меня есть следующий вариант использования. Моя основная программа написана на Python, и я хочу ускорить некоторые ее части. Программа Python использует классы данных (~структуры) для хранения параметров, массивов и т. д. Рассмотрим следующую основную программу Python; который использует структуру Point.

Код: Выделить всё

# 0/main.py

from dataclasses import dataclass

@dataclass
class Point:
x: float

def addOne(p: Point) -> Point:
return Point(p.x + 1.0)

p1 = Point(1.0)
print(p1)
p2 = addOne(p1)
print(p2)

Код: Выделить всё

(0) $ python main.py
Point(x=1.0)
Point(x=2.0)
Теперь я хочу ускорить функцию addOne. Моя отправная точка — заставить Chapel определить структуру Point, а Python импортировать ее.

Код: Выделить всё

# 1/main.py
from libexample import Point, makePoint, printPoint, addOne

p1 = Point(1.0)   # or makePoint(1.0)
printPoint(p1)
p2 = addOne(p1)
printPoint(p2)

Код: Выделить всё

// 1/libexample.chpl
// -- types used by exported functions need to be exported
// -- cannot export records, so we use extern
// export record Point {
//   var x: real(64);
// }

extern {
typedef struct {
double x;
} Point;
}

// -- altenatively
// require "point.h";
// --
// $ cat point.h
// #ifndef POINT_H
// #define POINT_H
// typedef struct {
//   double x;
// } Point;
// #endif

extern record Point {
var x: real(64);
}

export proc makePoint(x: real): Point {
var p: Point = new Point(x);
return p;
}

export proc printPoint(in p: Point) {
writeln("Point(", p.x, ")");
}

export proc addOne(in p: Point): Point {
return new Point(p.x + 1.0);
}
Тестовая программа Chapel работает нормально:

Код: Выделить всё

// 1/main.chpl
use libexample;

var p1 = makePoint(1.0);
printPoint(p1);
var p2 = addOne(p1);
printPoint(p2);

Код: Выделить всё

(1) $ chpl main.chpl
(1) $ ./main
Point(1.0)
Point(2.0)
Но компиляция как общая библиотека этого не делает:

Код: Выделить всё

(1) $ chpl --library --library-python libexample.chpl

Error compiling Cython file:
------------------------------------------------------------
...
from libc.stdint cimport *
from chplrt cimport *

cdef extern from "libexample.h":
void chpl__init_libexample(int64_t _ln, int32_t _fn);
Point makePoint(double x);
^
------------------------------------------------------------
./chpl_libexample.pxd:6:1: 'Point' is not a type identifier

# ... and more of such errors
Насколько я понимаю, экспорт записей и классов еще не реализован: https://github.com/chapel-lang/chapel/issues/9326.
Рабочий (но утомительный и неподдерживаемый) обходной путь — написать оболочки Python, чтобы распаковать все в базовые типы для вызова Chapel и переупаковать возвращаемые значения.

Код: Выделить всё

# 2/main.py
from dataclasses import dataclass

@dataclass
class Point:
x: float

def addOne(p: Point):
from libexample import addOne as addOne_chpl
return Point(addOne_chpl(p.x))

p1 = Point(1.0)
print(p1)
p2 = addOne(p1)
print(p2)

Код: Выделить всё

// 2/libexample.chpl
export proc addOne(p_x: real(64)): real(64) {
return p_x + 1.0;
}
Затем компилируем и запускаем:

Код: Выделить всё

(2) $ chpl --library --library-python libexample.chpl
(2) $ python main.py
Point(x=1.0)
Point(x=2.0)
Очевидно, что это нежелательно и чревато ошибками, особенно при работе с вложенными структурами.
Я также изучил модуль Python и увидел, что он позволяет определять пользовательские типы (https://github.com/chapel-lang/chapel/b ... mType.chpl).

Насколько я понимаю Понимаете, вы можете вызывать код Python из Chapel (возможно, с настраиваемыми структурами), но я хочу сделать наоборот: вызвать код Chapel из Python с настраиваемыми структурами. Структуры могут быть сначала определены либо в Python, либо в Chapel (хотя определение их сначала в Chapel кажется более разумным)
Существует ли в настоящее время «хороший» способ сделать это? В идеале структура должна быть определена только один раз, без необходимости использования специально написанных TypeConverter и тому подобного (которые на практике дублируют код). Спасибо за помощь!

Подробнее здесь: https://stackoverflow.com/questions/798 ... n-dataclas
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»