跳到主要内容

muSOLVER API 参考

函数

名称
MUSOLVER_EXPORT mublasStatus_tmusolverXgetrs_bufferSize(mublasOperation_t trans, const int n, const int nrhs, int * buffersize)
计算 GETRS 函数所需的工作空间缓冲区大小。
MUSOLVER_EXPORT mublasStatus_tmusolverXgetrs(mublasHandle_t handle, const mublasOperation_t trans, const int n, const int nrhs, float * A, const int lda, const int * ipiv, float * B, const int ldb, void * buffer)
GETRS 在其分解形式中解 n 个线性方程组。
MUSOLVER_EXPORT mublasStatus_tmusolverXgelsBatched_bufferSize(mublasOperation_t trans, const int m, const int n, const int nrhs, const int batch_count, int * buffer_size)
计算解决一批广义最小二乘问题的所需工作空间缓冲区大小。
MUSOLVER_EXPORT mublasStatus_tmusolverXgelsBatched(mublasHandle_t handle, mublasOperation_t trans, const int m, const int n, const int nrhs, muComplex *const A[], const int lda, muComplex *const B[], const int ldb, int * info, const int batch_count, void * buffer)
GELS_BATCHED 使用 GEQRF_BATCHED 计算的 QR 分解(或 GELQF_BATCHED 计算的 LQ 分解)解决一批超定(或欠定)线性方程组。
MUSOLVER_EXPORT mublasStatus_tmusolverXgetrf_bufferSize(const int m, const int n, const bool pivot, int * buffersize)
计算一般 m-by-n 矩阵 A 的 LU 分解所需的工作空间大小。
MUSOLVER_EXPORT mublasStatus_tmusolverXgetrf(mublasHandle_t handle, const int m, const int n, float * A, const int lda, int * ipiv, int * info, void * buffer)
GETRF 使用行交换的部分主元进行一般 m-by-n 矩阵 A 的 LU 分解。
MUSOLVER_EXPORT mublasStatus_tmusolverXgetriBatched(mublasHandle_t handle, const int n, float *const A[], const int lda, int * ipiv, const int strideP, int * info, const int batch_count)
GETRI_BATCHED 使用 GETRF_BATCHED 计算的 LU 分解来求一批 n-by-n 矩阵的逆。
MUSOLVER_EXPORT mublasStatus_tmusolverXgetrfBatched_bufferSize(const int m, const int n, const bool pivot, const int batch_count, int * buffersize)
计算一批一般 m-by-n 矩阵的 LU 分解所需的缓冲区大小。
MUSOLVER_EXPORT mublasStatus_tmusolverXgetrfBatched(mublasHandle_t handle, const int m, const int n, float *const A[], const int lda, int * ipiv, const int strideP, int * info, const int batch_count, void * buffer)
GETRF_BATCHED 使用行交换的部分主元对一批一般 m-by-n 矩阵进行 LU 分解。

函数文档

函数 musolverXgetrs_bufferSize

MUSOLVER_EXPORT mublasStatus_t musolverXgetrs_bufferSize(
mublasOperation_t trans,
const int n,
const int nrhs,
int * buffersize
)

计算 GETRS 函数所需的工作空间缓冲区大小。

参数

  • trans mublasOperation_t。

指定方程组的形式。确定是使用 AAATA^TAHA^H 解决系统。

  • n int. n >= 0.

系统的阶数,即矩阵 A 的行数和列数。

  • nrhs int. nrhs >= 0.

右手边的数量,即矩阵 B 的列数。

  • buffersize 指向 int 的指针。

musolverXgetrs 函数所需的工作空间缓冲区大小。这个值应该用来为缓冲区分配足够的内存。

这个函数确定 musolverXgetrs 函数所需的工作空间缓冲区大小。缓冲区大小取决于方程组的大小和右手边的数量。

在调用 musolverXgetrs 之前,先调用这个函数来获取缓冲区大小。分配至少这个函数返回大小的缓冲区,并将其实作为 buffer 参数传递给 musolverXgetrs

