Riccardo,
Thanks for your extended feedback!
> i finally managed to make my futurized sparse triangular solver to work.
> over the next days i'll try it for performance, but for this i'll need to
> develop a blocked version and some real CSR matrix.
> For now i post here the code so that if some expert has remarks i would be
> very glad to understand how to improve my code
>
> I should acknowledge that finally the error was on my side in passing the
> dependencies, which tells that hpx actually runs as expected.
> even though the final code is very simple it took me 3 days to have it to
> run, 95% of it due to difficulties with the c++ interface.
> Even though this is largely due to my lack of understanding of advanced
> c++, allow me a constructive user feedback:
That conforms to our experience with other users. Most problems come from
issues with C++ not with HPX.
> 1 - I'd like to signal that compiler error message become very obscure
> once "dataflow" comes into play.
> essentially any error is signalled in a "something wrong in the dataflow
> call" instead of being pointed to correctly.
> I fully appreciated it is not HPX fault, however i can tell you that for
> an unexperienced user it is a very problematic situation.
Yah, errors caused by dataflow are not very useful. If you had some examples of
code generating such errors we could try to improve those.
> 2 - it was not clear to me from the documentation that you expect either
> constant references or copy by value ... maybe an addition to your
> tutorial would or to your blog about this would be very interesting. I can
> ensure that for me it would have been impossible to figure this out from
> the error messages without Thomas's help.
This limitation is true for remote operation only (i.e. actions). But for those
you should see static_asserts explaining things properly. Using local
(non-action-based) async()/dataflow() do not have that restriction.
> 3 - it may be obvious for the developers but it was not obvious to me that
> unless i did a sort of "barrier" (wait_all) at the end of the code the
> destructors where being called before the parallel functions were
> executed. This was destroying my results. you might want to remark it in
> the documentation/blog posts...
Could you elaborate, please?
> 4 - the size of the overall HPX is huge. It would be much easier to
> include a dependency to it in other projects if it was split in smaller
> parts. For example if one is starting with SMP alone, dataflow & future
> would be very interesting on their own (i personally very much like the
> idea). Right now to compile HPX you also need all of the "distributed"
> code. the perfect situation would be that such core features are available
> as header only of course... Having said this i fully appreciate that the
> ideal situation would be to have such features available as part of the
> std lib.
Yes, that's something planned for HPX V2. Let's get V1 out of the door first,
then we can look into this.
> as promised here goes my code. Any suggestion on how to improve it would
> be very welcome. In particular i don't love the idea of passing all of
> those pointers, i would prefer passing a NON-STATIC class variable, but i
> could not manage to do that.
You should be able to pass references instead. You would need to wrap the
arguments in std::ref(), though:
int do_work(
hpx::lcos::future<std::vector<hpx::lcos::shared_future<int> > >
dependencies,
int color,
std::vector<int>& rows,
std::vector<int>& cols,
std::vector<double>& values,
std::vector<double>& b,
std::vector<double>& x)
{}
...
hpx::dataflow(hpx::launch::async,
&do_work_pointerversion,
hpx::when_all(item_dependencies.begin(), item_dependencies.end()),
i, std::ref(rows), std::ref(cols), std::ref(values), std::ref(b),
std::ref(xparallel));
Alternatively you package the variables in a new type and invoke a member
function of that type using dataflow:
struct my_type
{
std::vector<int> rows;
std::vector<int> cols
std::vector<double> values;
std::vector<double> b;
std::vector<double> x;
int do_work(
hpx::future<std::vector<hpx::shared_future<int> > > dependencies,
int color);
};
...
my_type t = {...};
hpx::dataflow(&my_type::do_work, &t,
hpx::when_all(item_dependencies.begin(), item_dependencies.end()),
i);
also possible:
hpx::dataflow(&my_type::do_work, std::ref(t),
hpx::when_all(item_dependencies.begin(), item_dependencies.end()),
i);
HTH
Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu
>
> regards
> Riccardo
>
> //[hello_world_client_getting_started
> #include <hpx/hpx_init.hpp>
> #include <hpx/hpx.hpp>
> #include <hpx/include/parallel_algorithm.hpp>
> #include <hpx/include/parallel_numeric.hpp>
> #include <hpx/include/threads.hpp>
> #include <hpx/include/threadmanager.hpp>
> #include <hpx/include/lcos.hpp>
> #include <unordered_map>
> #include <unordered_set>
> #include <vector>
>
> //compile with
> //g++ -std=c++14 -fPIC coloring_simpler.cpp -o coloring.exe -
> I/home/rrossi/scratch/hpx/build -I/home/rrossi/scratch/hpx/hpx -
> I/home/rrossi/compiled_libraries/boost_1_62/include/ -
> L/home/rrossi/scratch/hpx/build/lib -lhpx -
> L/home/rrossi/compiled_libraries/boost_1_62/lib/ -lboost_program_options -
> lboost_system -lboost_thread
>
>
>
>
>
> //this is the real worker function, which solves one line
> void SerialSolveLine(const int& i,
> const std::vector<int>& rows,
> const std::vector<int>& cols,
> const std::vector<double>& values,
> const std::vector<double>& b,
> std::vector<double>& x
> )
> {
> const auto row_begin = rows[i];
> const auto row_end = rows[i+1];
> double diag;
> double rhs = b[i];
> for(int k = row_begin; k<row_end; k++)
> {
>
> const auto col = cols[k];
> const auto value = values[k];
> if(col==i)
> diag = value;
> else
> rhs -= value*x[col];
> }
> x[i] = rhs/diag;
> }
>
> //provides the reference result
> void SerialTriangularSolve(const std::vector<int>& rows,
> const std::vector<int>& cols,
> const std::vector<double>& values,
> const std::vector<double>& b,
> std::vector<double>& x
> )
> {
> for(unsigned int i=0; i<x.size(); i++)
> {
> SerialSolveLine(i,rows,cols,values,b,x);
> }
> }
>
> int do_work_pointerversion(
> hpx::lcos::future<std::vector<hpx::lcos::shared_future<int> > >
> dependencies,
> int color,
> std::vector<int>* rows,
> std::vector<int>* cols,
> std::vector<double>* values,
> std::vector<double>* b,
> std::vector<double>* x)
> {
> SerialSolveLine(color,*rows,*cols,*values,*b,*x);
> return color;
> }
>
> int hpx_main(boost::program_options::variables_map&)
> {
> //lower triangular input matrix stored in compresses sparse row format
> //matrix
> // 1.0
> // 2.0 3.0
> // 4.0 5.0
> // 6.0 7.0
> // 8.0
> // 11 10 9.0
>
> //CSR format
> //rows vector 0 1 3 5 7 8 11
> //cols vector 0 0 1 1 2 2 3 4 0 1 5
> //values 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 11.0 10.0 9.0
> std::vector<int> rows = { 0, 1, 3, 5, 7, 8, 11};
> std::vector<int> cols = {0,0,1,1,2,2,3,4,0,1,5};
> std::vector<double> values =
> {1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,11.0,10.0,9.0};
>
> std::vector<double> b = {1.0,0.0,0.0,0.0,0.0,0.0};
> std::vector<double> x(6);
> std::vector<double> xparallel(6);
>
> int ncolors = x.size();
> std::vector< std::unordered_set<unsigned int> > dependencies(ncolors);
> dependencies[0]; //first has no dependencies
> dependencies[1].insert({0}); //can be executed when 0 is done
> dependencies[2].insert({1}); //can be executed when 1 is done
> dependencies[3].insert({2}); //can be executed when 2 is done
> dependencies[4]; //no dependencies
> dependencies[5].insert({0,1}); //can be executed when both 0 and 1 are
> done
>
> ////////////////////////////////////////////////////////
> //here reference serial solution
> SerialTriangularSolve(rows,cols,values,b,x);
>
> std::cout << "reference result is " << std::endl;
> for( auto it : x)
> std::cout << it << std::endl;
> std::cout << std::endl;
> ////////////////////////////////////////////////////////
>
> //this is a set with all of the tasks i am spawning
> std::unordered_map< unsigned int, hpx::lcos::shared_future<int> >
> work_items;
>
> //here i actually spawn the threads
> for(int i=0; i<ncolors; i++)
> {
> std::vector< hpx::lcos::shared_future<int> > item_dependencies;
>
> item_dependencies.reserve(dependencies[i].size());
> for(auto it : dependencies[i])
> {
> item_dependencies.push_back(work_items[it]);
> }
>
> work_items[i] = hpx::dataflow(hpx::launch::async,
> &do_work_pointerversion,
> hpx::when_all(item_dependencies.begi
> n(), item_dependencies.end()),
> i, &rows, &cols, &values, &b,
> &xparallel );
> }
>
> //the following wait_all is FUNDAMENTAL, otherwise it calls the
> destructor and the results are bullshit
> std::vector< hpx::lcos::shared_future<int> > towait;
> for(auto it : work_items)
> towait.push_back(it.second);
> hpx::wait_all(towait);
>
> std::cout << "parallel futurized result is " << std::endl;
> for( auto it : xparallel)
> std::cout << it << std::endl;
>
> return hpx::finalize(); // Initiate shutdown of the runtime system.
> }
>
> int main(int argc, char* argv[])
> {
> return hpx::init(argc, argv); // Initialize and run HPX.
> }
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> --
> Riccardo Rossi
> PhD, Civil Engineer
>
> member of the Kratos Team: www.cimne.com/kratos
> Tenure Track Lecturer at Universitat Politècnica de Catalunya,
> BarcelonaTech (UPC)
> Full Research Professor at International Center for Numerical Methods in
> Engineering (CIMNE)
>
> C/ Gran Capità, s/n, Campus Nord UPC, Ed. B0, Despatx 102
> (please deliver post to the porters of building C1)
> 08034 – Barcelona – Spain – www.cimne.com -
> T.(+34) 93 401 56 96 skype: rougered4
>
>
>
> Les dades personals contingudes en aquest missatge són tractades amb la
> finalitat de mantenir el contacte professional entre CIMNE i voste. Podra
> exercir els drets d'accés, rectificació, cancel·lació i oposició,
> dirigint-se a [email protected]. La utilització de la seva adreça de
> correu electronic per part de CIMNE queda subjecte a les disposicions de
> la Llei 34/2002, de Serveis de la Societat de la Informació i el Comerç
> Electronic.
> Imprimiu aquest missatge, només si és estrictament necessari.
_______________________________________________
hpx-users mailing list
[email protected]
https://mail.cct.lsu.edu/mailman/listinfo/hpx-users