diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml
index fbf5b49..813320d 100644
--- a/.buildkite/pipeline.yml
+++ b/.buildkite/pipeline.yml
@@ -1,42 +1,57 @@
-env:
-  SECRET_CODECOV_TOKEN: "MIXvKy8FpOJzyBykdGQdVdn0jVli57e1Mc1QQQQA6RyLBdViYwCOjLQS+Yh5sgeD5eEm9JLtu6ISePq01EjqpHF7/6zJlcEJTqj2JidcH/sp/FnJiIY0MfV48DSrz1XA7rN6hHQ8wh09+BMG1Ur4CbtwVQl1HF3wZqmt+b2Ahknyxd0mrIoT3j6RJ90vVSGagLLqWolaQLLOFoGNyHbeFV15r1YXLZDkwyE1SSNz4JF3qEN7vFbM9ZnbR4edd7zWABdDiGd3FDnbn1OJFbZ3JzJXph6JAxZyF34RFDzZsERiKyIrAM+0LfyDYqCAcYnjDpJoEASZugTTwIKXOjUkyQ==;U2FsdGVkX1+go3U7v0bYSZs2Lx4R/lwnJXQm4ATdXL2Y7x5H9QDOgazDvusO8UmBtwHFi3szvPuuxr/gcXYgxw=="
-
 steps:
-  - label: "Julia 1.6"
-    plugins:
-      - JuliaCI/julia#v1:
-          version: 1.6
-      - JuliaCI/julia-test#v1: ~
-      - JuliaCI/julia-coverage#v1:
-          codecov: true
-    agents:
-      queue: "juliagpu"
-      cuda: "10.0"
-    if: build.message !~ /\[skip tests\]/
-    timeout_in_minutes: 60
+  - group: ":julia: Julia"
+    steps:
+      - label: "Julia {{matrix.julia}}"
+        plugins:
+          - JuliaCI/julia#v1:
+              version: "{{matrix.julia}}"
+          - JuliaCI/julia-test#v1: ~
+          - JuliaCI/julia-coverage#v1: ~
+        agents:
+          queue: "juliagpu"
+          cuda: "*"
+        commands: |
+          julia --project -e "
+            using CUDA
+            CUDA.set_runtime_version!(local_toolkit=true)"
+        timeout_in_minutes: 60
+        matrix:
+          setup:
+            julia:
+              - "1.10"
+              - "1.11"
 
-  - label: "Julia 1.7"
-    plugins:
-      - JuliaCI/julia#v1:
-          version: 1.7
-      - JuliaCI/julia-test#v1: ~
-      - JuliaCI/julia-coverage#v1:
-          codecov: true
-    agents:
-      queue: "juliagpu"
-      cuda: "10.0"
-    if: build.message !~ /\[skip tests\]/
-    timeout_in_minutes: 60
+  - group: "CUDA"
+    steps:
+      - label: "CUDA {{matrix.cuda}}"
+        plugins:
+          - JuliaCI/julia#v1:
+              version: "1.11"
+          - JuliaCI/julia-test#v1: ~
+          - JuliaCI/julia-coverage#v1: ~
+        agents:
+          queue: "juliagpu"
+          cuda: "*"
+        timeout_in_minutes: 45
+        matrix:
+          setup:
+            cuda:
+              - "12.6"
+              - "12.5"
+              - "12.4"
+              - "12.3"
+              - "12.2"
+              - "12.1"
+              - "12.0"
+              - "11.8"
+              - "11.7"
+              - "11.6"
+              - "11.5"
+              - "11.4"
+        commands: |
+          julia --project -e "
+            using CUDA
+            CUDA.set_runtime_version!(v\"{{matrix.cuda}}\")"
 
-  - label: "Julia 1.8"
-    plugins:
-      - JuliaCI/julia#v1:
-          version: 1.8
-      - JuliaCI/julia-test#v1: ~
-      - JuliaCI/julia-coverage#v1:
-          codecov: true
-    agents:
-      queue: "juliagpu"
-      cuda: "10.0"
-    if: build.message !~ /\[skip tests\]/
-    timeout_in_minutes: 60
+env:
+  SECRET_CODECOV_TOKEN: "MIXvKy8FpOJzyBykdGQdVdn0jVli57e1Mc1QQQQA6RyLBdViYwCOjLQS+Yh5sgeD5eEm9JLtu6ISePq01EjqpHF7/6zJlcEJTqj2JidcH/sp/FnJiIY0MfV48DSrz1XA7rN6hHQ8wh09+BMG1Ur4CbtwVQl1HF3wZqmt+b2Ahknyxd0mrIoT3j6RJ90vVSGagLLqWolaQLLOFoGNyHbeFV15r1YXLZDkwyE1SSNz4JF3qEN7vFbM9ZnbR4edd7zWABdDiGd3FDnbn1OJFbZ3JzJXph6JAxZyF34RFDzZsERiKyIrAM+0LfyDYqCAcYnjDpJoEASZugTTwIKXOjUkyQ==;U2FsdGVkX1+go3U7v0bYSZs2Lx4R/lwnJXQm4ATdXL2Y7x5H9QDOgazDvusO8UmBtwHFi3szvPuuxr/gcXYgxw=="
diff --git a/Project.toml b/Project.toml
index 020feb5..a60a3b5 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,14 @@
+authors = ["JuliaHub"]
 name = "AMGX"
 uuid = "c963dde9-0319-47f5-bf0c-b07d3c80ffa6"
-authors = ["JuliaHub"]
-version = "0.1.4"
+version = "0.2.0"
+
+[compat]
+AMGX_jll = "2.4"
+CEnum = "0.5"
+CUDA = "4,5"
+JSON = "0.21"
+julia = "1.10"
 
 [deps]
 AMGX_jll = "656d14af-56e4-5275-8e68-4e861d7b5043"
@@ -11,12 +18,6 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
 Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
 SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
 
-[compat]
-CEnum = "0.4"
-CUDA = "2.2, 3, 4"
-JSON = "0.21"
-julia = "1.5"
-
 [extras]
 Defer = "6f25fe36-ecbb-5dff-aeb8-f7b50c87fb5f"
 Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
diff --git a/README.md b/README.md
index 135ba21..a80256b 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,6 @@ The library can now be initialized with:
 ```julia
 using AMGX
 AMGX.initialize()
-AMGX.initialize_plugins()
 ```
 
 ### `Config`
@@ -182,6 +181,7 @@ After a solve, the status can be retrieved using `AMGX.get_status(solver)`. It i
 - `AMGX.SUCCESS`
 - `AMGX.FAILED`
 - `AMGX.DIVERGED`
+- `AMGX.NOT_CONVERGED`
 
 The total number of iterations can be retrieved with `AMGX.get_iterations_number(solver)`.
 
diff --git a/lib/libAMGX.jl b/lib/libAMGX.jl
index b8677a1..ce12731 100644
--- a/lib/libAMGX.jl
+++ b/lib/libAMGX.jl
@@ -3,283 +3,283 @@
 
 
 function AMGX_get_api_version(major, minor)
-    @runtime_ccall((:AMGX_get_api_version, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}), major, minor)
+    ccall((:AMGX_get_api_version, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}), major, minor)
 end
 
 function AMGX_get_build_info_strings(version, date, time)
