Repository: alibaba/GraphScope (language: python)

Issue:
implement louvain algorithm

## What do these changes do?
implement a distributed louvain algorithm

## Related issue number
Fixes #182 


[BUG] Run louvain algo on k8s error
**Describe the bug**
Run louvain algo there is some error


**To Reproduce**

**run louvain**

```
graph = session.g(oid_type="string",generate_eid=True,directed=False)
####################################################################
#Louvain算法
print("开始运行 Louvain 算法")
result_louvain = graphscope.louvain(graph, min_progress=1000, progress_tries=1)
#格式整理
dataframe_louvain = result_louvain.to_dataframe({"node": "v.id", "result": "r"})
print("算法运行结束！")
```


**error log**

```
Consolidate compiler generated dependencies of target 5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a
[ 50%] Building CXX object CMakeFiles/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a.dir/opt/graphscope/include/graphscope/frame/app_frame.cc.o
In file included from /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:31,
                 from /opt/graphscope/include/graphscope/frame/app_frame.cc:43:
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h: In instantiation of 'void gs::PregelLouvain<FRAG_T>::Init(gs::PregelLouvain<FRAG_T>::pregel_vertex_t&, gs::PregelLouvain<FRAG_T>::compute_context_t&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; gs::PregelLouvain<FRAG_T>::pregel_vertex_t = gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; gs::PregelLouvain<FRAG_T>::compute_context_t = gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >]':
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:98:26:   required from 'void gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::PEval(const fragment_t&, gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::context_t&, gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::message_manager_t&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; VERTEX_PROGRAM_T = gs::PregelLouvain<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::fragment_t = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::context_t = gs::LouvainContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> > >; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::message_manager_t = grape::ParallelMessageManager]'
/opt/vineyard/include/grape/worker/worker.h:158:16:   required from 'typename std::enable_if<(! std::is_same<T, grape::AutoParallelMessageManager<typename APP_T::fragment_t> >::value)>::type grape::Worker<APP_T, MESSAGE_MANAGER_T>::runPEval() [with T = grape::ParallelMessageManager; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; MESSAGE_MANAGER_T = grape::ParallelMessageManager; typename std::enable_if<(! std::is_same<T, grape::AutoParallelMessageManager<typename APP_T::fragment_t> >::value)>::type = void; typename APP_T::fragment_t = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>]'
/opt/vineyard/include/grape/worker/worker.h:102:13:   required from 'void grape::Worker<APP_T, MESSAGE_MANAGER_T>::Query(Args&& ...) [with Args = {int, int}; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; MESSAGE_MANAGER_T = grape::ParallelMessageManager]'
/opt/graphscope/include/graphscope/core/app/app_invoker.h:191:18:   required from 'static void gs::AppInvoker<APP_T>::query_impl(std::shared_ptr<typename APP_T::worker_t>, const gs::rpc::QueryArgs&, std::index_sequence<__var_indices ...>) [with long unsigned int ...I = {0, 1}; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; typename APP_T::worker_t = grape::Worker<gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >, grape::ParallelMessageManager>; std::index_sequence<__var_indices ...> = std::integer_sequence<long unsigned int, 0, 1>]'
/opt/graphscope/include/graphscope/core/app/app_invoker.h:205:15:   required from 'static boost::leaf::result<std::nullptr_t> gs::AppInvoker<APP_T>::Query(std::shared_ptr<typename APP_T::worker_t>, const gs::rpc::QueryArgs&) [with APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; typename APP_T::worker_t = grape::Worker<gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >, grape::ParallelMessageManager>]'
/opt/graphscope/include/graphscope/frame/app_frame.cc:91:44:   required from here
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h:78:22: error: invalid 'static_cast' from type 'grape::EmptyType' to type 'gs::PregelLouvain<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >::edata_t' {aka 'float'}
   78 |       sigma_total += static_cast<edata_t>(e.get_data());
      |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h: In instantiation of 'void gs::PregelLouvain<FRAG_T>::getAndSendCommunityInfo(gs::PregelLouvain<FRAG_T>::pregel_vertex_t&, gs::PregelLouvain<FRAG_T>::compute_context_t&, const grape::IteratorPair<gs::LouvainMessage<typename FRAG_T::vid_t>*>&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; gs::PregelLouvain<FRAG_T>::pregel_vertex_t = gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; gs::PregelLouvain<FRAG_T>::compute_context_t = gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; typename FRAG_T::vid_t = long unsigned int]':
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h:154:7:   required from 'void gs::PregelLouvain<FRAG_T>::Compute(grape::IteratorPair<gs::LouvainMessage<typename FRAG_T::vid_t>*>, gs::PregelLouvain<FRAG_T>::pregel_vertex_t&, gs::PregelLouvain<FRAG_T>::compute_context_t&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; typename FRAG_T::vid_t = long unsigned int; gs::PregelLouvain<FRAG_T>::pregel_vertex_t = gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; gs::PregelLouvain<FRAG_T>::compute_context_t = gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >]'
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:110:37:   required from 'void gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::PEval(const fragment_t&, gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::context_t&, gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::message_manager_t&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; VERTEX_PROGRAM_T = gs::PregelLouvain<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::fragment_t = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::context_t = gs::LouvainContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> > >; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::message_manager_t = grape::ParallelMessageManager]'
/opt/vineyard/include/grape/worker/worker.h:158:16:   required from 'typename std::enable_if<(! std::is_same<T, grape::AutoParallelMessageManager<typename APP_T::fragment_t> >::value)>::type grape::Worker<APP_T, MESSAGE_MANAGER_T>::runPEval() [with T = grape::ParallelMessageManager; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; MESSAGE_MANAGER_T = grape::ParallelMessageManager; typename std::enable_if<(! std::is_same<T, grape::AutoParallelMessageManager<typename APP_T::fragment_t> >::value)>::type = void; typename APP_T::fragment_t = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>]'
/opt/vineyard/include/grape/worker/worker.h:102:13:   required from 'void grape::Worker<APP_T, MESSAGE_MANAGER_T>::Query(Args&& ...) [with Args = {int, int}; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; MESSAGE_MANAGER_T = grape::ParallelMessageManager]'
/opt/graphscope/include/graphscope/core/app/app_invoker.h:191:18:   required from 'static void gs::AppInvoker<APP_T>::query_impl(std::shared_ptr<typename APP_T::worker_t>, const gs::rpc::QueryArgs&, std::index_sequence<__var_indices ...>) [with long unsigned int ...I = {0, 1}; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; typename APP_T::worker_t = grape::Worker<gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >, grape::ParallelMessageManager>; std::index_sequence<__var_indices ...> = std::integer_sequence<long unsigned int, 0, 1>]'
/opt/graphscope/include/graphscope/core/app/app_invoker.h:205:15:   required from 'static boost::leaf::result<std::nullptr_t> gs::AppInvoker<APP_T>::Query(std::shared_ptr<typename APP_T::worker_t>, const gs::rpc::QueryArgs&) [with APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; typename APP_T::worker_t = grape::Worker<gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >, grape::ParallelMessageManager>]'
/opt/graphscope/include/graphscope/frame/app_frame.cc:91:44:   required from here
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h:215:35: error: invalid 'static_cast' from type 'grape::EmptyType' to type 'gs::PregelLouvain<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >::edata_t' {aka 'float'}
  215 |         out_message.edge_weight = static_cast<edata_t>(edge.get_data());
      |                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h:25,
                 from /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:31,
                 from /opt/graphscope/include/graphscope/frame/app_frame.cc:43:
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_vertex.h: In instantiation of 'gs::LouvainVertex<FRAG_T, VD_T, MD_T>::edata_t gs::LouvainVertex<FRAG_T, VD_T, MD_T>::get_edge_values(const std::set<typename FRAG_T::vid_t>&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; VD_T = std::__cxx11::basic_string<char>; MD_T = gs::LouvainMessage<long unsigned int>; gs::LouvainVertex<FRAG_T, VD_T, MD_T>::edata_t = float; typename FRAG_T::vid_t = long unsigned int; typename FRAG_T::vid_t = long unsigned int]':
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h:350:37:   required from 'double gs::PregelLouvain<FRAG_T>::calculateActualQuality(gs::PregelLouvain<FRAG_T>::pregel_vertex_t&, gs::PregelLouvain<FRAG_T>::compute_context_t&, const grape::IteratorPair<gs::LouvainMessage<typename FRAG_T::vid_t>*>&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; gs::PregelLouvain<FRAG_T>::pregel_vertex_t = gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; gs::PregelLouvain<FRAG_T>::compute_context_t = gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; typename FRAG_T::vid_t = long unsigned int]'
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h:133:16:   required from 'void gs::PregelLouvain<FRAG_T>::Compute(grape::IteratorPair<gs::LouvainMessage<typename FRAG_T::vid_t>*>, gs::PregelLouvain<FRAG_T>::pregel_vertex_t&, gs::PregelLouvain<FRAG_T>::compute_context_t&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; typename FRAG_T::vid_t = long unsigned int; gs::PregelLouvain<FRAG_T>::pregel_vertex_t = gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; gs::PregelLouvain<FRAG_T>::compute_context_t = gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >]'
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:110:37:   required from 'void gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::PEval(const fragment_t&, gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::context_t&, gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::message_manager_t&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; VERTEX_PROGRAM_T = gs::PregelLouvain<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::fragment_t = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::context_t = gs::LouvainContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> > >; gs::LouvainAppBase<FRAG_T, VERTEX_PROGRAM_T>::message_manager_t = grape::ParallelMessageManager]'
/opt/vineyard/include/grape/worker/worker.h:158:16:   required from 'typename std::enable_if<(! std::is_same<T, grape::AutoParallelMessageManager<typename APP_T::fragment_t> >::value)>::type grape::Worker<APP_T, MESSAGE_MANAGER_T>::runPEval() [with T = grape::ParallelMessageManager; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; MESSAGE_MANAGER_T = grape::ParallelMessageManager; typename std::enable_if<(! std::is_same<T, grape::AutoParallelMessageManager<typename APP_T::fragment_t> >::value)>::type = void; typename APP_T::fragment_t = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>]'
/opt/vineyard/include/grape/worker/worker.h:102:13:   required from 'void grape::Worker<APP_T, MESSAGE_MANAGER_T>::Query(Args&& ...) [with Args = {int, int}; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; MESSAGE_MANAGER_T = grape::ParallelMessageManager]'
/opt/graphscope/include/graphscope/core/app/app_invoker.h:191:18:   required from 'static void gs::AppInvoker<APP_T>::query_impl(std::shared_ptr<typename APP_T::worker_t>, const gs::rpc::QueryArgs&, std::index_sequence<__var_indices ...>) [with long unsigned int ...I = {0, 1}; APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; typename APP_T::worker_t = grape::Worker<gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >, grape::ParallelMessageManager>; std::index_sequence<__var_indices ...> = std::integer_sequence<long unsigned int, 0, 1>]'
/opt/graphscope/include/graphscope/core/app/app_invoker.h:205:15:   required from 'static boost::leaf::result<std::nullptr_t> gs::AppInvoker<APP_T>::Query(std::shared_ptr<typename APP_T::worker_t>, const gs::rpc::QueryArgs&) [with APP_T = gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >; typename APP_T::worker_t = grape::Worker<gs::LouvainAppBase<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >, grape::ParallelMessageManager>]'
/opt/graphscope/include/graphscope/frame/app_frame.cc:91:44:   required from here
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_vertex.h:123:18: error: invalid 'static_cast' from type 'grape::EmptyType' to type 'gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >::edata_t' {aka 'float'}
  123 |           ret += static_cast<edata_t>(edge.get_data());
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_vertex.h:129:18: error: invalid 'static_cast' from type 'grape::EmptyType' to type 'gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >::edata_t' {aka 'float'}
  129 |           ret += static_cast<edata_t>(edge.get_data());
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: note: unrecognized command-line option '-Wno-unused-lambda-capture' may have been intended to silence earlier diagnostics
cc1plus: note: unrecognized command-line option '-Wno-undef-prefix' may have been intended to silence earlier diagnostics
make[2]: *** [CMakeFiles/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a.dir/build.make:76: CMakeFiles/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a.dir/opt/graphscope/include/graphscope/frame/app_frame.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:110: CMakeFiles/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

```

