- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I was trying to see what difference does the function `mkl_sparse_optimize()` make for `mkl_sparse_d_trsm()`, but I am not able to execute the `mkl_sparse_set_sm_hint()` function correctly.
See the following code:
#include <cstdio>
#include <vector>
#include <mkl.h>
#include <omp.h>
#ifndef CHECK
#define CHECK(status) do { checkStatus(status, __FILE__, __LINE__); } while(false)
#endif
static inline void checkStatus(sparse_status_t status, const char * file, int line)
{
switch (status)
{
case SPARSE_STATUS_SUCCESS: break;
case SPARSE_STATUS_NOT_INITIALIZED: printf("MKL SPARSE_STATUS_NOT_INITIALIZED. file '%s'. line %d\n", file, line); exit(1);
case SPARSE_STATUS_ALLOC_FAILED: printf("MKL SPARSE_STATUS_ALLOC_FAILED. file '%s'. line %d\n", file, line); exit(1);
case SPARSE_STATUS_INVALID_VALUE: printf("MKL SPARSE_STATUS_INVALID_VALUE. file '%s'. line %d\n", file, line); exit(1);
case SPARSE_STATUS_EXECUTION_FAILED: printf("MKL SPARSE_STATUS_EXECUTION_FAILED. file '%s'. line %d\n", file, line); exit(1);
case SPARSE_STATUS_INTERNAL_ERROR: printf("MKL SPARSE_STATUS_INTERNAL_ERROR. file '%s'. line %d\n", file, line); exit(1);
case SPARSE_STATUS_NOT_SUPPORTED: printf("MKL SPARSE_STATUS_NOT_SUPPORTED. file '%s'. line %d\n", file, line); exit(1);
}
}
int main()
{
int size = 456;
int nrhs = 123;
std::vector<int> L_rowptrs(size + 1);
std::vector<int> L_colidxs(size);
std::vector<double> L_vals(size);
std::vector<double> B_vals(size * nrhs, 1.0);
std::vector<double> X_vals(size * nrhs, 0.0);
for(int i = 0; i <= size; i++) L_rowptrs[i] = i;
for(int i = 0; i < size; i++) L_colidxs[i] = i;
for(int i = 0; i < size; i++) L_vals[i] = 2.0;
for(int opt = 0; opt <= 1; opt++)
{
bool do_optimize = (bool)opt;
printf("optimize: %s\n", do_optimize ? "YES" : "NO");
sparse_matrix_t L_mkl;
matrix_descr L_descr;
CHECK(mkl_sparse_d_create_csr(&L_mkl, SPARSE_INDEX_BASE_ZERO, size, size, L_rowptrs.data(), L_rowptrs.data()+1, L_colidxs.data(), L_vals.data()));
L_descr.type = SPARSE_MATRIX_TYPE_TRIANGULAR;
L_descr.mode = SPARSE_FILL_MODE_LOWER;
L_descr.diag = SPARSE_DIAG_NON_UNIT;
auto op = SPARSE_OPERATION_NON_TRANSPOSE;
auto layout = SPARSE_LAYOUT_ROW_MAJOR;
double opt_start = omp_get_wtime();
if(do_optimize)
{
CHECK(mkl_sparse_set_sm_hint(L_mkl, op, L_descr, layout, nrhs, 1000));
CHECK(mkl_sparse_optimize(L_mkl));
}
double opt_stop = omp_get_wtime();
double calc_start = omp_get_wtime();
CHECK(mkl_sparse_d_trsm(op, 1.0, L_mkl, L_descr, layout, B_vals.data(), nrhs, nrhs, X_vals.data(), nrhs));
double calc_stop = omp_get_wtime();
CHECK(mkl_sparse_destroy(L_mkl));
printf(" time optimize: %12.3f ms\n", (opt_stop - opt_start) * 1000);
printf(" time calculate: %12.3f ms\n", (calc_stop - calc_start) * 1000);
}
return 0;
}
It first creates a lower triangular CSR matrix (actually just a diagonal filled with 2s) and a rhs and solution dense matrices in row-major format.
Then there is the loop which tests the non-optimized and optimized version of sparse trsm.
The first iteration, where optimization does not happen, everything runs just fine. But in the second iteration, where I try to call the set hint and optimize functions, it crashes.
I compiled using
icpx -qmkl=sequential -qopenmp -g -O2 source.cpp -o program.x
This is the output of the program:
optimize: NO
time optimize: 0.003 ms
time calculate: 2.359 ms
optimize: YES
MKL SPARSE_STATUS_NOT_SUPPORTED. file 'source.cpp'. line 62
line 62 is the line where `mkl_sparse_set_sm_hint()` is.
The version of sparse trsm without optimization executed just fine (so the combination of dense layout, matrix format, operation etc. is supported). So why does the set hint function report that it is not supported?
I tried oneAPI toolkit 2024.2.0 and 2025.0.0, in both there is the issue.
The documentation is of no help.
Some better error reporting in sparse mkl would be nice. MKL_VERBOSE did provide any more details.
So, *what* is not supported? What is wrong?
Thanks for any help,
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So a SPARSE_STATUS_NOT_SUPPORTED coming from the "mkl_sparse_set_xyz_hint()" means that there are currently no additional optimizations available for that particular xyz operation and you can proceed with calling "mkl_sparse_optimize()" (for any other hints you may have set) and then the "mkl_sparse_ ...xyz()" operation. The performance would be expected to be similar to not having called "mkl_sparse_set_xyz_hint()" and "mkl_sparse_optimize()".
It doesn't mean the operation is suddenly disabled or not supported, but rather that there are no additional optimizations supported based on the input hints... In your case, BSR + TRSM does have some potential optimizations, but currently CSR + TRSM does not ... you can effectively ignore SPARSE_STATUS_NOT_SUPPORTED return from the mkl_sparse_set_xyz_hint() functions and proceed with subsequent calls in normal pattern.
The Inspector-Executor model lets us inspect each operation you present to us to be inspected, and if something extra "can" be done, we do it, otherwise, you just move on to execution stage ... Does that make sense ? I could see an argument being made that even if we do nothing, we should return SPARSE_STATUS_SUCCESS at the mkl_sparse_set_xyz_hint() level. Maybe that is more clear, but we wanted to give an idea of when something was done or not done, so decided to return SPARSE_STATUS_NOT_SUPPORTED when nothing was being done...
We also agree that it would be helpful to have some MKL_VERBOSE output for Sparse BLAS routines and will try to plan it for future.
Spencer
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So a SPARSE_STATUS_NOT_SUPPORTED coming from the "mkl_sparse_set_xyz_hint()" means that there are currently no additional optimizations available for that particular xyz operation and you can proceed with calling "mkl_sparse_optimize()" (for any other hints you may have set) and then the "mkl_sparse_ ...xyz()" operation. The performance would be expected to be similar to not having called "mkl_sparse_set_xyz_hint()" and "mkl_sparse_optimize()".
It doesn't mean the operation is suddenly disabled or not supported, but rather that there are no additional optimizations supported based on the input hints... In your case, BSR + TRSM does have some potential optimizations, but currently CSR + TRSM does not ... you can effectively ignore SPARSE_STATUS_NOT_SUPPORTED return from the mkl_sparse_set_xyz_hint() functions and proceed with subsequent calls in normal pattern.
The Inspector-Executor model lets us inspect each operation you present to us to be inspected, and if something extra "can" be done, we do it, otherwise, you just move on to execution stage ... Does that make sense ? I could see an argument being made that even if we do nothing, we should return SPARSE_STATUS_SUCCESS at the mkl_sparse_set_xyz_hint() level. Maybe that is more clear, but we wanted to give an idea of when something was done or not done, so decided to return SPARSE_STATUS_NOT_SUPPORTED when nothing was being done...
We also agree that it would be helpful to have some MKL_VERBOSE output for Sparse BLAS routines and will try to plan it for future.
Spencer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Alright, I understand. Thanks for the reply.
So I would like to request an update to the documentation which mentions this return value behavior of the mkl_sparse_set_xyz_hint() functions.
The MKL_VERBOSE output would be very helpful.
From my point of view, the SPARSE_STATUS_SUCCESS return makes more sense in this case. For me, SPARSE_STATUS_NOT_SUPPORTED means that I called the function with the wrong/unsupported combination of matrixformat/uplo/trans/layout/indexing, that it was *my* fault for using the function in a wrong way. Using SPARSE_STATUS_NOT_SUPPORTED as an indicator that no optimizations are available seems weird to me.
Thanks,
Jakub

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page