-    @runtime_ccall((:AMGX_get_build_info_strings, libAMGX), AMGX_RC, (Ptr{Cstring}, Ptr{Cstring}, Ptr{Cstring}), version, date, time)
+    ccall((:AMGX_get_build_info_strings, libAMGX), AMGX_RC, (Ptr{Cstring}, Ptr{Cstring}, Ptr{Cstring}), version, date, time)
 end
 
 function AMGX_get_error_string(err, buf, buf_len)
-    @runtime_ccall((:AMGX_get_error_string, libAMGX), AMGX_RC, (AMGX_RC, Cstring, Cint), err, buf, buf_len)
+    ccall((:AMGX_get_error_string, libAMGX), AMGX_RC, (AMGX_RC, Cstring, Cint), err, buf, buf_len)
 end
 
 function AMGX_initialize()
-    @runtime_ccall((:AMGX_initialize, libAMGX), AMGX_RC, ())
+    ccall((:AMGX_initialize, libAMGX), AMGX_RC, ())
 end
 
 function AMGX_initialize_plugins()
-    @runtime_ccall((:AMGX_initialize_plugins, libAMGX), AMGX_RC, ())
+    ccall((:AMGX_initialize_plugins, libAMGX), AMGX_RC, ())
 end
 
 function AMGX_finalize()
-    @runtime_ccall((:AMGX_finalize, libAMGX), AMGX_RC, ())
+    ccall((:AMGX_finalize, libAMGX), AMGX_RC, ())
 end
 
 function AMGX_finalize_plugins()
-    @runtime_ccall((:AMGX_finalize_plugins, libAMGX), AMGX_RC, ())
+    ccall((:AMGX_finalize_plugins, libAMGX), AMGX_RC, ())
 end
 
 function AMGX_abort(rsrc, err)
-    @runtime_ccall((:AMGX_abort, libAMGX), Cvoid, (AMGX_resources_handle, Cint), rsrc, err)
+    ccall((:AMGX_abort, libAMGX), Cvoid, (AMGX_resources_handle, Cint), rsrc, err)
 end
 
 function AMGX_pin_memory(ptr, bytes)
-    @runtime_ccall((:AMGX_pin_memory, libAMGX), AMGX_RC, (Ptr{Cvoid}, UInt32), ptr, bytes)
+    ccall((:AMGX_pin_memory, libAMGX), AMGX_RC, (Ptr{Cvoid}, UInt32), ptr, bytes)
 end
 
 function AMGX_unpin_memory(ptr)
-    @runtime_ccall((:AMGX_unpin_memory, libAMGX), AMGX_RC, (Ptr{Cvoid},), ptr)
+    ccall((:AMGX_unpin_memory, libAMGX), AMGX_RC, (Ptr{Cvoid},), ptr)
 end
 
 function AMGX_install_signal_handler()
-    @runtime_ccall((:AMGX_install_signal_handler, libAMGX), AMGX_RC, ())
+    ccall((:AMGX_install_signal_handler, libAMGX), AMGX_RC, ())
 end
 
 function AMGX_reset_signal_handler()
-    @runtime_ccall((:AMGX_reset_signal_handler, libAMGX), AMGX_RC, ())
+    ccall((:AMGX_reset_signal_handler, libAMGX), AMGX_RC, ())
 end
 
 function AMGX_register_print_callback(func)
-    @runtime_ccall((:AMGX_register_print_callback, libAMGX), AMGX_RC, (AMGX_print_callback,), func)
+    ccall((:AMGX_register_print_callback, libAMGX), AMGX_RC, (AMGX_print_callback,), func)
 end
 
 function AMGX_config_create(cfg, options)
