<jupyter_start><jupyter_text>NumPy under MinPy, with GPUThis part of tutorial is also available in step-by-step notebook version on [github](https://github.com/dmlc/minpy/blob/master/examples/tutorials/numpy_under_minpy.ipynb). Please try it out! Basic NDArray OperationMinPy has the same syntax as NumPy, which is the language of choice for numerical computing, and in particular deep learning. The popular [Stanford course cs231n](http://cs231n.stanford.edu/syllabus.html) uses NumPy as its main coursework. To use NumPy under MinPy, you only need to replace `import numpy as np` with `import minpy.numpy as np` at the header of your NumPy program. if you are not familiar with NumPy, you may want to look up [NumPy Quickstart Tutorial](https://docs.scipy.org/doc/numpy-dev/user/quickstart.html) for more details.Using NumPy under MinPy has two simple but important reasons, one for productivity and another for performance: 1) Auto-differentiation, and 2) GPU/CPU co-execution. We will discuss them in this tutorial.But first, let us review some of the most common usages of NumPy.  Array Creation An array can be created in multiple ways. For example, we can create an array from a regular Python list or tuple by using the `array` function<jupyter_code>import minpy.numpy as np

a = np.array([1,2,3])  # create a 1-dimensional array with a python list
b = np.array([[1,2,3], [2,3,4]])  # create a 2-dimensional array with a nested python list<jupyter_output><empty_output><jupyter_text>Here are some useful ways to create arrays with initial placeholder content.<jupyter_code>a = np.zeros((2,3))    # create a 2-dimensional array full of zeros with shape (2,3)  
b = np.ones((2,3))     # create a same shape array full of ones
c = np.full((2,3), 7)  # create a same shape array with all elements set to 7
d = np.empty((2,3))    # create a same shape whose initial content is random and depends on the state of the memory<jupyter_output><empty_output><jupyter_text>Basic OperationsArithmetic operators on arrays apply *elementwise*, with a new array holding result.<jupyter_code>a = np.ones((2,3))
b = np.ones((2,3))
c = a + b  # elementwise plus
d = - c    # elementwise minus
print(d)
e = np.sin(c**2).T  # elementwise pow and sin, and then transpose
print(e)
f = np.maximum(a, c)  # elementwise max
print(f)<jupyter_output>[[-2. -2. -2.]
 [-2. -2. -2.]]
[[-0.7568025 -0.7568025]
 [-0.7568025 -0.7568025]
 [-0.7568025 -0.7568025]]
[[ 2.  2.  2.]
 [ 2.  2.  2.]]<jupyter_text>Indexing and SlicingThe slice operator `[]` applies on axis 0.<jupyter_code>a = np.arange(6)
a = np.reshape(a, (3,2))
print(a[:])
# assign -1 to the 2nd row
a[1:2] = -1 
print(a)<jupyter_output>[[ 0.  1.]
 [ 2.  3.]
 [ 4.  5.]]
[[ 0.  1.]
 [-1. -1.]
 [ 4.  5.]]<jupyter_text>We can also slice a particular axis with the method `slice_axis`<jupyter_code># slice out the 2nd column
d = np.slice_axis(a, axis=1, begin=1, end=2)
print(d)<jupyter_output>[[ 1.]
 [-1.]
 [ 5.]]<jupyter_text>AutoGrad FeatureIf you work in a policy mode called `NumpyOnlyPolicy` (refer [here](https://minpy.readthedocs.io/en/latest/feature/policy.html) for more details), MinPy is almost compatible with the most of NumPy usages. But what makes MinPy awesome is that it give you the power of autograd, saving you from writing the most tedious and error prone part of deep net implementation:<jupyter_code>from minpy.core import grad

# define a function: f(x) = 5*x^2 + 3*x - 2
def foo(x):
    return 5*(x**2) + 3*x - 2

# f(4) = 90
print(foo(4))

# get the derivative function by `grad`: f'(x) = 10*x + 3
d_foo = grad(foo)

# f'(4) = 43.0
print(d_foo(4))<jupyter_output>90
43.0<jupyter_text>More details about this part can be found in [Autograd Tutorial](http://minpy.readthedocs.io/en/latest/tutorial/autograd_tutorial.html).  GPU SupportBut we do not stop here, we want MinPy not only friendly to use, but also fast. To this end, MinPy leverages GPU's parallel computing ability. The code below shows our GPU support and a set of API to make you freely to change the runnning context (i.e. to run on CPU or GPU). You can refer to [Select Context for MXNet](http://minpy.readthedocs.io/en/latest/feature/context.html) for more details.<jupyter_code>import minpy.numpy as np
import minpy.numpy.random as random
from minpy.context import cpu, gpu
import time

n = 100

with cpu():
    x_cpu = random.rand(1024, 1024) - 0.5
    y_cpu = random.rand(1024, 1024) - 0.5

    # dry run
    for i in xrange(10):
        z_cpu = np.dot(x_cpu, y_cpu)
    z_cpu.asnumpy()

    # real run
    t0 = time.time()
    for i in xrange(n):
        z_cpu = np.dot(x_cpu, y_cpu)
    z_cpu.asnumpy()
    t1 = time.time()

with gpu(0):
    x_gpu0 = random.rand(1024, 1024) - 0.5
    y_gpu0 = random.rand(1024, 1024) - 0.5

    # dry run
    for i in xrange(10):
        z_gpu0 = np.dot(x_gpu0, y_gpu0)
    z_gpu0.asnumpy()

    # real run
    t2 = time.time()
    for i in xrange(n):
        z_gpu0 = np.dot(x_gpu0, y_gpu0)
    z_gpu0.asnumpy()
    t3 = time.time()

print("run on cpu: %.6f s/iter" % ((t1 - t0) / n))
print("run on gpu: %.6f s/iter" % ((t3 - t2) / n))<jupyter_output>run on cpu: 0.100039 s/iter
run on gpu: 0.000422 s/iter
{'fraction_non_alphanumeric': 0.12173913043478261, 'fraction_numerical': 0.04483091787439614, 'mean_word_length': 3.73992673992674, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '46977', 'license': 'Apache-2.0', 'n_tokens_mistral': 1990, 'n_tokens_neox': 1853, 'n_words': 648, 'path': 'examples/tutorials/numpy_under_minpy.ipynb', 'repo_name': 'yuhonghong66/minpy', 'size': '5175'}