Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 162 additions & 110 deletions recipes/numojo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,51 @@

![logo](./image.jpeg)

NuMojo is a library for numerical computing in Mojo 🔥 similar to NumPy, SciPy in Python.
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![Mojo](https://img.shields.io/badge/mojo-%3E%3D1.0.0-orange.svg)](https://www.modular.com/mojo)

**[Explore the docs»](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo-Examples-and-Benchmarks/blob/main/docs/README.md)** | **[Changelog»](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/docs/changelog.md)** | **[Check out our Discord»](https://discord.gg/NcnSH5n26F)**
NuMojo is a library for numerical computing in Mojo 🔥, similar to NumPy in Python.

**[中文·简»](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/docs/readme_zhs.md)** | **[中文·繁»](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/docs/readme_zht.md)** | **[日本語»](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/docs/readme_jp.md)**
**[Explore the examples»](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo-Examples-and-Benchmarks/blob/main/docs/README.md)** | **[Changelog»](docs/user-guide/changelog.md)** | **[Check out our Discord»](https://discord.gg/NcnSH5n26F)**

**[中文·简»](docs/getting-started/readme_zhs.md)** | **[中文·繁»](docs/getting-started/readme_zht.md)** | **[日本語»](docs/getting-started/readme_jp.md)** | **[한국어»](docs/getting-started/readme_kr.md)**

**Table of Contents**

1. [About The Project](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#about-the-project)
2. [Goals](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#goals)
3. [Usage](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#usage)
4. [How to install](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#how-to-install)
5. [Contributing](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#contributing)
6. [Warnings](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#warnings)
7. [License](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#license)
8. [Acknowledgements](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#acknowledgments)
9. [Contributors](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/README.MD#Contributors)
1. [About the project](#about-the-project)
2. [Why NuMojo](#why-numojo)
3. [Features and goals](#features-and-goals)
4. [Usage](#usage)
5. [Installation](#installation)
6. [Contributing](#contributing)
7. [Warnings](#warnings)
8. [License](#license)
9. [Acknowledgements](#acknowledgements)
10. [Contributors](#contributors)

## About the project

NuMojo aims to encompass the extensive numerics capabilities found in Python packages such as NumPy, SciPy, and Scikit-learn.

=======
NuMojo aims to encompass the extensive numerics capabilities found in NumPy.

***What NuMojo is***
**What NuMojo is**

We seek to harness the full potential of Mojo, including vectorization, parallelization, and GPU acceleration (when available). Currently, NuMojo extends most (if not all) standard library math functions to support array inputs.
We seek to harness the full potential of Mojo, including vectorization, parallelization, and GPU acceleration. Currently, NuMojo extends most (if not all) standard library math functions to support array inputs.

Our vision for NuMojo is to serve as an essential building block for other Mojo packages needing fast math operations, without the additional weight of a machine learning back-propagation system.
Our vision for NuMojo is to serve as a familiar and essential building block for other Mojo libraries needing fast math operations, without the additional weight of a machine learning back-propagation system.

***What NuMojo is not***
## Why NuMojo

NuMojo is not a machine learning library and will never include back-propagation as part of the base library.
- **Native to Mojo.** NuMojo's `NDArray` is a Mojo-native SIMD-backed type, not a binding around NumPy or MAX's tensor types, so it compiles into your program with no Python interop overhead.
- **NumPy-familiar API.** Slicing, broadcasting, `@` for matrix multiplication, and function names mirror NumPy where it makes sense, so existing intuition carries over.
- **Built for Mojo's strengths.** Vectorization and parallelism are used throughout the routines, with GPU and other accelerator support (`AcceleratorNDArray`) landing as Mojo's own device support matures.

## Features and goals

Our primary objective is to develop a fast, comprehensive numerics library in Mojo. Below are some features and long-term goals. Some have already been implemented, either fully or partially.
Our primary objective is to develop a fast, comprehensive numerics library in Mojo. Below are some features and long-term goals. Some have already been implemented (fully or partially).

Core data types:

- Native n-dimensional array (`numojo.NDArray`).
- Native 2-dimensional array, i.e., matrix (`numojo.Matrix`).
- Native n-dimensional complex array (`numojo.ComplexNDArray`)
- Native fixed-dimension array (to be implemented when trait parameterization is available).

Expand All @@ -64,22 +67,22 @@ Routines and objects:
- Statistics (`numojo.statistics`)
- etc...

Please find all the available functions and objects [here](docs/features.md).

For a detailed roadmap, please refer to the [docs/roadmap.md](docs/roadmap.md) file.
Please find all the available functions and objects [here](docs/user-guide/features.md). A living roadmap is maintained in [docs/user-guide/roadmap.md](docs/user-guide/roadmap.md).

## Usage

Runnable examples are available in `examples/` (e.g., `examples/quickstart.mojo`).

An example of n-dimensional array (`NDArray` type) goes as follows.

```mojo
import numojo as nm
from numojo.prelude import *


fn main() raises:
def main() raises:
# Generate two 1000x1000 matrices with random float64 values
var A = nm.random.randn(Shape(1000, 1000))
var A = nm.random.randn(Shape(1000, 1000)) # Shape is used for all shape related operations in numojo.
var B = nm.random.randn(Shape(1000, 1000))

# Generate a 3x2 matrix from string representation
Expand All @@ -98,75 +101,37 @@ fn main() raises:
var A_slice = A[1:3, 4:19]

# Get scalar from array
var A_item = A[item(291, 141)]
var A_item = A[Item(291, 141)] # Item() is used to define coordinates of an ndarray in numojo.
var A_item_2 = A.item(291, 141)
```

An example of matrix (`Matrix` type) goes as follows.

```mojo
from numojo import Matrix
from numojo.prelude import *


fn main() raises:
# Generate two 1000x1000 matrices with random float64 values
var A = Matrix.rand(shape=(1000, 1000))
var B = Matrix.rand(shape=(1000, 1000))

# Generate 1000x1 matrix (column vector) with random float64 values
var C = Matrix.rand(shape=(1000, 1))

# Generate a 4x3 matrix from string representation
var F = Matrix.fromstring[i8](
"[[12,11,10],[9,8,7],[6,5,4],[3,2,1]]", shape=(4, 3)
)

# Matrix slicing
var A_slice = A[1:3, 4:19]
var B_slice = B[255, 103:241:2]

# Get scalar from matrix
var A_item = A[291, 141]

# Flip the column vector
print(C[::-1, :])

# Sort and argsort along axis
print(nm.sort(A, axis=1))
print(nm.argsort(A, axis=0))

# Sum the matrix
print(nm.sum(B))
print(nm.sum(B, axis=1))
# Sum along axis
print(nm.sum(A))
print(nm.sum(A, axis=1))

# Matrix multiplication
print(A @ B)

# Matrix inversion
print(A.inv())

# Solve linear algebra
# Solve a linear system
print(nm.solve(A, B))

# Least square
print(nm.lstsq(A, C))
```

An example of ComplexNDArray is as follows,
An example of `ComplexNDArray` is as follows:

```mojo
import numojo as nm
from numojo.prelude import *


fn main() raises:
# Create a complexscalar 5 + 5j
var complexscalar = ComplexSIMD[cf32](re=5, im=5)
# Create complex array filled with (5 + 5j)
var A = nm.full[cf32](Shape(1000, 1000), fill_value=complexscalar)
# Create complex array filled with (1 + 1j)
var B = nm.ones[cf32](Shape(1000, 1000))
def main() raises:
# Create a complex scalar 5 + 5j
# cf32 is the complex version of f32 (DType.float32) used to identify complex types in numojo.
var complexscalar = CScalar[cf32](5) # Equivalently ComplexSIMD[cf32](5, 5)
# Also can be define as simple as 5 + 5*`1j`!

# Create complex arrays
var A = nm.full[cf32](Shape(1000, 1000), fill_value=complexscalar) # filled with (5+5j)
var B = nm.ones[cf32](Shape(1000, 1000)) # filled with (1+1j)

# Print array
print(A)
Expand All @@ -178,70 +143,157 @@ fn main() raises:
var C = A * B

# Get scalar from array
var A_item = A[item(291, 141)]
var A_item = A[Item(291, 141)]
# Set an element of the array
A[item(291, 141)] = complexscalar
```

## How to install
## Installation

There are three approach to install and use the Numojo package.
NuMojo offers several installation methods to suit different development needs. Choose the method that best fits your workflow:

### Use pixi CLI
### Method 1: Git Installation with pixi-build-mojo (Recommended)

You can use the following command in the terminal to install `numojo`.
Install NuMojo directly from the GitHub repository to access both stable releases and cutting-edge features. This method is perfect for developers who want the latest functionality or need to work with the most recent stable version.

Add the following to your existing `pixi.toml`:

```toml
[workspace]
preview = ["pixi-build"]

```console
pixi add numojo
[package]
name = "your_project_name"
version = "0.1.0"

[package.build]
backend = {name = "pixi-build-mojo", version = "0.*"}

[package.build.config.pkg]
name = "your_package_name"

[package.host-dependencies]
mojo = "==1.0.0"
max-core = "==26.5.0"

[package.build-dependencies]
mojo = "==1.0.0"
max-core = "==26.5.0"
numojo = { git = "https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo", branch = "main"}

[package.run-dependencies]
mojo = "==1.0.0"
max-core = "==26.5.0"
numojo = { git = "https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo", branch = "main"}

[dependencies]
mojo = ">=1.0.0, <1.1.0"
max-core = ">=26.5.0,<27"
numojo = { git = "https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo", branch = "main"}
```

Then run:
```bash
pixi install
```

### Add in toml file
**Branch Selection:**
- **`main` branch**: Provides the latest stable release. Currently NuMojo v0.10.0, compatible with Mojo >=1.0.0, <1.1.0. For earlier NuMojo versions, use Method 2.
- **`pre-x.y` branches**: Active development branch for the next release. Note that this branch receives frequent updates and may have breaking changes in features and syntax.

The package will be automatically available in your Pixi environment, and VSCode LSP will provide intelligent code hints.

### Method 2: Stable Release via Pixi (prefix.dev)

For most users, we recommend installing a stable release through Pixi for guaranteed compatibility and reproducibility.

You can add `pixi` in the dependencies section of your toml file.
Add the following to your `pixi.toml` file:

```toml
[workspace]
channels = ["https://repo.prefix.dev/modular-community"]

[dependencies]
pixi = "==0.7.0"
numojo = "=0.10.0"
```

### Build package
Then run:
```bash
pixi install
```

This approach involves building a standalone package file `mojopkg`.
**Version Compatibility:**

1. Clone the repository.
2. Build the package using `pixi run package`.
3. Move the `numojo.mojopkg` into the directory containing the your code.
| NuMojo Version | Required Mojo Version |
| -------------- | --------------------- |
| v0.10.0 | ==1.0.0 |
| v0.9.0 | ==26.2 |
| v0.8.0 | ==25.7 |
| v0.7.0 | ==25.3 |
| v0.6.1 | ==25.2 |
| v0.6.0 | ==25.2 |

### Include NuMojo's path for compiler and LSP
### Method 3: Build Standalone Package

This approach does not require building a package file. Instead, when you compile your code, you can include the path of NuMojo repository with the following command:
This method creates a portable `numojo.mojopkg` file that you can use across multiple projects, perfect for offline development or hermetic builds.

```console
mojo run -I "../NuMojo" example.mojo
```
1. Clone the repository:
```bash
git clone https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo.git
cd NuMojo
```

2. Build the package:
```bash
pixi run package
```

3. Copy `numojo.mojopkg` to your project directory or add its parent directory to your include paths.

### Method 4: Direct Source Integration

This is more flexible as you are able to edit the NuMojo source files when testing your code.
For maximum flexibility and the ability to modify NuMojo source code during development:

In order to allow VSCode LSP to resolve the imported `numojo` package, you can:
1. Clone the repository to your desired location:
```bash
git clone https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo.git
```

1. Go to preference page of VSCode.
2. Go to `Mojo › Lsp: Include Dirs`
3. Click `add item` and write the path where the Numojo repository is located, e.g. `/Users/Name/Programs/NuMojo`.
4. Restart the Mojo LSP server.
2. When compiling your code, include the NuMojo source path:
```bash
mojo run -I "/path/to/NuMojo" your_program.mojo
```

Now VSCode can show function hints for the Numojo package!
3. **VSCode LSP Setup** (for code hints and autocompletion):
- Open VSCode preferences
- Navigate to `Mojo › Lsp: Include Dirs`
- Click `Add Item` and enter the full path to your NuMojo directory (e.g., `/Users/YourName/Projects/NuMojo`)
- Restart the Mojo LSP server

After setup, VSCode will provide intelligent code completion and hints for NuMojo functions!

## Contributing

Any contributions you make are **greatly appreciated**. For more details and guidelines on contributions, please check [here](CONTRIBUTING.md)
Any contributions you make are **greatly appreciated**. NuMojo is early-stage and there's a lot of room to help: implementing routines, writing tests, improving docs, or just filing issues for things that feel off.

Quick start for contributors:

```bash
git clone https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo.git
cd NuMojo
pixi install
pixi run final # format + test
```

See [docs/developer-guide/contributing.md](docs/developer-guide/contributing.md) for full guidelines (coding style, directory structure, PR process), [docs/developer-guide/style-guide.md](docs/developer-guide/style-guide.md) for docstring/formatting conventions, and [docs/developer-guide/pre-pr-checks.md](docs/developer-guide/pre-pr-checks.md) for what to run before opening a PR.

## Warnings

This library is still very much a work in progress and may change at any time.
This library is still early and may introduce breaking changes between minor versions. Pin versions in production or research code.

## License

Distributed under the Apache 2.0 License with LLVM Exceptions. See [LICENSE](https://github.com/Mojo-Numerics-and-Algorithms-group/NuMojo/blob/main/LICENSE) and the LLVM [License](https://llvm.org/LICENSE.txt) for more information.
Distributed under the Apache 2.0 License with LLVM Exceptions. See [LICENSE](LICENSE) and the LLVM [License](https://llvm.org/LICENSE.txt) for more information.

This project includes code from [Mojo Standard Library](https://github.com/modularml/mojo), licensed under the Apache License v2.0 with LLVM Exceptions (see the LLVM [License](https://llvm.org/LICENSE.txt)). MAX and Mojo usage and distribution are licensed under the [MAX & Mojo Community License](https://www.modular.com/legal/max-mojo-license).

Expand Down
Loading
Loading