-    @runtime_ccall((:AMGX_config_create, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring), cfg, options)
+    ccall((:AMGX_config_create, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring), cfg, options)
 end
 
 function AMGX_config_add_parameters(cfg, options)
-    @runtime_ccall((:AMGX_config_add_parameters, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring), cfg, options)
+    ccall((:AMGX_config_add_parameters, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring), cfg, options)
 end
 
 function AMGX_config_create_from_file(cfg, param_file)
-    @runtime_ccall((:AMGX_config_create_from_file, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring), cfg, param_file)
+    ccall((:AMGX_config_create_from_file, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring), cfg, param_file)
 end
 
 function AMGX_config_create_from_file_and_string(cfg, param_file, options)
-    @runtime_ccall((:AMGX_config_create_from_file_and_string, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring, Cstring), cfg, param_file, options)
+    ccall((:AMGX_config_create_from_file_and_string, libAMGX), AMGX_RC, (Ptr{AMGX_config_handle}, Cstring, Cstring), cfg, param_file, options)
 end
 
 function AMGX_config_get_default_number_of_rings(cfg, num_import_rings)
-    @runtime_ccall((:AMGX_config_get_default_number_of_rings, libAMGX), AMGX_RC, (AMGX_config_handle, Ptr{Cint}), cfg, num_import_rings)
+    ccall((:AMGX_config_get_default_number_of_rings, libAMGX), AMGX_RC, (AMGX_config_handle, Ptr{Cint}), cfg, num_import_rings)
 end
 
 function AMGX_config_destroy(cfg)
-    @runtime_ccall((:AMGX_config_destroy, libAMGX), AMGX_RC, (AMGX_config_handle,), cfg)
+    ccall((:AMGX_config_destroy, libAMGX), AMGX_RC, (AMGX_config_handle,), cfg)
 end
 
 function AMGX_resources_create(rsc, cfg, comm, device_num, devices)
-    @runtime_ccall((:AMGX_resources_create, libAMGX), AMGX_RC, (Ptr{AMGX_resources_handle}, AMGX_config_handle, Ptr{Cvoid}, Cint, Ptr{Cint}), rsc, cfg, comm, device_num, devices)
+    ccall((:AMGX_resources_create, libAMGX), AMGX_RC, (Ptr{AMGX_resources_handle}, AMGX_config_handle, Ptr{Cvoid}, Cint, Ptr{Cint}), rsc, cfg, comm, device_num, devices)
 end
 
 function AMGX_resources_create_simple(rsc, cfg)
-    @runtime_ccall((:AMGX_resources_create_simple, libAMGX), AMGX_RC, (Ptr{AMGX_resources_handle}, AMGX_config_handle), rsc, cfg)
+    ccall((:AMGX_resources_create_simple, libAMGX), AMGX_RC, (Ptr{AMGX_resources_handle}, AMGX_config_handle), rsc, cfg)
 end
 
 function AMGX_resources_destroy(rsc)
-    @runtime_ccall((:AMGX_resources_destroy, libAMGX), AMGX_RC, (AMGX_resources_handle,), rsc)
+    ccall((:AMGX_resources_destroy, libAMGX), AMGX_RC, (AMGX_resources_handle,), rsc)
 end
 
 function AMGX_distribution_create(dist, cfg)
-    @runtime_ccall((:AMGX_distribution_create, libAMGX), AMGX_RC, (Ptr{AMGX_distribution_handle}, AMGX_config_handle), dist, cfg)
+    ccall((:AMGX_distribution_create, libAMGX), AMGX_RC, (Ptr{AMGX_distribution_handle}, AMGX_config_handle), dist, cfg)
 end
 
 function AMGX_distribution_destroy(dist)
-    @runtime_ccall((:AMGX_distribution_destroy, libAMGX), AMGX_RC, (AMGX_distribution_handle,), dist)
+    ccall((:AMGX_distribution_destroy, libAMGX), AMGX_RC, (AMGX_distribution_handle,), dist)
 end
 
 function AMGX_distribution_set_partition_data(dist, info, partition_data)
-    @runtime_ccall((:AMGX_distribution_set_partition_data, libAMGX), AMGX_RC, (AMGX_distribution_handle, AMGX_DIST_PARTITION_INFO, Ptr{Cvoid}), dist, info, partition_data)
+    ccall((:AMGX_distribution_set_partition_data, libAMGX), AMGX_RC, (AMGX_distribution_handle, AMGX_DIST_PARTITION_INFO, Ptr{Cvoid}), dist, info, partition_data)
 end
 
 function AMGX_distribution_set_32bit_colindices(dist, use32bit)
-    @runtime_ccall((:AMGX_distribution_set_32bit_colindices, libAMGX), AMGX_RC, (AMGX_distribution_handle, Cint), dist, use32bit)
+    ccall((:AMGX_distribution_set_32bit_colindices, libAMGX), AMGX_RC, (AMGX_distribution_handle, Cint), dist, use32bit)
 end
 
 function AMGX_matrix_create(mtx, rsc, mode)
-    @runtime_ccall((:AMGX_matrix_create, libAMGX), AMGX_RC, (Ptr{AMGX_matrix_handle}, AMGX_resources_handle, AMGX_Mode), mtx, rsc, mode)
+    ccall((:AMGX_matrix_create, libAMGX), AMGX_RC, (Ptr{AMGX_matrix_handle}, AMGX_resources_handle, AMGX_Mode), mtx, rsc, mode)
 end
 
 function AMGX_matrix_destroy(mtx)
