Giter VIP home page Giter VIP logo

facebookincubator / cinder Goto Github PK

View Code? Open in Web Editor NEW
3.4K 60.0 122.0 527.88 MB

Cinder is Meta's internal performance-oriented production version of CPython.

Home Page: https://trycinder.com

License: Other

Shell 0.11% C 32.71% C++ 6.35% DTrace 0.01% Python 59.63% Batchfile 0.13% HTML 0.32% CSS 0.01% Roff 0.07% VBScript 0.01% PLSQL 0.04% XSLT 0.01% PowerShell 0.03% Rich Text Format 0.01% Objective-C 0.05% Makefile 0.07% Assembly 0.08% Common Lisp 0.04% JavaScript 0.03% M4 0.32%
interpreter jit python compiler runtime

cinder's Issues

have cinderjit.force_compile() override jit list

I noticed that force_compile() fails if the function isn't in the jit list. Would it be reasonable to change that behavior?

Example use case: I'd like to enable jit on some 3rd party modules using jit list wildcards, but within my own code use decorators and force_compile() to mark functions for compile.

the float type is unbound in a simple program

What version of Static Python are you using?

9965302
2021-07-15

What program did you run?

# float_unbound.py

def f(x: float):
    reveal_type(x)

What happened?

The variable x has type dynamic.

compiler.static.TypedSyntaxError: reveal_type(x): 'dynamic', 'x' has declared type 'dynamic' and local type 'dynamic'

What should have happened?

We expected that the variable x has type float because of the annotation x: float. The function float has a
type and float(1) has the type Exact[float]

opt-in to JIT compile

From my understanding, starting cinder with -X jit will compile everything it encounters until cinderjit.disable(), but by then a bunch of things may already be compiled.

An option to start with jit disabled (i.e. init the JIT but set jit_config.is_enabled = 0) would be useful. For example, then I could use a decorator to tag functions for compile, without needing to maintain a jit-list.

Missing builtin modules such as math

Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.8/random.py", line 41, in
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
ModuleNotFoundError: No module named 'math'

Why does `1 + "foo"` type check?

6862bbd
2021-10-14

What program did you run?

def f():
    return 1 + "foo"

f()

What happened?

The program passes type checks.

What should have happened?

We expected a compile-time error complaining that we can't add up int and str.

BTW, the type of int's __add__ method is printed in an interesting way, what does that type mean?

reveal_type((42).__add__)
# compiler.static.errors.TypedSyntaxError:
# reveal_type(int(42).__add__):
# 'int.__add__'

error: catching polymorphic type ‘class std::exception’ by value

