bksahu's Blog

Weekly Check-in #6

bksahu
Published: 08/14/2019

1. What did you do this week?

This week I added support for Python 3 <tt>zip()</tt> built-in and added git workflow in the developer manual which can be found here: https://github.com/Nuitka/Nuitka/pull/485.  And also worked on the remnants of Python 2 support for the same.

2. What is coming up next?

Now that support for keyword only arguments has been added in Nuitka, I will finish the remaining of optimizations support  for min() and max() built-ins.

3. Did you get stuck anywhere?

Yes, I was stuck on reformulation of zip() for Python2.

View Blog Post

Blog Post #5

bksahu
Published: 08/10/2019

Hi, welcome to my blog post #5!

Today we will see how are exception messages are displayed while working with Reformulations in Nuitka. The following is an example try block which is trying to assign iter() to the arguments if supported else throw an type error.

makeTryExceptSingleHandlerNode(
                tried=makeStatementsSequence(
                    statements=[
                        StatementAssignmentVariable(
                            variable=zip_iter_variable,
                            source=ExpressionBuiltinIter1(
                                value=ExpressionTempVariableRef(
                                    variable=zip_arg_variable, source_ref=source_ref
                                ),
                                source_ref=source_ref,
                            ),
                            source_ref=source_ref,
                        )
                        for i, zip_iter_variable, zip_arg_variable in zip(
                            range(len(call_args)), zip_iter_variables, zip_arg_variables
                        )
                    ],
                    allow_none=False,
                    source_ref=source_ref,
                ),
                exception_name="TypeError",
                handler_body=StatementRaiseException(
                    exception_type=ExpressionBuiltinExceptionRef(
                        exception_name="TypeError", source_ref=source_ref
                    ),
                    exception_value=makeConstantRefNode(
                        constant="zip argument #%d must support iteration" % (i + 1),
                        source_ref=source_ref,
                    ),
                    exception_trace=None,
                    exception_cause=None,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            )

You can see there that I'm calling create a StatementRaiseException with a template i.e "zip argument #%d must support iteration" in our case, which is basically to handle cases like for example: zip(1, [1,2,3]).

Thanks for reading

View Blog Post

Weekly Checkin #5

bksahu
Published: 08/01/2019

1. What did you do this week?

I'm still going on with zip reformulation and at the same time also working on the keyfun parameter of the min and max builtin. To be completely honest this week has not be that productive because I am studying for an upcoming exam. But I'm hoping to get back on track in a next couple of days.

2. What is coming up next?

I will keep working on both them until they are ready to be merged.

3. Did you get stuck anywhere?

Yes I was stuck with zip reformulations for a while but with the help of my mentor everything is back on track. 

View Blog Post

Blog Post #4

bksahu
Published: 07/22/2019

Hi, welcome to my 4th blog post !

Last time we saw how reformulations of `min` and `max` works. This time we will drive in how reformulation of `zip` (only in Py27) works. If I were to implement `zip` using Python 2 it were to look something like this:

def _zip(*iterables):
     # zip('ABCD', 'xy') --> Ax By
     # import ipdb; ipdb.set_trace()
     sentinel = object()
     iterators = [iter(it) for it in iterables]
     zipped = []
     for _ in xrange(len(iterators)):
         result = []
         for it in iterators:
             elem = next(it, sentinel)
             if elem is not sentinel:
                 result.append(elem)
         if len(result) == len(iterators):    
             zipped.append(tuple(result))
     return zipped

But on reformulation, some things need to be changed. We also have to take define new temp variables inside the scope and release it when we are done. One more major optimizations that we have to do is to use one loop instead to two loops as seen above. So, finally our reformulation pseudo-code will look something like this:

def _zip(a, b, c, ... ):
   # First assign, to preserve order of execution,
   # the arguments might be complex expressions.
   tmp_arg1 = a
   tmp_arg2 = b
   tmp_arg3 = c
   ...

   tmp_iter_1 = iter(tmp_arg1)
   tmp_iter_2 = iter(tmp_arg2)
   tmp_iter_3 = iter(tmp_arg3)
   ...

   # could be more
   tmp_result = []
   try:
       while 1:
           tmp_result.append(
               (
                    next(tmp_iter_1),
                    next(tmp_iter_2),
                    next(tmp_iter_3),
                    ...
               )
            )
      except StopIteration:
          pass

   return tmp_result

In this way we can optimize the zip nodes in Nuitka.

Thank you for reading :) 

View Blog Post

Optimizing "map" and "zip" - Weekly check in #4

bksahu
Published: 07/15/2019

1. What did you do this week?

This week I started up with optimizing "map" built-in but later realised that I first need to optimize "zip" as there is no support on Nuitka for it as "map" is dependent on it. Initially I implemented the C backend for Python2 "zip" function but after discussing with my mentor we decided to keep only C backend for Python3 "zip" and depend on re-formulation for Python2 "zip" built-in.

2. What is coming up next?

Next up I will optimize zip for Python 3 and then get back to optimize "map" built-in.

3. Did you get stuck anywhere?

Well, I wouldn't say I was stuck anywhere but I had a lot of discussions on developing an optimization approach for the built-in mentioned above. 

 

Thanks!

Batakrishna

View Blog Post