-    @runtime_ccall((:AMGX_matrix_destroy, libAMGX), AMGX_RC, (AMGX_matrix_handle,), mtx)
+    ccall((:AMGX_matrix_destroy, libAMGX), AMGX_RC, (AMGX_matrix_handle,), mtx)
 end
 
 function AMGX_matrix_upload_all(mtx, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices, data, diag_data)
-    @runtime_ccall((:AMGX_matrix_upload_all, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}), mtx, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices, data, diag_data)
+    ccall((:AMGX_matrix_upload_all, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}), mtx, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices, data, diag_data)
 end
 
 function AMGX_matrix_replace_coefficients(mtx, n, nnz, data, diag_data)
-    @runtime_ccall((:AMGX_matrix_replace_coefficients, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Ptr{Cvoid}, Ptr{Cvoid}), mtx, n, nnz, data, diag_data)
+    ccall((:AMGX_matrix_replace_coefficients, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Ptr{Cvoid}, Ptr{Cvoid}), mtx, n, nnz, data, diag_data)
 end
 
 function AMGX_matrix_get_size(mtx, n, block_dimx, block_dimy)
-    @runtime_ccall((:AMGX_matrix_get_size, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), mtx, n, block_dimx, block_dimy)
+    ccall((:AMGX_matrix_get_size, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), mtx, n, block_dimx, block_dimy)
 end
 
 function AMGX_matrix_get_nnz(mtx, nnz)
-    @runtime_ccall((:AMGX_matrix_get_nnz, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}), mtx, nnz)
+    ccall((:AMGX_matrix_get_nnz, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}), mtx, nnz)
 end
 
 function AMGX_matrix_download_all(mtx, row_ptrs, col_indices, data, diag_data)
-    @runtime_ccall((:AMGX_matrix_download_all, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}, Ptr{Cint}, Ptr{Cvoid}, Ptr{Ptr{Cvoid}}), mtx, row_ptrs, col_indices, data, diag_data)
+    ccall((:AMGX_matrix_download_all, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}, Ptr{Cint}, Ptr{Cvoid}, Ptr{Ptr{Cvoid}}), mtx, row_ptrs, col_indices, data, diag_data)
 end
 
 function AMGX_matrix_vector_multiply(mtx, x, y)
-    @runtime_ccall((:AMGX_matrix_vector_multiply, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle), mtx, x, y)
+    ccall((:AMGX_matrix_vector_multiply, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle), mtx, x, y)
 end
 
 function AMGX_matrix_set_boundary_separation(mtx, boundary_separation)
-    @runtime_ccall((:AMGX_matrix_set_boundary_separation, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint), mtx, boundary_separation)
+    ccall((:AMGX_matrix_set_boundary_separation, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint), mtx, boundary_separation)
 end
 
 function AMGX_matrix_comm_from_maps(mtx, allocated_halo_depth, num_import_rings, max_num_neighbors, neighbors, send_ptrs, send_maps, recv_ptrs, recv_maps)
-    @runtime_ccall((:AMGX_matrix_comm_from_maps, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), mtx, allocated_halo_depth, num_import_rings, max_num_neighbors, neighbors, send_ptrs, send_maps, recv_ptrs, recv_maps)
+    ccall((:AMGX_matrix_comm_from_maps, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}), mtx, allocated_halo_depth, num_import_rings, max_num_neighbors, neighbors, send_ptrs, send_maps, recv_ptrs, recv_maps)
 end
 
 function AMGX_matrix_comm_from_maps_one_ring(mtx, allocated_halo_depth, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps)
-    @runtime_ccall((:AMGX_matrix_comm_from_maps_one_ring, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Cint}, Ptr{Ptr{Cint}}), mtx, allocated_halo_depth, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps)
+    ccall((:AMGX_matrix_comm_from_maps_one_ring, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Cint}, Ptr{Ptr{Cint}}), mtx, allocated_halo_depth, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps)
 end
 
 function AMGX_vector_create(vec, rsc, mode)
-    @runtime_ccall((:AMGX_vector_create, libAMGX), AMGX_RC, (Ptr{AMGX_vector_handle}, AMGX_resources_handle, AMGX_Mode), vec, rsc, mode)
+    ccall((:AMGX_vector_create, libAMGX), AMGX_RC, (Ptr{AMGX_vector_handle}, AMGX_resources_handle, AMGX_Mode), vec, rsc, mode)
 end
 
 function AMGX_vector_destroy(vec)
-    @runtime_ccall((:AMGX_vector_destroy, libAMGX), AMGX_RC, (AMGX_vector_handle,), vec)
+    ccall((:AMGX_vector_destroy, libAMGX), AMGX_RC, (AMGX_vector_handle,), vec)
 end
 
 function AMGX_vector_upload(vec, n, block_dim, data)
-    @runtime_ccall((:AMGX_vector_upload, libAMGX), AMGX_RC, (AMGX_vector_handle, Cint, Cint, Ptr{Cvoid}), vec, n, block_dim, data)
+    ccall((:AMGX_vector_upload, libAMGX), AMGX_RC, (AMGX_vector_handle, Cint, Cint, Ptr{Cvoid}), vec, n, block_dim, data)
 end
 
 function AMGX_vector_set_zero(vec, n, block_dim)
-    @runtime_ccall((:AMGX_vector_set_zero, libAMGX), AMGX_RC, (AMGX_vector_handle, Cint, Cint), vec, n, block_dim)
+    ccall((:AMGX_vector_set_zero, libAMGX), AMGX_RC, (AMGX_vector_handle, Cint, Cint), vec, n, block_dim)
 end
 
 function AMGX_vector_set_random(vec, n)