**Environment (please complete the following information):**
 - GraphScope version:v0.25.0
 - OS: Linux
 - Kubernetes Version 1.23
 - python 3.7




Discussion / hints:
### community quality test 
compare the modularity of result partition with https://github.com/taynaud/python-louvain
#### dataset:  p2p (62586 nodes, 147892 edges)

graphscope louvain: 0.571986  find community num: 103
python-louvain:  0.578780 find community num: 110

#### com-youtube dataset (1134890 nodes, 2987624 edges), community num: 8,385
graphscope louvain: 0.717838,  find community_num: 4980
python-louvain: 0.7204, find community num: 5340

### performance test 
dataset:  com-friendster ( 65,608,366 nodes, 1,806,067,135 edges)
tolerance=0, min_progress=1

#### parallel GraphScope louvain (8 worker)
time: 7 min (remove the atomic operation, but bring in a three-level vector buffer to process messages to prevent thread conflict.) 

#### grape louvain( 8 worker, 128 frag)
time: 5 min








> Since it's will be open sourced, please revise the code style, such as function naming (Camel Style), class encapsulation, variable naming, comments, fixme, non-necessary header and so on.
> 
> Maybe you could add a python test case for louvain, mainly to demonstrate it's usage, and the format of result.
> Reference: https://google.github.io/styleguide/cppguide.html

