1 /*
2 
3 Copyright (C) 2008-2021 Michele Martone
4 
5 This file is part of librsb.
6 
7 librsb is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11 
12 librsb is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with librsb; see the file COPYING.
19 If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 /*! @file
23  *  @author Michele Martone
24  *  @brief Implementation of the library user interface.
25  */
26 /*
27  *  The user interface functions and data structures for this library implementations.
28  *  (functions declared as static are not intended to be part of the user interface)
29  *  Internals should not be present in this file.
30  *  As a good rule, each function defined in this file (as well as any internal) shall NOT call another similar, but only its internal wrapper.
31  * */
32 #include "rsb_internals.h"
33 #include <stdio.h>
34 #include "rsb_do.h"
35 
36 RSB_INTERNALS_COMMON_HEAD_DECLS
37 
38 #define RSB_INTERFACE_RETURN_MTX_ERRP(MTXAP,ERRVAL,ERRVALP) \
39 	                                 RSB_INTERFACE_ENDCMD \
40 	RSB_CONDITIONAL_ERRPSET(ERRVALP,ERRVAL) RSB_DO_MTX_RETURN_INTERFACE(MTXAP,ERRVAL);
41 #define RSB_INTERFACE_RETURN_MTX(MTXAP)  RSB_INTERFACE_ENDCMD return MTXAP;
42 #define RSB_INTERFACE_RETURN_ERR(ERRVAL) 	RSB_INTERFACE_ENDCMD RSB_DO_ERR_RETURN_INTERFACE(ERRVAL)
43 /* #define RSB_INTERFACE_RETURN_ERR_SILENT(ERRVAL) RSB_INTERFACE_ENDCMD return (ERRVAL); */
44 #define RSB_INTERFACE_RETURN_VAL(VAL)    RSB_INTERFACE_ENDCMD {return (VAL);}
45 
46 /*!
47  * \internal
48  * This library, currently, can be used by only one master thread.
49  * Therefore it uses no handle for library execution instances.
50  * */
51 
rsb_lib_init(struct rsb_initopts * iop)52 rsb_err_t rsb_lib_init(struct rsb_initopts * iop)
53 {
54 	/*!
55 	   \ingroup rsb_doc_library rsb_doc_rsb
56  	   \brief
57 	   This is the library initialization function.
58 	   \n
59 	   It must be called only once before using any other library function.
60 	   \n
61 	   It is allowed to call it again after \ref rsb_lib_exit().
62 	   \n
63 	   To fine-tune the library behaviour, one may specify a number of options via the \c iop parameter.
64 	   \n
65 	   Options may be specified also after \ref rsb_lib_init() by calling \ref rsb_lib_reinit().
66 	   \n
67 	   One may call #RSB_REINIT_SINGLE_VALUE_GET  with flag  #RSB_IO_WANT_IS_INITIALIZED_MARKER  to verify whether the library has been initialized or not.
68 
69 	   \param \rsb_io_str_msg
70 	   \return \rsberrcodemsg
71 	   \see_lib_init
72 	 */
73 	rsb_err_t errval = RSB_ERR_NO_ERROR;
74 	RSB_INTERFACE_PREAMBLE
75 	errval = rsb__do_init(iop);
76 	RSB_INTERFACE_RETURN_ERR(errval)
77 }
78 
79 /* @cond INNERDOC  */
80 /* TODO: this is a "in development" function, not yet declared in rsb.h ; shall make it official when complete */
rsb__lib_get_info_str(int what,rsb_char_t * sbuf,size_t buflen)81 rsb_err_t rsb__lib_get_info_str(int what, rsb_char_t* sbuf, size_t buflen)
82 {
83 	/* \see_lib_init */
84 	rsb_err_t errval = RSB_ERR_NO_ERROR;
85 	RSB_INTERFACE_PREAMBLE
86 	errval = rsb__do_lib_get_info_str(what,sbuf,buflen);
87 	RSB_INTERFACE_RETURN_ERR(errval)
88 }
89 /* @endcond */
90 
rsb_lib_set_opt(enum rsb_opt_t iof,const void * iop)91 rsb_err_t rsb_lib_set_opt(enum rsb_opt_t iof, const void*iop)
92 {
93 	/*!
94 	 Sets value of a library option.
95  	 A value specified by the request flag \c iof  will be fetched from \c *iop and will be used to update the selected option in the library internal state.
96 
97 	 \rsb_iof_param_msg
98 	 \rsb_iop_out_param_msg
99 	 \see \rsb_iof_macros
100 	 \see_lib_init
101 	 */
102 	rsb_err_t errval = RSB_ERR_NO_ERROR;
103 	RSB_INTERFACE_PREAMBLE
104 	RSB_DO_REINIT_SINGLE_VALUE_C_IOP(iof,iop,RSB_IO_SPECIFIER_SET,errval);
105 	RSB_INTERFACE_RETURN_ERR(errval)
106 }
107 
rsb_lib_get_opt(enum rsb_opt_t iof,void * iop)108 rsb_err_t rsb_lib_get_opt(enum rsb_opt_t iof, void*iop)
109 {
110 	/*!
111 	 Gets value of a library option.
112  	 A value specified by the request flag \c iof  will be fetched from the library internal state and \c *iop will be updated accordingly.
113 
114 	 \rsb_iof_param_msg
115 	 \rsb_iop_out_param_msg
116 	 \see \rsb_iof_macros
117 	 \see_lib_init
118 	 */
119 	rsb_err_t errval = RSB_ERR_NO_ERROR;
120 	RSB_INTERFACE_PREAMBLE
121 	RSB_DO_REINIT_SINGLE_VALUE_GET(iof,iop,errval);
122 	RSB_INTERFACE_RETURN_ERR(errval)
123 }
124 
rsb_lib_set_opt_str(const rsb_char_t * opnp,const rsb_char_t * opvp)125 rsb_err_t rsb_lib_set_opt_str(const rsb_char_t* opnp, const rsb_char_t* opvp)
126 {
127 	/*!
128 	   \ingroup rsb_doc_library rsb_doc_rsb
129 
130 	   Specifies individual library options in order to fine-tune the library behaviour.
131 	   Both the option name and the value shall be expressed as strings, identical to their preprocessor identifiers (see #rsb_opt_t ).
132 	   The \c opnp string will be translated internally to the corresponding request flag values, and the passed value will be parsed out of the \c opvp string.
133 	   \n
134 
135 	   \param \rsb_io_str_msg_opnp
136 	   \param \rsb_io_str_msg_opvp
137 	   \return \rsberrcodemsg
138 
139 	   \see_lib_init
140 	 */
141 	rsb_err_t errval = RSB_ERR_NO_ERROR;
142 	RSB_INTERFACE_PREAMBLE
143 	errval = rsb__do_set_initopt_as_string(opnp,opvp);
144 	RSB_INTERFACE_RETURN_ERR(errval)
145 }
146 
rsb_lib_reinit(struct rsb_initopts * iop)147 rsb_err_t rsb_lib_reinit(struct rsb_initopts * iop)
148 {
149 	/*!
150 	   \ingroup rsb_doc_library rsb_doc_rsb
151 
152 	   Changes the library operation options which were set at initialization time either by a user or as defaults.
153 	   \n
154 	   Not all options may be supported, depending on build time library settings.
155 	   \n
156 	   If an unsupported option was specified, an appropriate error (e.g.: #RSB_ERR_UNSUPPORTED_OPERATION) will be returned.
157 	   \n
158 	   On the first error, option processing is interrupted and the remaining options (if any) are not processed.
159 	   \n
160 	   Program execution may continue safely even if an error code is returned (that is, library status should be consistent).
161 	   \n
162 
163 	   \param \rsb_io_str_msg
164 	   \return \rsberrcodemsg
165 	   \see_lib_init
166 	 */
167 	rsb_err_t errval = RSB_ERR_NO_ERROR;
168 	RSB_INTERFACE_PREAMBLE
169 	errval = rsb__do_reinit(iop);
170 	RSB_INTERFACE_RETURN_ERR(errval)
171 }
172 
rsb_lib_exit(struct rsb_initopts * iop)173 rsb_err_t rsb_lib_exit(struct rsb_initopts * iop)
174 {
175 	/*!
176 	   \ingroup rsb_doc_library rsb_doc_rsb
177 
178 	   Finalize \librsb.
179 	   \n
180 	   #rsb_lib_exit should be called after having freed all matrices.
181 	   \n
182 	   If not all of the data structures were properly deallocated before, this function may still attempt finalizing the library and return the #RSB_ERR_MEMORY_LEAK error code (this depends on the \c --enable-allocator-wrapper configure time option).
183 	   Any allocated memory will be lost (\librsb does not keep track of allocated matrices).
184 	   \n
185 	   Internal library state will be cleared.
186 	   After this call, it is legal to initialize the library again, by calling \ref rsb_lib_init().
187 	   \n
188 	   On an error, the library state may be inconsistent, so it is advisable to either
189 	   terminate program execution (rather than forcing a new initialization with \ref rsb_lib_init()).
190 	   \n
191 	   Parameter  \c iop  is reserved for future use; for now it is safe to pass #RSB_NULL_EXIT_OPTIONS.
192 
193 	   \param \rsb_io_str_msg
194 	   \return \rsberrcodemsg
195 	   \see_lib_init
196 	 */
197 	rsb_err_t errval = RSB_ERR_NO_ERROR;
198 	RSB_INTERFACE_PREAMBLE
199 	errval = rsb__do_exit();
200 	RSB_INTERFACE_RETURN_ERR(errval)
201 }
202 
rsb_mtx_alloc_from_coo_const(const void * VA,const rsb_coo_idx_t * IA,const rsb_coo_idx_t * JA,rsb_nnz_idx_t nnzA,rsb_type_t typecode,rsb_coo_idx_t nrA,rsb_coo_idx_t ncA,rsb_blk_idx_t brA,rsb_blk_idx_t bcA,rsb_flags_t flagsA,rsb_err_t * errvalp)203 struct rsb_mtx_t * rsb_mtx_alloc_from_coo_const(const void *VA, const rsb_coo_idx_t * IA, const rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp)
204 {
205 	/*!
206  	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
207 
208 	   Given as input COO arrays \c VA,IA,JA, allocates and assembles an RSB matrix using separate arrays.
209 
210 	   \param \rsb_ro_va_ia_ja_desc_msg
211 	   \param \rsb_nnzA_inp_param_msg
212 	   \param \rsb_type_param_msg
213 	   \param \rsb_nrcows_A_sparse_inp_param_msg
214 	   \param \rsb_nrbows_A_sparse_inp_param_msg
215 	   \param \rsb_flagsa_coc_param_msg
216 	   \param \rsb_errvp_inp_param_msg
217 	   \return \rsbmtxpmessage
218 	   \see_lib_alloc
219 	 */
220 	rsb_err_t errval = RSB_ERR_NO_ERROR;
221 	struct rsb_mtx_t * mtxAp = NULL;
222 	RSB_INTERFACE_PREAMBLE
223 	mtxAp = rsb__do_mtx_alloc_from_coo_const(VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,flagsA,&errval);
224 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxAp,errval,errvalp);
225 }
226 
rsb_mtx_alloc_from_coo_inplace(void * VA,rsb_coo_idx_t * IA,rsb_coo_idx_t * JA,rsb_nnz_idx_t nnzA,rsb_type_t typecode,rsb_coo_idx_t nrA,rsb_coo_idx_t ncA,rsb_blk_idx_t brA,rsb_blk_idx_t bcA,rsb_flags_t flagsA,rsb_err_t * errvalp)227 struct rsb_mtx_t * rsb_mtx_alloc_from_coo_inplace(void *VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp)
228 {
229 	/*!
230 	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
231 
232 	   \rsb_mtx_alloc_coo_inplace_msg
233 	   \n
234 	   \rsb_note_assume_nnz_sized
235 
236 	   \param \rsb_rw_va_ia_ja_desc_msg
237 	   \param \rsb_nnzA_inp_param_msg
238 	   \param \rsb_type_param_msg
239 	   \param \rsb_nrcows_A_sparse_inp_param_msg
240 	   \param \rsb_nrbows_A_sparse_inp_param_msg
241 	   \param \rsb_flagsa_coi_param_msg
242 	   \param \rsb_errvp_inp_param_msg
243 	   \return \rsbmtxpmessage
244 
245 	   \see_lib_alloc
246 	*/
247 	rsb_err_t errval = RSB_ERR_NO_ERROR;
248 	struct rsb_mtx_t * mtxAp = NULL;
249 	RSB_INTERFACE_PREAMBLE
250 	mtxAp = rsb__do_mtx_alloc_from_coo_inplace(VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,flagsA,&errval);
251 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxAp,errval,errvalp);
252 }
253 
rsb_mtx_free(struct rsb_mtx_t * mtxAp)254 struct rsb_mtx_t * rsb_mtx_free(struct rsb_mtx_t * mtxAp)
255 {
256 	/*!
257 	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
258 
259 	   Frees a previously allocated sparse matrix structure.
260 	   \n
261 	   In the case the matrix has the #RSB_FLAG_EXTERNALLY_ALLOCATED_ARRAYS flag, the main three data arrays \rsb_va_ia_ja_decl will not be freed by #rsb_mtx_free (see \rsb_lib_alloc_in_place).
262 
263 	   \param \rsb_mtxt_inp_param_msg_a
264 	   \return \rsb_ret_null
265 
266 	   \see_lib_alloc
267 	 */
268 	struct rsb_mtx_t * mtxBp = NULL;
269 	RSB_INTERFACE_PREAMBLE
270 	mtxBp = rsb__do_mtx_free(mtxAp);
271 	RSB_INTERFACE_RETURN_MTX(mtxBp);
272 }
273 
rsb_mtx_clone(struct rsb_mtx_t ** mtxBpp,rsb_type_t typecode,rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_flags_t flags)274 rsb_err_t rsb_mtx_clone(struct rsb_mtx_t ** mtxBpp, rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_flags_t flags)
275 {
276 	/*!
277 	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
278 
279 	   This function clones a given matrix, allocating a fresh data structure or overwriting an existing one.
280 
281 	   Target type (specified by \c typecode) can be different from that in the matrix.
282 
283 	   If \c alphap=NULL, the cloned matrix will not be scaled.
284 
285 	   This new structure will be completely separated and independent from the original one.
286 
287 	   */
288 	/**
289 	   Examples:
290 \code
291 // will clone the matrix exactly
292 errval = rsb_mtx_clone(&mtxBp,RSB_NUMERICAL_TYPE_SAME_TYPE,RSB_TRANSPOSITION_N,NULL,mtxAp,RSB_FLAG_IDENTICAL_FLAGS);
293 // will clone the transpose of the matrix
294 errval = rsb_mtx_clone(&mtxBp,RSB_NUMERICAL_TYPE_SAME_TYPE,RSB_TRANSPOSITION_T,NULL,mtxAp,RSB_FLAG_IDENTICAL_FLAGS);
295 // will clone the lower triangle of the matrix
296 errval = rsb_mtx_clone(&mtxBp,RSB_NUMERICAL_TYPE_SAME_TYPE,RSB_TRANSPOSITION_N,NULL,mtxAp,RSB_FLAG_TRIANGULAR|RSB_FLAG_LOWER);
297 \endcode
298 	   */
299 	/**
300 	   \param \rsb_mtxtpp_inp_param_msg_b If \c *mtxBpp==NULL, a fresh clone will be assigned there; if not, the existing matrix structure will be freed and allocated to host the new one. The case \c *mtxBpp==mtxAp is supported.
301 	   \param \rsb_type_o_param_msg
302 	   \param \rsb_transa_inp_param_msg
303 	   \param \rsb_alpha_s_inp_param_msg Of the type code of \c mtxAp.
304 	   \param \rsb_mtxt_inp_param_msg_a
305 	   \param \rsb_flags_stru_fla_msg
306 	   \return \rsberrcodemsg
307 
308 	   \see_lib_alloc
309 	 */
310 	/* FIXME: what if RSB_FLAG_EXTERNALLY_ALLOCATED_ARRAYS ? */
311 	rsb_err_t errval = RSB_ERR_NO_ERROR;
312 	RSB_INTERFACE_PREAMBLE
313 	errval = rsb__mtx_clone(mtxBpp,typecode,transA,alphap,mtxAp,flags);
314 	RSB_INTERFACE_RETURN_ERR(errval)
315 }
316 
317 #if 0
318 rsb_err_t rsb_get_rows_dense(const struct rsb_mtx_t * mtxAp, void* row, rsb_coo_idx_t frA, rsb_coo_idx_t lrA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_nnz_idx_t *rnzp, rsb_flags_t flags )
319 {
320         /*!
321 	 * \ingroup rsb_doc_matrix_operations rsb_doc_rsb
322 	 * \return \rsberrcodemsg
323          * FIXME : missing test case, document
324          * */
325         return rsb__do_get_rows_dense(mtxAp,row,frA,lrA,IA,JA,rnzp,flags);
326 }
327 #endif
328 
329 
330 
331 #define RSB_EXPOSE_NEW_GENERAL_INTERFACE 1	/* temporary (internals) to delimit the new interface which supersedes the deprecated one */
332 #if RSB_EXPOSE_NEW_GENERAL_INTERFACE
333 #if 0
334 /* #define RSB_EXTF_NONE		0x00000000*/			/* */
335 #define RSB_EXTF_SLOWTRI	0x00000001			/*!< Flag values for extracting the strictly lower submatrix*/
336 #define RSB_EXTF_SUPPTRI	0x00000002			/*!< Flag values for extracting the strictly upper submatrix .*/
337 #define RSB_EXTF_DIAG		0x00000004			/*!< Flag values for extracting the diagonal submatrix.*/
338 #define RSB_EXTF_LOWTRI		(RSB_EXTF_SLOWTRI|RSB_EXTF_DIAG)/*!< Flag values for extracting the lower submatrix.*/
339 #define RSB_EXTF_UPPTRI		(RSB_EXTF_SUPPTRI|RSB_EXTF_DIAG)/*!< Flag values for extracting the upper submatrix.*/
340 #define RSB_EXTF_OFFDIAG	(RSB_EXTF_SUPPTRI|RSB_EXTF_SLOWTRI)/*!< Flag values for extracting the whole matrix.*/
341 #define RSB_EXTF_EXPSYMM	0x00000008			/*!< */
342 #define RSB_EXTF_EXPDIAG	0x00000010			/*!< */
343 #define RSB_EXTF_EXP		(RSB_EXTF_EXPDIAG|RSB_EXTF_EXPSYMM)	/*!< */
344 #define RSB_EXTF_ALL		(RSB_EXTF_OFFDIAG|RSB_EXTF_DIAG)/*!< Flag values for extracting the whole matrix.*/
345 #define RSB_EXTF_EXPALL		(RSB_EXTF_ALL|RSB_EXTF_EXP)	/*!< */
346 #define RSB_EXTF_DEFAULT	RSB_EXTF_ALL			/*!< Flag values for extracting the whole matrix. */
347 /* #define RSB_EXTF_SYMMEXP	0x00000020*/
348 rsb_err_t rsb_get_submatrix_as_coo(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t *mtxAp, void* VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_nnz_idx_t *rnzp, rsb_flags_t flags);/* NEW, unfinished */
349 
350 rsb_err_t rsb_get_submatrix_as_coo(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t *mtxAp, void* VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_nnz_idx_t *rnzp, rsb_flags_t flags/* , rsb_extff_t eflags*/)/* NEW, unfinished */
351 {
352 	/*!
353 	   \ingroup rsb_doc_matrix_conversion rsb_doc_rsb
354 
355 	   Extracts a submatrix.
356 	   Call this function with VA,IA,JA NULL in order to get nonzeroes count.
357 
358 	   \param \rsb_type_param_msg
359 	   \param \rsb_transa_inp_param_msg
360 	   \param \rsb_alpha_inp_param_msg
361 	   \param \rsb_wr_va_ia_ja_desc_msg
362 	   \param \rsb_inp_rnz_msg
363 	   \param \rsb_flags_idc_param_msg
364 	   \return \rsberrcodemsg
365 
366 	   \warning \rsb_warn_unfinished_msg
367 	   \warning \rsb_warn_unfinished_flags_doc_msg
368 	 */
369 	 /*
370 	   \todo: Shall document eflags.
371 	 */
372 	rsb_err_t errval = RSB_ERR_NO_ERROR;
373 	RSB_INTERFACE_PREAMBLE
374 	errval = rsb_do_get_submatrix_as_coo(typecode, transA, alphap, mtxAp, VA, IA, JA, rnzp, flags/* , eflags*/);
375 	RSB_INTERFACE_RETURN_ERR(errval)
376 }
377 #endif
378 #endif /* RSB_EXPOSE_NEW_GENERAL_INTERFACE */
379 
380 #if 0
381 rsb_err_t rsb_spmv_nt(const void *alphap, const struct rsb_mtx_t * mtxAp, const void * x1p, const void * x2p, rsb_coo_idx_t incX, const void * betap, void * y1p, void * y2p, rsb_coo_idx_t incY);
382 rsb_err_t rsb_spmv_ata(const void *alphap, const struct rsb_mtx_t * mtxAp, const void * Xp, rsb_coo_idx_t incX, const void * betap, void * Yp, rsb_coo_idx_t incY);
383 rsb_err_t rsb_spmv_power(rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp,  rsb_int_t exp, const void * Xp, rsb_coo_idx_t incX, const void * betap, void * Yp, rsb_coo_idx_t incY);
384 
385 rsb_err_t rsb_spmv_nt(const void *alphap, const struct rsb_mtx_t * mtxAp, const void * x1p, const void * x2p, rsb_coo_idx_t incX, const void * betap, void * y1p, void * y2p, rsb_coo_idx_t incY)
386 {
387 	/*!
388 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
389 
390 	   Computes \f$Y_1 \leftarrow \beta Y_1 + \alpha {A}     \cdot X_1 \f$
391 	   and      \f$Y_2 \leftarrow \beta Y_2 + \alpha {A}^{T} \cdot X_2 \f$.
392 
393 	   \param \rsb_beta_inp_param_msg
394 	   \param \rsb_transa_inp_param_msg
395 	   \param \rsb_mtxt_inp_param_msg_a
396 	   \param \rsb_incx_inp_param_msg
397 	   \param \rsb_incy_inp_param_msg
398 	   \param \rsb_y1y2_inp_param_msg
399 	   \param \rsb_x1x2_inp_param_msg
400 	   \return \rsberrcodemsg
401 
402 	   \warning \rsb_warn_untested_msg
403 	 */
404 
405 	// FIXME: this is only a placeholder, waiting for a combined implementation.
406 	// once done, should speedup methods like Biconjugate Gradient (BiCG).
407 	rsb_err_t errval = RSB_ERR_NO_ERROR;
408 	RSB_INTERFACE_PREAMBLE
409 	errval = rsb_spmv(RSB_TRANSPOSITION_N,alphap,mtxAp,x1p,incX,betap,y1p,incY)|
410 		rsb_spmv(RSB_TRANSPOSITION_T,alphap,mtxAp,x2p,incX,betap,y2p,incY);
411 	RSB_INTERFACE_RETURN_ERR(errval)
412 }
413 
414 rsb_err_t rsb_spmv_ata(const void *alphap, const struct rsb_mtx_t * mtxAp, const void * Xp, rsb_coo_idx_t incX, const void * betap, void * Yp, rsb_coo_idx_t incY)
415 {
416 	/*!
417 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
418 
419 	   Computes \f$Y \leftarrow \beta Y + \alpha {A}^{T} {A} \cdot X \f$.
420 
421 	   \param \rsb_mtxt_inp_param_msg_a
422 	   \param \rsb_x_inp_param_msg
423 	   \param \rsb_y_out_param_msg
424 	   \param \rsb_incx_inp_param_msg
425 	   \param \rsb_incy_inp_param_msg
426 	   \param \rsb_alpha_inp_param_msg
427 	   \param \rsb_beta_inp_param_msg
428 	   \return \rsberrcodemsg
429 
430 	   \warning \rsb_warn_unimplemented_msg
431 	   \warning \rsb_warn_untested_msg
432 	 */
433 	rsb_err_t errval = RSB_ERR_UNIMPLEMENTED_YET;
434 	RSB_INTERFACE_PREAMBLE
435 	RSB_INTERFACE_RETURN_ERR(errval)
436 	// FIXME: this is only a placeholder, waiting for a combined implementation.
437 }
438 
439 rsb_err_t rsb_spmv_power(rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp,  rsb_int_t exp, const void * Xp, rsb_coo_idx_t incX, const void * betap, void * Y, rsb_coo_idx_t incY)
440 {
441 	/*!
442 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
443 
444 	   Computes \f$Y \leftarrow \beta Y + \alpha ({A}^{T})^{exp} {A} \cdot X \f$.
445 
446 	   \param \rsb_mtxt_inp_param_msg_a
447 	   \param \rsb_x_inp_param_msg
448 	   \param \rsb_y_out_param_msg
449 	   \param \rsb_incx_inp_param_msg
450 	   \param \rsb_incy_inp_param_msg
451 	   \param \rsb_alpha_inp_param_msg
452 	   \param \rsb_beta_inp_param_msg
453 	   \param \rsb_exp_inp_param_msg
454 	   \return \rsberrcodemsg
455 
456 	   \warning \rsb_warn_unimplemented_msg
457 	   \warning \rsb_warn_untested_msg
458 	 */
459 
460 	rsb_err_t errval = RSB_ERR_UNIMPLEMENTED_YET;
461 	RSB_INTERFACE_PREAMBLE
462 	RSB_INTERFACE_RETURN_ERR(errval)
463 	// FIXME: this is only a placeholder, waiting for a combined implementation.
464 }
465 #endif
466 
rsb_spmv(rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,const void * Xp,rsb_coo_idx_t incX,const void * betap,void * Yp,rsb_coo_idx_t incY)467 rsb_err_t rsb_spmv(rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, const void * Xp, rsb_coo_idx_t incX, const void * betap, void * Yp, rsb_coo_idx_t incY)
468 {
469 	/*!
470 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
471 
472 	   Multiplies a sparse matrix \f$opa(A)\f$ by a vector \f$X\f$, updating vector \f$Y\f$.
473 	   \n
474 	   Computes \f$Y \leftarrow \beta Y + \alpha \cdot opa(A) \cdot X \f$.
475 	   \n
476 	   It is not allowed to supply same \c Xp and \c Yp  (that is, \c Xp==Yp).
477 	   \n
478 
479 	   \rsb_transa_mtx_msg
480 	   \rsb_num_threads
481 
482 	   \param \rsb_transa_inp_param_msg
483 	   \param \rsb_alpha_inp_param_msg
484 	   \param \rsb_mtxt_inp_param_msg_a
485 	   \param \rsb_x_inp_param_msg
486 	   \param \rsb_incx_inp_param_msg
487 	   \param \rsb_beta_inp_param_msg
488 	   \param \rsb_y_out_param_msg
489 	   \param \rsb_incy_inp_param_msg
490 	   \return \rsberrcodemsg
491 	   \see_lib_spmx
492 	 */
493 	rsb_err_t errval = RSB_ERR_NO_ERROR;
494 	RSB_INTERFACE_PREAMBLE
495        	errval = rsb_do_spmv(transA, alphap, mtxAp, Xp, incX, betap, Yp, incY);
496 	RSB_INTERFACE_RETURN_ERR(errval)
497 }
498 
499 #if 0
500 rsb_err_t rsb_spmv_sa(const struct rsb_mtx_t * mtxAp, const void * Xp, void * Yp, const void *alphap, rsb_trans_t transA)
501 {
502 	/*!
503 	 * \ingroup rsb_doc_matrix_operations rsb_doc_rsb
504 	 * computes \f$Y \leftarrow Y + \alpha op(A) \cdot X \f$
505 	 * \return \rsberrcodemsg
506 	 *
507 	 * */
508 	if(!alphap || !mtxAp)
509 		return RSB_ERR_BADARGS;
510 	return rsb__do_spmv_general(transA,alphap,mtxTp,Xp,1,NULL,Yp,1,RSB_OP_FLAG_DEFAULT RSB_DEFAULT_OUTER_NRHS_SPMV_ARGS);
511 }
512 #endif
513 
rsb_spsv(rsb_trans_t transT,const void * alphap,const struct rsb_mtx_t * mtxTp,const void * Xp,rsb_coo_idx_t incX,void * Yp,rsb_coo_idx_t incY)514 rsb_err_t rsb_spsv(rsb_trans_t transT, const void * alphap, const struct rsb_mtx_t * mtxTp, const void * Xp, rsb_coo_idx_t incX, void * Yp, rsb_coo_idx_t incY)
515 {
516 	/*!
517 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
518 
519 	   Computes \f$Y \leftarrow \alpha \cdot opt( T )^{-1} \cdot X \f$, with upper or lower triangular \f$T\f$.
520 	   It is allowed to supply same \c Xp and \c Yp  (that is, \c Xp==Yp).
521 
522 	   \rsb_transt_mtx_msg
523 
524 	   \param \rsb_transt_inp_param_msg
525 	   \param \rsb_alpha_inp_param_msg
526 	   \param \rsb_mtxt_inp_param_msg_t
527 	   \param \rsb_x_inp_param_msg
528 	   \param \rsb_incx_inp_param_msg
529 	   \param \rsb_y_out_param_msg
530 	   \param \rsb_incy_inp_param_msg
531 	   \return \rsberrcodemsg
532 	   \rsb_spsv_no_zero
533 	   \see_lib_spsx
534 	 */
535 	rsb_err_t errval = RSB_ERR_NO_ERROR;
536 	RSB_INTERFACE_PREAMBLE
537 	errval = rsb__do_spsv(transT, alphap, mtxTp, Xp, incX, Yp, incY);
538 	RSB_INTERFACE_RETURN_ERR(errval)
539 }
540 
541 #if 0
542 static rsb_err_t rsb__do_spsv_sxsx(const struct rsb_mtx_t * mtxAp, void * Yp, const void * alphap, rsb_coo_idx_t incX, rsb_trans_t transl)
543 {
544 	/*!
545 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
546 	   computes \f$Y \leftarrow \alpha op(A)^{-1} \cdot Y \f$.
547 	   \return \rsberrcodemsg
548 
549 	   It is allowed to use rhs == out, but in this case beta should be set to 1 and incX=incY, or the result will be undefined.
550 	 */
551 	return rsb__do_spsv_general(transl,alphap,mtxAp,Yp,1,Yp,1,RSB_OP_FLAG_DEFAULT RSB_INNER_NRHS_SPSV_ARGS_IDS);
552 }
553 #endif
554 
555 #if 0
556 rsb_err_t rsb_spmv_uxux(const struct rsb_mtx_t * mtxAp, const void * Xp, void * Yp, const void *alphap, const void * betap, rsb_trans_t transA)
557 {
558 	/*!
559 	 * \ingroup rsb_doc_matrix_operations rsb_doc_rsb
560 	 * computes \f$Y \leftarrow \beta \cdot Y + \alpha\cdot A\cdot X\f$
561 	 * \return \rsberrcodemsg
562 	 * */
563 	if(!alphap || !betap)
564 		return RSB_ERR_BADARGS;
565 	return rsb__do_spmv_general(transA,alphap,mtxAp,Xp,1,betap,Yp,1,RSB_OP_FLAG_DEFAULT RSB_DEFAULT_OUTER_NRHS_SPMV_ARGS);
566 }
567 #endif
568 
569 #if 0
570 rsb_err_t rsb_spmm_az(const struct rsb_mtx_t * mtxAp, const void * mrhs, void *mout, rsb_int_t bstride, rsb_int_t cstride, rsb_int_t nrhs, rsb_trans_t transA)
571 {
572 	/*!
573 	 * \ingroup rsb_doc_matrix_operations rsb_doc_rsb
574 	 * computes \f$Y \leftarrow op(A) \cdot X \f$
575 	 * when X is a multi-vector with nrhs elements, mrhs elements having stride bstride and mout elements having stride cstride
576 	 * \return \rsberrcodemsg
577 	 * */
578 	 /* FIXME : and error detection ? **/
579 #ifdef RSB_HAVE_OPTYPE_SPMM_AZ
580 	if(!mtxAp || !mout)
581 		return -1;
582 
583 	rsb__cblas_Xscal(mtxAp->typecode,nrhs*mtxAp->nr,NULL,mout,1);	/*FIXME:temporary*/
584 
585 	return rsb_spmm_inner(mtxAp,mrhs,mout,bstride,cstride,nrhs,transA);
586 #else
587 	return RSB_ERR_UNSUPPORTED_OPERATION;
588 #endif
589 }
590 
591 rsb_err_t rsb_spmm_sxsx(const struct rsb_mtx_t * mtxAp, const void * Bp, void * Cp, rsb_nnz_idx_t ldB, rsb_nnz_idx_t ldC, rsb_coo_idx_t nrhs, rsb_trans_t transA, const void * alphap, const void * betap, rsb_flags_t order)
592 {
593 	/*!
594 	   \return \rsberrcodemsg
595 	 */
596 	return rsb__do_spmm(transA,alphap,mtxAp,nrhs,order,Bp,ldB,betap,Cp,ldC,RSB_OP_FLAG_DEFAULT);
597 }
598 #endif
599 
600 // rsb_err_t rsb_spsm_sxsx(const struct rsb_mtx_t * mtxAp, void * Bp, rsb_nnz_idx_t ldB, rsb_coo_idx_t nrhs, rsb_trans_t transT, const void * alphap, const void * betap, rsb_flags_t order)
601 
rsb_spsm(rsb_trans_t transT,const void * alphap,const struct rsb_mtx_t * mtxTp,rsb_coo_idx_t nrhs,rsb_flags_t order,const void * betap,const void * Bp,rsb_nnz_idx_t ldB,void * Cp,rsb_nnz_idx_t ldC)602 rsb_err_t rsb_spsm(rsb_trans_t transT, const void * alphap, const struct rsb_mtx_t * mtxTp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * betap, const void * Bp, rsb_nnz_idx_t ldB, void * Cp, rsb_nnz_idx_t ldC)
603 {
604 	/*!
605 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
606 
607 	   Computes \f$Y \leftarrow \alpha \cdot opt( T )^{-1} \cdot B \f$, with upper or lower triangular \f$T\f$.
608 
609 	   \rsb_transt_mtx_msg
610 
611 	   \param \rsb_transt_inp_param_msg
612 	   \param \rsb_alpha_inp_param_msg
613 	   \param \rsb_mtxt_inp_param_msg_t
614 	   \param \rsb_nrhs_inp_param_msg
615 	   \param \rsb_order_inp_param_msg
616 	   \param \rsb_beta_inp_param_msg
617 	   \param \rsb_b_inp_param_msg
618 	   \param \rsb_ldb_inp_param_msg
619 	   \param \rsb_c_inp_param_msg
620 	   \param \rsb_ldc_inp_param_msg
621 	   \return \rsberrcodemsg
622 	   \see_lib_spsx
623 	 */
624 	   // \param \rsb_incx_inp_param_msg \param \rsb_incy_inp_param_msg
625 	rsb_err_t errval = RSB_ERR_NO_ERROR;
626 	RSB_INTERFACE_PREAMBLE
627 	errval = rsb__do_spsm(transT,alphap,mtxTp,nrhs,order,betap,Bp,ldB,Cp,ldC);
628 	RSB_INTERFACE_RETURN_ERR(errval)
629 }
630 
rsb_coo_sort(void * VA,rsb_coo_idx_t * IA,rsb_coo_idx_t * JA,rsb_nnz_idx_t nnzA,rsb_coo_idx_t nrA,rsb_coo_idx_t ncA,rsb_type_t typecode,rsb_flags_t flagsA)631 rsb_err_t rsb_coo_sort(void *VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA,  rsb_type_t typecode, rsb_flags_t flagsA )
632 {
633 	/*!
634 	   \ingroup gr_util rsb_doc_rsb
635 
636 	   Sorts row-major the given COO input arrays representing a sparse matrix \f$A\f$.
637 
638 	   \param \rsb_wr_va_ia_ja_desc_msg
639 	   \param \rsb_nnzA_inp_param_msg
640 	   \param \rsb_nrcows_A_sparse_inp_param_msg
641 	   \param \rsb_type_param_msg
642 	   \param \rsb_flagsa_inp_param_msg If unsure, use #RSB_FLAG_NOFLAGS.
643 	   \return \rsberrcodemsg
644 	   \see_lib_util
645 
646 	   \note By invoking with swapped \c IA and \c JA (and swapping \c nrA and \c ncA as well) one can obtain column major order.
647 	 */
648 	/* \warning \rsb_warn_unfinished_flags_doc_msg */
649 	/* Does it support Fortran flags ? */
650 	/* In the future, one may reuse this interface for:
651 	 * - cleaning up nonzeroes
652 	 * - sorting in different ways
653 	 * - compacting
654 	 * - checking only if input is sorted; e.g.: using the RSB_FLAG_SORTED_INPUT flag
655 	 * */
656 	rsb_err_t errval = RSB_ERR_NO_ERROR;
657 	RSB_INTERFACE_PREAMBLE
658 #if 0
659 	/* This is not the default and shall be rechecked. */
660 	errval = rsb__util_sort_row_major_buffered(VA,IA,JA,nnzA,nrA,ncA,typecode,flags,NULL,0);
661 #else
662 	/* This is not the default, well tested. */
663 	errval = rsb__util_sort_row_major_inner(VA,IA,JA,nnzA,nrA,ncA,typecode,flagsA);
664 #endif
665 	RSB_INTERFACE_RETURN_ERR(errval)
666 }
667 
rsb_file_mtx_get_dims(const char * filename,rsb_coo_idx_t * nrp,rsb_coo_idx_t * ncp,rsb_coo_idx_t * nzp,rsb_flags_t * flagsp)668 rsb_err_t rsb_file_mtx_get_dims(const char * filename, rsb_coo_idx_t* nrp, rsb_coo_idx_t *ncp, rsb_coo_idx_t *nzp, rsb_flags_t*flagsp)
669 {
670 	/*!
671 	   Reads structural information (dimensions, structural flags) for a matrix file into user specified (and optionally \c NULL) variables.
672 
673 	   \ingroup rsb_doc_misc rsb_doc_rsb
674 	   \param \rsb_filename_inp_param_msg
675 	   \param \rsb_nrcowsp_inp_param_msg
676 	   \param \rsb_nnzp_inp_param_msg
677 	   \param \rsb_flagsp_inp_param_msg
678 	   \return \rsberrcodemsg If read dimensions are illegal (see #rsb_coo_idx_t,#rsb_nnz_idx_t), #RSB_ERR_LIMITS will be returned.
679 
680 	   \rsb_matrixmarketonlynote_m
681 	   \note Upper/lower flags will not be reported.
682 	   \see_lib_get
683 	*/
684 	/* TODO: do we detect/read hermitiann'ess ? */
685 	rsb_err_t errval = RSB_ERR_NO_ERROR;
686 	RSB_INTERFACE_PREAMBLE
687 	errval = rsb__do_file_mtx_get_dims(filename, nrp, ncp, nzp, flagsp);
688 	RSB_INTERFACE_RETURN_ERR(errval)
689 }
690 
rsb_perror(void * stream,rsb_err_t errval)691 rsb_err_t rsb_perror(void *stream, rsb_err_t errval)
692 {
693 	/*!
694 	   \ingroup rsb_doc_error_handling rsb_doc_rsb
695 
696 	   Prints out to the specified \c stream  a string corresponding to the error code (using \c <stdio.h>'s \c fprintf).
697 	   If \c stream==NULL, will print out to the default output stream; see #RSB_IO_WANT_OUTPUT_STREAM .
698 
699 	   \param stream A \c (FILE*) pointer, as declared in \c <stdio.h>; can be \c NULL.
700 	   \param \rsb_errval_inp_param_msg
701 	   \return \rsberrcodemsg
702 	   \see_lib_error
703 	 */
704 	// \warning \rsb_warn_soon_to_be_updated_msg.
705 	//   \todo : Should use all bits of the errval variable.
706 	//   \todo : Should rename the function or make a new one matching perror().
707 	//   \todo : Could invoke this function from rsb_strerror_r(*,NULL,*)
708 	RSB_INTERFACE_PREAMBLE
709 	errval = rsb__do_perror(stream,errval);
710 	RSB_INTERFACE_RETURN_ERR(errval)
711 }
712 
rsb_strerror_r(rsb_err_t errval,rsb_char_t * buf,size_t buflen)713 rsb_err_t rsb_strerror_r(rsb_err_t errval, rsb_char_t * buf, size_t buflen)
714 {
715 	/*!
716 	   \ingroup rsb_doc_error_handling rsb_doc_rsb
717 
718 	   Writes a textual description of an error code in the specified string buffer.
719 	   No more than buflen characters will be written (comprehensive of the terminting \c NUL character).
720 
721 	   \param \rsb_errval_inp_param_msg
722 	   \param \rsb_buf_inp_param_msg
723 	   \param \rsb_buflen_inp_param_msg
724 
725 	   \return \rsberrcodemsg
726 	   \see_lib_error
727 	 */
728 	RSB_INTERFACE_PREAMBLE
729 	errval = rsb__do_strerror_r(errval,buf,buflen);
730 	RSB_INTERFACE_RETURN_ERR(errval)
731 }
732 
rsb_mtx_upd_vals(struct rsb_mtx_t * mtxAp,enum rsb_elopf_t elop_flags,const void * omegap)733 rsb_err_t rsb_mtx_upd_vals(struct rsb_mtx_t * mtxAp, enum rsb_elopf_t elop_flags, const void * omegap)
734 {
735 	/*!
736 	   \ingroup rsb_doc_matrix_handling rsb_doc_rsb
737 
738 	   \f$ A \leftarrow op (A,\Omega) \f$
739 	   Updates the matrix \f$A\f$ by applying either a rowwise or an elemental operation \f$op\f$, which is determined by \c elop_flags.
740 	   If an unary operation is selected, \c omegap can be \c NULL.
741 
742 	   \param \rsb_mtxt_inp_param_msg_a
743 	   \param \rsb_flags_elop_param_msg
744 	   \param \rsb_omega_inp_param_msg
745 	   \return \rsberrcodemsg
746 
747 	   \see_lib_set
748 	 */
749 	rsb_err_t errval = RSB_ERR_NO_ERROR;
750 	RSB_INTERFACE_PREAMBLE
751 	errval = rsb__do_upd_vals(mtxAp, elop_flags, omegap);
752 	RSB_INTERFACE_RETURN_ERR(errval)
753 }
754 
rsb_mtx_set_vals(struct rsb_mtx_t * mtxAp,const void * VA,const rsb_coo_idx_t * IA,const rsb_coo_idx_t * JA,rsb_nnz_idx_t nnz,rsb_flags_t flags)755 rsb_err_t rsb_mtx_set_vals(struct rsb_mtx_t * mtxAp, const void * VA, const rsb_coo_idx_t *IA, const rsb_coo_idx_t *JA, rsb_nnz_idx_t nnz, rsb_flags_t flags)
756 {
757 	/*!
758 	   \ingroup rsb_doc_matrix_handling rsb_doc_rsb
759 
760 	   Updates the specified matrix elements, if found in the nonzero pattern.
761 
762 	   In the special case of a matrix in assembly state (that is, one that has been created as empty with #rsb_mtx_alloc_from_coo_begin() and not yet assembled with #rsb_mtx_alloc_from_coo_end() ) all the supplied matrix elements will be accepted: whether already present or not.
763 
764 	   \param \rsb_mtxt_inp_param_msg_a
765 	   \param \rsb_ro_va_ia_ja_desc_msg
766 	   \param \rsb_nnz_inp_param_msg
767 	   \param \rsb_flags_setv_inp_param_msg
768 	   \return \rsberrcodemsg
769 
770 	   \see_lib_set
771 	 */
772 
773 	/* FIXME: new, UNFINISHED */
774 	/* FIXME: shall document what will do on out-of-pattern elements */
775 	/* should support sum, max, etc .. */
776 //	RSB_ERROR("!!\n");
777 //	if(flags == RSB_FLAG_DUPLICATES_SUM)
778 //		return RSB_ERR_UNIMPLEMENTED_YET;
779 //	else
780 	rsb_err_t errval = RSB_ERR_NO_ERROR;
781 	RSB_INTERFACE_PREAMBLE
782 	errval = rsb__do_set_elements(mtxAp,VA,IA,JA,nnz,flags);
783 	RSB_INTERFACE_RETURN_ERR(errval)
784 }
785 
rsb_mtx_get_vals(const struct rsb_mtx_t * mtxAp,void * VA,const rsb_coo_idx_t * IA,const rsb_coo_idx_t * JA,rsb_nnz_idx_t nnz,rsb_flags_t flags)786 rsb_err_t rsb_mtx_get_vals(const struct rsb_mtx_t * mtxAp, void * VA, const rsb_coo_idx_t *IA, const rsb_coo_idx_t *JA, rsb_nnz_idx_t nnz, rsb_flags_t flags)
787 {
788 	/*!
789 	   \ingroup rsb_doc_matrix_handling rsb_doc_rsb
790 
791 	   Gets the specified matrix elements, if found.
792 	   Please note that unlike #rsb_mtx_set_vals, the matrix has to be fully assembled here.
793 
794 	   \param \rsb_mtxt_inp_param_msg_a
795 	   \param \rsb_wr_va_rd_ia_ja_desc_msg
796 	   \param \rsb_nnz_inp_param_msg
797 	   \param \rsb_flags_getv_inp_param_msg
798 	   \return \rsberrcodemsg
799 
800            \see_lib_get
801 	 */
802 	/* may return an ...UNFINALIZED... error here ... */
803 	/* TODO: could document better error behaviour (e.g.: what if all updated except one ? ) */
804 	rsb_err_t errval = RSB_ERR_NO_ERROR;
805 	RSB_INTERFACE_PREAMBLE
806 	errval = rsb__do_get_elements(mtxAp,VA,IA,JA,nnz,flags);
807 	RSB_INTERFACE_RETURN_ERR(errval)
808 }
809 
rsb_file_mtx_save(const struct rsb_mtx_t * mtxAp,const rsb_char_t * filename)810 rsb_err_t rsb_file_mtx_save(const struct rsb_mtx_t * mtxAp, const rsb_char_t * filename)
811 {
812 	/*!
813 	   \ingroup rsb_doc_input_output rsb_doc_rsb
814 
815 	   Saves the given matrix to the specified matrix file.
816 
817 	   \param \rsb_mtxt_inp_param_msg_a
818 	   \param \rsb_filename_out_param_msg
819 	   \return \rsberrcodemsg
820 
821 	   \warning \rsb_warn_flags_not_complete_msg
822 
823 	   \rsb_matrixmarketonlynote_m
824 
825            \see_lib_info
826 	 */
827 	rsb_err_t errval = RSB_ERR_NO_ERROR;
828 	RSB_INTERFACE_PREAMBLE
829 	errval = rsb__do_file_mtx_save(mtxAp,filename);
830 	RSB_INTERFACE_RETURN_ERR(errval)
831 }
832 
rsb_file_vec_save(const rsb_char_t * filename,rsb_type_t typecode,const void * Yp,rsb_coo_idx_t yvl)833 rsb_err_t rsb_file_vec_save(const rsb_char_t * filename, rsb_type_t typecode, const void * Yp, rsb_coo_idx_t yvl)
834 {
835 	/*!
836 	   \ingroup rsb_doc_input_output rsb_doc_rsb
837 
838 	   Saves a dense vector to the specified file, using the numerical type representation as specified by the user.
839 	   This function assumes \c Yp!=NULL and \c yvl>0.
840 
841 	   \param \rsb_filename_inv_param_msg
842 	   \param \rsb_type_param_msg
843 	   \param \rsb_y_out_param_msg
844 	   \param \rsb_yvl_param_msg
845 	   \return \rsberrcodemsg
846 
847 	   \rsb_matrixmarketonlynote_v
848            \see_lib_info
849 	 */
850 	rsb_err_t errval = RSB_ERR_NO_ERROR;
851 	RSB_INTERFACE_PREAMBLE
852 	errval = rsb__do_vec_save(filename, typecode, Yp, yvl);
853 	RSB_INTERFACE_RETURN_ERR(errval);
854 }
855 
rsb_file_vec_load(const rsb_char_t * filename,rsb_type_t typecode,void * Yp,rsb_coo_idx_t * yvlp)856 rsb_err_t rsb_file_vec_load(const rsb_char_t * filename, rsb_type_t typecode, void * Yp, rsb_coo_idx_t *yvlp)
857 {
858 	/*!
859 	   \ingroup rsb_doc_input_output rsb_doc_rsb
860 
861 	   Loads a dense vector from the specified file, using the numerical type representation as specified by the user.
862 	   This function is intended to be called in two steps: first with \c Yp=NULL, in order to write the vector length to \c *yvlp ; then, with \c yvlp=NULL, to get \c Yp written.
863 
864 	   \param \rsb_filename_inv_param_msg
865 	   \param \rsb_type_param_msg
866 	   \param \rsb_y_inp_param_msg
867 	   \param \rsb_yvlp_param_msg
868 	   \return \rsberrcodemsg
869 
870 	   \rsb_matrixmarketonlynote_v
871            \see_lib_info
872 	 */
873 	rsb_err_t errval = RSB_ERR_NO_ERROR;
874 	RSB_INTERFACE_PREAMBLE
875 	errval = rsb__do_load_vector_file_as_matrix_market(filename,typecode,Yp,yvlp);
876 	RSB_INTERFACE_RETURN_ERR(errval);
877 }
878 
rsb_file_mtx_load(const rsb_char_t * filename,rsb_flags_t flagsA,rsb_type_t typecode,rsb_err_t * errvalp)879 struct rsb_mtx_t * rsb_file_mtx_load(const rsb_char_t * filename, rsb_flags_t flagsA, rsb_type_t typecode, rsb_err_t *errvalp)
880 {
881 	/*!
882 	   \ingroup rsb_doc_input_output rsb_doc_rsb
883 
884 	   Loads a sparse matrix from the specified matrix file, assembling it in the format specified by \rsb_flags, using the numerical type representation as specified by the user.
885 
886 	   \param \rsb_filename_inp_param_msg
887 	   \param \rsb_flagsa_inp_param_msg
888 	   \param \rsb_type_param_msg
889 	   \param \rsb_errvp_inp_param_msg
890 	   \return \rsbmtxpmessage
891 
892 	   \rsb_matrixmarketonlynote_m
893 	   \see_lib_info
894 	 */
895 	struct rsb_mtx_t * mtxAp = NULL;
896 	rsb_err_t errval = RSB_ERR_NO_ERROR;
897 	RSB_INTERFACE_PREAMBLE
898 	mtxAp = rsb__dodo_load_matrix_file_as_matrix_market(filename, flagsA, typecode, &errval);
899 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxAp,errval,errvalp);
900 }
901 
rsb_sppsp(rsb_type_t typecode,rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_trans_t transB,const void * betap,const struct rsb_mtx_t * mtxBp,rsb_err_t * errvalp)902 struct rsb_mtx_t * rsb_sppsp(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_trans_t transB, const void *betap, const struct rsb_mtx_t * mtxBp, rsb_err_t * errvalp)
903 {
904 	/*!
905 	   \ingroup rsb_doc_matrix_handling rsb_doc_rsb
906 
907 	   Computes the weighted sum of two sparse matrices, returning a new matrix:
908 	   \f$C \leftarrow \alpha\cdot transA(A) + \beta\cdot transB{B} \f$
909 	   Symmetry flags are ignored in this operation.
910 
911 	   \rsb_transa_mtx_msg
912 	   \rsb_transb_mtx_msg
913 
914 	   \param \rsb_type_param_msg
915 	   \param \rsb_transa_inp_param_msg
916 	   \param \rsb_alpha_inp_param_msg
917 	   \param \rsb_mtxt_abi_param_msg_a
918 	   \param \rsb_transb_inp_param_msg
919 	   \param \rsb_beta_inp_param_msg
920 	   \param \rsb_mtxt_abi_param_msg_b
921 	   \param \rsb_errvp_inp_param_msg
922 	   \return \rsbmtxpmessage
923 
924 	   \see_lib_gemm
925 
926 	   \warning \rsb_warn_not_th_tested_msg
927 	   \warning \rsb_warn_unoptimized_msg
928 	 */
929 	rsb_err_t errval = RSB_ERR_NO_ERROR;
930 	struct rsb_mtx_t * mtxCp = NULL;
931 	RSB_INTERFACE_PREAMBLE
932 	mtxCp = rsb__do_matrix_sum(typecode,transA,alphap,mtxAp,transB,betap,mtxBp,&errval);
933 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxCp,errval,errvalp);
934 }
935 
rsb_spmsp(rsb_type_t typecode,rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_trans_t transB,const void * betap,const struct rsb_mtx_t * mtxBp,rsb_err_t * errvalp)936 struct rsb_mtx_t * rsb_spmsp(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_trans_t transB, const void *betap, const struct rsb_mtx_t * mtxBp, rsb_err_t * errvalp)
937 {
938 	/*!
939 	   \ingroup rsb_doc_matrix_handling rsb_doc_rsb
940 
941 	   Computes the weighted product of two sparse matrices in a new sparse matrix (also known as SpGEMM operation):
942 	   \f$C \leftarrow \alpha \cdot opa(A) \cdot \beta \cdot opb(B) \f$
943 	   Symmetry/Hermitian flags are ignored by this operation.
944 
945 	   \rsb_transa_mtx_msg
946 	   \rsb_transb_mtx_msg
947 
948 	   \param \rsb_type_param_msg
949 	   \param \rsb_transa_inp_param_msg
950 	   \param \rsb_alpha_inp_param_msg
951 	   \param \rsb_mtxt_abi_param_msg_a
952 	   \param \rsb_transb_inp_param_msg
953 	   \param \rsb_beta_inp_param_msg
954 	   \param \rsb_mtxt_abi_param_msg_b
955 	   \param \rsb_errvp_inp_param_msg
956 	   \return \rsbmtxpmessage
957 
958 	   \warning Parameters \c alphap,betap,transA,transB  are not yet taken in consideration. The following defaults are valid: \f$\alpha=1.0\f$ and \f$\beta=1.0\f$, and \c transA=transB=#RSB_TRANSPOSITION_N.
959 
960 	   \see_lib_gemm
961 	 */
962 	/* FIXME: NEW, UNFINISHED, UNTESTED, UNSECURED */
963 	/* \warning \rsb_warn_not_th_tested_msg \warning \rsb_warn_unoptimized_msg  */
964 	struct rsb_mtx_t * mtxCp = NULL;
965 	rsb_err_t errval = RSB_ERR_NO_ERROR;
966 	RSB_INTERFACE_PREAMBLE
967 	mtxCp = rsb__do_matrix_mul(typecode,transA,alphap,mtxAp,transB,betap,mtxBp,&errval);
968 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxCp,errval,errvalp);
969 }
970 
rsb_mtx_add_to_dense(const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_nnz_idx_t ldB,rsb_nnz_idx_t nrB,rsb_nnz_idx_t ncB,rsb_bool_t rowmajorB,void * Bp)971 rsb_err_t rsb_mtx_add_to_dense(const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_nnz_idx_t ldB, rsb_nnz_idx_t nrB, rsb_nnz_idx_t ncB, rsb_bool_t rowmajorB, void * Bp)
972 {
973 	/*!
974 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
975 
976 	   Dense matrix B is updated by adding scaled sparse matrix \f${A}\f$ to it:
977 	   \f$B \leftarrow B + \alpha {A} \f$
978 
979 	   \param \rsb_alpha_inp_param_msg
980 	   \param \rsb_mtxt_abi_param_msg_a
981 	   \param \rsb_ldb_inp_param_msg
982 	   \param \rsb_nrcows_B_dense_inp_param_msg
983 	   \param \rsb_rowmajor_B_inp_param_msg
984 	   \param \rsb_dmtx_abi_param_msg_b
985 	   \return \rsberrcodemsg
986 	   \warning \rsb_warn_not_th_tested_msg
987 
988 	   \note Please note that it suffices to 'transpose' \c Bp's description parameters to get \f$A\f$ transposed summed in.
989 	   \see_lib_gemm
990 	 */
991 	/* TODO: add transA */
992 	rsb_err_t errval = RSB_ERR_NO_ERROR;
993 	RSB_INTERFACE_PREAMBLE
994 	errval = rsb__do_matrix_add_to_dense(alphap, mtxAp, ldB, nrB, ncB, rowmajorB, Bp);
995 	RSB_INTERFACE_RETURN_ERR(errval)
996 }
997 
rsb_psblas_trans_to_rsb_trans(const char psbtrans)998 rsb_trans_t rsb_psblas_trans_to_rsb_trans(const char psbtrans)
999 {
1000 	/*!
1001 	   \ingroup rsb_doc_misc rsb_doc_rsb
1002 
1003 	    Translate a PSBLAS transposition value character to a \librsb one.
1004 	    \n
1005 	    See the PSBLAS library website/documentation for valid input values.
1006 
1007 	   \param \rsb_psb_trans_inp_param_msg
1008 	   \return A valid transposition code; that is #RSB_TRANSPOSITION_N for 'N', #RSB_TRANSPOSITION_T for 'T', RSB_TRANSPOSITION_C for 'C',  (See \ref matrix_transposition_flags_section).
1009 	   \see_lib_psblas
1010 	 */
1011 	rsb_trans_t rsbtrans = RSB_TRANSPOSITION_INVALID;
1012 	RSB_INTERFACE_PREAMBLE
1013 	rsbtrans = rsb__do_psblas_trans_to_rsb_trans(psbtrans);
1014 	RSB_INTERFACE_RETURN_VAL(rsbtrans)
1015 }
1016 
rsb_mtx_alloc_from_csr_const(const void * VA,const rsb_coo_idx_t * RP,const rsb_coo_idx_t * JA,rsb_nnz_idx_t nnzA,rsb_type_t typecode,rsb_coo_idx_t nrA,rsb_coo_idx_t ncA,rsb_blk_idx_t brA,rsb_blk_idx_t bcA,rsb_flags_t flagsA,rsb_err_t * errvalp)1017 struct rsb_mtx_t * rsb_mtx_alloc_from_csr_const(const void *VA, const rsb_coo_idx_t * RP, const rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp)
1018 {
1019 	/*!
1020  	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1021 
1022 	   Given input read only CSR format arrays, allocates and assembles an RSB matrix (stored in separate arrays).
1023 
1024 	   \param \rsb_ro_va_rp_ja_desc_msg
1025 	   \param \rsb_nnzA_inp_param_msg
1026 	   \param \rsb_type_param_msg
1027 	   \param \rsb_nrcows_A_sparse_inp_param_msg
1028 	   \param \rsb_nrbows_A_sparse_inp_param_msg
1029 	   \param \rsb_flagsa_csr_param_msg
1030 	   \param \rsb_errvp_inp_param_msg
1031 	   \return \rsbmtxpmessage
1032 	   \see_lib_alloc
1033 	 */
1034 	// FIXME: flags and index and alloc mangling, here
1035 	// FIXME: UNTESTED, AND NNZ<M ?
1036 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1037 	struct rsb_mtx_t * mtxAp = NULL;
1038 	RSB_INTERFACE_PREAMBLE
1039 	mtxAp = rsb__do_mtx_alloc_from_csr_const(VA,RP,JA,nnzA,typecode,nrA,ncA,brA,bcA,flagsA,&errval);
1040 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxAp,errval,errvalp);
1041 }
1042 
rsb_mtx_alloc_from_csc_const(const void * VA,const rsb_coo_idx_t * IA,const rsb_coo_idx_t * CP,rsb_nnz_idx_t nnzA,rsb_type_t typecode,rsb_coo_idx_t nrA,rsb_coo_idx_t ncA,rsb_blk_idx_t brA,rsb_blk_idx_t bcA,rsb_flags_t flagsA,rsb_err_t * errvalp)1043 struct rsb_mtx_t * rsb_mtx_alloc_from_csc_const(const void *VA, const rsb_coo_idx_t * IA, const rsb_coo_idx_t * CP, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp)
1044 {
1045 	/*!
1046  	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1047 
1048 	   Given input read only CSC format arrays, allocates and assembles an RSB matrix (stored in separate arrays).
1049 
1050 	   \param \rsb_ro_va_ia_cp_desc_msg
1051 	   \param \rsb_nnzA_inp_param_msg
1052 	   \param \rsb_type_param_msg
1053 	   \param \rsb_nrcows_A_sparse_inp_param_msg
1054 	   \param \rsb_nrbows_A_sparse_inp_param_msg
1055 	   \param \rsb_flagsa_csc_param_msg
1056 	   \param \rsb_errvp_inp_param_msg
1057 	   \return \rsbmtxpmessage
1058 	   \see_lib_alloc
1059 	 */
1060 	// FIXME: flags and index and alloc mangling, here
1061 	// FIXME: UNTESTED, AND NNZ<M ?
1062 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1063 	struct rsb_mtx_t * mtxAp = NULL;
1064 	RSB_INTERFACE_PREAMBLE
1065        	mtxAp = rsb__do_mtx_alloc_from_csc_const(VA,IA,CP,nnzA,typecode,nrA,ncA,brA,bcA,flagsA,&errval);
1066 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxAp,errval,errvalp);
1067 }
1068 
rsb_mtx_alloc_from_csr_inplace(void * VA,rsb_nnz_idx_t * RP,rsb_coo_idx_t * JA,rsb_nnz_idx_t nnzA,rsb_type_t typecode,rsb_coo_idx_t nrA,rsb_coo_idx_t ncA,rsb_blk_idx_t brA,rsb_blk_idx_t bcA,rsb_flags_t flagsA,rsb_err_t * errvalp)1069 struct rsb_mtx_t * rsb_mtx_alloc_from_csr_inplace (void *VA, rsb_nnz_idx_t * RP, rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp )
1070 {
1071 	/*!
1072  	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1073 
1074 	   \rsb_mtx_alloc_csr_inplace_msg
1075 	   \n
1076 	   \rsb_note_assume_nnz_sized
1077 
1078 	   \param \rsb_wr_va_rp_ja_desc_msg
1079 	   \param \rsb_nnzA_inp_param_msg
1080 	   \param \rsb_type_param_msg
1081 	   \param \rsb_nrcows_A_sparse_inp_param_msg
1082 	   \param \rsb_nrbows_A_sparse_inp_param_msg
1083 	   \param \rsb_flagsa_csr_param_msg
1084 	   \param \rsb_errvp_inp_param_msg
1085 	   \return \rsbmtxpmessage
1086 	   \see_lib_alloc
1087 	 */
1088 	struct rsb_mtx_t * mtxAp = NULL;
1089 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1090 	RSB_INTERFACE_PREAMBLE
1091 	mtxAp = rsb__do_mtx_alloc_from_csr_inplace (VA, RP, JA, nnzA, typecode, nrA, ncA, brA, bcA, flagsA, &errval );
1092 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxAp,errval,errvalp);
1093 }
1094 
rsb_mtx_switch_to_csr(struct rsb_mtx_t * mtxAp,void ** VAp,rsb_coo_idx_t ** IAp,rsb_coo_idx_t ** JAp,rsb_flags_t flags)1095 rsb_err_t rsb_mtx_switch_to_csr(struct rsb_mtx_t * mtxAp, void ** VAp, rsb_coo_idx_t ** IAp, rsb_coo_idx_t ** JAp, rsb_flags_t flags)
1096 {
1097 	/*!
1098  	   \ingroup rsb_doc_matrix_conversion rsb_doc_rsb
1099 
1100 	   Switches the matrix to the CSR format, in-place.
1101 
1102 	   \param \rsb_mtxt_inp_param_msg_a
1103 	   \param \rsb_wr_va_ia_ja_p_desc_msg
1104 	   \param \rsb_flags_idc_param_msg Flags #RSB_FLAG_EXTERNALLY_ALLOCATED_ARRAYS are forbidden.
1105 	   \return \rsberrcodemsg
1106 
1107 	   \note \rsb_note_switch_in_place
1108 	   \warning \rsb_warn_not_th_tested_msg
1109 	   \see_lib_conv
1110 	 */
1111 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1112 	RSB_INTERFACE_PREAMBLE
1113 	errval = rsb__do_switch_rsb_mtx_to_csr_sorted(mtxAp, VAp, IAp, JAp, flags);
1114 	RSB_INTERFACE_RETURN_ERR(errval)
1115 }
1116 
rsb_mtx_get_coo(const struct rsb_mtx_t * mtxAp,void * VA,rsb_coo_idx_t * IA,rsb_coo_idx_t * JA,rsb_flags_t flags)1117 rsb_err_t rsb_mtx_get_coo(const struct rsb_mtx_t * mtxAp, void * VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_flags_t flags )
1118 {
1119 	rsb_nnz_idx_t nnz = 0;
1120 	/*!
1121 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
1122 
1123 	   Returns the matrix converted in a coordinate storage format.
1124 	   \n
1125 	   Elements will be stored in no particular order.
1126 	   \n
1127 	   If there are structural or fill-in zero elements, these will be skipped.
1128 	   \n
1129 	   Writes as many entries as there are nonzeroes (use #rsb_mtx_get_info(mtxAp,#RSB_MIF_MATRIX_NNZ__TO__RSB_NNZ_INDEX_T,&nnz)) to find out how many in order to allocate the arrays correctly.
1130 
1131 	   \param \rsb_mtxt_inp_param_msg_a
1132 	   \param \rsb_wr_va_ia_ja_desc_msg
1133 	   \param \rsb_flags_getco_inp_param_msg
1134 	   \return \rsberrcodemsg
1135 
1136 	   \see_lib_get
1137 	   */
1138 	   /*
1139 	    No more than mtxAp->nnz elements will be written.
1140 	   \todo Allow optional VA,IA,JA, for pattern matrices, or other purposes.
1141 	   */
1142 	 // FIXME: does not support misc flags !
1143 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1144 	RSB_INTERFACE_PREAMBLE
1145 	errval = rsb__do_get_coo_noalloc(mtxAp,VA,IA,JA,&nnz,flags);
1146 //err:
1147 	RSB_INTERFACE_RETURN_ERR(errval)
1148 }
1149 
rsb_mtx_get_csr(rsb_type_t typecode,const struct rsb_mtx_t * mtxAp,void * VA,rsb_nnz_idx_t * RP,rsb_coo_idx_t * JA,rsb_flags_t flags)1150 rsb_err_t rsb_mtx_get_csr(rsb_type_t typecode, const struct rsb_mtx_t *mtxAp, void * VA, rsb_nnz_idx_t * RP, rsb_coo_idx_t * JA, rsb_flags_t flags )
1151 {
1152 	/*!
1153  	   \ingroup rsb_doc_matrix_conversion rsb_doc_rsb
1154 
1155 	   Fills the given arrays with the matrix expressed in the CSR format.
1156 
1157 	   \param \rsb_type_param_msg
1158 	   \param \rsb_mtxt_inp_param_msg_a
1159 	   \param \rsb_wo_va_rp_ja_desc_msg
1160 	   \param \rsb_flags_getcs_inp_param_msg
1161 	   \return \rsberrcodemsg
1162 
1163 	   \see_lib_get
1164 	 */
1165 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1166 	RSB_INTERFACE_PREAMBLE
1167 	errval = rsb__do_get_csr(typecode,mtxAp,VA,RP,JA,flags);
1168 	RSB_INTERFACE_RETURN_ERR(errval)
1169 }
1170 
rsb_mtx_get_rows_sparse(rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,void * VA,rsb_coo_idx_t * IA,rsb_coo_idx_t * JA,rsb_coo_idx_t frA,rsb_coo_idx_t lrA,rsb_nnz_idx_t * rnzp,rsb_flags_t flags)1171 rsb_err_t rsb_mtx_get_rows_sparse(rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, void* VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_coo_idx_t frA, rsb_coo_idx_t lrA, rsb_nnz_idx_t *rnzp, rsb_flags_t flags)
1172 {
1173         /*!
1174 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
1175 
1176 	   Writes to the given COO arrays the specified submatrix.
1177 
1178 	   Invoke with \c VA,IA,JA  set to \c NULL  in order to get the nonzeroes count written to \c *rnzp, and know how large the arrays should be.
1179 
1180 	   \rsb_IA_can_null_msg (in this case it will be ignored).
1181 	   The written rows are ordered.
1182 
1183 	   \param \rsb_mtxt_inp_param_msg_a
1184 	   \param \rsb_wr_va_rd_ia_ja_desc_msg
1185 	   \param \rsb_inp_frlr_msg
1186 	   \param \rsb_inp_rnz_msg
1187 	   \param \rsb_alpha_inp_param_msg
1188 	   \param \rsb_transa_inp_param_msg
1189 	   \param \rsb_flags_getrs_inp_param_msg
1190 	   \return \rsberrcodemsg
1191 	   \see_lib_get
1192          */
1193 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1194 	RSB_INTERFACE_PREAMBLE
1195 	errval = rsb__do_get_rows_sparse(transA, alphap, mtxAp, VA, IA, JA, frA, lrA, rnzp, flags);
1196 	RSB_INTERFACE_RETURN_ERR(errval)
1197 }
1198 
rsb_mtx_get_coo_block(const struct rsb_mtx_t * mtxAp,void * VA,rsb_coo_idx_t * IA,rsb_coo_idx_t * JA,rsb_coo_idx_t frA,rsb_coo_idx_t lrA,rsb_coo_idx_t fcA,rsb_coo_idx_t lcA,const rsb_coo_idx_t * IREN,const rsb_coo_idx_t * JREN,rsb_nnz_idx_t * rnzp,rsb_flags_t flags)1199 rsb_err_t rsb_mtx_get_coo_block(const struct rsb_mtx_t * mtxAp, void* VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_coo_idx_t frA, rsb_coo_idx_t lrA, rsb_coo_idx_t fcA, rsb_coo_idx_t lcA, const rsb_coo_idx_t * IREN, const rsb_coo_idx_t * JREN, rsb_nnz_idx_t *rnzp, rsb_flags_t flags )
1200 {
1201 	/*!
1202 	   \ingroup rsb_doc_matrix_conversion rsb_doc_rsb
1203 
1204 	   Writes in COO format the specified submatrix.
1205 	   Works in two stages: first the user invokes it with \c VA,IA,JA set to \c NULL  to get \c *rnzp.
1206 	   Then the \c VA,IA,JA arrays can be allocated, and the function called again, this time with \c rnzp=NULL but the \c VA,IA,JA arrays pointers non \c NULL (or at least, one of them).
1207 
1208 	   \param \rsb_mtxt_inp_param_msg_a
1209 	   \param \rsb_wr_va_ia_ja_desc_msg
1210 	   \param \rsb_inp_frlr_msg
1211 	   \param \rsb_inp_fclc_msg
1212 	   \param \rsb_xren_inp_param_msg
1213 	   \param \rsb_inp_rnz_msg
1214 	   \param \rsb_flags_getcb_inp_param_msg
1215 	   \return \rsberrcodemsg
1216 	*/
1217 	/**
1218 	   Examples:
1219 \code
1220 // get nnz count first
1221 errval=rsb_mtx_get_coo_block(mtxAp,NULL,NULL,NULL,frA,lrA,fcA,lcA,NULL,NULL,&rnz,flags )
1222 // allocate VA, IA, JA to rnz elements
1223 ...
1224 // get the  rnz  values then
1225 errval=rsb_mtx_get_coo_block(mtxAp,  VA,  IA,  JA,frA,lrA,fcA,lcA,NULL,NULL,NULL,flags )
1226 \endcode
1227 	   */
1228 	/**
1229 	   \warning Expect this function to change soon (e.g.: have scaling parameters, etc.). Contact the author if you intend to use it.
1230 	   \see_lib_get
1231 	 */
1232 	/* \rsb_VA_can_null_msg (in such case, only the pattern information is extracted). */
1233 	/* FIXME: shall test rsb_mtx_get_coo_block with VA=NULL */
1234 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1235 	RSB_INTERFACE_PREAMBLE
1236 	errval = rsb__do_get_block_sparse(mtxAp,VA,IA,JA,frA,lrA,fcA,lcA,IREN,JREN,rnzp,flags);
1237 	RSB_INTERFACE_RETURN_ERR(errval)
1238 }
1239 
rsb_spmm(rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_coo_idx_t nrhs,rsb_flags_t order,const void * Bp,rsb_nnz_idx_t ldB,const void * betap,void * Cp,rsb_nnz_idx_t ldC)1240 rsb_err_t rsb_spmm(rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * Bp, rsb_nnz_idx_t ldB, const void * betap, void * Cp, rsb_nnz_idx_t ldC)
1241 {
1242 	/*!
1243 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
1244 
1245 	   Updates a dense matrix with the product of sparse matrix by dense matrix;
1246 	   that is, computes \f$ C \leftarrow \beta\cdot C + \alpha\cdot opa(A) \cdot B \f$.
1247 
1248 	   \rsb_transa_mtx_msg
1249 	   \rsb_num_threads
1250 	   \rsb_spmm_compact_nrhs_msg
1251 
1252 	   \param \rsb_transa_inp_param_msg
1253 	   \param \rsb_alpha_inp_param_msg
1254 	   \param \rsb_mtxt_inp_param_msg_a
1255 	   \param \rsb_nrhs_inp_param_msg
1256 	   \param \rsb_order_inp_param_msg
1257 	   \param \rsb_b_inp_param_msg
1258 	   \param \rsb_ldb_inp_param_msg
1259 	   \param \rsb_beta_inp_param_msg
1260 	   \param \rsb_c_inp_param_msg
1261 	   \param \rsb_ldc_inp_param_msg
1262  	   \return \rsberrcodemsg
1263 	   \see_lib_spmx
1264 	 */
1265 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1266 	RSB_INTERFACE_PREAMBLE
1267 	errval = rsb__do_spmm(transA,alphap,mtxAp,nrhs,order,Bp,ldB,betap,Cp,ldC,RSB_OP_FLAG_DEFAULT);
1268 	RSB_INTERFACE_RETURN_ERR(errval)
1269 }
1270 
rsb_spmsp_to_dense(rsb_type_t typecode,rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_trans_t transB,const void * betap,const struct rsb_mtx_t * mtxBp,rsb_nnz_idx_t ldC,rsb_nnz_idx_t nrC,rsb_nnz_idx_t ncC,rsb_bool_t rowmajorC,void * Cp)1271 rsb_err_t rsb_spmsp_to_dense(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_trans_t transB, const void *betap, const struct rsb_mtx_t * mtxBp , rsb_nnz_idx_t ldC, rsb_nnz_idx_t nrC, rsb_nnz_idx_t ncC, rsb_bool_t rowmajorC, void *Cp)
1272 {
1273 	/*!
1274 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
1275 
1276 	   Computes the product of sparse matrices and adds it to a dense matrix:
1277 	   \f$C \leftarrow \alpha opa(A) \cdot \beta \cdot opb(B) \f$.
1278 
1279 	   \rsb_transa_mtx_msg
1280 	   \rsb_transb_mtx_msg
1281 
1282 	   \param \rsb_type_param_msg
1283 	   \param \rsb_transa_inp_param_msg
1284 	   \param \rsb_alpha_inp_param_msg
1285 	   \param \rsb_mtxt_inp_param_msg_a
1286 	   \param \rsb_transb_inp_param_msg
1287 	   \param \rsb_beta_inp_param_msg
1288 	   \param \rsb_mtxt_inp_param_msg_b
1289 	   \param \rsb_ldc_inp_param_msg
1290 	   \param \rsb_nrcows_C_dense_inp_param_msg
1291 	   \param \rsb_rowmajor_C_inp_param_msg
1292 	   \param \rsb_dmtx_abi_param_msg_c
1293  	   \return \rsberrcodemsg
1294 
1295 	   \warning Parameters \c alphap,betap,transA,transB  are not yet taken in consideration. The following defaults are valid: \f$\alpha=1.0\f$ and \f$\beta=1.0\f$, and \c transA=transB=#RSB_TRANSPOSITION_N.
1296 
1297 	   \see_lib_gemm
1298 	 */
1299 	/* \todo \rsb_todo_unfinished_inc_msg */
1300 	/* \warning \rsb_warn_unfinished_msg \warning \rsb_warn_unfinished_noerr_msg */
1301 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1302 	RSB_INTERFACE_PREAMBLE
1303 	errval = rsb__do_spgemm_to_dense(typecode,transA,alphap,mtxAp,transB,betap,mtxBp,ldC,nrC,ncC,!rowmajorC,Cp,NULL,NULL);
1304 	RSB_INTERFACE_RETURN_ERR(errval)
1305 }
1306 
rsb_mtx_rndr(const char * filename,const struct rsb_mtx_t * mtxAp,rsb_coo_idx_t pmWidth,rsb_coo_idx_t pmHeight,rsb_marf_t rflags)1307 rsb_err_t rsb_mtx_rndr(const char * filename, const struct rsb_mtx_t*mtxAp, rsb_coo_idx_t pmWidth, rsb_coo_idx_t pmHeight, rsb_marf_t rflags)
1308 {
1309 	/*!
1310 	   \ingroup rsb_doc_matrix_operations rsb_doc_rsb
1311 	   Renders a matrix to a file.
1312 	   Currently, only Encapsulated Postscript (EPS) is supported.
1313 
1314 	   \param \rsb_filename_out_param_msg
1315 	   \param \rsb_mtxt_inp_param_msg_a
1316 	   \param \rsb_render_pmwidth_inp_param_msg
1317 	   \param \rsb_render_pmheight_inp_param_msg
1318 	   \param \rsb_render_rflags_inp_param_msg
1319 
1320 	   \see_lib_rndr
1321 	*/
1322 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1323 	RSB_INTERFACE_PREAMBLE
1324 	errval = rsb__do_mtx_render(filename, mtxAp, pmWidth, pmHeight, rflags);
1325 	RSB_INTERFACE_RETURN_ERR(errval)
1326 }
1327 
rsb_file_mtx_rndr(void * pmp,const char * filename,rsb_coo_idx_t pmlWidth,rsb_coo_idx_t pmWidth,rsb_coo_idx_t pmHeight,rsb_marf_t rflags)1328 rsb_err_t rsb_file_mtx_rndr(void * pmp, const char * filename, rsb_coo_idx_t pmlWidth, rsb_coo_idx_t pmWidth, rsb_coo_idx_t pmHeight, rsb_marf_t rflags)
1329 {
1330 	/*!
1331 	   \ingroup rsb_doc_misc rsb_doc_rsb
1332 
1333 	   Renders as pixel map the matrix contained in a matrix file.
1334 
1335 	   \param \rsb_render_pmp_inp_param_msg
1336 	   \param \rsb_filename_inp_param_msg
1337 	   \param \rsb_render_pmlwidth_inp_param_msg
1338 	   \param \rsb_render_pmwidth_inp_param_msg
1339 	   \param \rsb_render_pmheight_inp_param_msg
1340 	   \param \rsb_render_rflags_inp_param_msg
1341 	   \return \rsberrcodemsg
1342 
1343 	   \warning \rsb_warn_not_th_tested_msg
1344 
1345 	   \note At the time being, \c pmlWidth is required to be equal to \c pmWidth.
1346 	   \see_lib_rndr
1347 	*/
1348 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1349 	RSB_INTERFACE_PREAMBLE
1350 	errval = rsb__do_file_mtx_rndr(pmp, filename, pmlWidth, pmWidth, pmHeight, rflags);
1351 	RSB_INTERFACE_RETURN_ERR(errval)
1352 }
1353 
rsb_mtx_switch_to_coo(struct rsb_mtx_t * mtxAp,void ** VAp,rsb_coo_idx_t ** IAp,rsb_coo_idx_t ** JAp,rsb_flags_t flags)1354 rsb_err_t rsb_mtx_switch_to_coo(struct rsb_mtx_t * mtxAp, void ** VAp, rsb_coo_idx_t ** IAp, rsb_coo_idx_t ** JAp, rsb_flags_t flags)
1355 {
1356 	/*!
1357  	   \ingroup rsb_doc_matrix_conversion rsb_doc_rsb
1358 
1359 	   Switches a matrix to COO arrays in place.
1360 
1361 	   \param \rsb_mtxt_inp_param_msg_a
1362 	   \param \rsb_wr_va_ia_ja_p_desc_msg
1363 	   \param \rsb_flags_swcoo_inp_param_msg
1364 	   \return \rsberrcodemsg
1365 
1366 	   \note \rsb_note_switch_in_place
1367 	   \warning \rsb_warn_not_th_tested_msg
1368 	   \see_lib_conv
1369 	 */
1370 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1371 	RSB_INTERFACE_PREAMBLE
1372 	errval = rsb__do_switch_rsb_mtx_to_coo(mtxAp, VAp, IAp, JAp, flags);
1373 	RSB_INTERFACE_RETURN_ERR(errval)
1374 }
1375 
rsb_mtx_get_prec(void * opdp,const struct rsb_mtx_t * mtxAp,rsb_precf_t prec_flags,const void * ipdp)1376 rsb_err_t rsb_mtx_get_prec(void *opdp, const struct rsb_mtx_t * mtxAp, rsb_precf_t prec_flags, const void *ipdp)
1377 {
1378 	/*!
1379 	   \ingroup rsb_doc_misc rsb_doc_rsb
1380 
1381 	   A function computing a simple preconditioner out of \c mtxAp.
1382 
1383 	   \param opdp Preconditioner data pointer (output).
1384 	   \param \rsb_mtxt_inp_param_msg_a
1385 	   \param prec_flags Valid preconditioner request flags (currently, only #RSB_PRECF_ILU0 is supported; for it, \c *opdp will be overwritten with two \c rsb_mtx_t pointers, respectively a lower and an upper matrix.).
1386 	   \param ipdp  Preconditioner data pointer (input).
1387 
1388 	   \return \rsberrcodemsg
1389 
1390 	   \note Matrix should be square, have at least two rows, and have at least one nonzero.
1391 	   \see_lib_get
1392 	*/
1393 	/*
1394 	   \warning \rsb_warn_not_th_tested_msg
1395 	*/
1396 	/* FIXME: temporary interface */
1397 	rsb_err_t errval = RSB_ERR_UNIMPLEMENTED_YET;
1398 	RSB_INTERFACE_PREAMBLE
1399 	errval = rsb__do_get_preconditioner(opdp,mtxAp,prec_flags,ipdp);
1400 	RSB_INTERFACE_RETURN_ERR(errval)
1401 }
1402 
rsb_mtx_get_info(const struct rsb_mtx_t * mtxAp,enum rsb_mif_t miflags,void * minfop)1403 rsb_err_t rsb_mtx_get_info(const struct rsb_mtx_t *mtxAp, enum rsb_mif_t miflags, void* minfop)
1404 {
1405 	/*!
1406 	   \ingroup rsb_doc_misc rsb_doc_rsb
1407 
1408 	   \rsb_mtx_getinfo_msg.
1409 
1410 	   \param \rsb_mtxt_inp_param_msg_a
1411 	   \param \rsb_miflags_inp_param_msg
1412 	   \param \rsb_minfop_inp_param_msg
1413 
1414 	   \return \rsberrcodemsg
1415 
1416 	   \warning \rsb_warn_not_th_tested_msg
1417 	   \see_lib_info
1418 	*/
1419 	rsb_err_t errval = RSB_ERR_UNIMPLEMENTED_YET;
1420 	RSB_INTERFACE_PREAMBLE
1421 	errval = rsb__do_mtx_get_info(mtxAp, miflags, minfop);
1422 	RSB_INTERFACE_RETURN_ERR(errval)
1423 }
1424 
rsb_mtx_get_info_str(const struct rsb_mtx_t * mtxAp,const rsb_char_t * mis,void * minfop,size_t buflen)1425 rsb_err_t rsb_mtx_get_info_str(const struct rsb_mtx_t *mtxAp, const rsb_char_t *mis, void* minfop, size_t buflen)
1426 {
1427 	/*!
1428 	   \ingroup rsb_doc_misc rsb_doc_rsb
1429 
1430 	   \rsb_mtx_getinfo_msg, via a string form query.
1431 
1432 	   \param \rsb_mtxt_inp_param_msg_a
1433 	   \param mis A string specifying any identifier among the matrix info ones. See #rsb_mif_t for a list of valid identifiers that can be supplied in string form.
1434 	   \param \rsb_minfop_inp_param_msg
1435 	   \param buflen If greater than 0, \c minfop will be treated as a string of length \c buflen and filled with the desired value via the standard \c snprintf() function.
1436 
1437 	   \return \rsberrcodemsg
1438 
1439 	   \see_lib_info
1440 	*/
1441 	/* \warning \rsb_warn_not_th_tested_msg */
1442 	rsb_err_t errval = RSB_ERR_UNIMPLEMENTED_YET;
1443 	RSB_INTERFACE_PREAMBLE
1444 	errval = rsb__do_get_matrix_info_from_string(mtxAp,mis,minfop,buflen);
1445 	RSB_INTERFACE_RETURN_ERR(errval)
1446 }
1447 
rsb_mtx_get_nrm(const struct rsb_mtx_t * mtxAp,void * Np,enum rsb_extff_t flags)1448 rsb_err_t rsb_mtx_get_nrm(const struct rsb_mtx_t * mtxAp , void * Np, enum rsb_extff_t flags)
1449 {
1450 	/*!
1451 	   \ingroup rsb_doc_misc rsb_doc_rsb
1452 
1453 	   Computes a matrix norm (either infinite-norm or or 2-norm or 1-norm).
1454 
1455 	   \param \rsb_mtxt_inp_param_msg_a
1456 	   \param Np  Points to a scalar value which will be overwritten with the selected norm.
1457 	   \param flags Either #RSB_EXTF_NORM_ONE or #RSB_EXTF_NORM_TWO or #RSB_EXTF_NORM_INF.
1458 
1459 	   In case of a complex type, only the real part will be written to \c Np.
1460 
1461 	   \return \rsberrcodemsg
1462 	   \see_lib_get
1463 	*/
1464 	rsb_err_t errval = RSB_ERR_BADARGS;
1465 	RSB_INTERFACE_PREAMBLE
1466 	errval = rsb__do_matrix_norm(mtxAp, Np, flags);
1467 	RSB_INTERFACE_RETURN_ERR(errval)
1468 }
1469 
rsb_mtx_get_vec(const struct rsb_mtx_t * mtxAp,void * Dp,enum rsb_extff_t flags)1470 rsb_err_t rsb_mtx_get_vec(const struct rsb_mtx_t * mtxAp , void * Dp, enum rsb_extff_t flags)
1471 {
1472 	/*!
1473 	   \ingroup rsb_doc_misc rsb_doc_rsb
1474 
1475 	   Will overwrite a supplied array with a specific vector quantity.
1476 
1477 	   \param \rsb_mtxt_inp_param_msg_a
1478 	   \param \rsb_d_inp_param_msg
1479 	   \param flags Either one of the different extraction filter flags (e.g.: #RSB_EXTF_DIAG, #RSB_EXTF_SUMS_ROW, ...) .
1480 	   \return \rsberrcodemsg
1481 	   \see_lib_get
1482 	*/
1483 	rsb_err_t errval = RSB_ERR_BADARGS;
1484 	RSB_INTERFACE_PREAMBLE
1485 	errval = rsb__do_matrix_compute(mtxAp,Dp,flags);
1486 	RSB_INTERFACE_RETURN_ERR(errval)
1487 }
1488 
rsb_time(void)1489 rsb_time_t rsb_time(void)
1490 {
1491 	/*!
1492 	   \ingroup rsb_doc_misc rsb_doc_rsb
1493 
1494 	   Returns the current time in seconds.
1495 	   This function is meant to be used for computing wall clock time intervals (e.g.: for benchmarking purposes).
1496 	   The user should not rely on this function for absolute time computations.
1497 
1498 	   \return A value for the current time, in seconds.
1499 	   \see_lib_util
1500 	 */
1501 	return rsb_do_time();
1502 }
1503 
1504 #if RSB_WANT_COO_BEGIN
rsb_mtx_alloc_from_coo_begin(rsb_nnz_idx_t nnzA,rsb_type_t typecode,rsb_coo_idx_t nrA,rsb_coo_idx_t ncA,rsb_flags_t flagsA,rsb_err_t * errvalp)1505 struct rsb_mtx_t * rsb_mtx_alloc_from_coo_begin(rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_flags_t flagsA, rsb_err_t * errvalp)
1506 {
1507 	/*!
1508  	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1509 
1510 	   Creates an empty matrix structure in assembly state.
1511 	   The user then populates it using #rsb_mtx_set_vals() repeatedly; then assembles it with #rsb_mtx_alloc_from_coo_end().
1512 
1513 	   \param \rsb_nnzA_inp_param_msg_i
1514 	   \param \rsb_type_param_msg
1515 	   \param \rsb_nrcows_A_sparse_inp_param_msg
1516 	   \param \rsb_flagsa_coc_param_msg
1517 	   \param \rsb_errvp_inp_param_msg
1518 	   \return \rsbmtxapmessage
1519 	   \warning \rsb_warn_not_th_tested_msg
1520 	   \see_lib_alloc
1521 	 */
1522 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1523 	struct rsb_mtx_t * mtxAp = NULL;
1524 	RSB_INTERFACE_PREAMBLE
1525 	mtxAp = rsb__do_mtx_alloc_from_coo_begin(nnzA,typecode,nrA,ncA,flagsA,&errval);
1526 	RSB_INTERFACE_RETURN_MTX_ERRP(mtxAp,errval,errvalp);
1527 }
1528 
rsb_mtx_alloc_from_coo_end(struct rsb_mtx_t ** mtxApp)1529 rsb_err_t rsb_mtx_alloc_from_coo_end(struct rsb_mtx_t ** mtxApp)
1530 {
1531 	/*!
1532  	   \ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1533 
1534 	   Assembles RSB arrays for a matrix in build state created with #rsb_mtx_alloc_from_coo_begin() and populated with #rsb_mtx_set_vals().
1535 	   After assembly, any operation on the matrix is allowed.
1536 
1537 	   \param \rsb_mtxt_inp_param_msg_i
1538 	   \return \rsberrcodemsg
1539 	   \warning \rsb_warn_not_th_tested_msg
1540 	   \note Note that the memory location of the matrix will be changed by this call, and the (old) \c *mtxApp  address value will be not valid anymore.
1541 	   \see_lib_alloc
1542 	 */
1543 	rsb_err_t errval = RSB_ERR_BADARGS;
1544 	RSB_INTERFACE_PREAMBLE
1545 	errval = rsb__do_mtx_alloc_from_coo_end(mtxApp);
1546 	RSB_INTERFACE_RETURN_ERR(errval)
1547 }
1548 #endif
1549 
1550 #if 0
1551 rsb_err_t rsb_tune_wrt(struct rsb_mtx_t ** mtxOpp, rsb_real_t *sfp, rsb_int_t *tnp, rsb_int_t maxr, rsb_time_t maxt, const struct rsb_mtx_t * mtxAp)
1552 {
1553 	/*!
1554  	\ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1555 
1556 	Tunes matrix with respect to a user specified "benchmark" or "performance oracle" function.
1557 	...
1558 	\rsb_version_12
1559 	*/
1560 
1561 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1562 	/* rsb__tune_spxx_bos (...) */
1563 	return errval;
1564 }
1565 #endif
1566 
rsb_tune_spmm(struct rsb_mtx_t ** mtxOpp,rsb_real_t * sfp,rsb_int_t * tnp,rsb_int_t maxr,rsb_time_t maxt,rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_coo_idx_t nrhs,rsb_flags_t order,const void * Bp,rsb_nnz_idx_t ldB,const void * betap,void * Cp,rsb_nnz_idx_t ldC)1567 rsb_err_t rsb_tune_spmm(struct rsb_mtx_t ** mtxOpp, rsb_real_t *sfp, rsb_int_t *tnp, rsb_int_t maxr, rsb_time_t maxt, rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * Bp, rsb_nnz_idx_t ldB, const void * betap, void * Cp, rsb_nnz_idx_t ldC)
1568 {
1569 	/*!
1570  	\ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1571 
1572        	An auto-tuner: optimizes either the matrix instance, the thread count or both for the #rsb_spmm operation.
1573 
1574 	\rsb_tune__doc_msg
1575 	\param \rsb_tune_mtxOpp_iou_param_msg
1576 	\param \rsb_tune_sfp_iou_param_msg
1577 	\param \rsb_tune_tnp_iou_param_msg
1578 	\param \rsb_tune_maxr_iou_param_msg
1579 	\param \rsb_tune_maxt_iou_param_msg
1580 	\param \rsb_transa_inp_param_msg
1581 	\param \rsb_alpha_inp_param_msg
1582 	\param \rsb_mtxt_inp_param_msg_a
1583 	\param \rsb_nrhs_inp_param_msg
1584 	\param \rsb_order_inp_param_msg
1585 	\param \rsb_b_tune_inp_param_msg
1586 	\param \rsb_ldb_inp_param_msg
1587 	\param \rsb_beta_inp_param_msg
1588 	\param \rsb_c_tune_inp_param_msg
1589 	\param \rsb_ldc_inp_param_msg
1590 	\return \rsberrcodemsg
1591 	*/
1592 	/**
1593 	   Examples:
1594 \code
1595 // obtain best thread count for mtxAp:
1596 errval = rsb_tune_spmm(NULL  ,&sf,&tn ,maxr,maxt,transA,&alpha,mtxAp,nrhs,order,Bp,ldB,&beta,Cp,ldC);
1597 
1598 // obtain best thread count for mtxAp; Bp and Cp will be allocated by the tuner:
1599 errval = rsb_tune_spmm(NULL  ,&sf,&tn ,maxr,maxt,transA,&alpha,mtxAp,nrhs,order,NULL,0,&beta,NULL,0);
1600 
1601 // obtain best clone of mtxAp (for current thread count):
1602 assert(mtxOp == NULL && mtxAp != NULL);
1603 errval = rsb_tune_spmm(&mtxOp,&sf,NULL,maxr,maxt,transA,&alpha,mtxAp,nrhs,order,Bp,ldB,&beta,Cp,ldC);
1604 
1605 // obtain best clone of mtxAp and best thread count:
1606 assert(mtxOp == NULL && mtxAp != NULL);
1607 errval = rsb_tune_spmm(&mtxOp,&sf,&tn ,maxr,maxt,transA,&alpha,mtxAp,nrhs,order,Bp,ldB,&beta,Cp,ldC);
1608 
1609 // replace mtxAp with best clone (if any):
1610 errval = rsb_tune_spmm(&mtxAp,&sf,NULL,maxr,maxt,transA,&alpha,NULL ,nrhs,order,Bp,ldB,&beta,Cp,ldC);
1611 
1612 // replace mtxAp with best clone (if any) and obtain best thread count:
1613 errval = rsb_tune_spmm(&mtxAp,&sf,&tn ,maxr,maxt,transA,&alpha,NULL ,nrhs,order,Bp,ldB,&beta,Cp,ldC);
1614 
1615 // illegal call:
1616 assert(mtxOp != NULL && mtxAp != NULL);
1617 errval = rsb_tune_spmm(&mtxOp,&sf,&tn ,maxr,maxt,transA,&alpha,mtxAp,nrhs,order,Bp,ldB,&beta,Cp,ldC);
1618 \endcode
1619 	   */
1620 	/**
1621 	\warning
1622 	\rsb_tune_warning_doc_msg
1623 	\todo
1624 	\rsb_tune_todo_doc_msg
1625 	\see_lib_spmx
1626 	*/
1627 	rsb_err_t errval = RSB_ERR_BADARGS;
1628 	RSB_INTERFACE_PREAMBLE
1629 	errval = rsb__do_tune_spmm( mtxOpp, sfp, tnp, maxr, maxt, transA, alphap, mtxAp, nrhs, order, Bp, ldB, betap, Cp, ldC);
1630 	RSB_INTERFACE_RETURN_ERR(errval)
1631 }
1632 
rsb_tune_spsm(struct rsb_mtx_t ** mtxOpp,rsb_real_t * sfp,rsb_int_t * tnp,rsb_int_t maxr,rsb_time_t maxt,rsb_trans_t transA,const void * alphap,const struct rsb_mtx_t * mtxAp,rsb_coo_idx_t nrhs,rsb_flags_t order,const void * Bp,rsb_nnz_idx_t ldB,const void * betap,void * Cp,rsb_nnz_idx_t ldC)1633 rsb_err_t rsb_tune_spsm(struct rsb_mtx_t ** mtxOpp, rsb_real_t *sfp, rsb_int_t *tnp, rsb_int_t maxr, rsb_time_t maxt, rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * Bp, rsb_nnz_idx_t ldB, const void * betap, void * Cp, rsb_nnz_idx_t ldC)
1634 {
1635 	/*!
1636  	\ingroup rsb_doc_matrix_assembly rsb_doc_rsb
1637 
1638        	An auto-tuner: optimizes either the matrix instance, the thread count or both for the #rsb_spsm operation.
1639 
1640 	\rsb_tune__doc_msg
1641 	\param \rsb_tune_mtxOpp_iou_param_msg
1642 	\param \rsb_tune_sfp_iou_param_msg
1643 	\param \rsb_tune_tnp_iou_param_msg
1644 	\param \rsb_tune_maxr_iou_param_msg
1645 	\param \rsb_tune_maxt_iou_param_msg
1646 	\param \rsb_transa_inp_param_msg
1647 	\param \rsb_alpha_inp_param_msg
1648 	\param \rsb_mtxt_inp_param_msg_a
1649 	\param \rsb_nrhs_inp_param_msg
1650 	\param \rsb_order_inp_param_msg
1651 	\param \rsb_b_tune_inp_param_msg
1652 	\param \rsb_ldb_inp_param_msg
1653 	\param \rsb_beta_inp_param_msg
1654 	\param \rsb_c_tune_inp_param_msg
1655 	\param \rsb_ldc_inp_param_msg
1656 	\return \rsberrcodemsg
1657 
1658 	\rsb_spsv_no_zero
1659 	\warning
1660 	\rsb_tune_warning_doc_msg
1661 	\todo
1662 	\rsb_tune_todo_doc_msg
1663 	\see_lib_spsx
1664 	\see rsb_tune_spmm
1665 	*/
1666 	rsb_err_t errval = RSB_ERR_NO_ERROR;
1667 	RSB_INTERFACE_PREAMBLE
1668 	errval = rsb__do_tune_spsm( mtxOpp, sfp, tnp, maxr, maxt, transA, alphap, mtxAp, nrhs, order, Bp, ldB, betap, Cp, ldC);
1669 	RSB_INTERFACE_RETURN_ERR(errval)
1670 }
1671 
1672 /*
1673 struct rsb_mtx_t * rsb_BLAS_get_mtx(blas_sparse_matrix handle)
1674 {
1675 	struct rsb_mtx_t * mtxAp = NULL;
1676 	RSB_INTERFACE_PREAMBLE
1677 	mtxAp = rsb_do_BLAS_get_mtx(handle);
1678 	RSB_INTERFACE_RETURN_MTX(mtxAp);
1679 }
1680 */
1681 
1682