---
include: rocblas_common.yaml
include: known_bugs.yaml

Definitions:
  - &small_matrix_size_range
    - { M:    10, N:    10, lda:    2, stride_a:        1 }
    - { M:   100, N:   200, lda:  200, stride_a:    40000 }

  - &qmcpack_matrix_size_range
    - { M:    2 , N:    32, lda:    2, stride_a:       64 }
    - { M:    32, N:    32, lda:   32, stride_a:     1024 }
    - { M:    15, N:    33, lda:   16, stride_a:     1024 }
    - { M:    32, N:  1536, lda:   32, stride_a:    49152 }

  - &skinny_n_matrix_size_range
    # n <= 128 && m >= 2048 * n
    - { M:  32000, N:  11, lda:    32000, stride_a:   352000 }
    - { M:  81920, N:  40, lda:    81920, stride_a:  3276800 }
    - { M:  20480, N:   7, lda:    20480, stride_a:   143360 }
    - { M: 131071, N:  63, lda:   131071, stride_a:  8257473 }

  - &all_algo_matrix_size_range
    - { M:  4096, N:    2, lda:  4096, stride_a:     8192 } # skinny n
    - { M:    32, N:    32, lda:   32, stride_a:     1024 }
    - { M:   100, N:   200, lda:  200, stride_a:    40000 }

  - &size_t_idx_all_algo_matrix_size_range
    - { M: 12000, N:    5,  lda:  536870912,  stride_a: 536870912 } # skinny n
    - { M:    16, N:    5,  lda:  536870912,  stride_a: 536870912 }

  - &special_case_range
    # Quick return
    - { M:    0, N:    1, lda:    1, incx: 1, incy: 1, batch_count: 1 }
    - { M:    1, N:    0, lda:    1, incx: 1, incy: 1, batch_count: 1 }
    - { M:    1, N:    1, lda:    1, incx: 1, incy: 1, batch_count: 0 }

    # invalid_arg checks
    - { M:   -1, N:    0, lda:    1, incx: 1, incy: 1, batch_count:  0 }
    - { M:    0, N:   -1, lda:    1, incx: 1, incy: 1, batch_count:  0 }
    - { M:    5, N:    5, lda:    4, incx: 1, incy: 1, batch_count:  0 }
    - { M:    0, N:    0, lda:    0, incx: 1, incy: 1, batch_count:  0 }
    - { M:    0, N:    0, lda:    1, incx: 0, incy: 1, batch_count:  0 }
    - { M:    0, N:    0, lda:    1, incx: 1, incy: 0, batch_count:  0 }
    - { M:    0, N:    0, lda:    1, incx: 1, incy: 1, batch_count: -1 }

  - &medium_matrix_size_range
    - { M:   300, N:   400, lda:  400, stride_a:   160000 }
    - { M:   600, N:   500, lda:  601, stride_a:   301000 }

  - &large_matrix_size_range
    - { M:  1000, N:  1000,  lda: 1000,  stride_a:  1000000 }
    - { M:  2000, N:  2000,  lda: 2000,  stride_a:  4000000 }
    - { M:  4011, N:  4011,  lda: 4011,  stride_a: 16088200 }
    - { M:  8000, N:  8000,  lda: 8000,  stride_a: 64000000 }

  - &very_large_matrix_size_range
    - { M:  16010, N: 16010, lda: 16010, stride_a: 256320100 }
    - { M:  25020, N: 25020, lda: 25020, stride_a: 625000400 }

  - &incx_incy_range
    - { incx:   2, incy:   1, stride_scale: 1   }
    - { incx:  -1, incy:   2, stride_scale: 1   }
    - { incx:   1, incy:   1, stride_scale: 1   }
    - { incx:  -1, incy:   3, stride_scale: 1.5 }
    - { incx:   3, incy:  -1, stride_scale: 2   }
    - { incx:  10, incy: 100, stride_scale: 1   }

  - &incx_incy_range_small
    - { incx: 2, incy: 2, stride_scale: 1 }

  - &incx_incy_unity
    - { incx: 1, incy: 1, stride_scale: 1 }

  - &alpha_beta_range
    - { alpha:  2.0, beta:  0.0, alphai: 1.5, betai: 0.5 }
    - { alpha: -1.0, beta: -1.0, alphai: 0.5, betai: 1.5 }
    - { alpha:  2.0, beta:  1.0, alphai: -1.5, betai: 0.5 }
    - { alpha:  0.0, beta:  1.0, alphai: -0.5, betai: 0 }

  - &alpha_beta_range_small
    - { alpha: 2.0, beta: 2.0, alphai: 1.5, betai: -1.5 }