Hi, @siyuan0322, thanks for reviewing,  could you quote some bad code examples as a hint, that would be much help.
# [Codecov](https://codecov.io/gh/alibaba/GraphScope/pull/183?src=pr&el=h1) Report
> Merging [#183](https://codecov.io/gh/alibaba/GraphScope/pull/183?src=pr&el=desc) (5a19fcc) into [main](https://codecov.io/gh/alibaba/GraphScope/commit/7a8f3f62b727eb2130126e569ffd03008adba058?el=desc) (7a8f3f6) will **decrease** coverage by `0.55%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/alibaba/GraphScope/pull/183/graphs/tree.svg?width=650&height=150&src=pr&token=S5G9F02T3J)](https://codecov.io/gh/alibaba/GraphScope/pull/183?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##             main     #183      +/-   ##
==========================================
- Coverage   78.91%   78.35%   -0.56%     
==========================================
  Files          52       53       +1     
  Lines        4767     4986     +219     
==========================================
+ Hits         3762     3907     +145     
- Misses       1005     1079      +74     
```


| [Impacted Files](https://codecov.io/gh/alibaba/GraphScope/pull/183?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [python/graphscope/analytical/app/\_\_init\_\_.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvYW5hbHl0aWNhbC9hcHAvX19pbml0X18ucHk=) | `100.00% <100.00%> (ø)` | |
| [python/graphscope/analytical/app/louvain.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvYW5hbHl0aWNhbC9hcHAvbG91dmFpbi5weQ==) | `100.00% <100.00%> (ø)` | |
| [...n/graphscope/deploy/kubernetes/resource\_builder.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvZGVwbG95L2t1YmVybmV0ZXMvcmVzb3VyY2VfYnVpbGRlci5weQ==) | `57.65% <0.00%> (-6.06%)` | :arrow_down: |
| [python/graphscope/framework/graph\_utils.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvZnJhbWV3b3JrL2dyYXBoX3V0aWxzLnB5) | `84.05% <0.00%> (-4.79%)` | :arrow_down: |
| [python/graphscope/framework/errors.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvZnJhbWV3b3JrL2Vycm9ycy5weQ==) | `92.64% <0.00%> (-1.48%)` | :arrow_down: |
| [python/graphscope/client/session.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvY2xpZW50L3Nlc3Npb24ucHk=) | `72.30% <0.00%> (-1.41%)` | :arrow_down: |
| [python/graphscope/interactive/query.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvaW50ZXJhY3RpdmUvcXVlcnkucHk=) | `89.28% <0.00%> (-0.72%)` | :arrow_down: |
| [python/graphscope/config.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvY29uZmlnLnB5) | `100.00% <0.00%> (ø)` | |
| [python/graphscope/client/rpc.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvY2xpZW50L3JwYy5weQ==) | `83.70% <0.00%> (ø)` | |
| [python/graphscope/dataset/ldbc.py](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree#diff-cHl0aG9uL2dyYXBoc2NvcGUvZGF0YXNldC9sZGJjLnB5) | `100.00% <0.00%> (ø)` | |
| ... and [10 more](https://codecov.io/gh/alibaba/GraphScope/pull/183/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/alibaba/GraphScope/pull/183?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/alibaba/GraphScope/pull/183?src=pr&el=footer). Last update [7a8f3f6...5a19fcc](https://codecov.io/gh/alibaba/GraphScope/pull/183?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

error log

```
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h:215:35: error: invalid 'static_cast' from type 'grape::EmptyType' to type 'gs::PregelLouvain<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false> >::edata_t' {aka 'float'}
```
Does the louvain algorithm not support oid custom String ID?
```
graph = session.g(oid_type="string",generate_eid=True,directed=False)
```
It means the graph has no edge data, but it needs it.
the graph has edge data:
```
## GIE 图基本操作
# Get the entrypoint for submitting Gremlin queries on graph g.
interactive = session.gremlin(graph)

edgenum = interactive.execute(
    "g.E().count()").one()
print("edgenum", edgenum)


vertexnum = interactive.execute(
    "g.V().count()").one()
print("vertexnum", vertexnum)

```

edgenum [30]
vertexnum [18]
Sorry, I mean property on that edges. For example, the louvain takes a graph which has a schema of (person, knows), where the knows has property as (id: string, weight: double)


After add property ('weight','double'), the same error is still reported
```
from graphscope.framework.loader import Loader
graph = (
        graph.add_vertices(Loader("file:///user/jacky.yang/graphcomputer/louvain/vertex_address.csv",filetype="csv")
                           ,label="user_id"
                           ,vid_field="id"
              )
             .add_edges(Loader("file:///user/jacky.yang/graphcomputer/louvain/edge_transaction.csv",filetype="csv")
                    ,label="login"
                    ,src_label="user_id"
                    ,dst_label="user_id"
                    ,src_field='from'
                    ,dst_field='to'
                    ,properties=[('weight', 'double')]
              )
             
            
    )
```

error log
```
开始运行 Louvain 算法
I1227 03:00:59.000000   506 /home/graphscope/GraphScope/analytical_engine/core/grape_instance.cc:268] Projecting graph graph_ipnqLnvB to simple graph: graph_projected_DYlg2S3a, type sig: 76170b1daab8ede76f000284df3134d76e2f0be377b9f3824b6501d4e33267c2
2023-12-27 03:01:00,315 [INFO][utils:243]: app type: gs::LouvainAppBase<_GRAPH_TYPE> (apps/pregel/louvain/louvain_app_base.h), graph type: gs::ArrowProjectedFragment<std::string,uint64_t,grape::EmptyType,grape::EmptyType,vineyard::ArrowVertexMap<vineyard::arrow_string_view,uint64_t>,false> (core/fragment/arrow_projected_fragment.h)
2023-12-27 03:01:00,318 [INFO][utils:452]: Building app library...
2023-12-27 03:01:00,421 [INFO][utils:469]: Codegened application type: cpp_pie, app header: apps/pregel/louvain/louvain_app_base.h, app_class: gs::LouvainAppBase<_GRAPH_TYPE>, vd_type: None, md_type: None, pregel_combine: None,             java_jar_path: None, java_app_class: None
2023-12-27 03:01:00,422 [INFO][utils:377]: compile on kubernetes, ["cmake . -DNETWORKX=ON -DCMAKE_PREFIX_PATH='/opt/graphscope;'", 'make -j2'], /tmp/gs/builtin/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a, 5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a, gs-engine-leahic-0, engine
2023-12-27 03:01:00,422 [INFO][utils:321]: Running command: kubectl exec -c engine gs-engine-leahic-0 -- bash -c "test -f /tmp/gs/builtin/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a/lib5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a.so", cwd: None
2023-12-27 03:01:00,794 [ERROR][utils:325]: Failed to run command: kubectl exec -c engine gs-engine-leahic-0 -- bash -c "test -f /tmp/gs/builtin/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a/lib5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a.so", error message is: command terminated with exit code 1
2023-12-27 03:01:00,794 [INFO][utils:321]: Running command: kubectl exec -c engine gs-engine-leahic-0 -- bash -c "mkdir -p /tmp/gs/builtin", cwd: None
2023-12-27 03:01:01,089 [DEBUG][utils:398]:
2023-12-27 03:01:01,089 [INFO][utils:321]: Running command: kubectl cp /tmp/gs/builtin/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a gs-engine-leahic-0:/tmp/gs/builtin/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a -c engine --retries=5, cwd: None
2023-12-27 03:01:01,359 [DEBUG][utils:399]:
2023-12-27 03:01:01,360 [INFO][utils:321]: Running command: kubectl exec -c engine gs-engine-leahic-0 -- bash -c "cd /tmp/gs/builtin/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a && cmake . -DNETWORKX=ON -DCMAKE_PREFIX_PATH='/opt/graphscope;'", cwd: None
2023-12-27 03:01:05,369 [DEBUG][utils:402]: -- The C compiler identification is GNU 11.4.0
2023-12-27 03:01:14,865 [ERROR][utils:325]: Failed to run command: kubectl exec -c engine gs-engine-leahic-0 -- bash -c "cd /tmp/gs/builtin/5bd82f1167356c336b6d76a64a6391048f8a717871f46092e024df869e6f2c3a && make -j2", error message is: In file included from /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:31,
                 from /opt/graphscope/include/graphscope/frame/app_frame.cc:43:
