按要求输入信息后报错,帮忙看下呗,谢谢,系统 Mac
Callback must be a function at maybeCallback (fs.js:129:9) at Object.writeFile (fs.js:1159:14) at prompt.then.answer (/Users/xiaofei19/Desktop/gitRepository/node_12306-master/main.js:204:7) (node:87907) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:87907) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
That would be truly awesome! I have had to work quite hard to work around the lack of class support (but it was worth it!). Simple classes with encapsulated data would already be super useful!
One question @nbecker and @jeanlaroche : do you want to use such classes in Python or in Pythran kernels?
If it is only to be used in Python, a pure python solution is good and simple. Something like
from fluidpythran import cachedjit
class Transmitter():
freq: float
def __init__(self, freq):
self.freq = float(freq)
@cachedjit
def __call__(self, inp: float):
return inp * np.exp(np.arange(len(inp))*self.freq*1j)
This could (will) be easily implemented in fluidpythran and it's going to be quite efficient from Python.
Remark: __call__ may not be a good example since I think it is really a special case and I'm not sure one can monkey patch this special function...
If you want to use instances of this class in Pythran kernels, it is another story... It has to be implemented in Pythran and it is a big work! A nice benefit is that one would be able to write C++ struct in Python/Numpy.
Then, it seems to me that it would be better to clearly write than it is not a standard Python class with something like:
from pythran_runtime import dataclass
@dataclass
class Transmitter():
freq: float
def __call__(self, inp: float):
return inp * np.exp(np.arange(len(inp))*self.freq*1j)
like that we can build an object with the same behavior in Python (without compilation) and Pythran.
In my case I'm interested in both. I use pythran to speed up my python code, but I also use it to deploy my python code as a C++ module that's compiled and linked into a separate code base (i.e., I provide C++ modules to other teams, and they compile them into their executables)... I realize it's truly not a trivial task to support classes (even de-featured classes)
@jeanlaroche
Cython+Pythran might be fine for your use case.
You should be able to define a cdef class with Cython using Pythran in methods of this class. Then I guess you could produce C++ code which does not depend on the Python interpreter.
If the Pythran kernel do not use your class (but only standard types), it would be fine without proper user-defined Pythran types.
So it seems to me that the use cases can be split in 3 categories:
- define Python class to be used in Python with methods using Pythran (this could be done in pure Python using Pythran 0.9)
- define C++ class/struct to be used in C++/Python with methods using Pythran (I guess this could be done with Cython and Pythran 0.9 (?)) this class
- define proper user-defined Pythran types that can be used in Pythran kernels (need some work on Pythran)
My main interest is using from python. So case 1 above seems relevant. Of course it is more convenient if code does not have to be rewritten. I'm assuming to implement case 1 today would require rewriting class methods to call ordinary functions, which could then be pythran.
@paugier Thanks for the suggestion, I had not thought of that. I'll have to look into it!
@paugier Question, how is it possible to use pythran to implement a class method, as that method needs "self". How is self available to a pythran function? Unless you mean calling a non-class method from the class method (passing the right parameters) and using pythran on the non-class method. If that's what you mean, it's still a huge overhead (coding-wise). But maybe I don't understand what you're suggesting...
Self is always passed as the 1st argument to a method, so it's always available, right?
Self is always passed as the 1st argument to a method, so it's always available, right?
Sure, but it will be available as what in pythran? That's the question! How would the function-to-be-pythranized access self.this for example?
Well at least it's available as a python object which has attributes that can be accessed. For my example, I can get the 'freq' attribute from the python object in my c++ code. Is that what you want?
Well at least it's available as a python object which has attributes that can be accessed. For my example, I can get the 'freq' attribute from the python object in my c++ code. Is that what you want?
You can currently get a python object in your C++ code created by pythran? Or are you saying that's what you'd like to be able to get?
I meant that pythran could theoretically generate c++ code to access the attributes of the self object.
Question, how is it possible to use pythran to implement a class method, as that method needs "self". How is self available to a pythran function? Unless you mean calling a non-class method from the class method (passing the right parameters) and using pythran on the non-class method. If that's what you mean, it's still a huge overhead (coding-wise). But maybe I don't understand what you're suggesting...
Let's start by the case 1. In this case, we want to define a class in Python and to use Pythran in methods. Since we cannot send an object of the class (self) in a Pythran function, we need to modify the code. But it can be done automatically for us by fluidpythran (so very small overhead, coding-wise and performance-wise). This is the principle of fluidpythran. The developer only writes code in Python files (which are not compiled by Pythran, so no limitation related to Pythran in these files). Fluidpythran creates the necessary Pythran files, compiles them and replace blocks, functions (or method) by Pythran functions or by code calling Pythran functions.
Then the case 2: using Pythran in Cython and produce C++ code not using pythran.h, so not using the interpreter and which can be used in pure C++ projects. I really don't know if it is feasible right now. What I now is that (i) it is possible to write buildin types with Cython with a syntax very similar to Python classes (cdef class MyClass, cdef namemethod(self, ...): and self.my_attr in the methods). It seems to me that these "cdef classes" are very simple, i.e. just C structures. I don't know if functions from python.h are used by these classes, but it seems to me that it is not yellow at all in the Cython web representation (meaning that it is mostly pure C or close to pure C) (ii) Cython is able to replace Python/Numpy code by Pythran C++ code. From these two facts, I conclude we may not be far from being able to write a C++ classes with Cython and Pythran. But I may be wrong :slightly_smiling_face:
Let's start by the case 1. In this case, we want to define a class in Python and to use Pythran in methods. Since we cannot send an object of the class (self) in a Pythran function, we need to modify the code. But it can be done automatically for us by fluidpythran (so very small overhead, coding-wise and performance-wise). This is the principle of fluidpythran. The developer only writes code in Python files (which are not compiled by Pythran, so no limitation related to Pythran in these files). Fluidpythran creates the necessary Pythran files, compiles them and replace blocks, functions (or method) by Pythran functions or by code calling Pythran functions.
According to https://bitbucket.org/fluiddyn/fluidpythran, this Python classes: @pythran_def for methods is not yet implemented in fluidpythran, so you are speaking about some future version of fluidpythran, correct?
so you are speaking about some future version of fluidpythran, correct?
Correct. But @pythran_def and @cachedjit for simple methods is really doable in few days. It should not be so difficult now that we have fluidpythran as it is today.
i have to say I've never used fluidpythran... I have to give it a shot, I think it will simplify my work quite a bit...
I just released a new version of fluidpythran (0.1.4) which supports this:
import numpy as np
from fluidpythran import boost
# pythran import numpy as np
@boost
class Transmitter():
freq: float
def __init__(self, freq):
self.freq = float(freq)
@boost
def __call__(self, inp: float):
return inp * np.exp(np.arange(len(inp))*self.freq*1j)
- One needs to decorate the method and the class...
- It's only usable in Python (and of course it cannot be used as a new Pythran type!).
See https://fluidpythran.readthedocs.io
Nice!
In the above Transmitter example, 'freq' was type 'float', which can use python annotation. What if it was a list of float?
you can use strings (actually anything) in Python annotations, so you could write:
freq: "float list"
Of course, for performance with Pythran arrays are better...
New release of FluidPythran (v. 0.1.5): @cachedjit can be used for methods...
https://fluidpythran.readthedocs.io/en/latest/examples/methods.html
I'm currently upgrading to python3, once that's finished, I'm sure to give fluidpythran a shot! Can't wait!
An update on this issue.
https://transonic.readthedocs.io/ (new name of fluidpythran) supports well acceleration of methods with Pythran. It is good enough for many cases.
However, in other situations supporting kind of struct that can be used in the numerical kernels would be very useful.
Numba has @jitclass and Cython has cdef class.
Scikit-learn people use them in some algorithms, see for example a good example https://github.com/ogrisel/pygbm/blob/master/pygbm/splitting.py#L21
For Transonic (and Pythran?), dataclass (https://docs.python.org/3/library/dataclasses.html) could be a nice syntax.
@dataclass
class InventoryItem:
'''Class for keeping track of an item in inventory.'''
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self):
return self.unit_price * self.quantity_on_hand
Then, it should of course be possible to use these types in Pythran signatures!
How hard would it be to support this in Pythran?