Thursday, 26 June 2014

Parallel Reduction in CUDA

Leave a Comment
Parallel Reduction, Parallel Reduction using shared memory CUDA

    Operations which are associative and commutative can be reduction operations some of them are addition, multiplication, bitwise AND/OR/XOR, logical AND/OR/XOR, finding maximum/minimum amongst a given set of numbers. Sequential computation complexity of these operation is over 'n' number of elements is O(n), whereas best theoretical parallel computation complexity can be O(log n). The code below implements parallel reduction in CUDA, here in this case we do addition of floating point array, providing near optimal implementation for arbitrary data sizes and thread block sizes taking transparent scalability into account using shared memory for facilitating faster access and reusing intermediate data.
    In case of any questions/clarifications related to this program, please post them in comment, I will be pleased to answer any queries pertaining to it.

 Parallel Reduction in CUDA

#include <cuda.h>
#include <stdio.h>
#include <stdlib.h>

#define BLOCK_SIZE 512 // You can change this
#define NUM_OF_ELEMS 4096 // You can change this

#define funcCheck(stmt) {                                            \
    cudaError_t err = stmt;                                          \
    if (err != cudaSuccess)                                          \
    {                                                                \
        printf( "Failed to run stmt %d ", __LINE__);                 \
        printf( "Got CUDA error ...  %s ", cudaGetErrorString(err)); \
        return -1;                                                   \
    }                                                                \

__global__  void total(float * input, float * output, int len) 
    // Load a segment of the input vector into shared memory
    __shared__ float partialSum[2*BLOCK_SIZE];
    int globalThreadId = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int t = threadIdx.x;
    unsigned int start = 2*blockIdx.x*blockDim.x;

    if ((start + t) < len)
        partialSum[t] = input[start + t];      
        partialSum[t] = 0.0;
    if ((start + blockDim.x + t) < len)
        partialSum[blockDim.x + t] = input[start + blockDim.x + t];
        partialSum[blockDim.x + t] = 0.0;

    // Traverse reduction tree
    for (unsigned int stride = blockDim.x; stride > 0; stride /= 2)
        if (t < stride)
            partialSum[t] += partialSum[t + stride];

    // Write the computed sum of the block to the output vector at correct index
    if (t == 0 && (globalThreadId*2) < len)
        output[blockIdx.x] = partialSum[t];

int main(int argc, char ** argv) 
    int ii;

    float * hostInput; // The input 1D vector
    float * hostOutput; // The output vector
    float * deviceInput;
    float * deviceOutput;

    int numInputElements = NUM_OF_ELEMS; // number of elements in the input list
    int numOutputElements; // number of elements in the output list
    hostInput = (float *) malloc(sizeof(float) * numInputElements);

    for (int i=0; i < NUM_OF_ELEMS; i++)
        hostInput[i] = 1.0;     // Add your input values

    numOutputElements = numInputElements / (BLOCK_SIZE<<1);
    if (numInputElements % (BLOCK_SIZE<<1)) 
    hostOutput = (float*) malloc(numOutputElements * sizeof(float));

    //@@ Allocate GPU memory here
    funcCheck(cudaMalloc((void **)&deviceInput, numInputElements * sizeof(float)));
    funcCheck(cudaMalloc((void **)&deviceOutput, numOutputElements * sizeof(float)));

    // Copy memory to the GPU here
    cudaMemcpy(deviceInput, hostInput, numInputElements * sizeof(float), cudaMemcpyHostToDevice);

    // Initialize the grid and block dimensions here
    dim3 DimGrid( numOutputElements, 1, 1);
    dim3 DimBlock(BLOCK_SIZE, 1, 1);

    // Launch the GPU Kernel here
    total<<<DimGrid, DimBlock>>>(deviceInput, deviceOutput, numInputElements);

    // Copy the GPU memory back to the CPU here
    cudaMemcpy(hostOutput, deviceOutput, numOutputElements * sizeof(float), cudaMemcpyDeviceToHost);

     * Reduce output vector on the host
    for (ii = 1; ii < numOutputElements; ii++) 
        hostOutput[0] += hostOutput[ii];

    printf("Reduced Sum from GPU = %f\n", hostOutput[0]);   

    // Free the GPU memory here

    return 0;

Monday, 23 June 2014

How to Pick Up Best Web Hosting Provider for Your Website?