/opt/graphscope/include/graphscope/apps/pregel/louvain/louvain.h: In instantiation of 'void gs::PregelLouvain<FRAG_T>::Init(gs::PregelLouvain<FRAG_T>::pregel_vertex_t&, gs::PregelLouvain<FRAG_T>::compute_context_t&) [with FRAG_T = gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>; gs::PregelLouvain<FRAG_T>::pregel_vertex_t = gs::LouvainVertex<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >; gs::PregelLouvain<FRAG_T>::compute_context_t = gs::PregelComputeContext<gs::ArrowProjectedFragment<std::__cxx11::basic_string<char>, long unsigned int, grape::EmptyType, grape::EmptyType, vineyard::ArrowVertexMap<std::basic_string_view<char>, long unsigned int>, false>, std::__cxx11::basic_string<char>, gs::LouvainMessage<long unsigned int> >]':

```


ArrowProjectedFragment<std::string,uint64_t,grape::EmptyType,grape::EmptyType
but there's still no edge data there. Could you paste the code from load graph to run app, and several lines of your data so I can have a try of it?
load graph and run louvain
```
# enabled_engines="analytical,interactive",
import graphscope
graphscope.set_option(log_level='DEBUG')
graphscope.set_option(show_log=True)
from graphscope.config import Config

