node_12306 icon indicating copy to clipboard operation
node_12306 copied to clipboard

按要求输入信息后报错,帮忙看下呗,谢谢,系统 Mac

Open wayward-man opened this issue 6 years ago • 0 comments

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.

wayward-man avatar Jan 08 '20 09:01 wayward-man

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!

jeanlaroche avatar Nov 27 '18 16:11 jeanlaroche

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.

paugier avatar Nov 27 '18 18:11 paugier

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 avatar Nov 27 '18 18:11 jeanlaroche

@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:

  1. define Python class to be used in Python with methods using Pythran (this could be done in pure Python using Pythran 0.9)
  2. 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
  3. define proper user-defined Pythran types that can be used in Pythran kernels (need some work on Pythran)

paugier avatar Nov 28 '18 11:11 paugier

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.

nbecker avatar Nov 28 '18 12:11 nbecker

@paugier Thanks for the suggestion, I had not thought of that. I'll have to look into it!

jeanlaroche avatar Nov 28 '18 16:11 jeanlaroche

@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...

jeanlaroche avatar Nov 28 '18 17:11 jeanlaroche

Self is always passed as the 1st argument to a method, so it's always available, right?

nbecker avatar Nov 28 '18 18:11 nbecker

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?

jeanlaroche avatar Nov 28 '18 18:11 jeanlaroche

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?

nbecker avatar Nov 28 '18 19:11 nbecker

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?

jeanlaroche avatar Nov 28 '18 19:11 jeanlaroche

I meant that pythran could theoretically generate c++ code to access the attributes of the self object.

nbecker avatar Nov 28 '18 19:11 nbecker

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:

paugier avatar Nov 28 '18 20:11 paugier

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?

nbecker avatar Nov 29 '18 12:11 nbecker

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.

paugier avatar Nov 29 '18 15:11 paugier

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...

jeanlaroche avatar Nov 29 '18 16:11 jeanlaroche

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

paugier avatar Dec 07 '18 17:12 paugier

Nice!

jeanlaroche avatar Dec 07 '18 17:12 jeanlaroche

In the above Transmitter example, 'freq' was type 'float', which can use python annotation. What if it was a list of float?

nbecker avatar Dec 07 '18 19:12 nbecker

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...

paugier avatar Dec 07 '18 22:12 paugier

New release of FluidPythran (v. 0.1.5): @cachedjit can be used for methods...

https://fluidpythran.readthedocs.io/en/latest/examples/methods.html

paugier avatar Dec 12 '18 17:12 paugier

I'm currently upgrading to python3, once that's finished, I'm sure to give fluidpythran a shot! Can't wait!

jeanlaroche avatar Dec 12 '18 17:12 jeanlaroche

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?

paugier avatar Sep 03 '19 09:09 paugier