[vsipl++] [patch] double support for SAL LU solver
Jules Bergmann
jules at codesourcery.com
Sun May 7 01:35:55 UTC 2006
Don McCoy wrote:
> This was tested against C-SAL but without the portions of the tests
> excercising the transpose options (when using the "old" functions).
Don,
This looks good. Can you:
- Move the reciprocal call from sal_matfbs to sal_matlud. That way
if multiple sal_matfbs calls are made (either because B/X have
multiple columns, or because the LU object is used multiple times),
vrecip will only get called once.
- Create a typedef for the block_type of recip_. That way the Ext_data
for recip_ is guaranteed to have the correct block type if recip_
ever changes.
- a few more comments sprinkled below.
If these comments make sense, once you address them this looks good to
check in.
How do we test this? By manually disabling the the mat_trans and
mat_herm cases?
thanks,
-- Jules
> +
> +
> +
> + // "Legacy" SAL functions - The single-precision versions are listed
> + // in the Appendix of the SAL Reference manual. Although the double-
> + // precision ones are still part of the normal API, we refer to both
> + // sets of functions as legacy functions just for ease of naming.
> +
> + // Legacy SAL LUD decomposition functions
> + #define VSIP_IMPL_SAL_LUD_DEC( T, SAL_T, SALFCN ) \
> + inline void \
> + sal_matlud( \
> + T *c, \
> + int *d, int n) \
> + { \
> + SALFCN((SAL_T*) c, d, n); \
If you pass recip_ in, you can perform the reciprocal one time here.
> + }
> --- 285,308 ----
>
> protected:
> template <mat_op_type tr,
> ! typename Block0,
> ! typename Block1>
> bool impl_solve(const_Matrix<T, Block0>, Matrix<T, Block1>)
> VSIP_NOTHROW;
>
> + length_type max_decompose_size();
> +
> // Member data.
> private:
> typedef std::vector<int, Aligned_allocator<int> > vector_type;
>
> ! length_type length_; // Order of A.
> ! vector_type ipiv_; // Pivot table for Q. This gets
> // generated from the decompose and
> ! // gets used in the solve
> ! Vector<T> recip_; // Vector of reciprocals used
> ! // with legacy solvers
Use a typedef for recip_'s block type.
> ! Matrix<T, data_block_type> data_; // Factorized matrix (A)
> };
>
>
> *************** Lud_impl<T,Mercury_sal_tag>::Lud_impl(
> *** 191,196 ****
> --- 320,326 ----
> VSIP_THROW((std::bad_alloc))
> : length_ (length),
> ipiv_ (length_),
> + recip_ (length_),
> data_ (length_, length_)
> {
> assert(length_ > 0);
> *************** Lud_impl<T,Mercury_sal_tag>::Lud_impl(Lu
> *** 203,213 ****
> --- 333,347 ----
> VSIP_THROW((std::bad_alloc))
> : length_ (lu.length_),
> ipiv_ (length_),
> + recip_ (length_),
> data_ (length_, length_)
> {
> data_ = lu.data_;
> for (index_type i=0; i<length_; ++i)
> + {
> ipiv_[i] = lu.ipiv_[i];
> + recip_.put(i, lu.recip_.get(i));
> + }
Since recip_ is a vector, you could just say:
recip_ = lu.recip_;
> }
>
>
> else
> --- 464,498 ----
> }
> Ext_data<data_block_type> a_ext((tr == mat_trans)?
> data_int.block():data_.block());
> + Ext_data<Dense<1, T> > r_ext(recip_.block());
>
> // sal_mat_lud_sol only takes vectors, so, we have to do this for each
> // column in the matrix
> ptr_type b_ptr = b_ext.data();
> ptr_type x_ptr = x_ext.data();
> ! for(index_type i=0;i<b.size(1);i++)
> ! {
> ! #if VSIP_IMPL_SAL_USE_MAT_LUD
> sal_mat_lud_sol(a_ext.data(), a_ext.stride(0),
> &ipiv_[0],
> ! storage_type::offset(b_ptr,i*length_),
> ! storage_type::offset(x_ptr,i*length_),
> ! length_,trans);
> ! #else
> ! if (x_ext.stride(0) != 1)
> ! VSIP_IMPL_THROW(unimplemented(
> ! "Lud_impl<>::impl_solve - data must be dense (have unit stride)"));
This should either be an assertion, or removed. x_ext refers to x_int,
which is declared by the LU object to be column major. Since we know
the block is column major, the condition x_ext.stride(0) != 1 would
indicate a bug in Ext_data (i.e. something impossible happened -> assert
failure), as opposed to unsupported behavior (user tried to do something
unsupported -> throw exception).
> ! if (tr == mat_ntrans)
> ! sal_matfbs(a_ext.data(), r_ext.data(), &ipiv_[0],
> ! storage_type::offset(b_ptr, i*length_),
> ! storage_type::offset(x_ptr, i*length_),
> ! length_);
> ! else
> ! VSIP_IMPL_THROW(unimplemented(
> ! "Lud_impl<mat_op_type!=mat_ntrans>::impl_solve - unimplemented"));
Good! Well, actually bad (SAL doesn't support mat_trans), but throwing
an exception is the right thing to do.
> ! #endif
> }
>
> assign_local(x, x_int);
> }
> else
--
Jules Bergmann
CodeSourcery
jules at codesourcery.com
(650) 331-3385 x705
More information about the vsipl++
mailing list