
Hello, Chritian Tismer wrote:
If we teach the specializer to not crash if something does not work out, but to add the problem blocks to a list, then we could have one report with all pending problems and work through this in a more general way. We also would get an estimate how much has still to be done.
That's what I have done to follow the fantastic progress you make on the translation process. - In rtyper.py, there is already a crash_on_first_typeerror variable. Turn it to False, this will catch all TyperErrors. - There are some assertions and other exceptions that will stop the process. I changed all of them into TyperErrors. I suppose that some tests are not done at the right place, but they do the job... And the specialization goes to the end! There are 81 TyperErrors left for 20206 blocks. They were 230 last week. Good job! Then the "Back-end optimizations" fail, probably because of the incompletely specialized blocks. I hope this helps! Here are my diffs: Index: pypy/rpython/rstr.py =================================================================== --- pypy/rpython/rstr.py (revision 14755) +++ pypy/rpython/rstr.py (working copy) @@ -264,7 +264,8 @@ if curstr: r.append(curstr) curstr = '' - assert f in 'xdsrf' + if f not in 'xdsrf': + raise TyperError("String format not supported: %r" % (f,)) r.append((f,)) else: @@ -295,6 +296,9 @@ vitem, r_arg = argsiter.next() rep = inputconst(Void, r_arg) if code == 's' or (code == 'r' and isinstance(r_arg, InstanceRepr)): + if not hasattr(r_arg,'ll_str'): + raise TyperError("AttributeError: %s instance has no attribute 'll_str'" + % r_arg) vchunk = hop.gendirectcall(r_arg.ll_str, vitem, rep) elif code == 'd': assert isinstance(r_arg, IntegerRepr) Index: pypy/rpython/callparse.py =================================================================== --- pypy/rpython/callparse.py (revision 14755) +++ pypy/rpython/callparse.py (working copy) @@ -2,6 +2,7 @@ from pypy.interpreter.argument import Arguments, ArgErr from pypy.annotation import model as annmodel from pypy.rpython import rtuple +from pypy.rpython.rmodel import TyperError class CallPatternTooComplex(Exception): pass @@ -47,7 +48,7 @@ try: holders = arguments.match_signature(signature, defs_h) except ArgErr, e: - raise TypeError, "signature mismatch: %s" % e.getmsg(arguments, func.__name__) + raise TyperError, "signature mismatch: %s" % e.getmsg(arguments, func.__name__) assert len(holders) == len(rinputs), "argument parsing mismatch" vlist = [] Index: pypy/rpython/rbuiltin.py =================================================================== --- pypy/rpython/rbuiltin.py (revision 14755) +++ pypy/rpython/rbuiltin.py (working copy) @@ -107,9 +107,15 @@ def rtype_builtin_unichr(hop): assert hop.nb_args == 1 + if not hasattr(hop.args_r[0],'rtype_unichr'): + raise TyperError("AttributeError: %s instance has no attribute 'rtype_unichr'" + % hop.args_r[0]) return hop.args_r[0].rtype_unichr(hop) def rtype_builtin_list(hop): + if not hasattr(hop.args_r[0],'rtype_bltn_list'): + raise TyperError("AttributeError: %s instance has no attribute 'rtype_bltn_list'" + % hop.args_r[0]) return hop.args_r[0].rtype_bltn_list(hop) def rtype_builtin_isinstance(hop): Index: pypy/rpython/rtyper.py =================================================================== --- pypy/rpython/rtyper.py (revision 14755) +++ pypy/rpython/rtyper.py (working copy) @@ -31,7 +31,7 @@ log = py.log.Producer("rtyper") py.log.setconsumer("rtyper", None) -crash_on_first_typeerror = True +crash_on_first_typeerror = False class RPythonTyper: @@ -45,6 +45,7 @@ self.pbc_reprs = {} self.class_pbc_attributes = {} self.typererror = None + self.nb_typeerrors = 0 # make the primitive_to_repr constant mapping self.primitive_to_repr = {} for s_primitive, lltype in annmodel.annotation_to_ll_map: @@ -138,8 +139,8 @@ n = len(self.already_seen) if n % 100 == 0: total = len(self.annotator.annotated) - print 'specializing: %d / %d blocks (%d%%)' % ( - n, total, 100 * n // total) + print 'specializing: %d / %d blocks (%d%%, %d errors)' % ( + n, total, 100 * n // total, self.nb_typeerrors) # make sure all reprs so far have had their setup() called self.call_all_setups() @@ -200,7 +201,11 @@ def specialize_block(self, block): # give the best possible types to the input args - self.setup_block_entry(block) + try: + self.setup_block_entry(block) + except TyperError, e: + self.gottypererror(e, block, "block entry", None) + return # cannot continue this block # specialize all the operations, as far as possible if block.operations == (): # return or except block @@ -269,8 +274,9 @@ new_a1 = newops.convertvar(a1, r_a1, r_a2) except TyperError, e: self.gottypererror(e, block, link, newops) - if new_a1 != a1: - newlinkargs[i] = new_a1 + else: + if new_a1 != a1: + newlinkargs[i] = new_a1 if newops: if can_insert_here: @@ -343,13 +349,16 @@ """Record a TyperError without crashing immediately. Put a 'TyperError' operation in the graph instead. """ + self.nb_typeerrors += 1 e.where = (block, position) if crash_on_first_typeerror: raise + print "*** TyperError:",e if self.typererror is None: self.typererror = sys.exc_info() c1 = inputconst(Void, Exception.__str__(e)) - llops.genop('TYPER ERROR', [c1], resulttype=Void) + if llops: + llops.genop('TYPER ERROR', [c1], resulttype=Void) # __________ regular operations __________ @@ -377,7 +386,12 @@ def translate_op_contains(self, hop): r_arg1 = hop.args_r[0] r_arg2 = hop.args_r[1] - return pair(r_arg1, r_arg2).rtype_contains(hop) + p = pair(r_arg1, r_arg2) + try: + f = p.rtype_contains + except AttributeError,e: + raise TyperError(str(e)) + return f(hop) # __________ irregular operations __________ -- Amaury Forgeot d'Arc Ubix Development www.ubitrade.com

