Skylark (Sketching Library)  0.1
/var/lib/jenkins/jobs/Skylark/workspace/examples/lsqr.cpp
Go to the documentation of this file.
00001 
00005 #include <iostream>
00006 #include <functional>
00007 #include <cstring>
00008 #include <vector>
00009 #include <utility>
00010 #include <ext/hash_map>
00011 
00012 #include <elemental.hpp>
00013 #include <CombBLAS.h>
00014 #include <boost/mpi.hpp>
00015 #include <skylark.hpp>
00016 
00017 #include "utilities.hpp"
00018 #include "parser.hpp"
00019 
00020 /*******************************************/
00021 namespace bmpi =  boost::mpi;
00022 namespace skys =  skylark::sketch;
00023 namespace skyb =  skylark::base;
00024 namespace skyalg = skylark::algorithms;
00025 namespace skynla = skylark::nla;
00026 namespace skyutil = skylark::utility;
00027 /*******************************************/
00028 
00029 /* These were declared as extern in utilities.hpp --- defining it here */
00030 int int_params [NUM_INT_PARAMETERS];
00031 char* chr_params[NUM_CHR_PARAMETERS];
00032 
00034 typedef std::vector<int> IntContainer;
00035 typedef std::vector<double> DblContainer;
00036 typedef elem::Matrix<double> DenseMatrixType;
00037 typedef elem::DistMatrix<double> DenseDistMatrixType;
00038 
00039 typedef SpDCCols<int, double> SparseMatrixType;
00040 typedef SpParMat<int, double, SparseMatrixType> SparseDistMatrixType;
00041 typedef FullyDistVec<int, double> SparseVectorType;
00042 typedef FullyDistMultiVec<int, double> SparseMultiVectorType;
00043 
00044 typedef skyutil::uniform_matrix_t<DenseDistMatrixType> uni_dense_dist_mat_t;
00045 typedef skyutil::uniform_matrix_t<SparseDistMatrixType> uni_sparse_dist_mat_t;
00046 typedef skyutil::uniform_matrix_t<SparseMultiVectorType> 
00047                                                   uni_sparse_dist_multi_vec_t;
00048 
00049 typedef skyutil::empty_matrix_t<DenseDistMatrixType> empty_dense_dist_mat_t;
00050 typedef skyutil::empty_matrix_t<SparseDistMatrixType> empty_sparse_dist_mat_t;
00051 typedef skyutil::empty_matrix_t<SparseMultiVectorType> 
00052                                                   empty_sparse_dist_multi_vec_t;
00053 
00054 typedef skyutil::print_t<SparseDistMatrixType> sparse_dist_mat_printer_t;
00055 typedef skyutil::print_t<SparseMultiVectorType> sparse_dist_multi_vec_printer_t;
00056 typedef skyutil::print_t<DenseDistMatrixType> dense_dist_mat_printer_t;
00057 
00058 int main (int argc, char** argv) {
00059 
00060   /* Initilize MPI manually to make sure that threading is supported */
00061   int provided;
00062   MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
00063 
00064   /* Create a global communicator */
00065   bmpi::communicator world;
00066 
00067   /* MPI sends argc and argv everywhere --- parse everywhere */
00068   parse_parameters (argc,argv);
00069 
00070   /* Initialize skylark */
00071   skyb::context_t context (int_params[RAND_SEED_INDEX]);
00072 
00074   if (SKETCH_LEFT != int_params[SKETCH_DIRECTION_INDEX]) {
00075     std::cout << "We don't support reading --- yet --" << std::endl;
00076     goto END;
00077   }
00078 
00080   if (0==int_params[USE_RANDOM_INDEX]) {
00082     std::cout << "We don't support reading --- yet --" << std::endl;
00083     goto END;
00084   }
00085 
00086   if (0==strcmp("elem",chr_params[MATRIX_TYPE_INDEX])) {
00089     /* Initialize elemental */
00090     elem::Initialize (argc, argv);
00091     MPI_Comm mpi_world(world);
00092     elem::Grid grid (mpi_world);
00093   
00094     DenseDistMatrixType A=uni_dense_dist_mat_t::generate
00095             (int_params[M_INDEX], int_params[N_INDEX], grid, context);
00096     DenseDistMatrixType B=uni_dense_dist_mat_t::generate
00097             (int_params[M_INDEX], int_params[N_RHS_INDEX], grid, context);
00098     DenseDistMatrixType X(int_params[N_INDEX], int_params[N_RHS_INDEX], grid);
00099 
00101     DenseMatrixType sketch_A(int_params[S_INDEX], int_params[N_INDEX]);
00102     DenseMatrixType sketch_B(int_params[S_INDEX], int_params[N_RHS_INDEX]);
00103     DenseMatrixType sketch_X(int_params[N_INDEX], int_params[N_RHS_INDEX]);
00104 
00105     /***********************************************************************/
00106     /* Hack to make sure that we can sketch matrices with MC,MR distributn */
00107     /***********************************************************************/
00108     typedef elem::DistMatrix<double, elem::VC, elem::STAR> CheatDistMatrixType;
00109     CheatDistMatrixType A_cheat(A), B_cheat(B);
00110     /***********************************************************************/
00111     if (0==strcmp("JLT", chr_params[TRANSFORM_INDEX]) ) {
00112       skys::JLT_t<CheatDistMatrixType, DenseMatrixType> 
00113         JLT (int_params[M_INDEX], int_params[S_INDEX], context);
00114       JLT.apply (A_cheat, sketch_A, skys::columnwise_tag());
00115       JLT.apply (B_cheat, sketch_B, skys::columnwise_tag());
00116     } else if (0==strcmp("FJLT", chr_params[TRANSFORM_INDEX]) ) {
00117       skys::FJLT_t<CheatDistMatrixType, DenseMatrixType> 
00118         FJLT (int_params[M_INDEX], int_params[S_INDEX], context);
00119         FJLT.apply (A_cheat, sketch_A, skys::columnwise_tag());
00120         FJLT.apply (B_cheat, sketch_B, skys::columnwise_tag());
00121     } else if (0==strcmp("CWT", chr_params[TRANSFORM_INDEX]) ) {
00122       skys::CWT_t<CheatDistMatrixType, DenseMatrixType>
00123         Sparse (int_params[M_INDEX], int_params[S_INDEX], context);
00124       Sparse.apply (A_cheat, sketch_A, skys::columnwise_tag());
00125       Sparse.apply (B_cheat, sketch_B, skys::columnwise_tag());
00126     } else {
00127       std::cout << "We only have JLT/FJLT/CWT sketching" << std::endl;
00128     }
00129     A_cheat.Empty();
00130     B_cheat.Empty();
00131 
00133     skynla::iter_params_t params(1e-14,  /* tolerance */
00134                                  world.rank()==0, /* only root prints */
00135                                  100, /* number of iterations */
00136                                  int_params[DEBUG_INDEX]-1); /* debugging */
00137 
00139     DblContainer exact_norms(int_params[N_RHS_INDEX], 0.0);
00140     skyalg::regression_problem_t<skyalg::l2_tag, DenseDistMatrixType> 
00141             exact_problem(int_params[M_INDEX], int_params[N_INDEX], A);
00142     skyalg::exact_regressor_t
00143         <skyalg::l2_tag,
00144          DenseDistMatrixType, 
00145          DenseDistMatrixType,
00146          skyalg::iterative_l2_solver_tag<skyalg::lsqr_tag> > 
00147          exact_regr(exact_problem);
00148     exact_regr.solve(B, X, params);
00149     skynla::iter_solver_op_t<DenseDistMatrixType, DenseDistMatrixType>::
00150                       residual_norms(A, B, X, exact_norms);
00151 
00152     if (1<int_params[DEBUG_INDEX] && 
00153         (int_params[M_INDEX]*int_params[N_INDEX])<100 && 
00154         world.rank() == 0) {
00155       elem::Display(A, "A"); 
00156       elem::Display(B, "B");
00157       elem::Display(X, "X");
00158     }
00159 
00161     DblContainer sketched_norms(int_params[N_RHS_INDEX], 0.0);
00162     skyalg::regression_problem_t<skyalg::l2_tag, DenseMatrixType> 
00163         sketched_problem(int_params[S_INDEX], int_params[N_INDEX], sketch_A);
00164     skyalg::exact_regressor_t
00165         <skyalg::l2_tag,
00166          DenseMatrixType, 
00167          DenseMatrixType,
00168          skyalg::iterative_l2_solver_tag<skyalg::lsqr_tag> > 
00169          sketched_regr(sketched_problem);
00170     sketched_regr.solve(sketch_B, sketch_X, params);
00171     DenseDistMatrixType sketch_X_global(X);
00172     skynla::iter_solver_op_t<DenseDistMatrixType, DenseDistMatrixType>::
00173                     make_dist_from_local (sketch_X, sketch_X_global);
00174     skynla::iter_solver_op_t<DenseDistMatrixType, DenseDistMatrixType>::
00175                       residual_norms(A, B, sketch_X_global, sketched_norms);
00176 
00177     if (1<int_params[DEBUG_INDEX] && 
00178         (int_params[M_INDEX]*int_params[N_INDEX])<100 && 
00179         world.rank() == 0) {
00180       dense_dist_mat_printer_t::apply (A, "A", true, 2);
00181       dense_dist_mat_printer_t::apply (B, "B", true, 2);
00182       dense_dist_mat_printer_t::apply (X, "X", true, 2);
00183     }
00184 
00186     if (0==world.rank()) {
00187       for (int i=0; i<int_params[N_RHS_INDEX]; ++i) 
00188         printf ("For RHS (%d), exact norm = %lf, sketched norm=%lf\n", 
00189                               i, exact_norms[i], sketched_norms[i]);
00190     }
00191 
00193     elem::Finalize();
00194 
00195   } else {
00198     /* Create matrices A and B */
00199     const int NNZ = int_params[M_INDEX]*int_params[N_INDEX]*0.5;
00200     SparseDistMatrixType A=uni_sparse_dist_mat_t::generate
00201             (int_params[M_INDEX], int_params[N_INDEX], NNZ, context);
00202     SparseMultiVectorType B=uni_sparse_dist_multi_vec_t::generate
00203             (int_params[M_INDEX], int_params[N_RHS_INDEX], context);
00204     SparseMultiVectorType X (int_params[N_INDEX], int_params[N_RHS_INDEX]);
00205 
00207     SparseDistMatrixType sketch_A=empty_sparse_dist_mat_t::generate
00208             (int_params[S_INDEX], int_params[N_INDEX]);
00209     SparseMultiVectorType sketch_B=empty_sparse_dist_multi_vec_t::generate
00210             (int_params[S_INDEX], int_params[N_RHS_INDEX]);
00211     SparseMultiVectorType sketch_X=empty_sparse_dist_multi_vec_t::generate
00212             (int_params[N_INDEX], int_params[N_RHS_INDEX]);
00213     if (0==strcmp("CWT", chr_params[TRANSFORM_INDEX]) ) {
00214       skys::CWT_t<SparseDistMatrixType, SparseDistMatrixType> 
00215         CWT_mat (int_params[M_INDEX], int_params[S_INDEX], context);
00216       CWT_mat.apply (A, sketch_A, skys::columnwise_tag());
00217       skys::CWT_t<SparseMultiVectorType, SparseMultiVectorType> 
00218         CWT_vec (CWT_mat);
00219       CWT_vec.apply (B, sketch_B, skys::columnwise_tag());
00220     } else {
00221       std::cout << "We only have CWT for sparse sketching" << std::endl;
00222     }
00223 
00225     skynla::iter_params_t params(1e-14,  /* tolerance */
00226                                  world.rank()==0, /* only root prints */
00227                                  100, /* number of iterations */
00228                                  int_params[DEBUG_INDEX]-1); /* debugging */
00229 
00231     DblContainer exact_norms(int_params[N_RHS_INDEX], 0.0);
00232     skyalg::regression_problem_t<skyalg::l2_tag, SparseDistMatrixType> 
00233             exact_problem(int_params[M_INDEX], int_params[N_INDEX], A);
00234     skyalg::exact_regressor_t
00235         <skyalg::l2_tag,
00236          SparseDistMatrixType, 
00237          SparseMultiVectorType,
00238          skyalg::iterative_l2_solver_tag<skyalg::lsqr_tag> > 
00239          exact_regr(exact_problem);
00240     exact_regr.solve(B, X, params);
00241     skynla::iter_solver_op_t<SparseDistMatrixType, SparseMultiVectorType>::
00242                       residual_norms(A, B, X, exact_norms);
00243 
00245     DblContainer sketched_norms(int_params[N_RHS_INDEX], 0.0);
00246     skyalg::regression_problem_t<skyalg::l2_tag, SparseDistMatrixType> 
00247          sketched_problem(int_params[S_INDEX], int_params[N_INDEX], sketch_A);
00248     skyalg::exact_regressor_t
00249         <skyalg::l2_tag,
00250          SparseDistMatrixType, 
00251          SparseMultiVectorType,
00252          skyalg::iterative_l2_solver_tag<skyalg::lsqr_tag> > 
00253          sketched_regr(sketched_problem);
00254     sketched_regr.solve(sketch_B, sketch_X, params);
00255     skynla::iter_solver_op_t<SparseDistMatrixType, SparseMultiVectorType>::
00256               residual_norms(A, B, sketch_X, sketched_norms);
00257 
00258     if (1<int_params[DEBUG_INDEX] && 
00259         (int_params[M_INDEX]*int_params[N_INDEX])<100 && 
00260         world.rank() == 0) {
00261       sparse_dist_mat_printer_t::apply (A, "A", true, 2);
00262       sparse_dist_multi_vec_printer_t::apply (B, "B", true, 2);
00263       sparse_dist_multi_vec_printer_t::apply (X, "X", true, 2);
00264     }
00265 
00267     if (0==world.rank()) {
00268       for (int i=0; i<int_params[N_RHS_INDEX]; ++i) 
00269         printf ("For RHS (%d), exact norm = %lf, sketched norm=%lf\n", 
00270                               i, exact_norms[i], sketched_norms[i]);
00271     }
00272   }
00273 
00274 END:
00275   return 0;
00276 }