Tests:
# Regular gemv
- name: gemv_bad_arg
  category: pre_checkin
  function: gemv_bad_arg
  precision: *single_double_precisions
  transA: N
  fortran: [ false, true ]

- name: gemv_arg_check
  category: quick
  function: gemv
  precision: *single_double_precisions
  transA: N

- name: gemv_NaN
  category: pre_checkin
  function: gemv
  precision: *single_double_precisions
  transA: [ N, T ]
  matrix_size: *all_algo_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha: [ 1.0, .NaN ]  # NaN is converted to 0.0 in test code
  beta: [ 0.5, 1.0, .NaN ]

- name: gemv_fortran
  category: quick
  function: gemv
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  fortran: true

- name: gemv_small
  category: quick
  function: gemv
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *small_matrix_size_range
  incx_incy: *incx_incy_range
  alpha_beta: *alpha_beta_range

- name: gemv_medium
  category: pre_checkin
  function: gemv
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *medium_matrix_size_range
  incx_incy: *incx_incy_range
  alpha_beta: *alpha_beta_range

- name: gemv_medium_HMM
  category: HMM
  function: gemv
  precision: *single_double_precisions_complex_real
  transA: [ N ]
  matrix_size: *medium_matrix_size_range
  incx: -1
  incy: 2
  alpha: 1
  beta: 1

- name: gemv_medium_multi_gpu
  category: multi_gpu
  function: gemv
  precision: *single_double_precisions
  transA: [ N, T ]
  matrix_size: *medium_matrix_size_range
  incx: 2
  incy: 1
  alpha_beta: *alpha_beta_range
  threads_streams: *common_threads_streams
  devices: [0, 2, 4]

- name: gemv_medium_multi_threads_streams
  category: nightly
  function: gemv
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *medium_matrix_size_range
  incx: 2
  incy: 1
  alpha_beta: *alpha_beta_range
  threads_streams: *common_threads_streams

- name: gemv_large
  category: nightly
  function: gemv
  precision: *single_double_precisions_complex_real
  transA: [  N, T, C ]
  matrix_size: *large_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small

- name: gemv_very_large
  category: nightly
  function: gemv
  precision: *double_precision
  transA: [ N ]
  matrix_size: *very_large_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small

- name: gemv_skinny_n
  category: pre_checkin
  function: gemv
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *skinny_n_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range

- name: gemv_lda
  category: nightly
  function: gemv
  precision: *single_precision
  transA: [  N, T, C ]
  matrix_size: *size_t_idx_all_algo_matrix_size_range
  incx_incy: *incx_incy_unity
  alpha_beta: *alpha_beta_range_small

# gemv_batched
- name: gemv_batched_bad_arg
  category: pre_checkin
  function: gemv_batched_bad_arg
  precision: *single_double_precisions
  transA: N
  fortran: [ false, true ]

- name: gemv_batched_arg_check
  category: quick
  function: gemv_batched
  precision: *single_double_precisions
  transA: N

- name: gemv_batched_NaN
  category: pre_checkin
  function: gemv_batched
  precision: *single_double_precisions
  transA: [ N, T, C ]
  matrix_size: *all_algo_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha: [ 1.0, 2.0, .NaN ] # NaN is converted to 0.0 in test code
  beta: [2.0, 1.0, .NaN ]
  batch_count: [ 2, 9 ] # 9 for qmc_pack algo

- name: gemv_batched_fortran
  category: quick
  function: gemv_batched
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ -1, 0, 3 ]
  fortran: true

