#ifndef UTIL_HH #define UTIL_HH #include #include #include #include // rand #include // gettimeofday #include #include //------------------------------------------------------------------------------ /// @return string describing cuBLAS error code. /// (CUDA has cudaGetErrorString, but cuBLAS doesn't have equivalent.) /// inline const char* my_cublasGetErrorString( cublasStatus_t err ) { switch (err) { case CUBLAS_STATUS_SUCCESS: return "success"; case CUBLAS_STATUS_NOT_INITIALIZED: return "not initialized"; case CUBLAS_STATUS_ALLOC_FAILED: return "alloc failed"; case CUBLAS_STATUS_INVALID_VALUE: return "invalid value"; case CUBLAS_STATUS_ARCH_MISMATCH: return "arch mismatch"; case CUBLAS_STATUS_MAPPING_ERROR: return "mapping error"; case CUBLAS_STATUS_EXECUTION_FAILED: return "execution failed"; case CUBLAS_STATUS_INTERNAL_ERROR: return "internal error"; case CUBLAS_STATUS_NOT_SUPPORTED: return "not supported"; case CUBLAS_STATUS_LICENSE_ERROR: return "license error"; default: return "unknown"; } } //------------------------------------------------------------------------------ /// Throws runtime_error if err is not cudaSuccess. /// inline void throw_error( cudaError_t err ) { if (err != cudaSuccess) { throw std::runtime_error( std::string("CUDA error: ") + cudaGetErrorString( err ) ); } } //------------------------------------------------------------------------------ /// Throws runtime_error if err is not CUBLAS_STATUS_SUCCESS. /// inline void throw_error( cublasStatus_t err ) { if (err != CUBLAS_STATUS_SUCCESS) { throw std::runtime_error( std::string("cuBLAS error: ") + my_cublasGetErrorString( err ) ); } } //------------------------------------------------------------------------------ /// @return ceil( x / y ) for integers x >= 0 and y > 0. /// Template types can be integer (int, long, ...). /// template T1 ceildiv( T1 x, T2 y ) { return (x + y - 1) / y; } //------------------------------------------------------------------------------ /// @return wall-clock time in seconds, with up to microsecond resolution. /// inline double get_wtime() { struct timeval tv; gettimeofday( &tv, nullptr ); return tv.tv_sec + tv.tv_usec * 1e-6; } //------------------------------------------------------------------------------ /// Fills an m-by-n matrix with random uniform [-1, 1] entries. /// Template type can be float or double. /// template void rand_matrix( int m, int n, T* A, int ld ) { for (int j = 0; j < n; ++j) { for (int i = 0; i < m; ++i) { A[ i + j*ld ] = 2. * rand() / T(RAND_MAX) - 1; } } } //------------------------------------------------------------------------------ /// Prints an m-by-n matrix. /// Template type can be float or double. /// template void print_matrix( const char* label, int m, int n, T const* A, int ld ) { printf( "%s = [\n", label ); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { printf( " %7.4f", A[ i + j*ld ] ); } printf( "\n" ); } printf( "];\n" ); } #endif // #ifndef UTIL_HH