Class: Ignis::Solver::AMGXSolver

Inherits:
Object
  • Object
show all
Defined in:
lib/nvruby/solver/amgx_solver.rb

Overview

GPU-accelerated algebraic multigrid solver using NVIDIA AMGX Solves sparse linear systems Ax = b

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config: :classical_v_cycle, precision: :double, device: true) ⇒ AMGXSolver

Returns a new instance of AMGXSolver.

Parameters:

  • config (Symbol, String, AMGXConfig) (defaults to: :classical_v_cycle)

    Configuration (preset symbol, string, or AMGXConfig)

  • precision (Symbol) (defaults to: :double)

    :double or :float

  • device (Boolean) (defaults to: true)

    Use GPU (true) or CPU (false)



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/nvruby/solver/amgx_solver.rb', line 26

def initialize(config: :classical_v_cycle, precision: :double, device: true)
  AMGXBindings.ensure_loaded!

  @config = case config
            when Symbol
              AMGXConfig.new(preset: config)
            when String
              AMGXConfig.new(custom: config)
            when AMGXConfig
              config
            else
              raise ArgumentError, "Invalid config type: #{config.class}"
            end

  @precision = precision
  @device = device
  @mode = determine_mode
  @initialized = false
  @iterations = 0
  @residual = 0.0

  initialize_amgx!
end

Instance Attribute Details

#configAMGXConfig (readonly)

Returns Solver configuration.

Returns:



12
13
14
# File 'lib/nvruby/solver/amgx_solver.rb', line 12

def config
  @config
end

#iterationsInteger (readonly)

Returns Number of iterations from last solve.

Returns:

  • (Integer)

    Number of iterations from last solve



18
19
20
# File 'lib/nvruby/solver/amgx_solver.rb', line 18

def iterations
  @iterations
end

#precisionSymbol (readonly)

Returns Precision mode (:double or :float).

Returns:

  • (Symbol)

    Precision mode (:double or :float)



15
16
17
# File 'lib/nvruby/solver/amgx_solver.rb', line 15

def precision
  @precision
end

#residualFloat (readonly)

Returns Final residual from last solve.

Returns:

  • (Float)

    Final residual from last solve



21
22
23
# File 'lib/nvruby/solver/amgx_solver.rb', line 21

def residual
  @residual
end

Class Method Details

.release_finalizer(solver, sol, rhs, matrix, resources, config) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
# File 'lib/nvruby/solver/amgx_solver.rb', line 237

def release_finalizer(solver, sol, rhs, matrix, resources, config)
  proc do
    AMGXBindings.AMGX_solver_destroy(solver) if solver && !solver.null?
    AMGXBindings.AMGX_vector_destroy(sol) if sol && !sol.null?
    AMGXBindings.AMGX_vector_destroy(rhs) if rhs && !rhs.null?
    AMGXBindings.AMGX_matrix_destroy(matrix) if matrix && !matrix.null?
    AMGXBindings.AMGX_resources_destroy(resources) if resources && !resources.null?
    AMGXBindings.AMGX_config_destroy(config) if config && !config.null?
    AMGXBindings.AMGX_finalize
  end
end

Instance Method Details

#destroy!void

This method returns an undefined value.

Release all AMGX resources



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/nvruby/solver/amgx_solver.rb', line 95

def destroy!
  return unless @initialized

  AMGXBindings.AMGX_solver_destroy(@solver_handle) if @solver_handle
  AMGXBindings.AMGX_vector_destroy(@sol_handle) if @sol_handle
  AMGXBindings.AMGX_vector_destroy(@rhs_handle) if @rhs_handle
  AMGXBindings.AMGX_matrix_destroy(@matrix_handle) if @matrix_handle
  AMGXBindings.AMGX_resources_destroy(@resources_handle) if @resources_handle
  AMGXBindings.AMGX_config_destroy(@config_handle) if @config_handle
  AMGXBindings.AMGX_finalize

  @initialized = false
end

#solve(a, b, x0: nil) ⇒ Array<Float>

Solve sparse linear system Ax = b

Parameters:

  • a (Hash)

    Sparse matrix in CSR format { row_ptr:, col_idx:, values:, n:, nnz: }

  • b (Array<Float>, NvArray)

    Right-hand side vector

  • x0 (Array<Float>, NvArray, nil) (defaults to: nil)

    Initial guess (nil for zero)

Returns:

  • (Array<Float>)

    Solution vector

Raises:



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/nvruby/solver/amgx_solver.rb', line 55

def solve(a, b, x0: nil)
  raise AMGXError, "Solver not initialized" unless @initialized

  n = a[:n]
  nnz = a[:nnz]

  upload_matrix(a)
  upload_vector(@rhs_handle, b)

  if x0
    upload_vector(@sol_handle, x0)
    rc = AMGXBindings.AMGX_solver_solve(@solver_handle, @rhs_handle, @sol_handle)
  else
    rc = AMGXBindings.AMGX_solver_solve_with_0_initial_guess(
      @solver_handle, @rhs_handle, @sol_handle
    )
  end
  AMGXBindings.check_rc!(rc, "AMGX_solver_solve")

  update_solve_stats!
  download_solution(n)
end

#statusSymbol

Get solve status

Returns:

  • (Symbol)

    :success, :failed, :diverged, or :not_converged



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/nvruby/solver/amgx_solver.rb', line 80

def status
  status_ptr = FFI::MemoryPointer.new(:int)
  AMGXBindings.AMGX_solver_get_status(@solver_handle, status_ptr)

  case status_ptr.read_int
  when AMGXBindings::SolveStatus::SUCCESS then :success
  when AMGXBindings::SolveStatus::FAILED then :failed
  when AMGXBindings::SolveStatus::DIVERGED then :diverged
  when AMGXBindings::SolveStatus::NOT_CONVERGED then :not_converged
  else :unknown
  end
end