104template<
class T>
class CNC_MatrixCRS :
public CNC_MatrixPatternCRS {
108 inline CNC_MatrixCRS() : separate_diag(
true) {
111 inline void mult(
const T* x, T* y)
const{
114 if(symmetric_storage) {
116 for(
long i=0; i<diag.size(); i++) {
117 y[i] = x[i] * diag[i] ;
119 for(
long i=diag.size(); i<
m(); i++) {
122 for(
long i=0; i<
m(); i++) {
123 for(
long j=rowptr[i] ; j<rowptr[i+1]; j++) {
124 y[i] += a[j] * x[colind[j]] ;
125 y[colind[j]] += a[j] * x[i] ;
130 for(
long i=0; i<
m(); i++) {
132 for(
long j=rowptr[i] ; j<rowptr[i+1]; j++) {
133 sum += a[j] * x[colind[j]] ;
137 for(
long i=0; i<diag.size(); i++) {
138 y[i] += x[i] * diag[i] ;
142 if(symmetric_storage) {
144 memset ( y, 0,
sizeof(T) ) ;
145 for(
long i=0; i<
m(); i++) {
146 for(
long j=rowptr[i] ; j<rowptr[i+1]; j++) {
147 y[i] += a[j] * x[colind[j]] ;
149 y[colind[j]] += a[j] * x[i] ;
155 for(
long i=0; i<
m(); i++) {
157 for(
long j=rowptr[i] ; j<rowptr[i+1]; j++) {
158 sum += a[j] * x[colind[j]] ;
168 mult(x.data(), y.
data()) ;
170 long mem_usage()
const {
172 return CNC_MatrixPatternCRS::mem_usage() +
178 inline void gpu_allocate(){
181 cublasAlloc(a.size()+16,
sizeof(
double), &(gpu_mat_) ) ;
184 cublasAlloc(colind.size()+16, 4, &(gpu_ci_) ) ;
185 cublasAlloc(rowptr.size()-1+16,
sizeof(uint2), &(gpu_redundant_rp_)) ;
186 unsigned int * ci = CNCallocate_and_copy<long, unsigned int> ( colind.data(), colind.size() ) ;
187 uint2 * cpu_redundant_rp = CNCallocate<uint2> ( rowptr.size()-1 ) ;
189 for (
unsigned int i=0; i<rowptr.size()-1; i++) {
190 cpu_redundant_rp[i].x = rowptr.data()[i ] ;
191 cpu_redundant_rp[i].y = rowptr.data()[i+1] ;
194 cublasSetVector(rowptr.size()-1,
sizeof(uint2),cpu_redundant_rp, 1,gpu_redundant_rp_, 1 ) ;
195 cublasSetVector(colind.size(),
sizeof(
unsigned int),ci, 1, gpu_ci_, 1 ) ;
196 CNCdeallocate<uint2> ( cpu_redundant_rp ) ;
197 CNCdeallocate<unsigned int> ( ci ) ;
200 inline void gpu_upload(){
204 cublasSetVector(a.size(),
sizeof(
double), a.data(), 1, gpu_mat_, 1) ;
223 inline void gpu_deallocate () {
225 cublasFree(gpu_mat_) ;
227 cublasFree(gpu_redundant_rp_);
229 inline void gpu_mult(
const void *x,
void *y,
unsigned int vec_size){
231 cnc_cuda_mat1x1vecmult((
double*)gpu_mat_, a.size(),
232 (uint2*)gpu_redundant_rp_, rowptr.size(),
233 (
unsigned int*)gpu_ci_, colind.size(),
234 (
double*)x, (
double*)y, vec_size ) ;
237 inline void print(
void) {
238 printf(
"\n[CNC_MatrixCRS] print\n") ;
239 for(
long i=0; i<
m(); i++) {
240 for(
long jj=rowptr[i]; jj<rowptr[i+1]; jj++) {
242 long j = colind[jj] ;
243 printf (
"\t%d %d %f\n", i, j, a[jj] ) ;
244 if(symmetric_storage && j != i) {
245 printf (
"\t%d %d %f\n", j, i, a[jj] ) ;
251 for(
long i=0; i<diag.size(); i++) {
253 printf (
"\t%d %d %f\n", i, i, diag[i] ) ;
263 void * gpu_redundant_rp_ ;