-    @runtime_ccall((:AMGX_vector_set_random, libAMGX), AMGX_RC, (AMGX_vector_handle, Cint), vec, n)
+    ccall((:AMGX_vector_set_random, libAMGX), AMGX_RC, (AMGX_vector_handle, Cint), vec, n)
 end
 
 function AMGX_vector_download(vec, data)
-    @runtime_ccall((:AMGX_vector_download, libAMGX), AMGX_RC, (AMGX_vector_handle, Ptr{Cvoid}), vec, data)
+    ccall((:AMGX_vector_download, libAMGX), AMGX_RC, (AMGX_vector_handle, Ptr{Cvoid}), vec, data)
 end
 
 function AMGX_vector_get_size(vec, n, block_dim)
-    @runtime_ccall((:AMGX_vector_get_size, libAMGX), AMGX_RC, (AMGX_vector_handle, Ptr{Cint}, Ptr{Cint}), vec, n, block_dim)
+    ccall((:AMGX_vector_get_size, libAMGX), AMGX_RC, (AMGX_vector_handle, Ptr{Cint}, Ptr{Cint}), vec, n, block_dim)
 end
 
 function AMGX_vector_bind(vec, mtx)
-    @runtime_ccall((:AMGX_vector_bind, libAMGX), AMGX_RC, (AMGX_vector_handle, AMGX_matrix_handle), vec, mtx)
+    ccall((:AMGX_vector_bind, libAMGX), AMGX_RC, (AMGX_vector_handle, AMGX_matrix_handle), vec, mtx)
 end
 
 function AMGX_solver_create(slv, rsc, mode, cfg_solver)
-    @runtime_ccall((:AMGX_solver_create, libAMGX), AMGX_RC, (Ptr{AMGX_solver_handle}, AMGX_resources_handle, AMGX_Mode, AMGX_config_handle), slv, rsc, mode, cfg_solver)
+    ccall((:AMGX_solver_create, libAMGX), AMGX_RC, (Ptr{AMGX_solver_handle}, AMGX_resources_handle, AMGX_Mode, AMGX_config_handle), slv, rsc, mode, cfg_solver)
 end
 
 function AMGX_solver_destroy(slv)
-    @runtime_ccall((:AMGX_solver_destroy, libAMGX), AMGX_RC, (AMGX_solver_handle,), slv)
+    ccall((:AMGX_solver_destroy, libAMGX), AMGX_RC, (AMGX_solver_handle,), slv)
 end
 
 function AMGX_solver_setup(slv, mtx)
-    @runtime_ccall((:AMGX_solver_setup, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_matrix_handle), slv, mtx)
+    ccall((:AMGX_solver_setup, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_matrix_handle), slv, mtx)
 end
 
 function AMGX_solver_solve(slv, rhs, sol)
-    @runtime_ccall((:AMGX_solver_solve, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_vector_handle, AMGX_vector_handle), slv, rhs, sol)
+    ccall((:AMGX_solver_solve, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_vector_handle, AMGX_vector_handle), slv, rhs, sol)
 end
 
 function AMGX_solver_solve_with_0_initial_guess(slv, rhs, sol)
-    @runtime_ccall((:AMGX_solver_solve_with_0_initial_guess, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_vector_handle, AMGX_vector_handle), slv, rhs, sol)
+    ccall((:AMGX_solver_solve_with_0_initial_guess, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_vector_handle, AMGX_vector_handle), slv, rhs, sol)
 end
 
 function AMGX_solver_get_iterations_number(slv, n)
-    @runtime_ccall((:AMGX_solver_get_iterations_number, libAMGX), AMGX_RC, (AMGX_solver_handle, Ptr{Cint}), slv, n)
+    ccall((:AMGX_solver_get_iterations_number, libAMGX), AMGX_RC, (AMGX_solver_handle, Ptr{Cint}), slv, n)
 end
 
 function AMGX_solver_get_iteration_residual(slv, it, idx, res)
-    @runtime_ccall((:AMGX_solver_get_iteration_residual, libAMGX), AMGX_RC, (AMGX_solver_handle, Cint, Cint, Ptr{Cdouble}), slv, it, idx, res)
+    ccall((:AMGX_solver_get_iteration_residual, libAMGX), AMGX_RC, (AMGX_solver_handle, Cint, Cint, Ptr{Cdouble}), slv, it, idx, res)
 end
 
 function AMGX_solver_get_status(slv, st)
-    @runtime_ccall((:AMGX_solver_get_status, libAMGX), AMGX_RC, (AMGX_solver_handle, Ptr{AMGX_SOLVE_STATUS}), slv, st)
+    ccall((:AMGX_solver_get_status, libAMGX), AMGX_RC, (AMGX_solver_handle, Ptr{AMGX_SOLVE_STATUS}), slv, st)
 end
 
 function AMGX_solver_calculate_residual_norm(solver, mtx, rhs, x, norm_vector)
-    @runtime_ccall((:AMGX_solver_calculate_residual_norm, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Ptr{Cvoid}), solver, mtx, rhs, x, norm_vector)
+    ccall((:AMGX_solver_calculate_residual_norm, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Ptr{Cvoid}), solver, mtx, rhs, x, norm_vector)
 end
 
 function AMGX_write_system(mtx, rhs, sol, filename)
