MAGMA  1.2.0
MatrixAlgebraonGPUandMulticoreArchitectures
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
auxiliary.cpp
Go to the documentation of this file.
1 /*
2  -- MAGMA (version 1.2.0) --
3  Univ. of Tennessee, Knoxville
4  Univ. of California, Berkeley
5  Univ. of Colorado, Denver
6  May 2012
7 */
8 
9 #include "common_magma.h"
10 #include <assert.h>
11 
12 /* ////////////////////////////////////////////////////////////////////////////
13  -- Get number of GPUs to use from $MAGMA_NUM_GPUS environment variable.
14  @author Mark Gates
15 */
16 extern "C"
17 int magma_num_gpus( void )
18 {
19  const char *ngpu_str = getenv("MAGMA_NUM_GPUS");
20  int ngpu = 1;
21  if ( ngpu_str != NULL ) {
22  char* endptr;
23  ngpu = strtol( ngpu_str, &endptr, 10 );
24  int ndevices;
25  cudaGetDeviceCount( &ndevices );
26  // if *endptr == '\0' then entire string was valid number (or empty)
27  if ( ngpu < 1 or *endptr != '\0' ) {
28  ngpu = 1;
29  fprintf( stderr, "$MAGMA_NUM_GPUS=%s is an invalid number; using %d GPU.\n",
30  ngpu_str, ngpu );
31  }
32  else if ( ngpu > MagmaMaxGPUs or ngpu > ndevices ) {
33  ngpu = min( ndevices, MagmaMaxGPUs );
34  fprintf( stderr, "$MAGMA_NUM_GPUS=%s exceeds MagmaMaxGPUs=%d or available GPUs=%d; using %d GPUs.\n",
35  ngpu_str, MagmaMaxGPUs, ndevices, ngpu );
36  }
37  assert( 1 <= ngpu and ngpu <= ndevices );
38  }
39  return ngpu;
40 }
41 
42 
43 /* ////////////////////////////////////////////////////////////////////////////
44  -- Print the available GPU devices
45  @author Mark Gates
46 */
47 extern "C"
49 {
50  int ndevices;
51  cudaGetDeviceCount( &ndevices );
52  for( int idevice = 0; idevice < ndevices; idevice++ ) {
53  cudaDeviceProp prop;
54  cudaGetDeviceProperties( &prop, idevice );
55  printf( "device %d: %s, %.1f MHz clock, %.1f MB memory, capability %d.%d\n",
56  idevice,
57  prop.name,
58  prop.clockRate / 1000.,
59  prop.totalGlobalMem / (1024.*1024.),
60  prop.major,
61  prop.minor );
62  }
63 }
64 
65 
66 /* ////////////////////////////////////////////////////////////////////////////
67  -- Auxiliary function: ipiv(i) indicates that row i has been swapped with
68  ipiv(i) from top to bottom. This function rearranges ipiv into newipiv
69  where row i has to be moved to newipiv(i). The new pivoting allows for
70  parallel processing vs the original one assumes a specific ordering and
71  has to be done sequentially.
72 */
73 extern "C"
74 void swp2pswp(char trans, int n, int *ipiv, int *newipiv){
75  int i, newind, ind;
76  char trans_[2] = {trans, 0};
77  long int notran = lapackf77_lsame(trans_, "N");
78 
79  for(i=0; i<n; i++)
80  newipiv[i] = -1;
81 
82  if (notran){
83  for(i=0; i<n; i++){
84  newind = ipiv[i] - 1;
85  if (newipiv[newind] == -1) {
86  if (newipiv[i]==-1){
87  newipiv[i] = newind;
88  if (newind>i)
89  newipiv[newind]= i;
90  }
91  else
92  {
93  ind = newipiv[i];
94  newipiv[i] = newind;
95  if (newind>i)
96  newipiv[newind]= ind;
97  }
98  }
99  else {
100  if (newipiv[i]==-1){
101  if (newind>i){
102  ind = newipiv[newind];
103  newipiv[newind] = i;
104  newipiv[i] = ind;
105  }
106  else
107  newipiv[i] = newipiv[newind];
108  }
109  else{
110  ind = newipiv[i];
111  newipiv[i] = newipiv[newind];
112  if (newind > i)
113  newipiv[newind] = ind;
114  }
115  }
116  }
117  } else {
118  for(i=n-1; i>=0; i--){
119  newind = ipiv[i] - 1;
120  if (newipiv[newind] == -1) {
121  if (newipiv[i]==-1){
122  newipiv[i] = newind;
123  if (newind>i)
124  newipiv[newind]= i;
125  }
126  else
127  {
128  ind = newipiv[i];
129  newipiv[i] = newind;
130  if (newind>i)
131  newipiv[newind]= ind;
132  }
133  }
134  else {
135  if (newipiv[i]==-1){
136  if (newind>i){
137  ind = newipiv[newind];
138  newipiv[newind] = i;
139  newipiv[i] = ind;
140  }
141  else
142  newipiv[i] = newipiv[newind];
143  }
144  else{
145  ind = newipiv[i];
146  newipiv[i] = newipiv[newind];
147  if (newind > i)
148  newipiv[newind] = ind;
149  }
150  }
151  }
152  }
153 }
154 
155 /* ////////////////////////////////////////////////////////////////////////////
156  -- Auxiliary function: used for debugging. Given a pointer to floating
157  point number on the GPU memory, the function returns the value
158  at that location.
159 */
160 extern "C"
161 float getv(float *da){
162  float res[1];
163  cublasGetVector(1, sizeof(float), da, 1, res, 1);
164  return res[0];
165 }
166 
167 /* ////////////////////////////////////////////////////////////////////////////
168  -- Auxiliary function sp_cat
169 */
170 extern "C"
171 int sp_cat(char *lp, char *rpp[], magma_int_t *rnp, magma_int_t*np, magma_int_t ll)
172 {
173  magma_int_t i, n, nc;
174  char *f__rp;
175 
176  n = (int)*np;
177  for(i = 0 ; i < n ; ++i)
178  {
179  nc = ll;
180  if(rnp[i] < nc)
181  nc = rnp[i];
182  ll -= nc;
183  f__rp = rpp[i];
184  while(--nc >= 0)
185  *lp++ = *f__rp++;
186  }
187  while(--ll >= 0)
188  *lp++ = ' ';
189 
190  return 0;
191 }