- name: gemv_batched_skinny_n
  category: pre_checkin
  function: gemv_batched
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *skinny_n_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ 3 ]

- name: gemv_batched_small
  category: quick
  function: gemv_batched
  precision: *single_double_precisions
  transA: [ N, T, C ]
  matrix_size: *small_matrix_size_range
  incx_incy: *incx_incy_range
  alpha_beta: *alpha_beta_range
  batch_count: [ -1, 0, 1, 3 ]

- name: gemv_batched_qmcpack
  category: quick
  function: gemv_batched
  precision: *single_double_precisions_complex_real
  transA: [ T, C ]
  matrix_size: *qmcpack_matrix_size_range
  incx: [ 2 ]
  incy: [ 2 ]
  alpha_beta: *alpha_beta_range
  batch_count: [ 100, 1000 ]

- name: gemv_batched_medium
  category: pre_checkin
  function: gemv_batched
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *medium_matrix_size_range
  incx_incy: *incx_incy_range
  alpha_beta: *alpha_beta_range
  batch_count: [ 3 ]

- name: gemv_batched_large
  category: nightly
  function: gemv_batched
  precision: *single_double_precisions
  transA: [ N, T, C ]
  matrix_size: *large_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ 3 ]

- name: gemv_batched_very_large
  category: nightly
  function: gemv_batched
  precision: *double_precision
  transA: [ N ]
  matrix_size: *very_large_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ 3 ]

# gemv_strided_batched
- name: gemv_strided_batched_bad_arg
  category: pre_checkin
  function: gemv_strided_batched_bad_arg
  precision: *single_double_precisions
  transA: N
  fortran: [ false, true ]

- name: gemv_strided_batched_arg_check
  category: quick
  function: gemv_strided_batched
  precision: *single_double_precisions
  transA: N

- name: gemv_strided_batched_NaN
  category: pre_checkin
  function: gemv_strided_batched
  precision: *single_double_precisions
  transA: [ N, T, C ]
  matrix_size: *all_algo_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha: [ 2.0, .NaN ] # NaN converted to 0.0 in test code
  beta:  [ 0.5, 1.0, .NaN ]
  batch_count: [ 2 ]

- name: gemv_strided_batched_fortran
  category: quick
  function: gemv_strided_batched
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ -1, 0, 3 ]
  fortran: true

- name: gemv_strided_batched_small
  category: quick
  function: gemv_strided_batched
  precision: *single_double_precisions
  transA: [ N, T, C ]
  matrix_size: *small_matrix_size_range
  incx_incy: *incx_incy_range
  alpha_beta: *alpha_beta_range
  batch_count: [ -1, 0, 1, 3 ]

- name: gemv_strided_batched_skinny_n
  category: pre_checkin
  function: gemv_strided_batched
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *skinny_n_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ 3 ]


- name: gemv_strided_batched_qmcpack
  category: quick
  function: gemv_strided_batched
  precision: *single_double_precisions_complex_real
  transA: [ T, C ]
  matrix_size: *qmcpack_matrix_size_range
  incx: [ 2 ]
  incy: [ 2 ]
  stride_scale: 1
  alpha_beta: *alpha_beta_range
  batch_count: [ 64, 512 ]

- name: gemv_strided_batched_medium
  category: pre_checkin
  function: gemv_strided_batched
  precision: *single_double_precisions_complex_real
  transA: [ N, T, C ]
  matrix_size: *medium_matrix_size_range
  incx_incy: *incx_incy_range
  alpha_beta: *alpha_beta_range
  batch_count: [ 3 ]

- name: gemv_strided_batched_large
  category: nightly
  function: gemv_strided_batched
  precision: *single_double_precisions
  transA: [ N, T, C ]
  matrix_size: *large_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ 3 ]

- name: gemv_strided_batched_very_large
  category: nightly
  function: gemv_strided_batched
  precision: *double_precision
  transA: [ N ]
  matrix_size: *very_large_matrix_size_range
  incx_incy: *incx_incy_range_small
  alpha_beta: *alpha_beta_range_small
  batch_count: [ 3 ]
...
