<GitHub72>
artiq/new-py2llvm 6f11fa6 whitequark: Add conversion to LLVM IR (except handling of exception handling).
<whitequark>
so far
<whitequark>
every function I have tried has been optimized by LLVM into "ret void"
<whitequark>
I mean, that's better than "unreachable" (which would imply it invokes UB on every dynamic path)
<whitequark>
but underwhelming.
<whitequark>
I want a print().
<cr1901_modern>
sb0_: Looks like at least the Xilinx tools will run on Net. Would you accept a patch to add support for Net and Free for the poor souls running them?
* rjo
autocompletes "Net" to "Internet" and "Free" to "Free Beer".
<cr1901_modern>
Bee Ess Dee
<cr1901_modern>
Like the License of Migen, but with more downsides
<rjo>
you must be very ashamed that you abbreviate BSD away!
<cr1901_modern>
Possibly. sb0 didn't seem so enthused about BSD last time I brought the topic up XD
<rjo>
but for mibuild i don't see what you would need to change to get it running on *BSD.
<rjo>
is it "bash"? ;P
<cr1901_modern>
Yes, that's part of it. Also (possibly) environment variable propogation
<cr1901_modern>
(I will never use bash again after shellshock if I can help it)
<rjo>
getting rid of bashisms is always nice.
<rjo>
the fixing of one bug is basically never correlated with the existence of another bug.
<cr1901_modern>
It's not the existence of the bug in the first place. It's the fact it went undiscovered for f***ing 20 years
<cr1901_modern>
With most likely hundreds of maintainers looking over the code.
<cr1901_modern>
Also, I'm quite happy with a Bourne shell clone (ash, in this case) as long as it has autocomplete
<rjo>
i don't think there is evidence that age of a certain bug is correlated with the quality of a piece of software.
Gurty has quit [Ping timeout: 260 seconds]
<rjo>
i would like my shell to have a history as well please.
<cr1901_modern>
Yes, that too.
<cr1901_modern>
In any case, not adding support tonight. I'll save that for later (hopefully Altera is as well behaved as Xilinx is being).
<cr1901_modern>
Funny how ISE seems to run fine with Linux emul, but Skype can't o.0;
Gurty has joined #m-labs
<cr1901_modern>
rjo: Looks like I didn't have to change anything after all. Of course, synthesis failed b/c I'm missing a license, but whatever lol
<sb0_>
whitequark, yes, m1 is fine. i hope it works, considering the time we spent testing those damn things.
sb0_ has quit [Remote host closed the connection]
mumptai has joined #m-labs
<whitequark>
ok, that solves the hardware problem then
<whitequark>
rjo: sb0: what's worse, taking two registers or issuing a 64-bit load?
<whitequark>
I can pass closures around as {env*, fn*} or {env*, fn*}*
<whitequark>
ditto for lists
<whitequark>
passing both in registers for now.
<GitHub80>
[artiq] whitequark pushed 2 new commits to new-py2llvm: http://git.io/vmhcZ
<GitHub80>
artiq/new-py2llvm e299801 whitequark: LocalAccessValidator: fix validation of closures with no outer variables.
<GitHub80>
artiq/new-py2llvm ec9d40b whitequark: Add LLVM IR generation for function calls.
<whitequark>
oops, forgot function calls.
sb0 has joined #m-labs
<GitHub27>
[artiq] whitequark pushed 3 new commits to new-py2llvm: http://git.io/vmhgi
<GitHub27>
artiq/new-py2llvm e58b811 whitequark: Fix tests broken by fixed FloorDiv.
<GitHub27>
artiq/new-py2llvm 64d2604 whitequark: Tolerate assertion failures in tests when looking for diagnostics.
<GitHub27>
artiq/new-py2llvm 49ece6a whitequark: Add support for string literals.
<sb0>
whitequark, why do lists need 64 bits?
<whitequark>
struct list { size_t len; void *ptr; }, passed by value
<whitequark>
well, or by reference
<whitequark>
it's still two words long.
<sb0>
whitequark, the pipistrello has cleared customs.
<sb0>
you may not need to mess with a m1 port after all
<whitequark>
amazing, just took the germans 19 day
<sb0>
bah, strike...
<whitequark>
oh well.
<whitequark>
should be at my place in 1-2 days
<sb0>
why do you store the length in the value? as opposed to e.g. the first word pointed to
<sb0>
the german post also hasn't updated their tracking info.
<whitequark>
yeah, I noticed
<whitequark>
as for in the value. the reason is a bit contrived.
<whitequark>
I allocate the list with an alloca. I can make an alloca of {some_structure}, i32 %length
<whitequark>
but I cannot make an alloca of { i32, [{some_structure} x i32 length] }
<whitequark>
because array types in LLVM cannot depend on values
<whitequark>
i.e. you can only have a constant length there.
<whitequark>
now, I could of course allocate just an array of bytes. but figuring out how long that array of bytes should be requires calling into LLVM
<whitequark>
whereas currently all IR-building is solely on Python side
<sb0>
ok, and your aim is to limit the number of LLVM types created? because the current code creates one LLVM type for each list length
<whitequark>
oh, no
<whitequark>
as list length is now variable, you cannot possibly create all LLVM types
<whitequark>
I mean, I can do what you suggest, but I'll then need to use the LLVM C API (the TargetMachine ones) during IR-building
<whitequark>
which I wanted to avoid for simplicity.
<sb0>
I think the 64-bit structs are fine, but I don't fully understand why they are needed
<whitequark>
sb0: actually, I have another thought about this
<whitequark>
`count` cannot be a value, only an integer literal
<sb0>
ah, count is determined at runtime now?
<sb0>
ah, OK.
<whitequark>
as for another thought
<whitequark>
this design allows to create mutable views of lists for free.
<whitequark>
which is convenient, because iterating a list (or its view) does not incur any bounds checking cost.
<whitequark>
but I do not know how valuable would you consider this
<sb0>
fast bounds checking is nice to have, yes
<sb0>
not a priority, but nice
<whitequark>
ok. so I think we should keep the 64-bit struct format so far.
<whitequark>
because making views is as simple as advancing a pointer and reducing length with it
<whitequark>
the escape analysis already understands that the views do not outlive the list.
* whitequark
sighs
<whitequark>
llvmlite is crap. the idea behind it is sound, but the code is crap
sb0 has quit [Ping timeout: 240 seconds]
<whitequark>
and the docs are crap. I gave up and just use the source now
<whitequark>
ha. C++ has generators now. N4268
sb0 has joined #m-labs
<sb0>
llvmpy was worse
<sb0>
Qt has this "What's this" help support sprinkled around in some places of the API... never seen that used in practice
<sb0>
and wow, creating a tabbed view with radio buttons instead or tabs is an impressive mess
<whitequark>
why'd you do that?
<sb0>
radio button to select a mode, then widgets to parameterize that mode
<sb0>
maybe creating/destroying the widgets everytime the radio button is changed is easier than messing with QTabWidget and friends
<sb0>
oh, QStackedWidget.
<whitequark>
yea
sb0 has quit [Ping timeout: 256 seconds]
sb0 has joined #m-labs
<sb0>
why is qt making qstackedwidgets expansible by default?
<sb0>
insert a widget (e.g. text entry) directly -> size looks nice
<sb0>
wrap it in qstackedwidget -> your text entry covers the whole windows
<sb0>
oh, how i love this sort of problem
sb0 has quit [Ping timeout: 246 seconds]
ylamarre has joined #m-labs
sb0 has joined #m-labs
sb0 has quit [Client Quit]
cr1901_modern has quit [Remote host closed the connection]
cr1901_modern has joined #m-labs
<rjo>
why does Qt need to abbreviate to Q?
<whitequark>
dunno. historical reasons
<whitequark>
sb0: actually, "insert a widget directly" is what does not work properly
<whitequark>
Qt has layouts; use them!
<whitequark>
also, qtdesigner is great
ylamarre1 has joined #m-labs
ylamarre has quit [Read error: Connection reset by peer]
<cr1901_modern>
Why would anyone try to build their own GUI from scratch? Unless they're a Luddite and/or are acutely aware of the bootstrapping problem from using a GUI designer XD?
ylamarre1 has quit [Read error: Connection reset by peer]
ylamarre has joined #m-labs
<whitequark>
um, there are many valid reasons, e.g. a programmatically determined layout
_florent_ has joined #m-labs
ylamarre1 has joined #m-labs
ylamarre has quit [Read error: Connection reset by peer]
<GitHub68>
[artiq] whitequark pushed 4 new commits to new-py2llvm: http://git.io/vYvxf
<GitHub68>
artiq/new-py2llvm 7301a76 whitequark: Mark string constants as unnamed_addr....
<GitHub68>
artiq/new-py2llvm 8c9d9cb whitequark: Make compiler.testbench.llvmgen emit a main() function.
<GitHub68>
artiq/new-py2llvm 9d20080 whitequark: Use internal linkage for interior Python global values.
<GitHub140>
[artiq] whitequark pushed 1 new commit to new-py2llvm: http://git.io/vYvx0
<GitHub140>
artiq/new-py2llvm 1e851ad whitequark: Add a polymorphic print function.
tariq786 has quit [Quit: Leaving]
bambino has joined #m-labs
bambino is now known as tariq786
<whitequark>
sb0, rjo: question: shall I require the condition of an if to have the type bool, or retain python's behavior where all kinds of shit can be falseful?
<whitequark>
either behavior is a strict subset. I naturally like the latter, since it is more rigorous, but I'm clearly biased
<rjo>
falseful?
<whitequark>
if []: print("no") # never happens
<rjo>
because bool([]) is False?
<rjo>
are you asking whether you need to cast to bool or require the user to do it?
<whitequark>
that's kind of backwards reasoning; but essentially yes
<whitequark>
I am asking a slightly different thing
<whitequark>
just remove the auto-casting to bool entirely. len(lst) > 0
<rjo>
in your first alternative if [] would be invalid, right?
<whitequark>
yes
<whitequark>
similar to: if 0, if 0.0, if IndexError()
<rjo>
if it it not a massive amount of code, i like your second alternative.
<whitequark>
the 2nd one is simpler.
<rjo>
why would somebody prefer the 1st?
<whitequark>
it is apparently deemed 'Pythonic'
<whitequark>
and it is also an endless source of bugs in my experience
<whitequark>
done
<GitHub128>
[artiq] whitequark pushed 2 new commits to new-py2llvm: http://git.io/vYfEt
<GitHub128>
artiq/new-py2llvm d862db8 whitequark: Require boolean operand in BoolOp.
<GitHub83>
[artiq] whitequark force-pushed new-py2llvm from d862db8 to 5d518dc: http://git.io/vmI6O
<GitHub83>
artiq/new-py2llvm 5d518dc whitequark: Require boolean operand in BoolOp.
<GitHub17>
[pythonparser] whitequark pushed 1 new commit to master: http://git.io/vYfVA
<GitHub17>
pythonparser/master bb6b143 whitequark: Don't print both start and end position for zero-length ranges.
ylamarre has joined #m-labs
ylamarre1 has quit [Read error: Connection reset by peer]
ylamarre has quit [Quit: ylamarre]
_florent_ has quit [Quit: Leaving]
jaeckel has quit [Ping timeout: 246 seconds]
mumptai has quit [Ping timeout: 246 seconds]
cr1901_modern has joined #m-labs
mumptai has joined #m-labs
jaeckel has joined #m-labs
<rjo>
houh? in python the second (where if [] is valid) is "pythonic"
<whitequark>
oh
<whitequark>
I mixed these up.
<rjo>
assuming that 0-like and empty things are false seemed pythonic to me.
<rjo>
disentangling that with None is a different question.
<whitequark>
I read "< rjo> why would somebody prefer the 1st?" as if it was "the 2nd"
<whitequark>
hence the confusion.
<rjo>
so which is simpler?
<rjo>
still 2nd?
<whitequark>
what I just implemented, yes, slightly
<whitequark>
I can revert the behavior if you want
<rjo>
no. i like that boolean polymorphism.
<rjo>
you mixed it up again! ;)
<rjo>
"Require boolean operand in BoolOp" is the 1st in your enumeration above.
<whitequark>
gah
<whitequark>
okay, I'm even more confused
<whitequark>
can you check it out, try the expressions that you want, and want not, to be allowed, and say if this is the desired behavior?
<whitequark>
or just look at tests, that works too
<rjo>
let's define "Require boolean operand in BoolOp" as A and "allow 'if []' etc" as B
<whitequark>
ok
<rjo>
I like B and would consider it pythonic.
<whitequark>
ok, so that would mean reverting e21829c & 5d518dc
<rjo>
but if B is a significant amount of work, A is ok (+ good error message but it seems that you do that).
<whitequark>
no, not a significant amount of work
<rjo>
what are the current datatypes by the way? (float, int64, list, string)?
<rjo>
"const size list" and "const string".
<rjo>
and fraction.
<whitequark>
bool, arbitrary bit width int (width determined at compile time), float, homogeneous list (element type determined at compile time, list size determined at allocation time), range (range element type determined at compile time), closure, various exceptions, various types required for supporting built-in behavior such as polymorphic functions like print, int, bool, etc
<whitequark>
there is technically a str but you can't do anything with it except printing it
<whitequark>
there is no fraction right now
<rjo>
how can you determine the bit width of an integer type automatically at compile time?
<whitequark>
inference propagates it
<rjo>
through all expressions?
<whitequark>
most
<rjo>
if i keep multiplying an integer by two, will it want an infinite width integer? ;)
<whitequark>
no
<whitequark>
it's arbitrary, not variable
<whitequark>
in most code it will eventually anchor to a literal
<rjo>
but what does it do in that case?
<whitequark>
literals are 32-bit unless they don't fit into 32 bits, then they are 64-bit
<rjo>
how do i force 64bit ?
<whitequark>
x = int(0, width=64)
<rjo>
ok.
<whitequark>
x = int(0, width=48) also works.
<whitequark>
if you need that for something.
<whitequark>
there's nothing special about 32/64, except if you make it more than 128, it won't link.
<rjo>
ok. so then if i have "except ExceptionA, ExceptionB, ExceptionC" that is not a tuple? could i catch a list of exceptions?
<rjo>
(i don't know whether i can do that in cpython though).
<whitequark>
hrm
<rjo>
and i guess there is also no unpacking of arguments (*args)?
<whitequark>
there is no unpacking of arguments, but for a different reason
<rjo>
all these restrictions are fine. just probing the limits and trying to define them.
<whitequark>
that is, functions are neither monomorphized nor there is a unified value representation; thus, there is only one copy of a function translated to machine code
<whitequark>
so while I could give you *args, you could only ever pass a single set of argument types there
<whitequark>
which defeats the point, kinda
<rjo>
but i can pass a list (by reference)?
<rjo>
ack.
<whitequark>
it must be a tuple
<whitequark>
since arguments are heterogenous
<whitequark>
if you want a list, pass a list :p
<rjo>
a=[1,2,3]; f(a)
<whitequark>
sure.
<rjo>
is by reference, right?
<whitequark>
yes, like in Python.
<whitequark>
this compiler implements a strict subset of Python in every respect except integer arithmetic (which does not use bigints)
<whitequark>
so if something works in a particular way in Python, it will work the same way in ARTIQ, or die with a diagnostic at compile time.
<whitequark>
or it's a bug and has to be fixed
<rjo>
ok. so in APython (ARTIQ Python, lets define it). what will "f(0.); f(0)" do?
<whitequark>
unification error
<rjo>
ok. good.
<whitequark>
the first one will give the function the signature (float)->whatever
<whitequark>
assuming it has been polymorphic before (it probably was)
<whitequark>
so, it would be possible to give functions ML-style polymorphism with monomorphization
<whitequark>
so that if e.g.:
<whitequark>
def f(x): return x + 1
<whitequark>
f(0.) # => 1.
<whitequark>
f(0) # => 1
<whitequark>
but this is not done right now.
<whitequark>
a side effect would be that there would be a combinatorial explosion of sorts. the function will be copied for every set of argument types, if you look at machine code.
<whitequark>
essentially, this would be like C++ templates
<rjo>
nice. so. then "if a" will have to do implicitly "if bool(a)"?
mumptai has quit [Ping timeout: 244 seconds]
<whitequark>
no, if/while/bool() are intrinsically polymorphic
<whitequark>
they accept any type.
<rjo>
i meant "if a" would be implemented as "if bool(a)".
<whitequark>
these two will result in the same ARTIQ IR instruction sequence
<rjo>
ok.
<whitequark>
in essence, yes.
<rjo>
i guess that also means "if a" has no implications on the type of a during inferrence. while in the other case (A) if would infer bool for a?
<whitequark>
exactly
<rjo>
ack.
<whitequark>
this is generally undesirable, because it would cause a function that would otherwise have its type inferred locally to require some external constraint to have a fully inferred type
<rjo>
which one?
<whitequark>
anything that constraints the type of the condition
<whitequark>
e.g. if it was something like:
<whitequark>
def x(a): if a: do_whatever()
<whitequark>
you would need to call x(v) where v would have a defined type
<whitequark>
the `+` operator is a particularly bad case of the same, because the result type of `+` cannot be inferred at all unless the types of *both* arguments are known to at least some degree
<whitequark>
since its result type is the 'widest' of both arguments, where float is wider than int
<whitequark>
generally speaking, coercion as well as highly polymorphic constructs and inference mix extremely poorly
<whitequark>
OCaml has separate operators for "+ for integers", "+ for floats", "+ for fractions" etc
<whitequark>
Rust has typeclasses, which in this case guarantee that operand and return types are all the same
<whitequark>
both of them allow inference to flow across `+`, which is not possible in Python
<rjo>
i see. does APython require all types to be inferred at compile time?
<whitequark>
yes, since it does not have a unified data representation and thus cannot reserve storage for values whose types it does not know
<whitequark>
(`float` takes two times as much space as `int(width=32)`)
<rjo>
how does it know the return type of an rpc?
<rjo>
and polymorphism w.r.t the arguments of a kernel invokation will be implemented by recompiling the entire kernel?
<whitequark>
1) encoded in the name of RPC, I believe
<whitequark>
2) yes
<rjo>
is float() a double?
<whitequark>
yes, like in python
<rjo>
argh. personally if soft-fp is >=2 times faster for floats than for doubles, I would make float() be a float.
<rjo>
and deviate from CPython.
<whitequark>
that can be done
<rjo>
but not urgent.
<whitequark>
it's a one-line change...
<rjo>
i guess that change would not require a lot of coding
<rjo>
yes.
mumptai has joined #m-labs
<rjo>
but requires a benchmark ;)
<whitequark>
why doesn't it have hard-fp anyway
<rjo>
sb0 did not like the hard-fp (32 bit only iirc) in mor1kx ;)
<rjo>
if we do type annotations and track the dirtyness of the compilation context (pdb, AutoDB attributes) we could do quite some caching/pipelining of kernel compilation.
<whitequark>
I'll need to look more closely at the kernel interface
<whitequark>
the annoying part with caching is that it's pretty hard to clone typified ASTs
<whitequark>
since the type variables are a particularly nasty kind of mutable state
<whitequark>
so you could cache parsed text, which doesn't give you all that much, or IR, which is too late if you want to change any types
<rjo>
you mean hash() a hunk of ast?
<whitequark>
I mean don't reparse the kernels when all that's changed is some argument
<rjo>
i see. yes. caching might be tricky.
<whitequark>
inference is strictly O(n) so I'm not even sure if it will give any speedup over just re-infering
<rjo>
OTOH pipelining (overlapping execution and compilation/uploading) combined with fast kernel swaps should be good enough.
<whitequark>
we could certainly cache kernels once compiled
<rjo>
and making scans run in-kernel or having the kernel rpc the host for next().
<rjo>
yep.
<whitequark>
we could even cache separate APython modules
<whitequark>
(since it is designed so that as long as the signature stays constant, modules are interchangeable)
<rjo>
well. with a bit of type annotation that might be really smooth.
<rjo>
how does APython react to type annotations?
<whitequark>
it doesn't
<rjo>
room for improvement ;) but also later.
<whitequark>
Python's annotations are kind of fugly
<whitequark>
in the sense that they're executed when the def is evaluated
<whitequark>
should've put an AST in that slot.
<rjo>
in 3.4 they don't do anything, iirc? this is only 3.5, right?
<whitequark>
hum? annotations are there since 3.0
<rjo>
do they do anything?
<whitequark>
they execute and the result is stored into a slot of the function
<whitequark>
that is all. in CPython they will not ever do anything by design
<rjo>
i can do "def f(a:int): return a" and "f(0.) == 0."
<whitequark>
yep.
<rjo>
i had thought that they do something in 3.5.
<rjo>
there was some behavior people were talking about.