 	{ OPT_KRYLOV,        "--krylov-method",      SO_REQ_CMB },
 	{ OPT_SAFE_FACT,     "--safe-fact",          SO_NONE    },
 	{ OPT_CONST_BAND,    "--const-band",         SO_NONE    },
-	{ OPT_VERBOSE,       "-v",                   SO_NONE    },
-	{ OPT_VERBOSE,       "--verbose",            SO_NONE    },
     { OPT_HELP,          "-?",                   SO_NONE    },
 	{ OPT_HELP,          "-h",                   SO_NONE    },
     { OPT_HELP,          "--help",               SO_NONE    },

			return false;
		}

		switch (args.OptionId()) {

		case OPT_HELP:
			ShowUsage();
			return false;

		case OPT_PART:
			pb.numPart = atoi(args.OptionArg());
			if (pb.numPart <= 0) {
				cout << "Invalid value for the number of partitions. P = " << pb.numPart << endl;
				return false;
			}
			break;

		case OPT_TOL:
			pb.tol = atof(args.OptionArg());
			break;
			
		case OPT_MAXIT:
			pb.maxIt = atoi(args.OptionArg());
			break;

		case OPT_DROPOFF_FRAC:
			pb.fraction = atof(args.OptionArg());
			break;

		case OPT_NO_REORDERING:
			pb.reorder = false;
			break;

		case OPT_NO_SCALING:
			pb.scale = false;
			break;

		case OPT_VERBOSE:
			pb.verbose = true;
			break;

		case OPT_MATFILE:
			pb.fileMat = args.OptionArg();
			break;

		case OPT_RHSFILE:
			pb.fileRhs = args.OptionArg();
			break;

		case OPT_OUTFILE:
			pb.fileSol = args.OptionArg();
			break;

		case OPT_FACTORIZATION:
			{
				string fact = args.OptionArg();
				std::transform(fact.begin(), fact.end(), fact.begin(), ::toupper);
				if (fact == "0" || fact == "LU_UL")
					pb.factorization = spike::LU_UL;
				else if (fact == "1" || fact == "LU_LU")
					pb.factorization = spike::LU_only;
				else
					return false;
			}

			break;

		case OPT_PRECOND:
			{
				string precond = args.OptionArg();
				std::transform(precond.begin(), precond.end(), precond.begin(), ::toupper);
				if (precond == "0" || precond == "SPIKE")
					pb.precondMethod = spike::Spike;
				else if(precond == "1" || precond == "BLOCK")
					pb.precondMethod = spike::Block;
				else
					return false;
			}

			break;

		case OPT_KRYLOV:
			{
				string kry = args.OptionArg();
				std::transform(kry.begin(), kry.end(), kry.begin(), ::toupper);
				if (kry == "0" || kry == "BICGSTAB")
					pb.krylov = spike::BiCGStab;
				else if (kry == "1" || kry == "BICGSTAB2")
					pb.krylov = spike::BiCGStab2;
				else
					return false;
			}

			break;

		case OPT_SINGLE_COMP:
			pb.singleComponent = true;
			break;

		case OPT_SAFE_FACT:
			pb.safeFactorization = true;
			break;

		case OPT_CONST_BAND:
			pb.variousBandwidth = false;
			break;
		}

	}

	// If no problem was defined, show usage and exit.
	if (pb.fileMat.length() == 0) {
		cout << "No matrix file was defined!" << endl << endl;
		ShowUsage();
		return false;
	}

	return true;
}


// -------------------------------------------------------------------
// ShowUsage()
//
// This function displays the correct usage of this program
// -------------------------------------------------------------------
void ShowUsage()
{
	cout << "Usage:  driver_mm [OPTIONS]" << endl;

};


// -----------------------------------------------------------------------------
// Forward declarations.
// -----------------------------------------------------------------------------
void ShowUsage();
void spikeSetDevice();
bool GetProblemSpecs(int                   argc, 
                     char**                argv,
				     string&               fileMat,
                     string&               fileRhs,
                     string&               fileSol,
                     int&                  numPart,
                     spike::SolverOptions& opts);
void PrintStats(bool               success,
                const SpikeSolver& mySolver,
                const SpmvFunctor& mySpmv);


// -----------------------------------------------------------------------------
// MAIN
// -----------------------------------------------------------------------------
int main(int argc, char** argv) 
{
	// Set up the problem to be solved.
	string  fileMat;
	string  fileRhs;
	string  fileSol;
	int     numPart;
	spike::SolverOptions  opts;

	if (!GetProblemSpecs(argc, argv, fileMat, fileRhs, fileSol, numPart, opts))
		return 1;

	// Get the device with most available memory.
	spikeSetDevice();

	// Get matrix and rhs.
	Matrix A;
	Vector b;

	cusp::io::read_matrix_market_file(A, fileMat);

	if (fileRhs.length() > 0)
		cusp::io::read_matrix_market_file(b, fileRhs);
	else
		b.resize(A.num_rows, 1);

	// Create the SPIKE Solver object and the SPMV functor. Perform the solver
	// setup, then solve the linear system using a 0 initial guess.
	// Set the initial guess to the zero vector.
	SpikeSolver mySolver(numPart, opts);
	SpmvFunctor  mySpmv(A);
	Vector       x(A.num_rows, 0);

	mySolver.setup(A);
	bool success = mySolver.solve(mySpmv, b, x);

	// Write solution file and print solver statistics.
	if (fileSol.length() > 0)
		cusp::io::write_matrix_market_file(x, fileSol);

	PrintStats(success, mySolver, mySpmv);

	return 0;
}


// -----------------------------------------------------------------------------
// spikeSetDevice()
//
// This function sets the active device to be the one with maximum available
// space.
// -----------------------------------------------------------------------------
void spikeSetDevice() {
	int deviceCount = 0;
	