config = Config()
config.coordinator.monitor=True
config.log_level="debug"
config.show_log=True

# Create GraphScope client session, the 'cluster_type' is k8s by default.
session = graphscope.session(
                             k8s_coordinator_cpu=1,
                             k8s_coordinator_mem="1Gi",
                             k8s_vineyard_cpu=4,
                             k8s_vineyard_mem="5Gi",
                             vineyard_shared_mem="5Gi",
                             k8s_engine_cpu=2,
                             k8s_namespace='gs-new-orc-jacky',
                             k8s_engine_mem="5Gi",
                             num_workers=1,
                             enabled_engines="analytical,interactive",
                             k8s_client_config='~/.kube/config')
print('========= Session created. ==========')


graph = session.g(oid_type="string",generate_eid=True,directed=False)
from graphscope.framework.loader import Loader
graph = (
        graph.add_vertices(Loader("file:///user/jacky.yang/graphcomputer/louvain/vertex_address.csv",filetype="csv")
                           ,label="user_id"
                           ,vid_field="id"
              )
             .add_edges(Loader("file:///user/jacky.yang/graphcomputer/louvain/edge_transaction.csv",filetype="csv")
                    ,label="login"
                    ,src_label="user_id"
                    ,dst_label="user_id"
                    ,src_field='from'
                    ,dst_field='to'
                    ,properties=[('weight', 'double')]
              )
    )

# 目标：demo 所有的图分析算法
import numpy  as np
import pandas as pd
####################################################################
#Louvain算法
print("开始运行 Louvain 算法")
result_louvain = graphscope.louvain(graph, min_progress=1000, progress_tries=1)
#格式整理
dataframe_louvain = result_louvain.to_dataframe({"node": "v.id", "result": "r"})
                              
                              
                              
print("算法运行结束！")

```


vertex_address.csv
```
id
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
```

edge_transaction.csv


```
from,to,weight
2,6,1
0,16,1
0,11,1
0,4,1
3,13,1
0,7,1
0,14,1
0,10,1
1,17,1
2,5,1
3,9,1
2,8,1
9,15,1
2,12,1
16,5,1

```

Thanks you, I will try it later
Does Graphscope louvain algorithm not support execution on mac?
```
2023-12-27 11:55:30,468 [ERROR][rpc:188]: Runstep failed with code: ANALYTICAL_ENGINE_INTERNAL_ERROR, message: Error occurred during RunStep, The traceback is: Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/gscoordinator/utils.py", line 417, in _compile_on_local
    logger.debug(run_command(command, cwd=workdir))
  File "/usr/local/lib/python3.10/site-packages/gscoordinator/utils.py", line 322, in run_command
    cp = subprocess.run(shlex.split(args), capture_output=True, cwd=cwd, **kwargs)
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/subprocess.py", line 503, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/subprocess.py", line 971, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/local/Cellar/python@3.10/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/subprocess.py", line 1847, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'cmake'
```

FileNotFoundError: [Errno 2] No such file or directory: 'cmake'

Project the graph to correct schema first, and I passed the compilation with it.
```
pg = graph.project(vertices={'user_id': ['id']}, edges={'login': ['weight']})
graphscope.louvain(pg, ...)
```
> pg = graph.project(vertices={'user_id': ['id']}, edges={'login': ['weight']})

Running successfully, thank you very much for your help！
You are welcome
**by the way**
i want to adate algo nx 

```
from community import community_louvain
com = community_louvain.best_partition(G) 
```


how can we get the best_partition with graphscope louvain 
```
print("开始运行 Louvain 算法")
result_louvain = graphscope.louvain(graph, min_progress=1000, progress_tries=1)
#格式整理
dataframe_louvain = result_louvain.to_dataframe({"node": "v.id", "result": "r"})
```

if use default args min_progress=1000, progress_tries=1 the result not the best community

**result**
```
node result
0     0       
1     1       
2     2       
3     3       
4     4       
5     5       
6     6       
7     7       
8     8       
9     9       
10   10       
11   11       
12   12       
13   13       
14   14       
15   15       
16   16       
17   17   

```

expect 18 nodes in 4 communities!

Try tune the parameters and see if it helps. For example `min_progress=1000` this means < 1000 node changes is not seen as a progress, which is too large for your 18 node graph.
```
print("开始运行 Louvain 算法")
result_louvain = graphscope.louvain(graph, min_progress=2, progress_tries=2)
#格式整理
dataframe_louvain = result_louvain.to_dataframe({"node": "v.id", "result": "r"})