amaury.forgeotdarc@ubitrade.com wrote:
Hello,
Chritian Tismer wrote:
If we teach the specializer to not crash if something does not work out, but to add the problem blocks to a list, then we could have one report with all pending problems and work through this in a more general way. We also would get an estimate how much has still to be done.
That's what I have done to follow the fantastic progress you make on the translation process.
- In rtyper.py, there is already a crash_on_first_typeerror variable. Turn it to False, this will catch all TyperErrors.
- There are some assertions and other exceptions that will stop the process. I changed all of them into TyperErrors. I suppose that some tests are not done at the right place, but they do the job...
And the specialization goes to the end! There are 81 TyperErrors left for 20206 blocks. They were 230 last week. Good job!
Then the "Back-end optimizations" fail, probably because of the incompletely specialized blocks.
I hope this helps! Here are my diffs:
thanks a lot for suggesting and trying this out. I will try out a variation on the patch. The hook should then be useful to reproduce in a direct and mostly deterministic way the problems.
Index: pypy/rpython/rstr.py =================================================================== --- pypy/rpython/rstr.py (revision 14755) +++ pypy/rpython/rstr.py (working copy) @@ -264,7 +264,8 @@ if curstr: r.append(curstr) curstr = '' - assert f in 'xdsrf' + if f not in 'xdsrf': + raise TyperError("String format not supported: %r" % (f,))
r.append((f,)) else: @@ -295,6 +296,9 @@ vitem, r_arg = argsiter.next() rep = inputconst(Void, r_arg) if code == 's' or (code == 'r' and isinstance(r_arg, InstanceRepr)): + if not hasattr(r_arg,'ll_str'): + raise TyperError("AttributeError: %s instance has no attribute 'll_str'" + % r_arg) vchunk = hop.gendirectcall(r_arg.ll_str, vitem, rep) elif code == 'd': assert isinstance(r_arg, IntegerRepr) Index: pypy/rpython/callparse.py =================================================================== --- pypy/rpython/callparse.py (revision 14755) +++ pypy/rpython/callparse.py (working copy) @@ -2,6 +2,7 @@ from pypy.interpreter.argument import Arguments, ArgErr from pypy.annotation import model as annmodel from pypy.rpython import rtuple +from pypy.rpython.rmodel import TyperError
class CallPatternTooComplex(Exception): pass @@ -47,7 +48,7 @@ try: holders = arguments.match_signature(signature, defs_h) except ArgErr, e: - raise TypeError, "signature mismatch: %s" % e.getmsg(arguments, func.__name__) + raise TyperError, "signature mismatch: %s" % e.getmsg(arguments, func.__name__)
assert len(holders) == len(rinputs), "argument parsing mismatch" vlist = [] Index: pypy/rpython/rbuiltin.py =================================================================== --- pypy/rpython/rbuiltin.py (revision 14755) +++ pypy/rpython/rbuiltin.py (working copy) @@ -107,9 +107,15 @@
def rtype_builtin_unichr(hop): assert hop.nb_args == 1 + if not hasattr(hop.args_r[0],'rtype_unichr'): + raise TyperError("AttributeError: %s instance has no attribute 'rtype_unichr'" + % hop.args_r[0]) return hop.args_r[0].rtype_unichr(hop)
def rtype_builtin_list(hop): + if not hasattr(hop.args_r[0],'rtype_bltn_list'): + raise TyperError("AttributeError: %s instance has no attribute 'rtype_bltn_list'" + % hop.args_r[0]) return hop.args_r[0].rtype_bltn_list(hop)
def rtype_builtin_isinstance(hop): Index: pypy/rpython/rtyper.py =================================================================== --- pypy/rpython/rtyper.py (revision 14755) +++ pypy/rpython/rtyper.py (working copy) @@ -31,7 +31,7 @@
log = py.log.Producer("rtyper") py.log.setconsumer("rtyper", None) -crash_on_first_typeerror = True +crash_on_first_typeerror = False
class RPythonTyper:
@@ -45,6 +45,7 @@ self.pbc_reprs = {} self.class_pbc_attributes = {} self.typererror = None + self.nb_typeerrors = 0 # make the primitive_to_repr constant mapping self.primitive_to_repr = {} for s_primitive, lltype in annmodel.annotation_to_ll_map: @@ -138,8 +139,8 @@ n = len(self.already_seen) if n % 100 == 0: total = len(self.annotator.annotated) - print 'specializing: %d / %d blocks (%d%%)' % ( - n, total, 100 * n // total) + print 'specializing: %d / %d blocks (%d%%, %d errors)' % ( + n, total, 100 * n // total, self.nb_typeerrors) # make sure all reprs so far have had their setup() called self.call_all_setups()
@@ -200,7 +201,11 @@
def specialize_block(self, block): # give the best possible types to the input args - self.setup_block_entry(block) + try: + self.setup_block_entry(block) + except TyperError, e: + self.gottypererror(e, block, "block entry", None) + return # cannot continue this block
# specialize all the operations, as far as possible if block.operations == (): # return or except block @@ -269,8 +274,9 @@ new_a1 = newops.convertvar(a1, r_a1, r_a2) except TyperError, e: self.gottypererror(e, block, link, newops) - if new_a1 != a1: - newlinkargs[i] = new_a1 + else: + if new_a1 != a1: + newlinkargs[i] = new_a1
if newops: if can_insert_here: @@ -343,13 +349,16 @@ """Record a TyperError without crashing immediately. Put a 'TyperError' operation in the graph instead. """ + self.nb_typeerrors += 1 e.where = (block, position) if crash_on_first_typeerror: raise + print "*** TyperError:",e if self.typererror is None: self.typererror = sys.exc_info() c1 = inputconst(Void, Exception.__str__(e)) - llops.genop('TYPER ERROR', [c1], resulttype=Void) + if llops: + llops.genop('TYPER ERROR', [c1], resulttype=Void)
# __________ regular operations __________
@@ -377,7 +386,12 @@ def translate_op_contains(self, hop): r_arg1 = hop.args_r[0] r_arg2 = hop.args_r[1] - return pair(r_arg1, r_arg2).rtype_contains(hop) + p = pair(r_arg1, r_arg2) + try: + f = p.rtype_contains + except AttributeError,e: + raise TyperError(str(e)) + return f(hop)
# __________ irregular operations __________
-- Amaury Forgeot d'Arc Ubix Development www.ubitrade.com
_______________________________________________ pypy-dev@codespeak.net http://codespeak.net/mailman/listinfo/pypy-dev
participants (2)
-
amaury.forgeotdarcīŧ ubitrade.com
-
Samuele Pedroni