这个函数计算的缓冲区大小确保在求解操作期间内部工作空间有足够的空间。

MUSOLVER_EXPORT mublasStatus_t musolverSgetrs_bufferSize(mublasOperation_t trans,
const int n,
const int nrhs,
int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverDgetrs_bufferSize(mublasOperation_t trans,
const int n,
const int nrhs,
int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverCgetrs_bufferSize(mublasOperation_t trans,
const int n,
const int nrhs,
int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverZgetrs_bufferSize(mublasOperation_t trans,
const int n,
const int nrhs,
int* buffersize);

函数 musolverXgetrs

MUSOLVER_EXPORT mublasStatus_t musolverXgetrs(
mublasHandle_t handle,
const mublasOperation_t trans,
const int n,
const int nrhs,
float * A,
const int lda,
const int * ipiv,
float * B,
const int ldb,
void * buffer
)

GETRS 解 n 个变量的 n 个线性方程组的分解形式。

参数

  • handle mublasHandle_t .
  • trans mublasOperation_t.

指定方程组的形式。

  • n int. n >= 0.

系统的阶数,即 A 的列数和行数。

  • nrhs int. nrhs >= 0.

右手边的数量,即矩阵 B 的列数。

  • A 类型指针。GPU 上的数组,维度为 lda*n。

分解 A = PLU 返回的 L 和 U 因子。

  • lda int. lda >= n.

A 的领先维度。

  • ipiv 指向 int 的指针。GPU 上的数组,维度为 n。

GETRF 返回的枢轴索引。

  • B 类型指针。GPU 上的数组,维度为 ldb*nrhs。

输入时,右手边矩阵 B。输出时,解矩阵 X。

  • ldb int. ldb >= n.

B 的领先维度。

  • buffer 指向 void 的指针。为分解过程分配的工作空间缓冲区。这个缓冲区的大小应该由之前的 [musolverXgetrf_bufferSize()](#function-musolverxgetrf-buffersize) 调用确定。缓冲区在分解过程中内部使用,存储临时数据。

根据 trans 的值,它解决以下系统之一:

AX=B不转置,ATX=B转置, 或AHX=B共轭转置.\begin{array}{cl} A X = B & \text{不转置,} \\ A^T X = B & \text{转置, 或} \\ A^H X = B & \text{共轭转置.} \end{array}

矩阵 A 由 GETRF 返回的三角因子定义。

MUSOLVER_EXPORT mublasStatus_t musolverSgetrs(mublasHandle_t handle,
const mublasOperation_t trans,
const int n,
const int nrhs,
float* A,
const int lda,
const int* ipiv,
float* B,
const int ldb,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverDgetrs(mublasHandle_t handle,
const mublasOperation_t trans,
const int n,
const int nrhs,
double* A,
const int lda,
const int* ipiv,
double* B,
const int ldb,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverCgetrs(mublasHandle_t handle,
const mublasOperation_t trans,
const int n,
const int nrhs,
muComplex* A,
const int lda,
const int* ipiv,
muComplex* B,
const int ldb,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverZgetrs(mublasHandle_t handle,
const mublasOperation_t trans,
const int n,
const int nrhs,
muDoubleComplex* A,
const int lda,
const int* ipiv,
muDoubleComplex* B,
const int ldb,
void* buffer);

函数 musolverXgelsBatched_bufferSize

MUSOLVER_EXPORT mublasStatus_t musolverXgelsBatched_bufferSize(
mublasOperation_t trans,
const int m,
const int n,
const int nrhs,
const int batch_count,
int * buffer_size
)

计算解决一批广义最小二乘问题的所需工作空间缓冲区大小。

参数

  • trans mublasOperation_t。

指定矩阵操作的形式(无、转置或共轭转置)。

  • m int. m >= 0.

矩阵(A)的行数。

  • n int. n >= 0.

矩阵(A)的列数。

  • nrhs int. nrhs >= 0.

右手边的数量(即矩阵(B)的列数)。

  • batch_count int. batch_count >= 0.

批次中的矩阵数量。

  • buffer_size 指向 int 的指针。

输出时,计算所需的工作空间缓冲区大小。大小以字节为单位。

这个函数计算执行一批矩阵的广义最小二乘计算所需的缓冲区大小。缓冲区大小取决于矩阵尺寸、右手边的数量和批次计数。

工作空间缓冲区由 musolverXgelsBatched 函数内部使用进行计算。在调用 musolverXgelsBatched 之前,必须用这个函数确定的大小分配缓冲区。

MUSOLVER_EXPORT mublasStatus_t musolverCgelsBatched_bufferSize(mublasOperation_t trans,
const int m,
const int n,
const int nrhs,
const int batch_count,
int* buffer_size);

函数 musolverXgelsBatched

MUSOLVER_EXPORT mublasStatus_t musolverXgelsBatched(
mublasHandle_t handle,
mublasOperation_t trans,
const int m,
const int n,
const int nrhs,
muComplex *const A[],
const int lda,
muComplex *const B[],
const int ldb,
int * info,
const int batch_count,
void * buffer
)

GELS_BATCHED 解决由一批 m-by-n 矩阵 AjA_j 和相应的矩阵 BjB_j 定义的超定(或欠定)线性方程组,使用 GEQRF_BATCHED 计算的 QR 分解(或 GELQF_BATCHED 计算的 LQ 分解)。

参数

  • handle mublasHandle_t .
  • trans mublasOperation_t.

指定方程组的形式。

  • m int. m >= 0.

批次中所有矩阵 A_j 的行数。

  • n int. n >= 0.

批次中所有矩阵 A_j 的列数。

  • nrhs int. nrhs >= 0.

批次中所有矩阵 B_j 和 X_j 的列数;即右手边的列数。

  • A 类型指针数组。每个指针指向 GPU 上的数组,维度为 lda*n。

输入时,矩阵 A_j。输出时,QR(或 LQ)分解 A_j 如 GEQRF_BATCHED(或 GELQF_BATCHED)返回。

  • lda int. lda >= m.

指定矩阵 A_j 的领先维度。

  • B 类型指针数组。每个指针指向 GPU 上的数组,维度为 ldb*nrhs。

输入时,矩阵 B_j。输出时,当 info[j] = 0 时,B_j 被解向量(和超定情况下的残差)覆盖,存储为列。

  • ldb int. ldb >= max(m,n)。

指定矩阵 B_j 的领先维度。

  • info 指向 int 的指针。GPU 上的 batch_count 整数数组。

如果 info[j] = 0,则 A_j 的解成功退出。如果 info[j] = i > 0,则解 A_j 无法计算,因为输入矩阵 A_j 秩不足;其三角因子的第 i 个对角元素为零。

  • batch_count int. batch_count >= 0.

批次中的矩阵数量。

对于批次中的每个实例,根据 trans 的值,这个函数解决的问题形式为

AjXj=Bj不转置, 或AjXj=Bj如果实数则转置, 或复数则共轭转置\begin{array}{cl} A_j X_j = B_j & \text{不转置, 或}\\ A_j' X_j = B_j & \text{如果实数则转置, 或复数则共轭转置} \end{array}

如果 mnm \geq n(或在转置/共轭转置的情况下 m<nm < n),系统是超定的,通过最小化

BjAjXj(或:BjAjXj)\| B_j - A_j X_j | \quad \text{(或} : | B_j - A_j' X_j |\text{)}

找到近似解 XjX_j

如果 m<nm < n(或在转置/共轭转置的情况下 mnm \geq n),系统是欠定的,选择一个唯一的解 XjX_j,使得 Xj| X_j | 最小。

MUSOLVER_EXPORT mublasStatus_t musolverCgelsBatched(mublasHandle_t handle,
mublasOperation_t trans,
const int m,
const int n,
const int nrhs,
muComplex* const A[],
const int lda,
muComplex* const B[],
const int ldb,
int* info,
const int batch_count,
void* buffer);

函数 musolverXgetrf_bufferSize

MUSOLVER_EXPORT mublasStatus_t musolverXgetrf_bufferSize(
const int m,
const int n,
const bool pivot,
int * buffersize
)

计算一般 m-by-n 矩阵 A 的 LU 分解所需的工作空间大小。

参数

  • m int. m >= 0. 矩阵 A 的行数。
  • n int. n >= 0. 矩阵 A 的列数。
  • pivot bool. 表示是否使用主元。如果为 true,则执行主元;否则,不执行。
  • buffersize 指向 int 的指针。输出时,LU 分解所需的工作空间缓冲区大小。大小以字节为单位。

这个函数计算使用行交换的部分主元对矩阵 A 进行 LU 分解所需的工作空间缓冲区大小。在执行 LU 分解之前,重要的是确定这个缓冲区大小。大小根据矩阵尺寸和主元选项计算。这些信息用于为 LU 分解操作分配足够的内存。

MUSOLVER_EXPORT mublasStatus_t musolverSgetrf_bufferSize(const int m,
const int n,
const bool pivot,
int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverDgetrf_bufferSize(const int m,
const int n,
const bool pivot,
int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverCgetrf_bufferSize(const int m,
const int n,
const bool pivot,
int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverZgetrf_bufferSize(const int m,
const int n,
const bool pivot,
int* buffersize);

函数 musolverXgetrf

MUSOLVER_EXPORT mublasStatus_t musolverXgetrf(
mublasHandle_t handle,
const int m,
const int n,
float * A,
const int lda,
int * ipiv,
int * info,
void * buffer
)

GETRF 使用行交换的部分主元对一般 m-by-n 矩阵 A 进行 LU 分解。

参数

  • handle mublasHandle_t .
  • m int. m >= 0.

矩阵 A 的行数。

  • n int. n >= 0.

矩阵 A 的列数。

  • A 类型指针。GPU 上的数组,维度为 lda*n。

输入时,要分解的 m-by-n 矩阵 A。输出时,分解后的因子 L 和 U。L 的单位对角线元素不存储。

  • lda int. lda >= m.

指定 A 的领先维度。

  • ipiv 指向 int 的指针。GPU 上的数组,维度为 min(m,n)。

枢轴索引向量。ipiv 的元素是 1 基础索引。对于 1 <= i <= min(m,n),矩阵的行 i 与行 ipiv[i] 交换。可以从 ipiv 导出分解的矩阵 P。

  • info 指向 GPU 上的 int 的指针。

如果 info = 0,则成功退出。如果 info = i > 0,则 U 是奇异的。U[i,i] 是第一个零主元。

  • buffer 指向 void 的指针。为分解过程分配的工作空间缓冲区。这个缓冲区的大小应该由之前的 musolverXgetrf_bufferSize() 调用确定。缓冲区在分解过程中内部使用,存储临时数据。

(这是算法的分块 Level-3-BLAS 版本。如果启用优化(默认选项),则可以对中等大小的矩阵执行没有 muBLAS 调用的优化内部实现。有关更多详细信息,请参阅库设计指南中的 "调整 muSOLVER 性能" 部分。)

分解的形式为

A=PLUA = PLU

其中 PP 是置换矩阵,LL 是具有单位对角线元素的下三角(如果 m>nm > n 则是下梯形),UU 是上三角(如果 m<nm < n 则是上梯形)。

MUSOLVER_EXPORT mublasStatus_t musolverSgetrf(mublasHandle_t handle,
const int m,
const int n,
float* A,
const int lda,
int* ipiv,
int* info,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverDgetrf(mublasHandle_t handle,
const int m,
const int n,
double* A,
const int lda,
int* ipiv,
int* info,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverCgetrf(mublasHandle_t handle,
const int m,
const int n,
muComplex* A,
const int lda,
int* ipiv,
int* info,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverZgetrf(mublasHandle_t handle,
const int m,
const int n,
muDoubleComplex* A,
const int lda,
int* ipiv,
int* info,
void* buffer);

函数 musolverXgetriBatched

MUSOLVER_EXPORT mublasStatus_t musolverXgetriBatched(
mublasHandle_t handle,
const int n,
float *const A[],
const int lda,
int * ipiv,
const int strideP,
int * info,
const int batch_count
)

GETRI_BATCHED 使用 GETRF_BATCHED 计算的 LU 分解来求一批 n-by-n 矩阵的逆。

参数

  • handle mublasHandle_t.

  • n int. n0n \geq 0.
    批次中所有矩阵 AjA_j 的行数和列数。

  • A 类型指针数组。每个指针指向 GPU 上的数组,维度为 lda×n\text{lda} \times n.
    输入时,分解 A=PjLjUjA = P_j L_j U_j 返回的因子 LjL_jUjU_jGETRF_BATCHED 返回。
    输出时,如果 info[j]=0\text{info}[j] = 0,则 AjA_j 的逆;否则,未定义。

  • lda int. ldan\text{lda} \geq n.
    指定矩阵 AjA_j 的领先维度。

  • ipiv 指向 int 的指针。GPU 上的数组(大小取决于 strideP 的值)。
    GETRF_BATCHED 返回的枢轴索引。

  • strideP int.
    从一个向量 ipivj\text{ipiv}*j 的开始到下一个 ipivi+j\text{ipiv}*{i+j} 的步长。
    strideP 的值没有限制。正常使用情况是 stridePn\text{strideP} \geq n

  • info 指向 int 的指针。GPU 上的 batch_count 整数数组。
    如果 info[j]=0\text{info}[j] = 0,则 AjA_j 的求逆成功退出。
    如果 info[j]=i>0\text{info}[j] = i > 0,则 UjU_j 是奇异的。Uj[i,i]U_j[i,i] 是第一个零主元。

  • batch_count int. batch_count0\text{batch\_count} \geq 0.
    批次中的矩阵数量。

批次中矩阵 AjA_j 的逆通过解线性系统计算:

Aj1Lj=Uj1A_j^{-1} L_j = U_j^{-1}

其中 LjL_jAjA_j 的具有单位对角线元素的下三角因子,UjU_j 是上三角因子。

MUSOLVER_EXPORT mublasStatus_t musolverSgetriBatched(mublasHandle_t handle,
const int n,
float* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count);

MUSOLVER_EXPORT mublasStatus_t musolverDgetriBatched(mublasHandle_t handle,
const int n,
double* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count);

MUSOLVER_EXPORT mublasStatus_t musolverCgetriBatched(mublasHandle_t handle,
const int n,
muComplex* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count);

MUSOLVER_EXPORT mublasStatus_t musolverZgetriBatched(mublasHandle_t handle,
const int n,
muDoubleComplex* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count);

函数 musolverXgetrfBatched_bufferSize

MUSOLVER_EXPORT mublasStatus_t musolverXgetrfBatched_bufferSize(
const int m,
const int n,
const bool pivot,
const int batch_count,
int * buffersize
)

计算一批一般 m-by-n 矩阵的 LU 分解所需的缓冲区大小。

参数

  • m int. m0m \geq 0.
    批次中每个矩阵的行数。

  • n int. n0n \geq 0.
    批次中每个矩阵的列数。

  • pivot bool.
    指定分解过程中是否应用主元。如果为 true,则执行主元;否则,不执行。

  • batch_count int. batch_count0\text{batch\_count} \geq 0.
    批次中的矩阵数量。

  • buffersize int*.
    指向整数的指针,返回所需的缓冲区大小(以字节为单位)。

这个函数计算执行一批矩阵的 LU 分解所需的工作空间缓冲区大小,使用相应的批处理 GETRF 例程。

MUSOLVER_EXPORT mublasStatus_t musolverSgetrfBatched_bufferSize(
const int m, const int n, const bool pivot, const int batch_count, int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverDgetrfBatched_bufferSize(
const int m, const int n, const bool pivot, const int batch_count, int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverCgetrfBatched_bufferSize(
const int m, const int n, const bool pivot, const int batch_count, int* buffersize);

MUSOLVER_EXPORT mublasStatus_t musolverZgetrfBatched_bufferSize(
const int m, const int n, const bool pivot, const int batch_count, int* buffersize);

函数 musolverXgetrfBatched

MUSOLVER_EXPORT mublasStatus_t musolverXgetrfBatched(
mublasHandle_t handle,
const int m,
const int n,
float *const A[],
const int lda,
int * ipiv,
const int strideP,
int * info,
const int batch_count,
void * buffer
)

GETRF_BATCHED 使用行交换的部分主元对一批一般 m-by-n 矩阵进行 LU 分解。

参数

  • handle mublasHandle_t.

  • m int. m0m \geq 0.
    批次中所有矩阵 AjA_j 的行数。

  • n int. n0n \geq 0.
    批次中所有矩阵 AjA_j 的列数。

  • A 类型指针数组。每个指针指向 GPU 上的数组,维度为 lda×n\text{lda} \times n.
    输入时,要分解的 m×nm \times n 矩阵 AjA_j。输出时,分解后的因子 LjL_jUjU_j。L_j 的单位对角线元素不存储。

  • lda int. ldam\text{lda} \geq m.
    指定矩阵 AjA_j 的领先维度。

  • ipiv 指向 int 的指针。GPU 上的数组(大小取决于 strideP 的值)。
    包含枢轴索引向量 ipiv_j\text{ipiv}\_j(对应于 AjA_j)。
    ipivj\text{ipiv}_j 的维度是 min(m,n)\min(m, n),且 ipivj\text{ipiv}_j 的元素是基于 1 的索引。对于批次中的每个实例 AjA_j,以及对于 1imin(m,n)1 \leq i \leq \min(m, n),矩阵 AjA_j 的第 ii 行与 ipivj[i]\text{ipiv}_j[i] 指定的行进行交换。

    可以从 ipiv_j\text{ipiv}\_j 导出分解的矩阵 P_jP\_j

  • strideP int.
    从一个向量 ipivj\text{ipiv}*j 的开始到下一个 ipivj+1\text{ipiv}*{j+1} 的步长。
    strideP 的值没有限制。正常使用情况是 stridePmin(m,n)\text{strideP} \geq \min(m, n)

  • info 指向 int 的指针。GPU 上的 batch_count 整数数组。
    如果 info[j]=0\text{info}[j] = 0,则 AjA_j 的分解成功退出。
    如果 info[j]=i>0\text{info}[j] = i > 0,则 UjU_j 是奇异的。Uj[i,i]U_j[i,i] 是第一个零主元。

  • batch_count int. batch_count0\text{batch\_count} \geq 0.
    批次中的矩阵数量。


(这是算法的分块 Level-3-BLAS 版本。如果启用优化(默认选项),则可以对中等大小的矩阵执行没有 muBLAS 调用的优化内部实现。有关更多详细信息,请参阅库设计指南中的 "调整 muSOLVER 性能" 部分。)

批次中矩阵 AjA_j 的分解形式为:

Aj=PjLjUjA_j = P_j L_j U_j

其中 PjP_j 是置换矩阵,LjL_j 是具有单位对角线元素的下三角(如果 m>nm > n 则是下梯形),UjU_j 是上三角(如果 m<nm < n 则是上梯形)。

MUSOLVER_EXPORT mublasStatus_t musolverSgetrfBatched(mublasHandle_t handle,
const int m,
const int n,
float* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverDgetrfBatched(mublasHandle_t handle,
const int m,
const int n,
double* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverCgetrfBatched(mublasHandle_t handle,
const int m,
const int n,
muComplex* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count,
void* buffer);

MUSOLVER_EXPORT mublasStatus_t musolverZgetrfBatched(mublasHandle_t handle,
const int m,
const int n,
muDoubleComplex* const A[],
const int lda,
int* ipiv,
const int strideP,
int* info,
const int batch_count,
void* buffer);