/cinder/Jit/pyjit.cpp: In function ‘long int flag_long(const char*, const char*, long int)’:
/cinder/Jit/pyjit.cpp:535:19: error: catching polymorphic type ‘class std::exception’ by value [-Werror=catch-value=]
  535 |     } catch (std::exception) {
      |                   ^~~~~~~~~
cc1plus: all warnings being treated as errors
make: *** [Makefile:2110: Jit/pyjit.o] Error 1
make: *** Waiting for unfinished jobs....

when running either configure & make or ./oss-build-and-test.sh on Ubuntu 20.04 on x64

"TypeError: an integer is required" when calling function returning double

seen as of cinder 5bd8c57 (and it occurs prior to that commit)

from __static__ import double

def test() -> double:
    return double(.5)

test()
$ python -m compiler --static foo.py
TypeError: an integer is required

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.8/compiler/__main__.py", line 111, in <module>
    exec(codeobj)
  File "/.../foo.py", line 6, in __main__
    test()
SystemError: PyEval_EvalFrameEx returned a result with an error set

(Same error even when test() is not called from module scope.)

Static Python allows passing too many arguments to `__init__`

What version of Static Python are you using?

4f1b313
2021-07-26

What program did you run?

# constructor_args_static.py

class Person:
    def __init__(self, name, age):
        pass

def main():
    p1 = Person('Alice', 21, False)
    return p1

What happened?

The program terminates without errors.

What should have happened?

We expected a compile-time error because the Person constructor (__init__) accepts only 2 arguments, but was given 3.

undefined reference to shm_open

I get a couple of these errors when linking the final executable:

$ g++ -pthread   -lrt   -Xlinker -export-dynamic -o python Programs/python.o libpython3.8_static.a -lcrypt -lpthread -ldl  -lutil -lm   -lm 
/usr/bin/ld: libpython3.8_static.a(virtmem.o): in function `asmjit::VirtMem_openAnonymousMemory(int*, bool) [clone .part.0]':
/home/kmod/cinder/ThirdParty/asmjit/src/asmjit/core/virtmem.cpp:330: undefined reference to `shm_open'
/usr/bin/ld: /home/kmod/cinder/ThirdParty/asmjit/src/asmjit/core/virtmem.cpp:332: undefined reference to `shm_unlink'
collect2: error: ld returned 1 exit status

Adding -lrt to the makefile LIBS variable solved this for me. This is on Ubuntu 20.04.

code accessing numpy array elements slower on cinder (jit on or off)

The example below is fairly straightforward, and gets about 20x speedup under numba. If I understand correctly, numba achieves that by accessing the numpy C API directly from jitted code, so the Python VM isn't involved. (I don't expect cinder jit to do that.)

Still, cinder (no jit) is 50% slower on this code than stock CPython (not using numba). And with cinder jit enabled on this function exclusively, there is no improvement over the no-jit case. (I confirmed that the function is compiled.)

What makes cinder slower than stock Python when touching numpy arrays?

def masked_mean(array: numpy.ndarray):
    n_rows, n_cols = array.shape
    mean = [0.0] * n_cols

    for j in range(n_cols):
        sum_ = 0.0
        n = 0
        for i in range(n_rows):
            val = array[i, j]
            if val > 0.0:
                sum_ += val
                n += 1
        mean[j] = sum_ / n if n > 0 else -1.0

    return mean

Overriding a method with a field raises an unexpected error

What version of Static Python are you using?

4f1b313
2021-07-27

What program did you run?

# override_instance_method_with_field.py
class C:
    def x(self):
        pass
class D(C):
    x: int

What happened?

The program raised a seemly irrelevant error.
AttributeError: 'ContainerTypeRef' object has no attribute 'module'

What should have happened?

We expected a compile-time type error complaining that one cannot override a method with a field. Actually, the trace back, especially the second line of the following quote, shows that StaticPython was trying to report such an error.

    f"class cannot hide inherited member: {value!r}"
  File "/vol/Lib/compiler/static/types.py", line 2245, in __repr__
    return f"<{self.name} '{self.name}' instance, args={self.args}>"
  File "/vol/Lib/compiler/static/types.py", line 1415, in __repr__
    f"<Parameter name={self.name}, ref={self.type_ref}, "
  File "/vol/Lib/compiler/static/types.py", line 260, in __repr__
    return f"TypeRef({self.module.name}, {ast.dump(self.ref)})"
AttributeError: 'ContainerTypeRef' object has no attribute 'module'

2021 H2 static Python roadmap

Usability

  • [P0] Make static python consumable easily for any Cinder user
    • Module loader in cinder
    • Consolidate rewriter logic into static compiler (out of strict modules)
    • minimum runtime version for static pycs
  • [P0] Make static python type checker run as a linter
  • [P0] Fix module dependency tracking for pyc invalidation
  • [P1] Support Enums defined in static modules
  • [P1] Expand Static Python reference guide
    • How to improve perf: primitives, CheckedDict...
    • Things that aren’t supported: multiple inheritance, metaclasses...
    • Gotchas: cbool comparison results
  • [P1] Don’t JIT all static functions
    • As we adopt more code into Static Python, not all static functions will be hot enough to deserve JIT, this should be left up to the JIT list to determine.
  • [P1] support prod_assert
  • [P1] support primitive floats
  • [P1] cross-module import always sees consistent (DeclarationVisit only) view of imported module types
  • [P1] fix patching of static functions with compatible but keyword-requiring signatures
  • [P2] improve type inference of primitive int literals

Performance

  • [P0] CheckedList
  • [P0] Optimize calls to types
  • [P0] Improved descriptor support:
    • Properties
    • Cached properties
    • class methods
  • [P1] Primitives in method calls
  • [P1] Primitives in type calls
  • [P1] More typed built-in methods
  • [P1] Dataclass intrinsic
  • [P1] Run declaration visitor on nonstatic dependency code and stubs so we can generate invokes against them
    • make sure the failure mode is appropriate Python error, not crash
    • also emit CAST on return value (helps with narrowing and Pyre compat for usability)
  • [P1] Support for runtime-checking small unions
  • [P1] avoid checking types of default argument values
  • [P1] return type of async functions
    • type-specialized await?
    • eager evaluation?
  • [P1] type-preserving user-defined decorators (util.etc, statsd.timer)
  • [P1] Declarable Exact types
    • Unlocks more non-GC containers, can declare they contain only Exact[str], which is non-GC
    • Unlocks other optimizations and statically known types also, subclasses of Python builtins can do crazy things
  • [P2] inlining decorators at compile time
  • [P2] Fixed size arrays
  • [P2] Perhaps some exploratory work around object lifetimes? Would be great to get some objects out of the GC.
    • Multiple return values that box to tuples but don’t allocate might be something slightly related

Accessing undeclared field does not raise a type error

6862bbd
2021-10-13

What program did you run?

# lookup_self_field_neg.py
# This should fail.

class C:
    pass

def f(c: C):
    # reveal_type(c.x) # dynamic
    return c.x

What happened?

The program passes type checks.

What should have happened?

We expected a compile-time error complaining that "C has no attribute x". (This is what mypy does.)

Is this another case where Static Python falls back to dynamic (similar to #50)?

What would it take to make unhashable dict key a static error?

What version of Static Python are you using?

9965302
2021-07-15

What program did you run?

# compile_nested_dict_dict_key.py

from __static__ import CheckedDict

class B: pass

class D(B): pass

def testfunc():
    x = CheckedDict[B, int]({B():42, D():42})
    y = CheckedDict[CheckedDict[B, int], int]({x: 42})
    return y

print(testfunc())

What happened?

The program raises a runtime error.

TypeError: unhashable type: 'dict[B, int]'

What should have happened?

We expected a compile-time error complaining that CheckedDict[B, int] is unhashable. Maybe the type system can look for a __hash__ method.

can't open file 'Lib/test/test_multithreaded_compile.py': [Errno 2] No such file or directory

./oss-build-and-test.sh from the root directory fails on Ubuntu 20.10 w/ the next error:

Total duration: 3 min 25 sec
Tests result: SUCCESS
./python  -X jit -X jit-test-multithreaded-compile -X jit-batch-compile-workers=10 Lib/test/test_multithreaded_compile.py
./python: can't open file 'Lib/test/test_multithreaded_compile.py': [Errno 2] No such file or directory
make: *** [Makefile:1567: testcinder_jit] Segmentation fault (core dumped)

static compile: support chained comparison

if 0 < 5 < 10:
    pass
$ python -m compiler --static foo.py
Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.8/compiler/__main__.py", line 81, in <module>
    codeobj = pycodegen.compile(
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 111, in compile
    result = make_compiler(source, filename, mode, flags, optimize, compiler, modname)
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 154, in make_compiler
    return generator.make_code_gen(
  File "/usr/lib/python3.8/compiler/static.py", line 6848, in make_code_gen
    code_gen.visit(tree)
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 2815, in visit
    ret = super().visit(node, *args)
  File "/usr/lib/python3.8/compiler/visitor.py", line 70, in visit
    return meth(node, *args)
  File "/usr/lib/python3.8/compiler/static.py", line 6939, in visitModule
    super().visitModule(node)
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 379, in visitModule
    self.visit(self.skip_docstring(node.body))
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 2815, in visit
    ret = super().visit(node, *args)
  File "/usr/lib/python3.8/compiler/visitor.py", line 62, in visit
    return self.walk_list(node, *args)
  File "/usr/lib/python3.8/compiler/visitor.py", line 53, in walk_list
    self.visit(item, *args)
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 2815, in visit
    ret = super().visit(node, *args)
  File "/usr/lib/python3.8/compiler/visitor.py", line 70, in visit
    return meth(node, *args)
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 586, in visitIf
    self.compileJumpIf(test, orelse or end, False)
  File "/usr/lib/python3.8/compiler/static.py", line 7282, in compileJumpIf
    self.get_type(test).emit_jumpif(test, next, is_if_true, self)
  File "/usr/lib/python3.8/compiler/static.py", line 911, in emit_jumpif
    CinderCodeGenerator.compileJumpIf(code_gen, test, next, is_if_true)
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 2277, in compileJumpIf
    self.emitChainedCompareStep(
  File "/usr/lib/python3.8/compiler/static.py", line 7112, in emitChainedCompareStep
    self.visit(value)
  File "/usr/lib/python3.8/compiler/pycodegen.py", line 2815, in visit
    ret = super().visit(node, *args)
  File "/usr/lib/python3.8/compiler/visitor.py", line 70, in visit
    return meth(node, *args)
  File "/usr/lib/python3.8/compiler/visitor.py", line 42, in generic_visit
    for _field, value in ast.iter_fields(node):
  File "/usr/lib/python3.8/ast.py", line 229, in iter_fields
    for field in node._fields:
AttributeError: 'Block' object has no attribute '_fields'

docker build

   docker run -t -i fedora:32 bash
   git clone https://github.com/facebookincubator/cinder.git
   yum install zlib-devel openssl-devel
   ./configure
   make
   make altinstall

PyDict is not equivalent to dict

What version of Static Python are you using?

9965302
2021-07-15

The Problem

We believe that PyDict is supposed to be the same as the dict type. However, the following pair of programs reveals that these two type constructors are not equivalent. Is this a bug? Or are there some subtle differences between PyDict and dict?

$ diff ./CheckedDict_is_dict.py ./CheckedDict_is_not_PyDict.py 
...
7c7
< def consumer(d: dict[int, int]) -> int:
---
> def consumer(d: PyDict[int, int]) -> int:
...
# CheckedDict_is_dict.py
from __static__ import CheckedDict

def producer() -> CheckedDict[int, int]:
    return CheckedDict[int, int]({2: 3})

def consumer(d: dict[int, int]) -> int:
    return d[2]

d = producer()
print(consumer(d))  # 3
# CheckedDict_is_not_PyDict.py
from __static__ import CheckedDict, PyDict

def producer() -> CheckedDict[int, int]:
    return CheckedDict[int, int]({2: 3})

def consumer(d: PyDict[int, int]) -> int:
    return d[2]

d = producer()
print(consumer(d))

# We expected the value `3`, but saw
#
#    compiler.static.TypedSyntaxError: type mismatch: chkdict[int, int]
#    received for positional arg 'd', expected dict

Subclassing a final class should give a type error

What program did you run?

from __static__ import int64
class D(int64): pass

What happened?

No error

What should have happened?

Type error because int64 is final.

Currently D(1) gives a compiler assertion error. That's good, but it'd be more helpful to reject the class definition in the first place.

error: initializer element is not constant

Running #49~18.04.1-Ubuntu SMP Wed Apr 28 23:08:58 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Building with either configure; make -j or ./oss-build-and-test
....

Python/codecs.o
Python/marshal.o
Python/context.o
Python/hamt.o
Python/errors.o
In file included from ./Include/pytime.h:6:0,
from ./Include/Python.h:85,
from Parser/acceler.c:13:
./Include/object.h:520:40: error: initializer element is not constant
static const Py_ssize_t kImmortalBit = 1L << kImmortalBitPos;
^~
./Include/object.h:521:49: error: initializer element is not constant
static const Py_ssize_t kImmortalInitialCount = kImmortalBit;
^~~~~~~~~~~~
In file included from ./Include/pytime.h:6:0,
from ./Include/Python.h:85,
from Parser/node.c:3:
./Include/object.h:520:40: error: initializer element is not constant
static const Py_ssize_t kImmortalBit = 1L << kImmortalBitPos;
^~
./Include/object.h:521:49: error: initializer element is not constant
static const Py_ssize_t kImmortalInitialCount = kImmortalBit;
^~~~~~~~~~~~
....

Cannot declare class with attributes

What version of Static Python are you using?

9965302
2021-07-13

What program did you run?

class C:
    x: int = 3

What happened?

ValueError: 'x' in __slots__ conflicts with class variable

What should have happened?

We expected the program to terminate without errors.

The error confuses us because it mentions __slots__. As far as we can tell from the python doc and a stackoverflow, __slots__ is used to optimize access to instance attributes. And this optimization has to be enabled in a manual and low-level manner. From this perspective, class attributes should have little to do with slots, unless a class attribute is shadowed by an instance attribute.

We found a similar test in cinder/test_static.py

    def test_class_level_final_reinitialized_directly(self):
        codestr = """
        from typing import Final

        class C:
            x: Final[int] = 3

        C.x = 4
        """
        # Note - this will raise even without the Final, we don't allow assignments to slots
        with self.assertRaisesRegex(
            TypedSyntaxError,
            type_mismatch("Literal[4]", "Exact[types.MemberDescriptorType]"),
        ):
            self.compile(codestr, StaticCodeGenerator, modname="foo")

We wonder

  • How to read the line x: Final[int] = 3? Is this an initialization, an assignment, or both?
  • Does Static Python have class attributes? Or are you only supposed to declare the fields that instances will have?

chkdict prints as "dict"

What version of Static Python are you using?

9965302
2021-06-24

What program did you run?

from __static__ import CheckedDict

def chk_ref(d: CheckedDict[int, int]) -> int:
  return d[0]

pydict: dict[int, int] = {1: 1}

chk_ref(pydict)

What happened?

TypeError: expected 'dict[int, int]', got 'dict'

What should have happened?

Error: expected Checked Dict got Python dict

-X jit-enable-jit-list-wildcards adds significant overhead

As per discussion in #18, enabling this option adds a ~2% overhead when enabled. We should at least add a comment to let people know this is not suitable for production.

The root-cause is likely O(all pattern lengths) complexity being introduced on every PyEval_LazyInit() which can be a very significant given how nested-function support currently works.

unsound static-to-static field overrides

What version of Static Python are you using?

9965302
2021-07-15

What program did you run?

# override_field_incompatible_type.py
from typing import ClassVar

class C:
    x: ClassVar[int] = 0

class D(C):
    x: ClassVar[str] = "0"

# Interestingly, `D.x = "hello"` raises a compile-time error
# 
#     compiler.static.TypedSyntaxError: type mismatch: Exact[str] 
#     cannot be assigned to int

What happened?

The program terminates without errors.

What should have happened?

We expected a compile-time error because D override the class variable x with an incompatible type.

Static Python: primitive types don't support pow operator

(and there is an exception while assembling the error message)

def test(x: double, y: double) -> double:
    return x ** y
  File "/usr/lib/python3.8/compiler/visitor.py", line 70, in visit
    return meth(node, *args)
  File "/usr/lib/python3.8/compiler/static.py", line 5995, in visitBinOp
    if ltype.bind_binop(node, self, type_ctx):
  File "/usr/lib/python3.8/compiler/static.py", line 4866, in bind_binop
    raise visitor.syntax_error(self.binop_error(self, rtype, node.op), node)
  File "/usr/lib/python3.8/compiler/static.py", line 4398, in binop_error
    return f"cannot {self._op_name[type(op)]} {left.name} and {right.name}"
KeyError: <class '_ast.Pow'>

`Union[str, int]` is treated as `dynamic`

What version of Static Python are you using?

6862bbd
2021-10-03

What program did you run?

from typing import Union

x: Union[int, str] = 1
reveal_type(x)

What happened?

The type of x is dynamic

compiler.static.errors.TypedSyntaxError:
reveal_type(x): 'dynamic',
'x' has declared type 'dynamic' and
local type 'Literal[1]'

What should have happened?

We expected the type of x to be Union[int, str] because union types are supported:

x: Any = 1
if True:
    x = "hello"
else:
    x = 42
reveal_type(x)

# compiler.static.errors.TypedSyntaxError:
# reveal_type(x): 'dynamic',
# 'x' has declared type 'dynamic' and
# local type 'Union[str, int]'

Can't get Docker Image - Unauthorized

When I try to run

docker run -v "$PWD/cinder:/vol" -w /vol -ti ghcr.io/facebookincubator/cinder/python-build-env:latest bash

I get

Unable to find image 'ghcr.io/facebookincubator/cinder/python-build-env:latest' locally
docker: Error response from daemon: Get https://ghcr.io/v2/facebookincubator/cinder/python-build-env/manifests/latest: unauthorized.
See 'docker run --help'.

Add compilation statistics for static python

It'd be nice if we had some metrics around when/where we were emitting code in the static compiler which used static features. This could either be full statistics on opcodes used, or just individual stats on when we hit specific features. The compiler should expose some way to enable collecting this data and then we could log it out / dump it on compile.

track python3.8 minor releases

Cinder is on 3.8.5, and there have been countless security and bug fixes up until 3.8.11

is it reasonable for the Cinder project to track minor upstream releases?

I suppose trying to rebase locally before a build may have some chance of success, but I haven't tried it.

undefined variables do not raise a type error

What version of Static Python are you using?

6862bbd
2021-10-07

What program did you run?

def f() -> int:
    return a_definitly_undefined_variable

What happened?

The program passes type checks.

What should have happened?

We expected a compile-time error complaining that a_definitly_undefined_variable is undefined. (This is what mypy does.)

calling CheckedDict

What version of Static Python are you using?

9965302
2021-07-21

What program did you run?

# calling_CheckedDict.py
from __static__ import CheckedDict


def testfunc():
    x = CheckedDict[int, str]({int(i): int(i) for i in
                               range(1, 5)})
    return x

testfunc()

What happened?

A dynamic error was raised.

TypeError: bad value 'int' for dict[int, str]

What should have happened?

We expected a static error because the type checker has enough information to push int and str into the comprehension. This behavior has been illustrated by a similar program, which raises a static error.

# calling_CheckedDict_variant.py
from __static__ import CheckedDict


def testfunc():
    x: CheckedDict[int, str] = {int(i): int(i) for i in
                               range(1, 5)}
    return x

testfunc()

# compiler.static.TypedSyntaxError: type mismatch: 
# Exact[chkdict[Exact[int], Exact[int]]] cannot be assigned to chkdict[int, str] 

unsound static-to-static method overrides

What version of Static Python are you using?

9965302
2021-06-24

What program did you run?

class A:
  def m(self) -> str:
    return "hello"

class B(A):
  def m(self) -> int:
    return 0

def main(a:A) -> str:
  return a.m()

print(main(B()))

What happened?

0

What should have happened?

Static error in the child class B because type int is not a subtype of the parent's return type.

Other notes

If B inherited from an untyped child of A, then we might need a runtime check instead.

Jit/slot_gen.cpp:111:6: error: call to member function 'bt' is ambiguous

>> Jit/slot_gen.o
warning: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Wunknown-warning-option]
Jit/slot_gen.cpp:111:6: error: call to member function 'bt' is ambiguous
  as.bt(tmp, kImmortalBitPos);
  ~~~^~
./ThirdParty/asmjit/src/asmjit/./x86/x86emitter.h:482:18: note: candidate function
  ASMJIT_INST_2i(bt, Bt, Gp, Imm)                                      // ANY
                 ^
./ThirdParty/asmjit/src/asmjit/./x86/x86emitter.h:482:18: note: candidate function
./ThirdParty/asmjit/src/asmjit/./x86/x86emitter.h:482:18: note: candidate function
./ThirdParty/asmjit/src/asmjit/./x86/x86emitter.h:482:18: note: candidate function
Jit/slot_gen.cpp:120:6: error: call to member function 'call' is ambiguous

jit-list wildcards: support "name.*" for <qualname>

Currently there doesn't seem to be a way to include all methods of a certain class.

possible now: include everything in a module (<module>:*), include methods of any class with a certain name (<module>:*.__init__).

not possible now: <module>:MyClass.*

Unsound list to Array conversion

What version of SP are you using

43d1ce7 2021-10-21

What program did you run?

  # typed.py
  from __static__ import Array, int32
  def h(x:Array[int32])->int32:
    print(x)
    return x[0]
  from typed import h
  x = ["B"]
  print(h(x))
  # ['B'] # from typed code!
  # B

What happened?

No error

What should have happened?

A runtime error --- either because ["B"] is not an array or because "B" is not an int32.

On the bright side, I haven't been able to use the wrong types to get a serious error. Adding (+) and comparing (<) x[0] with another int32 gives an error about mixing strings and numbers.

In general, we were wondering what's the SP strategy for Arrays and Vectors at the boundaries to untyped code. Is there a conversion story like for int32, should these boundaries always error, or something else?

Right now, typed code can send an Array to Python, so I'd expect the function h to look for an Array object and reject everything else.

error: ‘siginterrupt’ is deprecated: Use sigaction with SA_RESTART instead

./oss-build-and-test.sh output (Ubuntu 20.04):

/home/dev/experiments/cinder/Modules/signalmodule.c: In function ‘signal_siginterrupt_impl’:
/home/dev/experiments/cinder/Modules/signalmodule.c:661:5: error: ‘siginterrupt’ is deprecated: Use sigaction with SA_RESTART instead [-Werror=deprecated-declarations]
  661 |     if (siginterrupt(signalnum, flag)<0) {
      |     ^~
In file included from /home/dev/experiments/cinder/Modules/signalmodule.c:26:
/usr/include/signal.h:311:12: note: declared here
  311 | extern int siginterrupt (int __sig, int __interrupt) __THROW
      |            ^~~~~~~~~~~~
gcc -pthread -I"/home/dev/experiments/cinder" -fno-omit-frame-pointer -momit-leaf-frame-pointer  -Wno-unused-result -Wsign-compare -Wno-cast-function-type -Wno-type-limits -DNDEBUG -g -fwrapv -O3 -Wall    -std=c99 -Wextra -Werror -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration  -I/home/dev/experiments/cinder/Include/internal -I"/home/dev/experiments/cinder" -IObjects -IInclude -IPython -I. -I/home/dev/experiments/cinder/Include -I/home/dev/experiments/cinder/ThirdParty/fmt-6.1.1/include -I/home/dev/experiments/cinder/ThirdParty/i386-dis   -DFMT_HEADER_ONLY=1  -DPy_BUILD_CORE_BUILTIN  -c /home/dev/experiments/cinder/Modules/_stat.c -o Modules/_stat.o
cc1: all warnings being treated as errors
make: *** [Makefile:2431: Modules/signalmodule.o] Error 1
make: *** Waiting for unfinished jobs....

-X jit-enable-jit-list-wildcards has high overhead

The -X jit-enable-jit-list-wildcards option causes overhead of PyEntry_init to increase by 4x.

The following are measured with prof top -g -p ... on my app process.

empty jit list, wildcards disabled:
Screen Shot 2021-06-17 at 11 53 08 AM

empty jit list, -X jit-enable-jit-list-wildcards:
Screen Shot 2021-06-17 at 11 54 03 AM

(from discussion in #18)

Redeclaring variables may cause segmentation fault

bae060e
2021-10-22

What program did you run?

from __static__ import CheckedDict

class f():
    pass

# reveal_type(f) # 'Exact[chkdict[str, int]]'

print(f["foo"])

f: CheckedDict[str, int] = CheckedDict[str, int]({'foo': 2})

What happened?

The program is type-checked and compiled, but triggers a segmentation fault at runtime.

What should have happened?

We expected two possible outcomes. But either way, the type of f shouldn't be Exact[chkdict[str, int]].

One outcome is that the program fails type checks. It is reasonable to disallow redeclaring a variable at the same scope level when the new type is not a subtype of the old type.

Another possible outcome is that Static Python catches the runtime error. In this case, the type of f should be dynamic. The local type can be type[f] and, after the redeclaration, chkdict[str, int].

Is bool a subtype of int?

What version of Static Python are you using?

4f1b313
2021-07-27

What program did you run?

x: int = True

What happened?

The program errors.

compiler.static.errors.TypedSyntaxError: type mismatch: Exact[bool] cannot be assigned to int

What should have happened?

We expected no error because bool is a subclass of int (isinstance(True, int) is True).

Improve handling of Type[...] so distinguish between types and instances properly

Currently we don't really fully handle instances of types correctly. One example of this is:

def produce() -> type:
    @final
    class C:
        pass
    return C
C = produce()
reveal_type(C)

The inferred type of "C" becomes "Type[type]", when it really should be "Type[object]", "Type[typing.Any]" or "Type[dynamic]".

There's other places that tie into this like can_assign_from might be better taking a Value vs. a class.

Unable to build the _socket module

On Ubuntu 20.04, getting this error during the build:

$ gcc -pthread -fPIC -I. -fno-omit-frame-pointer -momit-leaf-frame-pointer -Wno-unused-result -Wsign-compare -Wno-cast-function-type -Wno-type-limits -DNDEBUG -g -fwrapv -O3 -Wall -std=c99 -Wextra -Werror -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -I./Include/internal -I./ThirdParty/i386-dis -I. -I./Include -I./ThirdParty/fmt-6.1.1/include -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/home/kmod/cinder/Include -I/home/kmod/cinder -c /home/kmod/cinder/Modules/socketmodule.c -o build/temp.linux-x86_64-3.8/home/kmod/cinder/Modules/socketmodule.o
In file included from /usr/include/string.h:495,
                 from ./Include/Python.h:30,
                 from /home/kmod/cinder/Modules/socketmodule.c:103:
In function ‘memset’,
    inlined from ‘getsockaddrarg’ at /home/kmod/cinder/Modules/socketmodule.c:2301:9,
    inlined from ‘sock_bind’ at /home/kmod/cinder/Modules/socketmodule.c:3079:10:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:71:10: error: ‘__builtin_memset’ offset [17, 88] from the object at ‘addrbuf’ is out of the bounds of referenced subobject ‘sa’ with type ‘struct sockaddr’ at offset 0 [-Werror=array-bounds]
   71 |   return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

Class values as CheckedDict type-arguments are not handled properly

9186730
2021-12-01

This issue might be related to #33

What program did you run?

from __static__ import CheckedDict
def make_C():
    class C: pass
    return C
C = make_C()
d = CheckedDict[str, C]({})

What happened?

The program raises a runtime error.

TypeError: chkdict[str, object].__new__(chkdict[str, C]): chkdict[str, C] is not a subtype of chkdict[str, object]

What should have happened?

We expected two possible outcomes:

  • a compile-time error complaining that CheckedDict[str, C] is invalid because C is not a valid type
  • a clearer run-time error
  • the program terminates without any error.

numba import error with "-X jit-no-frame"

(noted that cinder jit is experimental, and jit-no-frame is more experimental)
(also, it's silly to have multiple jitters going on, and we want to exorcise numba from our app dependencies)

things are fine with plain jit:

$ python3.8 -X jit
Python 3.8.5+cinder (heads/cinder/3.8:afb6375, May 28 2021, 05:28:52)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from numba.core.types.common import Buffer
>>> Buffer(int, 2, 'C')
buffer(<class 'int'>, 2d, C)

import problem with jit-no-frame:

$ python3.8 -X jit -X jit-no-frame
Python 3.8.5+cinder (heads/cinder/3.8:afb6375, May 28 2021, 05:28:52)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from numba.core.types.common import Buffer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/dev/.local/lib/python3.8/site-packages/numba/__init__.py", line 55, in <module>
    import numba.cpython.charseq
  File "/home/dev/.local/lib/python3.8/site-packages/numba/cpython/charseq.py", line 10, in <module>
    from numba.cpython import unicode
  File "/home/dev/.local/lib/python3.8/site-packages/numba/cpython/unicode.py", line 30, in <module>
    from numba.cpython.hashing import _Py_hash_t
  File "/home/dev/.local/lib/python3.8/site-packages/numba/cpython/hashing.py", line 562, in <module>
    'tmp': types.Array(types.uint64, 1, 'C'),
  File "/home/dev/.local/lib/python3.8/site-packages/numba/core/types/abstract.py", line 66, in __call__
    inst = type.__call__(cls, *args, **kwargs)
  File "/home/dev/.local/lib/python3.8/site-packages/numba/core/types/npytypes.py", line 411, in __init__
    super(Array, self).__init__(dtype, ndim, layout, name=name)
  File "/home/dev/.local/lib/python3.8/site-packages/numba/core/types/common.py", line 49, in __init__
    from .misc import unliteral
ModuleNotFoundError: No module named 'numba.cpython.misc'

numba version: 0.51.2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.