Selecting a good web hosting provider is a tough task until you know the important aspects to consider while selecting one. Today, a huge number of providers offer you lucrative hosting packages that meet all your website requirements. However, one must still recognize what makes a hosting provider the best otherwise he would have to face lot of problems in future and change his web hosting frequently to get better service. Below mentioned are some of the points that will help you understand how to pick up best web hosting provider for your website.

Decide Your Hosting Requirements

To get an appropriate hosting provider you must first decide on your hosting requirements. Following is a set of questions you must answer to decide your hosing necessities.
  • What type of website are you building?
  • What would be the estimated traffic volume for your website?
  • Does your website need any special software?
The above question will help you understand the hosting plan you will select for your website. However, for newbie bloggers and Internet marketers, it’s often suggested to select a good shared hosting plan.
Server Uptime

One of the most important aspects while selecting a best web hosting is its uptime. Always see to it that the hosting you choose offers you an uptime of 99.5% and above. The uptime below this value is simply not recommended.

The server uptime also remains one of the crucial features when it comes to the search engine ranking. And hence, one must not compromise on this factor while selecting a best hosting provider for their website.

Available Options for Server Upgrades

You start your website small but eventually it grows big and you find yourself in a need for much larger hosting space and performance. Hence, it’s recommended to choose only those service providers that make you available an option for server upgrades. You can even apply coupon codes like Bluehost coupon codes for saving your money on web hosting.

As we said before, if you are a newbie blogger or an Internet marketer, shared hosting is fully sufficient to start with. However, as your business grows, your provider must help you in transferring from shared to VPS or dedicated servers.

Installing Applications

Ensure that your service provider supports several CMS applications. These days WordPress has become one of the prime content management systems. It helps the novice bloggers and marketers to setup their websites within minutes and start blogging the next moment.

Today, most web hosting service providers offer you single click installation option from their control panel. However, it’s safe to check previously if your provider supports installing these applications.

Security and Backup

Security is one of the essential factors when it comes to picking up the best web hosting provider for your website. One must check what security factors do their provider offers in order to ensure the safety of their website. Often, you will find details about the provider’s data centers, precautions taken and more on their website. Moreover, you can check for the SSLcertificate of the provider and also opt for the same for your website.

Backup is yet another important factor and one must confirm that their provider allows them to take backup of their data. Usually, everyone is allowed to take data backup however certain service providers put restriction on accessing the servers. Hence, it’s better to check before selecting a particular web hosting provider.

Technical Support

Since web hosting is a technical industry and not everyone is technically proficient, the provider must offer best technical support for their customer. An efficient customer support is one when you can reach your provider over phone, email or live chat.

Money Back Guarantee

Every service provider boasts of being the best. However, what if you face certain problems after opting for the service from a particular provider? Hence, one must ensure that their web hosting service providers offer them money back guarantee in case they do not like the services provided.

The above information covers all the essential aspects one must check while selecting a hosting provider. These points together will help you in picking up a best web hosting provider for your website. 

Saturday, 19 April 2014

Python is compiled language or interpreted language ?

Leave a Comment

So you can code into python with ease (kudos to its simplicity). So next is to go deep and learn more about decorators, __add__ method, __get__ method, and more exciting stuff, that's great. But when somebody (most probably in interviews) ask you what exactly is python, compiled or interpreted language? You stuck for some time and explain them (or try to explain) with some heck of technical terms. With my personal experience, Yes! people do get stuck in this question even if they can code smoothly in python (I personally did).
Therefore, I decided to sit and explore about it. With some understanding, I prefer simpler way to explain it to you.

