Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/juliagpu/amgx.jl
https://github.com/juliagpu/amgx.jl
amgx julia
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/juliagpu/amgx.jl
- Owner: JuliaGPU
- License: mit
- Created: 2021-01-14T15:18:32.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2023-08-22T14:40:49.000Z (over 1 year ago)
- Last Synced: 2024-05-09T13:11:15.399Z (8 months ago)
- Topics: amgx, julia
- Language: Julia
- Size: 57.6 KB
- Stars: 11
- Watchers: 6
- Forks: 4
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# AMGX.jl
*AMGX in Julia*
| **Build Status** |
|:-------------------------------------------------------------------:|
| [![][buildkite-img]][buildkite-url] [![][codecov-img]][codecov-url] |The AMGX.jl package provides an interface for using NVIDIA's [AMGX](https://github.com/NVIDIA/AMGX) library from the Julia language.
[buildkite-img]: https://badge.buildkite.com/ce21dc6bf28e053c02c8c726ea0c65cc981a22ec2934e01e56.svg?branch=master
[buildkite-url]: https://buildkite.com/julialang/amgx-dot-jl[codecov-img]: https://codecov.io/gh/JuliaGPU/AMGX.jl/branch/master/graph/badge.svg
[codecov-url]: https://codecov.io/gh/JuliaGPU/AMGX.jl## Installation
The package is installed using the Julia package manager:
```julia
using Pkg; Pkg.add("AMGX")
```Currently, only prebuilt binaries are available for Linux, on other operating systems you need to have AMGX available
locally.Before using the package, reading through the [official API reference docs for
AMGX](https://github.com/NVIDIA/AMGX/blob/main/doc/AMGX_Reference.pdf) is recommended.## API
### Initialization
If you do not want to use the provided prebuilt binaries, set the environment variable `JULIA_AMGX_PATH` to the path to the local AMGX library.
The library can now be initialized with:
```julia
using AMGX
AMGX.initialize()
AMGX.initialize_plugins()
```### `Config`
An AMGX `Config` can be created from a dictionary or a string:
```julia
config = AMGX.Config(Dict("monitor_residual" => 1, "max_iters" => 10, "store_res_history" => 1));
```### `Resources`
An AMGX `Resources` object is created from an AMGX `Config`. Currently, only simple resources are wrapped:
```julia
resources = AMGX.Resources(config)
```### `Mode`
The different modes in AMGX are available as:
- `AMGX.hDDI`
- `AMGX.hDFI`
- `AMGX.hFFI`
- `AMGX.dDDI`
- `AMGX.dDFI`
- `AMGX.dFFI`### `Vector`
An `AMGXVector` is created from a resource object with a given mode.
```julia
v = AMGX.AMGXVector(resources, AMGX.dDDI)
```Data can then be uploaded to the vectorusing `upload!`:
```julia
AMGX.upload!(v, [1.0, 2.0, 3.0])
```Optionally, the "block dimension" can be given:
```julia
v_block = AMGX.AMGXVector(resources, AMGX.dDDI)
AMGX.upload!(v_block, [1.0, 2.0, 3.0, 4.0]; block_dim=2)
```Data can be downloaded from the vector (for example after solving a system) using `Vector`:
```julia
v_h = Vector(v)
```It is also possible to download to a preallocated buffer using `copy!`:
```julia
v_h_buffer = zeros(3)
copy!(v_h_buffer, v)
```Note that data can be uploaded / downloaded from arrays already allocated on the GPU (`CuArray`):
```julia
using CUDA
v_cu = AMGX.AMGXVector(resources, AMGX.dDDI)
cu = CuVector([1.0, 2.0, 3.0])
AMGX.upload!(v_cu, cu)
cu_buffer = CUDA.zeros(Float64, 3)
copy!(cu_buffer, v_cu)
```A vector can be set to zero:
```julia
v_zero = AMGX.AMGXVector(resources, AMGX.dDDI)
AMGX.set_zero!(v_zero, 5)
```### `AMGXMatrix`
Matrices in AMGX are stored in CSR format (as opposed to CSC which is typically used in Julia).
An `AMGXMatrix` is created from a `Resources` and a `mode`:```julia
matrix = AMGX.AMGXMatrix(resources, AMGX.dDDI)
```Data can be uploaded to it using the 3 CSR arrays:
```julia
AMGX.upload!(matrix,
Cint[0, 1, 3], # row_ptrs
Cint[1, 0, 1], # col_indices
[1.0, 2.0, 3.0] # data
)
```These arrays can also be uploaded from `CuArrays` already residing on the GPU.
Alternatively, a `CUDA.CUSPARSE.CuSparseMatrixCSR` can be directly uploaded.
The non zero values can be replaced:
```julia
AMGX.replace_coefficients!(matrix, [3.0, 2.0, 1.0])
```### `Solver`
A solver is created from a `Resources`, a `Mode`, and a `Config`:
```julia
solver = AMGX.Solver(resources, AMGX.dDDI, config)
```A system can now be solved as:
```julia
x = AMGX.AMGXVector(resources, AMGX.dDDI)
AMGX.set_zero!(x, 3)
AMGX.setup!(solver, matrix)
AMGX.solve!(x, solver, v)
```The solution vector can now be downloaded:
```julia
Vector(x)
```After a solve, the status can be retrieved using `AMGX.get_status(solver)`. It is of type `AMGX.SolverStatus` and can be either:
- `AMGX.SUCCESS`
- `AMGX.FAILED`
- `AMGX.DIVERGED`The total number of iterations can be retrieved with `AMGX.get_iterations_number(solver)`.
The residual for a given iteration can be retrieved with
```julia
AMGX.get_iteration_residual(solver)
AMGX.get_iteration_residual(solver, 0)
```### Utilities
#### Version information
The API version is retrieved with `AMGX.api_version()`.
Some more version info can be printed using `AMGX.versioninfo()`.#### Pinning/Unpinning memory
For performance, it is recommended to pin host memory before uploading it to the GPU. Pinning and unpinning of memory is done using:
```julia
v = rand(5)
AMGX.pin_memory(v)
AMGX.unpin_memory(v)
```#### Print callback
By default, the AMGX library prints various things to `stdout`. This can be overridden by registering a print callback, which is a Julia function accepting a `String` and returning `nothing`:
```julia
str = ""
store_to_str(amgx_printed::String) = (global str = amgx_printed; nothing)
AMGX.register_print_callback(store_to_str)
c_config = AMGX.Config("")
print(str)
print_stdout(amgx_printed::String) = print(stdout, amgx_printed)
AMGX.register_print_callback(print_stdout)
```#### Signal handlers
Signal handlers can be installed and reset using:
```julia
AMGX.install_signal_handler()
AMGX.reset_signal_handler()
```## Memory management and finalizing
You need to explicitly free memory of every AMGX object (`Config`, `Resources`, `AMGXVector`, `AMGXMatrix`, `Solver`) created using the julia call
`close`.
Using [Defer.jl](https://github.com/adambrewster/Defer.jl) can significantly
increase the convenience of this.AMGX.jl contains a reference counting system so that it errors if you try to close things in the wrong order (e.g. closing the `Resources` object before the `AMGXVector` created from it is closed (destroyed))
When usage of the library is done, it should be finalized with:
```jl
AMGX.finalize_plugins()
AMGX.finalize()
```## Not implemented:
The following functions from the C-API are not yet implemented:
- `AMGX_read_system`
- `AMGX_read_system_distributed`
- `AMGX_write_system`
- `AMGX_write_system_distributed`
- `AMGX_config_create_from_file`
- `AMGX_config_get_default_number_of_rings`
- `AMGX_resources_create` (only simple is currently wrapped)
- `AMGX_matrix_upload_all_global`
- `AMGX_matrix_comm_from_maps`
- `AMGX_matrix_comm_from_maps_one_ring`
- `AMGX_vector_bind`