```

get the same result

```
node result
0     0       
1     1       
2     2       
3     3       
4     4       
5     5       
6     6       
7     7       
8     8       
9     9       
10   10       
11   11       
12   12       
13   13       
14   14       
15   15       
16   16       
17   17   
```


when i see #183 the louvain test result is 

```
dataset: p2p (62586 nodes, 147892 edges)
graphscope louvain: 0.571986 find community num: 103
python-louvain: 0.578780 find community num: 110
```


i want to use dataset: p2p (62586 nodes, 147892 edges)  where the dataset ?
> ```
> print("开始运行 Louvain 算法")
> result_louvain = graphscope.louvain(graph, min_progress=2, progress_tries=2)
> #格式整理
> dataframe_louvain = result_louvain.to_dataframe({"node": "v.id", "result": "r"})
> ```
> 
> get the same result
> 
> ```
> node result
> 0     0       
> 1     1       
> 2     2       
> 3     3       
> 4     4       
> 5     5       
> 6     6       
> 7     7       
> 8     8       
> 9     9       
> 10   10       
> 11   11       
> 12   12       
> 13   13       
> 14   14       
> 15   15       
> 16   16       
> 17   17   
> ```
> 
> when i see #183 the louvain test result is
> 
> ```
> dataset: p2p (62586 nodes, 147892 edges)
> graphscope louvain: 0.571986 find community num: 103
> python-louvain: 0.578780 find community num: 110
> ```
> 
> i want to use dataset: p2p (62586 nodes, 147892 edges) where the dataset ?

hi, @JackyYangPassion, the p2p dataset you can use the p2p-31.v and p2p-31.e in [gstest](https://github.com/GraphScope/gstest)
> > ```
> > print("开始运行 Louvain 算法")
> > result_louvain = graphscope.louvain(graph, min_progress=2, progress_tries=2)
> > #格式整理
> > dataframe_louvain = result_louvain.to_dataframe({"node": "v.id", "result": "r"})
> > ```
> > 
> > 
> >     
> >       
> >     
> > 
> >       
> >     
> > 
> >     
> >   
> > get the same result
> > ```
> > node result
> > 0     0       
> > 1     1       
> > 2     2       
> > 3     3       
> > 4     4       
> > 5     5       
> > 6     6       
> > 7     7       
> > 8     8       
> > 9     9       
> > 10   10       
> > 11   11       
> > 12   12       
> > 13   13       
> > 14   14       
> > 15   15       
> > 16   16       
> > 17   17   
> > ```
> > 
> > 
> >     
> >       
> >     
> > 
> >       
> >     
> > 
> >     
> >   
> > when i see #183 the louvain test result is
> > ```
> > dataset: p2p (62586 nodes, 147892 edges)
> > graphscope louvain: 0.571986 find community num: 103
> > python-louvain: 0.578780 find community num: 110
> > ```
> > 
> > 
> >     
> >       
> >     
> > 
> >       
> >     
> > 
> >     
> >   
> > i want to use dataset: p2p (62586 nodes, 147892 edges) where the dataset ?
> 
> hi, @JackyYangPassion, the p2p dataset you can use the p2p-31.v and p2p-31.e in [gstest](https://github.com/GraphScope/gstest)

Thanks for the reply. If the results are reproduced, what are the two configuration parameters of louvain? Are they the default ones?

```
min_progress=2, progress_tries=2

```

@acezen 
> > > ```
> > > print("开始运行 Louvain 算法")
> > > result_louvain = graphscope.louvain(graph, min_progress=2, progress_tries=2)
> > > #格式整理
> > > dataframe_louvain = result_louvain.to_dataframe({"node": "v.id", "result": "r"})
> > > ```
> > > 
> > > 
> > >     
> > >       
> > >     
> > > 
> > >       
> > >     
> > > 
> > >     
> > >   
> > > get the same result
> > > ```
> > > node result
> > > 0     0       
> > > 1     1       
> > > 2     2       
> > > 3     3       
> > > 4     4       
> > > 5     5       
> > > 6     6       
> > > 7     7       
> > > 8     8       
> > > 9     9       
> > > 10   10       
> > > 11   11       
> > > 12   12       
> > > 13   13       
> > > 14   14       
> > > 15   15       
> > > 16   16       
> > > 17   17   
> > > ```
> > > 
> > > 
> > >     
> > >       
> > >     
> > > 
> > >       
> > >     
> > > 
> > >     
> > >   
> > > when i see #183 the louvain test result is
> > > ```
> > > dataset: p2p (62586 nodes, 147892 edges)
> > > graphscope louvain: 0.571986 find community num: 103
> > > python-louvain: 0.578780 find community num: 110
> > > ```
> > > 
> > > 
> > >     
> > >       
> > >     
> > > 
> > >       
> > >     
> > > 
> > >     
> > >   
> > > i want to use dataset: p2p (62586 nodes, 147892 edges) where the dataset ?
> > 
> > 
> > hi, @JackyYangPassion, the p2p dataset you can use the p2p-31.v and p2p-31.e in [gstest](https://github.com/GraphScope/gstest)
> 
> Thanks for the reply. If the results are reproduced, what are the two configuration parameters of louvain? Are they the default ones?
> 
> ```
> min_progress=2, progress_tries=2
> ```
> 
> @acezen
like p2p the  small dataset，you can try 
```
min_progress=0
progress_tries=1
```
refer to: https://sotera.github.io/distributed-graph-analytics/louvain/

I followed the mentioned dataset and modified the [test_app.py:test_louvain_on_projected_graph](https://github.com/alibaba/GraphScope/blob/4a239383adf4f357b0424fabbcc58c5f290948dd/python/graphscope/tests/unittest/test_app.py#L330C1-L336C53) test case locally

but I couldn't reproduce the results of the previous PR #183 . The group_id column is empty. if there is any logical error?.

test_app.py:test_louvain_on_projected_graph The code logic has been modified as follows:

```
# TODO: 验证p2p 数据集合：性能，结果准确性
def test_louvain_on_p2p_projected_graph(p2p_project_undirected_graph_string,graphscope_session):
    g = p2p_project_undirected_graph_string
    interactive = graphscope_session.interactive(g)
    edgeNum = interactive.execute("g.E().count()").one()
    vertexNum = interactive.execute("g.V().count()").one()
        
    ctx = louvain(g, min_progress=0, progress_tries=1)
    df_com_louvain = ctx.to_dataframe({"node": "v.id", "r": "r"})
    logger.info(df_com_louvain.head(100))
    ctx.output_to_client(f'/home/graphscope/result/p2p_louvain_result.csv', selector={'id': 'v.id', 'dist': 'r'})