Which Python?
Confused with question? Then you should read this article. We are going to consider CPython for this time (or it doesn't matter to understand concept here).

What is Python?
First thing you need to understand is python is not language (What the heck). Yes TRUE, its merely an interface for language developers. You may be aware of interface in Java or C#. As with interfaces, it gives you an abstraction about how particular functionality should work leaving implementation work for you (or for your class). In simple words it contains behavior that class will implement.
Being interpreted or compiled is not relative terms to interface rather it is related to implementation. So considering Python, which is merely an interface cannot be compiled or interpreted.
Rather, if you you ask, is Cpython compiled or interpreted ? We can say that its interpreted with some compilation (I know bit confusing but have patience for few more lines please).

You need to understand….

How your python code gets executed?
The python code you write is compiled into python bytecode, which creates file with extension .pyc. If compiles, again question is, why not compiled language.

Note that this isn't compilation in the traditional sense of the word. Typically, we’d say that compilation is taking a high-level language and converting it to machine code. But it is a compilation of sorts. Compiled in to intermediate code not into machine code (Hope you got it Now).

Back to the execution process, your bytecode, present in pyc file, created in compilation step, is then executed by appropriate virtual machines, in our case, the CPython VM (actually we call it interpreter, right?).

Execution of Python Code
So for Cpython, we can say that its interpreted language. Aha, So that made to confuse you as Python is an "interpreted language"(which in term True for Cpython, a most famous implementation of python).

So my pyc file contains cross platform code right?. Yes, your bytecode is cross platform but its version dependent ( python 2.x or 3.x).

Is .pyc created every time I run code?
Answer is No. Actually it depends on your modification in py file. The time-stamp (called as magic number) is used to validate whether .py file is changed or not, depending on that new pyc file is created. If pyc is of current code then it simply skips compilation step.

Basically the way the programs are run is always the same. The compiled code is interpreted. The way the programs are loaded differs. If there is a current pyc file, this is taken as the compiled version, so no compile step has to be taken before running the command. Otherwise the py file is read, the compiler has to compile it (which takes a little time) but then the compiled version in memory is interpreted just the same way as always.

Again Its all same for them also, all of them have a typical implementation strategy of producing bytecode first, then executing it via a VM/interpreter. Difference is only in VM they use. Jython use JVM where as Ironpython use CLR.

Is there any python compiler?
Now we are talking about compilers (according to above definition).You may have heard about PyPy it is JIT compiler for python code. Nuitka, is one of the notable compilers. Nuitka attempts to translate pure Python not into bytecode, but into machine code (via C++ compiler), while using libpython at run time. Another one is ShedSkin. It compiles implicitly statically typed Python to C++, stand-alone programs or extension modules.

    Hence, perfect answer to the question, Python is compiled language or interpreted language ?, It totally depends upon which python is in consideration?, After that you can proceed with further explanation as per python in consideration (mostly answer is interpreter), and you can explain the process to clarify. I hope this article helped you.


Sunday, 6 April 2014

Linux Filesystem Commands

Linux Filesystem simplified, Linux Filesystem Commands
df [options] [device name] : It displays the filesystem usage related information
-a : Displays all the filesystems
-i : Gives inode usage information
-h : Displays in human readable format. Shows quantified byte information

Example -:
$ df -a
Filesystem       1K-blocks    Used Available Use% Mounted on
/dev/sda1          7608792 2469924   4729320  35% /

proc                     0       0         0    - /proc
sysfs                    0       0         0    - /sys
none                     0       0         0    - /sys/fs/fuse/connections
none                     0       0         0    - /sys/kernel/debug
none                     0       0         0    - /sys/kernel/security
udev                244408       4    244404   1% /dev
devpts                   0       0         0    - /dev/pts
tmpfs               101288     772    100516   1% /run
none                  5120       0      5120   0% /run/lock
none                253216     124    253092   1% /run/shm
gvfs-fuse-daemon         0       0         0    - /home/mahesh/.gvfs
/dev/sr0             62658   62658         0 100% /media/VBOXADDITIONS_4.3.6_
du [options] [pattern]  :  Displays space usage on files and directories
-c : Displays grand total for all the arguments
-h : Displays in human readable format. Shows quantified byte information
Example -:
$ du -ahc
0 ./centos/6
8.0K ./centos
4.0K ./samplefile.txt
0 ./ubuntu/ub10
4.0K ./ubuntu
16K .
16K total

ls [options] [filepattern] : Lists out directories and file entries from the given pattern
-a : Displays all the files including . &  ..
-r : Lists all the files in directories recursively
-l : Displays long list consisting of permissions on each file and other details
-d : Lists directories and not their content
-x : Displays sorted list by extension of the file
-s : Sorts output according to file size
-u : Displays sorted list by the access time
Example -:
$ ls -la
total 160
drwxr-xr-x 20 mahesh mahesh  4096 Mar 24 00:00 .
drwxr-xr-x  3 root   root    4096 Mar  9 01:23 ..
-rw-r--r--  1 mahesh mahesh   220 Mar  9 01:23 .bash_logout
-rw-r--r--  1 mahesh mahesh  3486 Mar  9 01:23 .bashrc
drwx------ 14 mahesh mahesh  4096 Mar 24 00:00 .cache
drwx------ 10 mahesh mahesh  4096 Mar 24 00:11 .config
drwx------  3 mahesh mahesh  4096 Mar  9 01:36 .dbus
drwxr-xr-x  2 mahesh mahesh  4096 Mar 24 00:11 Desktop
-rw-r--r--  1 mahesh mahesh    25 Mar 23 19:50 .dmrc
drwxr-xr-x  2 mahesh mahesh  4096 Mar  9 01:36 Documents
drwxr-xr-x  2 mahesh mahesh  4096 Mar  9 01:36 Downloads
-rw-r--r--  1 mahesh mahesh  8445 Mar  9 01:23 examples.desktop
drwx------  3 mahesh mahesh  4096 Mar 23 19:51 .gconf
drwx------  4 mahesh mahesh  4096 Mar  9 01:37 .gnome2
-rw-rw-r--  1 mahesh mahesh   142 Mar 23 19:51 .gtk-bookmarks
dr-x------  2 mahesh mahesh     0 Mar 23 19:51 .gvfs
-rw-------  1 mahesh mahesh   724 Mar 23 19:51 .ICEauthority
drwxr-xr-x  3 mahesh mahesh  4096 Mar  9 01:36 .local
drwx------  3 mahesh mahesh  4096 Mar  9 01:37 .mission-control
drwx------  4 mahesh mahesh  4096 Mar 24 00:00 .mozilla
drwxr-xr-x  2 mahesh mahesh  4096 Mar  9 01:36 Music
drwxr-xr-x  2 mahesh mahesh  4096 Mar  9 01:36 Pictures
-rw-r--r--  1 mahesh mahesh   675 Mar  9 01:23 .profile
drwxr-xr-x  2 mahesh mahesh  4096 Mar  9 01:36 Public
drwx------  2 mahesh mahesh  4096 Mar 23 19:51 .pulse
-rw-------  1 mahesh mahesh   256 Mar  9 01:36 .pulse-cookie
drwxr-xr-x  2 mahesh mahesh  4096 Mar  9 01:36 Templates
drwxr-xr-x  2 mahesh mahesh  4096 Mar  9 01:36 Videos
-rw-------  1 mahesh mahesh    62 Mar 23 19:50 .Xauthority
-rw-------  1 mahesh mahesh 23406 Mar 24 02:44 .xsession-errors
-rw-------  1 mahesh mahesh 12494 Mar 16 15:11 .xsession-errors.old 

mkdir [options] [directory-name] : Creates a new directory by the given directory-name
-m : Sets file mode
-p  : Creates parent directories if it does not exists.
Example -:
$ mkdir testdir
The above command will create a directory named "testdir"

 touch [options] [pattern] : Updates the timestamp of a file, If the file does not exists by default options creates it.
-a : Changes the access time only
-c : Do not create the file
-t  : Give a timestamp to use instead of current time
Example -:
$ touch testfile.txt
Creates "testfile.txt" if it does not exists, else it only updates timestamp of the "testfile.txt".

shred [options] [file_pattern] : Enables to overwrite a file to hide its content, also allows to delete file data in secured manner.
-s : This followed by number of bytes, will shred those many bytes
-n : Number of pattern iterations to run
-z : Add a final overwrite with zero to hide shredding
-u : Truncate and remove the file after overwriting
 Example -:
$ shred file1.txt file2.txt
The above command will destroy file1.txt and file2.txt completely, so not be able to recover even using any recovery utilities

rm [options] [file_pattern] : Remove the file
-f : Force removal
-i : Prompt before removal of each file 
-r : Deletes directories and their contents recursively.
Example -:
$ rm -rf testdir
Removes forcefully and recursively all the files in "testdir" as well as removes "testdir" directory.

mv [options] [from_pattern] [to_file] : Move or Rename a file
-f  : Do not prompt before overwriting
-i  : Interactive, prompts before moving
-n : Do not overwrite an existing file
Example -:
$ mv old_name new_name
Above command renames the "old_name" file/directory to "new_name".
$ mv alphonso basket/mango
Moves a file to another directory and rename it:

tar [options] [tar_file] [pattern] : Creates, Extracts an archive.
-c  : Creates a new tar archive
-f  : Specify an tar archive file to use
-t  : List the contents
-v : Verbose mode
-x : Extracts the archive contents
-z : Compress/Decompress through gzip
-j : Compress/Decompress through bzip2
Example -:
$ tar -cvf techdarting-04-14.tar /home/techdarting/

cd [directory] : Change directory

chown [options]  [mode] [file_name] : Enables to change the ownership of a directory, file etc.
-R : Recursively change ownership.

chmod [options] [user] [file_name] :  Enables to change the permission of a file, directory, etc.
-R : Recursively change permissions


Monday, 24 March 2014

Hack The New Programming Language

Leave a Comment
Hack Programming Language,  Facebook Hack Programming Language
Any Programming language have 3 main features. Performance, Productivity and Generality. We always have to give up on one of the three. People always try to create a so called super-language which meets all three features and that leads to creation and modification of languages. Some other points that lead to creation of languages are,

  • People take ideas from different languages and combine them into a new languages.
  • Some features improved, Some added and some removed of existing language.
  • Programmers start using a language in a particular way, Language designers identify some usage patterns and introduce new abstractions to support that patterns.
  • Some languages are designed to support particular domains.
  • People thinks they can improve on existing products.

Now Facebook jump into programing language creation. Google is already into it. Google have developed GO (aka golang) and Dart Web programming language. Facebook have unveiled language called Hack (nothing to have with hacking). What made them go for Hack? Lets get deep into it to understand more about it.

What is Hack?

As said earlier, its programming language invented by Facebook(introduced on March 20, 2014, that too young). Hack is for the HipHop Virtual Machine (HHVM). Now what's that? In simplest context It is PHP execution engine and improvement. The HHVM is a machine designed to execute programs written in Hack and PHP. Its main motive is to increase speed of the PHP application. Hack is, in simpler terms, new version of PHP.

Why Hack?

I think point that would attract PHP developer is, it interoperates seamlessly with PHP. The highlighting point of the Hack is static typing. Ok, I know bit about static typing but Why and how does that matter.
  • Static Typing:
Static typing languages required to carefully define your variable types. Annoying to many developers right?(specially who do scripting like PHP which is dynamically typed). But where does it benefits. It requires fewer server to run your code and it’s easier to manage your code. Since typing itself gives you documentation you need for collaborative development. You no need to explain your code to other developers for its typing.  
So Hack provide static typing? YES and still Interoperate with PHP How? The answer is  gradual typing. It is both static and dynamic typing.(Now that make a sense).

Other Point to highlight about Hack are,
  • Generics:
It allows classes and methods to be parameterized, a type associated when a class is instantiated or a method is called.

  • Collections:
It enhances the experience of working with PHP arrays. Hack implemented some collection types such as, Vector, Map, Set, Pair.
There are few more features such as, Lambdas, Shapes, Type Aliasing, Async, Continuations, Override Attribute, Method Dispatch and few more.
Tested and Proven:

So next thing comes to mind, is it tested and proven? As Facebook stated, we had already implemented the code and "battle tested" it on a large portion of Facebook's site. So we can consider it safe and tested (If we believe what they stated).

PHP to Hack:

Running your PHP project as Hack (is it possible?). Hack provide some tools that will be used to convert your code into Hack. It is automated conversion while running on HHVM so you no need to be worried about other things than your logic.

Hack is creating buzz with some of the top software developer’s appreciation. But some do question about it being new language or update to PHP.

Sunday, 16 March 2014

Why different flavors of Python


Why different flavors of python, Python, Implementations of Python

    We always want different flavors in everything, don’t we? As they say varieties add spice to life. So python need not be exception to this. How many times have you wondered why there is python,Cpython, Jython, IronPython and many more .*ython, that is, these different flavors of python. Lets start understanding it.

1) Cpython:    The base of all these implementation is Cpython or more formally known as python (Yeah its True your Python is actually Cpython). Cpython is de-facto reference Python implementation. Some implementations may extend behavior or features in some aspects or re-implementations language that do not depend or interact with the CPython runtime core but reuses the standard library implementation of Cpython. Since Cpython is standard to implement python someone can implement it to be compiled or to be interpreted according to their requirements.
    It is written in C and is a bytecode interpreter. Your bytecode is executed on CPython Virtual Machine. That is why I used to say foolishly that Python is interpreted language which indirectly is True about Cpython not for all python variants. 
    Python website categories all other implementations  as Alternative Implementations(Rightly so).