-    @runtime_ccall((:AMGX_write_system, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring), mtx, rhs, sol, filename)
+    ccall((:AMGX_write_system, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring), mtx, rhs, sol, filename)
 end
 
 function AMGX_write_system_distributed(mtx, rhs, sol, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
-    @runtime_ccall((:AMGX_write_system_distributed, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), mtx, rhs, sol, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
+    ccall((:AMGX_write_system_distributed, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), mtx, rhs, sol, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
 end
 
 function AMGX_read_system(mtx, rhs, sol, filename)
-    @runtime_ccall((:AMGX_read_system, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring), mtx, rhs, sol, filename)
+    ccall((:AMGX_read_system, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring), mtx, rhs, sol, filename)
 end
 
 function AMGX_read_system_distributed(mtx, rhs, sol, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
-    @runtime_ccall((:AMGX_read_system_distributed, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), mtx, rhs, sol, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
+    ccall((:AMGX_read_system_distributed, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), mtx, rhs, sol, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
 end
 
 function AMGX_read_system_maps_one_ring(n, nnz, block_dimx, block_dimy, row_ptrs, col_indices, data, diag_data, rhs, sol, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps, rsc, mode, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
-    @runtime_ccall((:AMGX_read_system_maps_one_ring, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cint}}, Ptr{Ptr{Ptr{Cint}}}, Ptr{Ptr{Cint}}, Ptr{Ptr{Ptr{Cint}}}, AMGX_resources_handle, AMGX_Mode, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), n, nnz, block_dimx, block_dimy, row_ptrs, col_indices, data, diag_data, rhs, sol, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps, rsc, mode, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
+    ccall((:AMGX_read_system_maps_one_ring, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cint}}, Ptr{Ptr{Ptr{Cint}}}, Ptr{Ptr{Cint}}, Ptr{Ptr{Ptr{Cint}}}, AMGX_resources_handle, AMGX_Mode, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), n, nnz, block_dimx, block_dimy, row_ptrs, col_indices, data, diag_data, rhs, sol, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps, rsc, mode, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
 end
 
 function AMGX_free_system_maps_one_ring(row_ptrs, col_indices, data, diag_data, rhs, sol, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps)
-    @runtime_ccall((:AMGX_free_system_maps_one_ring, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Cint}, Ptr{Ptr{Cint}}), row_ptrs, col_indices, data, diag_data, rhs, sol, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps)
+    ccall((:AMGX_free_system_maps_one_ring, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Cint, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Cint}, Ptr{Ptr{Cint}}), row_ptrs, col_indices, data, diag_data, rhs, sol, num_neighbors, neighbors, send_sizes, send_maps, recv_sizes, recv_maps)
 end
 
 function AMGX_generate_distributed_poisson_7pt(mtx, rhs, sol, allocated_halo_depth, num_import_rings, nx, ny, nz, px, py, pz)
-    @runtime_ccall((:AMGX_generate_distributed_poisson_7pt, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cint, Cint, Cint, Cint, Cint, Cint, Cint, Cint), mtx, rhs, sol, allocated_halo_depth, num_import_rings, nx, ny, nz, px, py, pz)
+    ccall((:AMGX_generate_distributed_poisson_7pt, libAMGX), AMGX_RC, (AMGX_matrix_handle, AMGX_vector_handle, AMGX_vector_handle, Cint, Cint, Cint, Cint, Cint, Cint, Cint, Cint), mtx, rhs, sol, allocated_halo_depth, num_import_rings, nx, ny, nz, px, py, pz)
 end
 
 function AMGX_write_parameters_description(filename, mode)
-    @runtime_ccall((:AMGX_write_parameters_description, libAMGX), AMGX_RC, (Cstring, AMGX_GET_PARAMS_DESC_FLAG), filename, mode)
+    ccall((:AMGX_write_parameters_description, libAMGX), AMGX_RC, (Cstring, AMGX_GET_PARAMS_DESC_FLAG), filename, mode)
 end
 
 function AMGX_matrix_attach_coloring(mtx, row_coloring, num_rows, num_colors)
-    @runtime_ccall((:AMGX_matrix_attach_coloring, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}, Cint, Cint), mtx, row_coloring, num_rows, num_colors)
+    ccall((:AMGX_matrix_attach_coloring, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cint}, Cint, Cint), mtx, row_coloring, num_rows, num_colors)
 end
 
 function AMGX_matrix_attach_geometry(mtx, geox, geoy, geoz, n)
-    @runtime_ccall((:AMGX_matrix_attach_geometry, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Cint), mtx, geox, geoy, geoz, n)
+    ccall((:AMGX_matrix_attach_geometry, libAMGX), AMGX_RC, (AMGX_matrix_handle, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Cint), mtx, geox, geoy, geoz, n)
 end
 
 function AMGX_read_system_global(n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, rhs, sol, rsc, mode, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
-    @runtime_ccall((:AMGX_read_system_global, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, AMGX_resources_handle, AMGX_Mode, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, rhs, sol, rsc, mode, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
+    ccall((:AMGX_read_system_global, libAMGX), AMGX_RC, (Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Cint}, Ptr{Ptr{Cint}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, Ptr{Ptr{Cvoid}}, AMGX_resources_handle, AMGX_Mode, Cstring, Cint, Cint, Ptr{Cint}, Cint, Ptr{Cint}), n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, rhs, sol, rsc, mode, filename, allocated_halo_depth, num_partitions, partition_sizes, partition_vector_size, partition_vector)
 end
 
 function AMGX_matrix_upload_all_global(mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, allocated_halo_depth, num_import_rings, partition_vector)
-    @runtime_ccall((:AMGX_matrix_upload_all_global, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Cint, Cint, Ptr{Cint}), mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, allocated_halo_depth, num_import_rings, partition_vector)
+    ccall((:AMGX_matrix_upload_all_global, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Cint, Cint, Ptr{Cint}), mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, allocated_halo_depth, num_import_rings, partition_vector)
 end
 
 function AMGX_matrix_upload_all_global_32(mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, allocated_halo_depth, num_import_rings, partition_vector)
-    @runtime_ccall((:AMGX_matrix_upload_all_global_32, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Cint, Cint, Ptr{Cint}), mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, allocated_halo_depth, num_import_rings, partition_vector)
+    ccall((:AMGX_matrix_upload_all_global_32, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Cint, Cint, Ptr{Cint}), mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, allocated_halo_depth, num_import_rings, partition_vector)
 end
 
 function AMGX_matrix_upload_distributed(mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, distribution)
-    @runtime_ccall((:AMGX_matrix_upload_distributed, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, AMGX_distribution_handle), mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, distribution)
+    ccall((:AMGX_matrix_upload_distributed, libAMGX), AMGX_RC, (AMGX_matrix_handle, Cint, Cint, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, AMGX_distribution_handle), mtx, n_global, n, nnz, block_dimx, block_dimy, row_ptrs, col_indices_global, data, diag_data, distribution)
 end
 
 function AMGX_solver_register_print_callback(func)
-    @runtime_ccall((:AMGX_solver_register_print_callback, libAMGX), AMGX_RC, (AMGX_print_callback,), func)
+    ccall((:AMGX_solver_register_print_callback, libAMGX), AMGX_RC, (AMGX_print_callback,), func)
 end
 
 function AMGX_solver_resetup(slv, mtx)
-    @runtime_ccall((:AMGX_solver_resetup, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_matrix_handle), slv, mtx)
+    ccall((:AMGX_solver_resetup, libAMGX), AMGX_RC, (AMGX_solver_handle, AMGX_matrix_handle), slv, mtx)
 end
 # Julia wrapper for header: amgx_config.h
 # Automatically generated using Clang.jl
diff --git a/lib/libAMGX_common.jl b/lib/libAMGX_common.jl
index 8323d92..aafaf32 100644
--- a/lib/libAMGX_common.jl
+++ b/lib/libAMGX_common.jl
@@ -38,7 +38,7 @@ end
     AMGX_SOLVE_SUCCESS = 0
     AMGX_SOLVE_FAILED = 1
     AMGX_SOLVE_DIVERGED = 2
-    AMGX_SOLVE_NOT_CONVERGED = 2
+    AMGX_SOLVE_NOT_CONVERGED = 3
 end
 
 @cenum AMGX_GET_PARAMS_DESC_FLAG::UInt32 begin
diff --git a/src/AMGX.jl b/src/AMGX.jl
index c03f671..daf598e 100644
--- a/src/AMGX.jl
+++ b/src/AMGX.jl
@@ -38,45 +38,6 @@ end
 #########
 
 module API
-    using Libdl
-    # Taken from LLVM.jl, can be removed when package only supports 1.6 and higher
-    macro runtime_ccall(target, args...)
-        if VERSION >= v"1.6.0-DEV.819"
-            quote
-                ccall($(esc(target)), $(map(esc, args)...))
-            end
-        else
-            # decode ccall function/library target
-            Meta.isexpr(target, :tuple) || error("Expected (function_name, library) tuple")
-            function_name, library = target.args
-
-            # global const ref to hold the function pointer
-            @gensym fptr_cache
-            @eval __module__ begin
-                # uses atomics (release store, acquire load) for thread safety.
-                # see https://github.com/JuliaGPU/CUDAapi.jl/issues/106 for details
-                const $fptr_cache = Threads.Atomic{UInt}(0)
-            end
-
-            quote
-                # use a closure to hold the lookup and avoid code bloat in the caller
-                @noinline function cache_fptr!()
-                    library = Libdl.dlopen($(esc(library)))
-                    $(esc(fptr_cache))[] = Libdl.dlsym(library, $(esc(function_name)))
-
-                    $(esc(fptr_cache))[]
-                end
-
-                fptr = $(esc(fptr_cache))[]
-                if fptr == 0        # folded into the null check performed by ccall
-                    fptr = cache_fptr!()
-                end
-
-                ccall(reinterpret(Ptr{Cvoid}, fptr), $(map(esc, args)...))
-            end
-        end
-    end
-
     using CEnum
     import ..libAMGX
 
diff --git a/src/Config.jl b/src/Config.jl
index fa7521e..d9281ad 100644
--- a/src/Config.jl
+++ b/src/Config.jl
@@ -19,8 +19,11 @@ end
 Config(content::String) = create!(Config(), content)
 
 function create!(config::Config, d::Dict)
-    str = sprint(JSON.print, d)
-    create!(config, str)
+    buf = IOBuffer()
+    for (key, val) in d
+        write(buf, "$key=$val,")
+    end
+    create!(config, String(take!(buf)))
 end
 Config(d::Dict) = create!(Config(), d)
 
diff --git a/src/Solver.jl b/src/Solver.jl
index a881e9d..9567e30 100644
--- a/src/Solver.jl
+++ b/src/Solver.jl
@@ -42,6 +42,12 @@ function setup!(solver::Solver, matrix::AMGXMatrix)
     return solver
 end
 
+function resetup!(solver::Solver, matrix::AMGXMatrix)
+    solver.bound_matrix == matrix || throw(ArgumentError("Matrix is not the same as the one bound to the solver"))
+    @checked API.AMGX_solver_resetup(solver.handle, matrix.handle)
+    return solver
+end
+
 function solve!(sol::AMGXVector, solver::Solver, rhs::AMGXVector; zero_inital_guess::Bool=false)
     if solver.bound_matrix === nothing 
         error("no matrix attached to solver")
@@ -59,8 +65,7 @@ end
 function get_iterations_number(solver::Solver)
     n_ptr = Ref{Cint}()
     @checked API.AMGX_solver_get_iterations_number(solver.handle, n_ptr)
-    # for some reason AMGX returns 1 + number of iterations.
-    return Int(n_ptr[]) - 1
+    return Int(n_ptr[])
 end
 
 function get_iteration_residual(solver::Solver, iter::Int=get_iterations_number(solver), block_idx::Int=0)
@@ -73,6 +78,7 @@ end
    SUCCESS = Int(API.AMGX_SOLVE_SUCCESS)
    FAILED = Int(API.AMGX_SOLVE_FAILED)
    DIVERGED = Int(API.AMGX_SOLVE_DIVERGED)
+   NOT_CONVERGED = Int(API.AMGX_SOLVE_NOT_CONVERGED)
 end
 
 function get_status(solver::Solver)
diff --git a/test/test_solver.jl b/test/test_solver.jl
index c522140..a1fd6d7 100644
--- a/test/test_solver.jl
+++ b/test/test_solver.jl
@@ -18,11 +18,44 @@ using AMGX: Config, Resources, AMGXVector, AMGXMatrix, Solver, dDDI, dFFI
         AMGX.upload!(x, [0.0, 0.0, 0.0])
         AMGX.upload!(b, [1.0, 2.0, 4.0])
 
+        AMGX.setup!(s, M)
+        AMGX.solve!(x, s, b)
+        x_h = AMGX.download(b)
+        @test x_h ≈ [1.0, 2.0, 4.0]
+
+        AMGX.upload!(x, [1.0, 2.0, 3.0])
+        AMGX.solve!(x, s, b; zero_inital_guess=true)
+        x_h = AMGX.download(x)
+        @test x_h ≈ [1.0, 2.0, 4.0]
+
+        # We can reuse the same sparsity structure, but change the coefficients
+        AMGX.replace_coefficients!(M, [0.1, 0.1, 0.1])
+        AMGX.resetup!(s, M)
+        AMGX.solve!(x, s, b)
+        x_h2 = AMGX.download(x)
+        @test x_h2 ≈ [10.0, 20.0, 40.0]
+    end
+
+    @scope @testset "solver with residuals" begin
+        # Same test as above, but this time output residuals.
+        c = @! Config(Dict("monitor_residual" => 1))
+        r = @! Resources(c)
+        M = @! AMGXMatrix(r, mode)
+        x = @! AMGXVector(r, mode)
+        b = @! AMGXVector(r, mode)
+        s = @! Solver(r, mode, c)
+
+        AMGX.upload!(M, Cint[0, 1, 2, 3], Cint[0, 1, 2], [1.0, 1.0, 1.0])
+        AMGX.upload!(x, [0.0, 0.0, 0.0])
+        AMGX.upload!(b, [1.0, 2.0, 4.0])
+
         AMGX.setup!(s, M)
         AMGX.solve!(x, s, b)
         x_h = AMGX.download(b)
         @test x_h ≈ [1.0, 2.0, 4.0]
         status = AMGX.get_status(s)
+        # Note: If we don't set monitor_residual, the status flag does not
+        # reflect if the solution has converged or not.
         @test status == AMGX.SUCCESS
 
         AMGX.upload!(x, [1.0, 2.0, 3.0])
@@ -46,7 +79,7 @@ using AMGX: Config, Resources, AMGXVector, AMGXMatrix, Solver, dDDI, dFFI
         AMGX.upload!(b, [1.0, 2.0, 4.0])
         AMGX.setup!(s, M)
         AMGX.solve!(x, s, b; zero_inital_guess=true)
-        @test AMGX.get_status(s) == AMGX.DIVERGED
+        @test AMGX.get_status(s) == AMGX.NOT_CONVERGED
         @test AMGX.get_iterations_number(s) == 0
         @test AMGX.get_iteration_residual(s) > 1.0
 
@@ -55,7 +88,7 @@ using AMGX: Config, Resources, AMGXVector, AMGXMatrix, Solver, dDDI, dFFI
     end
 
     @scope @testset "get_iterations_number" begin
-        c = @! Config(Dict("monitor_residual" => 1, "tolerance" => 1e-14, "store_res_history" => 1))
+        c = @! Config(Dict("monitor_residual" => 1, "tolerance" => "1e-14", "store_res_history" => 1))
         r = @! Resources(c)
         M = @! AMGXMatrix(r, mode)
         x = @! AMGXVector(r, mode)
@@ -67,8 +100,9 @@ using AMGX: Config, Resources, AMGXVector, AMGXMatrix, Solver, dDDI, dFFI
         AMGX.upload!(b, [1.0, 2.0, 4.0])
         AMGX.setup!(s, M)
         AMGX.solve!(x, s, b)
-        @test AMGX.get_iteration_residual(s) < 1e-14
         niter = AMGX.get_iterations_number(s)
+        @test niter > 0
+        @test AMGX.get_iteration_residual(s) < 1e-14
         @test AMGX.get_iteration_residual(s, niter) == AMGX.get_iteration_residual(s)
     end
 end