• Home
  • About
    • Piyush Raikwar photo

      Piyush Raikwar

      Sophomore at ABV-IIITM, Gwalior, India

    • Learn More
    • Email
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Getting Started..

10 Jun 2019

Reading time ~4 minutes

Hey! So, this is the second blog-post in my series of GSoC experience. In this post I’ll be sharing what I did, what difficulties I came across in the first two weeks of Phase-1.

Actually, I had a pretty great start! I came to know the awesomeness of Python. I learnt many things, from Python internals to unittests. Also some git and GitHub things were a new experience to me. Time passed by and I did not even realize it.

First week

Python Magic Methods

First week of my coding period was all about trial and error. I got to learn many things regarding Python internals. I played with __dir__, __dict__ and many more. These also included Python magic methods such as __getattr__, __getattribute__, __setattr__. These methods are super cool. They let you hack your way into Python internals. Python is such an awesome language!

I tried many different implementations to achieve the goal of capturing attributes. It was very easy to catch just one attribute i.e, capturing numpy.ones, numpy.compress was easy. But to take this work to next level was quite troublesome. It was needed for catching functions like numpy.linalg.norm which included sub-modules of NumPy between them. I struggled with this a lot. I also tried using __setattr__ while exploring whole NumPy directory. But that lead to recursion error because of many sub-modules of NumPy having cyclic dependencies.

Second week

After trying many ideas, I finally got it to work. I implemented a class Recursive_attr which had __getattr__ working in recursion to catch attributes and storing them in a list. This also worked out quite well for functions such as numpy.linalg.norm which contained a sub-module.

I then had to implement a way to catch *args and **kwargs passed to the function. It was easy. Then I had to implement a way to search for method using previously prepared list in both CuPy and NumPy. And then calling that method with captured *args, **kwargs and by performing necessary data transfers from GPU to CPU and back to GPU after getting result. Then finally returning the result. I tested several functions with it. It seemed to work really well!

In this process I learnt many things including Python’s awesome memory allocation methods, automatic garbage collection and Python giving same ids to special immutable objects. How cool is that!

Summary

I implemented following classes/methods during this period. It’s in PR #2229.

  • class Recursive_attr
  • class FallbackUtil
  • class Fallback
  • method call_cupy
  • method call_numpy
  • method ram2vram
  • method vram2ram

Currently all basic methods for fallback_mode has been implemented. There is still much left for improvement and some bug fixes. Still it’s able to show following behavior.

>>> from cupy.fallback_mode import numpy
>>> numpy.ones((3,4)) # calling function in cupy
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
>>> x = numpy.array([1,2,3,4])
>>> type(x)
<class cupy.core.core.ndarray>
>>> numpy.argmin(x) # calling function in cupy
array(0, dtype=int64)
>>> type(numpy.argmin(x))
<class cupy.core.core.ndarray>
>>> x = numpy.array([float(nan),2,3,4])
>>> numpy.nanargmin(x) # calling function not in cupy
Attribute nanargmin not found in cupy. falling back to numpy
1
>>> numpy.linalg() # requesting module in cupy
<module cupy.linalg from \lib\\site-packages\\cupy\\linalg\\__init__.py>
>>> numpy.matrixlib() # requesting module not in cupy
Attribute matrixlib not found in cupy. falling back to numpy
<module numpy.matrixlib from \lib\\site-packages\\numpy\\matrixlib\\__init__.py>
>>>

Future work

Future work will consist of preparing tests for fallback_mode. Plus, there are some improvements and bug fixes planned after discussing with mentor. These includes:

  • Good class structure for fallback_mode. Probably combining Fallback class and Recursive_attr class.
  • Requesting NumPy/CuPy modules without calling.
  • Raising TypeError if module is called.
  • Handling of NumPy scalars such as numpy.nan, numpy.pi etc.
  • Adding __repr__ in Recursive_attr class.
  • Bringing behaviour of fallback_mode closer to actual NumPy/CuPy.


gsoccupy Share Tweet +1