2) Jython:    Jython,earlier known as Jpython (or known to be successor of Jpython) is an implementation of the Python programming language which is designed to run on the Java Platform. It has compiler which compiles your python code into Java bytecode. Stable releases of compatible python(latest) is still not available.
    But question is why we need Jython? Jython adds compatible libraries of python that are really helpful for developers(Now you have both java and Python libraries at one place, isn’t that great?) and make it more powerful language. You can look at this as a way to glue together and leverage an existing collection of class libraries. Some find syntax of python concise and quicker.
    For a instance you want to write HTTP GET request in java,how much code you have to right? and when you know urllib in python isn’t things get easier?

3) IronPython:    IronPython is another implementation of the Python targeting the .NET Framework. It is entirely written in C# and runs on .NET virtual machine(That is nothing but CLR). Again you can import C# classes into ironPython. IronPython can use the .NET Framework and Python libraries(again isn’t that great ), providing Python developers with the power of the .NET framework or providing .NET developers with power of scripting.
    Current version targets Python 2.7.There are some known compatibility issues with Cpython libraries.  

4) Pypy:    Pypy is actually bit different than other implementations its primary focus is to overcome drawbacks(so called) of python. It is a Python interpreter and just-in-time compiler. It is written in Python itself. Actually PyPy is written in a language called RPython, which is suitable for writing dynamic language interpreters (and not much else). RPython is a subset of Python and is itself written in Python. According to claims made by pypy its around 6 times faster than Python.
    While JIT is main goal, it also focuses on efficiency and compatibility with the original CPython interpreter. Its implementation is highly compatible with Cpython.
    There are many talks about pypy being the future of the languages. For some JIT may not that useful for small scripts with non-repeatable code. Lets wait and watch for more of Pypy, future is yet to come.

