@@ -1117,13 +1117,13 @@ class ArrowProjectedFragment
1117
1117
grape::PrepareConf conf) {
1118
1118
if (conf.message_strategy ==
1119
1119
grape::MessageStrategy::kAlongEdgeToOuterVertex ) {
1120
- initDestFidList (true , true , iodst_, iodoffset_);
1120
+ initDestFidList (comm_spec, true , true , iodst_, iodoffset_);
1121
1121
} else if (conf.message_strategy ==
1122
1122
grape::MessageStrategy::kAlongIncomingEdgeToOuterVertex ) {
1123
- initDestFidList (true , false , idst_, idoffset_);
1123
+ initDestFidList (comm_spec, true , false , idst_, idoffset_);
1124
1124
} else if (conf.message_strategy ==
1125
1125
grape::MessageStrategy::kAlongOutgoingEdgeToOuterVertex ) {
1126
- initDestFidList (false , true , odst_, odoffset_);
1126
+ initDestFidList (comm_spec, false , true , odst_, odoffset_);
1127
1127
}
1128
1128
1129
1129
initOuterVertexRanges ();
@@ -1140,16 +1140,19 @@ class ArrowProjectedFragment
1140
1140
ie_spliters_ptr_.clear ();
1141
1141
oe_spliters_ptr_.clear ();
1142
1142
if (directed_) {
1143
- initEdgeSpliters (ie_, ie_offsets_begin_, ie_offsets_end_, ie_spliters_);
1144
- initEdgeSpliters (oe_, oe_offsets_begin_, oe_offsets_end_, oe_spliters_);
1143
+ initEdgeSpliters (comm_spec, ie_, ie_offsets_begin_, ie_offsets_end_,
1144
+ ie_spliters_);
1145
+ initEdgeSpliters (comm_spec, oe_, oe_offsets_begin_, oe_offsets_end_,
1146
+ oe_spliters_);
1145
1147
for (auto & vec : ie_spliters_) {
1146
1148
ie_spliters_ptr_.push_back (vec.data ());
1147
1149
}
1148
1150
for (auto & vec : oe_spliters_) {
1149
1151
oe_spliters_ptr_.push_back (vec.data ());
1150
1152
}
1151
1153
} else {
1152
- initEdgeSpliters (oe_, oe_offsets_begin_, oe_offsets_end_, oe_spliters_);
1154
+ initEdgeSpliters (comm_spec, oe_, oe_offsets_begin_, oe_offsets_end_,
1155
+ oe_spliters_);
1153
1156
for (auto & vec : oe_spliters_) {
1154
1157
ie_spliters_ptr_.push_back (vec.data ());
1155
1158
oe_spliters_ptr_.push_back (vec.data ());
@@ -1690,7 +1693,7 @@ class ArrowProjectedFragment
1690
1693
ends[i] = range.second ;
1691
1694
}
1692
1695
},
1693
- std::thread::hardware_concurrency ());
1696
+ std::thread::hardware_concurrency (), 1024 );
1694
1697
return {};
1695
1698
}
1696
1699
@@ -1721,16 +1724,81 @@ class ArrowProjectedFragment
1721
1724
bends[i] = range.second .second ;
1722
1725
}
1723
1726
},
1724
- std::thread::hardware_concurrency ());
1727
+ std::thread::hardware_concurrency (), 1024 );
1725
1728
return {};
1726
1729
}
1727
1730
1728
- void initDestFidList (bool in_edge, bool out_edge ,
1729
- std::vector<fid_t >& fid_list,
1731
+ void initDestFidList (const grape::CommSpec& comm_spec, const bool in_edge ,
1732
+ const bool out_edge, std::vector<fid_t >& fid_list,
1730
1733
std::vector<fid_t *>& fid_list_offset) {
1731
1734
if (!fid_list_offset.empty ()) {
1732
1735
return ;
1733
1736
}
1737
+ fid_list_offset.resize (ivnum_ + 1 , NULL );
1738
+
1739
+ int concurrency =
1740
+ (std::thread::hardware_concurrency () + comm_spec.local_num () - 1 ) /
1741
+ comm_spec.local_num ();
1742
+
1743
+ // don't use std::vector<bool> due to its specialization
1744
+ std::vector<uint8_t > fid_list_bitmap (ivnum_ * fnum_, 0 );
1745
+ std::atomic_size_t fid_list_size (0 );
1746
+
1747
+ vineyard::parallel_for (
1748
+ static_cast <vid_t >(0 ), static_cast <vid_t >(ivnum_),
1749
+ [this , in_edge, out_edge, &fid_list_bitmap,
1750
+ &fid_list_size](const vid_t & offset) {
1751
+ vertex_t v = *(inner_vertices_.begin () + offset);
1752
+ if (in_edge) {
1753
+ auto es = GetIncomingAdjList (v);
1754
+ fid_t last_fid = -1 ;
1755
+ for (auto & e : es) {
1756
+ fid_t f = GetFragId (e.neighbor ());
1757
+ if (f != last_fid && f != fid_ &&
1758
+ !fid_list_bitmap[offset * fnum_ + f]) {
1759
+ last_fid = f;
1760
+ fid_list_bitmap[offset * fnum_ + f] = 1 ;
1761
+ fid_list_size.fetch_add (1 );
1762
+ }
1763
+ }
1764
+ }
1765
+ if (out_edge) {
1766
+ auto es = GetOutgoingAdjList (v);
1767
+ fid_t last_fid = -1 ;
1768
+ for (auto & e : es) {
1769
+ fid_t f = GetFragId (e.neighbor ());
1770
+ if (f != last_fid && f != fid_ &&
1771
+ !fid_list_bitmap[offset * fnum_ + f]) {
1772
+ last_fid = f;
1773
+ fid_list_bitmap[offset * fnum_ + f] = 1 ;
1774
+ fid_list_size.fetch_add (1 );
1775
+ }
1776
+ }
1777
+ }
1778
+ },
1779
+ concurrency, 1024 );
1780
+
1781
+ fid_list.reserve (fid_list_size.load ());
1782
+ fid_list_offset[0 ] = fid_list.data ();
1783
+
1784
+ for (vid_t i = 0 ; i < ivnum_; ++i) {
1785
+ size_t nonzero = 0 ;
1786
+ for (fid_t fid = 0 ; fid < fnum_; ++fid) {
1787
+ if (fid_list_bitmap[i * fnum_ + fid]) {
1788
+ nonzero += 1 ;
1789
+ fid_list.push_back (fid);
1790
+ }
1791
+ }
1792
+ fid_list_offset[i + 1 ] = fid_list_offset[i] + nonzero;
1793
+ }
1794
+ }
1795
+
1796
+ void initDestFidListSeq (const bool in_edge, const bool out_edge,
1797
+ std::vector<fid_t >& fid_list,
1798
+ std::vector<fid_t *>& fid_list_offset) {
1799
+ if (!fid_list_offset.empty ()) {
1800
+ return ;
1801
+ }
1734
1802
1735
1803
fid_list_offset.resize (ivnum_ + 1 , NULL );
1736
1804
@@ -1773,6 +1841,7 @@ class ArrowProjectedFragment
1773
1841
}
1774
1842
1775
1843
void initEdgeSpliters (
1844
+ const grape::CommSpec& comm_spec,
1776
1845
const std::shared_ptr<arrow::FixedSizeBinaryArray>& edge_list,
1777
1846
const std::shared_ptr<arrow::Int64Array>& offsets_begin,
1778
1847
const std::shared_ptr<arrow::Int64Array>& offsets_end,
@@ -1784,28 +1853,38 @@ class ArrowProjectedFragment
1784
1853
for (auto & vec : spliters) {
1785
1854
vec.resize (ivnum_);
1786
1855
}
1787
- std::vector<int > frag_count;
1788
- for (vid_t i = 0 ; i < ivnum_; ++i) {
1789
- frag_count.clear ();
1790
- frag_count.resize (fnum_, 0 );
1791
- int64_t begin = offsets_begin->Value (i);
1792
- int64_t end = offsets_end->Value (i);
1793
- for (int64_t j = begin; j != end; ++j) {
1794
- const nbr_unit_t * nbr_ptr =
1795
- reinterpret_cast <const nbr_unit_t *>(edge_list->GetValue (j));
1796
- vertex_t u (nbr_ptr->vid );
1797
- fid_t u_fid = GetFragId (u);
1798
- ++frag_count[u_fid];
1799
- }
1800
- begin += frag_count[fid_];
1801
- frag_count[fid_] = 0 ;
1802
- spliters[0 ][i] = begin;
1803
- for (fid_t j = 0 ; j < fnum_; ++j) {
1804
- begin += frag_count[j];
1805
- spliters[j + 1 ][i] = begin;
1806
- }
1807
- CHECK_EQ (begin, end);
1808
- }
1856
+
1857
+ int concurrency =
1858
+ (std::thread::hardware_concurrency () + comm_spec.local_num () - 1 ) /
1859
+ comm_spec.local_num ();
1860
+
1861
+ vineyard::parallel_for (
1862
+ static_cast <vid_t >(0 ), ivnum_,
1863
+ [this , &offsets_begin, &offsets_end, &edge_list,
1864
+ &spliters](const vid_t i) {
1865
+ std::vector<int > frag_count (fnum_, 0 );
1866
+ int64_t begin = offsets_begin->Value (i);
1867
+ int64_t end = offsets_end->Value (i);
1868
+ for (int64_t j = begin; j != end; ++j) {
1869
+ const nbr_unit_t * nbr_ptr =
1870
+ reinterpret_cast <const nbr_unit_t *>(edge_list->GetValue (j));
1871
+ vertex_t u (nbr_ptr->vid );
1872
+ fid_t u_fid = GetFragId (u);
1873
+ ++frag_count[u_fid];
1874
+ }
1875
+ begin += frag_count[fid_];
1876
+ frag_count[fid_] = 0 ;
1877
+ spliters[0 ][i] = begin;
1878
+ for (fid_t j = 0 ; j < fnum_; ++j) {
1879
+ begin += frag_count[j];
1880
+ spliters[j + 1 ][i] = begin;
1881
+ }
1882
+ if (begin != end) {
1883
+ LOG (ERROR) << " Unexpected edge spliters for ith vertex " << i
1884
+ << " , begin: " << begin << " vs. end: " << end;
1885
+ }
1886
+ },
1887
+ concurrency, 1024 );
1809
1888
}
1810
1889
1811
1890
void initOuterVertexRanges () {
0 commit comments