```

the result in p2p_louvain_result.csv, the dist column is empty

```
id,dist
31993,
32003,
32004,
32005,
```



**The number of groups obtained through community_louvain.best_partition(G) in nx is 62.**


![image](https://github.com/alibaba/GraphScope/assets/13795366/a984005b-1d34-4157-a92f-8d148a71b805)


@acezen @siyuan0322 Can you help me take a look at it?
```
I0103 09:19:59.000000   418 /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:237] super step: 56 decided to halt, ACTUAL QUALITY: 0.875365 previous QUALITY: 0
I0103 09:19:59.000000   418 /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:155] current super step: -1 current minor step: -1 current iteration: 0
I0103 09:19:59.000000   418 /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:155] current super step: 0 current minor step: 0 current iteration: 0
I0103 09:19:59.000000   418 /opt/graphscope/include/graphscope/apps/pregel/louvain/louvain_app_base.h:155] current super step: 1 current minor step: 1 current iteration: 0
I0103 09:19:59.000000   418 /opt/graphscope/include/graphscope/core/app/app_invoker.h:196] Query time: 1.05882 seconds

```

from the log ΔQ = ACTUAL QUALITY: 0.875365


> I followed the mentioned dataset and modified the [test_app.py:test_louvain_on_projected_graph](https://github.com/alibaba/GraphScope/blob/4a239383adf4f357b0424fabbcc58c5f290948dd/python/graphscope/tests/unittest/test_app.py#L330C1-L336C53) test case locally
> 
> but I couldn't reproduce the results of the previous PR #183 . The group_id column is empty. if there is any logical error?.
> 
> test_app.py:test_louvain_on_projected_graph The code logic has been modified as follows:
> 
> ```
> # TODO: 验证p2p 数据集合：性能，结果准确性
> def test_louvain_on_p2p_projected_graph(p2p_project_undirected_graph_string,graphscope_session):
>     g = p2p_project_undirected_graph_string
>     interactive = graphscope_session.interactive(g)
>     edgeNum = interactive.execute("g.E().count()").one()
>     vertexNum = interactive.execute("g.V().count()").one()
>         
>     ctx = louvain(g, min_progress=0, progress_tries=1)
>     df_com_louvain = ctx.to_dataframe({"node": "v.id", "r": "r"})
>     logger.info(df_com_louvain.head(100))
>     ctx.output_to_client(f'/home/graphscope/result/p2p_louvain_result.csv', selector={'id': 'v.id', 'dist': 'r'})
> ```
> 
> the result in p2p_louvain_result.csv, the dist column is empty
> 
> ```
> id,dist
> 31993,
> 32003,
> 32004,
> 32005,
> ```
> 
> **The number of groups obtained through community_louvain.best_partition(G) in nx is 62.**
> 
> ![image](https://private-user-images.githubusercontent.com/13795366/293879859-a984005b-1d34-4157-a92f-8d148a71b805.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDQzMzQ2NDUsIm5iZiI6MTcwNDMzNDM0NSwicGF0aCI6Ii8xMzc5NTM2Ni8yOTM4Nzk4NTktYTk4NDAwNWItMWQzNC00MTU3LWE5MmYtOGQxNDhhNzFiODA1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDAxMDQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwMTA0VDAyMTIyNVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWFkMjJhM2UyYjA2ZGZkNDRkYjk4MTNiNzllNmI2OTE3ZDZkODJjNDY2MGNkNDgxY2I0MGM2NmEyMzEzZTViYzYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.t82e8PzVJyjFPZMKNxNFwwFWh7dSDYOFlbkn6CrbdIo)
> 
> @acezen @siyuan0322 Can you help me take a look at it?

It's weird. The  louvain logic may change since the PR merged, I would try to reproduce the result and report to you ASAP.
Thank you for your reply. @acezen 
Currently, with the growth of graph data scale, we are adapting from nx to gs louvain to speed up the running efficiency. During the result verification stage, we found that the results after clustering do not meet expectations.

Fix patch:
diff --git a/analytical_engine/apps/pregel/louvain/auxiliary.h b/analytical_engine/apps/pregel/louvain/auxiliary.h
index cae182879263..7e2f0939a860 100644
--- a/analytical_engine/apps/pregel/louvain/auxiliary.h
+++ b/analytical_engine/apps/pregel/louvain/auxiliary.h
@@ -41,6 +41,8 @@ constexpr int phase_one_minor_step_0 = 0;
 constexpr int phase_one_minor_step_1 = 1;
 constexpr int phase_one_minor_step_2 = 2;
 
+constexpr double min_quality_improvement = 0.001;
+
 /**
  * The state of a vertex.
  */
diff --git a/analytical_engine/apps/pregel/louvain/louvain_app_base.h b/analytical_engine/apps/pregel/louvain/louvain_app_base.h
index 7ae2da7e6060..13386bf7790b 100644
--- a/analytical_engine/apps/pregel/louvain/louvain_app_base.h
+++ b/analytical_engine/apps/pregel/louvain/louvain_app_base.h
@@ -16,6 +16,7 @@ limitations under the License.
 #ifndef ANALYTICAL_ENGINE_APPS_PREGEL_LOUVAIN_LOUVAIN_APP_BASE_H_
 #define ANALYTICAL_ENGINE_APPS_PREGEL_LOUVAIN_LOUVAIN_APP_BASE_H_
 
+#include <cmath>
 #include <memory>
 #include <string>
 #include <utility>
@@ -224,7 +225,9 @@ class LouvainAppBase
               actual_quality_aggregator);
       // after one pass if already decided halt, that means the pass yield no
       // changes, so we halt computation.
-      if (current_super_step <= 14 || actual_quality <= ctx.prev_quality()) {
+      if (current_super_step <= 14 ||
+          std::fabs(actual_quality - ctx.prev_quality()) <
+              min_quality_improvement) {
         // turn to sync community result
         ctx.compute_context().set_superstep(sync_result_step);
         syncCommunity(frag, ctx, messages);
@@ -273,13 +276,6 @@ class LouvainAppBase
       } else if (ctx.compute_context().superstep() == compress_community_step) {
         ctx.GetVertexState(v).is_alived_community = false;
       }
-
-      if (!ctx.compute_context().active(v)) {
-        std::vector<std::pair<vid_t, edata_t>> tmp_edges;
-        ctx.GetVertexState(v).fake_edges.swap(tmp_edges);
-        std::vector<vid_t> tmp_nodes;
-        ctx.GetVertexState(v).nodes_in_community.swap(tmp_nodes);
-      }
     });
 
     {
@@ -321,7 +317,7 @@ class LouvainAppBase
                                 int tid, vertex_t v) {
       const auto& member_list = ctx.vertex_state()[v].nodes_in_community;
       if (!member_list.empty()) {
-        auto community_id = frag.Gid2Oid(member_list.front());
+        auto community_id = frag.Gid2Oid(ctx.vertex_state()[v].community);
         // send community id to members
         for (const auto& member_gid : member_list) {
           auto fid = vid_parser.GetFid(member_gid);


Test patch:
diff --git a/python/graphscope/nx/algorithms/tests/builtin/test_cluster.py b/python/graphscope/nx/algorithms/tests/builtin/test_cluster.py
index 4c4b3b487239..5f14199d97d4 100644
--- a/python/graphscope/nx/algorithms/tests/builtin/test_cluster.py
+++ b/python/graphscope/nx/algorithms/tests/builtin/test_cluster.py
@@ -290,6 +290,7 @@ def test_k5(self):
             4: 0.83333333333333337,
         }
 
+    @pytest.mark.skip(reason="FIXME(@acezen): first assert failed, got 0.0")
     def test_triangle_and_edge(self):
         G = nx.cycle_graph(3)
         G.add_edge(0, 4, weight=2)
@@ -339,6 +340,9 @@ def test_cubical(self):
         assert nx.builtin.clustering(G, 1) == 0
         assert nx.builtin.clustering(G, [1, 2]) == {1: 0, 2: 0}
 
+    @pytest.mark.skip(
+        reason="FIXME(@acezen): first assert failed, got [12, 12, 12, 12,12]"
+    )
     def test_k5(self):
         G = nx.complete_graph(5)
         assert list(nx.builtin.clustering(G).values()) == [1, 1, 1, 1, 1]
@@ -468,6 +472,7 @@ def test_lind_square_clustering(self):
 
 
 @pytest.mark.usefixtures("graphscope_session")
+@pytest.mark.skip(reason="FIXME(@acezen): first assert failed, got -2.0")
 def test_average_clustering():
     G = nx.cycle_graph(3)
     G.add_edge(2, 3)
diff --git a/python/graphscope/tests/unittest/test_app.py b/python/graphscope/tests/unittest/test_app.py
index 92d56695c360..b26b72462d41 100644
--- a/python/graphscope/tests/unittest/test_app.py
+++ b/python/graphscope/tests/unittest/test_app.py
@@ -235,7 +235,10 @@ def test_other_app_on_undirected_graph(
 
     # louvain
     ctx = louvain(p2p_project_undirected_graph, min_progress=50, progress_tries=2)
-    assert ctx is not None
+    df = ctx.to_dataframe({"node": "v.id", "r": "r"})
+    community_num = len(df["r"].unique())
+    print("community_num: ", community_num)  # it's not a fixed number
+
     # simple_path
     ctx = is_simple_path(p2p_project_undirected_graph, [1, 10])
     assert ctx is not None
diff --git a/python/graphscope/tests/unittest/test_lazy.py b/python/graphscope/tests/unittest/test_lazy.py
index 1d9048a74ffe..75388aa38338 100644
--- a/python/graphscope/tests/unittest/test_lazy.py
+++ b/python/graphscope/tests/unittest/test_lazy.py
@@ -231,6 +231,7 @@ def test_across_engine(sess):
     assert res[0] == 62586
 
 
+@pytest.mark.skip(reason="FIXME(@shirly121): The regex pattern is not correct.")
 def test_gremlin_timeout(sess):
     g_node = load_p2p_network(sess)
     interactive = sess.gremlin(g_node)