5) Stackless Python:    If you ever tried threading in python then you will understand what and why Stackless Python. Stackless Python is a reimplementation of traditional python and its key point is lightweight threading. You can say its branch of CPython supporting microthreads.
    Stackless python's key concept is tasklets which is nothing but tiny taks. It allows you to run hundreds of thousands of tasklets in a single main thread. Tasklets run independently on CPU and can communicate with other via Channels. Channel is sort of manager that take all the responsibility to control suspension and resuming of tasklets. You can also control scheduling of tasklets and not to mention serialization with pickle can be done for tasklets.
    Stackless is claimed to be completely compatible with Standard Python but some issue been reported when using with PyQT.

6) ActiveState ActivePython:    ActivePython is a CPython distribution by company named ActiveState. It is commercial implementation and is proprietary. Key points are support and reduced risk for commercial application and some additional modules(Haven't tried it yet).

7) Pythonxy:    Firstly its pronounced as Python x-y and mostly written as Python(X,Y). It is nothing but a scientific Python distribution. Python added with scientific and engineering related packages is your python(x,y). Its also includes Qt for GUI and Spyder IDE.
    Why use it when i can manulally install packages i will be needed. No doubt you can add any package to your python but what if dish is served to you ready made with these packages.

8) Portable Python:    How about having python language pre-configured,any time, any where,run directly from any USB storage device. It is what Portable python is. Its for Windows OS. You just need to extract it to your portable storage device.

9) Anaconda Python:    In short words you can say it is distribution for large-scale data processing, predictive analytics, and scientific computing. This implementation basically focuses large scale of data.

Some other names to mention here. Some of them are language bindings e.g. RubyPython  some are VMs e.g. Brython.

PyIMSL Studio
A commercial distribution for numerical analysis – free for non-commercial use
Enables writing C extensions for the Python easy,  calling C functions and declaring C types variables.
A bridge between the Ruby and Python interpreters. It embeds a running Python interpreter in the Ruby applications.
A portable scientific Python distribution for Windows. same as python(x,y)
Python 3000 (Py3k)
Its nothing but your Python 3
Conceptive PythonSDK
For development and deployment of desktop applications
Language bridge for Python and Objective-C.
Enthought Canopy
Commercial scientific python implementation.
Goal is to replace Javascript with Python, as the scripting language for web browsers. Python Vm written in JS. Python 3.
Combines all the advantages of Qt and Python.


Author :

Amit Khomane